The orbital maths, the satellite models and the repository contracts sat in a Kotlin/JVM module, so an iOS target could not share a single line of them: java.lang.String.format, InputStream, System.currentTimeMillis, java.util.Locale and org.json are all JVM-only, and the tests that covered them used JUnit4. core:domain now declares jvm, iosArm64 and iosSimulatorArm64 targets, its sources moved to commonMain/commonTest, and the JVM-only pieces were replaced with multiplatform equivalents: java.lang.String.format by a shared printf implementation, System.currentTimeMillis by kotlin.time.Clock, InputStream by ByteArray, org.json by kotlinx-serialization, Locale by nothing at all. Tests that read classpath resources (javaClass.classLoader) moved to jvmTest, because that is JVM-only behaviour rather than a JVM-only API. Auditing the migration against the old module turned up four things that were wrong rather than merely ported: - java.lang.String.format rounds the shortest decimal representation of a double half-up, not the binary value: "%.3f" of 0.5005 is "0.501", because the stored double is 0.50049999999999994493. The shared implementation scaled in binary first and printed "0.500", which would have changed APRS position packets and the Wavelog frequency fields against the released Android app. It now takes the digits from the decimal representation and rounds them with integer arithmetic, and jvmTest compares it against String.format(Locale.ROOT, ...) over 40 000 sampled doubles plus the boundary cases, while commonTest pins literals so the iOS run checks the same digits. - The queue mutators lost the kotlin.jvm.Synchronized monitor each of them had. It is not a JVM-only annotation - it is an optional expectation, so it still compiles in common code - but the stdlib deprecated it for common use in 1.8 and made it an error in 2.1. The monitor is a platform actual now: the JVM keeps the real monitor, since Compose and the upload coroutine both reach the queue there, and iOS carries a documented placeholder until the iOS side has a second thread to protect against. - 107 assertions in DataParserTest and QthConverterTest were bare kotlin.assert calls, which a build without -ea skips silently: they are assertTrue now, so the iOS run cannot pass vacuously. The three Locale.setDefault cases (ar-EG, bn-BD, fa-IR) that used to guard APRS output against Eastern Arabic digits moved to jvmTest instead of being deleted with the Locale dependency - APRS-IS is an ASCII protocol, and Locale.setDefault does not exist on iOS. - @Volatile on the LoTW name cache would not have compiled for iOS either: kotlin.jvm's variant is an error in common code since 2.1. kotlin.concurrent.Volatile is the multiplatform annotation, and it is the stronger form: it takes effect on Kotlin/Native rather than being ignored. A second audit pass over the files the first one could not reach - the HTTP client, the parsers, the queue and the injection - found three more: - OkHttpHttpClient built its Request outside the try, so a URL OkHttp refuses to parse left postQso/testToken/getStation as an exception, and neither caller catches one. The client it replaced reported HTTP -1 and let the caller treat it as a failure; building the request inside the try restores that, and a transport failure reports -1 again rather than 0. - WavelogQueue's readers were stricter than the org.json ones they replaced. A timestamp stored as 1234.0 (or "1234.0") read back as 0L instead of 1234 - a QSO uploaded as 1970 - and a field holding an object or array threw the whole list away instead of falling back. The readers coerce decimals, keep the old defaults and no longer throw, matching optLong, optInt, optString and optBoolean. - The ADIF dates went through the JVM default locale before, so a device set to Arabic wrote Eastern Arabic digits into the QSO date. The shared formatter only ever produces ASCII, which the locale cases in AprsPacketDefaultLocaleTest pin down. Verified locally with ./gradlew jvmTest (343 tests, 0 failures) and the multiplatform gate in check-multiplatform.sh, which now also refuses JVM-only stdlib APIs that resolve in common code but fail to compile for iOS: @Synchronized, kotlin.jvm.Volatile, synchronized(), toUpperCase/toLowerCase/capitalize, BigDecimal. The iOS targets themselves need the macOS runner in .github/workflows/ios-kmp.yml.
4 lines
64 B
Kotlin
4 lines
64 B
Kotlin
plugins {
|
|
alias(libs.plugins.convention.coreDomainPlugin)
|
|
}
|