diff --git a/.github/actions/add-secret-files/action.yml b/.github/actions/add-secret-files/action.yml new file mode 100644 index 0000000000..008d338129 --- /dev/null +++ b/.github/actions/add-secret-files/action.yml @@ -0,0 +1,67 @@ +name: 'Add Secret Files' +description: 'Add secret files to the project' +inputs: + ANDROID_RELEASE_KEYSTORE_ASC: + description: 'Android Release Keystore' + required: true + SECRET_PASSWORD: + description: 'Secret Password' + required: true + GOOGLE_SERVICES_JSON_ASC: + description: 'Google Services JSON' + required: true + AG_CONNECT_SERVICES_JSON_ASC: + description: 'AG Connect Services JSON' + required: true + GOOGLE_SERVICE_INFO_PLIST_ASC_RELEASE: + description: 'GoogleService-Info.plist Release' + required: true + GOOGLE_SERVICE_INFO_PLIST_ASC_DEBUG: + description: 'GoogleService-Info.plist Debug' + required: true + IOS_XCCONFIG_ASC_RELEASE: + description: 'iOS xcconfig Release' + required: true + IOS_XCCONFIG_ASC_DEBUG: + description: 'iOS xcconfig Debug' + required: true + GOOGLE_PLAY_SERVICE_ACCOUNT_JSON: + description: 'Google Play Service Account JSON' + required: true +runs: + using: 'composite' + steps: + - run: | + # Save the Android Release Keystore + echo "${{ inputs.ANDROID_RELEASE_KEYSTORE_ASC }}" > release.keystore.asc + gpg -d --passphrase "${{ inputs.SECRET_PASSWORD }}" --batch release.keystore.asc > android/app/release.keystore + + # Save google-services.json files + mkdir android/app/src/release + mkdir android/app/src/debug + echo "${{ inputs.GOOGLE_SERVICES_JSON_ASC }}" > google-services.json.asc + gpg -d --passphrase "${{ inputs.SECRET_PASSWORD }}" --batch google-services.json.asc > android/app/src/release/google-services.json + gpg -d --passphrase "${{ inputs.SECRET_PASSWORD }}" --batch google-services.json.asc > android/app/src/debug/google-services.json + + # Save agconnect-services.json + echo "${{ inputs.AG_CONNECT_SERVICES_JSON_ASC }}" > agconnect-services.json.asc + gpg -d --passphrase "${{ inputs.SECRET_PASSWORD }}" --batch agconnect-services.json.asc > android/app/src/release/agconnect-services.json + + # Save GoogleService-Info.plist files + mkdir ios/CCC/Resources/Release + mkdir ios/CCC/Resources/Debug + echo "${{ inputs.GOOGLE_SERVICE_INFO_PLIST_ASC_RELEASE }}" > Release-GoogleService-Info.plist.asc + gpg -d --passphrase "${{ inputs.SECRET_PASSWORD }}" --batch Release-GoogleService-Info.plist.asc > ios/CCC/Resources/Release/GoogleService-Info.plist + echo "${{ inputs.GOOGLE_SERVICE_INFO_PLIST_ASC_DEBUG }}" > Debug-GoogleService-Info.plist.asc + gpg -d --passphrase "${{ inputs.SECRET_PASSWORD }}" --batch Debug-GoogleService-Info.plist.asc > ios/CCC/Resources/Debug/GoogleService-Info.plist + + # Save Config.xcconfig files + echo "${{ inputs.IOS_XCCONFIG_ASC_RELEASE }}" > Release.xcconfig.asc + gpg -d --passphrase "${{ inputs.SECRET_PASSWORD }}" --batch Release.xcconfig.asc > ios/CCC/Resources/Release/Config.xcconfig + echo "${{ inputs.IOS_XCCONFIG_ASC_DEBUG }}" > Debug.xcconfig.asc + gpg -d --passphrase "${{ inputs.SECRET_PASSWORD }}" --batch Debug.xcconfig.asc > ios/CCC/Resources/Debug/Config.xcconfig + + # Save service_account.json + echo "${{ inputs.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }}" > service_account.json.asc + gpg -d --passphrase "${{ inputs.SECRET_PASSWORD }}" --batch service_account.json.asc > service_account.json + shell: bash \ No newline at end of file diff --git a/.github/workflows/copy-secrets.yml b/.github/workflows/copy-secrets.yml deleted file mode 100644 index 3e67046f77..0000000000 --- a/.github/workflows/copy-secrets.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Copy Repository Secrets to Dependabot - -on: - workflow_dispatch: - -jobs: - copy-secrets: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4.1.6 - - - name: List repository secrets - id: list_secrets - run: | - secrets=$(gh api -H "Accept: application/vnd.github.v3+json" /repos/${{ github.repository }}/actions/secrets --jq '.secrets[].name') - echo "secrets=$secrets" >> $GITHUB_ENV - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Copy secrets to Dependabot - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SECRETS: ${{ env.secrets }} - run: | - for secret in $SECRETS; do - secret_value=$(gh api -H "Accept: application/vnd.github.v3+json" /repos/${{ github.repository }}/actions/secrets/$secret --jq '.encrypted_value') - gh api -X PUT -H "Accept: application/vnd.github.v3+json" /repos/${{ github.repository }}/dependabot/secrets/$secret -f encrypted_value="$secret_value" - echo "Copied secret: $secret" - done diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 13779495b4..f3b47568b1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,8 +7,8 @@ on: pull_request: concurrency: - group: ${{ github.ref }} - cancel-in-progress: ${{ !contains(github.ref, 'develop')}} + group: ${{ github.ref == 'refs/heads/develop' && 'develop' || github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/develop' }} env: BASE_URL_BACKEND: ${{ secrets.BASE_URL_BACKEND }} @@ -65,20 +65,20 @@ jobs: steps: - name: Setup Gradle Repo - uses: Oztechan/Global/actions/setup-gradle-repo@v1.0.5 + uses: Oztechan/Global/actions/setup-gradle-repo@d5c2d633506a792e53d7a273d90dde429df3bba7 - name: Adding secret files - run: | - echo "${{ secrets.ANDROID_GPG_RELEASE_KEYSTORE }}" > release.keystore.asc - gpg -d --passphrase "${{ secrets.SECRET_PASSWORD }}" --batch release.keystore.asc > android/app/release.keystore - mkdir android/app/src/release - echo "${{ secrets.RELEASE_GOOGLE_SERVICES_JSON_ASC }}" > google-services.json.asc - gpg -d --passphrase "${{ secrets.SECRET_PASSWORD }}" --batch google-services.json.asc > android/app/src/release/google-services.json - mkdir android/app/src/debug - echo "${{ secrets.DEBUG_GOOGLE_SERVICES_JSON_ASC }}" > google-services.json.asc - gpg -d --passphrase "${{ secrets.SECRET_PASSWORD }}" --batch google-services.json.asc > android/app/src/debug/google-services.json - echo "${{ secrets.AG_CONNECT_SERVICES_JSON_ASC }}" > agconnect-services.json.asc - gpg -d --passphrase "${{ secrets.SECRET_PASSWORD }}" --batch agconnect-services.json.asc > android/app/src/release/agconnect-services.json + uses: ./.github/actions/add-secret-files + with: + ANDROID_RELEASE_KEYSTORE_ASC: ${{ secrets.ANDROID_RELEASE_KEYSTORE_ASC }} + SECRET_PASSWORD: ${{ secrets.SECRET_PASSWORD }} + GOOGLE_SERVICES_JSON_ASC: ${{ secrets.GOOGLE_SERVICES_JSON_ASC }} + AG_CONNECT_SERVICES_JSON_ASC: ${{ secrets.AG_CONNECT_SERVICES_JSON_ASC }} + GOOGLE_SERVICE_INFO_PLIST_ASC_RELEASE: ${{ secrets.GOOGLE_SERVICE_INFO_PLIST_ASC_RELEASE }} + GOOGLE_SERVICE_INFO_PLIST_ASC_DEBUG: ${{ secrets.GOOGLE_SERVICE_INFO_PLIST_ASC_DEBUG }} + IOS_XCCONFIG_ASC_RELEASE: ${{ secrets.IOS_XCCONFIG_ASC_RELEASE }} + IOS_XCCONFIG_ASC_DEBUG: ${{ secrets.IOS_XCCONFIG_ASC_DEBUG }} + GOOGLE_PLAY_SERVICE_ACCOUNT_JSON: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }} - name: Assemble run: ./gradlew assemble @@ -89,12 +89,14 @@ jobs: with: name: androidArtifacts path: | + android/app/build/outputs/apk/google/debug/app-google-debug.apk + android/app/build/outputs/apk/huawei/debug/app-huawei-debug.apk android/app/build/outputs/apk/google/release/app-google-release.apk android/app/build/outputs/apk/huawei/release/app-huawei-release.apk - name: Cancel other jobs if this fails if: failure() - uses: andymckay/cancel-action@0.4 + uses: andymckay/cancel-action@0.5 - name: Set Job Status id: status @@ -109,25 +111,41 @@ jobs: steps: - name: Clone Repo # Needed for reading commit message for Firebase App Distribution - uses: actions/checkout@v4.1.6 + uses: actions/checkout@v4.1.7 - name: Download Android Artifacts uses: actions/download-artifact@v4.1.7 with: name: androidArtifacts - - name: Firebase App Distribution Google + - name: Firebase App Distribution Google Debug + uses: wzieba/Firebase-Distribution-Github-Action@v1.7.0 + with: + appId: ${{secrets.ANDROID_GOOGLE_DEBUG_FIREBASE_APP_ID}} + token: ${{secrets.FIREBASE_CLI_TOKEN}} + groups: QA + file: google/debug/app-google-debug.apk + + - name: Firebase App Distribution Google Release uses: wzieba/Firebase-Distribution-Github-Action@v1.7.0 with: - appId: ${{secrets.ANDROID_GOOGLE_FIREBASE_APP_ID}} + appId: ${{secrets.ANDROID_GOOGLE_RELEASE_FIREBASE_APP_ID}} token: ${{secrets.FIREBASE_CLI_TOKEN}} groups: QA file: google/release/app-google-release.apk - - name: Firebase App Distribution Huawei + - name: Firebase App Distribution Huawei Debug uses: wzieba/Firebase-Distribution-Github-Action@v1.7.0 with: - appId: ${{secrets.ANDROID_HUAWEI_FIREBASE_APP_ID}} + appId: ${{secrets.ANDROID_HUAWEI_DEBUG_FIREBASE_APP_ID}} + token: ${{secrets.FIREBASE_CLI_TOKEN}} + groups: QA + file: huawei/debug/app-huawei-debug.apk + + - name: Firebase App Distribution Huawei Release + uses: wzieba/Firebase-Distribution-Github-Action@v1.7.0 + with: + appId: ${{secrets.ANDROID_HUAWEI_RELEASE_FIREBASE_APP_ID}} token: ${{secrets.FIREBASE_CLI_TOKEN}} groups: QA file: huawei/release/app-huawei-release.apk @@ -148,26 +166,20 @@ jobs: steps: - name: Setup Gradle Repo - uses: Oztechan/Global/actions/setup-gradle-repo@v1.0.5 + uses: Oztechan/Global/actions/setup-gradle-repo@d5c2d633506a792e53d7a273d90dde429df3bba7 - name: Adding secret files - run: | - echo "${{ secrets.ANDROID_GPG_RELEASE_KEYSTORE }}" > release.keystore.asc - gpg -d --passphrase "${{ secrets.SECRET_PASSWORD }}" --batch release.keystore.asc > android/app/release.keystore - mkdir android/app/src/release - echo "${{ secrets.RELEASE_GOOGLE_SERVICES_JSON_ASC }}" > google-services.json.asc - gpg -d --passphrase "${{ secrets.SECRET_PASSWORD }}" --batch google-services.json.asc > android/app/src/release/google-services.json - mkdir android/app/src/debug - echo "${{ secrets.DEBUG_GOOGLE_SERVICES_JSON_ASC }}" > google-services.json.asc - gpg -d --passphrase "${{ secrets.SECRET_PASSWORD }}" --batch google-services.json.asc > android/app/src/debug/google-services.json - echo "${{ secrets.AG_CONNECT_SERVICES_JSON_ASC }}" > agconnect-services.json.asc - gpg -d --passphrase "${{ secrets.SECRET_PASSWORD }}" --batch agconnect-services.json.asc > android/app/src/release/agconnect-services.json - echo "${{ secrets.IOS_GPG_FIREBASE_CONFIG }}" > GoogleService-Info.plist.asc - mkdir ios/CCC/Resources/Release - gpg -d --passphrase "${{ secrets.SECRET_PASSWORD }}" --batch GoogleService-Info.plist.asc > ios/CCC/Resources/Release/GoogleService-Info.plist - rm ios/CCC/Resources/Debug/GoogleService-Info.plist - echo "${{ secrets.IOS_GPG_RELEASE_XCCONFIG }}" > Release.xcconfig.asc - gpg -d --passphrase "${{ secrets.SECRET_PASSWORD }}" --batch Release.xcconfig.asc > ios/CCC/Resources/Release/Config.xcconfig + uses: ./.github/actions/add-secret-files + with: + ANDROID_RELEASE_KEYSTORE_ASC: ${{ secrets.ANDROID_RELEASE_KEYSTORE_ASC }} + SECRET_PASSWORD: ${{ secrets.SECRET_PASSWORD }} + GOOGLE_SERVICES_JSON_ASC: ${{ secrets.GOOGLE_SERVICES_JSON_ASC }} + AG_CONNECT_SERVICES_JSON_ASC: ${{ secrets.AG_CONNECT_SERVICES_JSON_ASC }} + GOOGLE_SERVICE_INFO_PLIST_ASC_RELEASE: ${{ secrets.GOOGLE_SERVICE_INFO_PLIST_ASC_RELEASE }} + GOOGLE_SERVICE_INFO_PLIST_ASC_DEBUG: ${{ secrets.GOOGLE_SERVICE_INFO_PLIST_ASC_DEBUG }} + IOS_XCCONFIG_ASC_RELEASE: ${{ secrets.IOS_XCCONFIG_ASC_RELEASE }} + IOS_XCCONFIG_ASC_DEBUG: ${{ secrets.IOS_XCCONFIG_ASC_DEBUG }} + GOOGLE_PLAY_SERVICE_ACCOUNT_JSON: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }} - name: Build working-directory: ios @@ -184,7 +196,7 @@ jobs: - name: Cancel other jobs if this fails if: failure() - uses: andymckay/cancel-action@0.4 + uses: andymckay/cancel-action@0.5 - name: Set Job Status id: status @@ -198,7 +210,7 @@ jobs: status: ${{ steps.status.outputs.status }} steps: - name: Clone Repo - uses: actions/checkout@v4.1.6 + uses: actions/checkout@v4.1.7 - name: Download iOS IPA uses: actions/download-artifact@v4.1.7 @@ -222,61 +234,53 @@ jobs: id: status run: echo "status=success" >> $GITHUB_OUTPUT - Quality: + Check: runs-on: macos-14 + if: github.ref != 'refs/heads/develop' outputs: status: ${{ steps.status.outputs.status }} steps: - name: Setup Gradle Repo - uses: Oztechan/Global/actions/setup-gradle-repo@v1.0.5 - - - name: Run Quality Jobs - run: ./gradlew check koverMergedXmlReport --parallel + uses: Oztechan/Global/actions/setup-gradle-repo@d5c2d633506a792e53d7a273d90dde429df3bba7 - - name: Upload Coverage Report - uses: actions/upload-artifact@v4.3.3 - with: - name: coverageReport - path: build/reports/kover/merged/xml/report.xml + - name: Run Check + run: ./gradlew check - name: Cancel other jobs if this fails if: failure() - uses: andymckay/cancel-action@0.4 + uses: andymckay/cancel-action@0.5 - name: Set Job Status id: status run: echo "status=success" >> $GITHUB_OUTPUT - UploadQualityReports: + Coverage: runs-on: ubuntu-22.04 - needs: [ Quality ] outputs: status: ${{ steps.status.outputs.status }} steps: - - name: Clone Repo # Codecov requires it - uses: actions/checkout@v4.1.6 - - name: Download Coverage Report - uses: actions/download-artifact@v4.1.7 - with: - name: coverageReport - path: build + - name: Setup Gradle Repo + uses: Oztechan/Global/actions/setup-gradle-repo@d5c2d633506a792e53d7a273d90dde429df3bba7 + + - name: Generate Coverage + run: ./gradlew koverXmlReport - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4.4.1 + uses: codecov/codecov-action@v4.5.0 with: token: ${{ secrets.CODECOV_TOKEN }} - files: build/report.xml + files: build/reports/kover/report.xml - name: Upload coverage to Codacy uses: codacy/codacy-coverage-reporter-action@v1.3.0 with: project-token: ${{ secrets.CODACY_PROJECT_TOKEN }} - coverage-reports: build/report.xml + coverage-reports: build/reports/kover/report.xml - name: SonarCloud Scan - uses: sonarsource/sonarcloud-github-action@v2.2.0 + uses: sonarsource/sonarcloud-github-action@v2.3.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} @@ -284,12 +288,11 @@ jobs: args: > -Dsonar.organization=oztechan -Dsonar.projectKey=Oztechan_CCC - -Dsonar.coverage.jacoco.xmlReportPaths=build/report.xml + -Dsonar.coverage.jacoco.xmlReportPaths=build/reports/kover/report.xml - - name: Delete Coverage Report - uses: geekyeggo/delete-artifact@v5.0.0 - with: - name: coverageReport + - name: Cancel other jobs if this fails + if: failure() + uses: andymckay/cancel-action@0.5 - name: Set Job Status id: status @@ -302,7 +305,7 @@ jobs: steps: - name: Setup Gradle Repo - uses: Oztechan/Global/actions/setup-gradle-repo@v1.0.5 + uses: Oztechan/Global/actions/setup-gradle-repo@d5c2d633506a792e53d7a273d90dde429df3bba7 - name: Detekt run: ./gradlew detektAll @@ -316,7 +319,7 @@ jobs: - name: Cancel other jobs if this fails if: failure() - uses: andymckay/cancel-action@0.4 + uses: andymckay/cancel-action@0.5 - name: Set Job Status id: status @@ -324,16 +327,16 @@ jobs: Notify: runs-on: ubuntu-22.04 - needs: [ GradleBuild, XCodeBuild, Quality, CodeAnalysis, DistributeAndroid, DistributeIOS, UploadQualityReports ] + needs: [ GradleBuild, XCodeBuild, Check, Coverage, CodeAnalysis, DistributeAndroid, DistributeIOS ] if: always() steps: - name: Notify slack fail if: false == (needs.GradleBuild.outputs.status == 'success') || false == (needs.XCodeBuild.outputs.status == 'success') || - false == (needs.Quality.outputs.status == 'success') || + (false == (needs.Check.outputs.status == 'success') && github.ref != 'refs/heads/develop')|| + false == (needs.Coverage.outputs.status == 'success') || false == (needs.CodeAnalysis.outputs.status == 'success') || - false == (needs.UploadQualityReports.outputs.status == 'success') || (false == (needs.DistributeAndroid.outputs.status == 'success') && github.event_name == 'push') || (false == (needs.DistributeIOS.outputs.status == 'success') && github.event_name == 'push') uses: voxmedia/github-action-slack-notify-build@v1.6.0 diff --git a/.github/workflows/project.yml b/.github/workflows/project.yml index 5681f65244..da597ea75e 100644 --- a/.github/workflows/project.yml +++ b/.github/workflows/project.yml @@ -14,7 +14,7 @@ on: jobs: ProjectAutomations: - uses: Oztechan/Global/.github/workflows/reusable-project.yml@v1.0.5 + uses: Oztechan/Global/.github/workflows/reusable-project.yml@d5c2d633506a792e53d7a273d90dde429df3bba7 with: project_id: 2 secrets: inherit diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index dd4e0d5364..92fea6009c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -8,7 +8,7 @@ on: jobs: PublishRelease: - uses: Oztechan/Global/.github/workflows/reusable-publish.yml@v1.0.5 + uses: Oztechan/Global/.github/workflows/reusable-publish.yml@d5c2d633506a792e53d7a273d90dde429df3bba7 with: slack_channel: "ccc-github" secrets: inherit diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1f897a07b4..05bbcb9bbd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -60,20 +60,20 @@ jobs: steps: - name: Setup Gradle Repo - uses: Oztechan/Global/actions/setup-gradle-repo@v1.0.5 + uses: Oztechan/Global/actions/setup-gradle-repo@d5c2d633506a792e53d7a273d90dde429df3bba7 - name: Adding secret files - run: | - echo "${{ secrets.ANDROID_GPG_RELEASE_KEYSTORE }}" > release.keystore.asc - gpg -d --passphrase "${{ secrets.SECRET_PASSWORD }}" --batch release.keystore.asc > android/app/release.keystore - mkdir android/app/src/release - echo "${{ secrets.RELEASE_GOOGLE_SERVICES_JSON_ASC }}" > google-services.json.asc - gpg -d --passphrase "${{ secrets.SECRET_PASSWORD }}" --batch google-services.json.asc > android/app/src/release/google-services.json - mkdir android/app/src/debug - echo "${{ secrets.DEBUG_GOOGLE_SERVICES_JSON_ASC }}" > google-services.json.asc - gpg -d --passphrase "${{ secrets.SECRET_PASSWORD }}" --batch google-services.json.asc > android/app/src/debug/google-services.json - echo "${{ secrets.AG_CONNECT_SERVICES_JSON_ASC }}" > agconnect-services.json.asc - gpg -d --passphrase "${{ secrets.SECRET_PASSWORD }}" --batch agconnect-services.json.asc > android/app/src/release/agconnect-services.json + uses: ./.github/actions/add-secret-files + with: + ANDROID_RELEASE_KEYSTORE_ASC: ${{ secrets.ANDROID_RELEASE_KEYSTORE_ASC }} + SECRET_PASSWORD: ${{ secrets.SECRET_PASSWORD }} + GOOGLE_SERVICES_JSON_ASC: ${{ secrets.GOOGLE_SERVICES_JSON_ASC }} + AG_CONNECT_SERVICES_JSON_ASC: ${{ secrets.AG_CONNECT_SERVICES_JSON_ASC }} + GOOGLE_SERVICE_INFO_PLIST_ASC_RELEASE: ${{ secrets.GOOGLE_SERVICE_INFO_PLIST_ASC_RELEASE }} + GOOGLE_SERVICE_INFO_PLIST_ASC_DEBUG: ${{ secrets.GOOGLE_SERVICE_INFO_PLIST_ASC_DEBUG }} + IOS_XCCONFIG_ASC_RELEASE: ${{ secrets.IOS_XCCONFIG_ASC_RELEASE }} + IOS_XCCONFIG_ASC_DEBUG: ${{ secrets.IOS_XCCONFIG_ASC_DEBUG }} + GOOGLE_PLAY_SERVICE_ACCOUNT_JSON: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }} - name: Generate Artifacts run: ./gradlew :android:app:bundleRelease :backend:app:jar --parallel @@ -113,9 +113,17 @@ jobs: name: googleBundle - name: Adding secret files - run: | - echo "${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }}" > service_account.json.asc - gpg -d --passphrase "${{ secrets.SECRET_PASSWORD }}" --batch service_account.json.asc > service_account.json + uses: ./.github/actions/add-secret-files + with: + ANDROID_RELEASE_KEYSTORE_ASC: ${{ secrets.ANDROID_RELEASE_KEYSTORE_ASC }} + SECRET_PASSWORD: ${{ secrets.SECRET_PASSWORD }} + GOOGLE_SERVICES_JSON_ASC: ${{ secrets.GOOGLE_SERVICES_JSON_ASC }} + AG_CONNECT_SERVICES_JSON_ASC: ${{ secrets.AG_CONNECT_SERVICES_JSON_ASC }} + GOOGLE_SERVICE_INFO_PLIST_ASC_RELEASE: ${{ secrets.GOOGLE_SERVICE_INFO_PLIST_ASC_RELEASE }} + GOOGLE_SERVICE_INFO_PLIST_ASC_DEBUG: ${{ secrets.GOOGLE_SERVICE_INFO_PLIST_ASC_DEBUG }} + IOS_XCCONFIG_ASC_RELEASE: ${{ secrets.IOS_XCCONFIG_ASC_RELEASE }} + IOS_XCCONFIG_ASC_DEBUG: ${{ secrets.IOS_XCCONFIG_ASC_DEBUG }} + GOOGLE_PLAY_SERVICE_ACCOUNT_JSON: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }} - name: Upload Artifact to Google Play Console uses: r0adkll/upload-google-play@v1.1.3 @@ -203,16 +211,20 @@ jobs: status: ${{ steps.status.outputs.status }} steps: - name: Setup Gradle Repo - uses: Oztechan/Global/actions/setup-gradle-repo@v1.0.5 + uses: Oztechan/Global/actions/setup-gradle-repo@d5c2d633506a792e53d7a273d90dde429df3bba7 - name: Adding secret files - run: | - echo "${{ secrets.IOS_GPG_FIREBASE_CONFIG }}" > GoogleService-Info.plist.asc - mkdir ios/CCC/Resources/Release - gpg -d --passphrase "${{ secrets.SECRET_PASSWORD }}" --batch GoogleService-Info.plist.asc > ios/CCC/Resources/Release/GoogleService-Info.plist - rm ios/CCC/Resources/Debug/GoogleService-Info.plist - echo "${{ secrets.IOS_GPG_RELEASE_XCCONFIG }}" > Release.xcconfig.asc - gpg -d --passphrase "${{ secrets.SECRET_PASSWORD }}" --batch Release.xcconfig.asc > ios/CCC/Resources/Release/Config.xcconfig + uses: ./.github/actions/add-secret-files + with: + ANDROID_RELEASE_KEYSTORE_ASC: ${{ secrets.ANDROID_RELEASE_KEYSTORE_ASC }} + SECRET_PASSWORD: ${{ secrets.SECRET_PASSWORD }} + GOOGLE_SERVICES_JSON_ASC: ${{ secrets.GOOGLE_SERVICES_JSON_ASC }} + AG_CONNECT_SERVICES_JSON_ASC: ${{ secrets.AG_CONNECT_SERVICES_JSON_ASC }} + GOOGLE_SERVICE_INFO_PLIST_ASC_RELEASE: ${{ secrets.GOOGLE_SERVICE_INFO_PLIST_ASC_RELEASE }} + GOOGLE_SERVICE_INFO_PLIST_ASC_DEBUG: ${{ secrets.GOOGLE_SERVICE_INFO_PLIST_ASC_DEBUG }} + IOS_XCCONFIG_ASC_RELEASE: ${{ secrets.IOS_XCCONFIG_ASC_RELEASE }} + IOS_XCCONFIG_ASC_DEBUG: ${{ secrets.IOS_XCCONFIG_ASC_DEBUG }} + GOOGLE_PLAY_SERVICE_ACCOUNT_JSON: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }} - name: StoreBuild working-directory: ios diff --git a/.gitignore b/.gitignore index 6a583e91c5..c1c0682ec6 100644 --- a/.gitignore +++ b/.gitignore @@ -25,8 +25,7 @@ secret.properties # iOS Project ios/CCC/Resources/Release/ -ios/CCC/Resources/GoogleService-Info.plist -ios/CCC/Resources/Config.xcconfig +ios/CCC/Resources/Debug/ ios/fastlane/.env ios/fastlane/README.md ios/fastlane/report.xml @@ -34,6 +33,7 @@ xcuserdata # Android secrets android/app/release.keystore +android/app/release.keystore.asc android/app/src/debug/google-services.json android/app/src/debug/google-services.json.asc android/app/src/debug/agconnect-services.json diff --git a/CCC.gradle.kts b/CCC.gradle.kts index 20dfdc1956..5d0e182ed0 100755 --- a/CCC.gradle.kts +++ b/CCC.gradle.kts @@ -24,18 +24,12 @@ version = ProjectSettings.getVersionName(project) allprojects { apply(plugin = rootProject.libs.plugins.kover.get().pluginId).also { - koverMerged { - filters { - annotations { - excludes += listOf( - "com.oztechan.ccc.android.ui.compose.annotations.ThemedPreviews", - "androidx.compose.ui.tooling.preview.Preview", - "androidx.compose.runtime.Composable" - ) - } - } - enable() - } + rootProject.dependencies.add("kover", project(path)) + kover.reports.filters.excludes.annotatedBy( + "com.oztechan.ccc.android.ui.compose.annotations.ThemedPreviews", + "androidx.compose.ui.tooling.preview.Preview", + "androidx.compose.runtime.Composable" + ) } apply(plugin = rootProject.libs.plugins.detekt.get().pluginId).also { @@ -43,20 +37,19 @@ allprojects { buildUponDefaultConfig = true allRules = true parallel = true - config.from("${rootProject.projectDir}/detekt.yml") + config.from(rootProject.layout.projectDirectory.file("detekt.yml")) } + tasks.withType { - setSource(files(project.projectDir)) + // Use providers to avoid direct project references + val projectDirectory = layout.projectDirectory.asFile + val buildDirectory = layout.buildDirectory.asFile + + setSource(projectDirectory) exclude("**/build/**") exclude { - it.file.relativeTo(projectDir).startsWith( - project.layout.buildDirectory.asFile.get().relativeTo(projectDir) - ) - } - }.onEach { detekt -> - // skip detekt tasks unless a it is specifically called - detekt.onlyIf { - gradle.startParameter.taskNames.any { it.contains("detekt") } + val relativePath = it.file.relativeTo(projectDirectory) + relativePath.startsWith(buildDirectory.get().relativeTo(projectDirectory)) } } diff --git a/android/ui/mobile/android-ui-mobile.gradle.kts b/android/ui/mobile/android-ui-mobile.gradle.kts index 38693f4bb4..192bee483d 100644 --- a/android/ui/mobile/android-ui-mobile.gradle.kts +++ b/android/ui/mobile/android-ui-mobile.gradle.kts @@ -7,6 +7,7 @@ plugins { alias(kotlinAndroid) alias(safeArgs) // todo can be removed once compose migration done alias(jetbrainsCompose) + alias(kotlinPluginCompose) } } @@ -28,10 +29,6 @@ android { buildConfig = true } - composeOptions { - kotlinCompilerExtensionVersion = libs.versions.composeCompiler.get() - } - DeviceFlavour.apply { flavorDimensions.addAll(listOf(flavorDimension)) diff --git a/android/ui/mobile/src/main/kotlin/com/oztechan/ccc/android/ui/mobile/content/calculator/CalculatorFragment.kt b/android/ui/mobile/src/main/kotlin/com/oztechan/ccc/android/ui/mobile/content/calculator/CalculatorFragment.kt index 841bb89829..f67eb5b55a 100755 --- a/android/ui/mobile/src/main/kotlin/com/oztechan/ccc/android/ui/mobile/content/calculator/CalculatorFragment.kt +++ b/android/ui/mobile/src/main/kotlin/com/oztechan/ccc/android/ui/mobile/content/calculator/CalculatorFragment.kt @@ -60,6 +60,7 @@ class CalculatorFragment : BaseVBFragment() { override fun onResume() { super.onResume() + Logger.i { "CalculatorFragment onResume" } analyticsManager.trackScreen(ScreenName.Calculator) } diff --git a/android/ui/mobile/src/main/kotlin/com/oztechan/ccc/android/ui/mobile/content/premium/PremiumBottomSheet.kt b/android/ui/mobile/src/main/kotlin/com/oztechan/ccc/android/ui/mobile/content/premium/PremiumBottomSheet.kt index 14a03309f2..93118934d8 100644 --- a/android/ui/mobile/src/main/kotlin/com/oztechan/ccc/android/ui/mobile/content/premium/PremiumBottomSheet.kt +++ b/android/ui/mobile/src/main/kotlin/com/oztechan/ccc/android/ui/mobile/content/premium/PremiumBottomSheet.kt @@ -67,6 +67,7 @@ class PremiumBottomSheet : BaseVBBottomSheetDialogFragment Fragment.getNavigationResult( destinationId: Int ) = try { findNavController() - .getBackStackEntry(destinationId) - .savedStateHandle - .getLiveData(key) + .currentBackStackEntry + ?.savedStateHandle + ?.getLiveData(key) } catch (e: IllegalArgumentException) { Logger.e(e) { "$destinationId is not found in the backstack when getting navigation result for key $key" } null @@ -92,9 +92,9 @@ fun Fragment.setNavigationResult( key: String ) = try { findNavController() - .getBackStackEntry(destinationId) - .savedStateHandle - .set(key, result) + .previousBackStackEntry + ?.savedStateHandle + ?.set(key, result) } catch (e: IllegalArgumentException) { Logger.e(e) { "$destinationId is not found in the backstack when setting navigation result for key $key" } } diff --git a/android/ui/widget/android-ui-widget.gradle.kts b/android/ui/widget/android-ui-widget.gradle.kts index 53c68f765b..f898cf6e37 100644 --- a/android/ui/widget/android-ui-widget.gradle.kts +++ b/android/ui/widget/android-ui-widget.gradle.kts @@ -2,6 +2,7 @@ plugins { libs.plugins.apply { alias(androidLibrary) alias(kotlinAndroid) + alias(kotlinPluginCompose) } } @@ -20,10 +21,6 @@ android { buildFeatures { compose = true } - - composeOptions { - kotlinCompilerExtensionVersion = libs.versions.composeCompiler.get() - } } dependencies { diff --git a/android/viewmodel/widget/android-viewmodel-widget.gradle.kts b/android/viewmodel/widget/android-viewmodel-widget.gradle.kts index c0a5eaa0fd..f3131eec22 100644 --- a/android/viewmodel/widget/android-viewmodel-widget.gradle.kts +++ b/android/viewmodel/widget/android-viewmodel-widget.gradle.kts @@ -2,7 +2,7 @@ plugins { libs.plugins.apply { alias(androidLibrary) alias(kotlinAndroid) - alias(ksp) + alias(mokkery) } } @@ -30,13 +30,10 @@ dependencies { implementation(kermit) testImplementation(test) - testImplementation(mockative) testImplementation(coroutinesTest) } } - kspTest(libs.processors.mockative) - Modules.Common.Core.apply { implementation(project(model)) } diff --git a/android/viewmodel/widget/src/test/kotlin/com/oztechan/ccc/android/viewmodel/widget/WidgetViewModelTest.kt b/android/viewmodel/widget/src/test/kotlin/com/oztechan/ccc/android/viewmodel/widget/WidgetViewModelTest.kt index 4d47accedd..3fea803a4b 100644 --- a/android/viewmodel/widget/src/test/kotlin/com/oztechan/ccc/android/viewmodel/widget/WidgetViewModelTest.kt +++ b/android/viewmodel/widget/src/test/kotlin/com/oztechan/ccc/android/viewmodel/widget/WidgetViewModelTest.kt @@ -12,15 +12,15 @@ import com.oztechan.ccc.client.storage.app.AppStorage import com.oztechan.ccc.client.storage.calculation.CalculationStorage import com.oztechan.ccc.common.core.model.Conversion import com.oztechan.ccc.common.core.model.Currency -import io.mockative.Mock -import io.mockative.any -import io.mockative.classOf -import io.mockative.coEvery -import io.mockative.coVerify -import io.mockative.configure -import io.mockative.every -import io.mockative.mock -import io.mockative.verify +import dev.mokkery.MockMode +import dev.mokkery.answering.returns +import dev.mokkery.every +import dev.mokkery.everySuspend +import dev.mokkery.matcher.any +import dev.mokkery.mock +import dev.mokkery.verify +import dev.mokkery.verify.VerifyMode +import dev.mokkery.verifySuspend import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.onSubscription @@ -47,18 +47,13 @@ internal class WidgetViewModelTest { ) } - @Mock - private val calculationStorage = - configure(mock(classOf())) { stubsUnitByDefault = true } + private val calculationStorage = mock(MockMode.autoUnit) - @Mock - private val backendApiService = mock(classOf()) + private val backendApiService = mock() - @Mock - private val currencyDataSource = mock(classOf()) + private val currencyDataSource = mock() - @Mock - private val appStorage = mock(classOf()) + private val appStorage = mock() private val base = "EUR" private val firstBase = "USD" @@ -92,10 +87,10 @@ internal class WidgetViewModelTest { .returns(3) runTest { - coEvery { backendApiService.getConversion(base) } + everySuspend { backendApiService.getConversion(base) } .returns(conversion) - coEvery { currencyDataSource.getActiveCurrencies() } + everySuspend { currencyDataSource.getActiveCurrencies() } .returns(activeCurrencyList) } } @@ -106,7 +101,7 @@ internal class WidgetViewModelTest { every { calculationStorage.currentBase } .returns(firstBase) - coEvery { backendApiService.getConversion(firstBase) } + everySuspend { backendApiService.getConversion(firstBase) } .returns(conversion) repeat(activeCurrencyList.count() + 1) { @@ -123,7 +118,7 @@ internal class WidgetViewModelTest { every { calculationStorage.currentBase } .returns(base) - coEvery { backendApiService.getConversion(base) } + everySuspend { backendApiService.getConversion(base) } .returns(conversion) repeat(activeCurrencyList.count() + 1) { @@ -140,7 +135,7 @@ internal class WidgetViewModelTest { every { calculationStorage.currentBase } .returns(lastBase) - coEvery { backendApiService.getConversion(lastBase) } + everySuspend { backendApiService.getConversion(lastBase) } .returns(conversion) repeat(activeCurrencyList.count() + 1) { @@ -177,11 +172,9 @@ internal class WidgetViewModelTest { viewModel.event.onRefreshClick() - coVerify { backendApiService.getConversion(base) } - .wasInvoked() + verifySuspend { backendApiService.getConversion(base) } - coVerify { currencyDataSource.getActiveCurrencies() } - .wasInvoked() + verifySuspend { currencyDataSource.getActiveCurrencies() } } @Test @@ -191,11 +184,9 @@ internal class WidgetViewModelTest { viewModel.event.onRefreshClick() - coVerify { backendApiService.getConversion(base) } - .wasNotInvoked() + verifySuspend(VerifyMode.not) { backendApiService.getConversion(base) } - coVerify { currencyDataSource.getActiveCurrencies() } - .wasNotInvoked() + verifySuspend(VerifyMode.not) { currencyDataSource.getActiveCurrencies() } } @Test @@ -225,11 +216,9 @@ internal class WidgetViewModelTest { viewModel.event.onRefreshClick() - coVerify { currencyDataSource.getActiveCurrencies() } - .wasNotInvoked() + verifySuspend(VerifyMode.not) { currencyDataSource.getActiveCurrencies() } - verify { calculationStorage.currentBase = any() } - .wasNotInvoked() + verify(VerifyMode.not) { calculationStorage.currentBase = any() } } // region Event @@ -241,22 +230,18 @@ internal class WidgetViewModelTest { viewModel.event.onNextClick() - coVerify { currencyDataSource.getActiveCurrencies() } - .wasInvoked() + verifySuspend { currencyDataSource.getActiveCurrencies() } verify { calculationStorage.currentBase = lastBase } - .wasInvoked() every { calculationStorage.currentBase } .returns(lastBase) viewModel.event.onNextClick() - coVerify { currencyDataSource.getActiveCurrencies() } - .wasInvoked() + verifySuspend { currencyDataSource.getActiveCurrencies() } verify { calculationStorage.currentBase = firstBase } - .wasInvoked() } @Test @@ -267,22 +252,18 @@ internal class WidgetViewModelTest { viewModel.event.onPreviousClick() - coVerify { currencyDataSource.getActiveCurrencies() } - .wasInvoked() + verifySuspend { currencyDataSource.getActiveCurrencies() } verify { calculationStorage.currentBase = firstBase } - .wasInvoked() every { calculationStorage.currentBase } .returns(firstBase) viewModel.event.onPreviousClick() - coVerify { currencyDataSource.getActiveCurrencies() } - .wasInvoked() + verifySuspend { currencyDataSource.getActiveCurrencies() } verify { calculationStorage.currentBase = lastBase } - .wasInvoked() } @Test @@ -292,14 +273,11 @@ internal class WidgetViewModelTest { viewModel.event.onRefreshClick() - coVerify { backendApiService.getConversion(base) } - .wasInvoked() + verifySuspend { backendApiService.getConversion(base) } - coVerify { currencyDataSource.getActiveCurrencies() } - .wasInvoked() + verifySuspend { currencyDataSource.getActiveCurrencies() } verify { calculationStorage.currentBase } - .wasInvoked() } @Test diff --git a/backend/app/backend-app.gradle.kts b/backend/app/backend-app.gradle.kts index 43a32c0499..acfb88b02c 100644 --- a/backend/app/backend-app.gradle.kts +++ b/backend/app/backend-app.gradle.kts @@ -2,7 +2,6 @@ plugins { libs.plugins.apply { application alias(kotlinJvm) - alias(ksp) } } diff --git a/backend/controller/api/backend-controller-api.gradle.kts b/backend/controller/api/backend-controller-api.gradle.kts index e595d68877..d76740b014 100644 --- a/backend/controller/api/backend-controller-api.gradle.kts +++ b/backend/controller/api/backend-controller-api.gradle.kts @@ -1,22 +1,23 @@ +import dev.mokkery.gradle.ApplicationRule + plugins { libs.plugins.apply { alias(kotlinJvm) - alias(ksp) + alias(mokkery) } } +mokkery.rule.set(ApplicationRule.Listed("test")) + dependencies { libs.common.apply { implementation(kermit) implementation(koinCore) - testImplementation(mockative) testImplementation(coroutinesTest) testImplementation(test) } - kspTest(libs.processors.mockative) - Modules.Common.Core.apply { implementation(project(network)) implementation(project(model)) diff --git a/backend/controller/api/src/test/kotlin/com/oztechan/ccc/backend/controller/api/APIControllerTest.kt b/backend/controller/api/src/test/kotlin/com/oztechan/ccc/backend/controller/api/APIControllerTest.kt index 46d91e3e3e..188b6f3f18 100644 --- a/backend/controller/api/src/test/kotlin/com/oztechan/ccc/backend/controller/api/APIControllerTest.kt +++ b/backend/controller/api/src/test/kotlin/com/oztechan/ccc/backend/controller/api/APIControllerTest.kt @@ -3,11 +3,10 @@ package com.oztechan.ccc.backend.controller.api import com.oztechan.ccc.backend.controller.api.mapper.toExchangeRateAPIModel import com.oztechan.ccc.common.core.model.Conversion import com.oztechan.ccc.common.datasource.conversion.ConversionDataSource -import io.mockative.Mock -import io.mockative.classOf -import io.mockative.coEvery -import io.mockative.coVerify -import io.mockative.mock +import dev.mokkery.answering.returns +import dev.mokkery.everySuspend +import dev.mokkery.mock +import dev.mokkery.verifySuspend import kotlinx.coroutines.test.runTest import kotlin.test.Test import kotlin.test.assertEquals @@ -17,8 +16,7 @@ internal class APIControllerTest { APIControllerImpl(conversionDataSource) } - @Mock - private val conversionDataSource = mock(classOf()) + private val conversionDataSource = mock() @Test fun `getExchangeRateByBase returns getConversionByBase from ConversionDataSource`() = @@ -26,13 +24,12 @@ internal class APIControllerTest { val base = "EUR" val result = Conversion(base) - coEvery { conversionDataSource.getConversionByBase(base) } + everySuspend { conversionDataSource.getConversionByBase(base) } .returns(result) assertEquals(result.toExchangeRateAPIModel(), subject.getExchangeRateByBase(base)) - coVerify { conversionDataSource.getConversionByBase(base) } - .wasInvoked() + verifySuspend { conversionDataSource.getConversionByBase(base) } } @Test @@ -41,12 +38,11 @@ internal class APIControllerTest { val base = "eur" val result = Conversion(base.uppercase()) - coEvery { conversionDataSource.getConversionByBase(base.uppercase()) } + everySuspend { conversionDataSource.getConversionByBase(base.uppercase()) } .returns(result) assertEquals(result.toExchangeRateAPIModel(), subject.getExchangeRateByBase(base)) - coVerify { conversionDataSource.getConversionByBase(base.uppercase()) } - .wasInvoked() + verifySuspend { conversionDataSource.getConversionByBase(base.uppercase()) } } } diff --git a/backend/service/premium/backend-service-premium.gradle.kts b/backend/service/premium/backend-service-premium.gradle.kts index 4d9b26fe23..350f078076 100644 --- a/backend/service/premium/backend-service-premium.gradle.kts +++ b/backend/service/premium/backend-service-premium.gradle.kts @@ -1,23 +1,24 @@ +import dev.mokkery.gradle.ApplicationRule + plugins { libs.plugins.apply { alias(kotlinJvm) - alias(ksp) + alias(mokkery) } } +mokkery.rule.set(ApplicationRule.Listed("test")) + dependencies { libs.common.apply { implementation(koinCore) implementation(coroutines) implementation(kermit) - testImplementation(mockative) testImplementation(coroutinesTest) testImplementation(test) } - kspTest(libs.processors.mockative) - Modules.Common.Core.apply { implementation(project(network)) implementation(project(model)) diff --git a/backend/service/premium/src/test/kotlin/com/oztechan/ccc/backend/service/premium/PremiumApiServiceTest.kt b/backend/service/premium/src/test/kotlin/com/oztechan/ccc/backend/service/premium/PremiumApiServiceTest.kt index f1eeea4293..064c7ff8e0 100644 --- a/backend/service/premium/src/test/kotlin/com/oztechan/ccc/backend/service/premium/PremiumApiServiceTest.kt +++ b/backend/service/premium/src/test/kotlin/com/oztechan/ccc/backend/service/premium/PremiumApiServiceTest.kt @@ -8,11 +8,12 @@ import com.oztechan.ccc.common.core.network.api.premium.PremiumApi import com.oztechan.ccc.common.core.network.mapper.toConversionModel import com.oztechan.ccc.common.core.network.model.Conversion import com.oztechan.ccc.common.core.network.model.ExchangeRate -import io.mockative.Mock -import io.mockative.classOf -import io.mockative.coEvery -import io.mockative.coVerify -import io.mockative.mock +import dev.mokkery.answering.returns +import dev.mokkery.answering.throws +import dev.mokkery.everySuspend +import dev.mokkery.mock +import dev.mokkery.verify.VerifyMode +import dev.mokkery.verifySuspend import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runTest import kotlin.test.Test @@ -28,8 +29,7 @@ internal class PremiumApiServiceTest { PremiumApiServiceImpl(premiumAPI, UnconfinedTestDispatcher()) } - @Mock - private val premiumAPI: PremiumApi = mock(classOf()) + private val premiumAPI: PremiumApi = mock() private val base = "EUR" private val exchangeRate = ExchangeRate(base, "12.21.2121", Conversion(base)) @@ -42,13 +42,12 @@ internal class PremiumApiServiceTest { assertTrue { it.isFailure } } - coVerify { premiumAPI.getExchangeRate("") } - .wasNotInvoked() + verifySuspend(VerifyMode.not) { premiumAPI.getExchangeRate("") } } @Test fun `getConversion error`() = runTest { - coEvery { premiumAPI.getExchangeRate(base) } + everySuspend { premiumAPI.getExchangeRate(base) } .throws(throwable) runCatching { subject.getConversion(base) }.let { @@ -60,13 +59,12 @@ internal class PremiumApiServiceTest { assertEquals(throwable.message, it.exceptionOrNull()!!.cause!!.message) } - coVerify { premiumAPI.getExchangeRate(base) } - .wasInvoked() + verifySuspend { premiumAPI.getExchangeRate(base) } } @Test fun `getConversion success`() = runTest { - coEvery { premiumAPI.getExchangeRate(base) } + everySuspend { premiumAPI.getExchangeRate(base) } .returns(exchangeRate) runCatching { subject.getConversion(base) }.let { @@ -76,7 +74,6 @@ internal class PremiumApiServiceTest { assertEquals(exchangeRate.toConversionModel(), it.getOrNull()) } - coVerify { premiumAPI.getExchangeRate(base) } - .wasInvoked() + verifySuspend { premiumAPI.getExchangeRate(base) } } } diff --git a/buildSrc/src/main/kotlin/ProjectSettings.kt b/buildSrc/src/main/kotlin/ProjectSettings.kt index cebe004274..06b5ea98b4 100644 --- a/buildSrc/src/main/kotlin/ProjectSettings.kt +++ b/buildSrc/src/main/kotlin/ProjectSettings.kt @@ -3,7 +3,6 @@ */ import org.gradle.api.JavaVersion import org.gradle.api.Project -import java.io.ByteArrayOutputStream import java.io.File object ProjectSettings { @@ -48,35 +47,27 @@ object ProjectSettings { "0.0.1" } - private fun gitCommitCount(project: Project): String { - val os = ByteArrayOutputStream() - project.exec { - commandLine = "git rev-list --first-parent --count HEAD".split(" ") - standardOutput = os - } - return String(os.toByteArray()).trim() - } + @Suppress("UnstableApiUsage") + private fun gitCommitCount(project: Project): String = project.providers.exec { + commandLine("git rev-list --first-parent --count HEAD".split(" ")) + }.standardOutput.asText.get().trim() - private fun isMaster(project: Project): Boolean { - val os = ByteArrayOutputStream() - project.exec { - commandLine = "git rev-parse --abbrev-ref HEAD".split(" ") - standardOutput = os - } - return String(os.toByteArray()).trim() == "master" - } + @Suppress("UnstableApiUsage") + private fun isMaster(project: Project): Boolean = project.providers.exec { + commandLine("git rev-parse --abbrev-ref HEAD".split(" ")) + }.standardOutput.asText.get().trim() == "master" private fun isCI() = System.getenv("CI") == "true" - @Suppress("TooGenericExceptionCaught") + @Suppress("TooGenericExceptionCaught", "UnstableApiUsage") private fun Project.setIOSVersion(versionName: String) = try { - exec { + project.providers.exec { workingDir = File("${project.rootDir}/ios") - commandLine = "agvtool new-version -all ${getVersionCode(project)}".split(" ") + commandLine("agvtool new-version -all ${getVersionCode(project)}".split(" ")) } - exec { + project.providers.exec { workingDir = File("${project.rootDir}/ios") - commandLine = "agvtool new-marketing-version $versionName".split(" ") + commandLine("agvtool new-marketing-version $versionName".split(" ")) } } catch (e: Exception) { println("agvtool exist only mac environment") diff --git a/client/core/persistence/client-core-persistence.gradle.kts b/client/core/persistence/client-core-persistence.gradle.kts index 557968396b..3330673442 100644 --- a/client/core/persistence/client-core-persistence.gradle.kts +++ b/client/core/persistence/client-core-persistence.gradle.kts @@ -2,7 +2,7 @@ plugins { libs.plugins.apply { alias(kotlinMultiplatform) alias(androidLibrary) - alias(ksp) + alias(mokkery) } } kotlin { @@ -21,22 +21,11 @@ kotlin { } } commonTest.dependencies { - libs.common.apply { - implementation(test) - implementation(mockative) - } + implementation(libs.common.test) } } } -dependencies { - configurations - .filter { it.name.startsWith("ksp") && it.name.contains("Test") } - .forEach { - add(it.name, libs.processors.mockative) - } -} - android { ProjectSettings.apply { namespace = Modules.Client.Core.persistence.packageName diff --git a/client/core/persistence/src/commonTest/kotlin/com/oztechan/ccc/client/core/persistence/PersistenceTest.kt b/client/core/persistence/src/commonTest/kotlin/com/oztechan/ccc/client/core/persistence/PersistenceTest.kt index fbbccc21bc..e56a88a282 100644 --- a/client/core/persistence/src/commonTest/kotlin/com/oztechan/ccc/client/core/persistence/PersistenceTest.kt +++ b/client/core/persistence/src/commonTest/kotlin/com/oztechan/ccc/client/core/persistence/PersistenceTest.kt @@ -8,12 +8,11 @@ import com.oztechan.ccc.client.core.persistence.fakes.Fakes.mockInt import com.oztechan.ccc.client.core.persistence.fakes.Fakes.mockLong import com.oztechan.ccc.client.core.persistence.fakes.Fakes.mockString import com.russhwolf.settings.Settings -import io.mockative.Mock -import io.mockative.classOf -import io.mockative.configure -import io.mockative.every -import io.mockative.mock -import io.mockative.verify +import dev.mokkery.MockMode +import dev.mokkery.answering.returns +import dev.mokkery.every +import dev.mokkery.mock +import dev.mokkery.verify import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFailsWith @@ -23,8 +22,7 @@ internal class PersistenceTest { PersistenceImpl(settings) } - @Mock - private val settings = configure(mock(classOf())) { stubsUnitByDefault = true } + private val settings = mock(MockMode.autoUnit) @Test fun `getValue returns the same type`() { @@ -46,15 +44,10 @@ internal class PersistenceTest { assertEquals(mockLong, persistence.getValue(KEY, mockLong)) verify { settings.getFloat(KEY, mockFloat) } - .wasInvoked() verify { settings.getBoolean(KEY, mockBoolean) } - .wasInvoked() verify { settings.getInt(KEY, mockInt) } - .wasInvoked() verify { settings.getString(KEY, mockString) } - .wasInvoked() verify { settings.getLong(KEY, mockLong) } - .wasInvoked() } @Test @@ -66,15 +59,10 @@ internal class PersistenceTest { persistence.setValue(KEY, mockLong) verify { settings.putFloat(KEY, mockFloat) } - .wasInvoked() verify { settings.putBoolean(KEY, mockBoolean) } - .wasInvoked() verify { settings.putInt(KEY, mockInt) } - .wasInvoked() verify { settings.putString(KEY, mockString) } - .wasInvoked() verify { settings.putLong(KEY, mockLong) } - .wasInvoked() } @Test diff --git a/client/core/res/client-core-res.gradle.kts b/client/core/res/client-core-res.gradle.kts index 80986f994e..8f07949500 100644 --- a/client/core/res/client-core-res.gradle.kts +++ b/client/core/res/client-core-res.gradle.kts @@ -51,9 +51,8 @@ android { } multiplatformResources { - multiplatformResourcesPackage = Modules.Client.Core.res.packageName - disableStaticFrameworkWarning = true - multiplatformResourcesClassName = Modules.Client.Core.res.frameworkName + resourcesPackage.set(Modules.Client.Core.res.packageName) + resourcesClassName.set(Modules.Client.Core.res.frameworkName) } // todo https://github.com/icerockdev/moko-resources/issues/421 diff --git a/client/core/res/src/commonMain/resources/MR/base/strings.xml b/client/core/res/src/commonMain/moko-resources/base/strings.xml similarity index 100% rename from client/core/res/src/commonMain/resources/MR/base/strings.xml rename to client/core/res/src/commonMain/moko-resources/base/strings.xml diff --git a/client/core/res/src/commonMain/resources/MR/colors/colors.xml b/client/core/res/src/commonMain/moko-resources/colors/colors.xml similarity index 82% rename from client/core/res/src/commonMain/resources/MR/colors/colors.xml rename to client/core/res/src/commonMain/moko-resources/colors/colors.xml index 3deec77999..9c6e4fb4fa 100644 --- a/client/core/res/src/commonMain/resources/MR/colors/colors.xml +++ b/client/core/res/src/commonMain/moko-resources/colors/colors.xml @@ -7,32 +7,39 @@ ~ 200 variant for dark mode ~ 500 variant for light mode --> - + + #009688ff #80cbc4ff - + + #00bcd4ff #80deeaff - + + #03a9f4ff #81d4faff - + + #4caf50ff #a5d6a7ff - + + #2196f3ff #90caf9ff - + + #ff9800ff #ffcc80ff - + + #f44336ff #ef9a9aff diff --git a/client/core/res/src/commonMain/resources/MR/images/aed@2x.png b/client/core/res/src/commonMain/moko-resources/images/aed@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/aed@2x.png rename to client/core/res/src/commonMain/moko-resources/images/aed@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/afn@2x.png b/client/core/res/src/commonMain/moko-resources/images/afn@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/afn@2x.png rename to client/core/res/src/commonMain/moko-resources/images/afn@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/all@2x.png b/client/core/res/src/commonMain/moko-resources/images/all@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/all@2x.png rename to client/core/res/src/commonMain/moko-resources/images/all@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/amd@2x.png b/client/core/res/src/commonMain/moko-resources/images/amd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/amd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/amd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/ang@2x.png b/client/core/res/src/commonMain/moko-resources/images/ang@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/ang@2x.png rename to client/core/res/src/commonMain/moko-resources/images/ang@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/aoa@2x.png b/client/core/res/src/commonMain/moko-resources/images/aoa@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/aoa@2x.png rename to client/core/res/src/commonMain/moko-resources/images/aoa@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/ars@2x.png b/client/core/res/src/commonMain/moko-resources/images/ars@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/ars@2x.png rename to client/core/res/src/commonMain/moko-resources/images/ars@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/aud@2x.png b/client/core/res/src/commonMain/moko-resources/images/aud@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/aud@2x.png rename to client/core/res/src/commonMain/moko-resources/images/aud@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/awg@2x.png b/client/core/res/src/commonMain/moko-resources/images/awg@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/awg@2x.png rename to client/core/res/src/commonMain/moko-resources/images/awg@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/azn@2x.png b/client/core/res/src/commonMain/moko-resources/images/azn@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/azn@2x.png rename to client/core/res/src/commonMain/moko-resources/images/azn@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/bam@2x.png b/client/core/res/src/commonMain/moko-resources/images/bam@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/bam@2x.png rename to client/core/res/src/commonMain/moko-resources/images/bam@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/bbd@2x.png b/client/core/res/src/commonMain/moko-resources/images/bbd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/bbd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/bbd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/bdt@2x.png b/client/core/res/src/commonMain/moko-resources/images/bdt@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/bdt@2x.png rename to client/core/res/src/commonMain/moko-resources/images/bdt@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/bgn@2x.png b/client/core/res/src/commonMain/moko-resources/images/bgn@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/bgn@2x.png rename to client/core/res/src/commonMain/moko-resources/images/bgn@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/bhd@2x.png b/client/core/res/src/commonMain/moko-resources/images/bhd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/bhd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/bhd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/bif@2x.png b/client/core/res/src/commonMain/moko-resources/images/bif@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/bif@2x.png rename to client/core/res/src/commonMain/moko-resources/images/bif@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/bmd@2x.png b/client/core/res/src/commonMain/moko-resources/images/bmd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/bmd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/bmd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/bnd@2x.png b/client/core/res/src/commonMain/moko-resources/images/bnd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/bnd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/bnd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/bob@2x.png b/client/core/res/src/commonMain/moko-resources/images/bob@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/bob@2x.png rename to client/core/res/src/commonMain/moko-resources/images/bob@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/brl@2x.png b/client/core/res/src/commonMain/moko-resources/images/brl@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/brl@2x.png rename to client/core/res/src/commonMain/moko-resources/images/brl@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/bsd@2x.png b/client/core/res/src/commonMain/moko-resources/images/bsd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/bsd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/bsd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/btn@2x.png b/client/core/res/src/commonMain/moko-resources/images/btn@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/btn@2x.png rename to client/core/res/src/commonMain/moko-resources/images/btn@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/bwp@2x.png b/client/core/res/src/commonMain/moko-resources/images/bwp@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/bwp@2x.png rename to client/core/res/src/commonMain/moko-resources/images/bwp@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/byn@2x.png b/client/core/res/src/commonMain/moko-resources/images/byn@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/byn@2x.png rename to client/core/res/src/commonMain/moko-resources/images/byn@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/bzd@2x.png b/client/core/res/src/commonMain/moko-resources/images/bzd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/bzd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/bzd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/cad@2x.png b/client/core/res/src/commonMain/moko-resources/images/cad@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/cad@2x.png rename to client/core/res/src/commonMain/moko-resources/images/cad@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/cdf@2x.png b/client/core/res/src/commonMain/moko-resources/images/cdf@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/cdf@2x.png rename to client/core/res/src/commonMain/moko-resources/images/cdf@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/chf@2x.png b/client/core/res/src/commonMain/moko-resources/images/chf@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/chf@2x.png rename to client/core/res/src/commonMain/moko-resources/images/chf@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/clp@2x.png b/client/core/res/src/commonMain/moko-resources/images/clp@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/clp@2x.png rename to client/core/res/src/commonMain/moko-resources/images/clp@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/cny@2x.png b/client/core/res/src/commonMain/moko-resources/images/cny@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/cny@2x.png rename to client/core/res/src/commonMain/moko-resources/images/cny@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/cop@2x.png b/client/core/res/src/commonMain/moko-resources/images/cop@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/cop@2x.png rename to client/core/res/src/commonMain/moko-resources/images/cop@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/crc@2x.png b/client/core/res/src/commonMain/moko-resources/images/crc@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/crc@2x.png rename to client/core/res/src/commonMain/moko-resources/images/crc@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/cup@2x.png b/client/core/res/src/commonMain/moko-resources/images/cup@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/cup@2x.png rename to client/core/res/src/commonMain/moko-resources/images/cup@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/cve@2x.png b/client/core/res/src/commonMain/moko-resources/images/cve@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/cve@2x.png rename to client/core/res/src/commonMain/moko-resources/images/cve@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/czk@2x.png b/client/core/res/src/commonMain/moko-resources/images/czk@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/czk@2x.png rename to client/core/res/src/commonMain/moko-resources/images/czk@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/djf@2x.png b/client/core/res/src/commonMain/moko-resources/images/djf@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/djf@2x.png rename to client/core/res/src/commonMain/moko-resources/images/djf@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/dkk@2x.png b/client/core/res/src/commonMain/moko-resources/images/dkk@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/dkk@2x.png rename to client/core/res/src/commonMain/moko-resources/images/dkk@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/dop@2x.png b/client/core/res/src/commonMain/moko-resources/images/dop@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/dop@2x.png rename to client/core/res/src/commonMain/moko-resources/images/dop@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/dzd@2x.png b/client/core/res/src/commonMain/moko-resources/images/dzd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/dzd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/dzd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/egp@2x.png b/client/core/res/src/commonMain/moko-resources/images/egp@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/egp@2x.png rename to client/core/res/src/commonMain/moko-resources/images/egp@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/ern@2x.png b/client/core/res/src/commonMain/moko-resources/images/ern@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/ern@2x.png rename to client/core/res/src/commonMain/moko-resources/images/ern@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/etb@2x.png b/client/core/res/src/commonMain/moko-resources/images/etb@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/etb@2x.png rename to client/core/res/src/commonMain/moko-resources/images/etb@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/eur@2x.png b/client/core/res/src/commonMain/moko-resources/images/eur@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/eur@2x.png rename to client/core/res/src/commonMain/moko-resources/images/eur@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/fjd@2x.png b/client/core/res/src/commonMain/moko-resources/images/fjd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/fjd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/fjd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/fkp@2x.png b/client/core/res/src/commonMain/moko-resources/images/fkp@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/fkp@2x.png rename to client/core/res/src/commonMain/moko-resources/images/fkp@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/fok@2x.png b/client/core/res/src/commonMain/moko-resources/images/fok@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/fok@2x.png rename to client/core/res/src/commonMain/moko-resources/images/fok@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/gbp@2x.png b/client/core/res/src/commonMain/moko-resources/images/gbp@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/gbp@2x.png rename to client/core/res/src/commonMain/moko-resources/images/gbp@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/gel@2x.png b/client/core/res/src/commonMain/moko-resources/images/gel@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/gel@2x.png rename to client/core/res/src/commonMain/moko-resources/images/gel@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/ggp@2x.png b/client/core/res/src/commonMain/moko-resources/images/ggp@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/ggp@2x.png rename to client/core/res/src/commonMain/moko-resources/images/ggp@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/ghs@2x.png b/client/core/res/src/commonMain/moko-resources/images/ghs@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/ghs@2x.png rename to client/core/res/src/commonMain/moko-resources/images/ghs@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/gip@2x.png b/client/core/res/src/commonMain/moko-resources/images/gip@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/gip@2x.png rename to client/core/res/src/commonMain/moko-resources/images/gip@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/gmd@2x.png b/client/core/res/src/commonMain/moko-resources/images/gmd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/gmd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/gmd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/gnf@2x.png b/client/core/res/src/commonMain/moko-resources/images/gnf@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/gnf@2x.png rename to client/core/res/src/commonMain/moko-resources/images/gnf@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/gtq@2x.png b/client/core/res/src/commonMain/moko-resources/images/gtq@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/gtq@2x.png rename to client/core/res/src/commonMain/moko-resources/images/gtq@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/gyd@2x.png b/client/core/res/src/commonMain/moko-resources/images/gyd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/gyd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/gyd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/hkd@2x.png b/client/core/res/src/commonMain/moko-resources/images/hkd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/hkd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/hkd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/hnl@2x.png b/client/core/res/src/commonMain/moko-resources/images/hnl@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/hnl@2x.png rename to client/core/res/src/commonMain/moko-resources/images/hnl@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/hrk@2x.png b/client/core/res/src/commonMain/moko-resources/images/hrk@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/hrk@2x.png rename to client/core/res/src/commonMain/moko-resources/images/hrk@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/htg@2x.png b/client/core/res/src/commonMain/moko-resources/images/htg@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/htg@2x.png rename to client/core/res/src/commonMain/moko-resources/images/htg@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/huf@2x.png b/client/core/res/src/commonMain/moko-resources/images/huf@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/huf@2x.png rename to client/core/res/src/commonMain/moko-resources/images/huf@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/ic_app_logo@2x.png b/client/core/res/src/commonMain/moko-resources/images/ic_app_logo@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/ic_app_logo@2x.png rename to client/core/res/src/commonMain/moko-resources/images/ic_app_logo@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/ic_dialog_and_snackbar@2x.png b/client/core/res/src/commonMain/moko-resources/images/ic_dialog_and_snackbar@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/ic_dialog_and_snackbar@2x.png rename to client/core/res/src/commonMain/moko-resources/images/ic_dialog_and_snackbar@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/idr@2x.png b/client/core/res/src/commonMain/moko-resources/images/idr@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/idr@2x.png rename to client/core/res/src/commonMain/moko-resources/images/idr@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/ils@2x.png b/client/core/res/src/commonMain/moko-resources/images/ils@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/ils@2x.png rename to client/core/res/src/commonMain/moko-resources/images/ils@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/imp@2x.png b/client/core/res/src/commonMain/moko-resources/images/imp@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/imp@2x.png rename to client/core/res/src/commonMain/moko-resources/images/imp@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/inr@2x.png b/client/core/res/src/commonMain/moko-resources/images/inr@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/inr@2x.png rename to client/core/res/src/commonMain/moko-resources/images/inr@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/iqd@2x.png b/client/core/res/src/commonMain/moko-resources/images/iqd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/iqd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/iqd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/irr@2x.png b/client/core/res/src/commonMain/moko-resources/images/irr@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/irr@2x.png rename to client/core/res/src/commonMain/moko-resources/images/irr@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/isk@2x.png b/client/core/res/src/commonMain/moko-resources/images/isk@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/isk@2x.png rename to client/core/res/src/commonMain/moko-resources/images/isk@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/jep@2x.png b/client/core/res/src/commonMain/moko-resources/images/jep@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/jep@2x.png rename to client/core/res/src/commonMain/moko-resources/images/jep@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/jmd@2x.png b/client/core/res/src/commonMain/moko-resources/images/jmd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/jmd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/jmd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/jod@2x.png b/client/core/res/src/commonMain/moko-resources/images/jod@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/jod@2x.png rename to client/core/res/src/commonMain/moko-resources/images/jod@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/jpy@2x.png b/client/core/res/src/commonMain/moko-resources/images/jpy@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/jpy@2x.png rename to client/core/res/src/commonMain/moko-resources/images/jpy@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/kes@2x.png b/client/core/res/src/commonMain/moko-resources/images/kes@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/kes@2x.png rename to client/core/res/src/commonMain/moko-resources/images/kes@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/kgs@2x.png b/client/core/res/src/commonMain/moko-resources/images/kgs@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/kgs@2x.png rename to client/core/res/src/commonMain/moko-resources/images/kgs@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/khr@2x.png b/client/core/res/src/commonMain/moko-resources/images/khr@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/khr@2x.png rename to client/core/res/src/commonMain/moko-resources/images/khr@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/kid@2x.png b/client/core/res/src/commonMain/moko-resources/images/kid@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/kid@2x.png rename to client/core/res/src/commonMain/moko-resources/images/kid@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/kmf@2x.png b/client/core/res/src/commonMain/moko-resources/images/kmf@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/kmf@2x.png rename to client/core/res/src/commonMain/moko-resources/images/kmf@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/krw@2x.png b/client/core/res/src/commonMain/moko-resources/images/krw@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/krw@2x.png rename to client/core/res/src/commonMain/moko-resources/images/krw@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/kwd@2x.png b/client/core/res/src/commonMain/moko-resources/images/kwd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/kwd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/kwd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/kyd@2x.png b/client/core/res/src/commonMain/moko-resources/images/kyd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/kyd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/kyd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/kzt@2x.png b/client/core/res/src/commonMain/moko-resources/images/kzt@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/kzt@2x.png rename to client/core/res/src/commonMain/moko-resources/images/kzt@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/lak@2x.png b/client/core/res/src/commonMain/moko-resources/images/lak@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/lak@2x.png rename to client/core/res/src/commonMain/moko-resources/images/lak@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/lbp@2x.png b/client/core/res/src/commonMain/moko-resources/images/lbp@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/lbp@2x.png rename to client/core/res/src/commonMain/moko-resources/images/lbp@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/lkr@2x.png b/client/core/res/src/commonMain/moko-resources/images/lkr@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/lkr@2x.png rename to client/core/res/src/commonMain/moko-resources/images/lkr@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/lrd@2x.png b/client/core/res/src/commonMain/moko-resources/images/lrd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/lrd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/lrd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/lsl@2x.png b/client/core/res/src/commonMain/moko-resources/images/lsl@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/lsl@2x.png rename to client/core/res/src/commonMain/moko-resources/images/lsl@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/lyd@2x.png b/client/core/res/src/commonMain/moko-resources/images/lyd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/lyd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/lyd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/mad@2x.png b/client/core/res/src/commonMain/moko-resources/images/mad@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/mad@2x.png rename to client/core/res/src/commonMain/moko-resources/images/mad@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/mdl@2x.png b/client/core/res/src/commonMain/moko-resources/images/mdl@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/mdl@2x.png rename to client/core/res/src/commonMain/moko-resources/images/mdl@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/mga@2x.png b/client/core/res/src/commonMain/moko-resources/images/mga@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/mga@2x.png rename to client/core/res/src/commonMain/moko-resources/images/mga@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/mkd@2x.png b/client/core/res/src/commonMain/moko-resources/images/mkd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/mkd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/mkd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/mmk@2x.png b/client/core/res/src/commonMain/moko-resources/images/mmk@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/mmk@2x.png rename to client/core/res/src/commonMain/moko-resources/images/mmk@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/mnt@2x.png b/client/core/res/src/commonMain/moko-resources/images/mnt@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/mnt@2x.png rename to client/core/res/src/commonMain/moko-resources/images/mnt@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/mop@2x.png b/client/core/res/src/commonMain/moko-resources/images/mop@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/mop@2x.png rename to client/core/res/src/commonMain/moko-resources/images/mop@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/mru@2x.png b/client/core/res/src/commonMain/moko-resources/images/mru@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/mru@2x.png rename to client/core/res/src/commonMain/moko-resources/images/mru@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/mur@2x.png b/client/core/res/src/commonMain/moko-resources/images/mur@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/mur@2x.png rename to client/core/res/src/commonMain/moko-resources/images/mur@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/mvr@2x.png b/client/core/res/src/commonMain/moko-resources/images/mvr@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/mvr@2x.png rename to client/core/res/src/commonMain/moko-resources/images/mvr@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/mwk@2x.png b/client/core/res/src/commonMain/moko-resources/images/mwk@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/mwk@2x.png rename to client/core/res/src/commonMain/moko-resources/images/mwk@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/mxn@2x.png b/client/core/res/src/commonMain/moko-resources/images/mxn@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/mxn@2x.png rename to client/core/res/src/commonMain/moko-resources/images/mxn@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/myr@2x.png b/client/core/res/src/commonMain/moko-resources/images/myr@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/myr@2x.png rename to client/core/res/src/commonMain/moko-resources/images/myr@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/mzn@2x.png b/client/core/res/src/commonMain/moko-resources/images/mzn@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/mzn@2x.png rename to client/core/res/src/commonMain/moko-resources/images/mzn@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/nad@2x.png b/client/core/res/src/commonMain/moko-resources/images/nad@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/nad@2x.png rename to client/core/res/src/commonMain/moko-resources/images/nad@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/ngn@2x.png b/client/core/res/src/commonMain/moko-resources/images/ngn@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/ngn@2x.png rename to client/core/res/src/commonMain/moko-resources/images/ngn@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/nio@2x.png b/client/core/res/src/commonMain/moko-resources/images/nio@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/nio@2x.png rename to client/core/res/src/commonMain/moko-resources/images/nio@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/nok@2x.png b/client/core/res/src/commonMain/moko-resources/images/nok@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/nok@2x.png rename to client/core/res/src/commonMain/moko-resources/images/nok@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/npr@2x.png b/client/core/res/src/commonMain/moko-resources/images/npr@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/npr@2x.png rename to client/core/res/src/commonMain/moko-resources/images/npr@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/nzd@2x.png b/client/core/res/src/commonMain/moko-resources/images/nzd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/nzd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/nzd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/omr@2x.png b/client/core/res/src/commonMain/moko-resources/images/omr@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/omr@2x.png rename to client/core/res/src/commonMain/moko-resources/images/omr@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/pab@2x.png b/client/core/res/src/commonMain/moko-resources/images/pab@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/pab@2x.png rename to client/core/res/src/commonMain/moko-resources/images/pab@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/pen@2x.png b/client/core/res/src/commonMain/moko-resources/images/pen@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/pen@2x.png rename to client/core/res/src/commonMain/moko-resources/images/pen@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/pgk@2x.png b/client/core/res/src/commonMain/moko-resources/images/pgk@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/pgk@2x.png rename to client/core/res/src/commonMain/moko-resources/images/pgk@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/php@2x.png b/client/core/res/src/commonMain/moko-resources/images/php@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/php@2x.png rename to client/core/res/src/commonMain/moko-resources/images/php@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/pkr@2x.png b/client/core/res/src/commonMain/moko-resources/images/pkr@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/pkr@2x.png rename to client/core/res/src/commonMain/moko-resources/images/pkr@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/pln@2x.png b/client/core/res/src/commonMain/moko-resources/images/pln@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/pln@2x.png rename to client/core/res/src/commonMain/moko-resources/images/pln@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/pyg@2x.png b/client/core/res/src/commonMain/moko-resources/images/pyg@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/pyg@2x.png rename to client/core/res/src/commonMain/moko-resources/images/pyg@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/qar@2x.png b/client/core/res/src/commonMain/moko-resources/images/qar@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/qar@2x.png rename to client/core/res/src/commonMain/moko-resources/images/qar@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/ron@2x.png b/client/core/res/src/commonMain/moko-resources/images/ron@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/ron@2x.png rename to client/core/res/src/commonMain/moko-resources/images/ron@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/rsd@2x.png b/client/core/res/src/commonMain/moko-resources/images/rsd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/rsd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/rsd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/rub@2x.png b/client/core/res/src/commonMain/moko-resources/images/rub@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/rub@2x.png rename to client/core/res/src/commonMain/moko-resources/images/rub@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/rwf@2x.png b/client/core/res/src/commonMain/moko-resources/images/rwf@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/rwf@2x.png rename to client/core/res/src/commonMain/moko-resources/images/rwf@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/sar@2x.png b/client/core/res/src/commonMain/moko-resources/images/sar@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/sar@2x.png rename to client/core/res/src/commonMain/moko-resources/images/sar@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/sbd@2x.png b/client/core/res/src/commonMain/moko-resources/images/sbd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/sbd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/sbd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/scr@2x.png b/client/core/res/src/commonMain/moko-resources/images/scr@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/scr@2x.png rename to client/core/res/src/commonMain/moko-resources/images/scr@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/sdg@2x.png b/client/core/res/src/commonMain/moko-resources/images/sdg@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/sdg@2x.png rename to client/core/res/src/commonMain/moko-resources/images/sdg@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/sek@2x.png b/client/core/res/src/commonMain/moko-resources/images/sek@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/sek@2x.png rename to client/core/res/src/commonMain/moko-resources/images/sek@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/sgd@2x.png b/client/core/res/src/commonMain/moko-resources/images/sgd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/sgd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/sgd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/shp@2x.png b/client/core/res/src/commonMain/moko-resources/images/shp@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/shp@2x.png rename to client/core/res/src/commonMain/moko-resources/images/shp@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/sle@2x.png b/client/core/res/src/commonMain/moko-resources/images/sle@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/sle@2x.png rename to client/core/res/src/commonMain/moko-resources/images/sle@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/sll@2x.png b/client/core/res/src/commonMain/moko-resources/images/sll@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/sll@2x.png rename to client/core/res/src/commonMain/moko-resources/images/sll@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/sos@2x.png b/client/core/res/src/commonMain/moko-resources/images/sos@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/sos@2x.png rename to client/core/res/src/commonMain/moko-resources/images/sos@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/srd@2x.png b/client/core/res/src/commonMain/moko-resources/images/srd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/srd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/srd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/ssp@2x.png b/client/core/res/src/commonMain/moko-resources/images/ssp@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/ssp@2x.png rename to client/core/res/src/commonMain/moko-resources/images/ssp@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/stn@2x.png b/client/core/res/src/commonMain/moko-resources/images/stn@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/stn@2x.png rename to client/core/res/src/commonMain/moko-resources/images/stn@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/syp@2x.png b/client/core/res/src/commonMain/moko-resources/images/syp@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/syp@2x.png rename to client/core/res/src/commonMain/moko-resources/images/syp@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/szl@2x.png b/client/core/res/src/commonMain/moko-resources/images/szl@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/szl@2x.png rename to client/core/res/src/commonMain/moko-resources/images/szl@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/thb@2x.png b/client/core/res/src/commonMain/moko-resources/images/thb@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/thb@2x.png rename to client/core/res/src/commonMain/moko-resources/images/thb@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/tjs@2x.png b/client/core/res/src/commonMain/moko-resources/images/tjs@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/tjs@2x.png rename to client/core/res/src/commonMain/moko-resources/images/tjs@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/tmt@2x.png b/client/core/res/src/commonMain/moko-resources/images/tmt@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/tmt@2x.png rename to client/core/res/src/commonMain/moko-resources/images/tmt@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/tnd@2x.png b/client/core/res/src/commonMain/moko-resources/images/tnd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/tnd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/tnd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/top@2x.png b/client/core/res/src/commonMain/moko-resources/images/top@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/top@2x.png rename to client/core/res/src/commonMain/moko-resources/images/top@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/tryy@2x.png b/client/core/res/src/commonMain/moko-resources/images/tryy@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/tryy@2x.png rename to client/core/res/src/commonMain/moko-resources/images/tryy@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/ttd@2x.png b/client/core/res/src/commonMain/moko-resources/images/ttd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/ttd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/ttd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/tvd@2x.png b/client/core/res/src/commonMain/moko-resources/images/tvd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/tvd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/tvd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/twd@2x.png b/client/core/res/src/commonMain/moko-resources/images/twd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/twd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/twd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/tzs@2x.png b/client/core/res/src/commonMain/moko-resources/images/tzs@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/tzs@2x.png rename to client/core/res/src/commonMain/moko-resources/images/tzs@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/uah@2x.png b/client/core/res/src/commonMain/moko-resources/images/uah@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/uah@2x.png rename to client/core/res/src/commonMain/moko-resources/images/uah@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/ugx@2x.png b/client/core/res/src/commonMain/moko-resources/images/ugx@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/ugx@2x.png rename to client/core/res/src/commonMain/moko-resources/images/ugx@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/unknown@2x.png b/client/core/res/src/commonMain/moko-resources/images/unknown@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/unknown@2x.png rename to client/core/res/src/commonMain/moko-resources/images/unknown@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/usd@2x.png b/client/core/res/src/commonMain/moko-resources/images/usd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/usd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/usd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/uyu@2x.png b/client/core/res/src/commonMain/moko-resources/images/uyu@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/uyu@2x.png rename to client/core/res/src/commonMain/moko-resources/images/uyu@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/uzs@2x.png b/client/core/res/src/commonMain/moko-resources/images/uzs@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/uzs@2x.png rename to client/core/res/src/commonMain/moko-resources/images/uzs@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/ves@2x.png b/client/core/res/src/commonMain/moko-resources/images/ves@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/ves@2x.png rename to client/core/res/src/commonMain/moko-resources/images/ves@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/vnd@2x.png b/client/core/res/src/commonMain/moko-resources/images/vnd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/vnd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/vnd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/vuv@2x.png b/client/core/res/src/commonMain/moko-resources/images/vuv@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/vuv@2x.png rename to client/core/res/src/commonMain/moko-resources/images/vuv@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/wst@2x.png b/client/core/res/src/commonMain/moko-resources/images/wst@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/wst@2x.png rename to client/core/res/src/commonMain/moko-resources/images/wst@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/xaf@2x.png b/client/core/res/src/commonMain/moko-resources/images/xaf@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/xaf@2x.png rename to client/core/res/src/commonMain/moko-resources/images/xaf@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/xcd@2x.png b/client/core/res/src/commonMain/moko-resources/images/xcd@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/xcd@2x.png rename to client/core/res/src/commonMain/moko-resources/images/xcd@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/xdr@2x.png b/client/core/res/src/commonMain/moko-resources/images/xdr@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/xdr@2x.png rename to client/core/res/src/commonMain/moko-resources/images/xdr@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/xof@2x.png b/client/core/res/src/commonMain/moko-resources/images/xof@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/xof@2x.png rename to client/core/res/src/commonMain/moko-resources/images/xof@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/xpf@2x.png b/client/core/res/src/commonMain/moko-resources/images/xpf@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/xpf@2x.png rename to client/core/res/src/commonMain/moko-resources/images/xpf@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/yer@2x.png b/client/core/res/src/commonMain/moko-resources/images/yer@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/yer@2x.png rename to client/core/res/src/commonMain/moko-resources/images/yer@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/zar@2x.png b/client/core/res/src/commonMain/moko-resources/images/zar@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/zar@2x.png rename to client/core/res/src/commonMain/moko-resources/images/zar@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/zmw@2x.png b/client/core/res/src/commonMain/moko-resources/images/zmw@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/zmw@2x.png rename to client/core/res/src/commonMain/moko-resources/images/zmw@2x.png diff --git a/client/core/res/src/commonMain/resources/MR/images/zwl@2x.png b/client/core/res/src/commonMain/moko-resources/images/zwl@2x.png similarity index 100% rename from client/core/res/src/commonMain/resources/MR/images/zwl@2x.png rename to client/core/res/src/commonMain/moko-resources/images/zwl@2x.png diff --git a/client/datasource/currency/client-datasource-currency.gradle.kts b/client/datasource/currency/client-datasource-currency.gradle.kts index 9fc370bcf5..ffbafb53c4 100644 --- a/client/datasource/currency/client-datasource-currency.gradle.kts +++ b/client/datasource/currency/client-datasource-currency.gradle.kts @@ -2,7 +2,7 @@ plugins { libs.plugins.apply { alias(kotlinMultiplatform) alias(androidLibrary) - alias(ksp) + alias(mokkery) } } @@ -29,21 +29,12 @@ kotlin { commonTest.dependencies { libs.common.apply { implementation(test) - implementation(mockative) implementation(coroutinesTest) } } } } -dependencies { - configurations - .filter { it.name.startsWith("ksp") && it.name.contains("Test") } - .forEach { - add(it.name, libs.processors.mockative) - } -} - android { ProjectSettings.apply { namespace = Modules.Client.DataSource.currency.packageName diff --git a/client/datasource/currency/src/commonTest/kotlin/com/oztechan/ccc/client/datasource/currency/CurrencyDataSourceTest.kt b/client/datasource/currency/src/commonTest/kotlin/com/oztechan/ccc/client/datasource/currency/CurrencyDataSourceTest.kt index 4ceae8f35b..11c381838e 100644 --- a/client/datasource/currency/src/commonTest/kotlin/com/oztechan/ccc/client/datasource/currency/CurrencyDataSourceTest.kt +++ b/client/datasource/currency/src/commonTest/kotlin/com/oztechan/ccc/client/datasource/currency/CurrencyDataSourceTest.kt @@ -8,12 +8,11 @@ import com.oztechan.ccc.common.core.database.sql.CurrencyQueries import com.squareup.sqldelight.Query import com.squareup.sqldelight.db.SqlCursor import com.squareup.sqldelight.db.SqlDriver -import io.mockative.Mock -import io.mockative.classOf -import io.mockative.configure -import io.mockative.every -import io.mockative.mock -import io.mockative.verify +import dev.mokkery.MockMode +import dev.mokkery.answering.returns +import dev.mokkery.every +import dev.mokkery.mock +import dev.mokkery.verify import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runTest import kotlin.random.Random @@ -27,15 +26,9 @@ internal class CurrencyDataSourceTest { CurrencyDataSourceImpl(currencyQueries, UnconfinedTestDispatcher()) } - @Mock - private val currencyQueries = - configure(mock(classOf())) { stubsUnitByDefault = true } - - @Mock - private val sqlDriver = mock(classOf()) - - @Mock - private val sqlCursor = configure(mock(classOf())) { stubsUnitByDefault = true } + private val currencyQueries = mock(MockMode.autoUnit) + private val sqlDriver = mock() + private val sqlCursor = mock(MockMode.autoUnit) private val currency = Currency("EUR", "", "", 0.0, 0L) private val query = Query(-1, mutableListOf(), sqlDriver, query = "") { @@ -63,7 +56,6 @@ internal class CurrencyDataSourceTest { } verify { currencyQueries.getCurrencies() } - .wasInvoked() } @Test @@ -76,7 +68,6 @@ internal class CurrencyDataSourceTest { } verify { currencyQueries.getActiveCurrencies() } - .wasInvoked() } @Test @@ -89,7 +80,6 @@ internal class CurrencyDataSourceTest { } verify { currencyQueries.getActiveCurrencies() } - .wasInvoked() } @Test @@ -102,7 +92,6 @@ internal class CurrencyDataSourceTest { } verify { currencyQueries.updateCurrencyStateByCode(mockState.toLong(), mockCode) } - .wasInvoked() } @Test @@ -114,7 +103,6 @@ internal class CurrencyDataSourceTest { } verify { currencyQueries.updateCurrencyStates(mockState.toLong()) } - .wasInvoked() } @Test @@ -127,6 +115,5 @@ internal class CurrencyDataSourceTest { } verify { currencyQueries.getCurrencyByCode(currency.code) } - .wasInvoked() } } diff --git a/client/datasource/watcher/client-datasource-watcher.gradle.kts b/client/datasource/watcher/client-datasource-watcher.gradle.kts index 17b7a6098e..32029090fb 100644 --- a/client/datasource/watcher/client-datasource-watcher.gradle.kts +++ b/client/datasource/watcher/client-datasource-watcher.gradle.kts @@ -2,7 +2,7 @@ plugins { libs.plugins.apply { alias(kotlinMultiplatform) alias(androidLibrary) - alias(ksp) + alias(mokkery) } } @@ -29,21 +29,12 @@ kotlin { commonTest.dependencies { libs.common.apply { implementation(test) - implementation(mockative) implementation(coroutinesTest) } } } } -dependencies { - configurations - .filter { it.name.startsWith("ksp") && it.name.contains("Test") } - .forEach { - add(it.name, libs.processors.mockative) - } -} - android { ProjectSettings.apply { namespace = Modules.Client.DataSource.watcher.packageName diff --git a/client/datasource/watcher/src/commonTest/kotlin/com/oztechan/ccc/client/datasource/watcher/WatcherDataSourceTest.kt b/client/datasource/watcher/src/commonTest/kotlin/com/oztechan/ccc/client/datasource/watcher/WatcherDataSourceTest.kt index ee9f3051c8..c8e88fce39 100644 --- a/client/datasource/watcher/src/commonTest/kotlin/com/oztechan/ccc/client/datasource/watcher/WatcherDataSourceTest.kt +++ b/client/datasource/watcher/src/commonTest/kotlin/com/oztechan/ccc/client/datasource/watcher/WatcherDataSourceTest.kt @@ -8,12 +8,11 @@ import com.oztechan.ccc.common.core.database.sql.WatcherQueries import com.squareup.sqldelight.Query import com.squareup.sqldelight.db.SqlCursor import com.squareup.sqldelight.db.SqlDriver -import io.mockative.Mock -import io.mockative.classOf -import io.mockative.configure -import io.mockative.every -import io.mockative.mock -import io.mockative.verify +import dev.mokkery.MockMode +import dev.mokkery.answering.returns +import dev.mokkery.every +import dev.mokkery.mock +import dev.mokkery.verify import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runTest import kotlin.random.Random @@ -27,15 +26,9 @@ internal class WatcherDataSourceTest { WatcherDataSourceImpl(watcherQueries, UnconfinedTestDispatcher()) } - @Mock - private val watcherQueries = - configure(mock(classOf())) { stubsUnitByDefault = true } - - @Mock - private val sqlDriver = mock(classOf()) - - @Mock - private val sqlCursor = configure(mock(classOf())) { stubsUnitByDefault = true } + private val watcherQueries = mock(MockMode.autoUnit) + private val sqlDriver = mock() + private val sqlCursor = mock(MockMode.autoUnit) private val base = "EUR" private val target = "USD" @@ -64,7 +57,6 @@ internal class WatcherDataSourceTest { subject.getWatchersFlow() verify { watcherQueries.getWatchers() } - .wasInvoked() } @Test @@ -72,7 +64,6 @@ internal class WatcherDataSourceTest { subject.addWatcher(base, target) verify { watcherQueries.addWatcher(base, target) } - .wasInvoked() } @Test @@ -83,7 +74,6 @@ internal class WatcherDataSourceTest { subject.getWatchers() verify { watcherQueries.getWatchers() } - .wasInvoked() } @Test @@ -91,7 +81,6 @@ internal class WatcherDataSourceTest { subject.deleteWatcher(id) verify { watcherQueries.deleteWatcher(id) } - .wasInvoked() } @Test @@ -99,7 +88,6 @@ internal class WatcherDataSourceTest { subject.updateWatcherBaseById(base, id) verify { watcherQueries.updateWatcherBaseById(base, id) } - .wasInvoked() } @Test @@ -107,7 +95,6 @@ internal class WatcherDataSourceTest { subject.updateWatcherTargetById(target, id) verify { watcherQueries.updateWatcherTargetById(target, id) } - .wasInvoked() } @Test @@ -116,7 +103,6 @@ internal class WatcherDataSourceTest { subject.updateWatcherRelationById(relation, id) verify { watcherQueries.updateWatcherRelationById(relation.toLong(), id) } - .wasInvoked() } @Test @@ -126,6 +112,5 @@ internal class WatcherDataSourceTest { subject.updateWatcherRateById(rate, id) verify { watcherQueries.updateWatcherRateById(rate, id) } - .wasInvoked() } } diff --git a/client/repository/adcontrol/client-repository-adcontrol.gradle.kts b/client/repository/adcontrol/client-repository-adcontrol.gradle.kts index 3cddcc191c..09205f8cb4 100644 --- a/client/repository/adcontrol/client-repository-adcontrol.gradle.kts +++ b/client/repository/adcontrol/client-repository-adcontrol.gradle.kts @@ -2,7 +2,7 @@ plugins { libs.plugins.apply { alias(androidLibrary) alias(kotlinMultiplatform) - alias(ksp) + alias(mokkery) } } @@ -21,22 +21,11 @@ kotlin { implementation(project(Modules.Client.Core.shared)) } commonTest.dependencies { - libs.common.apply { - implementation(test) - implementation(mockative) - } + implementation(libs.common.test) } } } -dependencies { - configurations - .filter { it.name.startsWith("ksp") && it.name.contains("Test") } - .forEach { - add(it.name, libs.processors.mockative) - } -} - android { ProjectSettings.apply { namespace = Modules.Client.Repository.adControl.packageName diff --git a/client/repository/adcontrol/src/commonTest/kotlin/com/oztechan/ccc/client/repository/adcontrol/AdControlRepositoryTest.kt b/client/repository/adcontrol/src/commonTest/kotlin/com/oztechan/ccc/client/repository/adcontrol/AdControlRepositoryTest.kt index ed906268aa..4a412ed9e8 100644 --- a/client/repository/adcontrol/src/commonTest/kotlin/com/oztechan/ccc/client/repository/adcontrol/AdControlRepositoryTest.kt +++ b/client/repository/adcontrol/src/commonTest/kotlin/com/oztechan/ccc/client/repository/adcontrol/AdControlRepositoryTest.kt @@ -4,11 +4,11 @@ import com.oztechan.ccc.client.configservice.ad.AdConfigService import com.oztechan.ccc.client.configservice.ad.model.AdConfig import com.oztechan.ccc.client.core.shared.util.nowAsLong import com.oztechan.ccc.client.storage.app.AppStorage -import io.mockative.Mock -import io.mockative.classOf -import io.mockative.every -import io.mockative.mock -import io.mockative.verify +import dev.mokkery.answering.returns +import dev.mokkery.every +import dev.mokkery.mock +import dev.mokkery.verify +import dev.mokkery.verify.VerifyMode import kotlin.random.Random import kotlin.test.BeforeTest import kotlin.test.Test @@ -22,11 +22,9 @@ internal class AdControlRepositoryTest { AdControlRepositoryImpl(appStorage, adConfigService) } - @Mock - private val adConfigService = mock(classOf()) + private val adConfigService = mock() - @Mock - private val appStorage = mock(classOf()) + private val appStorage = mock() private var mockedSessionCount = Random.nextInt() @@ -50,16 +48,12 @@ internal class AdControlRepositoryTest { assertFalse { subject.shouldShowBannerAd() } verify { appStorage.firstRun } - .wasInvoked() - verify { appStorage.premiumEndDate } - .wasNotInvoked() + verify(VerifyMode.not) { appStorage.premiumEndDate } - verify { appStorage.sessionCount } - .wasNotInvoked() + verify(VerifyMode.not) { appStorage.sessionCount } - verify { adConfigService.config } - .wasNotInvoked() + verify(VerifyMode.not) { adConfigService.config } } @Test @@ -76,16 +70,12 @@ internal class AdControlRepositoryTest { assertFalse { subject.shouldShowBannerAd() } verify { appStorage.firstRun } - .wasInvoked() verify { appStorage.premiumEndDate } - .wasInvoked() - verify { appStorage.sessionCount } - .wasNotInvoked() + verify(VerifyMode.not) { appStorage.sessionCount } - verify { adConfigService.config } - .wasNotInvoked() + verify(VerifyMode.not) { adConfigService.config } } @Test @@ -102,16 +92,12 @@ internal class AdControlRepositoryTest { assertFalse { subject.shouldShowBannerAd() } verify { appStorage.firstRun } - .wasInvoked() - verify { appStorage.premiumEndDate } - .wasNotInvoked() + verify(VerifyMode.not) { appStorage.premiumEndDate } - verify { appStorage.sessionCount } - .wasNotInvoked() + verify(VerifyMode.not) { appStorage.sessionCount } - verify { adConfigService.config } - .wasNotInvoked() + verify(VerifyMode.not) { adConfigService.config } } @Test @@ -128,16 +114,12 @@ internal class AdControlRepositoryTest { assertFalse { subject.shouldShowBannerAd() } verify { appStorage.firstRun } - .wasInvoked() - verify { appStorage.premiumEndDate } - .wasNotInvoked() + verify(VerifyMode.not) { appStorage.premiumEndDate } - verify { appStorage.sessionCount } - .wasNotInvoked() + verify(VerifyMode.not) { appStorage.sessionCount } - verify { adConfigService.config } - .wasNotInvoked() + verify(VerifyMode.not) { adConfigService.config } } @Test @@ -154,16 +136,12 @@ internal class AdControlRepositoryTest { assertFalse { subject.shouldShowBannerAd() } verify { appStorage.firstRun } - .wasInvoked() - verify { appStorage.premiumEndDate } - .wasNotInvoked() + verify(VerifyMode.not) { appStorage.premiumEndDate } - verify { appStorage.sessionCount } - .wasNotInvoked() + verify(VerifyMode.not) { appStorage.sessionCount } - verify { adConfigService.config } - .wasNotInvoked() + verify(VerifyMode.not) { adConfigService.config } } @Test @@ -180,16 +158,12 @@ internal class AdControlRepositoryTest { assertFalse { subject.shouldShowBannerAd() } verify { appStorage.firstRun } - .wasInvoked() verify { appStorage.premiumEndDate } - .wasInvoked() - verify { appStorage.sessionCount } - .wasNotInvoked() + verify(VerifyMode.not) { appStorage.sessionCount } - verify { adConfigService.config } - .wasNotInvoked() + verify(VerifyMode.not) { adConfigService.config } } @Test @@ -206,16 +180,12 @@ internal class AdControlRepositoryTest { assertFalse { subject.shouldShowBannerAd() } verify { appStorage.firstRun } - .wasInvoked() verify { appStorage.premiumEndDate } - .wasInvoked() verify { appStorage.sessionCount } - .wasInvoked() verify { adConfigService.config } - .wasInvoked() } @Test @@ -232,16 +202,12 @@ internal class AdControlRepositoryTest { assertTrue { subject.shouldShowBannerAd() } verify { appStorage.firstRun } - .wasInvoked() verify { appStorage.premiumEndDate } - .wasInvoked() verify { appStorage.sessionCount } - .wasInvoked() verify { adConfigService.config } - .wasInvoked() } @Test @@ -255,13 +221,10 @@ internal class AdControlRepositoryTest { assertFalse { subject.shouldShowInterstitialAd() } verify { appStorage.premiumEndDate } - .wasInvoked() - verify { adConfigService.config.interstitialAdSessionCount } - .wasNotInvoked() + verify(VerifyMode.not) { adConfigService.config } - verify { appStorage.sessionCount } - .wasNotInvoked() + verify(VerifyMode.not) { appStorage.sessionCount } } @Test @@ -275,13 +238,10 @@ internal class AdControlRepositoryTest { assertTrue { subject.shouldShowInterstitialAd() } verify { appStorage.premiumEndDate } - .wasInvoked() verify { adConfigService.config } - .wasInvoked() verify { appStorage.sessionCount } - .wasInvoked() } @Test @@ -295,13 +255,10 @@ internal class AdControlRepositoryTest { assertFalse { subject.shouldShowInterstitialAd() } verify { appStorage.premiumEndDate } - .wasInvoked() - verify { adConfigService.config } - .wasNotInvoked() + verify(VerifyMode.not) { adConfigService.config } - verify { appStorage.sessionCount } - .wasNotInvoked() + verify(VerifyMode.not) { appStorage.sessionCount } } @Test @@ -315,12 +272,9 @@ internal class AdControlRepositoryTest { assertFalse { subject.shouldShowInterstitialAd() } verify { appStorage.premiumEndDate } - .wasInvoked() verify { adConfigService.config } - .wasInvoked() verify { appStorage.sessionCount } - .wasInvoked() } } diff --git a/client/repository/appconfig/client-repository-appconfig.gradle.kts b/client/repository/appconfig/client-repository-appconfig.gradle.kts index b4f49c5b0a..66b153122a 100644 --- a/client/repository/appconfig/client-repository-appconfig.gradle.kts +++ b/client/repository/appconfig/client-repository-appconfig.gradle.kts @@ -7,7 +7,7 @@ plugins { alias(androidLibrary) alias(kotlinMultiplatform) id(buildKonfig.get().pluginId) - alias(ksp) + alias(mokkery) } } @@ -31,22 +31,11 @@ kotlin { implementation(Submodules.scopemob) } commonTest.dependencies { - libs.common.apply { - implementation(test) - implementation(mockative) - } + implementation(libs.common.test) } } } -dependencies { - configurations - .filter { it.name.startsWith("ksp") && it.name.contains("Test") } - .forEach { - add(it.name, libs.processors.mockative) - } -} - android { ProjectSettings.apply { namespace = Modules.Client.Repository.appConfig.packageName diff --git a/client/repository/appconfig/src/commonTest/kotlin/com/oztechan/ccc/client/repository/appconfig/AppConfigRepositoryTest.kt b/client/repository/appconfig/src/commonTest/kotlin/com/oztechan/ccc/client/repository/appconfig/AppConfigRepositoryTest.kt index b3b39abc03..a60e920cfa 100644 --- a/client/repository/appconfig/src/commonTest/kotlin/com/oztechan/ccc/client/repository/appconfig/AppConfigRepositoryTest.kt +++ b/client/repository/appconfig/src/commonTest/kotlin/com/oztechan/ccc/client/repository/appconfig/AppConfigRepositoryTest.kt @@ -6,11 +6,10 @@ import com.oztechan.ccc.client.configservice.update.UpdateConfigService import com.oztechan.ccc.client.configservice.update.model.UpdateConfig import com.oztechan.ccc.client.core.shared.Device import com.oztechan.ccc.client.storage.app.AppStorage -import io.mockative.Mock -import io.mockative.classOf -import io.mockative.every -import io.mockative.mock -import io.mockative.verify +import dev.mokkery.answering.returns +import dev.mokkery.every +import dev.mokkery.mock +import dev.mokkery.verify import kotlin.random.Random import kotlin.test.Test import kotlin.test.assertEquals @@ -25,14 +24,11 @@ internal class AppConfigRepositoryTest { AppConfigRepositoryImpl(updateConfigService, reviewConfigService, appStorage, device) } - @Mock - private val updateConfigService = mock(classOf()) + private val updateConfigService = mock() - @Mock - private val reviewConfigService = mock(classOf()) + private val reviewConfigService = mock() - @Mock - private val appStorage = mock(classOf()) + private val appStorage = mock() private val device = Device.IOS @@ -57,7 +53,6 @@ internal class AppConfigRepositoryTest { } verify { updateConfigService.config } - .wasInvoked() } @Test @@ -71,7 +66,6 @@ internal class AppConfigRepositoryTest { } verify { updateConfigService.config } - .wasInvoked() } @Test @@ -82,7 +76,6 @@ internal class AppConfigRepositoryTest { assertNull(subject.checkAppUpdate(false)) verify { updateConfigService.config } - .wasInvoked() } @Test @@ -93,7 +86,6 @@ internal class AppConfigRepositoryTest { assertNull(subject.checkAppUpdate(false)) verify { updateConfigService.config } - .wasInvoked() } @Test @@ -104,7 +96,6 @@ internal class AppConfigRepositoryTest { assertNull(subject.checkAppUpdate(true)) verify { updateConfigService.config } - .wasInvoked() } @Test @@ -120,10 +111,8 @@ internal class AppConfigRepositoryTest { assertTrue { subject.shouldShowAppReview() } verify { appStorage.sessionCount } - .wasInvoked() verify { reviewConfigService.config } - .wasInvoked() } @Test @@ -139,10 +128,8 @@ internal class AppConfigRepositoryTest { assertFalse { subject.shouldShowAppReview() } verify { appStorage.sessionCount } - .wasInvoked() verify { reviewConfigService.config } - .wasInvoked() } @Test @@ -158,10 +145,8 @@ internal class AppConfigRepositoryTest { assertFalse { subject.shouldShowAppReview() } verify { appStorage.sessionCount } - .wasInvoked() verify { reviewConfigService.config } - .wasInvoked() } @Test diff --git a/client/service/backend/client-service-backend.gradle.kts b/client/service/backend/client-service-backend.gradle.kts index 8571d30ab9..1acfb4b4a4 100644 --- a/client/service/backend/client-service-backend.gradle.kts +++ b/client/service/backend/client-service-backend.gradle.kts @@ -2,7 +2,7 @@ plugins { libs.plugins.apply { alias(kotlinMultiplatform) alias(androidLibrary) - alias(ksp) + alias(mokkery) } } @@ -29,21 +29,12 @@ kotlin { commonTest.dependencies { libs.common.apply { implementation(test) - implementation(mockative) implementation(coroutinesTest) } } } } -dependencies { - configurations - .filter { it.name.startsWith("ksp") && it.name.contains("Test") } - .forEach { - add(it.name, libs.processors.mockative) - } -} - android { ProjectSettings.apply { namespace = Modules.Client.Service.backend.packageName diff --git a/client/service/backend/src/commonTest/kotlin/com/oztechan/ccc/client/service/backend/BackendApiServiceTest.kt b/client/service/backend/src/commonTest/kotlin/com/oztechan/ccc/client/service/backend/BackendApiServiceTest.kt index 78401b9fc3..dc6ad7e0ae 100644 --- a/client/service/backend/src/commonTest/kotlin/com/oztechan/ccc/client/service/backend/BackendApiServiceTest.kt +++ b/client/service/backend/src/commonTest/kotlin/com/oztechan/ccc/client/service/backend/BackendApiServiceTest.kt @@ -6,11 +6,12 @@ import com.oztechan.ccc.common.core.network.api.backend.BackendApi import com.oztechan.ccc.common.core.network.mapper.toConversionModel import com.oztechan.ccc.common.core.network.model.Conversion import com.oztechan.ccc.common.core.network.model.ExchangeRate -import io.mockative.Mock -import io.mockative.classOf -import io.mockative.coEvery -import io.mockative.coVerify -import io.mockative.mock +import dev.mokkery.answering.returns +import dev.mokkery.answering.throws +import dev.mokkery.everySuspend +import dev.mokkery.mock +import dev.mokkery.verify.VerifyMode +import dev.mokkery.verifySuspend import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runTest import kotlin.test.BeforeTest @@ -27,8 +28,7 @@ internal class BackendApiServiceTest { BackendApiServiceImpl(backendApi, UnconfinedTestDispatcher()) } - @Mock - private val backendApi = mock(classOf()) + private val backendApi = mock() private val base = "EUR" private val exchangeRate = ExchangeRate(base, "12.21.2121", Conversion(base)) @@ -46,13 +46,12 @@ internal class BackendApiServiceTest { assertTrue { it.isFailure } } - coVerify { backendApi.getExchangeRate("") } - .wasNotInvoked() + verifySuspend(VerifyMode.not) { backendApi.getExchangeRate("") } } @Test fun `getConversion error`() = runTest { - coEvery { backendApi.getExchangeRate(base) } + everySuspend { backendApi.getExchangeRate(base) } .throws(throwable) runCatching { subject.getConversion(base) }.let { @@ -64,13 +63,12 @@ internal class BackendApiServiceTest { assertEquals(throwable.message, it.exceptionOrNull()!!.cause!!.message) } - coVerify { backendApi.getExchangeRate(base) } - .wasInvoked() + verifySuspend { backendApi.getExchangeRate(base) } } @Test fun `getConversion success`() = runTest { - coEvery { backendApi.getExchangeRate(base) } + everySuspend { backendApi.getExchangeRate(base) } .returns(exchangeRate) runCatching { subject.getConversion(base) }.let { @@ -80,7 +78,6 @@ internal class BackendApiServiceTest { assertEquals(exchangeRate.toConversionModel(), it.getOrNull()) } - coVerify { backendApi.getExchangeRate(base) } - .wasInvoked() + verifySuspend { backendApi.getExchangeRate(base) } } } diff --git a/client/storage/app/client-storage-app.gradle.kts b/client/storage/app/client-storage-app.gradle.kts index 5b4d634d95..968206ccff 100644 --- a/client/storage/app/client-storage-app.gradle.kts +++ b/client/storage/app/client-storage-app.gradle.kts @@ -2,7 +2,7 @@ plugins { libs.plugins.apply { alias(kotlinMultiplatform) alias(androidLibrary) - alias(ksp) + alias(mokkery) } } kotlin { @@ -18,22 +18,11 @@ kotlin { implementation(project(Modules.Client.Core.persistence)) } commonTest.dependencies { - libs.common.apply { - implementation(test) - implementation(mockative) - } + implementation(libs.common.test) } } } -dependencies { - configurations - .filter { it.name.startsWith("ksp") && it.name.contains("Test") } - .forEach { - add(it.name, libs.processors.mockative) - } -} - android { ProjectSettings.apply { namespace = Modules.Client.Storage.app.packageName diff --git a/client/storage/app/src/commonTest/kotlin/com/oztechan/ccc/client/storage/app/AppStorageTest.kt b/client/storage/app/src/commonTest/kotlin/com/oztechan/ccc/client/storage/app/AppStorageTest.kt index 724b462ba0..e1d5b523f9 100644 --- a/client/storage/app/src/commonTest/kotlin/com/oztechan/ccc/client/storage/app/AppStorageTest.kt +++ b/client/storage/app/src/commonTest/kotlin/com/oztechan/ccc/client/storage/app/AppStorageTest.kt @@ -9,12 +9,11 @@ import com.oztechan.ccc.client.storage.app.AppStorageImpl.Companion.KEY_APP_THEM import com.oztechan.ccc.client.storage.app.AppStorageImpl.Companion.KEY_FIRST_RUN import com.oztechan.ccc.client.storage.app.AppStorageImpl.Companion.KEY_PREMIUM_END_DATE import com.oztechan.ccc.client.storage.app.AppStorageImpl.Companion.KEY_SESSION_COUNT -import io.mockative.Mock -import io.mockative.classOf -import io.mockative.configure -import io.mockative.every -import io.mockative.mock -import io.mockative.verify +import dev.mokkery.MockMode +import dev.mokkery.answering.returns +import dev.mokkery.every +import dev.mokkery.mock +import dev.mokkery.verify import kotlin.random.Random import kotlin.test.Test import kotlin.test.assertEquals @@ -25,8 +24,7 @@ internal class AppStorageTest { AppStorageImpl(persistence) } - @Mock - private val persistence = configure(mock(classOf())) { stubsUnitByDefault = true } + private val persistence = mock(MockMode.autoUnit) // defaults @Test @@ -37,7 +35,6 @@ internal class AppStorageTest { assertEquals(DEFAULT_FIRST_RUN, subject.firstRun) verify { persistence.getValue(KEY_FIRST_RUN, DEFAULT_FIRST_RUN) } - .wasInvoked() } @Test @@ -48,7 +45,6 @@ internal class AppStorageTest { assertEquals(DEFAULT_APP_THEME, subject.appTheme) verify { persistence.getValue(KEY_APP_THEME, DEFAULT_APP_THEME) } - .wasInvoked() } @Test @@ -59,7 +55,6 @@ internal class AppStorageTest { assertEquals(DEFAULT_PREMIUM_END_DATE, subject.premiumEndDate) verify { persistence.getValue(KEY_PREMIUM_END_DATE, DEFAULT_PREMIUM_END_DATE) } - .wasInvoked() } @Test @@ -70,7 +65,6 @@ internal class AppStorageTest { assertEquals(DEFAULT_SESSION_COUNT, subject.sessionCount) verify { persistence.getValue(KEY_SESSION_COUNT, DEFAULT_SESSION_COUNT) } - .wasInvoked() } // setters @@ -80,7 +74,6 @@ internal class AppStorageTest { subject.firstRun = mockedValue verify { persistence.setValue(KEY_FIRST_RUN, mockedValue) } - .wasInvoked() } @Test @@ -89,7 +82,6 @@ internal class AppStorageTest { subject.appTheme = mockValue verify { persistence.setValue(KEY_APP_THEME, mockValue) } - .wasInvoked() } @Test @@ -98,7 +90,6 @@ internal class AppStorageTest { subject.premiumEndDate = mockValue verify { persistence.setValue(KEY_PREMIUM_END_DATE, mockValue) } - .wasInvoked() } @Test @@ -107,6 +98,5 @@ internal class AppStorageTest { subject.sessionCount = mockValue verify { persistence.setValue(KEY_SESSION_COUNT, mockValue) } - .wasInvoked() } } diff --git a/client/storage/calculation/client-storage-calculation.gradle.kts b/client/storage/calculation/client-storage-calculation.gradle.kts index 024143a5fb..2cf9e38ecd 100644 --- a/client/storage/calculation/client-storage-calculation.gradle.kts +++ b/client/storage/calculation/client-storage-calculation.gradle.kts @@ -2,7 +2,7 @@ plugins { libs.plugins.apply { alias(kotlinMultiplatform) alias(androidLibrary) - alias(ksp) + alias(mokkery) } } kotlin { @@ -18,22 +18,11 @@ kotlin { implementation(project(Modules.Client.Core.persistence)) } commonTest.dependencies { - libs.common.apply { - implementation(test) - implementation(mockative) - } + implementation(libs.common.test) } } } -dependencies { - configurations - .filter { it.name.startsWith("ksp") && it.name.contains("Test") } - .forEach { - add(it.name, libs.processors.mockative) - } -} - android { ProjectSettings.apply { namespace = Modules.Client.Storage.calculation.packageName diff --git a/client/storage/calculation/src/commonTest/kotlin/com/oztechan/ccc/client/storage/calculation/CalculationStorageTest.kt b/client/storage/calculation/src/commonTest/kotlin/com/oztechan/ccc/client/storage/calculation/CalculationStorageTest.kt index d37a563dde..03dfa01470 100644 --- a/client/storage/calculation/src/commonTest/kotlin/com/oztechan/ccc/client/storage/calculation/CalculationStorageTest.kt +++ b/client/storage/calculation/src/commonTest/kotlin/com/oztechan/ccc/client/storage/calculation/CalculationStorageTest.kt @@ -7,12 +7,11 @@ import com.oztechan.ccc.client.storage.calculation.CalculationStorageImpl.Compan import com.oztechan.ccc.client.storage.calculation.CalculationStorageImpl.Companion.KEY_CURRENT_BASE import com.oztechan.ccc.client.storage.calculation.CalculationStorageImpl.Companion.KEY_LAST_INPUT import com.oztechan.ccc.client.storage.calculation.CalculationStorageImpl.Companion.KEY_PRECISION -import io.mockative.Mock -import io.mockative.classOf -import io.mockative.configure -import io.mockative.every -import io.mockative.mock -import io.mockative.verify +import dev.mokkery.MockMode +import dev.mokkery.answering.returns +import dev.mokkery.every +import dev.mokkery.mock +import dev.mokkery.verify import kotlin.random.Random import kotlin.test.Test import kotlin.test.assertEquals @@ -22,8 +21,7 @@ internal class CalculationStorageTest { CalculationStorageImpl(persistence) } - @Mock - private val persistence = configure(mock(classOf())) { stubsUnitByDefault = true } + private val persistence = mock(MockMode.autoUnit) // defaults @Test @@ -34,7 +32,6 @@ internal class CalculationStorageTest { assertEquals(DEFAULT_CURRENT_BASE, subject.currentBase) verify { persistence.getValue(KEY_CURRENT_BASE, DEFAULT_CURRENT_BASE) } - .wasInvoked() } @Test @@ -45,7 +42,6 @@ internal class CalculationStorageTest { assertEquals(DEFAULT_PRECISION, subject.precision) verify { persistence.getValue(KEY_PRECISION, DEFAULT_PRECISION) } - .wasInvoked() } @Test @@ -56,7 +52,6 @@ internal class CalculationStorageTest { assertEquals(DEFAULT_LAST_INPUT, subject.lastInput) verify { persistence.getValue(KEY_LAST_INPUT, DEFAULT_LAST_INPUT) } - .wasInvoked() } // setters @@ -66,7 +61,6 @@ internal class CalculationStorageTest { subject.currentBase = mockValue verify { persistence.setValue(KEY_CURRENT_BASE, mockValue) } - .wasInvoked() } @Test @@ -75,7 +69,6 @@ internal class CalculationStorageTest { subject.precision = mockValue verify { persistence.setValue(KEY_PRECISION, mockValue) } - .wasInvoked() } @Test @@ -84,6 +77,5 @@ internal class CalculationStorageTest { subject.lastInput = mockValue verify { persistence.setValue(KEY_LAST_INPUT, mockValue) } - .wasInvoked() } } diff --git a/client/viewmodel/calculator/client-viewmodel-calculator.gradle.kts b/client/viewmodel/calculator/client-viewmodel-calculator.gradle.kts index abb2431b51..60da179750 100644 --- a/client/viewmodel/calculator/client-viewmodel-calculator.gradle.kts +++ b/client/viewmodel/calculator/client-viewmodel-calculator.gradle.kts @@ -2,7 +2,7 @@ plugins { libs.plugins.apply { alias(kotlinMultiplatform) alias(androidLibrary) - alias(ksp) + alias(mokkery) } } kotlin { @@ -51,7 +51,6 @@ kotlin { commonTest.dependencies { libs.common.apply { implementation(test) - implementation(mockative) implementation(coroutinesTest) } } @@ -61,14 +60,6 @@ kotlin { } } -dependencies { - configurations - .filter { it.name.startsWith("ksp") && it.name.contains("Test") } - .forEach { - add(it.name, libs.processors.mockative) - } -} - android { ProjectSettings.apply { namespace = Modules.Client.ViewModel.calculator.packageName diff --git a/client/viewmodel/calculator/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/calculator/CalculatorViewModelTest.kt b/client/viewmodel/calculator/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/calculator/CalculatorViewModelTest.kt index 9f27b93a25..5e20b7042e 100644 --- a/client/viewmodel/calculator/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/calculator/CalculatorViewModelTest.kt +++ b/client/viewmodel/calculator/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/calculator/CalculatorViewModelTest.kt @@ -25,14 +25,14 @@ import com.oztechan.ccc.client.viewmodel.calculator.util.getConversionStringFrom import com.oztechan.ccc.common.core.model.Conversion import com.oztechan.ccc.common.core.model.Currency import com.oztechan.ccc.common.datasource.conversion.ConversionDataSource -import io.mockative.Mock -import io.mockative.classOf -import io.mockative.coEvery -import io.mockative.coVerify -import io.mockative.configure -import io.mockative.every -import io.mockative.mock -import io.mockative.verify +import dev.mokkery.MockMode +import dev.mokkery.answering.returns +import dev.mokkery.answering.throws +import dev.mokkery.every +import dev.mokkery.everySuspend +import dev.mokkery.mock +import dev.mokkery.verify +import dev.mokkery.verifySuspend import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.flowOf @@ -61,26 +61,17 @@ internal class CalculatorViewModelTest { ) } - @Mock - private val calculationStorage = - configure(mock(classOf())) { stubsUnitByDefault = true } + private val calculationStorage = mock(MockMode.autoUnit) - @Mock - private val backendApiService = mock(classOf()) + private val backendApiService = mock() - @Mock - private val currencyDataSource = mock(classOf()) + private val currencyDataSource = mock() - @Mock - private val conversionDataSource = - configure(mock(classOf())) { stubsUnitByDefault = true } + private val conversionDataSource = mock(MockMode.autoUnit) - @Mock - private val adControlRepository = mock(classOf()) + private val adControlRepository = mock() - @Mock - private val analyticsManager = - configure(mock(classOf())) { stubsUnitByDefault = true } + private val analyticsManager = mock(MockMode.autoUnit) private val currency1 = Currency("USD", "Dollar", "$", "12345.678", true) private val currency2 = Currency("EUR", "Dollar", "$", "12345.678", true) @@ -111,16 +102,16 @@ internal class CalculatorViewModelTest { .returns(shouldShowAds) runTest { - coEvery { currencyDataSource.getActiveCurrencies() } + everySuspend { currencyDataSource.getActiveCurrencies() } .returns(currencyList) - coEvery { conversionDataSource.getConversionByBase(currency1.code) } + everySuspend { conversionDataSource.getConversionByBase(currency1.code) } .returns(conversion) - coEvery { backendApiService.getConversion(currency1.code) } + everySuspend { backendApiService.getConversion(currency1.code) } .returns(conversion) - coEvery { currencyDataSource.getCurrencyByCode(currency1.code) } + everySuspend { currencyDataSource.getCurrencyByCode(currency1.code) } .returns(currency1) } } @@ -128,8 +119,7 @@ internal class CalculatorViewModelTest { @Test fun `conversion should be fetched on init`() = runTest { viewModel - coVerify { backendApiService.getConversion(currency1.code) } - .wasInvoked() + verifySuspend { backendApiService.getConversion(currency1.code) } assertNotNull(viewModel.data.conversion) } @@ -150,7 +140,6 @@ internal class CalculatorViewModelTest { } verify { adControlRepository.shouldShowBannerAd() } - .wasInvoked() } @Test @@ -180,7 +169,7 @@ internal class CalculatorViewModelTest { @Test fun `when api fails and there is conversion in db then conversion rates are calculated`() = runTest { - coEvery { backendApiService.getConversion(currency1.code) } + everySuspend { backendApiService.getConversion(currency1.code) } .throws(Exception()) viewModel.state.onSubscription { @@ -199,16 +188,15 @@ internal class CalculatorViewModelTest { assertEquals(result, it.currencyList) } - coVerify { conversionDataSource.getConversionByBase(currency1.code) } - .wasInvoked() + verifySuspend { conversionDataSource.getConversionByBase(currency1.code) } } @Test fun `when api fails and there is no conversion in db then error state displayed`() = runTest { - coEvery { backendApiService.getConversion(currency1.code) } + everySuspend { backendApiService.getConversion(currency1.code) } .throws(Exception()) - coEvery { conversionDataSource.getConversionByBase(currency1.code) } + everySuspend { conversionDataSource.getConversionByBase(currency1.code) } .returns(null) viewModel.effect.onSubscription { @@ -223,17 +211,16 @@ internal class CalculatorViewModelTest { } } - coVerify { conversionDataSource.getConversionByBase(currency1.code) } - .wasInvoked() + verifySuspend { conversionDataSource.getConversionByBase(currency1.code) } } @Test fun `when api fails and there is no offline and no enough currency few currency effect emitted`() = runTest { - coEvery { backendApiService.getConversion(currency1.code) } + everySuspend { backendApiService.getConversion(currency1.code) } .throws(Exception()) - coEvery { conversionDataSource.getConversionByBase(currency1.code) } + everySuspend { conversionDataSource.getConversionByBase(currency1.code) } .returns(null) every { currencyDataSource.getActiveCurrenciesFlow() } @@ -251,8 +238,7 @@ internal class CalculatorViewModelTest { } } - coVerify { conversionDataSource.getConversionByBase(currency1.code) } - .wasInvoked() + verifySuspend { conversionDataSource.getConversionByBase(currency1.code) } } @Test @@ -314,7 +300,7 @@ internal class CalculatorViewModelTest { analyticsManager.setUserProperty( UserProperty.CurrencyCount(currencyList.count().toString()) ) - }.wasInvoked() + } } // Event @@ -385,7 +371,6 @@ internal class CalculatorViewModelTest { assertEquals(currency1.code, it.code) verify { analyticsManager.trackEvent(Event.ShowConversion(Param.Base(currency1.code))) } - .wasInvoked() } } @@ -400,7 +385,6 @@ internal class CalculatorViewModelTest { ) verify { analyticsManager.trackEvent(Event.CopyClipboard) } - .wasInvoked() } } @@ -414,7 +398,6 @@ internal class CalculatorViewModelTest { assertEquals(CalculatorEffect.CopyToClipboard(output), it) verify { analyticsManager.trackEvent(Event.CopyClipboard) } - .wasInvoked() } } @@ -439,7 +422,6 @@ internal class CalculatorViewModelTest { assertEquals(text, it.input) verify { analyticsManager.trackEvent(Event.PasteFromClipboard) } - .wasInvoked() } viewModel.state.onSubscription { @@ -449,7 +431,6 @@ internal class CalculatorViewModelTest { assertEquals(text2.toSupportedCharacters(), it.input) verify { analyticsManager.trackEvent(Event.PasteFromClipboard) } - .wasInvoked() } } @@ -505,7 +486,7 @@ internal class CalculatorViewModelTest { every { calculationStorage.currentBase } .returns(currency1.code) - coEvery { backendApiService.getConversion(currency1.code) } + everySuspend { backendApiService.getConversion(currency1.code) } .returns(conversion) viewModel.state.onSubscription { @@ -517,10 +498,7 @@ internal class CalculatorViewModelTest { assertEquals(currency1.code, it.base) verify { analyticsManager.trackEvent(Event.BaseChange(Param.Base(currency1.code))) } - .wasInvoked() - verify { analyticsManager.setUserProperty(UserProperty.BaseCurrency(currency1.code)) } - .wasInvoked() } } } diff --git a/client/viewmodel/currencies/client-viewmodel-currencies.gradle.kts b/client/viewmodel/currencies/client-viewmodel-currencies.gradle.kts index 38265a33ec..3367b9cc6a 100644 --- a/client/viewmodel/currencies/client-viewmodel-currencies.gradle.kts +++ b/client/viewmodel/currencies/client-viewmodel-currencies.gradle.kts @@ -2,7 +2,7 @@ plugins { libs.plugins.apply { alias(kotlinMultiplatform) alias(androidLibrary) - alias(ksp) + alias(mokkery) } } kotlin { @@ -45,7 +45,6 @@ kotlin { commonTest.dependencies { libs.common.apply { implementation(test) - implementation(mockative) implementation(coroutinesTest) } } @@ -55,14 +54,6 @@ kotlin { } } -dependencies { - configurations - .filter { it.name.startsWith("ksp") && it.name.contains("Test") } - .forEach { - add(it.name, libs.processors.mockative) - } -} - android { ProjectSettings.apply { namespace = Modules.Client.ViewModel.currencies.packageName diff --git a/client/viewmodel/currencies/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/currencies/CurrenciesViewModelTest.kt b/client/viewmodel/currencies/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/currencies/CurrenciesViewModelTest.kt index bc936f029b..84f42b6260 100644 --- a/client/viewmodel/currencies/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/currencies/CurrenciesViewModelTest.kt +++ b/client/viewmodel/currencies/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/currencies/CurrenciesViewModelTest.kt @@ -12,13 +12,13 @@ import com.oztechan.ccc.client.repository.adcontrol.AdControlRepository import com.oztechan.ccc.client.storage.app.AppStorage import com.oztechan.ccc.client.storage.calculation.CalculationStorage import com.oztechan.ccc.common.core.model.Currency -import io.mockative.Mock -import io.mockative.classOf -import io.mockative.coVerify -import io.mockative.configure -import io.mockative.every -import io.mockative.mock -import io.mockative.verify +import dev.mokkery.MockMode +import dev.mokkery.answering.returns +import dev.mokkery.every +import dev.mokkery.mock +import dev.mokkery.verify +import dev.mokkery.verify.VerifyMode +import dev.mokkery.verifySuspend import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.flow.firstOrNull @@ -50,23 +50,15 @@ internal class CurrenciesViewModelTest { ) } - @Mock - private val appStorage = configure(mock(classOf())) { stubsUnitByDefault = true } + private val appStorage = mock(MockMode.autoUnit) - @Mock - private val calculationStorage = - configure(mock(classOf())) { stubsUnitByDefault = true } + private val calculationStorage = mock(MockMode.autoUnit) - @Mock - private val currencyDataSource = - configure(mock(classOf())) { stubsUnitByDefault = true } + private val currencyDataSource = mock(MockMode.autoUnit) - @Mock - private val adControlRepository = mock(classOf()) + private val adControlRepository = mock() - @Mock - private val analyticsManager = - configure(mock(classOf())) { stubsUnitByDefault = true } + private val analyticsManager = mock(MockMode.autoUnit) private var currency1 = Currency("EUR", "Euro", "€", isActive = true) private val currency2 = Currency("USD", "Dollar", "$", isActive = true) @@ -110,7 +102,6 @@ internal class CurrenciesViewModelTest { ) ) } - .wasInvoked() } // Analytics @@ -123,14 +114,13 @@ internal class CurrenciesViewModelTest { viewModel // init - verify { + verify(VerifyMode.not) { analyticsManager.setUserProperty( UserProperty.CurrencyCount( nonActiveCurrencyList.count().toString() ) ) } - .wasNotInvoked() } // init @@ -147,10 +137,8 @@ internal class CurrenciesViewModelTest { } verify { adControlRepository.shouldShowBannerAd() } - .wasInvoked() verify { appStorage.firstRun } - .wasInvoked() } @Test @@ -249,7 +237,6 @@ internal class CurrenciesViewModelTest { } verify { calculationStorage.currentBase = firstActiveBase } - .wasInvoked() } @Test @@ -274,7 +261,6 @@ internal class CurrenciesViewModelTest { } verify { calculationStorage.currentBase = currency2.code } - .wasInvoked() } // Event @@ -290,8 +276,7 @@ internal class CurrenciesViewModelTest { viewModel.event.updateAllCurrenciesState(mockValue) runTest { - coVerify { currencyDataSource.updateCurrencyStates(mockValue) } - .wasInvoked() + verifySuspend { currencyDataSource.updateCurrencyStates(mockValue) } } } @@ -300,9 +285,9 @@ internal class CurrenciesViewModelTest { viewModel.event.onItemClick(currency1) runTest { - coVerify { + verifySuspend { currencyDataSource.updateCurrencyStateByCode(currency1.code, !currency1.isActive) - }.wasInvoked() + } } } @@ -433,7 +418,6 @@ internal class CurrenciesViewModelTest { assertFalse { viewModel.state.value.isOnboardingVisible } verify { appStorage.firstRun = false } - .wasInvoked() } // where there are 2 currencies but only 1 active diff --git a/client/viewmodel/main/client-viewmodel-main.gradle.kts b/client/viewmodel/main/client-viewmodel-main.gradle.kts index 718f0c58cd..f9f389c9b2 100644 --- a/client/viewmodel/main/client-viewmodel-main.gradle.kts +++ b/client/viewmodel/main/client-viewmodel-main.gradle.kts @@ -2,7 +2,7 @@ plugins { libs.plugins.apply { alias(kotlinMultiplatform) alias(androidLibrary) - alias(ksp) + alias(mokkery) } } kotlin { @@ -40,7 +40,6 @@ kotlin { commonTest.dependencies { libs.common.apply { implementation(test) - implementation(mockative) implementation(coroutinesTest) } } @@ -50,14 +49,6 @@ kotlin { } } -dependencies { - configurations - .filter { it.name.startsWith("ksp") && it.name.contains("Test") } - .forEach { - add(it.name, libs.processors.mockative) - } -} - android { ProjectSettings.apply { namespace = Modules.Client.ViewModel.main.packageName diff --git a/client/viewmodel/main/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/main/MainViewModelTest.kt b/client/viewmodel/main/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/main/MainViewModelTest.kt index cc7e8c79b6..43c221b000 100644 --- a/client/viewmodel/main/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/main/MainViewModelTest.kt +++ b/client/viewmodel/main/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/main/MainViewModelTest.kt @@ -19,12 +19,12 @@ import com.oztechan.ccc.client.core.shared.util.nowAsLong import com.oztechan.ccc.client.repository.adcontrol.AdControlRepository import com.oztechan.ccc.client.repository.appconfig.AppConfigRepository import com.oztechan.ccc.client.storage.app.AppStorage -import io.mockative.Mock -import io.mockative.classOf -import io.mockative.configure -import io.mockative.every -import io.mockative.mock -import io.mockative.verify +import dev.mokkery.MockMode +import dev.mokkery.answering.returns +import dev.mokkery.every +import dev.mokkery.mock +import dev.mokkery.verify +import dev.mokkery.verify.VerifyMode import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.onSubscription @@ -54,28 +54,22 @@ internal class MainViewModelTest { ) } - @Mock - private val appStorage = configure(mock(classOf())) { stubsUnitByDefault = true } + private val appStorage = mock(MockMode.autoUnit) - @Mock - private val reviewConfigService = mock(classOf()) + private val reviewConfigService = mock() - @Mock - private val adConfigService = mock(classOf()) + private val adConfigService = mock() - @Mock - private val appConfigRepository = mock(classOf()) + private val appConfigRepository = mock() - @Mock - private val adControlRepository = mock(classOf()) + private val adControlRepository = mock() - @Mock - private val analyticsManager = - configure(mock(classOf())) { stubsUnitByDefault = true } + private val analyticsManager = mock(MockMode.autoUnit) private val appThemeValue = Random.nextInt() private val mockDevice = Device.IOS private val isFirstRun: Boolean = Random.nextBoolean() + private val sessionCount = 1L @BeforeTest fun setup() { @@ -91,7 +85,7 @@ internal class MainViewModelTest { .returns(nowAsLong()) every { appStorage.sessionCount } - .returns(1L) + .returns(sessionCount) every { appConfigRepository.getDeviceType() } .returns(mockDevice) @@ -109,28 +103,24 @@ internal class MainViewModelTest { viewModel // init verify { - analyticsManager.setUserProperty( - UserProperty.IsPremium( - appStorage.premiumEndDate.isNotPassed().toString() + appStorage.premiumEndDate.let { + analyticsManager.setUserProperty( + UserProperty.IsPremium(it.isNotPassed().toString()) ) - ) + } + } + verify { + appStorage.sessionCount + analyticsManager.setUserProperty(UserProperty.SessionCount(sessionCount.toString())) } - .wasInvoked() - verify { analyticsManager.setUserProperty(UserProperty.SessionCount(appStorage.sessionCount.toString())) } - .wasInvoked() verify { - analyticsManager.setUserProperty( - UserProperty.AppTheme( - AppTheme.getAnalyticsThemeName( - appStorage.appTheme, - mockDevice - ) + appStorage.appTheme.let { + analyticsManager.setUserProperty( + UserProperty.AppTheme(AppTheme.getAnalyticsThemeName(it, mockDevice)) ) - ) + } } - .wasInvoked() verify { analyticsManager.setUserProperty(UserProperty.DevicePlatform(mockDevice.name)) } - .wasInvoked() } // init @@ -143,10 +133,8 @@ internal class MainViewModelTest { } verify { appStorage.firstRun } - .wasInvoked() verify { appStorage.appTheme } - .wasInvoked() } @Test @@ -197,13 +185,11 @@ internal class MainViewModelTest { event.onResume() verify { appStorage.sessionCount = mockSessionCount + 1 } - .wasInvoked() assertFalse { data.isNewSession } event.onResume() - verify { appStorage.sessionCount = mockSessionCount + 1 } - .wasNotInvoked() + verify(VerifyMode.not) { appStorage.sessionCount = mockSessionCount + 1 } assertFalse { data.isNewSession } } @@ -247,13 +233,10 @@ internal class MainViewModelTest { } verify { reviewConfigService.config } - .wasInvoked() verify { adControlRepository.shouldShowInterstitialAd() } - .wasInvoked() verify { appStorage.premiumEndDate } - .wasInvoked() } @Test @@ -281,7 +264,6 @@ internal class MainViewModelTest { assertFalse { data.isAppUpdateShown } verify { appConfigRepository.checkAppUpdate(false) } - .wasInvoked() } @Test @@ -317,10 +299,8 @@ internal class MainViewModelTest { } verify { reviewConfigService.config } - .wasInvoked() verify { appConfigRepository.checkAppUpdate(false) } - .wasInvoked() } @Test @@ -350,10 +330,8 @@ internal class MainViewModelTest { } verify { appConfigRepository.shouldShowAppReview() } - .wasInvoked() verify { reviewConfigService.config } - .wasInvoked() } @Test @@ -379,7 +357,6 @@ internal class MainViewModelTest { onResume() verify { appConfigRepository.shouldShowAppReview() } - .wasInvoked() } @Test @@ -422,9 +399,7 @@ internal class MainViewModelTest { } verify { appStorage.firstRun } - .wasInvoked() verify { appStorage.appTheme } - .wasInvoked() } } diff --git a/client/viewmodel/premium/client-viewmodel-premium.gradle.kts b/client/viewmodel/premium/client-viewmodel-premium.gradle.kts index f6cdff3a9a..77ea3b6128 100644 --- a/client/viewmodel/premium/client-viewmodel-premium.gradle.kts +++ b/client/viewmodel/premium/client-viewmodel-premium.gradle.kts @@ -2,7 +2,7 @@ plugins { libs.plugins.apply { alias(kotlinMultiplatform) alias(androidLibrary) - alias(ksp) + alias(mokkery) } } kotlin { @@ -37,7 +37,6 @@ kotlin { commonTest.dependencies { libs.common.apply { implementation(test) - implementation(mockative) implementation(coroutinesTest) } } @@ -47,14 +46,6 @@ kotlin { } } -dependencies { - configurations - .filter { it.name.startsWith("ksp") && it.name.contains("Test") } - .forEach { - add(it.name, libs.processors.mockative) - } -} - android { ProjectSettings.apply { namespace = Modules.Client.ViewModel.premium.packageName diff --git a/client/viewmodel/premium/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/premium/PremiumViewModelTest.kt b/client/viewmodel/premium/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/premium/PremiumViewModelTest.kt index d263c3366c..c4dd0fb5b4 100644 --- a/client/viewmodel/premium/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/premium/PremiumViewModelTest.kt +++ b/client/viewmodel/premium/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/premium/PremiumViewModelTest.kt @@ -12,12 +12,12 @@ import com.oztechan.ccc.client.viewmodel.premium.model.OldPurchase import com.oztechan.ccc.client.viewmodel.premium.model.PremiumData import com.oztechan.ccc.client.viewmodel.premium.model.PremiumType import com.oztechan.ccc.client.viewmodel.premium.util.calculatePremiumEnd -import io.mockative.Mock -import io.mockative.classOf -import io.mockative.configure -import io.mockative.every -import io.mockative.mock -import io.mockative.verify +import dev.mokkery.MockMode +import dev.mokkery.answering.returns +import dev.mokkery.every +import dev.mokkery.mock +import dev.mokkery.verify +import dev.mokkery.verify.VerifyMode import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.onSubscription @@ -41,8 +41,7 @@ internal class PremiumViewModelTest { PremiumViewModel(appStorage) } - @Mock - private val appStorage = configure(mock(classOf())) { stubsUnitByDefault = true } + private val appStorage = mock(MockMode.autoUnit) @BeforeTest fun setup() { @@ -72,8 +71,7 @@ internal class PremiumViewModelTest { @Test fun onPremiumActivated() = runTest { viewModel.event.onPremiumActivated(null) - verify { appStorage.premiumEndDate } - .wasNotInvoked() + verify(VerifyMode.not) { appStorage.premiumEndDate } PremiumType.values().forEach { premiumType -> val now = nowAsLong() @@ -85,7 +83,6 @@ internal class PremiumViewModelTest { assertFalse { it.isRestorePurchase } verify { appStorage.premiumEndDate = premiumType.calculatePremiumEnd(now) } - .wasInvoked() } } } @@ -110,7 +107,6 @@ internal class PremiumViewModelTest { assertFalse { viewModel.state.value.loading } verify { appStorage.premiumEndDate = it.premiumType.calculatePremiumEnd(now) } - .wasInvoked() } // onRestorePurchase shouldn't do anything if all the old purchases out of dated @@ -121,10 +117,9 @@ internal class PremiumViewModelTest { viewModel.event.onRestorePurchase(listOf(oldPurchase)) - verify { + verify(VerifyMode.not) { appStorage.premiumEndDate = oldPurchase.type.calculatePremiumEnd(oldPurchase.date) } - .wasNotInvoked() // onRestorePurchase shouldn't do anything if the old purchase is already expired oldPurchase = OldPurchase(nowAsLong() - (32.days.inWholeMilliseconds), PremiumType.MONTH) @@ -134,10 +129,9 @@ internal class PremiumViewModelTest { viewModel.event.onRestorePurchase(listOf(oldPurchase)) - verify { + verify(VerifyMode.not) { appStorage.premiumEndDate = oldPurchase.type.calculatePremiumEnd(oldPurchase.date) } - .wasNotInvoked() } @Test diff --git a/client/viewmodel/selectcurrency/client-viewmodel-selectcurrency.gradle.kts b/client/viewmodel/selectcurrency/client-viewmodel-selectcurrency.gradle.kts index bd79ec9ace..f5ee3b6e24 100644 --- a/client/viewmodel/selectcurrency/client-viewmodel-selectcurrency.gradle.kts +++ b/client/viewmodel/selectcurrency/client-viewmodel-selectcurrency.gradle.kts @@ -2,7 +2,7 @@ plugins { libs.plugins.apply { alias(kotlinMultiplatform) alias(androidLibrary) - alias(ksp) + alias(mokkery) } } kotlin { @@ -36,7 +36,6 @@ kotlin { commonTest.dependencies { libs.common.apply { implementation(test) - implementation(mockative) implementation(coroutinesTest) } } @@ -46,14 +45,6 @@ kotlin { } } -dependencies { - configurations - .filter { it.name.startsWith("ksp") && it.name.contains("Test") } - .forEach { - add(it.name, libs.processors.mockative) - } -} - android { ProjectSettings.apply { namespace = Modules.Client.ViewModel.selectCurrency.packageName diff --git a/client/viewmodel/selectcurrency/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/selectcurrency/SelectCurrencyViewModelTest.kt b/client/viewmodel/selectcurrency/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/selectcurrency/SelectCurrencyViewModelTest.kt index fd18fa17fc..3ff8528c27 100644 --- a/client/viewmodel/selectcurrency/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/selectcurrency/SelectCurrencyViewModelTest.kt +++ b/client/viewmodel/selectcurrency/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/selectcurrency/SelectCurrencyViewModelTest.kt @@ -6,11 +6,10 @@ package com.oztechan.ccc.client.viewmodel.selectcurrency import co.touchlab.kermit.CommonWriter import co.touchlab.kermit.Logger import com.oztechan.ccc.client.datasource.currency.CurrencyDataSource -import io.mockative.Mock -import io.mockative.classOf -import io.mockative.every -import io.mockative.mock -import io.mockative.verify +import dev.mokkery.answering.returns +import dev.mokkery.every +import dev.mokkery.mock +import dev.mokkery.verify import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.flowOf @@ -34,8 +33,7 @@ internal class SelectCurrencyViewModelTest { SelectCurrencyViewModel(currencyDataSource) } - @Mock - private val currencyDataSource = mock(classOf()) + private val currencyDataSource = mock() private val currencyDollar = CurrencyCommon("USD", "Dollar", "$", "", true) private val currencyEuro = CurrencyCommon("Eur", "Euro", "", "", true) @@ -74,7 +72,6 @@ internal class SelectCurrencyViewModelTest { } verify { currencyDataSource.getActiveCurrenciesFlow() } - .wasInvoked() } @Test @@ -89,7 +86,6 @@ internal class SelectCurrencyViewModelTest { } verify { currencyDataSource.getActiveCurrenciesFlow() } - .wasInvoked() } @Test @@ -97,6 +93,7 @@ internal class SelectCurrencyViewModelTest { subject.effect.onSubscription { subject.event.onItemClick(currencyDollar) }.firstOrNull().let { + assertNotNull(it) assertIs(it) assertEquals(currencyDollar.code, it.newBase) } diff --git a/client/viewmodel/settings/client-viewmodel-settings.gradle.kts b/client/viewmodel/settings/client-viewmodel-settings.gradle.kts index 842834d864..6feab1949d 100644 --- a/client/viewmodel/settings/client-viewmodel-settings.gradle.kts +++ b/client/viewmodel/settings/client-viewmodel-settings.gradle.kts @@ -2,7 +2,7 @@ plugins { libs.plugins.apply { alias(kotlinMultiplatform) alias(androidLibrary) - alias(ksp) + alias(mokkery) } } kotlin { @@ -53,7 +53,6 @@ kotlin { commonTest.dependencies { libs.common.apply { implementation(test) - implementation(mockative) implementation(coroutinesTest) } } @@ -63,14 +62,6 @@ kotlin { } } -dependencies { - configurations - .filter { it.name.startsWith("ksp") && it.name.contains("Test") } - .forEach { - add(it.name, libs.processors.mockative) - } -} - android { ProjectSettings.apply { namespace = Modules.Client.ViewModel.settings.packageName diff --git a/client/viewmodel/settings/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/settings/SettingsViewModelTest.kt b/client/viewmodel/settings/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/settings/SettingsViewModelTest.kt index 2b1655fd18..8f255e7c45 100644 --- a/client/viewmodel/settings/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/settings/SettingsViewModelTest.kt +++ b/client/viewmodel/settings/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/settings/SettingsViewModelTest.kt @@ -23,14 +23,15 @@ import com.oztechan.ccc.common.core.model.Conversion import com.oztechan.ccc.common.core.model.Currency import com.oztechan.ccc.common.core.model.Watcher import com.oztechan.ccc.common.datasource.conversion.ConversionDataSource -import io.mockative.Mock -import io.mockative.classOf -import io.mockative.coEvery -import io.mockative.coVerify -import io.mockative.configure -import io.mockative.every -import io.mockative.mock -import io.mockative.verify +import dev.mokkery.MockMode +import dev.mokkery.answering.returns +import dev.mokkery.answering.throws +import dev.mokkery.every +import dev.mokkery.everySuspend +import dev.mokkery.mock +import dev.mokkery.verify +import dev.mokkery.verify.VerifyMode +import dev.mokkery.verifySuspend import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.flowOf @@ -64,36 +65,23 @@ internal class SettingsViewModelTest { ) } - @Mock - private val appStorage = configure(mock(classOf())) { stubsUnitByDefault = true } + private val appStorage = mock(MockMode.autoUnit) - @Mock - private val calculationStorage = - configure(mock(classOf())) { stubsUnitByDefault = true } + private val calculationStorage = mock(MockMode.autoUnit) - @Mock - private val backendApiService = mock(classOf()) + private val backendApiService = mock() - @Mock - private val currencyDataSource = mock(classOf()) + private val currencyDataSource = mock() - @Mock - private val conversionDataSource = configure(mock(classOf())) { - stubsUnitByDefault = true - } + private val conversionDataSource = mock(MockMode.autoUnit) - @Mock - private val watcherDataSource = mock(classOf()) + private val watcherDataSource = mock() - @Mock - private val appConfigRepository = mock(classOf()) + private val appConfigRepository = mock() - @Mock - private val adControlRepository = mock(classOf()) + private val adControlRepository = mock() - @Mock - private val analyticsManager = - configure(mock(classOf())) { stubsUnitByDefault = true } + private val analyticsManager = mock(MockMode.autoUnit) private val currencyList = listOf( Currency("", "", ""), @@ -156,7 +144,6 @@ internal class SettingsViewModelTest { } verify { adControlRepository.shouldShowBannerAd() } - .wasInvoked() } @Test @@ -206,10 +193,10 @@ internal class SettingsViewModelTest { val conversion = Conversion(base) val currency = Currency(base, "", "") - coEvery { currencyDataSource.getActiveCurrencies() } + everySuspend { currencyDataSource.getActiveCurrencies() } .returns(listOf(currency)) - coEvery { backendApiService.getConversion(base) } + everySuspend { backendApiService.getConversion(base) } .returns(conversion) viewModel.effect.onSubscription { @@ -218,21 +205,19 @@ internal class SettingsViewModelTest { assertIs(it) } - coVerify { conversionDataSource.insertConversion(conversion) } - .wasInvoked() + verifySuspend { conversionDataSource.insertConversion(conversion) } - coVerify { backendApiService.getConversion(base) } - .wasInvoked() + verifySuspend { backendApiService.getConversion(base) } } @Test fun `failed synchroniseConversions should pass Synchronised effect`() = runTest { viewModel.data.synced = false - coEvery { currencyDataSource.getActiveCurrencies() } + everySuspend { currencyDataSource.getActiveCurrencies() } .returns(currencyList) - coEvery { backendApiService.getConversion("") } + everySuspend { backendApiService.getConversion("") } .throws(Exception("test")) viewModel.effect.onSubscription { @@ -241,8 +226,7 @@ internal class SettingsViewModelTest { assertIs(it) } - coVerify { conversionDataSource.insertConversion(Conversion()) } - .wasNotInvoked() + verifySuspend(VerifyMode.not) { conversionDataSource.insertConversion(Conversion()) } } // Event @@ -339,7 +323,6 @@ internal class SettingsViewModelTest { } verify { appStorage.premiumEndDate } - .wasInvoked() every { appStorage.premiumEndDate } .returns(nowAsLong() + 1.days.inWholeMilliseconds) @@ -351,7 +334,6 @@ internal class SettingsViewModelTest { } verify { appStorage.premiumEndDate } - .wasInvoked() } @Test @@ -365,7 +347,7 @@ internal class SettingsViewModelTest { @Test fun onSyncClick() = runTest { - coEvery { currencyDataSource.getActiveCurrencies() } + everySuspend { currencyDataSource.getActiveCurrencies() } .returns(listOf()) viewModel.effect.onSubscription { @@ -382,7 +364,6 @@ internal class SettingsViewModelTest { } verify { analyticsManager.trackEvent(Event.OfflineSync) } - .wasInvoked() } @Test @@ -407,7 +388,6 @@ internal class SettingsViewModelTest { println("-----") verify { calculationStorage.precision = value.indexToNumber() } - .wasInvoked() } } @@ -424,6 +404,5 @@ internal class SettingsViewModelTest { } verify { appStorage.appTheme = mockTheme.themeValue } - .wasInvoked() } } diff --git a/client/viewmodel/watchers/client-viewmodel-watchers.gradle.kts b/client/viewmodel/watchers/client-viewmodel-watchers.gradle.kts index fece5adf77..afde279954 100644 --- a/client/viewmodel/watchers/client-viewmodel-watchers.gradle.kts +++ b/client/viewmodel/watchers/client-viewmodel-watchers.gradle.kts @@ -2,7 +2,7 @@ plugins { libs.plugins.apply { alias(kotlinMultiplatform) alias(androidLibrary) - alias(ksp) + alias(mokkery) } } kotlin { @@ -42,7 +42,6 @@ kotlin { commonTest.dependencies { libs.common.apply { implementation(test) - implementation(mockative) implementation(coroutinesTest) } } @@ -52,14 +51,6 @@ kotlin { } } -dependencies { - configurations - .filter { it.name.startsWith("ksp") && it.name.contains("Test") } - .forEach { - add(it.name, libs.processors.mockative) - } -} - android { ProjectSettings.apply { namespace = Modules.Client.ViewModel.watchers.packageName diff --git a/client/viewmodel/watchers/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/watchers/WatchersViewModelTest.kt b/client/viewmodel/watchers/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/watchers/WatchersViewModelTest.kt index f980545d38..6b4441d0da 100644 --- a/client/viewmodel/watchers/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/watchers/WatchersViewModelTest.kt +++ b/client/viewmodel/watchers/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/watchers/WatchersViewModelTest.kt @@ -11,14 +11,13 @@ import com.oztechan.ccc.client.datasource.watcher.WatcherDataSource import com.oztechan.ccc.client.repository.adcontrol.AdControlRepository import com.oztechan.ccc.common.core.model.Currency import com.oztechan.ccc.common.core.model.Watcher -import io.mockative.Mock -import io.mockative.classOf -import io.mockative.coEvery -import io.mockative.coVerify -import io.mockative.configure -import io.mockative.every -import io.mockative.mock -import io.mockative.verify +import dev.mokkery.MockMode +import dev.mokkery.answering.returns +import dev.mokkery.every +import dev.mokkery.everySuspend +import dev.mokkery.mock +import dev.mokkery.verify +import dev.mokkery.verifySuspend import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.flowOf @@ -44,19 +43,13 @@ internal class WatchersViewModelTest { ) } - @Mock - private val currencyDataSource = mock(classOf()) + private val currencyDataSource = mock() - @Mock - private val watcherDataSource = - configure(mock(classOf())) { stubsUnitByDefault = true } + private val watcherDataSource = mock(MockMode.autoUnit) - @Mock - private val adControlRepository = mock(classOf()) + private val adControlRepository = mock() - @Mock - private val analyticsManager = - configure(mock(classOf())) { stubsUnitByDefault = true } + private val analyticsManager = mock(MockMode.autoUnit) private val watcher = Watcher(1, "EUR", "USD", true, 1.1) @@ -87,7 +80,6 @@ internal class WatchersViewModelTest { } verify { adControlRepository.shouldShowBannerAd() } - .wasInvoked() } @Test @@ -107,7 +99,6 @@ internal class WatchersViewModelTest { ) ) } - .wasInvoked() } // Event @@ -149,8 +140,7 @@ internal class WatchersViewModelTest { viewModel.event.onBaseChanged(watcher, mockBase) runTest { - coVerify { watcherDataSource.updateWatcherBaseById(mockBase, watcher.id) } - .wasInvoked() + verifySuspend { watcherDataSource.updateWatcherBaseById(mockBase, watcher.id) } } } @@ -160,8 +150,7 @@ internal class WatchersViewModelTest { viewModel.event.onTargetChanged(watcher, mockBase) runTest { - coVerify { watcherDataSource.updateWatcherTargetById(mockBase, watcher.id) } - .wasInvoked() + verifySuspend { watcherDataSource.updateWatcherTargetById(mockBase, watcher.id) } } } @@ -171,31 +160,29 @@ internal class WatchersViewModelTest { val currency2 = Currency("EUR", "EUR", "", "", true) // when there is no active currency - coEvery { currencyDataSource.getActiveCurrencies() } + everySuspend { currencyDataSource.getActiveCurrencies() } .returns(listOf()) - coEvery { watcherDataSource.getWatchers() } + everySuspend { watcherDataSource.getWatchers() } .returns(listOf()) viewModel.event.onAddClick() - coVerify { watcherDataSource.addWatcher("", "") } - .wasInvoked() + verifySuspend { watcherDataSource.addWatcher("", "") } // when there is few watcher - coEvery { watcherDataSource.getWatchers() } + everySuspend { watcherDataSource.getWatchers() } .returns(listOf(watcher)) - coEvery { currencyDataSource.getActiveCurrencies() } + everySuspend { currencyDataSource.getActiveCurrencies() } .returns(listOf(currency1, currency2)) viewModel.event.onAddClick() - coVerify { watcherDataSource.addWatcher(currency1.code, currency2.code) } - .wasInvoked() + verifySuspend { watcherDataSource.addWatcher(currency1.code, currency2.code) } // when there are so much watcher - coEvery { watcherDataSource.getWatchers() } + everySuspend { watcherDataSource.getWatchers() } .returns(listOf(watcher, watcher, watcher, watcher, watcher)) viewModel.effect.onSubscription { @@ -211,8 +198,7 @@ internal class WatchersViewModelTest { viewModel.event.onDeleteClick(watcher) runTest { - coVerify { watcherDataSource.deleteWatcher(watcher.id) } - .wasInvoked() + verifySuspend { watcherDataSource.deleteWatcher(watcher.id) } } } @@ -222,8 +208,7 @@ internal class WatchersViewModelTest { viewModel.event.onRelationChange(watcher, mockBoolean) runTest { - coVerify { watcherDataSource.updateWatcherRelationById(mockBoolean, watcher.id) } - .wasInvoked() + verifySuspend { watcherDataSource.updateWatcherRelationById(mockBoolean, watcher.id) } } } @@ -233,13 +218,12 @@ internal class WatchersViewModelTest { var rate = "12" assertEquals(rate, viewModel.event.onRateChange(watcher, rate)) - coVerify { + verifySuspend { watcherDataSource.updateWatcherRateById( rate.toSupportedCharacters().toStandardDigits().toDoubleOrNull() ?: 0.0, watcher.id ) } - .wasInvoked() // when rate is not valid viewModel.effect.onSubscription { diff --git a/common/datasource/conversion/common-datasource-conversion.gradle.kts b/common/datasource/conversion/common-datasource-conversion.gradle.kts index 116d04cce8..be2f37b7f2 100644 --- a/common/datasource/conversion/common-datasource-conversion.gradle.kts +++ b/common/datasource/conversion/common-datasource-conversion.gradle.kts @@ -2,7 +2,7 @@ plugins { libs.plugins.apply { alias(kotlinMultiplatform) alias(androidLibrary) - alias(ksp) + alias(mokkery) } } @@ -31,21 +31,12 @@ kotlin { commonTest.dependencies { libs.common.apply { implementation(test) - implementation(mockative) implementation(coroutinesTest) } } } } -dependencies { - configurations - .filter { it.name.startsWith("ksp") && it.name.contains("Test") } - .forEach { - add(it.name, libs.processors.mockative) - } -} - android { ProjectSettings.apply { namespace = Modules.Common.DataSource.conversion.packageName diff --git a/common/datasource/conversion/src/commonTest/kotlin/com/oztechan/ccc/common/datasource/conversion/ConversionDataSourceTest.kt b/common/datasource/conversion/src/commonTest/kotlin/com/oztechan/ccc/common/datasource/conversion/ConversionDataSourceTest.kt index b0b719b491..fb2dbdab6d 100644 --- a/common/datasource/conversion/src/commonTest/kotlin/com/oztechan/ccc/common/datasource/conversion/ConversionDataSourceTest.kt +++ b/common/datasource/conversion/src/commonTest/kotlin/com/oztechan/ccc/common/datasource/conversion/ConversionDataSourceTest.kt @@ -8,12 +8,11 @@ import com.oztechan.ccc.common.datasource.conversion.mapper.toConversionDBModel import com.squareup.sqldelight.Query import com.squareup.sqldelight.db.SqlCursor import com.squareup.sqldelight.db.SqlDriver -import io.mockative.Mock -import io.mockative.classOf -import io.mockative.configure -import io.mockative.every -import io.mockative.mock -import io.mockative.verify +import dev.mokkery.MockMode +import dev.mokkery.answering.returns +import dev.mokkery.every +import dev.mokkery.mock +import dev.mokkery.verify import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runTest import kotlin.test.BeforeTest @@ -26,15 +25,9 @@ internal class ConversionDataSourceTest { ConversionDataSourceImpl(conversionQueries, UnconfinedTestDispatcher()) } - @Mock - private val conversionQueries = - configure(mock(classOf())) { stubsUnitByDefault = true } - - @Mock - private val sqlDriver = mock(classOf()) - - @Mock - private val sqlCursor = configure(mock(classOf())) { stubsUnitByDefault = true } + private val conversionQueries = mock(MockMode.autoUnit) + private val sqlDriver = mock() + private val sqlCursor = mock(MockMode.autoUnit) private val query = Query(-1, mutableListOf(), sqlDriver, query = "") { Fakes.conversionModel.toConversionDBModel() @@ -58,7 +51,6 @@ internal class ConversionDataSourceTest { } verify { conversionQueries.insertConversion(Fakes.conversionModel.toConversionDBModel()) } - .wasInvoked() } @Test @@ -71,6 +63,5 @@ internal class ConversionDataSourceTest { } verify { conversionQueries.getConversionByBase(Fakes.conversionModel.base) } - .wasInvoked() } } diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 0bdfc055c8..5a5a9dc74c 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -33,12 +33,12 @@ Pull Request title should follow below format: Example: ``` -[Oztechan/CCC#ISSUE_ID] Whatever the name of ticket is +[Oztechan/CCC#ISSUE_ID] Whatever the name of the issue is ``` ### Description -Description has to have `Resolves Oztechan/CCC#ISSUE_ID` with relevant issue. It will help project automations. +Description has to start `Resolves Oztechan/CCC#ISSUE_ID`. You can add more description into new lines if you want. `Resolves` key with a issue id helps project automations. Example: diff --git a/gradle.properties b/gradle.properties index 6b87c10ee9..1afbf57b37 100755 --- a/gradle.properties +++ b/gradle.properties @@ -8,6 +8,7 @@ org.gradle.caching=true org.gradle.daemon=true org.gradle.configureondemand=true org.gradle.kotlin.dsl.allWarningsAsErrors=true +org.gradle.configuration-cache=true # Kotlin kotlin.code.style=official kotlin.build.report.output=build_scan,file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0030fefeaf..fe9f6374e2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,11 +1,10 @@ [versions] -kotlin = "1.9.24" -androidGradlePlugin = "8.4.1" -ksp = "1.9.24-1.0.20" -composeCompiler = "1.5.14" -jetbrainsCompose = "1.6.10" -glance = "1.0.0" +kotlin = "2.0.0" +androidGradlePlugin = "8.5.0" +jetbrainsCompose = "1.6.11" +glance = "1.1.0" +mokkery = "2.1.1" activityCompose = "1.9.0" navigationCompose = "2.7.0-alpha07" detekt = "1.23.6" @@ -16,17 +15,17 @@ koinCore = "3.5.6" koinCompose = "3.5.6" koinAndroid = "3.5.6" koinKtor = "3.5.6" -ktor = "2.3.11" +ktor = "2.3.12" multiplatformSettings = "1.1.1" -firebaseAnalytics = "22.0.1" +firebaseAnalytics = "22.0.2" firebaseRemoteConfig = "22.0.0" googleServices = "4.4.2" firebasePer = "21.0.1" firebasePerPlugin = "1.4.2" -firebaseCrashlyticsPlugin = "3.0.1" -googleAds = "23.1.0" +firebaseCrashlyticsPlugin = "3.0.2" +googleAds = "23.2.0" googleUmp = "2.2.0" -huaweiAds = "3.4.71.300" +huaweiAds = "3.4.72.301" huaweiOsm = "1.3.35" navigation = "2.7.7" playCore = "1.10.3" @@ -35,22 +34,20 @@ coroutines = "1.8.1" billing = "6.2.1" leakCanary = "2.14" sqlDelight = "1.5.5" -lifecycle = "2.8.1" -mokoResources = "0.23.0" +lifecycle = "2.8.2" +mokoResources = "0.24.1" buildKonfig = "0.15.1" splashScreen = "1.0.1" -kover = "0.6.1" +kover = "0.8.2" rootBeer = "0.1.0" -mockative = "2.2.2" anrWatchDog = "1.4.0" -kermit = "2.0.3" +kermit = "2.0.4" konsist = "0.15.1" [libraries] # COMMON common-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } common-testAnnotations = { module = "org.jetbrains.kotlin:kotlin-test-annotations-common", version.ref = "kotlin" } -common-composeCompiler = { module = "androidx.compose.compiler:compiler", version.ref = "composeCompiler" } # Workaround for compose compiler update common-navigationCompose = { module = "org.jetbrains.androidx.navigation:navigation-compose", version.ref = "navigationCompose" } common-koinCore = { module = "io.insert-koin:koin-core", version.ref = "koinCore" } common-multiplatformSettings = { module = "com.russhwolf:multiplatform-settings", version.ref = "multiplatformSettings" } @@ -63,7 +60,6 @@ common-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", common-coroutinesTest = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" } common-sqlDelightCoroutinesExt = { module = "com.squareup.sqldelight:coroutines-extensions", version.ref = "sqlDelight" } common-mokoResources = { module = "dev.icerock.moko:resources", version.ref = "mokoResources" } -common-mockative = { module = "io.mockative:mockative", version.ref = "mockative" } common-kermit = { module = "co.touchlab:kermit", version.ref = "kermit" } common-detektFormatting = { module = "io.gitlab.arturbosch.detekt:detekt-formatting", version.ref = "detekt" } common-konsist = { module = "com.lemonappdev:konsist", version.ref = "konsist" } @@ -113,13 +109,11 @@ common-ktorServerContentNegotiation = { module = "io.ktor:ktor-server-content-ne jvm-sqlliteDriver = { module = "com.squareup.sqldelight:sqlite-driver", version.ref = "sqlDelight" } jvm-testJunit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlin" } -# PROCESSORS -processors-mockative = { module = "io.mockative:mockative-processor", version.ref = "mockative" } - [plugins] kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } jetbrainsCompose = { id = "org.jetbrains.compose", version.ref = "jetbrainsCompose" } +kotlinPluginCompose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } kotlinJvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } androidApplication = { id = "com.android.application", version.ref = "androidGradlePlugin" } @@ -133,5 +127,5 @@ sqlDelight = { id = "com.squareup.sqldelight", version.ref = "sqlDelight" } mokoResources = { id = "dev.icerock.mobile.multiplatform-resources", version.ref = "mokoResources" } serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" } -ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } +mokkery = { id = "dev.mokkery", version.ref = "mokkery" } detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" } diff --git a/ios/.xcode-version b/ios/.xcode-version new file mode 100644 index 0000000000..441e3fb386 --- /dev/null +++ b/ios/.xcode-version @@ -0,0 +1 @@ +15.4 \ No newline at end of file diff --git a/ios/CCC.xcodeproj/project.pbxproj b/ios/CCC.xcodeproj/project.pbxproj index 211a5439ec..ecb0a4c853 100644 --- a/ios/CCC.xcodeproj/project.pbxproj +++ b/ios/CCC.xcodeproj/project.pbxproj @@ -804,7 +804,7 @@ repositoryURL = "https://github.com/exyte/PopupView.git"; requirement = { kind = exactVersion; - version = 2.9.2; + version = 2.10.2; }; }; 5C3EB6D628775AFF001E822A /* XCRemoteSwiftPackageReference "swift-package-manager-google-mobile-ads" */ = { @@ -812,7 +812,7 @@ repositoryURL = "https://github.com/googleads/swift-package-manager-google-mobile-ads.git"; requirement = { kind = exactVersion; - version = 11.5.0; + version = 11.6.0; }; }; 5C5C0BA22874B8450061AEF9 /* XCRemoteSwiftPackageReference "swiftui-navigation-stack" */ = { @@ -828,7 +828,7 @@ repositoryURL = "https://github.com/firebase/firebase-ios-sdk"; requirement = { kind = exactVersion; - version = 10.27.0; + version = 10.28.1; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/ios/CCC.xcodeproj/xcshareddata/xcschemes/CCC.xcscheme b/ios/CCC.xcodeproj/xcshareddata/xcschemes/CCC.xcscheme index 7aa4991a75..0eb968251f 100644 --- a/ios/CCC.xcodeproj/xcshareddata/xcschemes/CCC.xcscheme +++ b/ios/CCC.xcodeproj/xcshareddata/xcschemes/CCC.xcscheme @@ -10,7 +10,7 @@ ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction"> + scriptText = "# Type a script or drag a script file from your workspace to insert its path. # Check if the CI environment variable is set to true if [[ "$CI" == "true" ]]; then echo "Running in CI environment" cp "$SRCROOT/CCC/Resources/$CONFIGURATION/GoogleService-Info.plist" "$SRCROOT/CCC/Resources/GoogleService-Info.plist" cp "$SRCROOT/CCC/Resources/$CONFIGURATION/Config.xcconfig" "$SRCROOT/CCC/Resources/Config.xcconfig" else echo "Not running in CI environment" fi "> SKAdNetworkIdentifier 4fzdc2evr5.skadnetwork + + SKAdNetworkIdentifier + 4pfyvq9l8r.skadnetwork + SKAdNetworkIdentifier 2fnua5tdw4.skadnetwork @@ -79,31 +83,35 @@ SKAdNetworkIdentifier - c6k4g5qg8m.skadnetwork + ludvb6z3bs.skadnetwork SKAdNetworkIdentifier - s39g8k73mm.skadnetwork + cp8zw746q7.skadnetwork SKAdNetworkIdentifier - 3qy4746246.skadnetwork + 3sh42y64q3.skadnetwork SKAdNetworkIdentifier - 3sh42y64q3.skadnetwork + c6k4g5qg8m.skadnetwork SKAdNetworkIdentifier - f38h382jlk.skadnetwork + s39g8k73mm.skadnetwork SKAdNetworkIdentifier - hs6bdukanm.skadnetwork + 3qy4746246.skadnetwork SKAdNetworkIdentifier - prcb7njmu6.skadnetwork + f38h382jlk.skadnetwork + + + SKAdNetworkIdentifier + hs6bdukanm.skadnetwork SKAdNetworkIdentifier @@ -127,12 +135,32 @@ SKAdNetworkIdentifier - 9rd848q2bz.skadnetwork + gta9lk7p23.skadnetwork + + + SKAdNetworkIdentifier + vutu7akeur.skadnetwork + + + SKAdNetworkIdentifier + y5ghdn5j9k.skadnetwork SKAdNetworkIdentifier n6fk4nfna4.skadnetwork + + SKAdNetworkIdentifier + v9wttpbfk9.skadnetwork + + + SKAdNetworkIdentifier + n38lu8286q.skadnetwork + + + SKAdNetworkIdentifier + 47vhws6wlr.skadnetwork + SKAdNetworkIdentifier kbd757ywx3.skadnetwork @@ -143,19 +171,27 @@ SKAdNetworkIdentifier - 4468km3ulz.skadnetwork + eh6m2bh4zr.skadnetwork SKAdNetworkIdentifier - 2u9pt9hc89.skadnetwork + a2p9lx4jpn.skadnetwork SKAdNetworkIdentifier - 8s468mfl3y.skadnetwork + 22mmun2rn5.skadnetwork SKAdNetworkIdentifier - av6w8kgt66.skadnetwork + 4468km3ulz.skadnetwork + + + SKAdNetworkIdentifier + 2u9pt9hc89.skadnetwork + + + SKAdNetworkIdentifier + 8s468mfl3y.skadnetwork SKAdNetworkIdentifier @@ -167,12 +203,20 @@ SKAdNetworkIdentifier - 424m5254lk.skadnetwork + ecpz2srf59.skadnetwork SKAdNetworkIdentifier uw77j35x4d.skadnetwork + + SKAdNetworkIdentifier + pwa73g5rt2.skadnetwork + + + SKAdNetworkIdentifier + mlmmfzh3r3.skadnetwork + SKAdNetworkIdentifier 578prtvx9j.skadnetwork @@ -193,6 +237,10 @@ SKAdNetworkIdentifier zq492l623r.skadnetwork + + SKAdNetworkIdentifier + 3rd42ekr43.skadnetwork + SKAdNetworkIdentifier 3qcr597p9d.skadnetwork diff --git a/ios/Gemfile b/ios/Gemfile index 01a93e83e5..ce182ff6d4 100644 --- a/ios/Gemfile +++ b/ios/Gemfile @@ -1,5 +1,4 @@ source "https://rubygems.org" -gem "fastlane", "2.220.0" +gem "fastlane", "2.221.1" gem "fastlane-plugin-firebase_app_distribution", "0.9.1" -gem "xcode-install", "2.8.1" diff --git a/ios/Gemfile.lock b/ios/Gemfile.lock index b0f92d224e..4c675f2cf9 100644 --- a/ios/Gemfile.lock +++ b/ios/Gemfile.lock @@ -5,22 +5,22 @@ GEM base64 nkf rexml - addressable (2.8.6) - public_suffix (>= 2.0.2, < 6.0) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) artifactory (3.0.17) atomos (0.1.3) aws-eventstream (1.3.0) - aws-partitions (1.934.0) - aws-sdk-core (3.196.1) + aws-partitions (1.947.0) + aws-sdk-core (3.199.0) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) aws-sigv4 (~> 1.8) jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.82.0) - aws-sdk-core (~> 3, >= 3.193.0) + aws-sdk-kms (1.87.0) + aws-sdk-core (~> 3, >= 3.199.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.151.0) - aws-sdk-core (~> 3, >= 3.194.0) + aws-sdk-s3 (1.154.0) + aws-sdk-core (~> 3, >= 3.199.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.8) aws-sigv4 (1.8.0) @@ -68,7 +68,7 @@ GEM faraday_middleware (1.2.0) faraday (~> 1.0) fastimage (2.3.1) - fastlane (2.220.0) + fastlane (2.221.1) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.8, < 3.0.0) artifactory (~> 3.0) @@ -154,14 +154,14 @@ GEM os (>= 0.9, < 2.0) signet (>= 0.16, < 2.a) highline (2.0.3) - http-cookie (1.0.5) + http-cookie (1.0.6) domain_name (~> 0.5) httpclient (2.8.3) jmespath (1.6.2) json (2.7.2) - jwt (2.8.1) + jwt (2.8.2) base64 - mini_magick (4.12.0) + mini_magick (4.13.1) mini_mime (1.1.5) multi_json (1.15.0) multipart-post (2.4.1) @@ -171,15 +171,15 @@ GEM optparse (0.5.0) os (1.1.4) plist (3.7.1) - public_suffix (5.0.5) + public_suffix (6.0.0) rake (13.2.1) representable (3.2.0) declarative (< 0.1.0) trailblazer-option (>= 0.1.1, < 0.2.0) uber (< 0.2.0) retriable (3.1.2) - rexml (3.2.8) - strscan (>= 3.0.9) + rexml (3.2.9) + strscan rouge (2.0.7) ruby2_keywords (0.0.5) rubyzip (2.3.2) @@ -204,9 +204,6 @@ GEM uber (0.1.0) unicode-display_width (2.5.0) word_wrap (1.0.0) - xcode-install (2.8.1) - claide (>= 0.9.1) - fastlane (>= 2.1.0, < 3.0.0) xcodeproj (1.24.0) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) @@ -221,12 +218,12 @@ GEM PLATFORMS x86_64-darwin-22 + x86_64-darwin-23 x86_64-linux DEPENDENCIES - fastlane (= 2.220.0) + fastlane (= 2.221.1) fastlane-plugin-firebase_app_distribution (= 0.9.1) - xcode-install (= 2.8.1) BUNDLED WITH - 2.4.3 + 2.5.11 diff --git a/ios/Package.swift b/ios/Package.swift index 95556c8217..9ac9f07383 100644 --- a/ios/Package.swift +++ b/ios/Package.swift @@ -14,15 +14,15 @@ let package = Package( dependencies: [ .package( url: "https://github.com/firebase/firebase-ios-sdk", - from: "10.27.0" + from: "10.28.1" ), .package( url: "https://github.com/googleads/swift-package-manager-google-mobile-ads.git", - from: "11.5.0" + from: "11.6.0" ), .package( url: "https://github.com/exyte/PopupView.git", - from: "2.9.2" + from: "2.10.1" ), .package( url: "https://github.com/matteopuc/swiftui-navigation-stack", diff --git a/ios/fastlane/Fastfile b/ios/fastlane/Fastfile index 251e57c4d7..c9f86876aa 100644 --- a/ios/fastlane/Fastfile +++ b/ios/fastlane/Fastfile @@ -115,10 +115,7 @@ platform :ios do update_project_provisioning( profile: ENV["sigh_com.oztechan.ccc_" + match_type + "_profile-path"] ) - xcodes( - version: '15.4', - select_for_current_build_only: true, - ) + xcodes(select_for_current_build_only: true) gym( workspace: "CCC.xcworkspace", scheme: "CCC", diff --git a/ios/repository/background/ios-repository-background.gradle.kts b/ios/repository/background/ios-repository-background.gradle.kts index 4e2e030234..d3f439a603 100644 --- a/ios/repository/background/ios-repository-background.gradle.kts +++ b/ios/repository/background/ios-repository-background.gradle.kts @@ -1,7 +1,7 @@ plugins { libs.plugins.apply { alias(kotlinMultiplatform) - alias(ksp) + alias(mokkery) } } @@ -26,16 +26,7 @@ kotlin { libs.common.apply { implementation(test) implementation(coroutinesTest) - implementation(mockative) } } } } - -dependencies { - configurations - .filter { it.name.startsWith("ksp") && it.name.contains("Test") } - .forEach { - add(it.name, libs.processors.mockative) - } -} diff --git a/ios/repository/background/src/commonTest/kotlin/com/oztechan/ccc/ios/repository/background/BackgroundRepositoryTest.kt b/ios/repository/background/src/commonTest/kotlin/com/oztechan/ccc/ios/repository/background/BackgroundRepositoryTest.kt index c55be6b271..d50757aecb 100644 --- a/ios/repository/background/src/commonTest/kotlin/com/oztechan/ccc/ios/repository/background/BackgroundRepositoryTest.kt +++ b/ios/repository/background/src/commonTest/kotlin/com/oztechan/ccc/ios/repository/background/BackgroundRepositoryTest.kt @@ -6,11 +6,11 @@ import com.oztechan.ccc.client.datasource.watcher.WatcherDataSource import com.oztechan.ccc.client.service.backend.BackendApiService import com.oztechan.ccc.common.core.model.Conversion import com.oztechan.ccc.common.core.model.Watcher -import io.mockative.Mock -import io.mockative.classOf -import io.mockative.coEvery -import io.mockative.coVerify -import io.mockative.mock +import dev.mokkery.answering.returns +import dev.mokkery.answering.throws +import dev.mokkery.everySuspend +import dev.mokkery.mock +import dev.mokkery.verifySuspend import kotlinx.coroutines.test.runTest import kotlin.test.BeforeTest import kotlin.test.Test @@ -23,11 +23,9 @@ internal class BackgroundRepositoryTest { BackgroundRepositoryImpl(watcherDataSource, backendApiService) } - @Mock - private val watcherDataSource = mock(classOf()) + private val watcherDataSource = mock() - @Mock - private val backendApiService = mock(classOf()) + private val backendApiService = mock() @BeforeTest fun setup() { @@ -36,51 +34,46 @@ internal class BackgroundRepositoryTest { @Test fun `if getWatchers throw an error should return false`() = runTest { - coEvery { watcherDataSource.getWatchers() } + everySuspend { watcherDataSource.getWatchers() } .throws(Exception()) assertFalse { subject.shouldSendNotification() } - coVerify { watcherDataSource.getWatchers() } - .wasInvoked() + verifySuspend { watcherDataSource.getWatchers() } } @Test fun `if getConversion throw an error should return false`() = runTest { val watcher = Watcher(1, "EUR", "USD", true, 1.1) - coEvery { watcherDataSource.getWatchers() } + everySuspend { watcherDataSource.getWatchers() } .returns(listOf(watcher)) - coEvery { backendApiService.getConversion(watcher.base) } + everySuspend { backendApiService.getConversion(watcher.base) } .throws(Exception()) assertFalse { subject.shouldSendNotification() } - coVerify { watcherDataSource.getWatchers() } - .wasInvoked() + verifySuspend { watcherDataSource.getWatchers() } - coVerify { backendApiService.getConversion(watcher.base) } - .wasInvoked() + verifySuspend { backendApiService.getConversion(watcher.base) } } @Test fun `if watcher set greater and response rate is more than watcher return true`() = runTest { val watcher = Watcher(1, "EUR", "USD", true, 1.1) - coEvery { watcherDataSource.getWatchers() } + everySuspend { watcherDataSource.getWatchers() } .returns(listOf(watcher)) - coEvery { backendApiService.getConversion(watcher.base) } + everySuspend { backendApiService.getConversion(watcher.base) } .returns(Conversion(base = watcher.base, usd = watcher.rate + 1)) assertTrue { subject.shouldSendNotification() } - coVerify { watcherDataSource.getWatchers() } - .wasInvoked() + verifySuspend { watcherDataSource.getWatchers() } - coVerify { backendApiService.getConversion(watcher.base) } - .wasInvoked() + verifySuspend { backendApiService.getConversion(watcher.base) } } @Test @@ -88,18 +81,16 @@ internal class BackgroundRepositoryTest { runTest { val watcher = Watcher(1, "EUR", "USD", false, 1.1) - coEvery { watcherDataSource.getWatchers() } + everySuspend { watcherDataSource.getWatchers() } .returns(listOf(watcher)) - coEvery { backendApiService.getConversion(watcher.base) } + everySuspend { backendApiService.getConversion(watcher.base) } .returns(Conversion(base = watcher.base, usd = watcher.rate - 1)) assertTrue { subject.shouldSendNotification() } - coVerify { watcherDataSource.getWatchers() } - .wasInvoked() + verifySuspend { watcherDataSource.getWatchers() } - coVerify { backendApiService.getConversion(watcher.base) } - .wasInvoked() + verifySuspend { backendApiService.getConversion(watcher.base) } } } diff --git a/submodule/basemob b/submodule/basemob index b77771485d..34eb65f466 160000 --- a/submodule/basemob +++ b/submodule/basemob @@ -1 +1 @@ -Subproject commit b77771485d777469f60a2de8e6e6f2af14fb837b +Subproject commit 34eb65f466d9072bd78063954446961b59e4c194 diff --git a/submodule/logmob b/submodule/logmob index f9077f8cff..9b30a8c6e4 160000 --- a/submodule/logmob +++ b/submodule/logmob @@ -1 +1 @@ -Subproject commit f9077f8cff59b969883e3b0615f545d26e8e9804 +Subproject commit 9b30a8c6e4bd35d2e90bc1b114c1f9867e5971c5 diff --git a/submodule/parsermob b/submodule/parsermob index f4cc21eb4e..1ad0858866 160000 --- a/submodule/parsermob +++ b/submodule/parsermob @@ -1 +1 @@ -Subproject commit f4cc21eb4e83860d625682d010bf234a4e2f907a +Subproject commit 1ad0858866fc26dd37cf2174854533881ec777e9 diff --git a/submodule/scopemob b/submodule/scopemob index e689bf3e4b..cefe5c7d18 160000 --- a/submodule/scopemob +++ b/submodule/scopemob @@ -1 +1 @@ -Subproject commit e689bf3e4ba2ee968909afebd10e7d1f57af9334 +Subproject commit cefe5c7d180225f90fd2a1d1018a44c8159b55e2