diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index 4104e22..616781a 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -1,4 +1,5 @@ -name: Build +name: Build and Test + on: push: branches: [ master ] @@ -19,3 +20,33 @@ jobs: uses: gradle/actions/setup-gradle@v4 - name: Build with Gradle run: ./gradlew build + + instrumented-tests: + needs: build + runs-on: ubuntu-latest + strategy: + matrix: + locale: ['en-US', 'de-DE', 'es-ES', 'ar-EG'] + steps: + - name: checkout + uses: actions/checkout@v4 + + - name: Set locale properties + id: locale_props + run: | + echo "language=$(echo ${{ matrix.locale }} | cut -d'-' -f1)" >> $GITHUB_OUTPUT + echo "country=$(echo ${{ matrix.locale }} | cut -d'-' -f2)" >> $GITHUB_OUTPUT + + - name: Enable KVM + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + + - name: Run Instrumented Tests for ${{ matrix.locale }} + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: 33 + arch: x86_64 + emulator-options: "-no-window -no-snapshot -prop persist.sys.language=${{ steps.locale_props.outputs.language }} -prop persist.sys.country=${{ steps.locale_props.outputs.country }}" + script: ./gradlew connectedAndroidTest diff --git a/app/src/androidTest/java/atorch/statspuzzles/PuzzleSelectionTest.java b/app/src/androidTest/java/atorch/statspuzzles/PuzzleSelectionTest.java new file mode 100644 index 0000000..785f739 --- /dev/null +++ b/app/src/androidTest/java/atorch/statspuzzles/PuzzleSelectionTest.java @@ -0,0 +1,37 @@ +package atorch.statspuzzles; + +import android.content.Context; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.rules.ActivityScenarioRule; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.espresso.Espresso; +import androidx.test.espresso.assertion.ViewAssertions; +import androidx.test.espresso.matcher.ViewMatchers; +import static androidx.test.espresso.action.ViewActions.click; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class PuzzleSelectionTest { + + @Rule + public ActivityScenarioRule activityRule = + new ActivityScenarioRule<>(PuzzleSelection.class); + + @Test + public void mainActivityLoads() { + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); + Espresso.onView(ViewMatchers.withText(context.getString(R.string.app_name))) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())); + } + + @Test + public void easyPuzzlesButton_loadsEasyPuzzles() { + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); + Espresso.onView(ViewMatchers.withText(context.getString(R.string.button_level_0))).perform(click()); + Espresso.onView(ViewMatchers.withText(context.getString(R.string.puzzle, 1))) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())); + } +} diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index e905209..e4838b4 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -67,7 +67,7 @@ Okay OK - %d/%d gelöst + %1$d/%2$d gelöst Teilen Einstellungen diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 2b09b7b..d64a69f 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -70,7 +70,7 @@ De acuerdo OK - Resueltos %d / %d + Resueltos %1$d / %2$d Compartir Configuración diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3e10612..fb74053 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -70,7 +70,7 @@ Okay OK - solved %d / %d + solved %1$d / %2$d Share Settings diff --git a/app/src/test/java/atorch/statspuzzles/AnswerCheckerTest.java b/app/src/test/java/atorch/statspuzzles/AnswerCheckerTest.java index e2e7d1e..8febe86 100644 --- a/app/src/test/java/atorch/statspuzzles/AnswerCheckerTest.java +++ b/app/src/test/java/atorch/statspuzzles/AnswerCheckerTest.java @@ -9,6 +9,10 @@ public class AnswerCheckerTest { public void testCorrectAnswer() { assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("2+2", "4")); assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("1/2", "0.5")); + assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("3!", "6.0")); + // Note that we have a Result.INACCURATE version of this test as well + assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("1/3", "0.33333333333333")); + assertEquals(AnswerChecker.Result.CORRECT, AnswerChecker.checkAnswer("C(5, 3)", "10")); } @Test @@ -19,11 +23,15 @@ public void testInaccurateAnswer() { @Test public void testIncorrectAnswer() { assertEquals(AnswerChecker.Result.INCORRECT, AnswerChecker.checkAnswer("1", "2")); + // The user's answer is not close enough to be considered merely inaccurate. + assertEquals(AnswerChecker.Result.INCORRECT, AnswerChecker.checkAnswer("1/3", "0.33")); } @Test public void testInvalidAnswer() { assertEquals(AnswerChecker.Result.INVALID, AnswerChecker.checkAnswer("1", "abc")); assertEquals(AnswerChecker.Result.INVALID, AnswerChecker.checkAnswer("1", "")); + // Imbalanced parentheses + assertEquals(AnswerChecker.Result.INVALID, AnswerChecker.checkAnswer("( 1 + 5", "")); } }