Skip to content

test(base58): run the vector gate on Kotlin/Native, not just the JVM - #1289

Merged
bmc08gt merged 1 commit into
code/cashfrom
test/base58-kmp-vector-fixtures
Aug 20, 2026
Merged

test(base58): run the vector gate on Kotlin/Native, not just the JVM#1289
bmc08gt merged 1 commit into
code/cashfrom
test/base58-kmp-vector-fixtures

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

What

:libs:encryption:base58's Kotlin/Native vector test never compiled, so Base58VectorTest only ever ran on the JVM host despite the "asserted on both Android and iOS" claim in its own KDoc. This makes it genuinely run on both toolchains.

Why

The iosTest actual for readTestResource called NSString.stringWithContentsOfFile without opting in to @kotlinx.cinterop.ExperimentalForeignApi — a hard compile error on Kotlin/Native:

e: .../src/iosTest/kotlin/com/getcode/vendor/TestResources.ios.kt:15:18 This declaration needs opt-in.
   Its usage must be marked with '@kotlinx.cinterop.ExperimentalForeignApi'...
> Task :libs:encryption:base58:compileTestKotlinIosSimulatorArm64 FAILED

Adding the opt-in alone would only have moved the failure to runtime: Kotlin/Native test binaries ship no resource bundle, so NSBundle.pathForResource returns null.

This is not a parity coverage hole. Per test-vectors/README.md, base58's iOS parity is covered by the iOS repo's FlipcashCoreVectors via xcodebuild, and that stays green. What this closes is misleading dead source — and it makes the run matrix's parity claim true on both toolchains inside this repo rather than only documented.

How

Adopt the fix :libs:codes:kikcode already uses (#1287): a generateTestFixtures task that compiles src/commonTest/resources into commonTest as Kotlin constants. That removes the need for the expect/actual readTestResource entirely and works on every target — so all four TestResources*.kt files are deleted, including the JVM actuals that are now redundant.

Second instance of the same defect, found while verifying

Base58Test.kt sat in src/androidTest/. Under the com.android.kotlin.multiplatform.library plugin the host-test source set is androidHostTest — this module declares only withHostTest {}, and :libs:encryption:base58:tasks --all confirms no device-test task exists. So src/androidTest/ was not a source set and those 13 unit tests had never run either. Moved to androidHostTest.

Results

Read from the JUnit XML, not just the build exit code:

Target Tests Result
testAndroidHostTest 14 (1 vector + 13 unit) green
iosSimulatorArm64Test 1 vector green

The module's base58.json is still byte-identical to canonical (9566944…c8b19d).

Also

test-vectors/README.md: run-matrix row for base58 now names both toolchains; added a note under the base58 section explaining why there is no resource loader (so the next person doesn't reintroduce one); and corrected the Regenerate sync path, which said src/test/resources/ when the file actually lives in src/commonTest/resources/.

Reviewer note

The src/androidTest/-isn't-a-source-set trap applies to any module on the KMP Android plugin, and it fails silently — no error, the tests just never run. Worth a sweep if more modules have been converted to KMP since.

`:libs:encryption:base58`'s `iosTest` actual for `readTestResource` called
`NSString.stringWithContentsOfFile` without opting in to
`@kotlinx.cinterop.ExperimentalForeignApi`, which is a hard compile error on
Kotlin/Native. `compileTestKotlinIosSimulatorArm64` had therefore never
succeeded, so `Base58VectorTest` only ever ran on the JVM host despite the
"asserted on both Android and iOS" claim in its own KDoc.

Opting in would only have moved the failure to runtime: Kotlin/Native test
binaries ship no resource bundle, so `NSBundle.pathForResource` returns null.
Adopt the fix `:libs:codes:kikcode` already uses -- a `generateTestFixtures`
task that compiles `src/commonTest/resources` into `commonTest` as Kotlin
constants. That removes the need for the `expect`/`actual` `readTestResource`
entirely and works on every target.

Also move `Base58Test` out of `src/androidTest/`. Under the KMP Android plugin
the host-test source set is `androidHostTest` (the module declares only
`withHostTest {}`, and no device-test task exists), so `src/androidTest/` was
not a source set and those 13 unit tests had never run either.

base58's iOS parity was never actually uncovered -- it runs through the iOS
repo's `FlipcashCoreVectors` via xcodebuild -- so this closes misleading dead
source rather than a coverage hole. It does make the run matrix's parity claim
true on both toolchains in this repo instead of only documented.

Verified: `testAndroidHostTest` 14 tests green (1 vector + 13 unit),
`iosSimulatorArm64Test` 1 test green.

While in test-vectors/README.md, correct the base58 sync path -- the canonical
JSON goes to `src/commonTest/resources/`, not the `src/test/resources/` the
Regenerate section still named.
@github-actions github-actions Bot added area: crypto Solana, keys, encryption, signing type: test Test additions or improvements labels Aug 20, 2026
@bmc08gt
bmc08gt merged commit 9ef2dea into code/cash Aug 20, 2026
2 of 3 checks passed
@bmc08gt
bmc08gt deleted the test/base58-kmp-vector-fixtures branch August 20, 2026 21:16
bmc08gt added a commit that referenced this pull request Aug 21, 2026
… fixtures (#1292)

`commonTest`'s `kotlin.srcDir(generateTestFixtures)` carries the task dependency to
the Kotlin compile tasks only. AGP's `lintAnalyzeAndroidHostTest` and
`generateAndroidHostTestLintModel` read the same source directories straight off
disk, so Gradle failed the build on an undeclared dependency on
`build/generated/testFixtures` whenever both landed in one task graph -- which is
exactly what CI's `flipcashTestDebug :apps:flipcash:app:lintDebug` does.

This is the same wiring #1288 added to :libs:codes:kikcode; #1289 introduced an
identical fixture generator in :libs:encryption:base58 without it, leaving
code/cash red and failing every open PR on a build-config error unrelated to its
own changes.
bmc08gt added a commit that referenced this pull request Aug 21, 2026
…convention plugin (#1293)

`libs/encryption/base58` and `libs/codes/kikcode` each carried a byte-identical
copy of `GenerateTestFixtures`, differing only in the package the generated file
is declared in, plus an identical block wiring the AGP lint tasks to depend on
the generator.

That copy-paste broke `code/cash` once already: #1288 added the lint wiring to
kikcode, then #1289 introduced the same generator in base58 without it, and lint
failed over an undeclared dependency on generated sources. Adding the source
directory only carries the dependency to the Kotlin compile tasks -- lint reads
the same directories straight off disk -- so the wiring is easy to forget and
invisible until CI runs.

Move the task into `build-logic` behind a `flipcash.kmp.test.fixtures`
convention plugin. The plugin takes the package via a `testFixtures {}`
extension, registers the generated directory on `commonTest`, and wires the lint
dependency itself, so a module that applies it cannot omit it. Both modules drop
from ~75 lines of build script to four.
bmc08gt added a commit that referenced this pull request Aug 21, 2026
…esign

* origin/code/cash:
  fix(core): add \ to escape ' in What's (#1298)
  feat(shared-core): wrap the framework in a Swift target (#1297)
  chore: update display name entry title/hint (#1296)
  ci(shared-core): write a placeholder local.properties before publishing (#1295)
  build(shared-core): publish the XCFramework to flipcash-shared-core-spm (#1294)
  refactor(build-logic): extract the KMP test-fixture generator into a convention plugin (#1293)
  build(base58): declare the base58 lint tasks' dependency on generated fixtures (#1292)
  test(base58): run the vector gate on Kotlin/Native, not just the JVM (#1289)
  build(codes): declare the kikcode lint tasks' dependency on generated fixtures (#1288)

# Conflicts:
#	apps/flipcash/core/src/main/res/values/strings.xml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: crypto Solana, keys, encryption, signing type: test Test additions or improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant