summaryrefslogtreecommitdiff
path: root/taler-kotlin-common
diff options
context:
space:
mode:
authorTorsten Grote <t@grobox.de>2020-08-18 11:35:28 -0300
committerTorsten Grote <t@grobox.de>2020-08-18 11:36:07 -0300
commit612876e44de35cdbd563ac2ce40dcd1d4e397bc5 (patch)
treeb2127aff7376b7d2304e300d216d838a2e1d2595 /taler-kotlin-common
parent451157d992a4c771e3bdf80b6563f80fb1582c77 (diff)
downloadtaler-android-612876e44de35cdbd563ac2ce40dcd1d4e397bc5.tar.gz
taler-android-612876e44de35cdbd563ac2ce40dcd1d4e397bc5.tar.bz2
taler-android-612876e44de35cdbd563ac2ce40dcd1d4e397bc5.zip
Include Taler common Kotlin library as a submodule
Diffstat (limited to 'taler-kotlin-common')
-rw-r--r--taler-kotlin-common/.gitignore1
-rw-r--r--taler-kotlin-common/.gitlab-ci.yml7
-rw-r--r--taler-kotlin-common/build.gradle82
-rw-r--r--taler-kotlin-common/src/commonMain/kotlin/net/taler/common/Amount.kt198
-rw-r--r--taler-kotlin-common/src/commonMain/kotlin/net/taler/common/Time.kt106
-rw-r--r--taler-kotlin-common/src/commonMain/kotlin/net/taler/common/Version.kt70
-rw-r--r--taler-kotlin-common/src/commonTest/kotlin/net/taler/common/AmountTest.kt234
-rw-r--r--taler-kotlin-common/src/commonTest/kotlin/net/taler/common/TestUtils.kt26
-rw-r--r--taler-kotlin-common/src/commonTest/kotlin/net/taler/common/TimeTest.kt49
-rw-r--r--taler-kotlin-common/src/commonTest/kotlin/net/taler/common/VersionTest.kt65
-rw-r--r--taler-kotlin-common/src/jsMain/kotlin/net/taler/common/Time.kt23
-rw-r--r--taler-kotlin-common/src/jvmMain/kotlin/net/taler/common/Time.kt21
-rw-r--r--taler-kotlin-common/src/nativeMain/kotlin/net/taler/common/Time.kt23
13 files changed, 0 insertions, 905 deletions
diff --git a/taler-kotlin-common/.gitignore b/taler-kotlin-common/.gitignore
deleted file mode 100644
index 796b96d..0000000
--- a/taler-kotlin-common/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/build
diff --git a/taler-kotlin-common/.gitlab-ci.yml b/taler-kotlin-common/.gitlab-ci.yml
deleted file mode 100644
index c241e31..0000000
--- a/taler-kotlin-common/.gitlab-ci.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-taler_kotlin_common_test:
- stage: test
- only:
- changes:
- - taler-kotlin-common/**/*
- - build.gradle
- script: ./gradlew :taler-kotlin-common:jvmTest
diff --git a/taler-kotlin-common/build.gradle b/taler-kotlin-common/build.gradle
deleted file mode 100644
index 129881d..0000000
--- a/taler-kotlin-common/build.gradle
+++ /dev/null
@@ -1,82 +0,0 @@
-plugins {
- id 'org.jetbrains.kotlin.multiplatform'
- id 'kotlinx-serialization'
-}
-
-group 'net.taler'
-version '0.0.1'
-
-apply plugin: 'maven-publish'
-
-kotlin {
- jvm()
- // This is for iPhone simulator
- // Switch here to iosArm64 (or iosArm32) to build library for iPhone device
- iosX64("ios") {
- binaries {
- framework()
- }
- }
- linuxX64("linux")
- js {
- browser {
- }
- nodejs {
- }
- }
- sourceSets {
- def serialization_version = "0.20.0"
- commonMain {
- dependencies {
- implementation kotlin('stdlib-common')
- implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serialization_version"
- }
- }
- commonTest {
- dependencies {
- implementation kotlin('test-common')
- implementation kotlin('test-annotations-common')
- }
- }
- jvmMain {
- dependencies {
- implementation kotlin('stdlib-jdk8')
- implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serialization_version"
- }
- }
- jvmTest {
- dependencies {
- implementation kotlin('test')
- implementation kotlin('test-junit')
- }
- }
- jsMain {
- dependencies {
- implementation kotlin('stdlib-js')
- implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:$serialization_version"
- }
- }
- jsTest {
- dependencies {
- implementation kotlin('test-js')
- }
- }
- nativeMain {
- dependsOn commonMain
- dependencies {
- implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version"
- }
- }
- nativeTest {
- dependsOn commonTest
- }
- configure([targets.linux, targets.ios]) {
- compilations.main.source(sourceSets.nativeMain)
- compilations.test.source(sourceSets.nativeTest)
- }
- }
-}
-
-configurations {
- compileClasspath
-}
diff --git a/taler-kotlin-common/src/commonMain/kotlin/net/taler/common/Amount.kt b/taler-kotlin-common/src/commonMain/kotlin/net/taler/common/Amount.kt
deleted file mode 100644
index 84d10c5..0000000
--- a/taler-kotlin-common/src/commonMain/kotlin/net/taler/common/Amount.kt
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * This file is part of GNU Taler
- * (C) 2020 Taler Systems S.A.
- *
- * GNU Taler is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 3, or (at your option) any later version.
- *
- * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-
-package net.taler.common
-
-import kotlinx.serialization.Decoder
-import kotlinx.serialization.Encoder
-import kotlinx.serialization.KSerializer
-import kotlinx.serialization.Serializable
-import kotlinx.serialization.Serializer
-import kotlin.math.floor
-import kotlin.math.pow
-import kotlin.math.roundToInt
-
-class AmountParserException(msg: String? = null, cause: Throwable? = null) : Exception(msg, cause)
-class AmountOverflowException(msg: String? = null, cause: Throwable? = null) : Exception(msg, cause)
-
-@Serializable(with = KotlinXAmountSerializer::class)
-data class Amount(
- /**
- * name of the currency using either a three-character ISO 4217 currency code,
- * or a regional currency identifier starting with a "*" followed by at most 10 characters.
- * ISO 4217 exponents in the name are not supported,
- * although the "fraction" is corresponds to an ISO 4217 exponent of 6.
- */
- val currency: String,
-
- /**
- * The integer part may be at most 2^52.
- * Note that "1" here would correspond to 1 EUR or 1 USD, depending on currency, not 1 cent.
- */
- val value: Long,
-
- /**
- * Unsigned 32 bit fractional value to be added to value representing
- * an additional currency fraction, in units of one hundred millionth (1e-8)
- * of the base currency value. For example, a fraction
- * of 50_000_000 would correspond to 50 cents.
- */
- val fraction: Int
-) : Comparable<Amount> {
-
- companion object {
-
- private const val FRACTIONAL_BASE: Int = 100000000 // 1e8
-
- private val REGEX_CURRENCY = Regex("""^[-_*A-Za-z0-9]{1,12}$""")
- val MAX_VALUE = 2.0.pow(52).toLong()
- private const val MAX_FRACTION_LENGTH = 8
- const val MAX_FRACTION = 99_999_999
-
- fun zero(currency: String): Amount {
- return Amount(checkCurrency(currency), 0, 0)
- }
-
- fun fromJSONString(str: String): Amount {
- val split = str.split(":")
- if (split.size != 2) throw AmountParserException("Invalid Amount Format")
- return fromString(split[0], split[1])
- }
-
- fun fromString(currency: String, str: String): Amount {
- // value
- val valueSplit = str.split(".")
- val value = checkValue(valueSplit[0].toLongOrNull())
- // fraction
- val fraction: Int = if (valueSplit.size > 1) {
- val fractionStr = valueSplit[1]
- if (fractionStr.length > MAX_FRACTION_LENGTH)
- throw AmountParserException("Fraction $fractionStr too long")
- val fraction = "0.$fractionStr".toDoubleOrNull()
- ?.times(FRACTIONAL_BASE)
- ?.roundToInt()
- checkFraction(fraction)
- } else 0
- return Amount(checkCurrency(currency), value, fraction)
- }
-
- fun min(currency: String): Amount = Amount(currency, 0, 1)
- fun max(currency: String): Amount = Amount(currency, MAX_VALUE, MAX_FRACTION)
-
-
- internal fun checkCurrency(currency: String): String {
- if (!REGEX_CURRENCY.matches(currency))
- throw AmountParserException("Invalid currency: $currency")
- return currency
- }
-
- internal fun checkValue(value: Long?): Long {
- if (value == null || value > MAX_VALUE)
- throw AmountParserException("Value $value greater than $MAX_VALUE")
- return value
- }
-
- internal fun checkFraction(fraction: Int?): Int {
- if (fraction == null || fraction > MAX_FRACTION)
- throw AmountParserException("Fraction $fraction greater than $MAX_FRACTION")
- return fraction
- }
-
- }
-
- val amountStr: String
- get() = if (fraction == 0) "$value" else {
- var f = fraction
- var fractionStr = ""
- while (f > 0) {
- fractionStr += f / (FRACTIONAL_BASE / 10)
- f = (f * 10) % FRACTIONAL_BASE
- }
- "$value.$fractionStr"
- }
-
- operator fun plus(other: Amount): Amount {
- check(currency == other.currency) { "Can only subtract from same currency" }
- val resultValue = value + other.value + floor((fraction + other.fraction).toDouble() / FRACTIONAL_BASE).toLong()
- if (resultValue > MAX_VALUE)
- throw AmountOverflowException()
- val resultFraction = (fraction + other.fraction) % FRACTIONAL_BASE
- return Amount(currency, resultValue, resultFraction)
- }
-
- operator fun times(factor: Int): Amount {
- // TODO consider replacing with a faster implementation
- if (factor == 0) return zero(currency)
- var result = this
- for (i in 1 until factor) result += this
- return result
- }
-
- operator fun minus(other: Amount): Amount {
- check(currency == other.currency) { "Can only subtract from same currency" }
- var resultValue = value
- var resultFraction = fraction
- if (resultFraction < other.fraction) {
- if (resultValue < 1L)
- throw AmountOverflowException()
- resultValue--
- resultFraction += FRACTIONAL_BASE
- }
- check(resultFraction >= other.fraction)
- resultFraction -= other.fraction
- if (resultValue < other.value)
- throw AmountOverflowException()
- resultValue -= other.value
- return Amount(currency, resultValue, resultFraction)
- }
-
- fun isZero(): Boolean {
- return value == 0L && fraction == 0
- }
-
- fun toJSONString(): String {
- return "$currency:$amountStr"
- }
-
- override fun toString(): String {
- return "$amountStr $currency"
- }
-
- override fun compareTo(other: Amount): Int {
- check(currency == other.currency) { "Can only compare amounts with the same currency" }
- when {
- value == other.value -> {
- if (fraction < other.fraction) return -1
- if (fraction > other.fraction) return 1
- return 0
- }
- value < other.value -> return -1
- else -> return 1
- }
- }
-
-}
-
-@Serializer(forClass = Amount::class)
-object KotlinXAmountSerializer: KSerializer<Amount> {
- override fun serialize(encoder: Encoder, value: Amount) {
- encoder.encodeString(value.toJSONString())
- }
-
- override fun deserialize(decoder: Decoder): Amount {
- return Amount.fromJSONString(decoder.decodeString())
- }
-}
diff --git a/taler-kotlin-common/src/commonMain/kotlin/net/taler/common/Time.kt b/taler-kotlin-common/src/commonMain/kotlin/net/taler/common/Time.kt
deleted file mode 100644
index 37b6606..0000000
--- a/taler-kotlin-common/src/commonMain/kotlin/net/taler/common/Time.kt
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * This file is part of GNU Taler
- * (C) 2020 Taler Systems S.A.
- *
- * GNU Taler is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 3, or (at your option) any later version.
- *
- * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-
-package net.taler.common
-
-import kotlinx.serialization.SerialName
-import kotlinx.serialization.Serializable
-import kotlinx.serialization.builtins.serializer
-import kotlinx.serialization.json.JsonElement
-import kotlinx.serialization.json.JsonPrimitive
-import kotlinx.serialization.json.JsonTransformingSerializer
-import kotlinx.serialization.json.contentOrNull
-import kotlinx.serialization.json.longOrNull
-import net.taler.common.Duration.Companion.FOREVER
-import kotlin.math.max
-
-expect fun nowMillis(): Long
-
-@Serializable
-data class Timestamp(
- @SerialName("t_ms")
- @Serializable(NeverSerializer::class)
- val ms: Long
-) : Comparable<Timestamp> {
-
- companion object {
- const val NEVER: Long = -1
- fun now(): Timestamp = Timestamp(nowMillis())
- }
-
- /**
- * Returns a copy of this [Timestamp] rounded to seconds.
- */
- fun truncateSeconds(): Timestamp {
- if (ms == NEVER) return Timestamp(ms)
- return Timestamp((ms / 1000L) * 1000L)
- }
-
- operator fun minus(other: Timestamp): Duration = when {
- ms == NEVER -> Duration(FOREVER)
- other.ms == NEVER -> throw Error("Invalid argument for timestamp comparision")
- ms < other.ms -> Duration(0)
- else -> Duration(ms - other.ms)
- }
-
- operator fun minus(other: Duration): Timestamp = when {
- ms == NEVER -> this
- other.ms == FOREVER -> Timestamp(0)
- else -> Timestamp(max(0, ms - other.ms))
- }
-
- override fun compareTo(other: Timestamp): Int {
- return if (ms == NEVER) {
- if (other.ms == NEVER) 0
- else 1
- } else {
- if (other.ms == NEVER) -1
- else ms.compareTo(other.ms)
- }
- }
-
-}
-
-@Serializable
-data class Duration(
- /**
- * Duration in milliseconds.
- */
- @SerialName("d_ms")
- @Serializable(ForeverSerializer::class)
- val ms: Long
-) {
- companion object {
- const val FOREVER: Long = -1
- }
-}
-
-abstract class MinusOneSerializer(private val keyword: String) :
- JsonTransformingSerializer<Long>(Long.serializer(), keyword) {
-
- override fun readTransform(element: JsonElement): JsonElement {
- return if (element.contentOrNull == keyword) return JsonPrimitive(-1)
- else super.readTransform(element)
- }
-
- override fun writeTransform(element: JsonElement): JsonElement {
- return if (element.longOrNull == -1L) return JsonPrimitive(keyword)
- else element
- }
-}
-
-object NeverSerializer : MinusOneSerializer("never")
-object ForeverSerializer : MinusOneSerializer("forever")
diff --git a/taler-kotlin-common/src/commonMain/kotlin/net/taler/common/Version.kt b/taler-kotlin-common/src/commonMain/kotlin/net/taler/common/Version.kt
deleted file mode 100644
index 8774115..0000000
--- a/taler-kotlin-common/src/commonMain/kotlin/net/taler/common/Version.kt
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * This file is part of GNU Taler
- * (C) 2020 Taler Systems S.A.
- *
- * GNU Taler is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 3, or (at your option) any later version.
- *
- * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-
-package net.taler.common
-
-import kotlin.math.sign
-
-/**
- * Semantic versioning, but libtool-style.
- * See https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html
- */
-data class Version(
- val current: Int,
- val revision: Int,
- val age: Int
-) {
- companion object {
- fun parse(v: String): Version? {
- val elements = v.split(":")
- if (elements.size != 3) return null
- val (currentStr, revisionStr, ageStr) = elements
- val current = currentStr.toIntOrNull()
- val revision = revisionStr.toIntOrNull()
- val age = ageStr.toIntOrNull()
- if (current == null || revision == null || age == null) return null
- return Version(current, revision, age)
- }
- }
-
- /**
- * Compare two libtool-style versions.
- *
- * Returns a [VersionMatchResult] or null if the given version was null.
- */
- fun compare(other: Version?): VersionMatchResult? {
- if (other == null) return null
- val compatible = current - age <= other.current &&
- current >= other.current - other.age
- val currentCmp = sign((current - other.current).toDouble()).toInt()
- return VersionMatchResult(compatible, currentCmp)
- }
-
- /**
- * Result of comparing two libtool versions.
- */
- data class VersionMatchResult(
- /**
- * Is the first version compatible with the second?
- */
- val compatible: Boolean,
- /**
- * Is the first version older (-1), newer (+1) or identical (0)?
- */
- val currentCmp: Int
- )
-
-}
diff --git a/taler-kotlin-common/src/commonTest/kotlin/net/taler/common/AmountTest.kt b/taler-kotlin-common/src/commonTest/kotlin/net/taler/common/AmountTest.kt
deleted file mode 100644
index e184307..0000000
--- a/taler-kotlin-common/src/commonTest/kotlin/net/taler/common/AmountTest.kt
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * This file is part of GNU Taler
- * (C) 2020 Taler Systems S.A.
- *
- * GNU Taler is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 3, or (at your option) any later version.
- *
- * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-
-package net.taler.common
-
-import kotlin.random.Random
-import kotlin.test.Test
-import kotlin.test.assertEquals
-import kotlin.test.assertFalse
-import kotlin.test.assertTrue
-import kotlin.test.fail
-
-class AmountTest {
-
- companion object {
- fun getRandomAmount() = getRandomAmount(getRandomString(1, Random.nextInt(1, 12)))
- fun getRandomAmount(currency: String): Amount {
- val value = Random.nextLong(0, Amount.MAX_VALUE)
- val fraction = Random.nextInt(0, Amount.MAX_FRACTION)
- return Amount(currency, value, fraction)
- }
- }
-
- @Test
- fun testFromJSONString() {
- var str = "TESTKUDOS:23.42"
- var amount = Amount.fromJSONString(str)
- assertEquals(str, amount.toJSONString())
- assertEquals("TESTKUDOS", amount.currency)
- assertEquals(23, amount.value)
- assertEquals((0.42 * 1e8).toInt(), amount.fraction)
- assertEquals("23.42 TESTKUDOS", amount.toString())
-
- str = "EUR:500000000.00000001"
- amount = Amount.fromJSONString(str)
- assertEquals(str, amount.toJSONString())
- assertEquals("EUR", amount.currency)
- assertEquals(500000000, amount.value)
- assertEquals(1, amount.fraction)
- assertEquals("500000000.00000001 EUR", amount.toString())
-
- str = "EUR:1500000000.00000003"
- amount = Amount.fromJSONString(str)
- assertEquals(str, amount.toJSONString())
- assertEquals("EUR", amount.currency)
- assertEquals(1500000000, amount.value)
- assertEquals(3, amount.fraction)
- assertEquals("1500000000.00000003 EUR", amount.toString())
- }
-
- @Test
- fun testFromJSONStringAcceptsMaxValuesRejectsAbove() {
- val maxValue = 4503599627370496
- val str = "TESTKUDOS123:$maxValue.99999999"
- val amount = Amount.fromJSONString(str)
- assertEquals(str, amount.toJSONString())
- assertEquals("TESTKUDOS123", amount.currency)
- assertEquals(maxValue, amount.value)
- assertEquals("$maxValue.99999999 TESTKUDOS123", amount.toString())
-
- // longer currency not accepted
- assertThrows<AmountParserException>("longer currency was accepted") {
- Amount.fromJSONString("TESTKUDOS1234:$maxValue.99999999")
- }
-
- // max value + 1 not accepted
- assertThrows<AmountParserException>("max value + 1 was accepted") {
- Amount.fromJSONString("TESTKUDOS123:${maxValue + 1}.99999999")
- }
-
- // max fraction + 1 not accepted
- assertThrows<AmountParserException>("max fraction + 1 was accepted") {
- Amount.fromJSONString("TESTKUDOS123:$maxValue.999999990")
- }
- }
-
- @Test
- fun testFromJSONStringRejections() {
- assertThrows<AmountParserException> {
- Amount.fromJSONString("TESTKUDOS:0,5")
- }
- assertThrows<AmountParserException> {
- Amount.fromJSONString("+TESTKUDOS:0.5")
- }
- assertThrows<AmountParserException> {
- Amount.fromJSONString("0.5")
- }
- assertThrows<AmountParserException> {
- Amount.fromJSONString(":0.5")
- }
- assertThrows<AmountParserException> {
- Amount.fromJSONString("EUR::0.5")
- }
- assertThrows<AmountParserException> {
- Amount.fromJSONString("EUR:.5")
- }
- }
-
- @Test
- fun testAddition() {
- assertEquals(
- Amount.fromJSONString("EUR:2"),
- Amount.fromJSONString("EUR:1") + Amount.fromJSONString("EUR:1")
- )
- assertEquals(
- Amount.fromJSONString("EUR:3"),
- Amount.fromJSONString("EUR:1.5") + Amount.fromJSONString("EUR:1.5")
- )
- assertEquals(
- Amount.fromJSONString("EUR:500000000.00000002"),
- Amount.fromJSONString("EUR:500000000.00000001") + Amount.fromJSONString("EUR:0.00000001")
- )
- assertThrows<AmountOverflowException>("addition didn't overflow") {
- Amount.fromJSONString("EUR:4503599627370496.99999999") + Amount.fromJSONString("EUR:0.00000001")
- }
- assertThrows<AmountOverflowException>("addition didn't overflow") {
- Amount.fromJSONString("EUR:4000000000000000") + Amount.fromJSONString("EUR:4000000000000000")
- }
- }
-
- @Test
- fun testTimes() {
- assertEquals(
- Amount.fromJSONString("EUR:2"),
- Amount.fromJSONString("EUR:2") * 1
- )
- assertEquals(
- Amount.fromJSONString("EUR:2"),
- Amount.fromJSONString("EUR:1") * 2
- )
- assertEquals(
- Amount.fromJSONString("EUR:4.5"),
- Amount.fromJSONString("EUR:1.5") * 3
- )
- assertEquals(Amount.fromJSONString("EUR:0"), Amount.fromJSONString("EUR:1.11") * 0)
- assertEquals(Amount.fromJSONString("EUR:1.11"), Amount.fromJSONString("EUR:1.11") * 1)
- assertEquals(Amount.fromJSONString("EUR:2.22"), Amount.fromJSONString("EUR:1.11") * 2)
- assertEquals(Amount.fromJSONString("EUR:3.33"), Amount.fromJSONString("EUR:1.11") * 3)
- assertEquals(Amount.fromJSONString("EUR:4.44"), Amount.fromJSONString("EUR:1.11") * 4)
- assertEquals(Amount.fromJSONString("EUR:5.55"), Amount.fromJSONString("EUR:1.11") * 5)
- assertEquals(
- Amount.fromJSONString("EUR:1500000000.00000003"),
- Amount.fromJSONString("EUR:500000000.00000001") * 3
- )
- assertThrows<AmountOverflowException>("times didn't overflow") {
- Amount.fromJSONString("EUR:4000000000000000") * 2
- }
- }
-
- @Test
- fun testSubtraction() {
- assertEquals(
- Amount.fromJSONString("EUR:0"),
- Amount.fromJSONString("EUR:1") - Amount.fromJSONString("EUR:1")
- )
- assertEquals(
- Amount.fromJSONString("EUR:1.5"),
- Amount.fromJSONString("EUR:3") - Amount.fromJSONString("EUR:1.5")
- )
- assertEquals(
- Amount.fromJSONString("EUR:500000000.00000001"),
- Amount.fromJSONString("EUR:500000000.00000002") - Amount.fromJSONString("EUR:0.00000001")
- )
- assertThrows<AmountOverflowException>("subtraction didn't underflow") {
- Amount.fromJSONString("EUR:23.42") - Amount.fromJSONString("EUR:42.23")
- }
- assertThrows<AmountOverflowException>("subtraction didn't underflow") {
- Amount.fromJSONString("EUR:0.5") - Amount.fromJSONString("EUR:0.50000001")
- }
- }
-
- @Test
- fun testIsZero() {
- assertTrue(Amount.zero("EUR").isZero())
- assertTrue(Amount.fromJSONString("EUR:0").isZero())
- assertTrue(Amount.fromJSONString("EUR:0.0").isZero())
- assertTrue(Amount.fromJSONString("EUR:0.00000").isZero())
- assertTrue((Amount.fromJSONString("EUR:1.001") - Amount.fromJSONString("EUR:1.001")).isZero())
-
- assertFalse(Amount.fromJSONString("EUR:0.00000001").isZero())
- assertFalse(Amount.fromJSONString("EUR:1.0").isZero())
- assertFalse(Amount.fromJSONString("EUR:0001.0").isZero())
- }
-
- @Test
- fun testComparision() {
- assertTrue(Amount.fromJSONString("EUR:0") <= Amount.fromJSONString("EUR:0"))
- assertTrue(Amount.fromJSONString("EUR:0") <= Amount.fromJSONString("EUR:0.00000001"))
- assertTrue(Amount.fromJSONString("EUR:0") < Amount.fromJSONString("EUR:0.00000001"))
- assertTrue(Amount.fromJSONString("EUR:0") < Amount.fromJSONString("EUR:1"))
- assertEquals(Amount.fromJSONString("EUR:0"), Amount.fromJSONString("EUR:0"))
- assertEquals(Amount.fromJSONString("EUR:42"), Amount.fromJSONString("EUR:42"))
- assertEquals(
- Amount.fromJSONString("EUR:42.00000001"),
- Amount.fromJSONString("EUR:42.00000001")
- )
- assertTrue(Amount.fromJSONString("EUR:42.00000001") >= Amount.fromJSONString("EUR:42.00000001"))
- assertTrue(Amount.fromJSONString("EUR:42.00000002") >= Amount.fromJSONString("EUR:42.00000001"))
- assertTrue(Amount.fromJSONString("EUR:42.00000002") > Amount.fromJSONString("EUR:42.00000001"))
- assertTrue(Amount.fromJSONString("EUR:0.00000002") > Amount.fromJSONString("EUR:0.00000001"))
- assertTrue(Amount.fromJSONString("EUR:0.00000001") > Amount.fromJSONString("EUR:0"))
- assertTrue(Amount.fromJSONString("EUR:2") > Amount.fromJSONString("EUR:1"))
-
- assertThrows<IllegalStateException>("could compare amounts with different currencies") {
- Amount.fromJSONString("EUR:0.5") < Amount.fromJSONString("USD:0.50000001")
- }
- }
-
- private inline fun <reified T : Throwable> assertThrows(
- msg: String? = null,
- function: () -> Any
- ) {
- try {
- function.invoke()
- fail(msg)
- } catch (e: Exception) {
- assertTrue(e is T)
- }
- }
-
-}
diff --git a/taler-kotlin-common/src/commonTest/kotlin/net/taler/common/TestUtils.kt b/taler-kotlin-common/src/commonTest/kotlin/net/taler/common/TestUtils.kt
deleted file mode 100644
index e3a6c17..0000000
--- a/taler-kotlin-common/src/commonTest/kotlin/net/taler/common/TestUtils.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * This file is part of GNU Taler
- * (C) 2020 Taler Systems S.A.
- *
- * GNU Taler is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 3, or (at your option) any later version.
- *
- * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-
-package net.taler.common
-
-import kotlin.random.Random
-
-private val charPool: List<Char> = ('a'..'z') + ('A'..'Z') + ('0'..'9')
-fun getRandomString(minLength: Int = 1, maxLength: Int = Random.nextInt(0, 1337)) =
- (minLength..maxLength)
- .map { Random.nextInt(0, charPool.size) }
- .map(charPool::get)
- .joinToString("")
diff --git a/taler-kotlin-common/src/commonTest/kotlin/net/taler/common/TimeTest.kt b/taler-kotlin-common/src/commonTest/kotlin/net/taler/common/TimeTest.kt
deleted file mode 100644
index 3ee0a99..0000000
--- a/taler-kotlin-common/src/commonTest/kotlin/net/taler/common/TimeTest.kt
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * This file is part of GNU Taler
- * (C) 2020 Taler Systems S.A.
- *
- * GNU Taler is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 3, or (at your option) any later version.
- *
- * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-
-package net.taler.common
-
-import kotlinx.serialization.UnstableDefault
-import kotlinx.serialization.json.Json.Default.parse
-import kotlinx.serialization.json.Json.Default.stringify
-import net.taler.common.Timestamp.Companion.NEVER
-import kotlin.random.Random
-import kotlin.test.Test
-import kotlin.test.assertEquals
-
-// TODO test other functionality of Timestamp and Duration
-@UnstableDefault
-class TimeTest {
-
- @Test
- fun testSerialize() {
- for (i in 0 until 42) {
- val t = Random.nextLong()
- assertEquals("""{"t_ms":$t}""", stringify(Timestamp.serializer(), Timestamp(t)))
- }
- assertEquals("""{"t_ms":"never"}""", stringify(Timestamp.serializer(), Timestamp(NEVER)))
- }
-
- @Test
- fun testDeserialize() {
- for (i in 0 until 42) {
- val t = Random.nextLong()
- assertEquals(Timestamp(t), parse(Timestamp.serializer(), """{ "t_ms": $t }"""))
- }
- assertEquals(Timestamp(NEVER), parse(Timestamp.serializer(), """{ "t_ms": "never" }"""))
- }
-
-}
diff --git a/taler-kotlin-common/src/commonTest/kotlin/net/taler/common/VersionTest.kt b/taler-kotlin-common/src/commonTest/kotlin/net/taler/common/VersionTest.kt
deleted file mode 100644
index f4f17ea..0000000
--- a/taler-kotlin-common/src/commonTest/kotlin/net/taler/common/VersionTest.kt
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * This file is part of GNU Taler
- * (C) 2020 Taler Systems S.A.
- *
- * GNU Taler is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 3, or (at your option) any later version.
- *
- * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-
-package net.taler.common
-
-import kotlin.test.Test
-import kotlin.test.assertEquals
-import kotlin.test.assertNull
-
-class VersionTest {
-
- @Test
- fun testParse() {
- assertNull(Version.parse(""))
- assertNull(Version.parse("foo"))
- assertNull(Version.parse("foo:bar:foo"))
- assertNull(Version.parse("0:0:0:"))
- assertNull(Version.parse("0:0:"))
- assertEquals(Version(0, 0, 0), Version.parse("0:0:0"))
- assertEquals(Version(1, 2, 3), Version.parse("1:2:3"))
- assertEquals(Version(1337, 42, 23), Version.parse("1337:42:23"))
- }
-
- @Test
- fun testComparision() {
- assertEquals(
- Version.VersionMatchResult(true, 0),
- Version.parse("0:0:0")!!.compare(Version.parse("0:0:0"))
- )
- assertEquals(
- Version.VersionMatchResult(true, -1),
- Version.parse("0:0:0")!!.compare(Version.parse("1:0:1"))
- )
- assertEquals(
- Version.VersionMatchResult(true, -1),
- Version.parse("0:0:0")!!.compare(Version.parse("1:5:1"))
- )
- assertEquals(
- Version.VersionMatchResult(false, -1),
- Version.parse("0:0:0")!!.compare(Version.parse("1:5:0"))
- )
- assertEquals(
- Version.VersionMatchResult(false, 1),
- Version.parse("1:0:0")!!.compare(Version.parse("0:5:0"))
- )
- assertEquals(
- Version.VersionMatchResult(true, 0),
- Version.parse("1:0:1")!!.compare(Version.parse("1:5:1"))
- )
- }
-
-}
diff --git a/taler-kotlin-common/src/jsMain/kotlin/net/taler/common/Time.kt b/taler-kotlin-common/src/jsMain/kotlin/net/taler/common/Time.kt
deleted file mode 100644
index b114022..0000000
--- a/taler-kotlin-common/src/jsMain/kotlin/net/taler/common/Time.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * This file is part of GNU Taler
- * (C) 2020 Taler Systems S.A.
- *
- * GNU Taler is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 3, or (at your option) any later version.
- *
- * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-
-package net.taler.common
-
-import kotlin.js.Date
-
-actual fun nowMillis(): Long {
- return Date().getMilliseconds().toLong()
-}
diff --git a/taler-kotlin-common/src/jvmMain/kotlin/net/taler/common/Time.kt b/taler-kotlin-common/src/jvmMain/kotlin/net/taler/common/Time.kt
deleted file mode 100644
index 6cd9040..0000000
--- a/taler-kotlin-common/src/jvmMain/kotlin/net/taler/common/Time.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * This file is part of GNU Taler
- * (C) 2020 Taler Systems S.A.
- *
- * GNU Taler is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 3, or (at your option) any later version.
- *
- * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-
-package net.taler.common
-
-actual fun nowMillis(): Long {
- return System.currentTimeMillis()
-}
diff --git a/taler-kotlin-common/src/nativeMain/kotlin/net/taler/common/Time.kt b/taler-kotlin-common/src/nativeMain/kotlin/net/taler/common/Time.kt
deleted file mode 100644
index 8a4091a..0000000
--- a/taler-kotlin-common/src/nativeMain/kotlin/net/taler/common/Time.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * This file is part of GNU Taler
- * (C) 2020 Taler Systems S.A.
- *
- * GNU Taler is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 3, or (at your option) any later version.
- *
- * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-
-package net.taler.common
-
-import kotlin.system.getTimeMillis
-
-actual fun nowMillis(): Long {
- return getTimeMillis()
-}