From 5720539d9cda6d1d270a8f4bb0234c8d78fe2101 Mon Sep 17 00:00:00 2001 From: CherryPerry Date: Tue, 4 Oct 2022 17:53:18 +0100 Subject: [PATCH 1/9] Branch split --- .github/workflows/build.yml | 67 ++++++++++++++++------------- .github/workflows/documentation.yml | 2 +- 2 files changed, 38 insertions(+), 31 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 73d3130c7..7d959cf96 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,10 +3,14 @@ name: Build on: push: branches: - - main + - 1.x + - 2.x pull_request: workflow_dispatch: +env: + MAIN_BRANCH: ${{ github.ref == 'refs/heads/1.x' || github.ref == 'refs/heads/2.x' }} + jobs: build: name: Build @@ -20,33 +24,35 @@ jobs: - uses: gradle/wrapper-validation-action@v1 - uses: gradle/gradle-build-action@v2 with: - arguments: | - build - projectHealth - mergeLintSarif - mergeDetektSarif - :plugins:buildPlugins - --continue - # checks integrity of release tasks, update publish workflows too if does not work - - uses: gradle/gradle-build-action@v2 - with: - arguments: | - publishAppyxReleasePublicationToOSSRHRepository - publishAppyxReleasePublicationToSonatypeSnapshotRepository - --dry-run - --no-parallel - - uses: gradle/gradle-build-action@v2 - if: github.ref == 'refs/heads/main' && github.repository == 'bumble-tech/appyx' + cache-read-only: ${{ env.MAIN_BRANCH != 'true' }} + - name: Build + run: > + ./gradlew + build + projectHealth + mergeLintSarif + mergeDetektSarif + :plugins:buildPlugins + --continue + - name: Check publication setup + run: > + ./gradlew + publishAppyxReleasePublicationToOSSRHRepository + publishAppyxReleasePublicationToSonatypeSnapshotRepository + --dry-run + --no-parallel + - name: Deploy snapshot + if: env.MAIN_BRANCH == 'true' && github.repository == 'bumble-tech/appyx' env: SIGNING_KEY: ${{ secrets.SIGNING_KEY }} - with: - arguments: | - publishAppyxReleasePublicationToSonatypeSnapshotRepository - -Psnapshot=true - --no-parallel - -Psigning.password=${{ secrets.SIGNING_PASSWORD }} - -Psonatype.username=${{ secrets.SONATYPE_USERNAME }} - -Psonatype.password=${{ secrets.SONATYPE_PASSWORD }} + run: > + ./gradlew + publishAppyxReleasePublicationToSonatypeSnapshotRepository + -Psnapshot=true + --no-parallel + -Psigning.password=${{ secrets.SIGNING_PASSWORD }} + -Psonatype.username=${{ secrets.SONATYPE_USERNAME }} + -Psonatype.password=${{ secrets.SONATYPE_PASSWORD }} - uses: github/codeql-action/upload-sarif@v2 if: success() || failure() with: @@ -67,7 +73,7 @@ jobs: instrumentation-tests: name: Instrumentation tests runs-on: macOS-latest - timeout-minutes: 60 + timeout-minutes: 30 steps: - uses: actions/checkout@v3 - uses: actions/setup-java@v3 @@ -75,10 +81,11 @@ jobs: distribution: 'zulu' java-version: '11' - uses: gradle/wrapper-validation-action@v1 - - name: Pre build sources before launching emulator - uses: gradle/gradle-build-action@v2 + - uses: gradle/gradle-build-action@v2 with: - arguments: compileDebugAndroidTestSources + cache-read-only: ${{ env.MAIN_BRANCH != 'true' }} + - name: Pre build sources before launching emulator + run: ./gradlew compileDebugAndroidTestSources - name: AVD cache uses: actions/cache@v3 id: avd-cache diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index a75372876..f2a5f59a6 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -3,7 +3,7 @@ name: Deploy mkdocs to GitHub Pages on: push: branches: - - main + - 1.x workflow_dispatch: jobs: From 92a2a0ce47a49b392226815efbf7da4eba53a55d Mon Sep 17 00:00:00 2001 From: CherryPerry Date: Wed, 5 Oct 2022 11:15:44 +0100 Subject: [PATCH 2/9] Split snapshot versions --- documentation/releases/downloads.md | 4 ++-- gradle.properties | 2 +- .../src/main/kotlin/ProjectPlugin.kt | 23 +++++++++++++------ 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/documentation/releases/downloads.md b/documentation/releases/downloads.md index 1355be67c..d2085deb6 100644 --- a/documentation/releases/downloads.md +++ b/documentation/releases/downloads.md @@ -47,7 +47,7 @@ dependencies { ## Snapshot -Snapshot version is available for all modules, use the provided repository url and `main-SNAPSHOT` version. +Snapshot version is available for all modules, use the provided repository url and `1-SNAPSHOT` version. ```groovy repositories { @@ -55,6 +55,6 @@ repositories { } dependencies { - implementation "com.bumble.appyx:core:main-SNAPSHOT" + implementation "com.bumble.appyx:core:v1-SNAPSHOT" } ``` diff --git a/gradle.properties b/gradle.properties index dc4439f6a..caeb12ca1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,4 @@ org.gradle.caching=true org.gradle.parallel=true android.useAndroidX=true kotlin.code.style=official -library.version=1.0-alpha09 +library.version=1.0.0-alpha09 diff --git a/plugins/publish-plugin/src/main/kotlin/ProjectPlugin.kt b/plugins/publish-plugin/src/main/kotlin/ProjectPlugin.kt index bc765b026..46e9c3eba 100644 --- a/plugins/publish-plugin/src/main/kotlin/ProjectPlugin.kt +++ b/plugins/publish-plugin/src/main/kotlin/ProjectPlugin.kt @@ -8,6 +8,7 @@ import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.create import org.gradle.kotlin.dsl.get import org.gradle.plugins.signing.SigningExtension +import org.jetbrains.kotlin.gradle.targets.js.npm.SemVer internal abstract class ProjectPlugin : Plugin { override fun apply(project: Project) { @@ -28,7 +29,7 @@ internal abstract class ProjectPlugin : Plugin { } project.tasks.named("publishAppyxReleasePublicationToSonatypeSnapshotRepository") { - val fail = project.findProperty("snapshot") != "true" + val fail = project.isSnapshotPublication doFirst { if (fail) throw GradleException( "Publishing to snapshot repository with disabled \"snapshot\" flag is permitted" @@ -67,15 +68,15 @@ internal abstract class ProjectPlugin : Plugin { private fun PublicationContainer.setupPublications(project: Project) { create("appyxRelease") { + val definedVersion = project.findProperty("library.version")?.toString() + ?: throw GradleException("'library.version' has not been set") from(project.components[getComponentName()]) groupId = "com.bumble.appyx" - version = if (project.findProperty("snapshot") == "true") { - "main-SNAPSHOT" + version = if (project.isSnapshotPublication) { + val semVer = SemVer.from(definedVersion) + "v${semVer.major}-SNAPSHOT" } else { - if (!project.hasProperty("library.version")) { - throw GradleException("'library.version' has not been set") - } - project.property("library.version").toString() + definedVersion } pom { @@ -116,4 +117,12 @@ internal abstract class ProjectPlugin : Plugin { ) } } + + private companion object { + + val Project.isSnapshotPublication: Boolean + get() = findProperty("snapshot") == "true" + + } + } From 4455442f769395119bcc053b8d64af0e85211c3d Mon Sep 17 00:00:00 2001 From: CherryPerry Date: Wed, 5 Oct 2022 17:45:54 +0100 Subject: [PATCH 3/9] Make version stable --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index caeb12ca1..78564903d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,4 @@ org.gradle.caching=true org.gradle.parallel=true android.useAndroidX=true kotlin.code.style=official -library.version=1.0.0-alpha09 +library.version=1.0.0 From 821f4771322193313fdd08d5b6eded922bfc2cca Mon Sep 17 00:00:00 2001 From: andreykovalev Date: Sat, 8 Oct 2022 10:11:07 +0100 Subject: [PATCH 4/9] Remove plugin implementation from view and retrieve node instance from LocalComposition --- .../appyx/core/plugin/AppyxTestScenario.kt | 6 +-- .../plugin/BackPressHandlerTestActivity.kt | 4 +- .../appyx/core/node/AbstractParentNodeView.kt | 19 --------- .../bumble/appyx/core/node/EmptyNodeViews.kt | 2 +- .../com/bumble/appyx/core/node/ParentNode.kt | 4 +- .../bumble/appyx/core/node/ParentNodeView.kt | 12 +++++- .../src/main/AndroidManifest.xml | 2 +- ...yxViewActivity.kt => AppyxTestActivity.kt} | 6 +-- ...yxTestRule.kt => AppyxActivityTestRule.kt} | 10 ++--- .../ui/rules/AppyxParentViewTestRule.kt | 19 --------- .../testing/ui/rules/AppyxViewTestRule.kt | 17 +++++--- .../appyx/testing/ui/utils/DummyNavModel.kt | 4 +- .../mvicoreexample/MviCoreExampleViewTest.kt | 6 +-- .../client/test/AppyxMviParentViewTestRule.kt | 41 ------------------- .../sandbox/client/test/AppyxViewRules.kt | 17 ++------ .../mvicoreexample/MviCoreExampleView.kt | 6 +-- .../bumble/appyx/sandbox/stub/NodeViewStub.kt | 4 +- 17 files changed, 51 insertions(+), 128 deletions(-) delete mode 100644 libraries/core/src/main/kotlin/com/bumble/appyx/core/node/AbstractParentNodeView.kt rename libraries/testing-ui-activity/src/main/kotlin/com/bumble/appyx/testing/ui/rules/{AppyxViewActivity.kt => AppyxTestActivity.kt} (74%) rename libraries/testing-ui/src/main/kotlin/com/bumble/appyx/testing/ui/rules/{AppyxTestRule.kt => AppyxActivityTestRule.kt} (89%) delete mode 100644 libraries/testing-ui/src/main/kotlin/com/bumble/appyx/testing/ui/rules/AppyxParentViewTestRule.kt delete mode 100644 samples/sandbox/src/androidTest/kotlin/com/bumble/appyx/sandbox/client/test/AppyxMviParentViewTestRule.kt diff --git a/libraries/core/src/androidTest/kotlin/com/bumble/appyx/core/plugin/AppyxTestScenario.kt b/libraries/core/src/androidTest/kotlin/com/bumble/appyx/core/plugin/AppyxTestScenario.kt index db5e6e5d0..c928d58cd 100644 --- a/libraries/core/src/androidTest/kotlin/com/bumble/appyx/core/plugin/AppyxTestScenario.kt +++ b/libraries/core/src/androidTest/kotlin/com/bumble/appyx/core/plugin/AppyxTestScenario.kt @@ -8,12 +8,12 @@ import androidx.test.core.app.ActivityScenario import com.bumble.appyx.core.integration.NodeFactory import com.bumble.appyx.core.integration.NodeHost import com.bumble.appyx.core.node.Node -import com.bumble.appyx.testing.ui.rules.AppyxViewActivity +import com.bumble.appyx.testing.ui.rules.AppyxTestActivity import java.util.concurrent.CountDownLatch import java.util.concurrent.TimeUnit /** - * [com.bumble.appyx.testing.ui.rules.AppyxTestRule] based on [ActivityScenario] to support lifecycle tests. + * [com.bumble.appyx.testing.ui.rules.AppyxActivityTestRule] based on [ActivityScenario] to support lifecycle tests. * * TODO: Consider merging with AppyxTestRule. */ @@ -27,7 +27,7 @@ class AppyxTestScenario( @get:WorkerThread val activityScenario: ActivityScenario by lazy { val awaitNode = CountDownLatch(1) - AppyxViewActivity.composableView = { activity -> + AppyxTestActivity.composableView = { activity -> decorator { NodeHost(integrationPoint = activity.appyxIntegrationPoint, factory = { buildContext -> node = nodeFactory.create(buildContext) diff --git a/libraries/core/src/androidTest/kotlin/com/bumble/appyx/core/plugin/BackPressHandlerTestActivity.kt b/libraries/core/src/androidTest/kotlin/com/bumble/appyx/core/plugin/BackPressHandlerTestActivity.kt index 29abe6eb0..d3a5bbbd2 100644 --- a/libraries/core/src/androidTest/kotlin/com/bumble/appyx/core/plugin/BackPressHandlerTestActivity.kt +++ b/libraries/core/src/androidTest/kotlin/com/bumble/appyx/core/plugin/BackPressHandlerTestActivity.kt @@ -3,11 +3,11 @@ package com.bumble.appyx.core.plugin import android.os.Bundle import androidx.activity.OnBackPressedCallback import androidx.lifecycle.lifecycleScope -import com.bumble.appyx.testing.ui.rules.AppyxViewActivity +import com.bumble.appyx.testing.ui.rules.AppyxTestActivity import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.launch -class BackPressHandlerTestActivity : AppyxViewActivity() { +class BackPressHandlerTestActivity : AppyxTestActivity() { private val callback = object : OnBackPressedCallback(handleBackPress.value) { override fun handleOnBackPressed() { diff --git a/libraries/core/src/main/kotlin/com/bumble/appyx/core/node/AbstractParentNodeView.kt b/libraries/core/src/main/kotlin/com/bumble/appyx/core/node/AbstractParentNodeView.kt deleted file mode 100644 index 9516bc933..000000000 --- a/libraries/core/src/main/kotlin/com/bumble/appyx/core/node/AbstractParentNodeView.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.bumble.appyx.core.node - -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier - -abstract class AbstractParentNodeView : ParentNodeView { - - final override lateinit var node: ParentNode - private set - - override fun init(node: ParentNode) { - this.node = node - } - - @Composable - override fun View(modifier: Modifier) { - node.NodeView(modifier = modifier) - } -} diff --git a/libraries/core/src/main/kotlin/com/bumble/appyx/core/node/EmptyNodeViews.kt b/libraries/core/src/main/kotlin/com/bumble/appyx/core/node/EmptyNodeViews.kt index e0091ff5c..bcbde45ca 100644 --- a/libraries/core/src/main/kotlin/com/bumble/appyx/core/node/EmptyNodeViews.kt +++ b/libraries/core/src/main/kotlin/com/bumble/appyx/core/node/EmptyNodeViews.kt @@ -9,7 +9,7 @@ object EmptyNodeView : NodeView { override fun View(modifier: Modifier) = Unit } -class EmptyParentNodeView : AbstractParentNodeView() { +class EmptyParentNodeView : ParentNodeView { @Composable override fun ParentNode.NodeView(modifier: Modifier) = Unit diff --git a/libraries/core/src/main/kotlin/com/bumble/appyx/core/node/ParentNode.kt b/libraries/core/src/main/kotlin/com/bumble/appyx/core/node/ParentNode.kt index 54441fb5f..0d86e496b 100644 --- a/libraries/core/src/main/kotlin/com/bumble/appyx/core/node/ParentNode.kt +++ b/libraries/core/src/main/kotlin/com/bumble/appyx/core/node/ParentNode.kt @@ -27,9 +27,9 @@ import com.bumble.appyx.core.children.nodeOrNull import com.bumble.appyx.core.composable.ChildRenderer import com.bumble.appyx.core.lifecycle.ChildNodeLifecycleManager import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.navigation.NavKey import com.bumble.appyx.core.navigation.NavModel import com.bumble.appyx.core.navigation.Resolver -import com.bumble.appyx.core.navigation.NavKey import com.bumble.appyx.core.navigation.isTransitioning import com.bumble.appyx.core.navigation.model.combined.plus import com.bumble.appyx.core.navigation.model.permanent.PermanentNavModel @@ -56,7 +56,7 @@ abstract class ParentNode( ) : Node( view = view, buildContext = buildContext, - plugins = plugins + navModel + childAware + view + plugins = plugins + navModel + childAware ), Resolver { private val permanentNavModel = PermanentNavModel( diff --git a/libraries/core/src/main/kotlin/com/bumble/appyx/core/node/ParentNodeView.kt b/libraries/core/src/main/kotlin/com/bumble/appyx/core/node/ParentNodeView.kt index 3bc3f6cb1..6fc2e1b2f 100644 --- a/libraries/core/src/main/kotlin/com/bumble/appyx/core/node/ParentNodeView.kt +++ b/libraries/core/src/main/kotlin/com/bumble/appyx/core/node/ParentNodeView.kt @@ -2,9 +2,17 @@ package com.bumble.appyx.core.node import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import com.bumble.appyx.core.plugin.NodeAware -interface ParentNodeView : NodeView, NodeAware> { +interface ParentNodeView : NodeView { + @Composable fun ParentNode.NodeView(modifier: Modifier) + + @Suppress("UNCHECKED_CAST") + @Composable + override fun View(modifier: Modifier) { + val node = LocalNode.current as? ParentNode + ?: error("${this::class.qualifiedName} is not provided to the appropriate ParentNode") + node.NodeView(modifier = modifier) + } } diff --git a/libraries/testing-ui-activity/src/main/AndroidManifest.xml b/libraries/testing-ui-activity/src/main/AndroidManifest.xml index 9820fdd83..dea581695 100644 --- a/libraries/testing-ui-activity/src/main/AndroidManifest.xml +++ b/libraries/testing-ui-activity/src/main/AndroidManifest.xml @@ -3,7 +3,7 @@ diff --git a/libraries/testing-ui-activity/src/main/kotlin/com/bumble/appyx/testing/ui/rules/AppyxViewActivity.kt b/libraries/testing-ui-activity/src/main/kotlin/com/bumble/appyx/testing/ui/rules/AppyxTestActivity.kt similarity index 74% rename from libraries/testing-ui-activity/src/main/kotlin/com/bumble/appyx/testing/ui/rules/AppyxViewActivity.kt rename to libraries/testing-ui-activity/src/main/kotlin/com/bumble/appyx/testing/ui/rules/AppyxTestActivity.kt index 47a2071a1..a6f980e21 100644 --- a/libraries/testing-ui-activity/src/main/kotlin/com/bumble/appyx/testing/ui/rules/AppyxViewActivity.kt +++ b/libraries/testing-ui-activity/src/main/kotlin/com/bumble/appyx/testing/ui/rules/AppyxTestActivity.kt @@ -5,19 +5,19 @@ import androidx.activity.compose.setContent import androidx.compose.runtime.Composable import com.bumble.appyx.core.integrationpoint.NodeActivity -open class AppyxViewActivity : NodeActivity() { +open class AppyxTestActivity : NodeActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val composableView = composableView setContent { - requireNotNull(composableView) { "AppyxViewActivity View has not been setup" } + requireNotNull(composableView) { "AppyxTestActivity View has not been setup" } composableView(this) } } companion object { - var composableView: (@Composable (activity: AppyxViewActivity) -> Unit)? = null + var composableView: (@Composable (activity: AppyxTestActivity) -> Unit)? = null } } diff --git a/libraries/testing-ui/src/main/kotlin/com/bumble/appyx/testing/ui/rules/AppyxTestRule.kt b/libraries/testing-ui/src/main/kotlin/com/bumble/appyx/testing/ui/rules/AppyxActivityTestRule.kt similarity index 89% rename from libraries/testing-ui/src/main/kotlin/com/bumble/appyx/testing/ui/rules/AppyxTestRule.kt rename to libraries/testing-ui/src/main/kotlin/com/bumble/appyx/testing/ui/rules/AppyxActivityTestRule.kt index 9bae267ab..404aafb08 100644 --- a/libraries/testing-ui/src/main/kotlin/com/bumble/appyx/testing/ui/rules/AppyxTestRule.kt +++ b/libraries/testing-ui/src/main/kotlin/com/bumble/appyx/testing/ui/rules/AppyxActivityTestRule.kt @@ -12,14 +12,14 @@ import org.junit.rules.TestRule import org.junit.runner.Description import org.junit.runners.model.Statement -open class AppyxTestRule( +open class AppyxActivityTestRule( private val launchActivity: Boolean = true, private val composeTestRule: ComposeTestRule = createEmptyComposeRule(), /** Add decorations like custom theme or CompositionLocalProvider. Do not forget to invoke `content()`. */ private val decorator: (@Composable (content: @Composable () -> Unit) -> Unit) = { content -> content() }, private val nodeFactory: NodeFactory, -) : ActivityTestRule( - /* activityClass = */ AppyxViewActivity::class.java, +) : ActivityTestRule( + /* activityClass = */ AppyxTestActivity::class.java, /* initialTouchMode = */ true, /* launchActivity = */ launchActivity ), ComposeTestRule by composeTestRule { @@ -42,7 +42,7 @@ open class AppyxTestRule( } override fun beforeActivityLaunched() { - AppyxViewActivity.composableView = { activity -> + AppyxTestActivity.composableView = { activity -> decorator { NodeHost(integrationPoint = activity.appyxIntegrationPoint, factory = { buildContext -> node = nodeFactory.create(buildContext) @@ -53,7 +53,7 @@ open class AppyxTestRule( } override fun afterActivityLaunched() { - AppyxViewActivity.composableView = null + AppyxTestActivity.composableView = null } @CallSuper diff --git a/libraries/testing-ui/src/main/kotlin/com/bumble/appyx/testing/ui/rules/AppyxParentViewTestRule.kt b/libraries/testing-ui/src/main/kotlin/com/bumble/appyx/testing/ui/rules/AppyxParentViewTestRule.kt deleted file mode 100644 index 082b32594..000000000 --- a/libraries/testing-ui/src/main/kotlin/com/bumble/appyx/testing/ui/rules/AppyxParentViewTestRule.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.bumble.appyx.testing.ui.rules - -import com.bumble.appyx.testing.ui.utils.DummyParentNode -import com.bumble.appyx.core.node.ParentNodeView -import com.bumble.appyx.core.node.ViewFactory - -open class AppyxParentViewTestRule>( - launchActivity: Boolean = true, - viewFactory: ViewFactory -) : AppyxViewTestRule(viewFactory, launchActivity) { - - override fun beforeActivityLaunched() { - super.beforeActivityLaunched() - runOnUiThread { - val testNode = DummyParentNode() - view.init(testNode) - } - } -} diff --git a/libraries/testing-ui/src/main/kotlin/com/bumble/appyx/testing/ui/rules/AppyxViewTestRule.kt b/libraries/testing-ui/src/main/kotlin/com/bumble/appyx/testing/ui/rules/AppyxViewTestRule.kt index dbcd2b476..04cca7f03 100644 --- a/libraries/testing-ui/src/main/kotlin/com/bumble/appyx/testing/ui/rules/AppyxViewTestRule.kt +++ b/libraries/testing-ui/src/main/kotlin/com/bumble/appyx/testing/ui/rules/AppyxViewTestRule.kt @@ -1,12 +1,15 @@ package com.bumble.appyx.testing.ui.rules import androidx.annotation.CallSuper +import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Modifier import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.compose.ui.test.junit4.createEmptyComposeRule import androidx.test.rule.ActivityTestRule +import com.bumble.appyx.core.node.LocalNode import com.bumble.appyx.core.node.NodeView import com.bumble.appyx.core.node.ViewFactory +import com.bumble.appyx.testing.ui.utils.DummyParentNode import org.junit.rules.TestRule import org.junit.runner.Description import org.junit.runners.model.Statement @@ -15,8 +18,8 @@ open class AppyxViewTestRule( viewFactory: ViewFactory, private val launchActivity: Boolean = true, private val composeTestRule: ComposeTestRule = createEmptyComposeRule() -) : ActivityTestRule( - /* activityClass = */ AppyxViewActivity::class.java, +) : ActivityTestRule( + /* activityClass = */ AppyxTestActivity::class.java, /* initialTouchMode = */ true, /* launchActivity = */ launchActivity ), ComposeTestRule by composeTestRule { @@ -46,13 +49,17 @@ open class AppyxViewTestRule( } override fun beforeActivityLaunched() { - AppyxViewActivity.composableView = { - view.View(modifier = Modifier) + AppyxTestActivity.composableView = { + CompositionLocalProvider( + LocalNode provides DummyParentNode(), + ) { + view.View(modifier = Modifier) + } } } override fun afterActivityLaunched() { - AppyxViewActivity.composableView = null + AppyxTestActivity.composableView = null } @CallSuper diff --git a/libraries/testing-ui/src/main/kotlin/com/bumble/appyx/testing/ui/utils/DummyNavModel.kt b/libraries/testing-ui/src/main/kotlin/com/bumble/appyx/testing/ui/utils/DummyNavModel.kt index 1c2096afc..66471ef0f 100644 --- a/libraries/testing-ui/src/main/kotlin/com/bumble/appyx/testing/ui/utils/DummyNavModel.kt +++ b/libraries/testing-ui/src/main/kotlin/com/bumble/appyx/testing/ui/utils/DummyNavModel.kt @@ -7,9 +7,7 @@ import com.bumble.appyx.core.navigation.onscreen.OnScreenStateResolver class DummyNavModel : BaseNavModel( savedStateMap = null, finalState = null, - screenResolver = object : OnScreenStateResolver { - override fun isOnScreen(state: State) = true - } + screenResolver = OnScreenStateResolver { true } ) { override val initialElements: NavElements get() = emptyList() diff --git a/samples/sandbox/src/androidTest/kotlin/com/bumble/appyx/sandbox/client/mvicoreexample/MviCoreExampleViewTest.kt b/samples/sandbox/src/androidTest/kotlin/com/bumble/appyx/sandbox/client/mvicoreexample/MviCoreExampleViewTest.kt index dccee32fc..950b94e0c 100644 --- a/samples/sandbox/src/androidTest/kotlin/com/bumble/appyx/sandbox/client/mvicoreexample/MviCoreExampleViewTest.kt +++ b/samples/sandbox/src/androidTest/kotlin/com/bumble/appyx/sandbox/client/mvicoreexample/MviCoreExampleViewTest.kt @@ -4,11 +4,11 @@ import androidx.compose.ui.test.assert import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.hasText import androidx.compose.ui.test.performClick -import com.bumble.appyx.testing.ui.utils.DummyNavModel import com.bumble.appyx.sandbox.client.mvicoreexample.MviCoreExampleViewImpl.Event import com.bumble.appyx.sandbox.client.mvicoreexample.feature.ViewModel -import com.bumble.appyx.sandbox.client.test.appyxParentViewRule +import com.bumble.appyx.sandbox.client.test.appyxViewRule import com.bumble.appyx.sandbox.client.test.assertLastValueEqual +import com.bumble.appyx.testing.ui.utils.DummyNavModel import org.junit.Rule import org.junit.Test @@ -18,7 +18,7 @@ internal class MviCoreExampleViewTest { private var title = "Title" @get:Rule - val rule = appyxParentViewRule(launchActivity = false) { + val rule = appyxViewRule(launchActivity = false) { createView() } diff --git a/samples/sandbox/src/androidTest/kotlin/com/bumble/appyx/sandbox/client/test/AppyxMviParentViewTestRule.kt b/samples/sandbox/src/androidTest/kotlin/com/bumble/appyx/sandbox/client/test/AppyxMviParentViewTestRule.kt deleted file mode 100644 index 5f10178c7..000000000 --- a/samples/sandbox/src/androidTest/kotlin/com/bumble/appyx/sandbox/client/test/AppyxMviParentViewTestRule.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.bumble.appyx.sandbox.client.test - -import com.bumble.appyx.testing.ui.rules.AppyxParentViewTestRule -import com.bumble.appyx.core.node.ParentNodeView -import com.bumble.appyx.core.node.ViewFactory -import io.reactivex.ObservableSource -import io.reactivex.functions.Consumer -import io.reactivex.observers.TestObserver - -class AppyxMviParentViewTestRule>( - launchActivity: Boolean = true, - private val modelConsumer: (View) -> Consumer, - private val eventObservable: (View) -> ObservableSource, - viewFactory: ViewFactory, -) : AppyxParentViewTestRule( - launchActivity = launchActivity, - viewFactory = viewFactory, -) { - private lateinit var _modelConsumer: Consumer - - val events: List - get() = testEvents.values() - val testEvents: TestObserver = TestObserver() - - override fun beforeActivityLaunched() { - super.beforeActivityLaunched() - runOnUiThread { - _modelConsumer = modelConsumer(view) - eventObservable(view).wrapToObservable().subscribe(testEvents) - } - } - - override fun after() { - super.after() - testEvents.dispose() - } - - fun accept(v: ViewModel) { - runOnUiThread { _modelConsumer.accept(v) } - } -} diff --git a/samples/sandbox/src/androidTest/kotlin/com/bumble/appyx/sandbox/client/test/AppyxViewRules.kt b/samples/sandbox/src/androidTest/kotlin/com/bumble/appyx/sandbox/client/test/AppyxViewRules.kt index 8959730b6..5dd3254d6 100644 --- a/samples/sandbox/src/androidTest/kotlin/com/bumble/appyx/sandbox/client/test/AppyxViewRules.kt +++ b/samples/sandbox/src/androidTest/kotlin/com/bumble/appyx/sandbox/client/test/AppyxViewRules.kt @@ -1,25 +1,14 @@ package com.bumble.appyx.sandbox.client.test -import com.bumble.appyx.core.node.ParentNodeView +import com.bumble.appyx.core.node.NodeView import com.bumble.appyx.core.node.ViewFactory import io.reactivex.ObservableSource import io.reactivex.functions.Consumer -fun appyxParentViewRule( +fun appyxViewRule( launchActivity: Boolean = true, viewFactory: ViewFactory, -) where View : ParentNodeView, View : Consumer, View : ObservableSource = - AppyxMviParentViewTestRule( - launchActivity = launchActivity, - modelConsumer = { it }, - eventObservable = { it }, - viewFactory = viewFactory - ) - -fun appyxViewRule( - launchActivity: Boolean = true, - viewFactory: ViewFactory, -) where View : ParentNodeView, View : Consumer, View : ObservableSource = +) where View : NodeView, View : Consumer, View : ObservableSource = AppyxMviViewTestRule( launchActivity = launchActivity, modelConsumer = { it }, diff --git a/samples/sandbox/src/main/kotlin/com/bumble/appyx/sandbox/client/mvicoreexample/MviCoreExampleView.kt b/samples/sandbox/src/main/kotlin/com/bumble/appyx/sandbox/client/mvicoreexample/MviCoreExampleView.kt index ffa04054d..cee13d394 100644 --- a/samples/sandbox/src/main/kotlin/com/bumble/appyx/sandbox/client/mvicoreexample/MviCoreExampleView.kt +++ b/samples/sandbox/src/main/kotlin/com/bumble/appyx/sandbox/client/mvicoreexample/MviCoreExampleView.kt @@ -24,9 +24,9 @@ import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.bumble.appyx.core.composable.Children -import com.bumble.appyx.core.node.AbstractParentNodeView -import com.bumble.appyx.core.node.ParentNode import com.bumble.appyx.core.navigation.NavModel +import com.bumble.appyx.core.node.ParentNode +import com.bumble.appyx.core.node.ParentNodeView import com.bumble.appyx.navmodel.backstack.BackStack import com.bumble.appyx.navmodel.backstack.transitionhandler.rememberBackstackSlider import com.bumble.appyx.sandbox.client.mvicoreexample.MviCoreExampleNode.NavTarget @@ -47,7 +47,7 @@ class MviCoreExampleViewImpl( private val title: String = "Title", private val backStack: NavModel, private val events: PublishRelay = PublishRelay.create() -) : AbstractParentNodeView(), +) : ParentNodeView, MviCoreExampleView, ObservableSource by events { diff --git a/samples/sandbox/src/test/kotlin/com/bumble/appyx/sandbox/stub/NodeViewStub.kt b/samples/sandbox/src/test/kotlin/com/bumble/appyx/sandbox/stub/NodeViewStub.kt index 146c05019..4a43ce57a 100644 --- a/samples/sandbox/src/test/kotlin/com/bumble/appyx/sandbox/stub/NodeViewStub.kt +++ b/samples/sandbox/src/test/kotlin/com/bumble/appyx/sandbox/stub/NodeViewStub.kt @@ -2,8 +2,8 @@ package com.bumble.appyx.sandbox.stub import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import com.bumble.appyx.core.node.AbstractParentNodeView import com.bumble.appyx.core.node.ParentNode +import com.bumble.appyx.core.node.ParentNodeView import com.jakewharton.rxrelay2.PublishRelay import io.reactivex.ObservableSource import io.reactivex.disposables.Disposable @@ -14,7 +14,7 @@ open class NodeViewStub( val eventsRelay: PublishRelay = PublishRelay.create(), val viewModelRelay: PublishRelay = PublishRelay.create(), private val disposable: Disposable = Disposables.empty() -) : AbstractParentNodeView(), +) : ParentNodeView, ObservableSource by eventsRelay, Consumer by viewModelRelay, Disposable by disposable { From 929e8093f1052dfaae0815739798be811277b772 Mon Sep 17 00:00:00 2001 From: andreykovalev Date: Sat, 8 Oct 2022 10:15:48 +0100 Subject: [PATCH 5/9] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f67a4ffd1..9b4d8d2ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Pending changes +- [#197](https://github.com/bumble-tech/appyx/pull/197) – **Breaking change**: `ParentNodeView` does not implement plugin anymore. Node instance is retrieved via LocalComposition. - [#185](https://github.com/bumble-tech/appyx/issues/185) – **Breaking change**: `Activity` must implement `IntegrationPointProvider` and create `IntegrationPoint` manually. Weak references usage has been removed. - [#173](https://github.com/bumble-tech/appyx/pull/173) – **Breaking change**: `ActivityStarter` and `PermissionRequester` now exposes coroutine based API instead of `minimal.reactive`. - [#43](https://github.com/bumble-tech/appyx/pull/43) – **Updated**: Jetpack Compose to 1.2.1 and kotlin to 1.7.10. From ddf773389107b8977d0483eac32b67cb2202eff6 Mon Sep 17 00:00:00 2001 From: andreykovalev Date: Mon, 10 Oct 2022 11:41:01 +0100 Subject: [PATCH 6/9] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6df827d40..be7d3d472 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## Pending changes -- [#197](https://github.com/bumble-tech/appyx/pull/197) – **Breaking change**: `ParentNodeView` does not implement plugin anymore. Node instance is retrieved via LocalComposition. +- [#197](https://github.com/bumble-tech/appyx/pull/197) – **Breaking change**: `ParentNodeView` does not implement plugin anymore. Node instance is retrieved via LocalComposition. `AppyxParentViewTestRule` and `AbstractParentNodeView` have been removed. - [#196](https://github.com/bumble-tech/appyx/pull/196) – **Breaking change**: `InteropBuilder` now should be supplied with Appyx `IntegrationPointProvider` to attach it at the same time Appyx Node is created - [#185](https://github.com/bumble-tech/appyx/issues/185) – **Breaking change**: `Activity` must implement `IntegrationPointProvider` and create `IntegrationPoint` manually. Weak references usage has been removed. - [#173](https://github.com/bumble-tech/appyx/pull/173) – **Breaking change**: `ActivityStarter` and `PermissionRequester` now exposes coroutine based API instead of `minimal.reactive`. From edd64eac9e2ef5a2a423c8715ee9cd9199cc300c Mon Sep 17 00:00:00 2001 From: CherryPerry Date: Tue, 11 Oct 2022 10:12:35 +0100 Subject: [PATCH 7/9] Fix publishAppyxReleasePublicationToSonatypeSnapshotRepository check --- plugins/publish-plugin/src/main/kotlin/ProjectPlugin.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/publish-plugin/src/main/kotlin/ProjectPlugin.kt b/plugins/publish-plugin/src/main/kotlin/ProjectPlugin.kt index 46e9c3eba..5c64e20a8 100644 --- a/plugins/publish-plugin/src/main/kotlin/ProjectPlugin.kt +++ b/plugins/publish-plugin/src/main/kotlin/ProjectPlugin.kt @@ -29,7 +29,7 @@ internal abstract class ProjectPlugin : Plugin { } project.tasks.named("publishAppyxReleasePublicationToSonatypeSnapshotRepository") { - val fail = project.isSnapshotPublication + val fail = !project.isSnapshotPublication doFirst { if (fail) throw GradleException( "Publishing to snapshot repository with disabled \"snapshot\" flag is permitted" From b2a174880bddedc8030ad984d8cbfd90af06c03b Mon Sep 17 00:00:00 2001 From: CherryPerry Date: Tue, 11 Oct 2022 10:16:28 +0100 Subject: [PATCH 8/9] Use dot split instead of semver to create snapshot version --- plugins/publish-plugin/src/main/kotlin/ProjectPlugin.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/publish-plugin/src/main/kotlin/ProjectPlugin.kt b/plugins/publish-plugin/src/main/kotlin/ProjectPlugin.kt index 5c64e20a8..c6ebd1a6d 100644 --- a/plugins/publish-plugin/src/main/kotlin/ProjectPlugin.kt +++ b/plugins/publish-plugin/src/main/kotlin/ProjectPlugin.kt @@ -8,7 +8,6 @@ import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.create import org.gradle.kotlin.dsl.get import org.gradle.plugins.signing.SigningExtension -import org.jetbrains.kotlin.gradle.targets.js.npm.SemVer internal abstract class ProjectPlugin : Plugin { override fun apply(project: Project) { @@ -73,8 +72,7 @@ internal abstract class ProjectPlugin : Plugin { from(project.components[getComponentName()]) groupId = "com.bumble.appyx" version = if (project.isSnapshotPublication) { - val semVer = SemVer.from(definedVersion) - "v${semVer.major}-SNAPSHOT" + "v${definedVersion.split('.').first()}-SNAPSHOT" } else { definedVersion } From acd4fd2ba2e7492639bd6e0f005935b95007484a Mon Sep 17 00:00:00 2001 From: andreykovalev Date: Tue, 11 Oct 2022 16:52:26 +0100 Subject: [PATCH 9/9] Add javadoc to ParentNodeView.kt --- .../main/kotlin/com/bumble/appyx/core/node/ParentNodeView.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/core/src/main/kotlin/com/bumble/appyx/core/node/ParentNodeView.kt b/libraries/core/src/main/kotlin/com/bumble/appyx/core/node/ParentNodeView.kt index 6fc2e1b2f..d91e2cb1d 100644 --- a/libraries/core/src/main/kotlin/com/bumble/appyx/core/node/ParentNodeView.kt +++ b/libraries/core/src/main/kotlin/com/bumble/appyx/core/node/ParentNodeView.kt @@ -8,6 +8,9 @@ interface ParentNodeView : NodeView { @Composable fun ParentNode.NodeView(modifier: Modifier) + /** + * Do not override this function. Parent views should implement NodeView method. + */ @Suppress("UNCHECKED_CAST") @Composable override fun View(modifier: Modifier) {