From d65736c300d6c05fdd2011de7bec9e1589ca8545 Mon Sep 17 00:00:00 2001 From: hanminjae Date: Tue, 6 Jan 2026 23:57:28 +0900 Subject: [PATCH 01/11] feat: update kotlin, jvm target, and test dependencies --- gradle/libs.versions.toml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 86ec710..1aa1d55 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,14 +6,14 @@ ksp = "2.3.0" ktlint = "11.5.1" # Kotlin -kotlin = "2.2.21" +kotlin = "2.3.0" kotlinxSerialization = "1.9.0" kotlinpoet = "2.2.0" # Android SDK compileSdk = "36" minSdk = "28" -jvmTarget = "11" +jvmTarget = "17" # AndroidX & Compose coreKtx = "1.17.0" @@ -27,6 +27,9 @@ material = "1.13.0" junit = "6.0.1" junitVersion = "1.3.0" espressoCore = "3.7.0" +mockk = "1.14.7" +robolectric = "4.16" +kctFork = "0.12.1" [libraries] # --- Build Tools & Plugins --- @@ -67,6 +70,12 @@ androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-co androidx-compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } +# --- Unit Test Libraries --- +mockk = { module = "io.mockk:mockk", version.ref = "mockk" } +robolectric = { module = "org.robolectric:robolectric", version.ref = "robolectric" } +kct-fork-core = { module = "dev.zacsweers.kctfork:core", version.ref = "kctFork" } +kct-fork-ksp = { module = "dev.zacsweers.kctfork:ksp", version.ref = "kctFork" } + [plugins] # Android android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" } @@ -81,4 +90,4 @@ kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", versi # Tools ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint" } -vanniktech-maven-publish = { id = "com.vanniktech.maven.publish", version.ref = "vanniktechMavenPublish" } +vanniktech-maven-publish = { id = "com.vanniktech.maven.publish", version.ref = "vanniktechMavenPublish" } \ No newline at end of file From c409668726e1e56f827fb08baa9492959039c042 Mon Sep 17 00:00:00 2001 From: hanminjae Date: Tue, 6 Jan 2026 23:59:13 +0900 Subject: [PATCH 02/11] chore: update JVM target configuration for consistency across modules --- app/build.gradle.kts | 7 ++++--- wisp-annotations/build.gradle.kts | 4 ++++ wisp-processor/build.gradle.kts | 13 ++++++++++++- wisp-runtime/build.gradle.kts | 11 ++++++++--- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 0246b14..943acfd 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -32,8 +32,9 @@ android { } } compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + val javaVersion = JavaVersion.toVersion(libs.versions.jvmTarget.get()) + sourceCompatibility = javaVersion + targetCompatibility = javaVersion } } @@ -68,4 +69,4 @@ dependencies { androidTestImplementation(libs.androidx.navigation.testing) debugImplementation(libs.androidx.compose.ui.tooling) debugImplementation(libs.androidx.compose.ui.test.manifest) -} +} \ No newline at end of file diff --git a/wisp-annotations/build.gradle.kts b/wisp-annotations/build.gradle.kts index 010aecd..941e7ec 100644 --- a/wisp-annotations/build.gradle.kts +++ b/wisp-annotations/build.gradle.kts @@ -1,3 +1,7 @@ plugins { alias(libs.plugins.kotlin.jvm) } + +kotlin { + jvmToolchain(libs.versions.jvmTarget.get().toInt()) +} \ No newline at end of file diff --git a/wisp-processor/build.gradle.kts b/wisp-processor/build.gradle.kts index 2b4608d..dc0e285 100644 --- a/wisp-processor/build.gradle.kts +++ b/wisp-processor/build.gradle.kts @@ -2,6 +2,10 @@ plugins { alias(libs.plugins.kotlin.jvm) } +kotlin { + jvmToolchain(libs.versions.jvmTarget.get().toInt()) +} + dependencies { implementation(project(":wisp-annotations")) implementation(libs.ksp.api) @@ -11,4 +15,11 @@ dependencies { testImplementation(libs.junit.jupiter.api) testRuntimeOnly(libs.junit.jupiter.engine) testRuntimeOnly(libs.junit.platform.launcher) -} + + // Unit Test + testImplementation(libs.mockk) + + // Integration Test (KCT) + testImplementation(libs.kct.fork.core) + testImplementation(libs.kct.fork.ksp) +} \ No newline at end of file diff --git a/wisp-runtime/build.gradle.kts b/wisp-runtime/build.gradle.kts index 0323544..f421b3f 100644 --- a/wisp-runtime/build.gradle.kts +++ b/wisp-runtime/build.gradle.kts @@ -27,8 +27,9 @@ android { } } compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + val javaVersion = JavaVersion.toVersion(libs.versions.jvmTarget.get()) + sourceCompatibility = javaVersion + targetCompatibility = javaVersion } } @@ -51,4 +52,8 @@ dependencies { testRuntimeOnly(libs.junit.platform.launcher) androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.espresso.core) -} + + // Unit Test + testImplementation(libs.mockk) + testImplementation(libs.robolectric) +} \ No newline at end of file From 39a139008a90d3b92a43d46a62986a5d7a78b672 Mon Sep 17 00:00:00 2001 From: hanminjae Date: Wed, 7 Jan 2026 00:08:52 +0900 Subject: [PATCH 03/11] chore: increase JVM heap size to 4096m in gradle properties --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 132244e..29bd29d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ # http://www.gradle.org/docs/current/userguide/build_environment.html # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8 # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. For more details, visit # https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects From 5ca2c25961b88eb55420fcdc697a9f56dee2b691 Mon Sep 17 00:00:00 2001 From: hanminjae Date: Thu, 8 Jan 2026 20:51:19 +0900 Subject: [PATCH 04/11] chore: update dependency versions in gradle libs.versions.toml --- gradle/libs.versions.toml | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1aa1d55..7c3a7c1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,8 +1,8 @@ [versions] # Build & Publish -androidGradlePlugin = "8.13.0" +androidGradlePlugin = "8.13.2" vanniktechMavenPublish = "0.30.0" -ksp = "2.3.0" +ksp = "2.3.4" ktlint = "11.5.1" # Kotlin @@ -18,18 +18,19 @@ jvmTarget = "17" # AndroidX & Compose coreKtx = "1.17.0" appcompat = "1.7.1" -activityCompose = "1.11.0" -composeBom = "2025.10.01" -composeNavigation = "2.9.5" +activityCompose = "1.12.2" +composeBom = "2025.12.01" +composeNavigation = "2.9.6" material = "1.13.0" # Test junit = "6.0.1" junitVersion = "1.3.0" espressoCore = "3.7.0" -mockk = "1.14.7" robolectric = "4.16" -kctFork = "0.12.1" +junit4 = "4.13.2" +mockito = "5.21.0" +mockitoKotlin = "6.1.0" [libraries] # --- Build Tools & Plugins --- @@ -71,10 +72,10 @@ androidx-compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui- androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } # --- Unit Test Libraries --- -mockk = { module = "io.mockk:mockk", version.ref = "mockk" } +mockito-core = { module = "org.mockito:mockito-core", version.ref = "mockito" } +mockito-kotlin = { module = "org.mockito.kotlin:mockito-kotlin", version.ref = "mockitoKotlin" } robolectric = { module = "org.robolectric:robolectric", version.ref = "robolectric" } -kct-fork-core = { module = "dev.zacsweers.kctfork:core", version.ref = "kctFork" } -kct-fork-ksp = { module = "dev.zacsweers.kctfork:ksp", version.ref = "kctFork" } +junit4 = { module = "junit:junit", version.ref = "junit4" } [plugins] # Android @@ -90,4 +91,4 @@ kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", versi # Tools ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint" } -vanniktech-maven-publish = { id = "com.vanniktech.maven.publish", version.ref = "vanniktechMavenPublish" } \ No newline at end of file +vanniktech-maven-publish = { id = "com.vanniktech.maven.publish", version.ref = "vanniktechMavenPublish" } From 8d7423a43ae1a9f36169858d857d10007774d4ee Mon Sep 17 00:00:00 2001 From: hanminjae Date: Thu, 8 Jan 2026 20:51:31 +0900 Subject: [PATCH 05/11] refactor: update test dependencies and maven publish configuration --- build.gradle.kts | 6 ++++-- wisp-processor/build.gradle.kts | 8 ++------ wisp-runtime/build.gradle.kts | 6 +++--- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 41aa8a7..227ecaf 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,5 @@ +import com.vanniktech.maven.publish.MavenPublishBaseExtension +import com.vanniktech.maven.publish.SonatypeHost import org.jlleitschuh.gradle.ktlint.KtlintExtension plugins { @@ -35,8 +37,8 @@ subprojects { if (name != "app") { apply(plugin = "com.vanniktech.maven.publish") - extensions.configure { - publishToMavenCentral(com.vanniktech.maven.publish.SonatypeHost.CENTRAL_PORTAL) + extensions.configure { + publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL) signAllPublications() coordinates("io.github.angrypodo", name, "0.1.0") diff --git a/wisp-processor/build.gradle.kts b/wisp-processor/build.gradle.kts index dc0e285..23cb93b 100644 --- a/wisp-processor/build.gradle.kts +++ b/wisp-processor/build.gradle.kts @@ -16,10 +16,6 @@ dependencies { testRuntimeOnly(libs.junit.jupiter.engine) testRuntimeOnly(libs.junit.platform.launcher) - // Unit Test - testImplementation(libs.mockk) - - // Integration Test (KCT) - testImplementation(libs.kct.fork.core) - testImplementation(libs.kct.fork.ksp) + testImplementation(libs.mockito.core) + testImplementation(libs.mockito.kotlin) } \ No newline at end of file diff --git a/wisp-runtime/build.gradle.kts b/wisp-runtime/build.gradle.kts index f421b3f..623ec64 100644 --- a/wisp-runtime/build.gradle.kts +++ b/wisp-runtime/build.gradle.kts @@ -53,7 +53,7 @@ dependencies { androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.espresso.core) - // Unit Test - testImplementation(libs.mockk) testImplementation(libs.robolectric) -} \ No newline at end of file + testImplementation(libs.junit4) + testImplementation(libs.androidx.junit) +} From d3e59deab0a2c8e27c1f8987352783d62570d4e9 Mon Sep 17 00:00:00 2001 From: hanminjae Date: Thu, 8 Jan 2026 20:51:39 +0900 Subject: [PATCH 06/11] chore: enable gradle configuration cache and build caching in gradle.properties --- gradle.properties | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gradle.properties b/gradle.properties index 29bd29d..ed52742 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,6 +7,8 @@ # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8 +org.gradle.configuration-cache=true +org.gradle.caching=true # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. For more details, visit # https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects From eecab56afeacbf2e04edad3b003b85d3d001e67c Mon Sep 17 00:00:00 2001 From: hanminjae Date: Thu, 8 Jan 2026 20:51:45 +0900 Subject: [PATCH 07/11] test: add unit tests for DefaultWispUriParser parsing logic --- .../parser/DefaultWispUriParserTest.kt | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 wisp-runtime/src/test/java/com/angrypodo/wisp/runtime/parser/DefaultWispUriParserTest.kt diff --git a/wisp-runtime/src/test/java/com/angrypodo/wisp/runtime/parser/DefaultWispUriParserTest.kt b/wisp-runtime/src/test/java/com/angrypodo/wisp/runtime/parser/DefaultWispUriParserTest.kt new file mode 100644 index 0000000..c65185e --- /dev/null +++ b/wisp-runtime/src/test/java/com/angrypodo/wisp/runtime/parser/DefaultWispUriParserTest.kt @@ -0,0 +1,41 @@ +package com.angrypodo.wisp.runtime.parser + +import android.net.Uri +import androidx.test.ext.junit.runners.AndroidJUnit4 +import org.junit.Assert.assertEquals +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class DefaultWispUriParserTest { + + private val parser = DefaultWispUriParser() + + @Test + fun parse_valid_path_returns_list_of_segments() { + val uri = Uri.parse("app://wisp/home/product") + val result = parser.parse(uri) + assertEquals(listOf("home", "product"), result) + } + + @Test + fun parse_empty_path_returns_empty_list() { + val uri = Uri.parse("app://wisp") + val result = parser.parse(uri) + assertEquals(emptyList(), result) + } + + @Test + fun parse_trailing_slash_returns_empty_list_for_root() { + val uri = Uri.parse("app://wisp/") + val result = parser.parse(uri) + assertEquals(emptyList(), result) + } + + @Test + fun parse_path_with_query_parameters_ignores_query() { + val uri = Uri.parse("app://wisp/product?id=123") + val result = parser.parse(uri) + assertEquals(listOf("product"), result) + } +} \ No newline at end of file From 587567b27b9c51a7e3aaf4a330e9a67a4eaf5109 Mon Sep 17 00:00:00 2001 From: hanminjae Date: Thu, 8 Jan 2026 20:51:52 +0900 Subject: [PATCH 08/11] test: add unit tests for RouteInfoMapper to verify annotation handling and route info creation --- .../wisp/mapper/RouteInfoMapperTest.kt | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 wisp-processor/src/test/java/com/angrypodo/wisp/mapper/RouteInfoMapperTest.kt diff --git a/wisp-processor/src/test/java/com/angrypodo/wisp/mapper/RouteInfoMapperTest.kt b/wisp-processor/src/test/java/com/angrypodo/wisp/mapper/RouteInfoMapperTest.kt new file mode 100644 index 0000000..b1fb968 --- /dev/null +++ b/wisp-processor/src/test/java/com/angrypodo/wisp/mapper/RouteInfoMapperTest.kt @@ -0,0 +1,101 @@ +package com.angrypodo.wisp.mapper + +import com.angrypodo.wisp.model.ClassRouteInfo +import com.angrypodo.wisp.model.ObjectRouteInfo +import com.google.devtools.ksp.symbol.ClassKind +import com.google.devtools.ksp.symbol.KSAnnotation +import com.google.devtools.ksp.symbol.KSClassDeclaration +import com.google.devtools.ksp.symbol.KSName +import com.google.devtools.ksp.symbol.KSValueArgument +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNotNull +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test +import org.mockito.Mockito.mock +import org.mockito.kotlin.whenever + +class RouteInfoMapperTest { + + @Test + fun `toRouteInfo returns null if @Wisp annotation is missing`() { + val classDeclaration = mock() + whenever(classDeclaration.annotations).thenReturn(emptySequence()) + + val result = classDeclaration.toRouteInfo() + + assertNull(result) + } + + @Test + fun `toRouteInfo returns ObjectRouteInfo for object declaration`() { + val mockPackageName = mock() + whenever(mockPackageName.asString()).thenReturn("com.example") + + val mockSimpleName = mock() + whenever(mockSimpleName.asString()).thenReturn("HomeScreen") + + val mockQualifiedName = mock() + whenever(mockQualifiedName.asString()).thenReturn("com.example.HomeScreen") + + val classDeclaration = mock() + whenever(classDeclaration.classKind).thenReturn(ClassKind.OBJECT) + whenever(classDeclaration.packageName).thenReturn(mockPackageName) + whenever(classDeclaration.simpleName).thenReturn(mockSimpleName) + whenever(classDeclaration.qualifiedName).thenReturn(mockQualifiedName) + + val mockAnnotation = createMockWispAnnotation("home") + whenever(classDeclaration.annotations).thenReturn(sequenceOf(mockAnnotation)) + + val result = classDeclaration.toRouteInfo() + + assertNotNull(result) + assertTrue(result is ObjectRouteInfo) + assertEquals("home", result?.wispPath) + } + + @Test + fun `toRouteInfo returns ClassRouteInfo for class declaration`() { + val mockPackageName = mock() + whenever(mockPackageName.asString()).thenReturn("com.example") + + val mockSimpleName = mock() + whenever(mockSimpleName.asString()).thenReturn("ProfileScreen") + + val mockQualifiedName = mock() + whenever(mockQualifiedName.asString()).thenReturn("com.example.ProfileScreen") + + val classDeclaration = mock() + whenever(classDeclaration.classKind).thenReturn(ClassKind.CLASS) + whenever(classDeclaration.packageName).thenReturn(mockPackageName) + whenever(classDeclaration.simpleName).thenReturn(mockSimpleName) + whenever(classDeclaration.qualifiedName).thenReturn(mockQualifiedName) + whenever(classDeclaration.primaryConstructor).thenReturn(null) + + val mockAnnotation = createMockWispAnnotation("profile") + whenever(classDeclaration.annotations).thenReturn(sequenceOf(mockAnnotation)) + + val result = classDeclaration.toRouteInfo() + + assertNotNull(result) + assertTrue(result is ClassRouteInfo) + } + + private fun createMockWispAnnotation(path: String): KSAnnotation { + val annotation = mock() + + val shortName = mock() + whenever(shortName.asString()).thenReturn("Wisp") + whenever(annotation.shortName).thenReturn(shortName) + + val arg = mock() + val argName = mock() + whenever(argName.asString()).thenReturn("path") + whenever(arg.name).thenReturn(argName) + whenever(arg.value).thenReturn(path) + + whenever(annotation.arguments).thenReturn(listOf(arg)) + + return annotation + } +} From 7e903f3240895f72a7af559f7a1b120ba191f675 Mon Sep 17 00:00:00 2001 From: hanminjae Date: Thu, 8 Jan 2026 20:52:11 +0900 Subject: [PATCH 09/11] test: add unit tests for WispValidator to verify duplicate path detection --- .../wisp/validation/WispValidatorTest.kt | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 wisp-processor/src/test/java/com/angrypodo/wisp/validation/WispValidatorTest.kt diff --git a/wisp-processor/src/test/java/com/angrypodo/wisp/validation/WispValidatorTest.kt b/wisp-processor/src/test/java/com/angrypodo/wisp/validation/WispValidatorTest.kt new file mode 100644 index 0000000..cfacc5d --- /dev/null +++ b/wisp-processor/src/test/java/com/angrypodo/wisp/validation/WispValidatorTest.kt @@ -0,0 +1,46 @@ +package com.angrypodo.wisp.validation + +import com.angrypodo.wisp.model.ObjectRouteInfo +import com.squareup.kotlinpoet.ClassName +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test + +class WispValidatorTest { + + @Test + fun `validateDuplicatePaths returns Success when there are no duplicates`() { + val routes = listOf( + createMockRouteInfo("home", "HomeScreen"), + createMockRouteInfo("profile", "ProfileScreen"), + createMockRouteInfo("settings", "SettingsScreen") + ) + + val result = WispValidator.validateDuplicatePaths(routes) + + assertTrue(result is WispValidator.ValidationResult.Success) + } + + @Test + fun `validateDuplicatePaths returns Failure when there are duplicates`() { + val routes = listOf( + createMockRouteInfo("home", "HomeScreen"), + createMockRouteInfo("home", "AnotherHomeScreen") + ) + + val result = WispValidator.validateDuplicatePaths(routes) + + assertTrue(result is WispValidator.ValidationResult.Failure) + val failure = result as WispValidator.ValidationResult.Failure + assertEquals(1, failure.errors.size) + assertTrue(failure.errors[0].contains("path 'home' is already used by multiple routes")) + } + + private fun createMockRouteInfo(path: String, className: String): ObjectRouteInfo { + return ObjectRouteInfo( + routeClassName = ClassName("com.example", className), + factoryClassName = ClassName("com.example", "${className}Factory"), + wispPath = path + ) + } +} From 612c0d2f8ef637dafdb7ee4839f5eeda4c88e228 Mon Sep 17 00:00:00 2001 From: hanminjae Date: Tue, 13 Jan 2026 21:34:34 +0900 Subject: [PATCH 10/11] chore: update ci workflow to run on main branch and improve caching --- .github/workflows/ci.yml | 57 ++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 32 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 985f6d5..cb6a4c3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,24 +2,21 @@ name: CI on: push: - branches: [ main, develop ] + branches: [ "main" ] pull_request: - types: [opened, synchronize, reopened] - branches: [ main, develop ] - workflow_dispatch: - -concurrency: - group: ci-${{ github.ref }} - cancel-in-progress: true + branches: [ "main" ] jobs: - lint: + build-and-test: + name: Build and Test runs-on: ubuntu-latest + permissions: + contents: read + checks: write + steps: - - name: Checkout - uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.sha || github.sha }} + - name: Checkout Code + uses: actions/checkout@v6 - name: Set up JDK 17 uses: actions/setup-java@v4 @@ -28,27 +25,23 @@ jobs: distribution: 'temurin' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v5 + with: + cache-read-only: ${{ github.ref != 'refs/heads/main' }} - - name: Run ktlintCheck + - name: Run Lint Check run: ./gradlew ktlintCheck - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.sha || github.sha }} + - name: Run Unit Tests + run: ./gradlew test --stacktrace - - name: Set up JDK 17 - uses: actions/setup-java@v4 - with: - java-version: '17' - distribution: 'temurin' + - name: Build App (Main Branch Only) + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + run: ./gradlew :app:assembleDebug - - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 - - - name: Build - run: ./gradlew build + - name: Upload Test Results + if: always() + uses: actions/upload-artifact@v6 + with: + name: test-results + path: '**/build/test-results/test/TEST-*.xml' From 095a641a5dfcdb3ea9b45eb500a91317467c37ec Mon Sep 17 00:00:00 2001 From: hanminjae Date: Tue, 13 Jan 2026 21:35:06 +0900 Subject: [PATCH 11/11] chore: ktlint format --- app/build.gradle.kts | 2 +- wisp-annotations/build.gradle.kts | 2 +- wisp-processor/build.gradle.kts | 2 +- .../wisp/mapper/RouteInfoMapperTest.kt | 20 +++++++++---------- .../parser/DefaultWispUriParserTest.kt | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 943acfd..4d4246d 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -69,4 +69,4 @@ dependencies { androidTestImplementation(libs.androidx.navigation.testing) debugImplementation(libs.androidx.compose.ui.tooling) debugImplementation(libs.androidx.compose.ui.test.manifest) -} \ No newline at end of file +} diff --git a/wisp-annotations/build.gradle.kts b/wisp-annotations/build.gradle.kts index 941e7ec..8b1dfa6 100644 --- a/wisp-annotations/build.gradle.kts +++ b/wisp-annotations/build.gradle.kts @@ -4,4 +4,4 @@ plugins { kotlin { jvmToolchain(libs.versions.jvmTarget.get().toInt()) -} \ No newline at end of file +} diff --git a/wisp-processor/build.gradle.kts b/wisp-processor/build.gradle.kts index 23cb93b..f4e4351 100644 --- a/wisp-processor/build.gradle.kts +++ b/wisp-processor/build.gradle.kts @@ -18,4 +18,4 @@ dependencies { testImplementation(libs.mockito.core) testImplementation(libs.mockito.kotlin) -} \ No newline at end of file +} diff --git a/wisp-processor/src/test/java/com/angrypodo/wisp/mapper/RouteInfoMapperTest.kt b/wisp-processor/src/test/java/com/angrypodo/wisp/mapper/RouteInfoMapperTest.kt index b1fb968..67fad90 100644 --- a/wisp-processor/src/test/java/com/angrypodo/wisp/mapper/RouteInfoMapperTest.kt +++ b/wisp-processor/src/test/java/com/angrypodo/wisp/mapper/RouteInfoMapperTest.kt @@ -31,10 +31,10 @@ class RouteInfoMapperTest { fun `toRouteInfo returns ObjectRouteInfo for object declaration`() { val mockPackageName = mock() whenever(mockPackageName.asString()).thenReturn("com.example") - + val mockSimpleName = mock() whenever(mockSimpleName.asString()).thenReturn("HomeScreen") - + val mockQualifiedName = mock() whenever(mockQualifiedName.asString()).thenReturn("com.example.HomeScreen") @@ -43,7 +43,7 @@ class RouteInfoMapperTest { whenever(classDeclaration.packageName).thenReturn(mockPackageName) whenever(classDeclaration.simpleName).thenReturn(mockSimpleName) whenever(classDeclaration.qualifiedName).thenReturn(mockQualifiedName) - + val mockAnnotation = createMockWispAnnotation("home") whenever(classDeclaration.annotations).thenReturn(sequenceOf(mockAnnotation)) @@ -58,10 +58,10 @@ class RouteInfoMapperTest { fun `toRouteInfo returns ClassRouteInfo for class declaration`() { val mockPackageName = mock() whenever(mockPackageName.asString()).thenReturn("com.example") - + val mockSimpleName = mock() whenever(mockSimpleName.asString()).thenReturn("ProfileScreen") - + val mockQualifiedName = mock() whenever(mockQualifiedName.asString()).thenReturn("com.example.ProfileScreen") @@ -71,7 +71,7 @@ class RouteInfoMapperTest { whenever(classDeclaration.simpleName).thenReturn(mockSimpleName) whenever(classDeclaration.qualifiedName).thenReturn(mockQualifiedName) whenever(classDeclaration.primaryConstructor).thenReturn(null) - + val mockAnnotation = createMockWispAnnotation("profile") whenever(classDeclaration.annotations).thenReturn(sequenceOf(mockAnnotation)) @@ -83,19 +83,19 @@ class RouteInfoMapperTest { private fun createMockWispAnnotation(path: String): KSAnnotation { val annotation = mock() - + val shortName = mock() whenever(shortName.asString()).thenReturn("Wisp") whenever(annotation.shortName).thenReturn(shortName) - + val arg = mock() val argName = mock() whenever(argName.asString()).thenReturn("path") whenever(arg.name).thenReturn(argName) whenever(arg.value).thenReturn(path) - + whenever(annotation.arguments).thenReturn(listOf(arg)) - + return annotation } } diff --git a/wisp-runtime/src/test/java/com/angrypodo/wisp/runtime/parser/DefaultWispUriParserTest.kt b/wisp-runtime/src/test/java/com/angrypodo/wisp/runtime/parser/DefaultWispUriParserTest.kt index c65185e..3bef796 100644 --- a/wisp-runtime/src/test/java/com/angrypodo/wisp/runtime/parser/DefaultWispUriParserTest.kt +++ b/wisp-runtime/src/test/java/com/angrypodo/wisp/runtime/parser/DefaultWispUriParserTest.kt @@ -38,4 +38,4 @@ class DefaultWispUriParserTest { val result = parser.parse(uri) assertEquals(listOf("product"), result) } -} \ No newline at end of file +}