From 07a7198455f3471972ccb45bf01596c7edf840db Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Tue, 25 May 2021 22:59:15 -0700 Subject: [PATCH] Added toCurrency(Locale). --- build.gradle.kts | 5 +- examples/build.gradle.kts | 2 +- .../net/thauvin/erik/crypto/CryptoPrice.kt | 15 +++--- .../thauvin/erik/crypto/CryptoPriceTest.kt | 53 +++++++++++-------- 4 files changed, 45 insertions(+), 30 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index bc3c1f5..f87cdb0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -53,7 +53,6 @@ java { withSourcesJar() } - detekt { //toolVersion = "main-SNAPSHOT" } @@ -74,6 +73,10 @@ val javadocJar by tasks.creating(Jar::class) { } tasks { + named("run") { + args = listOf("BTC","ETH","LTC") + } + withType().configureEach { kotlinOptions.jvmTarget = java.targetCompatibility.toString() } diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts index 36e7564..cc01279 100644 --- a/examples/build.gradle.kts +++ b/examples/build.gradle.kts @@ -5,7 +5,7 @@ plugins { } // ./gradlew run -// ./gradlew runJava" +// ./gradlew runJava defaultTasks(ApplicationPlugin.TASK_RUN_NAME) diff --git a/src/main/kotlin/net/thauvin/erik/crypto/CryptoPrice.kt b/src/main/kotlin/net/thauvin/erik/crypto/CryptoPrice.kt index defaed1..5f9c4f5 100644 --- a/src/main/kotlin/net/thauvin/erik/crypto/CryptoPrice.kt +++ b/src/main/kotlin/net/thauvin/erik/crypto/CryptoPrice.kt @@ -41,6 +41,7 @@ import java.io.IOException import java.text.NumberFormat import java.time.LocalDate import java.util.Currency +import java.util.Locale /** * A small Kotlin/Java library for retrieving cryptocurrencies current market prices. @@ -68,7 +69,7 @@ open class CryptoPrice(val base: String, val currency: String, val amount: Doubl throw CryptoException(message = "Missing price data.") } } catch (e: NumberFormatException) { - throw CryptoException(message = "Could not convert price data to number.", cause = e) + throw CryptoException(message = "Could not convert amount to number.", cause = e) } catch (e: JSONException) { throw CryptoException(message = "Could not parse price data.", cause = e) } @@ -113,9 +114,9 @@ open class CryptoPrice(val base: String, val currency: String, val amount: Doubl @JvmStatic fun main(args: Array) { - listOf("BTC", "BCH", "BSV", "ETH", "ETH2", "ETC").forEach { + args.forEach { with(marketPrice(it)) { - println("$base: $amount") + println("$base:\t" + "%10s".format(toCurrency())) } } } @@ -132,17 +133,17 @@ open class CryptoPrice(val base: String, val currency: String, val amount: Doubl @Throws(CryptoException::class, IOException::class) fun marketPrice(base: String, currency: String = "USD", date: LocalDate? = null): CryptoPrice { val params = if (date != null) mapOf("date" to "$date") else emptyMap() - val body = apiCall(listOf("prices", "$base-$currency", "spot"), params) - return body.toPrice() + return apiCall(listOf("prices", "$base-$currency", "spot"), params).toPrice() } } /** * Return the [amount] as a currency formatted string. (eg: $1,203.33) */ + @JvmOverloads @Throws(IllegalArgumentException::class) - fun toCurrency(): String { - return NumberFormat.getCurrencyInstance().let { + fun toCurrency(locale: Locale = Locale.getDefault(Locale.Category.FORMAT)): String { + return NumberFormat.getCurrencyInstance(locale).let { it.setCurrency(Currency.getInstance(currency)) it.format(amount) } diff --git a/src/test/kotlin/net/thauvin/erik/crypto/CryptoPriceTest.kt b/src/test/kotlin/net/thauvin/erik/crypto/CryptoPriceTest.kt index e4608de..7a9a23e 100644 --- a/src/test/kotlin/net/thauvin/erik/crypto/CryptoPriceTest.kt +++ b/src/test/kotlin/net/thauvin/erik/crypto/CryptoPriceTest.kt @@ -4,6 +4,7 @@ import net.thauvin.erik.crypto.CryptoPrice.Companion.apiCall import net.thauvin.erik.crypto.CryptoPrice.Companion.marketPrice import net.thauvin.erik.crypto.CryptoPrice.Companion.toPrice import java.time.LocalDate +import java.util.Locale import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFailsWith @@ -17,8 +18,8 @@ class CryptoPriceTest { @Throws(CryptoException::class) fun testBTCPrice() { val price = marketPrice("BTC") - assertEquals(price.base, "BTC", "BTC") - assertEquals(price.currency, "USD", "is USD") + assertEquals("BTC", price.base, "BTC") + assertEquals("USD", price.currency, "is USD") assertTrue(price.amount > 0.00, "BTC > 0") } @@ -26,8 +27,8 @@ class CryptoPriceTest { @Throws(CryptoException::class) fun testETHPrice() { val price = marketPrice("ETH", "EUR") - assertEquals(price.base, "ETH", "ETH") - assertEquals(price.currency, "EUR", "is EUR") + assertEquals("ETH", price.base, "ETH") + assertEquals("EUR", price.currency, "is EUR") assertTrue(price.amount > 0.00, "ETH > 0") } @@ -35,8 +36,8 @@ class CryptoPriceTest { @Throws(CryptoException::class) fun testETH2Price() { val price = marketPrice("ETH2", "GBP") - assertEquals(price.base, "ETH2", "ETH2") - assertEquals(price.currency, "GBP", "is GBP") + assertEquals("ETH2", price.base, "ETH2") + assertEquals("GBP", price.currency, "is GBP") assertTrue(price.amount > 0.00, "GBP > 0") } @@ -44,8 +45,8 @@ class CryptoPriceTest { @Throws(CryptoException::class) fun testBCHPrice() { val price = marketPrice("BCH", "GBP", LocalDate.now().minusDays(1)) - assertEquals(price.base, "BCH", "BCH") - assertEquals(price.currency, "GBP", "is GBP") + assertEquals("BCH", price.base, "BCH") + assertEquals("GBP", price.currency, "is GBP") assertTrue(price.amount > 0.00, "BCH > 0") } @@ -53,8 +54,8 @@ class CryptoPriceTest { @Throws(CryptoException::class) fun testApiCall() { val price = apiCall(listOf("prices", "BTC-USD", "buy"), emptyMap()).toPrice() - assertEquals(price.base, "BTC", "buy BTC") - assertEquals(price.currency, "USD", "buy BTC is USD") + assertEquals("BTC", price.base, "buy BTC") + assertEquals("USD", price.currency, "buy BTC is USD") assertTrue(price.amount > 0.00, "buy BTC > 0") } @@ -83,14 +84,24 @@ class CryptoPriceTest { @Test @Throws(IllegalArgumentException::class) fun testToCurrency() { - val eur = CryptoPrice("BTC", "EUR", 12345.67) - assertEquals(eur.toCurrency(), "€12,345.67", "EUR format") - - val gbp = CryptoPrice("ETH", "GBP", 12345.67) - assertEquals(gbp.toCurrency(), "£12,345.67", "GBP format") - - val aud = CryptoPrice("BTC", "AUD", 12345.67) - assertEquals(aud.toCurrency(), "A$12,345.67", "AUD format") + val d = 12345.67 + val usd = CryptoPrice("BTC", "USD", d) + assertEquals("$12,345.67", usd.toCurrency(), "EUR format") + + val eur = CryptoPrice("BTC", "EUR", d) + assertEquals("€12,345.67", eur.toCurrency(), "EUR format") + + val gbp = CryptoPrice("ETH", "GBP", d) + assertEquals("£12,345.67", gbp.toCurrency(), "GBP format") + + val aud = CryptoPrice("BTC", "AUD", d) + assertEquals("A$12,345.67", aud.toCurrency(), "AUD format") + + val fr = CryptoPrice("BTC", "EUR", d) + assertEquals("12 345,67 €", fr.toCurrency(Locale.FRANCE), "EUR-FR format") + + val jp = CryptoPrice("BTC", "JPY", d) + assertEquals("¥12,346", jp.toCurrency(Locale.JAPAN), "EUR-JPY format") } @Test @@ -99,9 +110,9 @@ class CryptoPriceTest { val d = 57515.69 val json = "{\"data\":{\"base\":\"BTC\",\"currency\":\"USD\",\"amount\":\"$d\"}}" val price = json.toPrice() - assertEquals(price.base, "BTC", "base is BTC") - assertEquals(price.currency, "USD", "currency is USD") - assertEquals(price.amount, d, "amount is 57515.69") + assertEquals("BTC", price.base, "base is BTC") + assertEquals("USD", price.currency, "currency is USD") + assertEquals(d, price.amount, "amount is 57515.69") assertFailsWith( message = "double conversion did not fail",