Skip to content

Commit

Permalink
Bump scala-lru-map to 0.5.0 (close #172)
Browse files Browse the repository at this point in the history
  • Loading branch information
lukeindykiewicz committed Aug 24, 2020
1 parent 983952e commit f75e628
Show file tree
Hide file tree
Showing 10 changed files with 42 additions and 163 deletions.
2 changes: 1 addition & 1 deletion project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ object Dependencies {
// Scala
val catsEffect = "2.1.4"
val circe = "0.13.0"
val lruMap = "0.3.0"
val lruMap = "0.5.0"
val scalaj = "2.4.1"

// Scala (test only)
Expand Down
27 changes: 12 additions & 15 deletions src/main/scala/com.snowplowanalytics/forex/Forex.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@ import java.math.{BigDecimal, RoundingMode}

import scala.util.{Failure, Success, Try}

import cats.{Eval, Id, Monad}
import cats.{Id, Monad}
import cats.effect.Sync
import cats.data.{EitherT, OptionT}
import cats.implicits._
import org.joda.money._

import errors._
import model._
import com.snowplowanalytics.lrumap.CreateLruMap

trait CreateForex[F[_]] {
def create(config: ForexConfig): F[Forex[F]]
Expand All @@ -34,18 +35,15 @@ trait CreateForex[F[_]] {
object CreateForex {
def apply[F[_]](implicit ev: CreateForex[F]): CreateForex[F] = ev

implicit def syncCreateForex[F[_]: Sync: ZonedClock]: CreateForex[F] =
implicit def syncCreateForex[F[_]: Sync: ZonedClock](implicit
CLM1: CreateLruMap[F, NowishCacheKey, NowishCacheValue],
CLM2: CreateLruMap[F, EodCacheKey, EodCacheValue]
): CreateForex[F] =
(config: ForexConfig) =>
OerClient
.getClient[F](config)
.map(client => Forex(config, client))

implicit def evalCreateForex: CreateForex[Eval] =
(config: ForexConfig) =>
OerClient
.getClient[Eval](config)
.map(client => Forex(config, client))

implicit def idCreateForex: CreateForex[Id] =
(config: ForexConfig) =>
OerClient
Expand All @@ -71,9 +69,8 @@ object Forex {
if (!fromCurrIsBaseCurr) {
val fromOverBase = new BigDecimal(1).divide(baseOverFrom, Forex.commonScale, RoundingMode.HALF_EVEN)
fromOverBase.multiply(baseOverTo)
} else {
} else
baseOverTo
}
}

/**
Expand Down Expand Up @@ -220,11 +217,11 @@ final case class ForexLookupWhen[F[_]](
* failed
*/
def at(tradeDate: ZonedDateTime)(implicit M: Monad[F]): F[Either[OerResponseError, Money]] = {
val latestEod = if (config.getNearestDay == EodRoundUp) {
tradeDate.truncatedTo(ChronoUnit.DAYS).plusDays(1)
} else {
tradeDate.truncatedTo(ChronoUnit.DAYS)
}
val latestEod =
if (config.getNearestDay == EodRoundUp)
tradeDate.truncatedTo(ChronoUnit.DAYS).plusDays(1)
else
tradeDate.truncatedTo(ChronoUnit.DAYS)
eod(latestEod)
}

Expand Down
13 changes: 0 additions & 13 deletions src/test/scala/com.snowplowanalytics.forex/ForexAtSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ package com.snowplowanalytics.forex

import java.time.{ZoneId, ZonedDateTime}

import cats.Eval
import cats.effect.IO
import org.joda.money.{CurrencyUnit, Money}
import org.specs2.mutable.Specification
Expand All @@ -32,9 +31,6 @@ class ForexAtSpec extends Specification {
val ioFx = CreateForex[IO].create(ForexConfig(key, DeveloperAccount))
val ioFxWithBaseGBP =
CreateForex[IO].create(ForexConfig(key, EnterpriseAccount, baseCurrency = CurrencyUnit.GBP))
val evalFx = CreateForex[Eval].create(ForexConfig(key, DeveloperAccount))
val evalFxWithBaseGBP =
CreateForex[Eval].create(ForexConfig(key, EnterpriseAccount, baseCurrency = CurrencyUnit.GBP))

val tradeDate =
ZonedDateTime.of(2011, 3, 13, 11, 39, 27, 567, ZoneId.of("America/New_York"))
Expand All @@ -45,9 +41,6 @@ class ForexAtSpec extends Specification {
val ioGbpToCadWithBaseUsd =
ioFx.flatMap(_.rate(CurrencyUnit.GBP).to(CurrencyUnit.CAD).at(tradeDate))
ioGbpToCadWithBaseUsd.unsafeRunSync() must beRight((m: Money) => m.isPositive)
val evalGbpToCadWithBaseUsd =
evalFx.flatMap(_.rate(CurrencyUnit.GBP).to(CurrencyUnit.CAD).at(tradeDate))
evalGbpToCadWithBaseUsd.value must beRight((m: Money) => m.isPositive)
}
}

Expand All @@ -56,9 +49,6 @@ class ForexAtSpec extends Specification {
"be > 0" in {
val ioGbpToCadWithBaseGbp = ioFxWithBaseGBP.flatMap(_.rate.to(CurrencyUnit.CAD).at(tradeDate))
ioGbpToCadWithBaseGbp.unsafeRunSync() must beRight((m: Money) => m.isPositive)
val evalGbpToCadWithBaseGbp =
evalFxWithBaseGBP.flatMap(_.rate.to(CurrencyUnit.CAD).at(tradeDate))
evalGbpToCadWithBaseGbp.value must beRight((m: Money) => m.isPositive)
}
}

Expand All @@ -68,9 +58,6 @@ class ForexAtSpec extends Specification {
val ioCnyOverGbpHistorical =
ioFx.flatMap(_.rate(CurrencyUnit.of("CNY")).to(CurrencyUnit.GBP).at(tradeDate))
ioCnyOverGbpHistorical.unsafeRunSync() must beRight((m: Money) => m.isPositive)
val evalCnyOverGbpHistorical =
evalFx.flatMap(_.rate(CurrencyUnit.of("CNY")).to(CurrencyUnit.GBP).at(tradeDate))
evalCnyOverGbpHistorical.value must beRight((m: Money) => m.isPositive)
}
}

Expand Down
15 changes: 4 additions & 11 deletions src/test/scala/com.snowplowanalytics.forex/ForexEodSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ package com.snowplowanalytics.forex
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter

import cats.Eval
import cats.effect.IO
import org.joda.money.{CurrencyUnit, Money}
import org.specs2.mutable.Specification
Expand All @@ -30,9 +29,8 @@ import model._
*/
class ForexEodSpec extends Specification with DataTables {

val key = sys.env.getOrElse("OER_KEY", "")
val ioFx = CreateForex[IO].create(ForexConfig(key, DeveloperAccount))
val evalFx = CreateForex[Eval].create(ForexConfig(key, DeveloperAccount))
val key = sys.env.getOrElse("OER_KEY", "")
val ioFx = CreateForex[IO].create(ForexConfig(key, DeveloperAccount))

override def is =
skipAllIf(sys.env.get("OER_KEY").isEmpty) ^
Expand All @@ -51,14 +49,9 @@ class ForexEodSpec extends Specification with DataTables {
.flatMap(
_.rate(fromCurr)
.to(toCurr)
.eod(ZonedDateTime.parse(date, DateTimeFormatter.ISO_OFFSET_DATE_TIME)))
.eod(ZonedDateTime.parse(date, DateTimeFormatter.ISO_OFFSET_DATE_TIME))
)
.unsafeRunSync() must beRight((m: Money) => m.getAmount.toString mustEqual exp)
evalFx
.flatMap(
_.rate(fromCurr)
.to(toCurr)
.eod(ZonedDateTime.parse(date, DateTimeFormatter.ISO_OFFSET_DATE_TIME)))
.value must beRight((m: Money) => m.getAmount.toString mustEqual exp)
}

}
38 changes: 12 additions & 26 deletions src/test/scala/com.snowplowanalytics.forex/ForexNowSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ package com.snowplowanalytics.forex

import java.math.RoundingMode

import cats.Eval
import cats.effect.IO
import org.joda.money._
import org.specs2.mutable.Specification
Expand All @@ -29,27 +28,19 @@ class ForexNowSpec extends Specification {
val ioFx = CreateForex[IO].create(ForexConfig(key, DeveloperAccount))
val ioFxWithBaseGBP =
CreateForex[IO].create(ForexConfig(key, EnterpriseAccount, baseCurrency = CurrencyUnit.GBP))
val evalFx = CreateForex[Eval].create(ForexConfig(key, DeveloperAccount))
val evalFxWithBaseGBP =
CreateForex[Eval].create(ForexConfig(key, EnterpriseAccount, baseCurrency = CurrencyUnit.GBP))

/** Trade 10000 USD to JPY at live exchange rate */
"convert 10000 USD dollars to Yen now" should {
"be > 10000" in {
val ioTradeInYenNow = ioFx.flatMap(_.convert(10000).to(CurrencyUnit.JPY).now)
ioTradeInYenNow.unsafeRunSync() must beRight(
(m: Money) => m.isGreaterThan(Money.of(CurrencyUnit.JPY, 10000, RoundingMode.HALF_EVEN)))
ioTradeInYenNow.unsafeRunSync() must beRight((m: Money) =>
m.isGreaterThan(Money.of(CurrencyUnit.JPY, 10000, RoundingMode.HALF_EVEN))
)
val ioTradeInYenNow2 = ioFx
.flatMap(_.convert(10000, CurrencyUnit.USD).to(CurrencyUnit.JPY).now)
ioTradeInYenNow2.unsafeRunSync() must beRight(
(m: Money) => m.isGreaterThan(Money.of(CurrencyUnit.JPY, 10000, RoundingMode.HALF_EVEN)))
val evalTradeInYenNow = evalFx.flatMap(_.convert(10000).to(CurrencyUnit.JPY).now)
evalTradeInYenNow.value must beRight(
(m: Money) => m.isGreaterThan(Money.of(CurrencyUnit.JPY, 10000, RoundingMode.HALF_EVEN)))
val evalTradeInYenNow2 = evalFx
.flatMap(_.convert(10000, CurrencyUnit.USD).to(CurrencyUnit.JPY).now)
evalTradeInYenNow2.value must beRight(
(m: Money) => m.isGreaterThan(Money.of(CurrencyUnit.JPY, 10000, RoundingMode.HALF_EVEN)))
ioTradeInYenNow2.unsafeRunSync() must beRight((m: Money) =>
m.isGreaterThan(Money.of(CurrencyUnit.JPY, 10000, RoundingMode.HALF_EVEN))
)
}
}

Expand All @@ -58,22 +49,19 @@ class ForexNowSpec extends Specification {
"be greater than 1 SGD" in {
val ioGbpToSgdWithBaseUsd =
ioFx.flatMap(_.rate(CurrencyUnit.GBP).to(CurrencyUnit.of("SGD")).now)
ioGbpToSgdWithBaseUsd.unsafeRunSync() must beRight(
(m: Money) => m.isGreaterThan(Money.of(CurrencyUnit.of("SGD"), 1)))
val evalGbpToSgdWithBaseUsd =
evalFx.flatMap(_.rate(CurrencyUnit.GBP).to(CurrencyUnit.of("SGD")).now)
evalGbpToSgdWithBaseUsd.value must beRight((m: Money) => m.isGreaterThan(Money.of(CurrencyUnit.of("SGD"), 1)))
ioGbpToSgdWithBaseUsd.unsafeRunSync() must beRight((m: Money) =>
m.isGreaterThan(Money.of(CurrencyUnit.of("SGD"), 1))
)
}
}

/** GBP -> SGD with GBP as base currency */
"GBP to SGD with base currency GBP live exchange rate" should {
"be greater than 1 SGD" in {
val ioGbpToSgdWithBaseGbp = ioFxWithBaseGBP.flatMap(_.rate.to(CurrencyUnit.of("SGD")).now)
ioGbpToSgdWithBaseGbp.unsafeRunSync() must beRight(
(m: Money) => m.isGreaterThan(Money.of(CurrencyUnit.of("SGD"), 1)))
val evalGbpToSgdWithBaseGbp = evalFxWithBaseGBP.flatMap(_.rate.to(CurrencyUnit.of("SGD")).now)
evalGbpToSgdWithBaseGbp.value must beRight((m: Money) => m.isGreaterThan(Money.of(CurrencyUnit.of("SGD"), 1)))
ioGbpToSgdWithBaseGbp.unsafeRunSync() must beRight((m: Money) =>
m.isGreaterThan(Money.of(CurrencyUnit.of("SGD"), 1))
)
}
}

Expand All @@ -82,8 +70,6 @@ class ForexNowSpec extends Specification {
"be equal 1 GBP" in {
val ioGbpToGbpWithBaseGbp = ioFxWithBaseGBP.flatMap(_.rate.to(CurrencyUnit.GBP).now)
ioGbpToGbpWithBaseGbp.unsafeRunSync() must beRight((m: Money) => m.isEqual(Money.of(CurrencyUnit.of("GBP"), 1)))
val evalGbpToGbpWithBaseGbp = evalFxWithBaseGBP.flatMap(_.rate.to(CurrencyUnit.GBP).now)
evalGbpToGbpWithBaseGbp.value must beRight((m: Money) => m.isEqual(Money.of(CurrencyUnit.of("GBP"), 1)))
}
}
}
24 changes: 6 additions & 18 deletions src/test/scala/com.snowplowanalytics.forex/ForexNowishSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ package com.snowplowanalytics.forex

import java.math.RoundingMode

import cats.Eval
import cats.effect.IO
import org.joda.money._
import org.specs2.mutable.Specification
Expand All @@ -29,44 +28,33 @@ class ForexNowishSpec extends Specification {
val ioFx = CreateForex[IO].create(ForexConfig(key, DeveloperAccount))
val ioFxWithBaseGBP =
CreateForex[IO].create(ForexConfig(key, EnterpriseAccount, baseCurrency = CurrencyUnit.GBP))
val evalFx = CreateForex[Eval].create(ForexConfig(key, DeveloperAccount))
val evalFxWithBaseGBP =
CreateForex[Eval].create(ForexConfig(key, EnterpriseAccount, baseCurrency = CurrencyUnit.GBP))

/** CAD -> GBP with base currency USD */
"CAD to GBP with USD as base currency returning near-live rate" should {
"be smaller than 1 pound" in {
val ioCadOverGbpNowish = ioFx.flatMap(_.rate(CurrencyUnit.CAD).to(CurrencyUnit.GBP).nowish)
ioCadOverGbpNowish
.unsafeRunSync() must beRight((m: Money) => m.isLessThan(Money.of(CurrencyUnit.GBP, 1)))
val evalCadOverGbpNowish =
evalFx.flatMap(_.rate(CurrencyUnit.CAD).to(CurrencyUnit.GBP).nowish)
evalCadOverGbpNowish.value must beRight((m: Money) => m.isLessThan(Money.of(CurrencyUnit.GBP, 1)))
}
}

/** GBP -> JPY with base currency USD */
"GBP to JPY with USD as base currency returning near-live rate" should {
"be greater than 1 Yen" in {
val ioGbpToJpyWithBaseUsd = ioFx.flatMap(_.rate(CurrencyUnit.GBP).to(CurrencyUnit.JPY).nowish)
ioGbpToJpyWithBaseUsd.unsafeRunSync() must beRight(
(m: Money) => m.isGreaterThan(BigMoney.of(CurrencyUnit.JPY, 1).toMoney(RoundingMode.HALF_EVEN)))
val evalGbpToJpyWithBaseUsd =
evalFx.flatMap(_.rate(CurrencyUnit.GBP).to(CurrencyUnit.JPY).nowish)
evalGbpToJpyWithBaseUsd.value must beRight(
(m: Money) => m.isGreaterThan(BigMoney.of(CurrencyUnit.JPY, 1).toMoney(RoundingMode.HALF_EVEN)))
ioGbpToJpyWithBaseUsd.unsafeRunSync() must beRight((m: Money) =>
m.isGreaterThan(BigMoney.of(CurrencyUnit.JPY, 1).toMoney(RoundingMode.HALF_EVEN))
)
}
}

/** GBP -> JPY with base currency GBP */
"GBP to JPY with GBP as base currency returning near-live rate" should {
"be greater than 1 Yen" in {
val ioGbpToJpyWithBaseGbp = ioFxWithBaseGBP.flatMap(_.rate.to(CurrencyUnit.JPY).nowish)
ioGbpToJpyWithBaseGbp.unsafeRunSync() must beRight(
(m: Money) => m.isGreaterThan(BigMoney.of(CurrencyUnit.of("JPY"), 1).toMoney(RoundingMode.HALF_EVEN)))
val evalGbpToJpyWithBaseGbp = evalFxWithBaseGBP.flatMap(_.rate.to(CurrencyUnit.JPY).nowish)
evalGbpToJpyWithBaseGbp.value must beRight(
(m: Money) => m.isGreaterThan(BigMoney.of(CurrencyUnit.of("JPY"), 1).toMoney(RoundingMode.HALF_EVEN)))
ioGbpToJpyWithBaseGbp.unsafeRunSync() must beRight((m: Money) =>
m.isGreaterThan(BigMoney.of(CurrencyUnit.of("JPY"), 1).toMoney(RoundingMode.HALF_EVEN))
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
*/
package com.snowplowanalytics.forex

import cats.Eval
import cats.effect.IO
import org.specs2.mutable.Specification

Expand All @@ -30,10 +29,6 @@ class ForexWithoutCachesSpec extends Specification {
CreateForex[IO].create(ForexConfig(key, DeveloperAccount, nowishCacheSize = 0, eodCacheSize = 0))
ioFxWithoutCache.unsafeRunSync().client.eodCache.isEmpty
ioFxWithoutCache.unsafeRunSync().client.nowishCache.isEmpty
val evalFxWithoutCache =
CreateForex[Eval].create(ForexConfig(key, DeveloperAccount, nowishCacheSize = 0, eodCacheSize = 0))
evalFxWithoutCache.value.client.eodCache.isEmpty
evalFxWithoutCache.value.client.nowishCache.isEmpty
}
}

Expand Down
13 changes: 2 additions & 11 deletions src/test/scala/com.snowplowanalytics.forex/OerClientSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ package com.snowplowanalytics.forex
import java.math.BigDecimal
import java.time.ZonedDateTime

import cats.Eval
import cats.effect.IO
import org.joda.money.CurrencyUnit
import org.specs2.mutable.Specification
Expand All @@ -26,29 +25,22 @@ import model._
class OerClientSpec extends Specification {
args(skipAll = sys.env.get("OER_KEY").isEmpty)

val key = sys.env.getOrElse("OER_KEY", "")
val ioFx = CreateForex[IO].create(ForexConfig(key, DeveloperAccount))
val evalFx = CreateForex[Eval].create(ForexConfig(key, DeveloperAccount))
val key = sys.env.getOrElse("OER_KEY", "")
val ioFx = CreateForex[IO].create(ForexConfig(key, DeveloperAccount))

"live currency value for USD" should {
"always equal to 1" in {
ioFx
.map(_.client)
.flatMap(_.getLiveCurrencyValue(CurrencyUnit.USD))
.unsafeRunSync() must beRight(new BigDecimal(1))
evalFx
.map(_.client)
.flatMap(_.getLiveCurrencyValue(CurrencyUnit.USD))
.value must beRight(new BigDecimal(1))
}
}

"live currency value for GBP" should {
"be less than 1" in {
val ioGbpLiveRate = ioFx.flatMap(_.client.getLiveCurrencyValue(CurrencyUnit.GBP))
ioGbpLiveRate.unsafeRunSync() must beRight((d: BigDecimal) => d.doubleValue < 1)
val evalGbpLiveRate = evalFx.flatMap(_.client.getLiveCurrencyValue(CurrencyUnit.GBP))
evalGbpLiveRate.value must beRight((d: BigDecimal) => d.doubleValue < 1)
}
}

Expand All @@ -58,7 +50,6 @@ class OerClientSpec extends Specification {
ioFx
.flatMap(_.client.getHistoricalCurrencyValue(CurrencyUnit.USD, date))
.unsafeRunSync() must beRight(new BigDecimal(1))
evalFx.flatMap(_.client.getHistoricalCurrencyValue(CurrencyUnit.USD, date)).value must beRight(new BigDecimal(1))
}
}
}
Loading

0 comments on commit f75e628

Please sign in to comment.