Skip to content

Commit

Permalink
Remove infinite recursion when converting currencies (closes #166)
Browse files Browse the repository at this point in the history
  • Loading branch information
BenFradet authored and dilyand committed Nov 8, 2019
1 parent 7dbdbbb commit 6ea7f16
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 14 deletions.
23 changes: 10 additions & 13 deletions src/main/scala/com.snowplowanalytics/forex/Forex.scala
Original file line number Diff line number Diff line change
Expand Up @@ -92,34 +92,31 @@ object Forex {
*/
final case class Forex[F[_]: Monad: ZonedClock](config: ForexConfig, client: OerClient[F]) {

def rate: ForexLookupTo[F] = ForexLookupTo(1, config.baseCurrency, config, client)
def rate: ForexLookupTo[F] = convert(1d, config.baseCurrency)

/**
* Starts building a fluent interface, performs currency look up from *source* currency.
* (The target currency will be supplied to the ForexLookupTo later).
* @param currency Source currency
* @return ForexLookupTo object which is the part of the fluent interface
*/
def rate(currency: CurrencyUnit): ForexLookupTo[F] =
ForexLookupTo(1, currency, config, client)
def rate(currency: CurrencyUnit): ForexLookupTo[F] = convert(1d, currency)

/**
* Starts building a currency conversion from the supplied currency, for the supplied amount.
* Starts building a currency conversion for the supplied amount, using the currency specified in config
* @param amount The amount of currency to be converted
* @param currency CurrencyUnit to convert from
* @return a ForexLookupTo, part of the currency conversion fluent interface.
* @return a ForexLookupTo, part of the currency conversion fluent interface
*/
def convert(amount: Double, currency: CurrencyUnit): ForexLookupTo[F] =
convert(amount, currency)
def convert(amount: Double): ForexLookupTo[F] = convert(amount, config.baseCurrency)

/**
* Starts building a currency conversion for the supplied amount, using the currency specified in config
* Starts building a currency conversion from the supplied currency, for the supplied amount.
* @param amount The amount of currency to be converted
* @return a ForexLookupTo, part of the currency conversion fluent interface
* @param currency CurrencyUnit to convert from
* @return a ForexLookupTo, part of the currency conversion fluent interface.
*/
def convert(amount: Double): ForexLookupTo[F] =
ForexLookupTo(amount, config.baseCurrency, config, client)

def convert(amount: Double, currency: CurrencyUnit): ForexLookupTo[F] =
ForexLookupTo(amount, currency, config, client)
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/com.snowplowanalytics/forex/OerClient.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import responses._
* @param nowishCache - user defined nowishCache
* @param eodCache - user defined eodCache
*/
case class OerClient[F[_]: Monad](
final case class OerClient[F[_]: Monad](
config: ForexConfig,
nowishCache: Option[NowishCache[F]] = None,
eodCache: Option[EodCache[F]] = None
Expand Down
8 changes: 8 additions & 0 deletions src/test/scala/com.snowplowanalytics.forex/ForexNowSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,17 @@ class ForexNowSpec extends Specification {
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)))
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)))
}
}

Expand Down

0 comments on commit 6ea7f16

Please sign in to comment.