diff --git a/fints4k/build.gradle b/fints4k/build.gradle index 075b7c9c..39c88743 100644 --- a/fints4k/build.gradle +++ b/fints4k/build.gradle @@ -26,13 +26,32 @@ kotlin { } } -// js(BOTH) { -// browser { -// commonWebpackConfig { -// cssSupport.enabled = true -// } -// } -// } + js(IR) { + binaries.executable() + browser { + commonWebpackConfig { + cssSupport.enabled = true + } + testTask { + useKarma { + // we cannot assume that Chrome and Firefox are installed on all systems + // useChromeHeadless() + // useFirefox() + enabled = false + } + } + } + nodejs { + testTask { + useMocha { + enabled = true + } + testLogging { + events "failed" + } + } + } + } ios { binaries { @@ -101,23 +120,11 @@ kotlin { } -// jsMain { -// dependencies { -// implementation npm("@js-joda/timezone", "2.3.0") -// implementation "io.ktor:ktor-client-js:$ktorVersion" -// } - /* Plus: -@JsModule("@js-joda/timezone") -@JsNonModule -external object JsJodaTimeZoneModule - -private val jsJodaTz = JsJodaTimeZoneModule - */ -// } -// -// jsTest { -// -// } + jsMain { + dependencies { + implementation "io.ktor:ktor-client-js:$ktorVersion" + } + } iosMain { diff --git a/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/extensions/AssertExtensions.kt b/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/extensions/AssertExtensions.kt index fa014afd..447f1c22 100644 --- a/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/extensions/AssertExtensions.kt +++ b/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/extensions/AssertExtensions.kt @@ -1,5 +1,6 @@ package net.dankito.banking.fints.extensions +import net.dankito.utils.multiplatform.extensions.platformSpecificQualifiedName import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract import kotlin.test.assertEquals @@ -65,7 +66,7 @@ fun assertContains(collection: Collection, vararg items: T) { inline fun assertThrows(action: () -> Unit) { try { action() - fail("action() didn't throw any exception. Expected was ${T::class.qualifiedName}") + fail("action() didn't throw any exception. Expected was ${T::class.platformSpecificQualifiedName}") } catch (throwable: Throwable) { assertTrue(throwable is T) } diff --git a/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/messages/segmente/implementierte/sepa/SepaMessageCreatorTest.kt b/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/messages/segmente/implementierte/sepa/SepaMessageCreatorTest.kt index de92004e..3a12a6b9 100644 --- a/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/messages/segmente/implementierte/sepa/SepaMessageCreatorTest.kt +++ b/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/messages/segmente/implementierte/sepa/SepaMessageCreatorTest.kt @@ -31,7 +31,7 @@ class SepaMessageCreatorTest { } @Test - fun `containsOnlyAllowedCharacters colon is a legal character`() { + fun containsOnlyAllowedCharacters_ColonIsALegalCharacter() { // when val result = underTest.containsOnlyAllowedCharacters(":") @@ -41,7 +41,7 @@ class SepaMessageCreatorTest { } @Test - fun `containsOnlyAllowedCharacters ! is an illegal character`() { + fun containsOnlyAllowedCharacters_ExclamationMarkIsAnIllegalCharacter() { // when val result = underTest.containsOnlyAllowedCharacters("!") @@ -51,7 +51,7 @@ class SepaMessageCreatorTest { } @Test - fun `containsOnlyAllowedCharacters € is an illegal character`() { + fun containsOnlyAllowedCharacters_EuroSignIsAnIllegalCharacter() { // when val result = underTest.containsOnlyAllowedCharacters("€") @@ -61,7 +61,7 @@ class SepaMessageCreatorTest { } @Test - fun `containsOnlyAllowedCharacters at sign is an illegal character`() { + fun containsOnlyAllowedCharacters_AtSignIsAnIllegalCharacter() { // when val result = underTest.containsOnlyAllowedCharacters("@") @@ -71,7 +71,7 @@ class SepaMessageCreatorTest { } @Test - fun `containsOnlyAllowedCharacters ö is an illegal character`() { + fun containsOnlyAllowedCharacters_ÖIsAnIllegalCharacter() { // when val result = underTest.containsOnlyAllowedCharacters("ö") diff --git a/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/tan/FlickerCodeDecoderTest.kt b/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/tan/FlickerCodeDecoderTest.kt index 55ca490d..468e8382 100644 --- a/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/tan/FlickerCodeDecoderTest.kt +++ b/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/tan/FlickerCodeDecoderTest.kt @@ -69,7 +69,7 @@ class FlickerCodeDecoderTest { @Test - fun `decode HHD 1_4 Get transactions`() { + fun decodeHHD1_4_GetTransactions() { // given val challenge = "0388A01239230124622DE26123456780987654321" @@ -82,7 +82,7 @@ class FlickerCodeDecoderTest { } @Test - fun `decode HHD 1_4 Money Transfer`() { + fun decodeHHD1_4_TransferMoney() { // given val challenge = "0438701109374422DE2612345678098765432106100,00" diff --git a/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/transactions/Mt940ParserTest.kt b/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/transactions/Mt940ParserTest.kt index 06769eed..c70ac495 100644 --- a/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/transactions/Mt940ParserTest.kt +++ b/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/transactions/Mt940ParserTest.kt @@ -129,7 +129,7 @@ class Mt940ParserTest : FinTsTestBase() { } @Test - fun `Fix annual jump from booking date to value date`() { + fun fixAnnualJumpFromBookingDateToValueDate() { val transactionsString = ":20:STARTUMSE\n" + ":25:$BankCode/$CustomerId\n" + @@ -164,7 +164,7 @@ class Mt940ParserTest : FinTsTestBase() { } @Test - fun `Fix line starts with dash but is not a statement separator`() { + fun fixLineStartsWithDashButIsNotASstatementSeparator() { // given val transactionsString = "\n" + @@ -227,7 +227,7 @@ class Mt940ParserTest : FinTsTestBase() { } @Test - fun `Fix that time got detected as field code`() { + fun fixThatTimeGotDetectedAsFieldCode() { // given val transactionsString = "\n" + @@ -276,7 +276,7 @@ class Mt940ParserTest : FinTsTestBase() { } @Test - fun `Fix that questionmark, gets detected as field code`() { + fun fixThat_QuestionMarkComma_GetsDetectedAsFieldCode() { val transactionsString = """ :20:STARTUMS :25:$BankCode/$CustomerId diff --git a/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/util/Base64Test.kt b/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/util/Base64Test.kt index 057242a7..56edcc2e 100644 --- a/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/util/Base64Test.kt +++ b/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/util/Base64Test.kt @@ -55,7 +55,7 @@ class Base64Test { @Test fun testRandomStrings() { - val steps = 1000000 + val steps = 10_000 // 1_000_000 have been too much for JavaScript val random = randomWithSeed() for (count in 0 until steps) { diff --git a/multiplatform-utils/build.gradle b/multiplatform-utils/build.gradle index 4d40ae0a..149b27e0 100644 --- a/multiplatform-utils/build.gradle +++ b/multiplatform-utils/build.gradle @@ -18,13 +18,32 @@ kotlin { } } -// js(BOTH) { -// browser { -// commonWebpackConfig { -// cssSupport.enabled = true -// } -// } -// } + js(IR) { + binaries.executable() + browser { + commonWebpackConfig { + cssSupport.enabled = true + } + testTask { + useKarma { + // we cannot assume that Chrome and Firefox are installed on all systems + // useChromeHeadless() + // useFirefox() + enabled = false + } + } + } + nodejs { + testTask { + useMocha { + enabled = true + } + testLogging { + events "failed" + } + } + } + } ios { binaries { @@ -80,19 +99,17 @@ kotlin { } -// jsMain { -// dependencies { -// implementation npm("@js-joda/timezone", "2.3.0") -// implementation "io.ktor:ktor-client-js:$ktorVersion" -// } -// } - /* Plus: -@JsModule("@js-joda/timezone") -@JsNonModule -external object JsJodaTimeZoneModule + jsMain { + dependencies { + implementation npm("@js-joda/timezone", "2.3.0") + } + } -private val jsJodaTz = JsJodaTimeZoneModule - */ + jsTest { + dependencies { + implementation kotlin("test-js") // don't know why this dependency is needed here, it's not needed e.g. in fints4k project + } + } iosMain { diff --git a/multiplatform-utils/src/commonMain/kotlin/net/dankito/utils/multiplatform/extensions/KClassExtensions.kt b/multiplatform-utils/src/commonMain/kotlin/net/dankito/utils/multiplatform/extensions/KClassExtensions.kt new file mode 100644 index 00000000..37b11ca8 --- /dev/null +++ b/multiplatform-utils/src/commonMain/kotlin/net/dankito/utils/multiplatform/extensions/KClassExtensions.kt @@ -0,0 +1,10 @@ +package net.dankito.utils.multiplatform.extensions + +import kotlin.reflect.KClass + + +/** + * On some platforms like JavaScript [KClass.qualifiedName] is not supported. + * On these [KClass.simpleName] is returned, on all others [KClass.qualifiedName]. + */ +expect val KClass<*>.platformSpecificQualifiedName: String \ No newline at end of file diff --git a/multiplatform-utils/src/commonMain/kotlin/net/dankito/utils/multiplatform/os/OsType.kt b/multiplatform-utils/src/commonMain/kotlin/net/dankito/utils/multiplatform/os/OsType.kt index 5a8e2463..19c1b3b7 100644 --- a/multiplatform-utils/src/commonMain/kotlin/net/dankito/utils/multiplatform/os/OsType.kt +++ b/multiplatform-utils/src/commonMain/kotlin/net/dankito/utils/multiplatform/os/OsType.kt @@ -9,6 +9,8 @@ enum class OsType { iOS, + JavaScript, // TODO: differenciate between Browser and NodeJS + Native // TODO: get if running on Linux, Windows or macOs } \ No newline at end of file diff --git a/multiplatform-utils/src/commonTest/kotlin/net.dankito.utils.multiplatform.extensions/NumberExtensionsTest.kt b/multiplatform-utils/src/commonTest/kotlin/net.dankito.utils.multiplatform.extensions/NumberExtensionsTest.kt index 9abd6e1e..2e8628ac 100644 --- a/multiplatform-utils/src/commonTest/kotlin/net.dankito.utils.multiplatform.extensions/NumberExtensionsTest.kt +++ b/multiplatform-utils/src/commonTest/kotlin/net.dankito.utils.multiplatform.extensions/NumberExtensionsTest.kt @@ -1,6 +1,5 @@ -import net.dankito.utils.multiplatform.extensions.ensureMinStringLength -import net.dankito.utils.multiplatform.extensions.numberOfDigits -import net.dankito.utils.multiplatform.extensions.toStringWithMinDigits +package net.dankito.utils.multiplatform.extensions + import kotlin.test.Test import kotlin.test.assertEquals diff --git a/multiplatform-utils/src/iosMain/kotlin/net/dankito/utils/multiplatform/extensions/KClassExtensions.kt b/multiplatform-utils/src/iosMain/kotlin/net/dankito/utils/multiplatform/extensions/KClassExtensions.kt new file mode 100644 index 00000000..cb99dca5 --- /dev/null +++ b/multiplatform-utils/src/iosMain/kotlin/net/dankito/utils/multiplatform/extensions/KClassExtensions.kt @@ -0,0 +1,10 @@ +package net.dankito.utils.multiplatform.extensions + +import kotlin.reflect.KClass + +/** + * On some platforms like JavaScript [KClass.qualifiedName] is not supported. + * On these [KClass.simpleName] is returned, on all others [KClass.qualifiedName]. + */ +actual val KClass<*>.platformSpecificQualifiedName: String + get() = this.qualifiedName ?: this.simpleName ?: "ClassNameNotFound" // should actually never occur \ No newline at end of file diff --git a/multiplatform-utils/src/jsMain/kotlin/net/dankito/utils/multiplatform/DateFormatter.kt b/multiplatform-utils/src/jsMain/kotlin/net/dankito/utils/multiplatform/DateFormatter.kt new file mode 100644 index 00000000..afdbad58 --- /dev/null +++ b/multiplatform-utils/src/jsMain/kotlin/net/dankito/utils/multiplatform/DateFormatter.kt @@ -0,0 +1,26 @@ +package net.dankito.utils.multiplatform + +import kotlinx.datetime.LocalDate +import kotlinx.datetime.LocalDateTime + +actual class DateFormatter actual constructor(pattern: String) { + + actual constructor(dateStyle: DateFormatStyle) : this("") + + actual constructor(dateStyle: DateFormatStyle, timeStyle: DateFormatStyle) : this("") + + + // TODO: implement for Logger, get current time formatted as string + actual fun format(date: LocalDateTime): String { + return "" // is only used in rare cases, don't implement right now + } + + actual fun parseDate(dateString: String): LocalDate? { + return null // is only used in rare cases, don't implement right now + } + + actual fun parse(dateString: String): LocalDateTime? { + return null // is only used in rare cases, don't implement right now + } + +} \ No newline at end of file diff --git a/multiplatform-utils/src/jsMain/kotlin/net/dankito/utils/multiplatform/JsJodaTimeZoneModule.kt b/multiplatform-utils/src/jsMain/kotlin/net/dankito/utils/multiplatform/JsJodaTimeZoneModule.kt new file mode 100644 index 00000000..651cd255 --- /dev/null +++ b/multiplatform-utils/src/jsMain/kotlin/net/dankito/utils/multiplatform/JsJodaTimeZoneModule.kt @@ -0,0 +1,11 @@ +package net.dankito.utils.multiplatform + +// required so that Joda time zones get loaded, see: +// https://github.com/Kotlin/kotlinx-datetime#note-about-time-zones-in-js +// https://github.com/Kotlin/kotlinx-datetime/blob/master/core/js/test/JsJodaTimeZoneModule.kt + +@JsModule("@js-joda/timezone") +@JsNonModule +external object JsJodaTimeZoneModule + +private val jsJodaTz = JsJodaTimeZoneModule \ No newline at end of file diff --git a/multiplatform-utils/src/jsMain/kotlin/net/dankito/utils/multiplatform/Thread.kt b/multiplatform-utils/src/jsMain/kotlin/net/dankito/utils/multiplatform/Thread.kt new file mode 100644 index 00000000..9bae311f --- /dev/null +++ b/multiplatform-utils/src/jsMain/kotlin/net/dankito/utils/multiplatform/Thread.kt @@ -0,0 +1,23 @@ +package net.dankito.utils.multiplatform + +actual class Thread actual constructor() { + + actual companion object { + + actual val current: Thread + get() = Thread() + + actual fun printCurrentThreadStackTrace() { + Thread.current.printStackTrace() + } + + } + + actual val threadName = "main" + + actual fun printStackTrace() { + // TODO: find a better way + Exception("Nothing happened, just to print the stack trace").printStackTrace() + } + +} \ No newline at end of file diff --git a/multiplatform-utils/src/jsMain/kotlin/net/dankito/utils/multiplatform/extensions/KClassExtensions.kt b/multiplatform-utils/src/jsMain/kotlin/net/dankito/utils/multiplatform/extensions/KClassExtensions.kt new file mode 100644 index 00000000..51570aa9 --- /dev/null +++ b/multiplatform-utils/src/jsMain/kotlin/net/dankito/utils/multiplatform/extensions/KClassExtensions.kt @@ -0,0 +1,11 @@ +package net.dankito.utils.multiplatform.extensions + +import kotlin.reflect.KClass + +/** + * On some platforms like JavaScript [KClass.qualifiedName] is not supported. + * On these [KClass.simpleName] is returned, on all others [KClass.qualifiedName]. + */ +actual val KClass<*>.platformSpecificQualifiedName: String + get() = this.simpleName // on JavaScript qualifiedName is not supported + ?: "ClassNameNotFound" // should actually never occur \ No newline at end of file diff --git a/multiplatform-utils/src/jsMain/kotlin/net/dankito/utils/multiplatform/log/DefaultLoggerFactory.kt b/multiplatform-utils/src/jsMain/kotlin/net/dankito/utils/multiplatform/log/DefaultLoggerFactory.kt new file mode 100644 index 00000000..9924f342 --- /dev/null +++ b/multiplatform-utils/src/jsMain/kotlin/net/dankito/utils/multiplatform/log/DefaultLoggerFactory.kt @@ -0,0 +1,9 @@ +package net.dankito.utils.multiplatform.log + +actual class DefaultLoggerFactory actual constructor() { + + actual fun createDefaultLoggerFactory(): ILoggerFactory { + return LogToConsoleLoggerFactory() + } + +} \ No newline at end of file diff --git a/multiplatform-utils/src/jsMain/kotlin/net/dankito/utils/multiplatform/os/OsHelper.kt b/multiplatform-utils/src/jsMain/kotlin/net/dankito/utils/multiplatform/os/OsHelper.kt new file mode 100644 index 00000000..4a74c9c3 --- /dev/null +++ b/multiplatform-utils/src/jsMain/kotlin/net/dankito/utils/multiplatform/os/OsHelper.kt @@ -0,0 +1,7 @@ +package net.dankito.utils.multiplatform.os + +actual class OsHelper actual constructor() { + + actual val osType = OsType.JavaScript + +} \ No newline at end of file diff --git a/multiplatform-utils/src/jvmMain/kotlin/net/dankito/utils/multiplatform/extensions/KClassExtensions.kt b/multiplatform-utils/src/jvmMain/kotlin/net/dankito/utils/multiplatform/extensions/KClassExtensions.kt new file mode 100644 index 00000000..cb99dca5 --- /dev/null +++ b/multiplatform-utils/src/jvmMain/kotlin/net/dankito/utils/multiplatform/extensions/KClassExtensions.kt @@ -0,0 +1,10 @@ +package net.dankito.utils.multiplatform.extensions + +import kotlin.reflect.KClass + +/** + * On some platforms like JavaScript [KClass.qualifiedName] is not supported. + * On these [KClass.simpleName] is returned, on all others [KClass.qualifiedName]. + */ +actual val KClass<*>.platformSpecificQualifiedName: String + get() = this.qualifiedName ?: this.simpleName ?: "ClassNameNotFound" // should actually never occur \ No newline at end of file diff --git a/multiplatform-utils/src/nativeMain/kotlin/net.dankito.utils.multiplatform/DateFormatter.kt b/multiplatform-utils/src/nativeMain/kotlin/net.dankito.utils.multiplatform/DateFormatter.kt index 90db9f72..84feed53 100644 --- a/multiplatform-utils/src/nativeMain/kotlin/net.dankito.utils.multiplatform/DateFormatter.kt +++ b/multiplatform-utils/src/nativeMain/kotlin/net.dankito.utils.multiplatform/DateFormatter.kt @@ -5,12 +5,9 @@ import kotlinx.datetime.* actual class DateFormatter actual constructor(pattern: String) { + actual constructor(dateStyle: DateFormatStyle) : this("") - actual constructor(dateStyle: DateFormatStyle) - : this("") - - actual constructor(dateStyle: DateFormatStyle, timeStyle: DateFormatStyle) - : this("") + actual constructor(dateStyle: DateFormatStyle, timeStyle: DateFormatStyle) : this("") // TODO: implement for Logger, get current time formatted as string diff --git a/multiplatform-utils/src/nativeMain/kotlin/net.dankito.utils.multiplatform/extensions/KClassExtensions.kt b/multiplatform-utils/src/nativeMain/kotlin/net.dankito.utils.multiplatform/extensions/KClassExtensions.kt new file mode 100644 index 00000000..cb99dca5 --- /dev/null +++ b/multiplatform-utils/src/nativeMain/kotlin/net.dankito.utils.multiplatform/extensions/KClassExtensions.kt @@ -0,0 +1,10 @@ +package net.dankito.utils.multiplatform.extensions + +import kotlin.reflect.KClass + +/** + * On some platforms like JavaScript [KClass.qualifiedName] is not supported. + * On these [KClass.simpleName] is returned, on all others [KClass.qualifiedName]. + */ +actual val KClass<*>.platformSpecificQualifiedName: String + get() = this.qualifiedName ?: this.simpleName ?: "ClassNameNotFound" // should actually never occur \ No newline at end of file