diff options
59 files changed, 90 insertions, 961 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6dc4426..1e90ba7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -13,7 +13,6 @@ include: - local: 'cashier/.gitlab-ci.yml' - local: 'merchant-lib/.gitlab-ci.yml' - local: 'merchant-terminal/.gitlab-ci.yml' - - local: 'taler-kotlin-common/.gitlab-ci.yml' - local: 'taler-kotlin-android/.gitlab-ci.yml' - local: 'wallet/.gitlab-ci.yml' diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..7171b3d --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "wallet-kotlin"] + path = wallet-kotlin + url = git://git.taler.net/wallet-kotlin.git diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 40ed937..2b48706 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -11,5 +11,9 @@ <entry name="!?*.kt" /> <entry name="!?*.clj" /> </wildcardResourcePatterns> + <bytecodeTargetLevel> + <module name="taler-kotlin-common_jvmMain" target="1.6" /> + <module name="taler-kotlin-common_jvmTest" target="1.6" /> + </bytecodeTargetLevel> </component> </project>
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 01ed15f..25f810e 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -15,8 +15,9 @@ <option value="$PROJECT_DIR$/merchant-lib" /> <option value="$PROJECT_DIR$/merchant-terminal" /> <option value="$PROJECT_DIR$/taler-kotlin-android" /> - <option value="$PROJECT_DIR$/taler-kotlin-common" /> <option value="$PROJECT_DIR$/wallet" /> + <option value="$PROJECT_DIR$/wallet-kotlin" /> + <option value="$PROJECT_DIR$/wallet-kotlin/common" /> </set> </option> <option name="resolveModulePerSourceSet" value="false" /> diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml index eb2873e..1e2d92c 100644 --- a/.idea/jarRepositories.xml +++ b/.idea/jarRepositories.xml @@ -26,5 +26,10 @@ <option name="name" value="Google" /> <option name="url" value="https://dl.google.com/dl/android/maven2/" /> </remote-repository> + <remote-repository> + <option name="id" value="MavenRepo" /> + <option name="name" value="MavenRepo" /> + <option name="url" value="https://repo.maven.apache.org/maven2/" /> + </remote-repository> </component> </project>
\ No newline at end of file diff --git a/anastasis-ui/src/main/java/org/gnu/anastasis/ui/authentication/AuthenticationFragment.kt b/anastasis-ui/src/main/java/org/gnu/anastasis/ui/authentication/AuthenticationFragment.kt index 607917d..fd770cb 100644 --- a/anastasis-ui/src/main/java/org/gnu/anastasis/ui/authentication/AuthenticationFragment.kt +++ b/anastasis-ui/src/main/java/org/gnu/anastasis/ui/authentication/AuthenticationFragment.kt @@ -31,7 +31,7 @@ import androidx.navigation.fragment.FragmentNavigatorExtras import androidx.navigation.fragment.findNavController import com.google.android.material.card.MaterialCardView import kotlinx.android.synthetic.main.fragment_authentication.* -import net.taler.common.Amount +import net.taler.lib.common.Amount import org.gnu.anastasis.ui.MainViewModel import org.gnu.anastasis.ui.R @@ -42,7 +42,8 @@ class AuthenticationFragment : Fragment() { private var price: Amount = Amount.zero("KUDOS") override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, + inflater: LayoutInflater, + container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.fragment_authentication, container, false) diff --git a/bootstrap b/bootstrap new file mode 100755 index 0000000..1b71b37 --- /dev/null +++ b/bootstrap @@ -0,0 +1,14 @@ +#!/bin/sh + +# Bootstrap the repository. Used when the repository is checked out from git. +# When using the source tarball, running this script is not necessary. + +set -eu + +if ! git --version >/dev/null; then + echo "git not installed" + exit 1 +fi + +git submodule update --init + diff --git a/cashier/src/main/java/net/taler/cashier/BalanceFragment.kt b/cashier/src/main/java/net/taler/cashier/BalanceFragment.kt index 246cba0..5b963a0 100644 --- a/cashier/src/main/java/net/taler/cashier/BalanceFragment.kt +++ b/cashier/src/main/java/net/taler/cashier/BalanceFragment.kt @@ -33,11 +33,11 @@ import kotlinx.android.synthetic.main.fragment_balance.* import net.taler.cashier.BalanceFragmentDirections.Companion.actionBalanceFragmentToTransactionFragment import net.taler.cashier.withdraw.LastTransaction import net.taler.cashier.withdraw.WithdrawStatus -import net.taler.common.Amount import net.taler.common.SignedAmount import net.taler.common.exhaustive import net.taler.common.fadeIn import net.taler.common.fadeOut +import net.taler.lib.common.Amount sealed class BalanceResult { class Error(val msg: String) : BalanceResult() diff --git a/cashier/src/main/java/net/taler/cashier/MainViewModel.kt b/cashier/src/main/java/net/taler/cashier/MainViewModel.kt index 1740494..a0796df 100644 --- a/cashier/src/main/java/net/taler/cashier/MainViewModel.kt +++ b/cashier/src/main/java/net/taler/cashier/MainViewModel.kt @@ -34,11 +34,11 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import net.taler.cashier.HttpHelper.makeJsonGetRequest import net.taler.cashier.withdraw.WithdrawManager -import net.taler.common.AmountParserException import net.taler.common.SignedAmount -import net.taler.common.Version import net.taler.common.getIncompatibleStringOrNull import net.taler.common.isOnline +import net.taler.lib.common.AmountParserException +import net.taler.lib.common.Version private val TAG = MainViewModel::class.java.simpleName diff --git a/cashier/src/main/java/net/taler/cashier/withdraw/WithdrawManager.kt b/cashier/src/main/java/net/taler/cashier/withdraw/WithdrawManager.kt index 59e0c50..9f3cf54 100644 --- a/cashier/src/main/java/net/taler/cashier/withdraw/WithdrawManager.kt +++ b/cashier/src/main/java/net/taler/cashier/withdraw/WithdrawManager.kt @@ -34,9 +34,9 @@ import net.taler.cashier.HttpJsonResult.Error import net.taler.cashier.HttpJsonResult.Success import net.taler.cashier.MainViewModel import net.taler.cashier.R -import net.taler.common.Amount import net.taler.common.QrCodeManager.makeQrCode import net.taler.common.isOnline +import net.taler.lib.common.Amount import org.json.JSONObject import java.util.concurrent.TimeUnit.MINUTES import java.util.concurrent.TimeUnit.SECONDS diff --git a/merchant-lib/src/main/java/net/taler/merchantlib/OrderHistory.kt b/merchant-lib/src/main/java/net/taler/merchantlib/OrderHistory.kt index b1ff5b1..dfd989b 100644 --- a/merchant-lib/src/main/java/net/taler/merchantlib/OrderHistory.kt +++ b/merchant-lib/src/main/java/net/taler/merchantlib/OrderHistory.kt @@ -18,8 +18,8 @@ package net.taler.merchantlib import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import net.taler.common.Amount -import net.taler.common.Timestamp +import net.taler.lib.common.Amount +import net.taler.lib.common.Timestamp @Serializable data class OrderHistory( diff --git a/merchant-lib/src/main/java/net/taler/merchantlib/Orders.kt b/merchant-lib/src/main/java/net/taler/merchantlib/Orders.kt index 783dd19..0a405ad 100644 --- a/merchant-lib/src/main/java/net/taler/merchantlib/Orders.kt +++ b/merchant-lib/src/main/java/net/taler/merchantlib/Orders.kt @@ -25,7 +25,7 @@ import kotlinx.serialization.Serializer import kotlinx.serialization.json.JsonInput import kotlinx.serialization.json.JsonObject import net.taler.common.ContractTerms -import net.taler.common.Duration +import net.taler.lib.common.Duration @Serializable data class PostOrderRequest( diff --git a/merchant-lib/src/main/java/net/taler/merchantlib/Refunds.kt b/merchant-lib/src/main/java/net/taler/merchantlib/Refunds.kt index 61f0ab7..b78b571 100644 --- a/merchant-lib/src/main/java/net/taler/merchantlib/Refunds.kt +++ b/merchant-lib/src/main/java/net/taler/merchantlib/Refunds.kt @@ -18,7 +18,7 @@ package net.taler.merchantlib import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import net.taler.common.Amount +import net.taler.lib.common.Amount @Serializable data class RefundRequest( diff --git a/merchant-lib/src/test/java/net/taler/merchantlib/MerchantApiTest.kt b/merchant-lib/src/test/java/net/taler/merchantlib/MerchantApiTest.kt index 992af6f..1e6a634 100644 --- a/merchant-lib/src/test/java/net/taler/merchantlib/MerchantApiTest.kt +++ b/merchant-lib/src/test/java/net/taler/merchantlib/MerchantApiTest.kt @@ -20,10 +20,10 @@ import io.ktor.http.HttpStatusCode.Companion.NotFound import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestCoroutineDispatcher import kotlinx.coroutines.test.runBlockingTest -import net.taler.common.Amount import net.taler.common.ContractProduct import net.taler.common.ContractTerms -import net.taler.common.Timestamp +import net.taler.lib.common.Amount +import net.taler.lib.common.Timestamp import net.taler.merchantlib.MockHttpClient.giveJsonResponse import net.taler.merchantlib.MockHttpClient.httpClient import org.junit.Assert.assertEquals diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigManager.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigManager.kt index 67e3685..23abe7d 100644 --- a/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigManager.kt +++ b/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigManager.kt @@ -34,8 +34,8 @@ import io.ktor.http.HttpStatusCode.Companion.Unauthorized import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import net.taler.common.Version import net.taler.common.getIncompatibleStringOrNull +import net.taler.lib.common.Version import net.taler.merchantlib.ConfigResponse import net.taler.merchantlib.MerchantApi import net.taler.merchantlib.MerchantConfig diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/config/PosConfig.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/config/PosConfig.kt index 2d8c040..cc8caf6 100644 --- a/merchant-terminal/src/main/java/net/taler/merchantpos/config/PosConfig.kt +++ b/merchant-terminal/src/main/java/net/taler/merchantpos/config/PosConfig.kt @@ -18,10 +18,10 @@ package net.taler.merchantpos.config import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import net.taler.common.Amount import net.taler.common.ContractProduct import net.taler.common.Product import net.taler.common.TalerUtils +import net.taler.lib.common.Amount import java.util.UUID data class Config( diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/order/LiveOrder.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/order/LiveOrder.kt index a77e39b..738e32b 100644 --- a/merchant-terminal/src/main/java/net/taler/merchantpos/order/LiveOrder.kt +++ b/merchant-terminal/src/main/java/net/taler/merchantpos/order/LiveOrder.kt @@ -20,8 +20,8 @@ import androidx.annotation.UiThread import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.Transformations -import net.taler.common.Amount import net.taler.common.CombinedLiveData +import net.taler.lib.common.Amount import net.taler.merchantpos.config.Category import net.taler.merchantpos.config.ConfigProduct import net.taler.merchantpos.order.RestartState.DISABLED diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/order/Order.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/order/Order.kt index 4053d4b..4fc2907 100644 --- a/merchant-terminal/src/main/java/net/taler/merchantpos/order/Order.kt +++ b/merchant-terminal/src/main/java/net/taler/merchantpos/order/Order.kt @@ -16,10 +16,10 @@ package net.taler.merchantpos.order -import net.taler.common.Amount import net.taler.common.ContractTerms -import net.taler.common.Timestamp import net.taler.common.now +import net.taler.lib.common.Amount +import net.taler.lib.common.Timestamp import net.taler.merchantpos.config.Category import net.taler.merchantpos.config.ConfigProduct import java.net.URLEncoder diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/payment/PaymentManager.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/payment/PaymentManager.kt index b39355a..af340f1 100644 --- a/merchant-terminal/src/main/java/net/taler/merchantpos/payment/PaymentManager.kt +++ b/merchant-terminal/src/main/java/net/taler/merchantpos/payment/PaymentManager.kt @@ -26,8 +26,8 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.isActive import kotlinx.coroutines.launch -import net.taler.common.Duration import net.taler.common.assertUiThread +import net.taler.lib.common.Duration import net.taler.merchantlib.CheckPaymentResponse import net.taler.merchantlib.MerchantApi import net.taler.merchantlib.PostOrderRequest diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/refund/RefundFragment.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/refund/RefundFragment.kt index edb2758..752b7aa 100644 --- a/merchant-terminal/src/main/java/net/taler/merchantpos/refund/RefundFragment.kt +++ b/merchant-terminal/src/main/java/net/taler/merchantpos/refund/RefundFragment.kt @@ -27,11 +27,11 @@ import androidx.navigation.fragment.findNavController import com.google.android.material.snackbar.BaseTransientBottomBar.LENGTH_LONG import com.google.android.material.snackbar.Snackbar import kotlinx.android.synthetic.main.fragment_refund.* -import net.taler.common.Amount -import net.taler.common.AmountParserException import net.taler.common.fadeIn import net.taler.common.fadeOut import net.taler.common.navigate +import net.taler.lib.common.Amount +import net.taler.lib.common.AmountParserException import net.taler.merchantlib.OrderHistoryEntry import net.taler.merchantpos.MainViewModel import net.taler.merchantpos.R diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/refund/RefundManager.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/refund/RefundManager.kt index 25c7c5e..de6cdde 100644 --- a/merchant-terminal/src/main/java/net/taler/merchantpos/refund/RefundManager.kt +++ b/merchant-terminal/src/main/java/net/taler/merchantpos/refund/RefundManager.kt @@ -21,8 +21,8 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch -import net.taler.common.Amount import net.taler.common.assertUiThread +import net.taler.lib.common.Amount import net.taler.merchantlib.MerchantApi import net.taler.merchantlib.OrderHistoryEntry import net.taler.merchantlib.RefundRequest diff --git a/merchant-terminal/src/test/java/net/taler/merchantpos/order/OrderManagerTest.kt b/merchant-terminal/src/test/java/net/taler/merchantpos/order/OrderManagerTest.kt index bb8dcb7..ca48b6e 100644 --- a/merchant-terminal/src/test/java/net/taler/merchantpos/order/OrderManagerTest.kt +++ b/merchant-terminal/src/test/java/net/taler/merchantpos/order/OrderManagerTest.kt @@ -20,7 +20,7 @@ import android.app.Application import androidx.test.core.app.ApplicationProvider.getApplicationContext import androidx.test.ext.junit.runners.AndroidJUnit4 import kotlinx.coroutines.runBlocking -import net.taler.common.Amount +import net.taler.lib.common.Amount import net.taler.merchantlib.MerchantConfig import net.taler.merchantpos.R import net.taler.merchantpos.config.Category diff --git a/settings.gradle b/settings.gradle index 2240bc2..1e16e26 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,7 +1,5 @@ -enableFeaturePreview('GRADLE_METADATA') - +include ':wallet-kotlin:common' include ':cashier', ':merchant-terminal', ':wallet' -include ':taler-kotlin-common' include ':taler-kotlin-android' include ':merchant-lib' include ':anastasis-ui' diff --git a/taler-kotlin-android/build.gradle b/taler-kotlin-android/build.gradle index 20590e0..e6a376c 100644 --- a/taler-kotlin-android/build.gradle +++ b/taler-kotlin-android/build.gradle @@ -50,7 +50,7 @@ android { } dependencies { - api project(":taler-kotlin-common") + api project(":wallet-kotlin:common") implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" implementation 'androidx.appcompat:appcompat:1.2.0' diff --git a/taler-kotlin-android/src/main/java/net/taler/common/AndroidUtils.kt b/taler-kotlin-android/src/main/java/net/taler/common/AndroidUtils.kt index b46f306..ceb5ead 100644 --- a/taler-kotlin-android/src/main/java/net/taler/common/AndroidUtils.kt +++ b/taler-kotlin-android/src/main/java/net/taler/common/AndroidUtils.kt @@ -43,6 +43,7 @@ import androidx.core.content.ContextCompat.getSystemService import androidx.fragment.app.Fragment import androidx.navigation.NavDirections import androidx.navigation.fragment.findNavController +import net.taler.lib.common.Version fun View.fadeIn(endAction: () -> Unit = {}) { if (visibility == VISIBLE && alpha == 1f) return diff --git a/taler-kotlin-android/src/main/java/net/taler/common/ContractTerms.kt b/taler-kotlin-android/src/main/java/net/taler/common/ContractTerms.kt index ab442f2..8bf77e8 100644 --- a/taler-kotlin-android/src/main/java/net/taler/common/ContractTerms.kt +++ b/taler-kotlin-android/src/main/java/net/taler/common/ContractTerms.kt @@ -24,6 +24,8 @@ import com.fasterxml.jackson.annotation.JsonProperty import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import net.taler.common.TalerUtils.getLocalizedString +import net.taler.lib.common.Amount +import net.taler.lib.common.Timestamp @Serializable data class ContractTerms( diff --git a/taler-kotlin-android/src/main/java/net/taler/common/SignedAmount.kt b/taler-kotlin-android/src/main/java/net/taler/common/SignedAmount.kt index 03a0d6e..e95685a 100644 --- a/taler-kotlin-android/src/main/java/net/taler/common/SignedAmount.kt +++ b/taler-kotlin-android/src/main/java/net/taler/common/SignedAmount.kt @@ -17,6 +17,8 @@ package net.taler.common import android.annotation.SuppressLint +import net.taler.lib.common.Amount +import net.taler.lib.common.AmountParserException data class SignedAmount( val positive: Boolean, @@ -37,4 +39,4 @@ data class SignedAmount( return if (positive) "$amount" else "-$amount" } -}
\ No newline at end of file +} diff --git a/taler-kotlin-android/src/main/java/net/taler/common/AmountMixin.kt b/taler-kotlin-android/src/main/java/net/taler/lib/common/AmountMixin.kt index f9b1330..59285b6 100644 --- a/taler-kotlin-android/src/main/java/net/taler/common/AmountMixin.kt +++ b/taler-kotlin-android/src/main/java/net/taler/lib/common/AmountMixin.kt @@ -14,7 +14,7 @@ * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -package net.taler.common +package net.taler.lib.common import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.JsonParser diff --git a/taler-kotlin-android/src/main/java/net/taler/common/TimestampMixin.kt b/taler-kotlin-android/src/main/java/net/taler/lib/common/TimestampMixin.kt index 6c1bebf..40c03f6 100644 --- a/taler-kotlin-android/src/main/java/net/taler/common/TimestampMixin.kt +++ b/taler-kotlin-android/src/main/java/net/taler/lib/common/TimestampMixin.kt @@ -14,7 +14,7 @@ * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -package net.taler.common +package net.taler.lib.common import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.core.JsonParser diff --git a/taler-kotlin-android/src/test/java/net/taler/common/ContractTermsTest.kt b/taler-kotlin-android/src/test/java/net/taler/common/ContractTermsTest.kt index 077ff51..62e8922 100644 --- a/taler-kotlin-android/src/test/java/net/taler/common/ContractTermsTest.kt +++ b/taler-kotlin-android/src/test/java/net/taler/common/ContractTermsTest.kt @@ -20,7 +20,11 @@ import com.fasterxml.jackson.databind.DeserializationFeature import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.kotlin.KotlinModule import com.fasterxml.jackson.module.kotlin.readValue -import net.taler.common.Timestamp.Companion.NEVER +import net.taler.lib.common.Amount +import net.taler.lib.common.AmountMixin +import net.taler.lib.common.Timestamp +import net.taler.lib.common.Timestamp.Companion.NEVER +import net.taler.lib.common.TimestampMixin import org.junit.Assert.assertEquals import org.junit.Test 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() -} diff --git a/wallet-kotlin b/wallet-kotlin new file mode 160000 +Subproject dade0470c7e378c72ac2f2fd2a623416dadbff1 diff --git a/wallet/build.gradle b/wallet/build.gradle index 4b204ec..af15619 100644 --- a/wallet/build.gradle +++ b/wallet/build.gradle @@ -124,7 +124,7 @@ dependencies { implementation 'me.zhanghai.android.materialprogressbar:library:1.6.1' // Markdown rendering - final def markwon_version = '4.3.1' + final def markwon_version = '4.5.1' implementation "io.noties.markwon:core:$markwon_version" implementation "io.noties.markwon:ext-tables:$markwon_version" implementation "io.noties.markwon:recycler:$markwon_version" @@ -133,7 +133,7 @@ dependencies { implementation 'com.fasterxml.jackson.module:jackson-module-kotlin:2.10.2' testImplementation 'junit:junit:4.13' - testImplementation 'org.json:json:20190722' + testImplementation 'org.json:json:20200518' androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' } diff --git a/wallet/src/main/java/net/taler/wallet/MainViewModel.kt b/wallet/src/main/java/net/taler/wallet/MainViewModel.kt index b4aa1dc..3fc49a9 100644 --- a/wallet/src/main/java/net/taler/wallet/MainViewModel.kt +++ b/wallet/src/main/java/net/taler/wallet/MainViewModel.kt @@ -29,13 +29,13 @@ import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.kotlin.KotlinModule import kotlinx.coroutines.Job import kotlinx.coroutines.launch -import net.taler.common.Amount -import net.taler.common.AmountMixin import net.taler.common.Event -import net.taler.common.Timestamp -import net.taler.common.TimestampMixin import net.taler.common.assertUiThread import net.taler.common.toEvent +import net.taler.lib.common.Amount +import net.taler.lib.common.AmountMixin +import net.taler.lib.common.Timestamp +import net.taler.lib.common.TimestampMixin import net.taler.wallet.backend.WalletBackendApi import net.taler.wallet.balances.BalanceItem import net.taler.wallet.balances.BalanceResponse diff --git a/wallet/src/main/java/net/taler/wallet/balances/BalanceAdapter.kt b/wallet/src/main/java/net/taler/wallet/balances/BalanceAdapter.kt index 24ee1a1..09ae353 100644 --- a/wallet/src/main/java/net/taler/wallet/balances/BalanceAdapter.kt +++ b/wallet/src/main/java/net/taler/wallet/balances/BalanceAdapter.kt @@ -25,7 +25,7 @@ import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView.Adapter import kotlinx.serialization.Serializable -import net.taler.common.Amount +import net.taler.lib.common.Amount import net.taler.wallet.R import net.taler.wallet.balances.BalanceAdapter.BalanceViewHolder diff --git a/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeFees.kt b/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeFees.kt index a026283..1da9b49 100644 --- a/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeFees.kt +++ b/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeFees.kt @@ -16,8 +16,8 @@ package net.taler.wallet.exchanges -import net.taler.common.Amount -import net.taler.common.Timestamp +import net.taler.lib.common.Amount +import net.taler.lib.common.Timestamp data class CoinFee( val coin: Amount, diff --git a/wallet/src/main/java/net/taler/wallet/exchanges/SelectExchangeFragment.kt b/wallet/src/main/java/net/taler/wallet/exchanges/SelectExchangeFragment.kt index ef4894d..9f5a916 100644 --- a/wallet/src/main/java/net/taler/wallet/exchanges/SelectExchangeFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/exchanges/SelectExchangeFragment.kt @@ -28,7 +28,7 @@ import androidx.fragment.app.activityViewModels import androidx.recyclerview.widget.RecyclerView.Adapter import androidx.recyclerview.widget.RecyclerView.ViewHolder import kotlinx.android.synthetic.main.fragment_select_exchange.* -import net.taler.common.Amount +import net.taler.lib.common.Amount import net.taler.common.toRelativeTime import net.taler.common.toShortDate import net.taler.wallet.MainViewModel diff --git a/wallet/src/main/java/net/taler/wallet/payment/PaymentManager.kt b/wallet/src/main/java/net/taler/wallet/payment/PaymentManager.kt index 041fcd3..4924752 100644 --- a/wallet/src/main/java/net/taler/wallet/payment/PaymentManager.kt +++ b/wallet/src/main/java/net/taler/wallet/payment/PaymentManager.kt @@ -24,7 +24,7 @@ import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.kotlin.readValue import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch -import net.taler.common.Amount +import net.taler.lib.common.Amount import net.taler.common.ContractTerms import net.taler.wallet.TAG import net.taler.wallet.backend.WalletBackendApi diff --git a/wallet/src/main/java/net/taler/wallet/payment/PaymentResponses.kt b/wallet/src/main/java/net/taler/wallet/payment/PaymentResponses.kt index 120489d..c490654 100644 --- a/wallet/src/main/java/net/taler/wallet/payment/PaymentResponses.kt +++ b/wallet/src/main/java/net/taler/wallet/payment/PaymentResponses.kt @@ -21,8 +21,8 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NAME import com.fasterxml.jackson.annotation.JsonTypeName import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import net.taler.common.Amount import net.taler.common.ContractTerms +import net.taler.lib.common.Amount import net.taler.wallet.transactions.TransactionError @JsonTypeInfo(use = NAME, property = "status") diff --git a/wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt b/wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt index 40664e3..3d00900 100644 --- a/wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt @@ -34,10 +34,10 @@ import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar.LENGTH_LONG import kotlinx.android.synthetic.main.payment_bottom_bar.* import kotlinx.android.synthetic.main.payment_details.* -import net.taler.common.Amount import net.taler.common.ContractTerms import net.taler.common.fadeIn import net.taler.common.fadeOut +import net.taler.lib.common.Amount import net.taler.wallet.MainViewModel import net.taler.wallet.R diff --git a/wallet/src/main/java/net/taler/wallet/refund/RefundManager.kt b/wallet/src/main/java/net/taler/wallet/refund/RefundManager.kt index fdacb0d..559b91d 100644 --- a/wallet/src/main/java/net/taler/wallet/refund/RefundManager.kt +++ b/wallet/src/main/java/net/taler/wallet/refund/RefundManager.kt @@ -22,7 +22,7 @@ import androidx.lifecycle.MutableLiveData import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import kotlinx.serialization.Serializable -import net.taler.common.Amount +import net.taler.lib.common.Amount import net.taler.wallet.TAG import net.taler.wallet.backend.WalletBackendApi diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt index be83b09..f5a4fc9 100644 --- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt @@ -35,9 +35,9 @@ import kotlinx.android.synthetic.main.fragment_transaction_payment.* import kotlinx.android.synthetic.main.fragment_transaction_withdrawal.* import kotlinx.android.synthetic.main.fragment_transaction_withdrawal.feeView import kotlinx.android.synthetic.main.fragment_transaction_withdrawal.timeView -import net.taler.common.Amount import net.taler.common.isSafe import net.taler.common.toAbsoluteTime +import net.taler.lib.common.Amount import net.taler.wallet.MainViewModel import net.taler.wallet.R import net.taler.wallet.cleanExchange diff --git a/wallet/src/main/java/net/taler/wallet/transactions/Transactions.kt b/wallet/src/main/java/net/taler/wallet/transactions/Transactions.kt index d227183..1ed6788 100644 --- a/wallet/src/main/java/net/taler/wallet/transactions/Transactions.kt +++ b/wallet/src/main/java/net/taler/wallet/transactions/Transactions.kt @@ -28,10 +28,10 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo.As.PROPERTY import com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NAME import com.fasterxml.jackson.annotation.JsonTypeName import kotlinx.serialization.Serializable -import net.taler.common.Amount +import net.taler.lib.common.Amount import net.taler.common.ContractMerchant import net.taler.common.ContractProduct -import net.taler.common.Timestamp +import net.taler.lib.common.Timestamp import net.taler.wallet.R import net.taler.wallet.cleanExchange import net.taler.wallet.transactions.WithdrawalDetails.ManualTransfer diff --git a/wallet/src/main/java/net/taler/wallet/withdraw/ManualWithdrawFragment.kt b/wallet/src/main/java/net/taler/wallet/withdraw/ManualWithdrawFragment.kt index 9788d1c..fbee6ae 100644 --- a/wallet/src/main/java/net/taler/wallet/withdraw/ManualWithdrawFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/withdraw/ManualWithdrawFragment.kt @@ -26,8 +26,8 @@ import android.widget.Toast.LENGTH_SHORT import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import kotlinx.android.synthetic.main.fragment_manual_withdraw.* -import net.taler.common.Amount import net.taler.common.hideKeyboard +import net.taler.lib.common.Amount import net.taler.wallet.MainViewModel import net.taler.wallet.R import net.taler.wallet.scanQrCode diff --git a/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt b/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt index 5a98a89..ffc64d4 100644 --- a/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt @@ -29,9 +29,9 @@ import androidx.navigation.fragment.findNavController import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar.LENGTH_LONG import kotlinx.android.synthetic.main.fragment_prompt_withdraw.* -import net.taler.common.Amount import net.taler.common.fadeIn import net.taler.common.fadeOut +import net.taler.lib.common.Amount import net.taler.wallet.MainViewModel import net.taler.wallet.R import net.taler.wallet.cleanExchange diff --git a/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt b/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt index 2aaa5dc..730f704 100644 --- a/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt +++ b/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt @@ -22,7 +22,7 @@ import androidx.lifecycle.MutableLiveData import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import kotlinx.serialization.Serializable -import net.taler.common.Amount +import net.taler.lib.common.Amount import net.taler.wallet.TAG import net.taler.wallet.backend.WalletBackendApi import net.taler.wallet.backend.WalletErrorInfo diff --git a/wallet/src/test/java/net/taler/wallet/backend/WalletResponseTest.kt b/wallet/src/test/java/net/taler/wallet/backend/WalletResponseTest.kt index 698c90a..d8f28c5 100644 --- a/wallet/src/test/java/net/taler/wallet/backend/WalletResponseTest.kt +++ b/wallet/src/test/java/net/taler/wallet/backend/WalletResponseTest.kt @@ -22,10 +22,10 @@ import com.fasterxml.jackson.module.kotlin.KotlinModule import com.fasterxml.jackson.module.kotlin.readValue import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonConfiguration -import net.taler.common.Amount -import net.taler.common.AmountMixin -import net.taler.common.Timestamp -import net.taler.common.TimestampMixin +import net.taler.lib.common.Amount +import net.taler.lib.common.AmountMixin +import net.taler.lib.common.Timestamp +import net.taler.lib.common.TimestampMixin import net.taler.wallet.balances.BalanceResponse import org.junit.Assert.assertEquals import org.junit.Test |