diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d58a109..a71016a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,8 +14,8 @@ permissions: contents: read jobs: - test: - name: Tests + jvm: + name: JVM And Lint runs-on: ubuntu-latest steps: @@ -36,3 +36,37 @@ jobs: - name: Check formatting run: ./gradlew :phosphor-core:ktlintCheck + + ios_compile: + name: iOS Compile + runs-on: macos-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'zulu' + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 + + - name: Compile iOS target + run: ./gradlew :phosphor-core:compileKotlinIosArm64 + + test: + name: Tests + runs-on: ubuntu-latest + needs: [jvm, ios_compile] + if: ${{ always() }} + + steps: + - name: Enforce required checks + run: | + if [ "${{ needs.jvm.result }}" != "success" ] || [ "${{ needs.ios_compile.result }}" != "success" ]; then + echo "Required CI jobs did not all pass." + exit 1 + fi diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 952dbe9..f41a654 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -47,7 +47,7 @@ jobs: uses: gradle/actions/setup-gradle@v4 - name: Run tests before publish - run: ./gradlew :phosphor-core:jvmTest + run: ./gradlew :phosphor-core:jvmTest :phosphor-core:compileKotlinIosArm64 - name: Decode signing key if: ${{ github.event.inputs.dry_run != 'true' }} diff --git a/phosphor-core/src/commonMain/kotlin/link/socket/phosphor/color/NeutralColor.kt b/phosphor-core/src/commonMain/kotlin/link/socket/phosphor/color/NeutralColor.kt index d51448e..260669d 100644 --- a/phosphor-core/src/commonMain/kotlin/link/socket/phosphor/color/NeutralColor.kt +++ b/phosphor-core/src/commonMain/kotlin/link/socket/phosphor/color/NeutralColor.kt @@ -1,5 +1,6 @@ package link.socket.phosphor.color +import kotlin.jvm.JvmInline import kotlin.math.abs import kotlin.math.roundToInt @@ -29,9 +30,9 @@ value class NeutralColor private constructor( val alphaInt: Int get() = (packedRgba and CHANNEL_MASK).toInt() fun toHex(includeAlpha: Boolean = true): String { - val rgb = "%02X%02X%02X".format(redInt, greenInt, blueInt) + val rgb = channelToHex(redInt) + channelToHex(greenInt) + channelToHex(blueInt) return if (includeAlpha) { - "#$rgb%02X".format(alphaInt) + "#$rgb${channelToHex(alphaInt)}" } else { "#$rgb" } @@ -155,5 +156,7 @@ value class NeutralColor private constructor( ): Float = start + ((end - start) * t) private fun toChannel(value: Float): Int = (value.coerceIn(0f, 1f) * CHANNEL_MAX_FLOAT).roundToInt() + + private fun channelToHex(channel: Int): String = channel.toString(radix = 16).uppercase().padStart(2, '0') } } diff --git a/phosphor-core/src/commonTest/kotlin/link/socket/phosphor/color/NeutralColorTest.kt b/phosphor-core/src/commonTest/kotlin/link/socket/phosphor/color/NeutralColorTest.kt index 9789d7d..4da61c6 100644 --- a/phosphor-core/src/commonTest/kotlin/link/socket/phosphor/color/NeutralColorTest.kt +++ b/phosphor-core/src/commonTest/kotlin/link/socket/phosphor/color/NeutralColorTest.kt @@ -76,6 +76,13 @@ class NeutralColorTest { assertEquals("#AABBCC", color.toHex(includeAlpha = false)) } + @Test + fun `toHex pads channels with leading zeros`() { + val color = NeutralColor.fromHex("#010A0B0C") + + assertEquals("#010A0B0C", color.toHex()) + } + @Test fun `fromRgba clamps out of range channels`() { val color = NeutralColor.fromRgba(-1f, 0.5f, 2f, 9f)