diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 54596a3ba2a..5c57263b1c7 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -45,6 +45,10 @@ gradlew.bat @BenHenning /.github/*.md @BenHenning /.github/ISSUE_TEMPLATE @BenHenning +# Git secret files & related configurations. +/.gitsecret/ @BenHenning +*.secret @BenHenning + # CI configuration. /.github/workflows/ @BenHenning diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f2f4453ae59..689631594ec 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,7 +17,7 @@ on: jobs: linters: name: Lint Tests - runs-on: ${{ matrix.os }} + runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-18.04] @@ -65,7 +65,7 @@ jobs: robolectric_tests: name: Robolectric Tests (Non-App Modules) - runs-on: ${{ matrix.os }} + runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-18.04] @@ -122,7 +122,7 @@ jobs: app_tests: name: Robolectric Tests - App Module (Non-Flaky) - runs-on: ${{ matrix.os }} + runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-18.04] @@ -158,32 +158,66 @@ jobs: os: [ubuntu-18.04] steps: - uses: actions/checkout@v2 - - name: Set up bazel - uses: jwlawson/actions-setup-bazel@v1 - with: - bazel-version: '3.4.1' - name: Clone Oppia Bazel run: git clone https://github.com/oppia/bazel.git $HOME/oppia-bazel - name: Set up JDK 9 uses: actions/setup-java@v1 with: java-version: 9 - - name: Extract Android Tools + - name: Extract Android tools run: | mkdir -p $GITHUB_WORKSPACE/tmp/android_tools cd $HOME/oppia-bazel unzip bazel-tools.zip tar -xf $HOME/oppia-bazel/android_tools.tar.gz -C $GITHUB_WORKSPACE/tmp/android_tools - - name: Unzip Bazel Binary and Build Oppia + # See https://git-secret.io/installation for details on installing git-secret. Note that the + # apt-get method isn't used since it's much slower to update & upgrade apt before installation + # versus just directly cloning & installing the project. Further, the specific version + # shouldn't matter since git-secret relies on a future-proof storage mechanism for secrets. + # This also uses a different directory to install git-secret to avoid requiring root access + # when running the git secret command. + - name: Install git-secret (non-fork only) + if: github.repository == 'oppia/oppia-android' + shell: bash + run: | + cd $HOME + mkdir -p $HOME/gitsecret + git clone https://github.com/sobolevn/git-secret.git git-secret + cd git-secret && make build + PREFIX="$HOME/gitsecret" make install + echo "$HOME/gitsecret" >> $GITHUB_PATH + echo "$HOME/gitsecret/bin" >> $GITHUB_PATH + - name: Decrypt secrets (non-fork only) + if: github.repository == 'oppia/oppia-android' + env: + GIT_SECRET_GPG_PRIVATE_KEY: ${{ secrets.GIT_SECRET_GPG_PRIVATE_KEY }} + run: | + cd $HOME + # NOTE TO DEVELOPERS: Make sure to never print this key directly to stdout! + echo $GIT_SECRET_GPG_PRIVATE_KEY | base64 --decode > ./git_secret_private_key.gpg + gpg --import ./git_secret_private_key.gpg + cd $GITHUB_WORKSPACE + git secret reveal + - name: Unzip Bazel binary run: | cd $HOME/oppia-bazel unzip bazel-build.zip cd $GITHUB_WORKSPACE chmod a+x $HOME/oppia-bazel/bazel - $HOME/oppia-bazel/bazel build //:oppia --android_databinding_use_v3_4_args --experimental_android_databinding_v2 --override_repository=android_tools=$GITHUB_WORKSPACE/tmp/android_tools --java_header_compilation=false --noincremental_dexing --define=android_standalone_dexing_tool=d8_compat_dx - cp $GITHUB_WORKSPACE/bazel-bin/oppia.apk /home/runner/work/oppia-android/oppia-android/ + # Note that caching only works on non-forks. + - name: Build Oppia binary (with caching, non-fork only) + if: github.repository == 'oppia/oppia-android' + env: + BAZEL_REMOTE_CACHE_URL: ${{ secrets.BAZEL_REMOTE_CACHE_URL }} + run: | + $HOME/oppia-bazel/bazel build --override_repository=android_tools=$GITHUB_WORKSPACE/tmp/android_tools --remote_http_cache=$BAZEL_REMOTE_CACHE_URL --google_credentials=./config/oppia-dev-workflow-remote-cache-credentials.json -- //:oppia + - name: Build Oppia binary (without caching, fork only) + if: github.repository != 'oppia/oppia-android' + run: | + $HOME/oppia-bazel/bazel build --override_repository=android_tools=$GITHUB_WORKSPACE/tmp/android_tools -- //:oppia + - name: Copy Oppia APK for uploading + run: cp $GITHUB_WORKSPACE/bazel-bin/oppia.apk /home/runner/work/oppia-android/oppia-android/ - uses: actions/upload-artifact@v2 with: name: oppia-bazel-apk path: /home/runner/work/oppia-android/oppia-android/oppia.apk - - uses: actions/checkout@v2 diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml new file mode 100644 index 00000000000..fa5a270d9e9 --- /dev/null +++ b/.github/workflows/unit_tests.yml @@ -0,0 +1,118 @@ +name: Unit Tests (Robolectric - Bazel) + +# Controls when the action will run. Triggers the workflow on pull request +# events or push events in the develop branch. +on: + workflow_dispatch: + pull_request: + push: + branches: + # Push events on develop branch + - develop + +jobs: + bazel_compute_affected_targets: + name: Compute affected tests + runs-on: ubuntu-18.04 + outputs: + matrix: ${{ steps.compute-test-matrix-from-affected.outputs.matrix || steps.compute-test-matrix-from-all.outputs.matrix }} + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Clone Oppia Bazel + run: git clone https://github.com/oppia/bazel.git $HOME/oppia-bazel + - name: Unzip Bazel binary + run: | + cd $HOME/oppia-bazel + unzip bazel-build.zip + cd $GITHUB_WORKSPACE + chmod a+x $HOME/oppia-bazel/bazel + - name: Compute test matrix based on affected targets + id: compute-test-matrix-from-affected + if: "!contains(github.event.pull_request.title, '[RunAllTests]')" + # https://unix.stackexchange.com/a/338124 for reference on creating a JSON-friendly + # comma-separated list of test targets for the matrix. + run: | + TEST_TARGET_LIST=$(bash ./scripts/compute_affected_tests.sh $HOME/oppia-bazel/bazel | sed 's/^\|$/"/g' | paste -sd, -) + echo "Affected tests (note that this might be all tests if on the develop branch): $TEST_TARGET_LIST" + echo "::set-output name=matrix::{\"test-target\":[$TEST_TARGET_LIST]}" + - name: Compute test matrix based on all tests + id: compute-test-matrix-from-all + if: "contains(github.event.pull_request.title, '[RunAllTests]')" + run: | + TEST_TARGET_LIST=$($HOME/oppia-bazel/bazel query "kind(test, //...)" | sed 's/^\|$/"/g' | paste -sd, -) + echo "Affected tests (note that this might be all tests if on the develop branch): $TEST_TARGET_LIST" + echo "::set-output name=matrix::{\"test-target\":[$TEST_TARGET_LIST]}" + + bazel_run_test: + name: Run Bazel Test + needs: bazel_compute_affected_targets + runs-on: ubuntu-18.04 + strategy: + fail-fast: false + matrix: ${{fromJson(needs.bazel_compute_affected_targets.outputs.matrix)}} + steps: + - uses: actions/checkout@v2 + - name: Clone Oppia Bazel + run: git clone https://github.com/oppia/bazel.git $HOME/oppia-bazel + - name: Set up JDK 9 + uses: actions/setup-java@v1 + with: + java-version: 9 + - name: Extract Android tools + run: | + mkdir -p $GITHUB_WORKSPACE/tmp/android_tools + cd $HOME/oppia-bazel + unzip bazel-tools.zip + tar -xf $HOME/oppia-bazel/android_tools.tar.gz -C $GITHUB_WORKSPACE/tmp/android_tools + # See explanation in bazel_build_app for how this is installed. + - name: Install git-secret (non-fork only) + if: github.repository == 'oppia/oppia-android' + shell: bash + run: | + cd $HOME + mkdir -p $HOME/gitsecret + git clone https://github.com/sobolevn/git-secret.git git-secret + cd git-secret && make build + PREFIX="$HOME/gitsecret" make install + echo "$HOME/gitsecret" >> $GITHUB_PATH + echo "$HOME/gitsecret/bin" >> $GITHUB_PATH + - name: Decrypt secrets (non-fork only) + if: github.repository == 'oppia/oppia-android' + env: + GIT_SECRET_GPG_PRIVATE_KEY: ${{ secrets.GIT_SECRET_GPG_PRIVATE_KEY }} + run: | + cd $HOME + # NOTE TO DEVELOPERS: Make sure to never print this key directly to stdout! + echo $GIT_SECRET_GPG_PRIVATE_KEY | base64 --decode > ./git_secret_private_key.gpg + gpg --import ./git_secret_private_key.gpg + cd $GITHUB_WORKSPACE + git secret reveal + - name: Unzip Bazel binary + run: | + cd $HOME/oppia-bazel + unzip bazel-build.zip + cd $GITHUB_WORKSPACE + chmod a+x $HOME/oppia-bazel/bazel + - name: Run Oppia Test (with caching, non-fork only) + if: github.repository == 'oppia/oppia-android' + env: + BAZEL_REMOTE_CACHE_URL: ${{ secrets.BAZEL_REMOTE_CACHE_URL }} + run: $HOME/oppia-bazel/bazel test --override_repository=android_tools=$GITHUB_WORKSPACE/tmp/android_tools --remote_http_cache=$BAZEL_REMOTE_CACHE_URL --google_credentials=./config/oppia-dev-workflow-remote-cache-credentials.json -- ${{ matrix.test-target }} + - name: Run Oppia Test (without caching, fork only) + if: github.repository != 'oppia/oppia-android' + env: + BAZEL_REMOTE_CACHE_URL: ${{ secrets.BAZEL_REMOTE_CACHE_URL }} + run: $HOME/oppia-bazel/bazel test --override_repository=android_tools=$GITHUB_WORKSPACE/tmp/android_tools -- ${{ matrix.test-target }} + + # Reference: https://github.community/t/127354/7. + check_test_results: + name: Check Bazel Test Results + needs: bazel_run_test + if: ${{ always() }} + runs-on: ubuntu-18.04 + steps: + - name: Check tests passed + if: ${{ needs.bazel_run_test.result != 'success' }} + run: exit 1 diff --git a/.github/workflows/workflow_canceller.yml b/.github/workflows/workflow_canceller.yml new file mode 100644 index 00000000000..fd6ac56313a --- /dev/null +++ b/.github/workflows/workflow_canceller.yml @@ -0,0 +1,28 @@ +name: Automatic Workflow Canceller + +# This workflow should be triggered in one of three situations: +# 1. Manual workflow dispatch via https://github.com/oppia/oppia-android/actions. +# 2. Upon creation of a PR & updates to that PR. +# 3. Whenever the develop branch is changed (e.g. after a PR is merged). +# +# Note that the action being used here automatically accounts for the current branch & the commit +# hash of the tip of the branch to ensure it doesn't cancel previous workflows that aren't related +# to the branch being evaluated. +on: + workflow_dispatch: + pull_request: + push: + branches: + # Push events on develop branch + - develop + +jobs: + cancel: + name: Cancel Previous Runs + runs-on: ubuntu-18.04 + steps: + # See https://github.com/styfle/cancel-workflow-action for details on this workflow. + - uses: styfle/cancel-workflow-action@0.6.0 + with: + workflow_id: main.yml + access_token: ${{ github.token }} diff --git a/.gitignore b/.gitignore index 76abf6584c3..7575c3465f8 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,8 @@ utility/build gradle gradlew gradlew.bat +.gitsecret/keys/random_seed +!*.secret +config/oppia-dev-workflow-remote-cache-credentials.json +bazel-* +.bazelproject diff --git a/.gitsecret/keys/pubring.kbx b/.gitsecret/keys/pubring.kbx new file mode 100644 index 00000000000..8727b699585 Binary files /dev/null and b/.gitsecret/keys/pubring.kbx differ diff --git a/.gitsecret/keys/pubring.kbx~ b/.gitsecret/keys/pubring.kbx~ new file mode 100644 index 00000000000..6c0170a784c Binary files /dev/null and b/.gitsecret/keys/pubring.kbx~ differ diff --git a/.gitsecret/keys/trustdb.gpg b/.gitsecret/keys/trustdb.gpg new file mode 100644 index 00000000000..59fe4e06e40 Binary files /dev/null and b/.gitsecret/keys/trustdb.gpg differ diff --git a/.gitsecret/paths/mapping.cfg b/.gitsecret/paths/mapping.cfg new file mode 100644 index 00000000000..75e37c7661f --- /dev/null +++ b/.gitsecret/paths/mapping.cfg @@ -0,0 +1 @@ +config/oppia-dev-workflow-remote-cache-credentials.json:c02f95d3829f9a7fb3757170ade432efa43d562d2e7c208372ec9d0f4a45da1a diff --git a/app/src/main/res/layout-land/submitted_answer_item.xml b/app/src/main/res/layout-land/submitted_answer_item.xml index 913916b4a95..a746e86c345 100644 --- a/app/src/main/res/layout-land/submitted_answer_item.xml +++ b/app/src/main/res/layout-land/submitted_answer_item.xml @@ -20,6 +20,7 @@ (0)) + testCoroutineDispatchers.runCurrent() onView( RecyclerViewMatcher.atPositionOnView( R.id.hints_and_solution_recycler_view, 0, R.id.hint_summary_container ) ).perform(click()) testCoroutineDispatchers.runCurrent() + onView(isRoot()).check( matches( not( @@ -763,6 +800,7 @@ class StateFragmentLocalTest { onView(withId(R.id.hints_and_solution_recycler_view)) .inRoot(isDialog()) .perform(scrollToPosition(/* position= */ solutionIndex * 2)) + testCoroutineDispatchers.runCurrent() onView(allOf(withId(R.id.reveal_solution_button), isDisplayed())) .inRoot(isDialog()) .check(matches(isDisplayed())) @@ -815,6 +853,7 @@ class StateFragmentLocalTest { onView(withId(R.id.hints_and_solution_recycler_view)) .inRoot(isDialog()) .perform(scrollToPosition(/* position= */ solutionIndex * 2)) + testCoroutineDispatchers.runCurrent() onView(allOf(withId(R.id.reveal_solution_button), isDisplayed())) .inRoot(isDialog()) .check(matches(isDisplayed())) @@ -838,9 +877,11 @@ class StateFragmentLocalTest { onView(withId(R.id.hints_and_solution_recycler_view)) .inRoot(isDialog()) .perform(scrollToPosition(/* position= */ solutionIndex * 2)) + testCoroutineDispatchers.runCurrent() onView(allOf(withId(R.id.reveal_solution_button), isDisplayed())) .inRoot(isDialog()) .perform(click()) + testCoroutineDispatchers.runCurrent() onView(withText("This will reveal the solution. Are you sure?")) .inRoot(isDialog()) @@ -1487,14 +1528,55 @@ class StateFragmentLocalTest { } // Go to previous state and then come back to current state - private fun moveToPreviousAndBackToCurrentState() { + private fun moveToPreviousAndBackToCurrentStateWithSubmitButton() { + // The previous navigation button is bundled with the submit button sometimes, and specifically + // for tests that are currently on a state with a submit button after the first state. + onView(withId(R.id.state_recycler_view)).perform(scrollToViewType(SUBMIT_ANSWER_BUTTON)) + testCoroutineDispatchers.runCurrent() onView(withId(R.id.previous_state_navigation_button)).perform(click()) testCoroutineDispatchers.runCurrent() + onView(withId(R.id.state_recycler_view)).perform(scrollToViewType(NEXT_NAVIGATION_BUTTON)) + testCoroutineDispatchers.runCurrent() onView(withId(R.id.next_state_navigation_button)).perform(click()) testCoroutineDispatchers.runCurrent() } + /** + * Returns a [ViewAssertion] that can be used to check the specified matcher applies the specified + * number of times for children against the view under test. If the count does not exactly match, + * the assertion will fail. + */ + private fun matchesChildren(matcher: Matcher, times: Int): ViewAssertion { + return matches( + object : TypeSafeMatcher() { + override fun describeTo(description: Description?) { + description + ?.appendDescriptionOf(matcher) + ?.appendText(" occurs times: $times in child views") + } + + override fun matchesSafely(view: View?): Boolean { + if (view !is ViewGroup) { + throw PerformException.Builder() + .withCause(IllegalStateException("Expected to match against view group, not: $view")) + .build() + } + val matchingCount = view.children.filter(matcher::matches).count() + if (matchingCount != times) { + throw PerformException.Builder() + .withActionDescription("Expected to match $matcher against $times children") + .withViewDescription("$view") + .withCause( + IllegalStateException("Matched $matchingCount times in $view (expected $times)") + ) + .build() + } + return true + } + }) + } + // TODO(#59): Figure out a way to reuse modules instead of needing to re-declare them. // TODO(#1675): Add NetworkModule once data module is migrated off of Moshi. @Singleton diff --git a/config/oppia-dev-workflow-remote-cache-credentials.json.secret b/config/oppia-dev-workflow-remote-cache-credentials.json.secret new file mode 100644 index 00000000000..2aa2fc7d0fe Binary files /dev/null and b/config/oppia-dev-workflow-remote-cache-credentials.json.secret differ diff --git a/domain/BUILD.bazel b/domain/BUILD.bazel index 88a69e91f23..aebc7016253 100755 --- a/domain/BUILD.bazel +++ b/domain/BUILD.bazel @@ -9,7 +9,10 @@ load("//domain:domain_test.bzl", "domain_test") kt_android_library( name = "domain", - srcs = glob(["src/main/java/org/oppia/android/domain/**/*.kt"]), + srcs = glob( + ["src/main/java/org/oppia/android/domain/**/*.kt"], + exclude = ["src/main/java/org/oppia/android/domain/testing/**/*.kt"], + ), assets = glob(["src/main/assets/**"]), assets_dir = "src/main/assets/", custom_package = "org.oppia.android.domain", @@ -22,10 +25,34 @@ kt_android_library( ], ) +kt_android_library( + name = "testing", + testonly = True, + srcs = glob(["src/main/java/org/oppia/android/domain/testing/**/*.kt"]), + deps = [ + ":domain", + "//third_party:androidx_work_work-runtime-ktx", + ], +) + +# TODO(#2143): Move InteractionObjectTestBuilder to a testing package outside the test folder. +kt_android_library( + name = "interaction_object_test_builder", + testonly = True, + srcs = [ + "src/test/java/org/oppia/android/domain/classify/InteractionObjectTestBuilder.kt", + ], + deps = [ + "//model", + ], +) + # keep sorted TEST_DEPS = [ ":dagger", ":domain", + ":interaction_object_test_builder", + ":testing", "//data:persistent_cache_store", "//model", "//testing", @@ -271,6 +298,15 @@ domain_test( deps = TEST_DEPS, ) +domain_test( + name = "ItemSelectionInputDoesNotContainAtLeastOneOfRuleClassifierProviderTest", + srcs = [ + "src/test/java/org/oppia/android/domain/classify/rules/itemselectioninput/ItemSelectionInputDoesNotContainAtLeastOneOfRuleClassifierProviderTest.kt", + ], + test_class = "org.oppia.android.domain.classify.rules.itemselectioninput.ItemSelectionInputDoesNotContainAtLeastOneOfRuleClassifierProviderTest", + deps = TEST_DEPS, +) + domain_test( name = "MultipleChoiceInputEqualsRuleClassifierProviderTest", srcs = [ @@ -316,15 +352,6 @@ domain_test( deps = TEST_DEPS, ) -domain_test( - name = "ItemSelectionInputDoesNotContainAtLeastOneOfRuleClassifierProviderTest", - srcs = [ - "src/test/java/org/oppia/android/domain/classify/rules/textinput/ItemSelectionInputDoesNotContainAtLeastOneOfRuleClassifierProviderTest.kt", - ], - test_class = "org.oppia.android.domain.classify.rules.textinput.ItemSelectionInputDoesNotContainAtLeastOneOfRuleClassifierProviderTest", - deps = TEST_DEPS, -) - domain_test( name = "TextInputEqualsRuleClassifierProviderTest", srcs = [ @@ -429,13 +456,6 @@ domain_test( deps = TEST_DEPS, ) -domain_test( - name = "StoryProgressTestHelperTest", - srcs = ["src/test/java/org/oppia/android/domain/topic/StoryProgressTestHelperTest.kt"], - test_class = "org.oppia.android.domain.topic.StoryProgressTestHelperTest", - deps = TEST_DEPS, -) - domain_test( name = "TopicControllerTest", srcs = ["src/test/java/org/oppia/android/domain/topic/TopicControllerTest.kt"], diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputHasDenominatorEqualToRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputHasDenominatorEqualToRuleClassifierProvider.kt index 920d80da61f..0e64186bf88 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputHasDenominatorEqualToRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputHasDenominatorEqualToRuleClassifierProvider.kt @@ -13,7 +13,8 @@ import javax.inject.Inject * * https://github.com/oppia/oppia/blob/37285a/extensions/interactions/FractionInput/directives/fraction-input-rules.service.ts#L55 */ -internal class FractionInputHasDenominatorEqualToRuleClassifierProvider @Inject constructor( +// TODO(#1580): Re-restrict access using Bazel visibilities +class FractionInputHasDenominatorEqualToRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.MultiTypeSingleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputHasFractionalPartExactlyEqualToRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputHasFractionalPartExactlyEqualToRuleClassifierProvider.kt index abd7a5e524d..0cf0436d126 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputHasFractionalPartExactlyEqualToRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputHasFractionalPartExactlyEqualToRuleClassifierProvider.kt @@ -13,7 +13,8 @@ import javax.inject.Inject * * https://github.com/oppia/oppia/blob/37285a/extensions/interactions/FractionInput/directives/fraction-input-rules.service.ts#L61 */ -internal class FractionInputHasFractionalPartExactlyEqualToRuleClassifierProvider +// TODO(#1580): Re-restrict access using Bazel visibilities +class FractionInputHasFractionalPartExactlyEqualToRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.SingleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputHasIntegerPartEqualToRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputHasIntegerPartEqualToRuleClassifierProvider.kt index d24052e7e67..936de86e002 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputHasIntegerPartEqualToRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputHasIntegerPartEqualToRuleClassifierProvider.kt @@ -13,7 +13,8 @@ import javax.inject.Inject * * https://github.com/oppia/oppia/blob/37285a/extensions/interactions/FractionInput/directives/fraction-input-rules.service.ts#L48 */ -internal class FractionInputHasIntegerPartEqualToRuleClassifierProvider @Inject constructor( +// TODO(#1580): Re-restrict access using Bazel visibilities +class FractionInputHasIntegerPartEqualToRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.MultiTypeSingleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputHasNoFractionalPartRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputHasNoFractionalPartRuleClassifierProvider.kt index 53be10e46a0..58f9c867e79 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputHasNoFractionalPartRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputHasNoFractionalPartRuleClassifierProvider.kt @@ -13,7 +13,8 @@ import javax.inject.Inject * * https://github.com/oppia/oppia/blob/37285a/extensions/interactions/FractionInput/directives/fraction-input-rules.service.ts#L58 */ -internal class FractionInputHasNoFractionalPartRuleClassifierProvider @Inject constructor( +// TODO(#1580): Re-restrict access using Bazel visibilities +class FractionInputHasNoFractionalPartRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.NoInputInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputHasNumeratorEqualToRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputHasNumeratorEqualToRuleClassifierProvider.kt index c4b57344f10..6ac6548b17b 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputHasNumeratorEqualToRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputHasNumeratorEqualToRuleClassifierProvider.kt @@ -13,7 +13,8 @@ import javax.inject.Inject * * https://github.com/oppia/oppia/blob/37285a/extensions/interactions/FractionInput/directives/fraction-input-rules.service.ts#L52 */ -internal class FractionInputHasNumeratorEqualToRuleClassifierProvider @Inject constructor( +// TODO(#1580): Re-restrict access using Bazel visibilities +class FractionInputHasNumeratorEqualToRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.MultiTypeSingleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputIsEquivalentToAndInSimplestFormRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputIsEquivalentToAndInSimplestFormRuleClassifierProvider.kt index f4796933679..b9d7669259e 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputIsEquivalentToAndInSimplestFormRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputIsEquivalentToAndInSimplestFormRuleClassifierProvider.kt @@ -16,7 +16,8 @@ import javax.inject.Inject * * https://github.com/oppia/oppia/blob/37285a/extensions/interactions/FractionInput/directives/fraction-input-rules.service.ts#L32 */ -internal class FractionInputIsEquivalentToAndInSimplestFormRuleClassifierProvider +// TODO(#1580): Re-restrict access using Bazel visibilities +class FractionInputIsEquivalentToAndInSimplestFormRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.SingleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputIsEquivalentToRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputIsEquivalentToRuleClassifierProvider.kt index 3f327c293f3..2fb33b8a49e 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputIsEquivalentToRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputIsEquivalentToRuleClassifierProvider.kt @@ -15,7 +15,8 @@ import javax.inject.Inject * * https://github.com/oppia/oppia/blob/37285a/extensions/interactions/FractionInput/directives/fraction-input-rules.service.ts#L29 */ -internal class FractionInputIsEquivalentToRuleClassifierProvider @Inject constructor( +// TODO(#1580): Re-restrict access using Bazel visibilities +class FractionInputIsEquivalentToRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.SingleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputIsExactlyEqualToRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputIsExactlyEqualToRuleClassifierProvider.kt index f6bf11e37c6..6d598462f21 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputIsExactlyEqualToRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputIsExactlyEqualToRuleClassifierProvider.kt @@ -13,7 +13,8 @@ import javax.inject.Inject * * https://github.com/oppia/oppia/blob/37285a/extensions/interactions/FractionInput/directives/fraction-input-rules.service.ts#L38 */ -internal class FractionInputIsExactlyEqualToRuleClassifierProvider @Inject constructor( +// TODO(#1580): Re-restrict access using Bazel visibilities +class FractionInputIsExactlyEqualToRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.SingleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputIsGreaterThanRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputIsGreaterThanRuleClassifierProvider.kt index 7f6134b77c2..b97634272a6 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputIsGreaterThanRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputIsGreaterThanRuleClassifierProvider.kt @@ -14,7 +14,8 @@ import javax.inject.Inject * * https://github.com/oppia/oppia/blob/37285a/extensions/interactions/FractionInput/directives/fraction-input-rules.service.ts#L45 */ -internal class FractionInputIsGreaterThanRuleClassifierProvider @Inject constructor( +// TODO(#1580): Re-restrict access using Bazel visibilities +class FractionInputIsGreaterThanRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.SingleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputIsLessThanRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputIsLessThanRuleClassifierProvider.kt index 2af4756865e..7daa45360ee 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputIsLessThanRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/fractioninput/FractionInputIsLessThanRuleClassifierProvider.kt @@ -14,7 +14,8 @@ import javax.inject.Inject * * https://github.com/oppia/oppia/blob/37285a/extensions/interactions/FractionInput/directives/fraction-input-rules.service.ts#L42 */ -internal class FractionInputIsLessThanRuleClassifierProvider @Inject constructor( +// TODO(#1580): Re-restrict access using Bazel visibilities +class FractionInputIsLessThanRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.SingleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/itemselectioninput/ItemSelectionInputContainsAtLeastOneOfRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/itemselectioninput/ItemSelectionInputContainsAtLeastOneOfRuleClassifierProvider.kt index ccecf8cf291..970e1a039c2 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/itemselectioninput/ItemSelectionInputContainsAtLeastOneOfRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/itemselectioninput/ItemSelectionInputContainsAtLeastOneOfRuleClassifierProvider.kt @@ -13,7 +13,8 @@ import javax.inject.Inject * * https://github.com/oppia/oppia/blob/37285a/extensions/interactions/ItemSelectionInput/directives/item-selection-input-rules.service.ts#L32 */ -internal class ItemSelectionInputContainsAtLeastOneOfRuleClassifierProvider @Inject constructor( +// TODO(#1580): Re-restrict access using Bazel visibilities +class ItemSelectionInputContainsAtLeastOneOfRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.SingleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/itemselectioninput/ItemSelectionInputDoesNotContainAtLeastOneOfRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/itemselectioninput/ItemSelectionInputDoesNotContainAtLeastOneOfRuleClassifierProvider.kt index d832f865683..b463656e257 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/itemselectioninput/ItemSelectionInputDoesNotContainAtLeastOneOfRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/itemselectioninput/ItemSelectionInputDoesNotContainAtLeastOneOfRuleClassifierProvider.kt @@ -13,7 +13,8 @@ import javax.inject.Inject * * https://github.com/oppia/oppia/blob/37285a/extensions/interactions/ItemSelectionInput/directives/item-selection-input-rules.service.ts#L41 */ -internal class ItemSelectionInputDoesNotContainAtLeastOneOfRuleClassifierProvider +// TODO(#1580): Re-restrict access using Bazel visibilities +class ItemSelectionInputDoesNotContainAtLeastOneOfRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.SingleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/itemselectioninput/ItemSelectionInputEqualsRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/itemselectioninput/ItemSelectionInputEqualsRuleClassifierProvider.kt index 4323babbcbf..2a0be24f078 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/itemselectioninput/ItemSelectionInputEqualsRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/itemselectioninput/ItemSelectionInputEqualsRuleClassifierProvider.kt @@ -13,7 +13,8 @@ import javax.inject.Inject * * https://github.com/oppia/oppia/blob/37285a/extensions/interactions/ItemSelectionInput/directives/item-selection-input-rules.service.ts#L24 */ -internal class ItemSelectionInputEqualsRuleClassifierProvider @Inject constructor( +// TODO(#1580): Re-restrict access using Bazel visibilities +class ItemSelectionInputEqualsRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.SingleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/itemselectioninput/ItemSelectionInputIsProperSubsetOfRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/itemselectioninput/ItemSelectionInputIsProperSubsetOfRuleClassifierProvider.kt index fd0b82bfdca..6be952bf6a3 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/itemselectioninput/ItemSelectionInputIsProperSubsetOfRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/itemselectioninput/ItemSelectionInputIsProperSubsetOfRuleClassifierProvider.kt @@ -13,7 +13,8 @@ import javax.inject.Inject * * https://github.com/oppia/oppia/blob/37285a/extensions/interactions/ItemSelectionInput/directives/item-selection-input-rules.service.ts#L50 */ -internal class ItemSelectionInputIsProperSubsetOfRuleClassifierProvider @Inject constructor( +// TODO(#1580): Re-restrict access using Bazel visibilities +class ItemSelectionInputIsProperSubsetOfRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.SingleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/numberwithunits/NumberWithUnitsIsEqualToRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/numberwithunits/NumberWithUnitsIsEqualToRuleClassifierProvider.kt index 2d041af1383..b9c3fc9647f 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/numberwithunits/NumberWithUnitsIsEqualToRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/numberwithunits/NumberWithUnitsIsEqualToRuleClassifierProvider.kt @@ -15,7 +15,8 @@ import javax.inject.Inject * * https://github.com/oppia/oppia/blob/37285a/extensions/interactions/NumberWithUnits/directives/number-with-units-rules.service.ts#L34 */ -internal class NumberWithUnitsIsEqualToRuleClassifierProvider @Inject constructor( +// TODO(#1580): Re-restrict access using Bazel visibilities +class NumberWithUnitsIsEqualToRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.SingleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/numberwithunits/NumberWithUnitsIsEquivalentToRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/numberwithunits/NumberWithUnitsIsEquivalentToRuleClassifierProvider.kt index e5d66332c9d..2572709908f 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/numberwithunits/NumberWithUnitsIsEquivalentToRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/numberwithunits/NumberWithUnitsIsEquivalentToRuleClassifierProvider.kt @@ -15,7 +15,8 @@ import javax.inject.Inject * * https://github.com/oppia/oppia/blob/37285a/extensions/interactions/NumberWithUnits/directives/number-with-units-rules.service.ts#L48 */ -internal class NumberWithUnitsIsEquivalentToRuleClassifierProvider @Inject constructor( +// TODO(#1580): Re-restrict access using Bazel visibilities +class NumberWithUnitsIsEquivalentToRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.SingleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/numericinput/NumericInputIsGreaterThanOrEqualToRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/numericinput/NumericInputIsGreaterThanOrEqualToRuleClassifierProvider.kt index 6416890a774..b6b2d3877af 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/numericinput/NumericInputIsGreaterThanOrEqualToRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/numericinput/NumericInputIsGreaterThanOrEqualToRuleClassifierProvider.kt @@ -11,7 +11,8 @@ import javax.inject.Inject * * https://github.com/oppia/oppia/blob/37285a/extensions/interactions/NumericInput/directives/numeric-input-rules.service.ts#L33 */ -internal class NumericInputIsGreaterThanOrEqualToRuleClassifierProvider @Inject constructor( +// TODO(#1580): Re-restrict access using Bazel visibilities +class NumericInputIsGreaterThanOrEqualToRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.SingleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/numericinput/NumericInputIsGreaterThanRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/numericinput/NumericInputIsGreaterThanRuleClassifierProvider.kt index 981f9064ae5..d1980129de1 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/numericinput/NumericInputIsGreaterThanRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/numericinput/NumericInputIsGreaterThanRuleClassifierProvider.kt @@ -11,7 +11,8 @@ import javax.inject.Inject * * https://github.com/oppia/oppia/blob/37285a/extensions/interactions/NumericInput/directives/numeric-input-rules.service.ts#L27 */ -internal class NumericInputIsGreaterThanRuleClassifierProvider @Inject constructor( +// TODO(#1580): Re-restrict access using Bazel visibilities +class NumericInputIsGreaterThanRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.SingleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/numericinput/NumericInputIsInclusivelyBetweenRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/numericinput/NumericInputIsInclusivelyBetweenRuleClassifierProvider.kt index 3205c34c470..942f774aeee 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/numericinput/NumericInputIsInclusivelyBetweenRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/numericinput/NumericInputIsInclusivelyBetweenRuleClassifierProvider.kt @@ -12,7 +12,8 @@ import javax.inject.Inject * * https://github.com/oppia/oppia/blob/37285a/extensions/interactions/NumericInput/directives/numeric-input-rules.service.ts#L36 */ -internal class NumericInputIsInclusivelyBetweenRuleClassifierProvider @Inject constructor( +// TODO(#1580): Re-restrict access using Bazel visibilities +class NumericInputIsInclusivelyBetweenRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.DoubleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/numericinput/NumericInputIsLessThanOrEqualToRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/numericinput/NumericInputIsLessThanOrEqualToRuleClassifierProvider.kt index 5685ae912be..122139a32c2 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/numericinput/NumericInputIsLessThanOrEqualToRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/numericinput/NumericInputIsLessThanOrEqualToRuleClassifierProvider.kt @@ -11,7 +11,8 @@ import javax.inject.Inject * * https://github.com/oppia/oppia/blob/37285a/extensions/interactions/NumericInput/directives/numeric-input-rules.service.ts#L30 */ -internal class NumericInputIsLessThanOrEqualToRuleClassifierProvider @Inject constructor( +// TODO(#1580): Re-restrict access using Bazel visibilities +class NumericInputIsLessThanOrEqualToRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.SingleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/numericinput/NumericInputIsLessThanRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/numericinput/NumericInputIsLessThanRuleClassifierProvider.kt index 2d737b89b3a..dfef211d916 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/numericinput/NumericInputIsLessThanRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/numericinput/NumericInputIsLessThanRuleClassifierProvider.kt @@ -11,7 +11,8 @@ import javax.inject.Inject * * https://github.com/oppia/oppia/blob/37285a/extensions/interactions/NumericInput/directives/numeric-input-rules.service.ts#L24 */ -internal class NumericInputIsLessThanRuleClassifierProvider @Inject constructor( +// TODO(#1580): Re-restrict access using Bazel visibilities +class NumericInputIsLessThanRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.SingleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/numericinput/NumericInputIsWithinToleranceRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/numericinput/NumericInputIsWithinToleranceRuleClassifierProvider.kt index 3097fe02137..63c38aa8116 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/numericinput/NumericInputIsWithinToleranceRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/numericinput/NumericInputIsWithinToleranceRuleClassifierProvider.kt @@ -12,7 +12,8 @@ import javax.inject.Inject * * https://github.com/oppia/oppia/blob/37285a/extensions/interactions/NumericInput/directives/numeric-input-rules.service.ts#L41 */ -internal class NumericInputIsWithinToleranceRuleClassifierProvider @Inject constructor( +// TODO(#1580): Re-restrict access using Bazel visibilities +class NumericInputIsWithinToleranceRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.DoubleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/ratioinput/RatioInputEqualsRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/ratioinput/RatioInputEqualsRuleClassifierProvider.kt index e27bb871863..cd25fb88cbf 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/ratioinput/RatioInputEqualsRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/ratioinput/RatioInputEqualsRuleClassifierProvider.kt @@ -11,7 +11,8 @@ import javax.inject.Inject * Provider for a classifier that determines whether two object are equal per the ratio input * interaction. */ -internal class RatioInputEqualsRuleClassifierProvider @Inject constructor( +// TODO(#1580): Re-restrict access using Bazel visibilities +class RatioInputEqualsRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.SingleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/ratioinput/RatioInputHasNumberOfTermsEqualToClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/ratioinput/RatioInputHasNumberOfTermsEqualToClassifierProvider.kt index e7428765bdf..ef0697a3b68 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/ratioinput/RatioInputHasNumberOfTermsEqualToClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/ratioinput/RatioInputHasNumberOfTermsEqualToClassifierProvider.kt @@ -10,7 +10,8 @@ import javax.inject.Inject /** * Provider for a classifier that determines whether two object have an equal number of terms. */ -internal class RatioInputHasNumberOfTermsEqualToClassifierProvider @Inject constructor( +// TODO(#1580): Re-restrict access using Bazel visibilities +class RatioInputHasNumberOfTermsEqualToClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.MultiTypeSingleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/ratioinput/RatioInputIsEquivalentRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/ratioinput/RatioInputIsEquivalentRuleClassifierProvider.kt index 2c6f24b7b52..3cdf2010e15 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/ratioinput/RatioInputIsEquivalentRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/ratioinput/RatioInputIsEquivalentRuleClassifierProvider.kt @@ -12,7 +12,8 @@ import javax.inject.Inject * Provider for a classifier that determines whether two object are equal by converting them into * their lowest form as per the ratio input interaction. */ -internal class RatioInputIsEquivalentRuleClassifierProvider @Inject constructor( +// TODO(#1580): Re-restrict access using Bazel visibilities +class RatioInputIsEquivalentRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.SingleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/textinput/TextInputCaseSensitiveEqualsRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/textinput/TextInputCaseSensitiveEqualsRuleClassifierProvider.kt index 61646b51790..ac9245f0ab3 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/textinput/TextInputCaseSensitiveEqualsRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/textinput/TextInputCaseSensitiveEqualsRuleClassifierProvider.kt @@ -13,7 +13,8 @@ import javax.inject.Inject * * https://github.com/oppia/oppia/blob/37285a/extensions/interactions/TextInput/directives/text-input-rules.service.ts#L59 */ -internal class TextInputCaseSensitiveEqualsRuleClassifierProvider @Inject constructor( +// TODO(#1580): Re-restrict access using Bazel visibilities +class TextInputCaseSensitiveEqualsRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.SingleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/textinput/TextInputFuzzyEqualsRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/textinput/TextInputFuzzyEqualsRuleClassifierProvider.kt index 7cef1505cdb..45a840cf78f 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/textinput/TextInputFuzzyEqualsRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/textinput/TextInputFuzzyEqualsRuleClassifierProvider.kt @@ -12,7 +12,8 @@ import javax.inject.Inject * * https://github.com/oppia/oppia/blob/37285a/extensions/interactions/TextInput/directives/text-input-rules.service.ts#L29. */ -internal class TextInputFuzzyEqualsRuleClassifierProvider @Inject constructor( +// TODO(#1580): Re-restrict access using Bazel visibilities +class TextInputFuzzyEqualsRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.SingleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/classify/rules/textinput/TextInputStartsWithRuleClassifierProvider.kt b/domain/src/main/java/org/oppia/android/domain/classify/rules/textinput/TextInputStartsWithRuleClassifierProvider.kt index e1bf898eca2..5c7869994d9 100644 --- a/domain/src/main/java/org/oppia/android/domain/classify/rules/textinput/TextInputStartsWithRuleClassifierProvider.kt +++ b/domain/src/main/java/org/oppia/android/domain/classify/rules/textinput/TextInputStartsWithRuleClassifierProvider.kt @@ -13,7 +13,8 @@ import javax.inject.Inject * * https://github.com/oppia/oppia/blob/37285a/extensions/interactions/TextInput/directives/text-input-rules.service.ts#L64 */ -internal class TextInputStartsWithRuleClassifierProvider @Inject constructor( +// TODO(#1580): Re-restrict access using Bazel visibilities +class TextInputStartsWithRuleClassifierProvider @Inject constructor( private val classifierFactory: GenericRuleClassifier.Factory ) : RuleClassifierProvider, GenericRuleClassifier.SingleInputMatcher { diff --git a/domain/src/main/java/org/oppia/android/domain/testing/oppialogger/loguploader/FakeLogUploader.kt b/domain/src/main/java/org/oppia/android/domain/testing/oppialogger/loguploader/FakeLogUploader.kt new file mode 100644 index 00000000000..b2a02324827 --- /dev/null +++ b/domain/src/main/java/org/oppia/android/domain/testing/oppialogger/loguploader/FakeLogUploader.kt @@ -0,0 +1,35 @@ +package org.oppia.android.domain.testing.oppialogger.loguploader + +import androidx.work.PeriodicWorkRequest +import androidx.work.WorkManager +import org.oppia.android.util.logging.LogUploader +import java.util.UUID +import javax.inject.Inject +import javax.inject.Singleton + +/** A test specific fake for the log uploader. */ +@Singleton +class FakeLogUploader @Inject constructor() : LogUploader { + private val eventRequestIdList = mutableListOf() + private val exceptionRequestIdList = mutableListOf() + + override fun enqueueWorkRequestForEvents( + workManager: WorkManager, + workRequest: PeriodicWorkRequest + ) { + eventRequestIdList.add(workRequest.id) + } + + override fun enqueueWorkRequestForExceptions( + workManager: WorkManager, + workRequest: PeriodicWorkRequest + ) { + exceptionRequestIdList.add(workRequest.id) + } + + /** Returns the most recent work request id that's stored in the [eventRequestIdList]. */ + fun getMostRecentEventRequestId() = eventRequestIdList.last() + + /** Returns the most recent work request id that's stored in the [exceptionRequestIdList]. */ + fun getMostRecentExceptionRequestId() = exceptionRequestIdList.last() +} diff --git a/domain/src/test/java/org/oppia/android/domain/oppialogger/OppiaLoggerTest.kt b/domain/src/test/java/org/oppia/android/domain/oppialogger/OppiaLoggerTest.kt index 03807c911a5..9f591202db4 100644 --- a/domain/src/test/java/org/oppia/android/domain/oppialogger/OppiaLoggerTest.kt +++ b/domain/src/test/java/org/oppia/android/domain/oppialogger/OppiaLoggerTest.kt @@ -13,13 +13,6 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.oppia.android.app.model.EventLog -import org.oppia.android.domain.oppialogger.analytics.TEST_EXPLORATION_ID -import org.oppia.android.domain.oppialogger.analytics.TEST_QUESTION_ID -import org.oppia.android.domain.oppialogger.analytics.TEST_SKILL_ID -import org.oppia.android.domain.oppialogger.analytics.TEST_SKILL_LIST_ID -import org.oppia.android.domain.oppialogger.analytics.TEST_STORY_ID -import org.oppia.android.domain.oppialogger.analytics.TEST_SUB_TOPIC_ID -import org.oppia.android.domain.oppialogger.analytics.TEST_TOPIC_ID import org.oppia.android.testing.RobolectricModule import org.oppia.android.testing.TestDispatcherModule import org.oppia.android.testing.TestLogReportingModule @@ -33,6 +26,14 @@ import org.robolectric.annotation.LooperMode import javax.inject.Inject import javax.inject.Singleton +private const val TEST_TOPIC_ID = "test_topicId" +private const val TEST_STORY_ID = "test_storyId" +private const val TEST_EXPLORATION_ID = "test_explorationId" +private const val TEST_QUESTION_ID = "test_questionId" +private const val TEST_SKILL_ID = "test_skillId" +private const val TEST_SKILL_LIST_ID = "test_skillListId" +private const val TEST_SUB_TOPIC_ID = 1 + @RunWith(AndroidJUnit4::class) @LooperMode(LooperMode.Mode.PAUSED) @Config(manifest = Config.NONE) diff --git a/domain/src/test/java/org/oppia/android/domain/oppialogger/analytics/AnalyticsControllerTest.kt b/domain/src/test/java/org/oppia/android/domain/oppialogger/analytics/AnalyticsControllerTest.kt index 3b45bf92e98..c7b96930266 100644 --- a/domain/src/test/java/org/oppia/android/domain/oppialogger/analytics/AnalyticsControllerTest.kt +++ b/domain/src/test/java/org/oppia/android/domain/oppialogger/analytics/AnalyticsControllerTest.kt @@ -54,14 +54,14 @@ import org.robolectric.annotation.LooperMode import javax.inject.Inject import javax.inject.Singleton -const val TEST_TIMESTAMP = 1556094120000 -const val TEST_TOPIC_ID = "test_topicId" -const val TEST_STORY_ID = "test_storyId" -const val TEST_EXPLORATION_ID = "test_explorationId" -const val TEST_QUESTION_ID = "test_questionId" -const val TEST_SKILL_ID = "test_skillId" -const val TEST_SKILL_LIST_ID = "test_skillListId" -const val TEST_SUB_TOPIC_ID = 1 +private const val TEST_TIMESTAMP = 1556094120000 +private const val TEST_TOPIC_ID = "test_topicId" +private const val TEST_STORY_ID = "test_storyId" +private const val TEST_EXPLORATION_ID = "test_explorationId" +private const val TEST_QUESTION_ID = "test_questionId" +private const val TEST_SKILL_ID = "test_skillId" +private const val TEST_SKILL_LIST_ID = "test_skillListId" +private const val TEST_SUB_TOPIC_ID = 1 @RunWith(AndroidJUnit4::class) @LooperMode(LooperMode.Mode.PAUSED) diff --git a/domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkManagerInitializerTest.kt b/domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkManagerInitializerTest.kt index dea0334695a..e4a7a40f1c0 100644 --- a/domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkManagerInitializerTest.kt +++ b/domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkManagerInitializerTest.kt @@ -9,8 +9,6 @@ import androidx.work.Configuration import androidx.work.Constraints import androidx.work.Data import androidx.work.NetworkType -import androidx.work.PeriodicWorkRequest -import androidx.work.WorkManager import androidx.work.testing.SynchronousExecutor import androidx.work.testing.WorkManagerTestInitHelper import com.google.common.truth.Truth.assertThat @@ -25,8 +23,8 @@ import org.junit.runner.RunWith import org.oppia.android.domain.oppialogger.EventLogStorageCacheSize import org.oppia.android.domain.oppialogger.ExceptionLogStorageCacheSize import org.oppia.android.domain.oppialogger.OppiaLogger -import org.oppia.android.domain.oppialogger.analytics.AnalyticsController import org.oppia.android.domain.oppialogger.exceptions.ExceptionsController +import org.oppia.android.domain.testing.oppialogger.loguploader.FakeLogUploader import org.oppia.android.testing.FakeEventLogger import org.oppia.android.testing.FakeExceptionLogger import org.oppia.android.testing.RobolectricModule @@ -43,10 +41,8 @@ import org.oppia.android.util.logging.LogUploader import org.oppia.android.util.networking.NetworkConnectionUtil import org.robolectric.annotation.Config import org.robolectric.annotation.LooperMode -import java.util.UUID import javax.inject.Inject import javax.inject.Singleton -import kotlin.collections.last @RunWith(AndroidJUnit4::class) @LooperMode(LooperMode.Mode.PAUSED) @@ -59,9 +55,6 @@ class LogUploadWorkManagerInitializerTest { @Inject lateinit var logUploadWorkManagerInitializer: LogUploadWorkManagerInitializer - @Inject - lateinit var analyticsController: AnalyticsController - @Inject lateinit var exceptionsController: ExceptionsController @@ -227,32 +220,3 @@ class LogUploadWorkManagerInitializerTest { fun inject(logUploadWorkRequestTest: LogUploadWorkManagerInitializerTest) } } - -/** A test specific fake for the log uploader. */ -@Singleton -class FakeLogUploader @Inject constructor() : - LogUploader { - - private val eventRequestIdList = mutableListOf() - private val exceptionRequestIdList = mutableListOf() - - override fun enqueueWorkRequestForEvents( - workManager: WorkManager, - workRequest: PeriodicWorkRequest - ) { - eventRequestIdList.add(workRequest.id) - } - - override fun enqueueWorkRequestForExceptions( - workManager: WorkManager, - workRequest: PeriodicWorkRequest - ) { - exceptionRequestIdList.add(workRequest.id) - } - - /** Returns the most recent work request id that's stored in the [eventRequestIdList]. */ - fun getMostRecentEventRequestId() = eventRequestIdList.last() - - /** Returns the most recent work request id that's stored in the [exceptionRequestIdList]. */ - fun getMostRecentExceptionRequestId() = exceptionRequestIdList.last() -} diff --git a/domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkerTest.kt b/domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkerTest.kt index 791f6c9d96e..9bc3bc3bf0b 100644 --- a/domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkerTest.kt +++ b/domain/src/test/java/org/oppia/android/domain/oppialogger/loguploader/LogUploadWorkerTest.kt @@ -27,9 +27,8 @@ import org.oppia.android.domain.oppialogger.EventLogStorageCacheSize import org.oppia.android.domain.oppialogger.ExceptionLogStorageCacheSize import org.oppia.android.domain.oppialogger.OppiaLogger import org.oppia.android.domain.oppialogger.analytics.AnalyticsController -import org.oppia.android.domain.oppialogger.analytics.TEST_TIMESTAMP -import org.oppia.android.domain.oppialogger.analytics.TEST_TOPIC_ID import org.oppia.android.domain.oppialogger.exceptions.ExceptionsController +import org.oppia.android.domain.testing.oppialogger.loguploader.FakeLogUploader import org.oppia.android.testing.FakeEventLogger import org.oppia.android.testing.FakeExceptionLogger import org.oppia.android.testing.RobolectricModule @@ -49,6 +48,9 @@ import org.robolectric.annotation.LooperMode import javax.inject.Inject import javax.inject.Singleton +private const val TEST_TIMESTAMP = 1556094120000 +private const val TEST_TOPIC_ID = "test_topicId" + @RunWith(AndroidJUnit4::class) @LooperMode(LooperMode.Mode.PAUSED) @Config(manifest = Config.NONE) @@ -157,13 +159,32 @@ class LogUploadWorkerTest { .build() workManager.enqueue(request) testCoroutineDispatchers.runCurrent() - val workInfo = workManager.getWorkInfoById(request.id) - val exceptionGot = fakeExceptionLogger.getMostRecentException() + val workInfo = workManager.getWorkInfoById(request.id) + val loggedException = fakeExceptionLogger.getMostRecentException() + val loggedExceptionStackTraceElems = loggedException.stackTrace.extractRelevantDetails() + val expectedExceptionStackTraceElems = exception.stackTrace.extractRelevantDetails() assertThat(workInfo.get().state).isEqualTo(WorkInfo.State.SUCCEEDED) - assertThat(exceptionGot.message).isEqualTo("TEST") - assertThat(exceptionGot.stackTrace).isEqualTo(exception.stackTrace) - assertThat(exceptionGot.cause).isEqualTo(null) + assertThat(loggedException.message).isEqualTo("TEST") + assertThat(loggedException.cause).isEqualTo(null) + // The following can't be an exact match for the stack trace since new properties are added to + // stack trace elements in newer versions of Java (such as module name). + assertThat(loggedExceptionStackTraceElems).isEqualTo(expectedExceptionStackTraceElems) + } + + /** + * Returns a list of lists of each relevant element of a [StackTraceElement] to be used for + * comparison in a way that's consistent across JDK versions. + */ + private fun Array.extractRelevantDetails(): List> { + return this.map { element -> + return@map listOf( + element.fileName, + element.methodName, + element.lineNumber, + element.className + ) + } } private fun setUpTestApplicationComponent() { diff --git a/scripts/compute_affected_tests.sh b/scripts/compute_affected_tests.sh new file mode 100755 index 00000000000..e264b37d824 --- /dev/null +++ b/scripts/compute_affected_tests.sh @@ -0,0 +1,77 @@ +#!/bin/bash + +# Compute the list of tests that are affected by changes on this branch (including in the working +# directory). This script is useful to verify that only the tests that could break due to a change +# are actually verified as passing. Note that this script does not actually run any of the tests. +# +# Usage: +# bash scripts/compute_affected_tests.sh +# +# This script is based on https://github.com/bazelbuild/bazel/blob/d96e1cd/scripts/ci/ci.sh and the +# documentation at https://docs.bazel.build/versions/master/query.html. Note that this script will +# automatically list all tests if it's run on the develop branch (the idea being that test +# considerations on the develop branch should always consider all targets). + +BAZEL_BINARY=$1 + +# Reference: https://stackoverflow.com/a/6245587. +current_branch=$(git branch --show-current) + +if [[ "$current_branch" != "develop" ]]; then + # Compute all files that have been changed on this branch. https://stackoverflow.com/a/9294015 for + # constructing the arrays. + commit_range=HEAD..$(git merge-base origin/develop HEAD) + changed_committed_files=($(git diff --name-only $commit_range)) + changed_staged_files=($(git diff --name-only --cached)) + changed_unstaged_files=($(git diff --name-only)) + # See https://stackoverflow.com/a/35484355 for how this works. + changed_untracked_files=($(git ls-files --others --exclude-standard)) + + changed_files_with_potential_duplicates=( + "${changed_committed_files[@]}" + "${changed_staged_files[@]}" + "${changed_unstaged_files[@]}" + "${changed_untracked_files[@]}" + ) + + # De-duplicate files: https://unix.stackexchange.com/q/377812. + changed_files=($(printf "%s\n" "${changed_files_with_potential_duplicates[@]}" | sort -u)) + + # Filter all of the source files among those that are actually included in Bazel builds. + changed_bazel_files=() + for changed_file in "${changed_files[@]}"; do + changed_bazel_files+=($($BAZEL_BINARY query --noshow_progress $changed_file 2> /dev/null)) + done + + # Compute the list of affected tests based on source files. + source_affected_targets="$($BAZEL_BINARY query --noshow_progress --universe_scope=//... --order_output=no "kind(test, allrdeps(set(${changed_bazel_files[@]})))" 2>/dev/null)" + + # Compute the list of files to consider for BUILD-level changes (this uses the base file list as a + # reference since Bazel's query won't find matching targets for utility bzl files that can still + # affect the build). https://stackoverflow.com/a/44107086 for reference on changing case matching. + shopt -s nocasematch + changed_bazel_support_files=() + for changed_file in "${changed_files[@]}"; do + if [[ "$changed_file" =~ ^.+?\.bazel$ ]] || [[ "$changed_file" =~ ^.+?\.bzl$ ]] || [[ "$changed_file" == "WORKSPACE" ]]; then + changed_bazel_support_files+=("$changed_file") + fi + done + shopt -u nocasematch + + # Compute the list of affected tests based on BUILD/Bazel/WORKSPACE files. These are generally + # framed as: if a BUILD file changes, run all tests transitively connected to it. + # Reference for joining an array to string: https://stackoverflow.com/a/53839433. + printf -v changed_bazel_support_files_list '%s,' "${changed_bazel_support_files[@]}" + build_affected_targets=$($BAZEL_BINARY query --noshow_progress --universe_scope=//... --order_output=no "filter('^[^@]', kind(test, allrdeps(siblings(rbuildfiles(${changed_bazel_support_files_list%,})))))" 2>/dev/null) + + all_affected_targets_with_potential_duplicated=( + "${source_affected_targets[@]}" + "${build_affected_targets[@]}" + ) + + # Print all of the affected targets without duplicates. + printf "%s\n" "${all_affected_targets_with_potential_duplicated[@]}" | sort -u +else + # Print all test targets. + $BAZEL_BINARY query --noshow_progress "kind(test, //...)" 2>/dev/null +fi diff --git a/testing/BUILD.bazel b/testing/BUILD.bazel index 25fd4736b7e..2ad57cd6a11 100644 --- a/testing/BUILD.bazel +++ b/testing/BUILD.bazel @@ -11,6 +11,7 @@ load("//testing:testing_test.bzl", "testing_test") # Library for general-purpose testing fakes. kt_android_library( name = "testing", + testonly = True, srcs = glob(["src/main/java/org/oppia/android/testing/**/*.kt"]), custom_package = "org.oppia.android.testing", manifest = "src/main/AndroidManifest.xml", @@ -26,6 +27,7 @@ kt_android_library( "//third_party:androidx_test_runner", "//third_party:com_google_truth_truth", "//third_party:junit_junit", + "//third_party:nl_dionsegijn_konfetti", "//third_party:org_jetbrains_kotlin_kotlin-reflect", "//third_party:org_jetbrains_kotlinx_kotlinx-coroutines-test", "//third_party:org_mockito_mockito-core", @@ -82,6 +84,13 @@ testing_test( deps = TEST_DEPS, ) +testing_test( + name = "StoryProgressTestHelperTest", + srcs = ["src/test/java/org/oppia/android/testing/story/StoryProgressTestHelperTest.kt"], + test_class = "org.oppia.android.testing.story.StoryProgressTestHelperTest", + deps = TEST_DEPS, +) + testing_test( name = "FakeOppiaClockTest", srcs = ["src/test/java/org/oppia/android/testing/time/FakeOppiaClockTest.kt"], diff --git a/third_party/BUILD.bazel b/third_party/BUILD.bazel index 159685a3c55..7fcf410315b 100644 --- a/third_party/BUILD.bazel +++ b/third_party/BUILD.bazel @@ -46,6 +46,7 @@ android_library( android_library( name = "robolectric_android-all", + visibility = ["//visibility:public"], exports = [ "@robolectric//bazel:android-all", ],