diff --git a/build.gradle.kts b/build.gradle.kts index 1e290154..66c15569 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,7 +5,7 @@ plugins { alias(libs.plugins.com.android.library) apply false alias(libs.plugins.com.android.application) apply false alias(libs.plugins.dev.icerock.mobile.multiplatform.resources) apply false - alias(libs.plugins.org.kodein.mock.mockmp) apply false + alias(libs.plugins.io.mockative) apply false alias(libs.plugins.com.vanniktech.maven.publish) apply false } diff --git a/gradle.properties b/gradle.properties index d7be2106..a98155b7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,9 @@ org.gradle.jvmargs=-Xmx1536m kotlin.code.style=official android.useAndroidX=true kotlin.js.yarn=false - +# https://github.com/mockative/mockative?tab=readme-ov-file#installation-for-multiplatform-projects +ksp.useKSP2=true +ksp.incremental=false org.jetbrains.compose.experimental.jscanvas.enabled=true org.jetbrains.compose.experimental.macos.enabled=true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5d3da458..c2261124 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -9,21 +9,73 @@ compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = " org-jetbrains-compose = { id = "org.jetbrains.compose", version.ref = "compose-jb" } com-vanniktech-maven-publish = { id = "com.vanniktech.maven.publish", version.ref = "vanniktech-publish" } dev-icerock-mobile-multiplatform-resources = { id = "dev.icerock.mobile.multiplatform-resources", version.ref = "multiplatform-resources" } -org-kodein-mock-mockmp = { id = "org.kodein.mock.mockmp", version.ref = "mockmp" } +io-mockative = { id = "io.mockative", version.ref = "mockative" } [versions] kotlin = "2.0.21" +## ⬆ = "2.1.0-Beta1" +## ⬆ = "2.1.0-Beta2" +## ⬆ = "2.1.0-RC" agp = "8.5.2" +##⬆= "8.6.0-alpha01" +##⬆= "8.6.0-alpha02" +##⬆= "8.6.0-alpha03" +##⬆= "8.6.0-alpha04" +##⬆= "8.6.0-alpha05" +##⬆= "8.6.0-alpha06" +##⬆= "8.6.0-alpha07" +##⬆= "8.6.0-alpha08" +##⬆= "8.6.0-beta01" +##⬆= "8.6.0-beta02" +##⬆= "8.6.0-rc01" +##⬆= "8.6.0" +##⬆= "8.6.1" +##⬆= "8.7.0-alpha01" +##⬆= "8.7.0-alpha02" +##⬆= "8.7.0-alpha03" +##⬆= "8.7.0-alpha04" +##⬆= "8.7.0-alpha05" +##⬆= "8.7.0-alpha06" +##⬆= "8.7.0-alpha07" +##⬆= "8.7.0-alpha08" +##⬆= "8.7.0-alpha09" +##⬆= "8.7.0-beta01" +##⬆= "8.7.0-beta02" +##⬆= "8.7.0-rc01" +##⬆= "8.7.0" +##⬆= "8.7.1" +##⬆= "8.7.2" +##⬆= "8.8.0-alpha01" +##⬆= "8.8.0-alpha02" +##⬆= "8.8.0-alpha03" +##⬆= "8.8.0-alpha04" +##⬆= "8.8.0-alpha05" +##⬆= "8.8.0-alpha06" +##⬆= "8.8.0-alpha07" +##⬆= "8.8.0-alpha08" +##⬆= "8.8.0-alpha09" compose-jb = "1.7.0" +## ⬆ = "1.8.0-dev1868" +## ⬆ = "1.8.0-dev1869" +## ⬆ = "1.8.0-dev1873" +## ⬆ = "1.8.0-dev1875" +## ⬆ = "1.8.0-dev1883" +## ⬆ = "1.8.0-dev1890" +## ⬆ = "1.8.0-dev1897" +## ⬆ = "1.8.0-dev1899" +## ⬆ = "1.8.0-dev1905" vanniktech-publish = "0.30.0" okio = "3.9.1" multiplatform-resources = "0.24.3" -mockmp = "1.17.0" +mockative = "3.0.0" kermit = "2.0.4" androidx-activity = "1.9.3" -androidx-lifecycle = "2.8.6" +## ⬆ = "1.10.0-alpha01" +## ⬆ = "1.10.0-alpha02" +## ⬆ = "1.10.0-alpha03" +androidx-lifecycle = "2.8.7" androidx-startup = "1.2.0" androidx-appcompat = "1.7.0" androidx-runner = "1.6.2" diff --git a/libphonenumber/build.gradle.kts b/libphonenumber/build.gradle.kts index a7593d8a..6392d17e 100644 --- a/libphonenumber/build.gradle.kts +++ b/libphonenumber/build.gradle.kts @@ -1,10 +1,9 @@ import com.vanniktech.maven.publish.SonatypeHost -import org.gradle.kotlin.dsl.implementation plugins { alias(libs.plugins.org.jetbrains.kotlin.multiplatform) alias(libs.plugins.com.android.library) - alias(libs.plugins.org.kodein.mock.mockmp) + alias(libs.plugins.io.mockative) alias(libs.plugins.com.vanniktech.maven.publish) alias(libs.plugins.org.jetbrains.compose) alias(libs.plugins.compose.compiler) @@ -121,6 +120,10 @@ kotlin { } } +compose.resources { + publicResClass = true +} + android { namespace = "io.michaelrocks.libphonenumber.kotlin" compileSdk = 34 @@ -153,11 +156,6 @@ android { } } -mockmp { - usesHelper = true - installWorkaround() // (3) -} - // https://youtrack.jetbrains.com/issue/KT-46466 val dependsOnTasks = mutableListOf() tasks.withType().configureEach { diff --git a/libphonenumber/src/commonMain/kotlin/io/michaelrocks/libphonenumber/kotlin/metadata/source/MetadataSource.kt b/libphonenumber/src/commonMain/kotlin/io/michaelrocks/libphonenumber/kotlin/metadata/source/MetadataSource.kt index 40f23888..f1d93b57 100644 --- a/libphonenumber/src/commonMain/kotlin/io/michaelrocks/libphonenumber/kotlin/metadata/source/MetadataSource.kt +++ b/libphonenumber/src/commonMain/kotlin/io/michaelrocks/libphonenumber/kotlin/metadata/source/MetadataSource.kt @@ -16,8 +16,7 @@ */ package io.michaelrocks.libphonenumber.kotlin.metadata.source -import io.michaelrocks.libphonenumber.kotlin.metadata.source.NonGeographicalEntityMetadataSource -import io.michaelrocks.libphonenumber.kotlin.metadata.source.RegionMetadataSource +import io.mockative.Mockable /** A source of phone metadata split by different regions. */ interface MetadataSource : RegionMetadataSource, NonGeographicalEntityMetadataSource diff --git a/libphonenumber/src/commonTest/kotlin/io/michaelrocks/libphonenumber/kotlin/PhoneNumberUtilTest.kt b/libphonenumber/src/commonTest/kotlin/io/michaelrocks/libphonenumber/kotlin/PhoneNumberUtilTest.kt index c78fe187..4ae85084 100644 --- a/libphonenumber/src/commonTest/kotlin/io/michaelrocks/libphonenumber/kotlin/PhoneNumberUtilTest.kt +++ b/libphonenumber/src/commonTest/kotlin/io/michaelrocks/libphonenumber/kotlin/PhoneNumberUtilTest.kt @@ -31,8 +31,9 @@ import io.michaelrocks.libphonenumber.kotlin.metadata.source.MetadataSource import io.michaelrocks.libphonenumber.kotlin.util.InplaceStringBuilder import io.michaelrocks.libphonenumber.kotlin.utils.RegionCode import io.michaelrocks.libphonenumber.kotlin.utils.assertThrows -import org.kodein.mock.Mock -import org.kodein.mock.Mocker +import io.mockative.MockState.Companion.mock +import io.mockative.every +import io.mockative.of import kotlin.test.* /** @@ -48,17 +49,15 @@ class PhoneNumberUtilTest : TestMetadataTestCase() { override val metadataLoader: MetadataLoader get() = defaultMetadataLoader() - @Mock - lateinit var mockedMetadataSource: MetadataSource + + val mockedMetadataSource = mock(of()) lateinit var phoneNumberUtilWithMissingMetadata: PhoneNumberUtil - val mocker = Mocker() @BeforeTest fun setUp() { - mocker.reset() //(1) - this.injectMocks(mocker) //(2) + mockedMetadataSource.reset() phoneNumberUtilWithMissingMetadata = PhoneNumberUtil( mockedMetadataSource, DefaultMetadataDependenciesProvider(metadataLoader), countryCodeToRegionCodeMap ) @@ -3620,7 +3619,7 @@ class PhoneNumberUtilTest : TestMetadataTestCase() { @Test fun testGetMetadataForRegionForMissingMetadata() { - mocker.every { mockedMetadataSource.getMetadataForRegion(isAny()) } returns null + every { mockedMetadataSource.getMetadataForRegion(isAny()) } returns null assertThrows( MissingMetadataException::class ) { phoneNumberUtilWithMissingMetadata.getMetadataForRegion(RegionCode.US) } @@ -3628,7 +3627,7 @@ class PhoneNumberUtilTest : TestMetadataTestCase() { @Test fun testGetMetadataForNonGeographicalRegionForMissingMetadata() { - mocker.every { mockedMetadataSource.getMetadataForNonGeographicalRegion(isAny()) } returns null + every { mockedMetadataSource.getMetadataForNonGeographicalRegion(isAny()) } returns null assertThrows( MissingMetadataException::class ) { phoneNumberUtilWithMissingMetadata.getMetadataForNonGeographicalRegion(800) } diff --git a/libphonenumber/src/nativeMain/kotlin/io/michaelrocks/libphonenumber/kotlin/metadata/defaultMetadataLoader.native.kt b/libphonenumber/src/nativeMain/kotlin/io/michaelrocks/libphonenumber/kotlin/metadata/defaultMetadataLoader.native.kt index 1ff789f1..165dedec 100644 --- a/libphonenumber/src/nativeMain/kotlin/io/michaelrocks/libphonenumber/kotlin/metadata/defaultMetadataLoader.native.kt +++ b/libphonenumber/src/nativeMain/kotlin/io/michaelrocks/libphonenumber/kotlin/metadata/defaultMetadataLoader.native.kt @@ -1,8 +1,8 @@ package io.michaelrocks.libphonenumber.kotlin.metadata import io.michaelrocks.libphonenumber.kotlin.MetadataLoader -import io.michaelrocks.libphonenumber.kotlin.metadata.init.MokoAssetResourceMetadataLoader +import io.michaelrocks.libphonenumber.kotlin.metadata.init.ComposeResourceMetadataLoader actual fun defaultMetadataLoader(): MetadataLoader { - return MokoAssetResourceMetadataLoader() + return ComposeResourceMetadataLoader() } \ No newline at end of file diff --git a/libphonenumber/src/nativeMain/kotlin/io/michaelrocks/libphonenumber/kotlin/metadata/init/MokoAssetResourceMetadataLoader.kt b/libphonenumber/src/nativeMain/kotlin/io/michaelrocks/libphonenumber/kotlin/metadata/init/ComposeResourceMetadataLoader.kt similarity index 50% rename from libphonenumber/src/nativeMain/kotlin/io/michaelrocks/libphonenumber/kotlin/metadata/init/MokoAssetResourceMetadataLoader.kt rename to libphonenumber/src/nativeMain/kotlin/io/michaelrocks/libphonenumber/kotlin/metadata/init/ComposeResourceMetadataLoader.kt index dcc6d777..4e94c2ed 100644 --- a/libphonenumber/src/nativeMain/kotlin/io/michaelrocks/libphonenumber/kotlin/metadata/init/MokoAssetResourceMetadataLoader.kt +++ b/libphonenumber/src/nativeMain/kotlin/io/michaelrocks/libphonenumber/kotlin/metadata/init/ComposeResourceMetadataLoader.kt @@ -17,22 +17,23 @@ package io.michaelrocks.libphonenumber.kotlin.metadata.init import co.touchlab.kermit.Logger -import dev.icerock.moko.resources.AssetResource import io.michaelrocks.libphonenumber.kotlin.MetadataLoader import io.michaelrocks.libphonenumber.kotlin.io.InputStream import io.michaelrocks.libphonenumber.kotlin.io.OkioInputStream import okio.FileSystem import okio.Path.Companion.toPath import okio.buffer +import org.jetbrains.compose.resources.MissingResourceException +import platform.Foundation.* /** * A [MetadataLoader] implementation that reads phone number metadata files as classpath * resources. */ -class MokoAssetResourceMetadataLoader : MetadataLoader { - override fun loadMetadata(phoneMetadataResource: AssetResource): InputStream? { +class ComposeResourceMetadataLoader : MetadataLoader { + override fun loadMetadata(phoneMetadataResource: String): InputStream? { return try { - val path = phoneMetadataResource.path.toPath() + val path = getPathOnDisk(phoneMetadataResource).toPath() OkioInputStream(FileSystem.SYSTEM.source(path).buffer()) } catch (t: Throwable) { logger.v("Failed to load metadata from $phoneMetadataResource.path", t) @@ -40,9 +41,24 @@ class MokoAssetResourceMetadataLoader : MetadataLoader { } } + + // https://github.com/JetBrains/compose-multiplatform/blob/bf6b00e9a22bb9885a44581418b289afcfa81b5b/components/resources/library/src/macosMain/kotlin/org/jetbrains/compose/resources/ResourceReader.macos.kt#L8 + private fun getPathOnDisk(path: String): String { + val fm = NSFileManager.defaultManager() + val currentDirectoryPath = fm.currentDirectoryPath + println("currentDirectoryPath: $currentDirectoryPath") + return listOf( + //todo in future bundle resources with app and use all sourceSets (skikoMain, nativeMain) + "$currentDirectoryPath/../libphonenumber/src/macosMain/composeResources/$path", + "$currentDirectoryPath/../libphonenumber/src/macosTest/composeResources/$path", + "$currentDirectoryPath/../libphonenumber/src/commonMain/composeResources/$path", + "$currentDirectoryPath/../libphonenumber/src/commonTest/composeResources/$path" + ).firstOrNull { p -> fm.fileExistsAtPath(p) } ?: throw MissingResourceException(path) + } + companion object { private val logger = Logger.withTag( - MokoAssetResourceMetadataLoader::class.simpleName.toString() + ComposeResourceMetadataLoader::class.simpleName.toString() ) } } diff --git a/library-test-resources/build.gradle.kts b/library-test-resources/build.gradle.kts index f9f84cc0..f727dd61 100644 --- a/library-test-resources/build.gradle.kts +++ b/library-test-resources/build.gradle.kts @@ -45,6 +45,7 @@ kotlin { } val commonMain by getting { dependencies { + implementation(compose.runtime) implementation(compose.components.resources) } } diff --git a/sample/build.gradle.kts b/sample/build.gradle.kts index 5eeef13c..29943ea2 100644 --- a/sample/build.gradle.kts +++ b/sample/build.gradle.kts @@ -1,6 +1,7 @@ import org.jetbrains.compose.desktop.application.dsl.TargetFormat import org.jetbrains.compose.desktop.application.tasks.AbstractNativeMacApplicationPackageAppDirTask import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractExecutable +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBinary import org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink import org.jetbrains.kotlin.library.impl.KotlinLibraryLayoutImpl @@ -26,60 +27,17 @@ kotlin { browser() binaries.executable() } - macosX64 { - binaries { - executable { - entryPoint = "main" - freeCompilerArgs += listOf( - "-linker-option", "-framework", "-linker-option", "Metal" - ) - } - } - } - macosArm64 { - binaries { - executable { - entryPoint = "main" - freeCompilerArgs += listOf( - "-linker-option", "-framework", "-linker-option", "Metal" - ) - } - } - } - iosX64() { - binaries { - executable { - entryPoint = "main" - freeCompilerArgs += listOf( - "-linker-option", "-framework", "-linker-option", "Metal", - "-linker-option", "-framework", "-linker-option", "CoreText", - "-linker-option", "-framework", "-linker-option", "CoreGraphics" - ) - } - } + fun macosTargets(config: KotlinNativeTarget.() -> Unit) { + macosX64(config) + macosArm64(config) } - iosArm64() { - binaries { - executable { - entryPoint = "main" - freeCompilerArgs += listOf( - "-linker-option", "-framework", "-linker-option", "Metal", - "-linker-option", "-framework", "-linker-option", "CoreText", - "-linker-option", "-framework", "-linker-option", "CoreGraphics" - ) - } - } - } - iosSimulatorArm64() { - // TODO: remove after 1.5 release - binaries.forEach { - it.freeCompilerArgs += listOf( - "-linker-option", "-framework", "-linker-option", "Metal", - "-linker-option", "-framework", "-linker-option", "CoreText", - "-linker-option", "-framework", "-linker-option", "CoreGraphics", - ) - } + macosTargets { + binaries.executable() } + iosX64() + iosArm64() + iosSimulatorArm64() + applyDefaultHierarchyTemplate() cocoapods { summary = "Shared code for the sample" @@ -126,37 +84,6 @@ kotlin { implementation(compose.desktop.currentOs) } } - - val jsMain by getting { - dependsOn(commonMain) - dependencies { - } - } - - val nativeMain by creating { - dependsOn(commonMain) - } - val macosMain by creating { - dependsOn(nativeMain) - } - val macosX64Main by getting { - dependsOn(macosMain) - } - val macosArm64Main by getting { - dependsOn(macosMain) - } - val iosMain by creating { - dependsOn(nativeMain) - } - val iosSimulatorArm64Main by getting { - dependsOn(iosMain) - } - val iosX64Main by getting { - dependsOn(iosMain) - } - val iosArm64Main by getting { - dependsOn(iosMain) - } } } @@ -173,12 +100,6 @@ compose.desktop { } -compose.experimental { - web.application {} -} - - - compose.desktop.nativeApplication { targets(kotlin.targets.getByName("macosArm64")) distributions {