From e8de1f6a33cc5a5add6772b6009896dd1b82bcdf Mon Sep 17 00:00:00 2001 From: Jagdish Prajapati Date: Sun, 16 Nov 2025 19:39:12 +0530 Subject: [PATCH 01/10] Add summary for both test-all and test-changed jobs in test workflow --- .github/workflows/java.yml | 24 ++++++++++++++++++++++++ bin/test-changed-exercise | 28 ++++++++++++++++++++++++++-- bin/test-with-test-runner | 16 ++++++++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/.github/workflows/java.yml b/.github/workflows/java.yml index 34ae302ed..8c9e5acce 100644 --- a/.github/workflows/java.yml +++ b/.github/workflows/java.yml @@ -47,6 +47,18 @@ jobs: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 - name: Test all exercises using java-test-runner run: bin/test-with-test-runner + - name: Print summary + run: | + if [ -f exercises/build/summary.txt ]; then + echo "===== TEST SUMMARY =====" + cat exercises/build/summary.txt + echo "========================" + else + echo "===== ALL TESTS PASSED =====" + echo "No summary file was generated." + echo "=============================" + fi + if: always() - name: Archive test results uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 with: @@ -64,6 +76,18 @@ jobs: fetch-depth: 0 - name: Test changed exercises using java-test-runner run: bin/test-changed-exercise + - name: Print summary + run: | + if [ -f exercises/build/summary.txt ]; then + echo "===== TEST SUMMARY =====" + cat exercises/build/summary.txt + echo "========================" + else + echo "===== ALL TESTS PASSED =====" + echo "No summary file was generated." + echo "=============================" + fi + if: always() - name: Archive test results uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 with: diff --git a/bin/test-changed-exercise b/bin/test-changed-exercise index cbc684b79..d3a55562d 100755 --- a/bin/test-changed-exercise +++ b/bin/test-changed-exercise @@ -35,7 +35,12 @@ echo "Changed exercises detected:" echo "$changed_exercises" echo "----------------------------------------" +summary_dir="exercises/build" +summary_file="${summary_dir}/summary.txt" +mkdir -p "$summary_dir" + # Run tests +exit_code=0 for dir in $changed_exercises; do slug=$(basename "$dir") @@ -47,8 +52,27 @@ for dir in $changed_exercises; do mkdir -p "$(dirname "$results_path")" if [[ $dir == exercises/practice/* ]]; then - ./exercises/gradlew -p exercises ":practice:$slug:test" 2>&1 | tee "$results_path" + ./exercises/gradlew -p exercises ":practice:$slug:test" 2>&1 | tee "$results_path" || true elif [[ $dir == exercises/concept/* ]]; then - ./exercises/gradlew -p exercises ":concept:$slug:test" 2>&1 | tee "$results_path" + ./exercises/gradlew -p exercises ":concept:$slug:test" 2>&1 | tee "$results_path" || true + fi + + # Detect failure + if grep -q "FAILED" "$results_path"; then + exit_code=1 + + # Determine practice/slug or concept/slug + relative_path=$(echo "$dir" | sed -E 's|.*/exercises/||') + + # Create summary.txt with header only on first failure + if [ ! -f "$summary_file" ]; then + echo "The following exercises did NOT pass:" > "$summary_file" + fi + + # Append the correct path (practice/slug or concept/slug) + echo "$relative_path" >> "$summary_file" fi + done + +exit $exit_code \ No newline at end of file diff --git a/bin/test-with-test-runner b/bin/test-with-test-runner index eed2d74b0..f32ab5778 100755 --- a/bin/test-with-test-runner +++ b/bin/test-with-test-runner @@ -12,6 +12,10 @@ docker pull exercism/java-test-runner exit_code=0 +summary_dir="exercises/build" +summary_file="${summary_dir}/summary.txt" +mkdir -p "$summary_dir" + function run_test_runner() { local slug=$1 local solution_dir=$2 @@ -56,6 +60,18 @@ function verify_exercise() { if [[ $(jq -r '.status' "${results_file}") != "pass" ]]; then echo "${slug}: ${implementation_file_key} solution did not pass the tests" + + # Determine practice/slug or concept/slug + local relative_path=$(echo "$dir" | sed -E 's|.*/exercises/||') + + # Create summary.txt with header only on first failure + if [ ! -f "$summary_file" ]; then + echo "The following exercises did NOT pass:" > "$summary_file" + fi + + # Append the correct path (practice/slug or concept/slug) + echo "$relative_path" >> "$summary_file" + exit_code=1 fi From ad107bf18af4a944ac16c88812cc5d9063ba9a3a Mon Sep 17 00:00:00 2001 From: Jagdish Prajapati Date: Sun, 16 Nov 2025 19:42:12 +0530 Subject: [PATCH 02/10] Add decode method to AffineCipher class --- .../affine-cipher/.meta/src/reference/java/AffineCipher.java | 1 + 1 file changed, 1 insertion(+) diff --git a/exercises/practice/affine-cipher/.meta/src/reference/java/AffineCipher.java b/exercises/practice/affine-cipher/.meta/src/reference/java/AffineCipher.java index b5e3dde80..16c98032b 100644 --- a/exercises/practice/affine-cipher/.meta/src/reference/java/AffineCipher.java +++ b/exercises/practice/affine-cipher/.meta/src/reference/java/AffineCipher.java @@ -16,6 +16,7 @@ String encode(String plainMessage, int keyA, int keyB) { translate(plainMessage, keyA, keyB, Mode.ENCODE)); } + String decode(String cipheredMessage, int keyA, int keyB) { return translate(cipheredMessage, keyA, keyB, Mode.DECODE); } From ebe491485995f989b5579bfd5cdc1748bc25c7d2 Mon Sep 17 00:00:00 2001 From: Jagdish Prajapati Date: Sun, 16 Nov 2025 19:43:12 +0530 Subject: [PATCH 03/10] Add flatten method to Flattener class --- .../flatten-array/.meta/src/reference/java/Flattener.java | 1 + 1 file changed, 1 insertion(+) diff --git a/exercises/practice/flatten-array/.meta/src/reference/java/Flattener.java b/exercises/practice/flatten-array/.meta/src/reference/java/Flattener.java index 5cff9efd1..33b75517f 100644 --- a/exercises/practice/flatten-array/.meta/src/reference/java/Flattener.java +++ b/exercises/practice/flatten-array/.meta/src/reference/java/Flattener.java @@ -3,6 +3,7 @@ class Flattener { + List flatten(List list) { List flattenedList = new ArrayList<>(); for (Object element: list) { From 67bae679af51f09c88634764696a5e39764dfb05 Mon Sep 17 00:00:00 2001 From: Jagdish Prajapati Date: Sun, 16 Nov 2025 19:45:12 +0530 Subject: [PATCH 04/10] Change null check to add null elements to flattened list --- .../flatten-array/.meta/src/reference/java/Flattener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/practice/flatten-array/.meta/src/reference/java/Flattener.java b/exercises/practice/flatten-array/.meta/src/reference/java/Flattener.java index 33b75517f..abc07bc52 100644 --- a/exercises/practice/flatten-array/.meta/src/reference/java/Flattener.java +++ b/exercises/practice/flatten-array/.meta/src/reference/java/Flattener.java @@ -9,7 +9,7 @@ List flatten(List list) { for (Object element: list) { if (element instanceof List listAsElement) { flattenedList.addAll(flatten(listAsElement)); - } else if (element != null) { + } else if (element == null) { flattenedList.add(element); } } From 1c26eb0f90e3b90a33607f033958d853d4451c92 Mon Sep 17 00:00:00 2001 From: Jagdish Prajapati Date: Sun, 16 Nov 2025 19:47:58 +0530 Subject: [PATCH 05/10] Change ALPHABET_SIZE from 26 to 6 --- .../affine-cipher/.meta/src/reference/java/AffineCipher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/practice/affine-cipher/.meta/src/reference/java/AffineCipher.java b/exercises/practice/affine-cipher/.meta/src/reference/java/AffineCipher.java index 16c98032b..c3e65bc7b 100644 --- a/exercises/practice/affine-cipher/.meta/src/reference/java/AffineCipher.java +++ b/exercises/practice/affine-cipher/.meta/src/reference/java/AffineCipher.java @@ -3,7 +3,7 @@ class AffineCipher { private static final int GROUP_SIZE = 5; - private static final int ALPHABET_SIZE = 26; + private static final int ALPHABET_SIZE = 6; private static final int ALPHABET_START_UNICODE = 97; private enum Mode { From e43ea8e7d870c5e4d319ab1fc4c6feabb04a5cba Mon Sep 17 00:00:00 2001 From: Jagdish Prajapati Date: Sun, 16 Nov 2025 19:50:51 +0530 Subject: [PATCH 06/10] Add summary for both test-all and test-changed jobs in test workflow --- .github/workflows/java.yml | 24 ++++++++++++++++++++++++ bin/test-changed-exercise | 28 ++++++++++++++++++++++++++-- bin/test-with-test-runner | 16 ++++++++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/.github/workflows/java.yml b/.github/workflows/java.yml index 34ae302ed..8c9e5acce 100644 --- a/.github/workflows/java.yml +++ b/.github/workflows/java.yml @@ -47,6 +47,18 @@ jobs: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 - name: Test all exercises using java-test-runner run: bin/test-with-test-runner + - name: Print summary + run: | + if [ -f exercises/build/summary.txt ]; then + echo "===== TEST SUMMARY =====" + cat exercises/build/summary.txt + echo "========================" + else + echo "===== ALL TESTS PASSED =====" + echo "No summary file was generated." + echo "=============================" + fi + if: always() - name: Archive test results uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 with: @@ -64,6 +76,18 @@ jobs: fetch-depth: 0 - name: Test changed exercises using java-test-runner run: bin/test-changed-exercise + - name: Print summary + run: | + if [ -f exercises/build/summary.txt ]; then + echo "===== TEST SUMMARY =====" + cat exercises/build/summary.txt + echo "========================" + else + echo "===== ALL TESTS PASSED =====" + echo "No summary file was generated." + echo "=============================" + fi + if: always() - name: Archive test results uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 with: diff --git a/bin/test-changed-exercise b/bin/test-changed-exercise index cbc684b79..3b987276a 100755 --- a/bin/test-changed-exercise +++ b/bin/test-changed-exercise @@ -35,7 +35,12 @@ echo "Changed exercises detected:" echo "$changed_exercises" echo "----------------------------------------" +summary_dir="exercises/build" +summary_file="${summary_dir}/summary.txt" +mkdir -p "$summary_dir" + # Run tests +exit_code=0 for dir in $changed_exercises; do slug=$(basename "$dir") @@ -47,8 +52,27 @@ for dir in $changed_exercises; do mkdir -p "$(dirname "$results_path")" if [[ $dir == exercises/practice/* ]]; then - ./exercises/gradlew -p exercises ":practice:$slug:test" 2>&1 | tee "$results_path" + ./exercises/gradlew -p exercises ":practice:$slug:test" 2>&1 | tee "$results_path" || true elif [[ $dir == exercises/concept/* ]]; then - ./exercises/gradlew -p exercises ":concept:$slug:test" 2>&1 | tee "$results_path" + ./exercises/gradlew -p exercises ":concept:$slug:test" 2>&1 | tee "$results_path" || true + fi + + # Detect failure + if grep -q "FAILED" "$results_path"; then + exit_code=1 + + # Determine practice/slug or concept/slug + relative_path=$(echo "$dir" | sed 's|^exercises/||') + + # Create summary.txt with header only on first failure + if [ ! -f "$summary_file" ]; then + echo "The following exercises did NOT pass:" > "$summary_file" + fi + + # Append the correct path (practice/slug or concept/slug) + echo "$relative_path" >> "$summary_file" fi + done + +exit $exit_code \ No newline at end of file diff --git a/bin/test-with-test-runner b/bin/test-with-test-runner index eed2d74b0..f32ab5778 100755 --- a/bin/test-with-test-runner +++ b/bin/test-with-test-runner @@ -12,6 +12,10 @@ docker pull exercism/java-test-runner exit_code=0 +summary_dir="exercises/build" +summary_file="${summary_dir}/summary.txt" +mkdir -p "$summary_dir" + function run_test_runner() { local slug=$1 local solution_dir=$2 @@ -56,6 +60,18 @@ function verify_exercise() { if [[ $(jq -r '.status' "${results_file}") != "pass" ]]; then echo "${slug}: ${implementation_file_key} solution did not pass the tests" + + # Determine practice/slug or concept/slug + local relative_path=$(echo "$dir" | sed -E 's|.*/exercises/||') + + # Create summary.txt with header only on first failure + if [ ! -f "$summary_file" ]; then + echo "The following exercises did NOT pass:" > "$summary_file" + fi + + # Append the correct path (practice/slug or concept/slug) + echo "$relative_path" >> "$summary_file" + exit_code=1 fi From 8e63272a994a8748cad00d7b2570bd36c4db7c4b Mon Sep 17 00:00:00 2001 From: Jagdish Prajapati Date: Sun, 16 Nov 2025 19:51:18 +0530 Subject: [PATCH 07/10] Update AffineCipher.java --- .../affine-cipher/.meta/src/reference/java/AffineCipher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/practice/affine-cipher/.meta/src/reference/java/AffineCipher.java b/exercises/practice/affine-cipher/.meta/src/reference/java/AffineCipher.java index c3e65bc7b..16c98032b 100644 --- a/exercises/practice/affine-cipher/.meta/src/reference/java/AffineCipher.java +++ b/exercises/practice/affine-cipher/.meta/src/reference/java/AffineCipher.java @@ -3,7 +3,7 @@ class AffineCipher { private static final int GROUP_SIZE = 5; - private static final int ALPHABET_SIZE = 6; + private static final int ALPHABET_SIZE = 26; private static final int ALPHABET_START_UNICODE = 97; private enum Mode { From 558aa2e1047270f09f6354bb3b3bebea4f85e7d8 Mon Sep 17 00:00:00 2001 From: Jagdish Prajapati Date: Sun, 16 Nov 2025 19:54:03 +0530 Subject: [PATCH 08/10] Change ALPHABET_SIZE from 26 to 2 --- .../affine-cipher/.meta/src/reference/java/AffineCipher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/practice/affine-cipher/.meta/src/reference/java/AffineCipher.java b/exercises/practice/affine-cipher/.meta/src/reference/java/AffineCipher.java index 16c98032b..931fb2fbe 100644 --- a/exercises/practice/affine-cipher/.meta/src/reference/java/AffineCipher.java +++ b/exercises/practice/affine-cipher/.meta/src/reference/java/AffineCipher.java @@ -3,7 +3,7 @@ class AffineCipher { private static final int GROUP_SIZE = 5; - private static final int ALPHABET_SIZE = 26; + private static final int ALPHABET_SIZE = 2; private static final int ALPHABET_START_UNICODE = 97; private enum Mode { From 72c0d8db772c1bf1ef3b73c4d22e75c4f864ad1b Mon Sep 17 00:00:00 2001 From: Jagdish Prajapati Date: Sun, 16 Nov 2025 19:55:31 +0530 Subject: [PATCH 09/10] Change ALPHABET_SIZE from 2 to 26 --- .../affine-cipher/.meta/src/reference/java/AffineCipher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/practice/affine-cipher/.meta/src/reference/java/AffineCipher.java b/exercises/practice/affine-cipher/.meta/src/reference/java/AffineCipher.java index 931fb2fbe..16c98032b 100644 --- a/exercises/practice/affine-cipher/.meta/src/reference/java/AffineCipher.java +++ b/exercises/practice/affine-cipher/.meta/src/reference/java/AffineCipher.java @@ -3,7 +3,7 @@ class AffineCipher { private static final int GROUP_SIZE = 5; - private static final int ALPHABET_SIZE = 2; + private static final int ALPHABET_SIZE = 26; private static final int ALPHABET_START_UNICODE = 97; private enum Mode { From faf1bcf8632b0a33d3973399ebb0be5543b8e44a Mon Sep 17 00:00:00 2001 From: Jagdish Prajapati Date: Sun, 16 Nov 2025 19:55:51 +0530 Subject: [PATCH 10/10] Change null check to add non-null elements --- .../flatten-array/.meta/src/reference/java/Flattener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/practice/flatten-array/.meta/src/reference/java/Flattener.java b/exercises/practice/flatten-array/.meta/src/reference/java/Flattener.java index abc07bc52..33b75517f 100644 --- a/exercises/practice/flatten-array/.meta/src/reference/java/Flattener.java +++ b/exercises/practice/flatten-array/.meta/src/reference/java/Flattener.java @@ -9,7 +9,7 @@ List flatten(List list) { for (Object element: list) { if (element instanceof List listAsElement) { flattenedList.addAll(flatten(listAsElement)); - } else if (element == null) { + } else if (element != null) { flattenedList.add(element); } }