From fcd6c35713c74e6ea1fb7a3c17b7f5ee3f18a923 Mon Sep 17 00:00:00 2001 From: Sander Ploegsma Date: Sun, 21 Jan 2024 11:15:18 +0100 Subject: [PATCH 1/4] Refactor exercise unit tests to golden tests --- tests/common/README.md | 4 ++ .../.meta/config.json | 0 .../expected_analysis.json | 8 --- .../expected_tags.json | 0 .../src/main/java/UnknownExercise.java | 5 ++ .../.meta/config.json | 22 ++++++++ .../expected_analysis.json | 0 .../expected_tags.json | 0 .../src/main/java/UnknownExercise.java | 5 ++ .../solution-file-missing/.meta/config.json | 22 ++++++++ .../expected_analysis.json} | 0 .../solution-file-missing}/expected_tags.json | 0 .../using-main-method/.meta/config.json | 22 ++++++++ .../using-main-method}/expected_analysis.json | 0 .../using-main-method/expected_tags.json | 1 + .../src/main/java/UnknownExercise.java | 5 ++ .../.meta/src/reference/java/Hamming.java | 26 --------- tests/hamming/.meta/tests.toml | 30 ----------- tests/hamming/.meta/version | 1 - .../.meta/config.json | 0 .../expected_analysis.json | 11 ++++ .../constructor-too-long/expected_tags.json | 1 + .../src/main/java/Hamming.java | 37 +++++++++++++ .../hamming/method-too-long/.meta/config.json | 49 +++++++++++++++++ .../method-too-long/expected_analysis.json | 11 ++++ .../method-too-long/expected_tags.json | 1 + .../src/main/java/Hamming.java | 41 ++++++++++++++ .../no-argument-validation/.meta/config.json | 49 +++++++++++++++++ .../expected_analysis.json | 10 ++++ .../no-argument-validation/expected_tags.json | 1 + .../src/main/java/Hamming.java | 18 +++++++ .../.meta/config.json | 49 +++++++++++++++++ .../expected_analysis.json | 10 ++++ .../expected_tags.json | 1 + .../src/main/java/Hamming.java | 12 +++++ .../hamming/no-memoization/.meta/config.json | 49 +++++++++++++++++ .../expected_analysis.json | 4 -- .../hamming/no-memoization/expected_tags.json | 1 + .../no-memoization/src/main/java/Hamming.java | 34 ++++++++++++ .../no-string-isempty/.meta/config.json | 49 +++++++++++++++++ .../no-string-isempty/expected_analysis.json | 10 ++++ .../no-string-isempty/expected_tags.json | 1 + .../src/main/java/Hamming.java | 32 +++++++++++ .../.meta/config.json | 49 +++++++++++++++++ .../expected_analysis.json | 1 + .../expected_tags.json | 1 + .../src/main/java/Hamming.java | 32 +++++++++++ .../.meta/config.json | 49 +++++++++++++++++ .../expected_analysis.json | 1 + .../expected_tags.json | 1 + .../src/main/java/Hamming.java | 32 +++++++++++ tests/hamming/src/main/java/Hamming.java | 53 ------------------- .../using-char-literals/.meta/config.json | 49 +++++++++++++++++ .../expected_analysis.json | 10 ++++ .../using-char-literals/expected_tags.json | 1 + .../src/main/java/Hamming.java | 50 +++++++++++++++++ .../using-stream-reduce/.meta/config.json | 49 +++++++++++++++++ .../expected_analysis.json | 10 ++++ .../using-stream-reduce/expected_tags.json | 1 + .../src/main/java/Hamming.java | 34 ++++++++++++ .../.meta/config.json | 49 +++++++++++++++++ .../expected_analysis.json | 10 ++++ .../expected_tags.json | 1 + .../src/main/java/Hamming.java | 35 ++++++++++++ tests/hello-world/README.md | 1 - tests/hello-world/src/main/java/Greeter.java | 5 -- tests/two-fer/README.md | 4 -- .../hard-coded-test-cases/.meta/config.json | 39 ++++++++++++++ .../expected_analysis.json | 10 ++++ .../hard-coded-test-cases/expected_tags.json | 1 + .../src/main/java/Twofer.java | 13 +++++ .../optimal-solution/.meta/config.json | 39 ++++++++++++++ .../optimal-solution/expected_analysis.json | 1 + .../optimal-solution/expected_tags.json | 1 + .../src/main/java/Twofer.java | 5 ++ tests/two-fer/src/main/java/Twofer.java | 15 ------ .../using-if-statement/.meta/config.json | 39 ++++++++++++++ .../using-if-statement/expected_analysis.json | 10 ++++ .../using-if-statement/expected_tags.json | 1 + .../src/main/java/Twofer.java | 7 +++ .../using-multiple-returns/.meta/config.json | 39 ++++++++++++++ .../expected_analysis.json | 10 ++++ .../using-multiple-returns/expected_tags.json | 1 + .../src/main/java/Twofer.java | 6 +++ .../using-string-format/.meta/config.json | 39 ++++++++++++++ .../expected_analysis.json | 10 ++++ .../using-string-format/expected_tags.json | 1 + .../src/main/java/Twofer.java | 5 ++ tests/unknown-exercise/README.md | 2 - .../src/main/java/UnknownExercise.java | 10 ---- 90 files changed, 1305 insertions(+), 159 deletions(-) create mode 100644 tests/common/README.md rename tests/{unknown-exercise => common/printing-instead-of-returning}/.meta/config.json (100%) rename tests/{two-fer => common/printing-instead-of-returning}/expected_analysis.json (52%) rename tests/{hamming => common/printing-instead-of-returning}/expected_tags.json (100%) create mode 100644 tests/common/printing-instead-of-returning/src/main/java/UnknownExercise.java create mode 100644 tests/common/solution-does-not-compile/.meta/config.json rename tests/{hello-world => common/solution-does-not-compile}/expected_analysis.json (100%) rename tests/{hello-world => common/solution-does-not-compile}/expected_tags.json (100%) create mode 100644 tests/common/solution-does-not-compile/src/main/java/UnknownExercise.java create mode 100644 tests/common/solution-file-missing/.meta/config.json rename tests/{two-fer/expected_tags.json => common/solution-file-missing/expected_analysis.json} (100%) rename tests/{unknown-exercise => common/solution-file-missing}/expected_tags.json (100%) create mode 100644 tests/common/using-main-method/.meta/config.json rename tests/{unknown-exercise => common/using-main-method}/expected_analysis.json (100%) create mode 100644 tests/common/using-main-method/expected_tags.json create mode 100644 tests/common/using-main-method/src/main/java/UnknownExercise.java delete mode 100644 tests/hamming/.meta/src/reference/java/Hamming.java delete mode 100644 tests/hamming/.meta/tests.toml delete mode 100644 tests/hamming/.meta/version rename tests/hamming/{ => constructor-too-long}/.meta/config.json (100%) create mode 100644 tests/hamming/constructor-too-long/expected_analysis.json create mode 100644 tests/hamming/constructor-too-long/expected_tags.json create mode 100644 tests/hamming/constructor-too-long/src/main/java/Hamming.java create mode 100644 tests/hamming/method-too-long/.meta/config.json create mode 100644 tests/hamming/method-too-long/expected_analysis.json create mode 100644 tests/hamming/method-too-long/expected_tags.json create mode 100644 tests/hamming/method-too-long/src/main/java/Hamming.java create mode 100644 tests/hamming/no-argument-validation/.meta/config.json create mode 100644 tests/hamming/no-argument-validation/expected_analysis.json create mode 100644 tests/hamming/no-argument-validation/expected_tags.json create mode 100644 tests/hamming/no-argument-validation/src/main/java/Hamming.java create mode 100644 tests/hamming/no-conditional-logic-in-constructor/.meta/config.json create mode 100644 tests/hamming/no-conditional-logic-in-constructor/expected_analysis.json create mode 100644 tests/hamming/no-conditional-logic-in-constructor/expected_tags.json create mode 100644 tests/hamming/no-conditional-logic-in-constructor/src/main/java/Hamming.java create mode 100644 tests/hamming/no-memoization/.meta/config.json rename tests/hamming/{ => no-memoization}/expected_analysis.json (68%) create mode 100644 tests/hamming/no-memoization/expected_tags.json create mode 100644 tests/hamming/no-memoization/src/main/java/Hamming.java create mode 100644 tests/hamming/no-string-isempty/.meta/config.json create mode 100644 tests/hamming/no-string-isempty/expected_analysis.json create mode 100644 tests/hamming/no-string-isempty/expected_tags.json create mode 100644 tests/hamming/no-string-isempty/src/main/java/Hamming.java create mode 100644 tests/hamming/optimal-solutions/validation-and-calculation-in-helper-method/.meta/config.json create mode 100644 tests/hamming/optimal-solutions/validation-and-calculation-in-helper-method/expected_analysis.json create mode 100644 tests/hamming/optimal-solutions/validation-and-calculation-in-helper-method/expected_tags.json create mode 100644 tests/hamming/optimal-solutions/validation-and-calculation-in-helper-method/src/main/java/Hamming.java create mode 100644 tests/hamming/optimal-solutions/validation-in-helper-method/.meta/config.json create mode 100644 tests/hamming/optimal-solutions/validation-in-helper-method/expected_analysis.json create mode 100644 tests/hamming/optimal-solutions/validation-in-helper-method/expected_tags.json create mode 100644 tests/hamming/optimal-solutions/validation-in-helper-method/src/main/java/Hamming.java delete mode 100644 tests/hamming/src/main/java/Hamming.java create mode 100644 tests/hamming/using-char-literals/.meta/config.json create mode 100644 tests/hamming/using-char-literals/expected_analysis.json create mode 100644 tests/hamming/using-char-literals/expected_tags.json create mode 100644 tests/hamming/using-char-literals/src/main/java/Hamming.java create mode 100644 tests/hamming/using-stream-reduce/.meta/config.json create mode 100644 tests/hamming/using-stream-reduce/expected_analysis.json create mode 100644 tests/hamming/using-stream-reduce/expected_tags.json create mode 100644 tests/hamming/using-stream-reduce/src/main/java/Hamming.java create mode 100644 tests/hamming/using-string-tochararray/.meta/config.json create mode 100644 tests/hamming/using-string-tochararray/expected_analysis.json create mode 100644 tests/hamming/using-string-tochararray/expected_tags.json create mode 100644 tests/hamming/using-string-tochararray/src/main/java/Hamming.java delete mode 100644 tests/hello-world/README.md delete mode 100644 tests/hello-world/src/main/java/Greeter.java delete mode 100644 tests/two-fer/README.md create mode 100644 tests/two-fer/hard-coded-test-cases/.meta/config.json create mode 100644 tests/two-fer/hard-coded-test-cases/expected_analysis.json create mode 100644 tests/two-fer/hard-coded-test-cases/expected_tags.json create mode 100644 tests/two-fer/hard-coded-test-cases/src/main/java/Twofer.java create mode 100644 tests/two-fer/optimal-solution/.meta/config.json create mode 100644 tests/two-fer/optimal-solution/expected_analysis.json create mode 100644 tests/two-fer/optimal-solution/expected_tags.json create mode 100644 tests/two-fer/optimal-solution/src/main/java/Twofer.java delete mode 100644 tests/two-fer/src/main/java/Twofer.java create mode 100644 tests/two-fer/using-if-statement/.meta/config.json create mode 100644 tests/two-fer/using-if-statement/expected_analysis.json create mode 100644 tests/two-fer/using-if-statement/expected_tags.json create mode 100644 tests/two-fer/using-if-statement/src/main/java/Twofer.java create mode 100644 tests/two-fer/using-multiple-returns/.meta/config.json create mode 100644 tests/two-fer/using-multiple-returns/expected_analysis.json create mode 100644 tests/two-fer/using-multiple-returns/expected_tags.json create mode 100644 tests/two-fer/using-multiple-returns/src/main/java/Twofer.java create mode 100644 tests/two-fer/using-string-format/.meta/config.json create mode 100644 tests/two-fer/using-string-format/expected_analysis.json create mode 100644 tests/two-fer/using-string-format/expected_tags.json create mode 100644 tests/two-fer/using-string-format/src/main/java/Twofer.java delete mode 100644 tests/unknown-exercise/README.md delete mode 100644 tests/unknown-exercise/src/main/java/UnknownExercise.java diff --git a/tests/common/README.md b/tests/common/README.md new file mode 100644 index 00000000..d1dee555 --- /dev/null +++ b/tests/common/README.md @@ -0,0 +1,4 @@ +# Golden tests for common analyzer feedback + +The tests in this directory are designed to test the general feedback from the analyzer. +All exercises in this directory are made-up, so that they will not receive feedback from any exercise-specific analyzers. diff --git a/tests/unknown-exercise/.meta/config.json b/tests/common/printing-instead-of-returning/.meta/config.json similarity index 100% rename from tests/unknown-exercise/.meta/config.json rename to tests/common/printing-instead-of-returning/.meta/config.json diff --git a/tests/two-fer/expected_analysis.json b/tests/common/printing-instead-of-returning/expected_analysis.json similarity index 52% rename from tests/two-fer/expected_analysis.json rename to tests/common/printing-instead-of-returning/expected_analysis.json index 63d1d831..ab44a0d2 100644 --- a/tests/two-fer/expected_analysis.json +++ b/tests/common/printing-instead-of-returning/expected_analysis.json @@ -1,12 +1,4 @@ {"comments": [ - { - "comment": "java.general.do_not_use_main_method", - "type": "essential" - }, - { - "comment": "java.two-fer.avoid_string_format", - "type": "actionable" - }, { "comment": "java.general.avoid_print_statements", "type": "informative" diff --git a/tests/hamming/expected_tags.json b/tests/common/printing-instead-of-returning/expected_tags.json similarity index 100% rename from tests/hamming/expected_tags.json rename to tests/common/printing-instead-of-returning/expected_tags.json diff --git a/tests/common/printing-instead-of-returning/src/main/java/UnknownExercise.java b/tests/common/printing-instead-of-returning/src/main/java/UnknownExercise.java new file mode 100644 index 00000000..0709975a --- /dev/null +++ b/tests/common/printing-instead-of-returning/src/main/java/UnknownExercise.java @@ -0,0 +1,5 @@ +class UnknownExercise { + int calculate() { + System.out.println(42); + } +} diff --git a/tests/common/solution-does-not-compile/.meta/config.json b/tests/common/solution-does-not-compile/.meta/config.json new file mode 100644 index 00000000..acebb5d0 --- /dev/null +++ b/tests/common/solution-does-not-compile/.meta/config.json @@ -0,0 +1,22 @@ +{ + "authors": [ + "sanderploegsma" + ], + "files": { + "solution": [ + "src/main/java/UnknownExercise.java" + ], + "test": [ + "src/test/java/UnknownExerciseTest.java" + ], + "example": [ + ".meta/src/reference/java/UnknownExercise.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Nothing to see here", + "source": "No source", + "source_url": "https://example.com" +} diff --git a/tests/hello-world/expected_analysis.json b/tests/common/solution-does-not-compile/expected_analysis.json similarity index 100% rename from tests/hello-world/expected_analysis.json rename to tests/common/solution-does-not-compile/expected_analysis.json diff --git a/tests/hello-world/expected_tags.json b/tests/common/solution-does-not-compile/expected_tags.json similarity index 100% rename from tests/hello-world/expected_tags.json rename to tests/common/solution-does-not-compile/expected_tags.json diff --git a/tests/common/solution-does-not-compile/src/main/java/UnknownExercise.java b/tests/common/solution-does-not-compile/src/main/java/UnknownExercise.java new file mode 100644 index 00000000..986e775a --- /dev/null +++ b/tests/common/solution-does-not-compile/src/main/java/UnknownExercise.java @@ -0,0 +1,5 @@ +class UnknownExercise { + int calculate() { + return "42"; + } +} diff --git a/tests/common/solution-file-missing/.meta/config.json b/tests/common/solution-file-missing/.meta/config.json new file mode 100644 index 00000000..acebb5d0 --- /dev/null +++ b/tests/common/solution-file-missing/.meta/config.json @@ -0,0 +1,22 @@ +{ + "authors": [ + "sanderploegsma" + ], + "files": { + "solution": [ + "src/main/java/UnknownExercise.java" + ], + "test": [ + "src/test/java/UnknownExerciseTest.java" + ], + "example": [ + ".meta/src/reference/java/UnknownExercise.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Nothing to see here", + "source": "No source", + "source_url": "https://example.com" +} diff --git a/tests/two-fer/expected_tags.json b/tests/common/solution-file-missing/expected_analysis.json similarity index 100% rename from tests/two-fer/expected_tags.json rename to tests/common/solution-file-missing/expected_analysis.json diff --git a/tests/unknown-exercise/expected_tags.json b/tests/common/solution-file-missing/expected_tags.json similarity index 100% rename from tests/unknown-exercise/expected_tags.json rename to tests/common/solution-file-missing/expected_tags.json diff --git a/tests/common/using-main-method/.meta/config.json b/tests/common/using-main-method/.meta/config.json new file mode 100644 index 00000000..acebb5d0 --- /dev/null +++ b/tests/common/using-main-method/.meta/config.json @@ -0,0 +1,22 @@ +{ + "authors": [ + "sanderploegsma" + ], + "files": { + "solution": [ + "src/main/java/UnknownExercise.java" + ], + "test": [ + "src/test/java/UnknownExerciseTest.java" + ], + "example": [ + ".meta/src/reference/java/UnknownExercise.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Nothing to see here", + "source": "No source", + "source_url": "https://example.com" +} diff --git a/tests/unknown-exercise/expected_analysis.json b/tests/common/using-main-method/expected_analysis.json similarity index 100% rename from tests/unknown-exercise/expected_analysis.json rename to tests/common/using-main-method/expected_analysis.json diff --git a/tests/common/using-main-method/expected_tags.json b/tests/common/using-main-method/expected_tags.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/tests/common/using-main-method/expected_tags.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/common/using-main-method/src/main/java/UnknownExercise.java b/tests/common/using-main-method/src/main/java/UnknownExercise.java new file mode 100644 index 00000000..9fd020e9 --- /dev/null +++ b/tests/common/using-main-method/src/main/java/UnknownExercise.java @@ -0,0 +1,5 @@ +class UnknownExercise { + public static void main(String[] args) { + System.out.println(42); + } +} diff --git a/tests/hamming/.meta/src/reference/java/Hamming.java b/tests/hamming/.meta/src/reference/java/Hamming.java deleted file mode 100644 index 7db3984d..00000000 --- a/tests/hamming/.meta/src/reference/java/Hamming.java +++ /dev/null @@ -1,26 +0,0 @@ -import java.util.function.IntPredicate; -import java.util.stream.IntStream; - -class Hamming { - private final int hammingDistance; - - Hamming(String leftStrand, String rightStrand) { - String exceptionMessage = "leftStrand and rightStrand must be of equal length."; - if (leftStrand.length() != rightStrand.length()) { - if (leftStrand.isEmpty()) { - exceptionMessage = "left strand must not be empty."; - } - if (rightStrand.isEmpty()) { - exceptionMessage = "right strand must not be empty."; - } - throw new IllegalArgumentException(exceptionMessage); - } - - IntPredicate areNotEqual = index -> leftStrand.charAt(index) != rightStrand.charAt(index); - hammingDistance = (int) IntStream.range(0, leftStrand.length()).filter(areNotEqual).count(); - } - - int getHammingDistance() { - return hammingDistance; - } -} diff --git a/tests/hamming/.meta/tests.toml b/tests/hamming/.meta/tests.toml deleted file mode 100644 index b2f80f48..00000000 --- a/tests/hamming/.meta/tests.toml +++ /dev/null @@ -1,30 +0,0 @@ -# This is an auto-generated file. Regular comments will be removed when this -# file is regenerated. Regenerating will not touch any manually added keys, -# so comments can be added in a "comment" key. - -[f6dcb64f-03b0-4b60-81b1-3c9dbf47e887] -description = "empty strands" - -[54681314-eee2-439a-9db0-b0636c656156] -description = "single letter identical strands" - -[294479a3-a4c8-478f-8d63-6209815a827b] -description = "single letter different strands" - -[9aed5f34-5693-4344-9b31-40c692fb5592] -description = "long identical strands" - -[cd2273a5-c576-46c8-a52b-dee251c3e6e5] -description = "long different strands" - -[919f8ef0-b767-4d1b-8516-6379d07fcb28] -description = "disallow first strand longer" - -[8a2d4ed0-ead5-4fdd-924d-27c4cf56e60e] -description = "disallow second strand longer" - -[5dce058b-28d4-4ca7-aa64-adfe4e17784c] -description = "disallow left empty strand" - -[38826d4b-16fb-4639-ac3e-ba027dec8b5f] -description = "disallow right empty strand" diff --git a/tests/hamming/.meta/version b/tests/hamming/.meta/version deleted file mode 100644 index 276cbf9e..00000000 --- a/tests/hamming/.meta/version +++ /dev/null @@ -1 +0,0 @@ -2.3.0 diff --git a/tests/hamming/.meta/config.json b/tests/hamming/constructor-too-long/.meta/config.json similarity index 100% rename from tests/hamming/.meta/config.json rename to tests/hamming/constructor-too-long/.meta/config.json diff --git a/tests/hamming/constructor-too-long/expected_analysis.json b/tests/hamming/constructor-too-long/expected_analysis.json new file mode 100644 index 00000000..4dbd585a --- /dev/null +++ b/tests/hamming/constructor-too-long/expected_analysis.json @@ -0,0 +1,11 @@ +{"comments": [ + { + "comment": "java.general.constructor_too_long", + "type": "actionable", + "params": {"constructorNames": "Hamming"} + }, + { + "comment": "java.general.feedback_request", + "type": "informative" + } +]} \ No newline at end of file diff --git a/tests/hamming/constructor-too-long/expected_tags.json b/tests/hamming/constructor-too-long/expected_tags.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/tests/hamming/constructor-too-long/expected_tags.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/hamming/constructor-too-long/src/main/java/Hamming.java b/tests/hamming/constructor-too-long/src/main/java/Hamming.java new file mode 100644 index 00000000..9f7a426e --- /dev/null +++ b/tests/hamming/constructor-too-long/src/main/java/Hamming.java @@ -0,0 +1,37 @@ +/** + * Optimal solution, but the constructor does too much. + * We use a simple heuristic based on line length. + */ +class Hamming { + private final int hammingDistance; + + Hamming(String leftStrand, String rightStrand) { + if (leftStrand.length() != rightStrand.length()) { + if (leftStrand.isEmpty()) { + throw new IllegalArgumentException("left strand must not be empty."); + } + if (rightStrand.isEmpty()) { + throw new IllegalArgumentException("right strand must not be empty."); + } + throw new IllegalArgumentException( + "leftStrand and rightStrand must be of equal length."); + } + + int distance = 0; + + for (int i = 0; + i < leftStrand.length(); + i++) { + if (leftStrand.charAt(i) + != rightStrand.charAt(i)) { + distance++; + } + } + + hammingDistance = distance; + } + + int getHammingDistance() { + return hammingDistance; + } +} diff --git a/tests/hamming/method-too-long/.meta/config.json b/tests/hamming/method-too-long/.meta/config.json new file mode 100644 index 00000000..5e2dba3a --- /dev/null +++ b/tests/hamming/method-too-long/.meta/config.json @@ -0,0 +1,49 @@ +{ + "authors": [ + "wdjunaidi" + ], + "contributors": [ + "c-thornton", + "ChristianWilkie", + "FridaTveit", + "javaeeeee", + "jmrunkle", + "jonnynabors", + "jtigger", + "kytrinyx", + "lemoncurry", + "matthewmorgan", + "michael-berger-FR", + "michaelspets", + "mirkoperillo", + "msomji", + "muzimuzhi", + "odzeno", + "sjwarner-bp", + "SleeplessByte", + "Smarticles101", + "sshine", + "stkent", + "t0dd", + "Valkryst", + "vasouv", + "Zaldrick" + ], + "files": { + "solution": [ + "src/main/java/Hamming.java" + ], + "test": [ + "src/test/java/HammingTest.java" + ], + "example": [ + ".meta/src/reference/java/Hamming.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Calculate the Hamming difference between two DNA strands.", + "source": "The Calculating Point Mutations problem at Rosalind", + "source_url": "https://rosalind.info/problems/hamm/" +} diff --git a/tests/hamming/method-too-long/expected_analysis.json b/tests/hamming/method-too-long/expected_analysis.json new file mode 100644 index 00000000..9b4612ac --- /dev/null +++ b/tests/hamming/method-too-long/expected_analysis.json @@ -0,0 +1,11 @@ +{"comments": [ + { + "comment": "java.general.method_too_long", + "type": "actionable", + "params": {"methodNames": "calculateHammingDistance"} + }, + { + "comment": "java.general.feedback_request", + "type": "informative" + } +]} \ No newline at end of file diff --git a/tests/hamming/method-too-long/expected_tags.json b/tests/hamming/method-too-long/expected_tags.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/tests/hamming/method-too-long/expected_tags.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/hamming/method-too-long/src/main/java/Hamming.java b/tests/hamming/method-too-long/src/main/java/Hamming.java new file mode 100644 index 00000000..a7ccd70e --- /dev/null +++ b/tests/hamming/method-too-long/src/main/java/Hamming.java @@ -0,0 +1,41 @@ +/** + * Optimal solution, but the helper method does too much. + * We use a simple heuristic based on line length. + */ +class Hamming { + private final int hammingDistance; + + Hamming(String leftStrand, String rightStrand) { + hammingDistance = calculateHammingDistance(leftStrand, rightStrand); + } + + private int calculateHammingDistance(String leftStrand, String rightStrand) { + if (leftStrand.length() != rightStrand.length()) { + if (leftStrand.isEmpty()) { + throw new IllegalArgumentException("left strand must not be empty."); + } + if (rightStrand.isEmpty()) { + throw new IllegalArgumentException("right strand must not be empty."); + } + throw new IllegalArgumentException( + "leftStrand and rightStrand must be of equal length."); + } + + int distance = 0; + + for (int i = 0; + i < leftStrand.length(); + i++) { + if (leftStrand.charAt(i) + != rightStrand.charAt(i)) { + distance++; + } + } + + return distance; + } + + int getHammingDistance() { + return hammingDistance; + } +} diff --git a/tests/hamming/no-argument-validation/.meta/config.json b/tests/hamming/no-argument-validation/.meta/config.json new file mode 100644 index 00000000..5e2dba3a --- /dev/null +++ b/tests/hamming/no-argument-validation/.meta/config.json @@ -0,0 +1,49 @@ +{ + "authors": [ + "wdjunaidi" + ], + "contributors": [ + "c-thornton", + "ChristianWilkie", + "FridaTveit", + "javaeeeee", + "jmrunkle", + "jonnynabors", + "jtigger", + "kytrinyx", + "lemoncurry", + "matthewmorgan", + "michael-berger-FR", + "michaelspets", + "mirkoperillo", + "msomji", + "muzimuzhi", + "odzeno", + "sjwarner-bp", + "SleeplessByte", + "Smarticles101", + "sshine", + "stkent", + "t0dd", + "Valkryst", + "vasouv", + "Zaldrick" + ], + "files": { + "solution": [ + "src/main/java/Hamming.java" + ], + "test": [ + "src/test/java/HammingTest.java" + ], + "example": [ + ".meta/src/reference/java/Hamming.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Calculate the Hamming difference between two DNA strands.", + "source": "The Calculating Point Mutations problem at Rosalind", + "source_url": "https://rosalind.info/problems/hamm/" +} diff --git a/tests/hamming/no-argument-validation/expected_analysis.json b/tests/hamming/no-argument-validation/expected_analysis.json new file mode 100644 index 00000000..4dda3dd9 --- /dev/null +++ b/tests/hamming/no-argument-validation/expected_analysis.json @@ -0,0 +1,10 @@ +{"comments": [ + { + "comment": "java.hamming.must_throw_in_constructor", + "type": "essential" + }, + { + "comment": "java.general.feedback_request", + "type": "informative" + } +]} \ No newline at end of file diff --git a/tests/hamming/no-argument-validation/expected_tags.json b/tests/hamming/no-argument-validation/expected_tags.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/tests/hamming/no-argument-validation/expected_tags.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/hamming/no-argument-validation/src/main/java/Hamming.java b/tests/hamming/no-argument-validation/src/main/java/Hamming.java new file mode 100644 index 00000000..ee03e633 --- /dev/null +++ b/tests/hamming/no-argument-validation/src/main/java/Hamming.java @@ -0,0 +1,18 @@ +import java.util.stream.IntStream; + +/** Constructor must throw IllegalArgumentException. */ +class Hamming { + private final int hammingDistance; + + Hamming(String leftStrand, String rightStrand) { + if (leftStrand.isEmpty()) { + this.hammingDistance = 0; + } else { + this.hammingDistance = 1; + } + } + + int getHammingDistance() { + return hammingDistance; + } +} diff --git a/tests/hamming/no-conditional-logic-in-constructor/.meta/config.json b/tests/hamming/no-conditional-logic-in-constructor/.meta/config.json new file mode 100644 index 00000000..5e2dba3a --- /dev/null +++ b/tests/hamming/no-conditional-logic-in-constructor/.meta/config.json @@ -0,0 +1,49 @@ +{ + "authors": [ + "wdjunaidi" + ], + "contributors": [ + "c-thornton", + "ChristianWilkie", + "FridaTveit", + "javaeeeee", + "jmrunkle", + "jonnynabors", + "jtigger", + "kytrinyx", + "lemoncurry", + "matthewmorgan", + "michael-berger-FR", + "michaelspets", + "mirkoperillo", + "msomji", + "muzimuzhi", + "odzeno", + "sjwarner-bp", + "SleeplessByte", + "Smarticles101", + "sshine", + "stkent", + "t0dd", + "Valkryst", + "vasouv", + "Zaldrick" + ], + "files": { + "solution": [ + "src/main/java/Hamming.java" + ], + "test": [ + "src/test/java/HammingTest.java" + ], + "example": [ + ".meta/src/reference/java/Hamming.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Calculate the Hamming difference between two DNA strands.", + "source": "The Calculating Point Mutations problem at Rosalind", + "source_url": "https://rosalind.info/problems/hamm/" +} diff --git a/tests/hamming/no-conditional-logic-in-constructor/expected_analysis.json b/tests/hamming/no-conditional-logic-in-constructor/expected_analysis.json new file mode 100644 index 00000000..ebca724c --- /dev/null +++ b/tests/hamming/no-conditional-logic-in-constructor/expected_analysis.json @@ -0,0 +1,10 @@ +{"comments": [ + { + "comment": "java.hamming.must_use_conditional_logic_in_constructor", + "type": "essential" + }, + { + "comment": "java.general.feedback_request", + "type": "informative" + } +]} \ No newline at end of file diff --git a/tests/hamming/no-conditional-logic-in-constructor/expected_tags.json b/tests/hamming/no-conditional-logic-in-constructor/expected_tags.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/tests/hamming/no-conditional-logic-in-constructor/expected_tags.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/hamming/no-conditional-logic-in-constructor/src/main/java/Hamming.java b/tests/hamming/no-conditional-logic-in-constructor/src/main/java/Hamming.java new file mode 100644 index 00000000..1990326f --- /dev/null +++ b/tests/hamming/no-conditional-logic-in-constructor/src/main/java/Hamming.java @@ -0,0 +1,12 @@ +/** Constructor must have conditional logic. */ +class Hamming { + private final int hammingDistance; + + Hamming(String leftStrand, String rightStrand) { + this.hammingDistance = 0; + } + + int getHammingDistance() { + return hammingDistance; + } +} diff --git a/tests/hamming/no-memoization/.meta/config.json b/tests/hamming/no-memoization/.meta/config.json new file mode 100644 index 00000000..5e2dba3a --- /dev/null +++ b/tests/hamming/no-memoization/.meta/config.json @@ -0,0 +1,49 @@ +{ + "authors": [ + "wdjunaidi" + ], + "contributors": [ + "c-thornton", + "ChristianWilkie", + "FridaTveit", + "javaeeeee", + "jmrunkle", + "jonnynabors", + "jtigger", + "kytrinyx", + "lemoncurry", + "matthewmorgan", + "michael-berger-FR", + "michaelspets", + "mirkoperillo", + "msomji", + "muzimuzhi", + "odzeno", + "sjwarner-bp", + "SleeplessByte", + "Smarticles101", + "sshine", + "stkent", + "t0dd", + "Valkryst", + "vasouv", + "Zaldrick" + ], + "files": { + "solution": [ + "src/main/java/Hamming.java" + ], + "test": [ + "src/test/java/HammingTest.java" + ], + "example": [ + ".meta/src/reference/java/Hamming.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Calculate the Hamming difference between two DNA strands.", + "source": "The Calculating Point Mutations problem at Rosalind", + "source_url": "https://rosalind.info/problems/hamm/" +} diff --git a/tests/hamming/expected_analysis.json b/tests/hamming/no-memoization/expected_analysis.json similarity index 68% rename from tests/hamming/expected_analysis.json rename to tests/hamming/no-memoization/expected_analysis.json index 7e7cbaa6..36d33952 100644 --- a/tests/hamming/expected_analysis.json +++ b/tests/hamming/no-memoization/expected_analysis.json @@ -3,10 +3,6 @@ "comment": "java.hamming.calculate_distance_in_constructor", "type": "actionable" }, - { - "comment": "java.hamming.should_use_string_is_empty", - "type": "informative" - }, { "comment": "java.general.feedback_request", "type": "informative" diff --git a/tests/hamming/no-memoization/expected_tags.json b/tests/hamming/no-memoization/expected_tags.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/tests/hamming/no-memoization/expected_tags.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/hamming/no-memoization/src/main/java/Hamming.java b/tests/hamming/no-memoization/src/main/java/Hamming.java new file mode 100644 index 00000000..00e44417 --- /dev/null +++ b/tests/hamming/no-memoization/src/main/java/Hamming.java @@ -0,0 +1,34 @@ +import java.util.stream.IntStream; + +/** Optimal solution but getHammingDistance doesn't store calculated distance. */ +class Hamming { + private final String leftStrand; + private final String rightStrand; + + Hamming(String leftStrand, String rightStrand) { + validateStrandsHaveEqualLength(leftStrand, rightStrand); + + this.leftStrand = leftStrand; + this.rightStrand = rightStrand; + } + + private void validateStrandsHaveEqualLength() { + if (leftStrand.length() == rightStrand.length()) { + return; + } + if (leftStrand.isEmpty()) { + throw new IllegalArgumentException("left strand must not be empty."); + } + if (rightStrand.isEmpty()) { + throw new IllegalArgumentException("right strand must not be empty."); + } + throw new IllegalArgumentException( + "leftStrand and rightStrand must be of equal length."); + } + + int getHammingDistance() { + return (int) IntStream.range(0, leftStrand.length()) + .filter(index -> leftStrand.charAt(index) != rightStrand.charAt(index)) + .count(); + } +} diff --git a/tests/hamming/no-string-isempty/.meta/config.json b/tests/hamming/no-string-isempty/.meta/config.json new file mode 100644 index 00000000..5e2dba3a --- /dev/null +++ b/tests/hamming/no-string-isempty/.meta/config.json @@ -0,0 +1,49 @@ +{ + "authors": [ + "wdjunaidi" + ], + "contributors": [ + "c-thornton", + "ChristianWilkie", + "FridaTveit", + "javaeeeee", + "jmrunkle", + "jonnynabors", + "jtigger", + "kytrinyx", + "lemoncurry", + "matthewmorgan", + "michael-berger-FR", + "michaelspets", + "mirkoperillo", + "msomji", + "muzimuzhi", + "odzeno", + "sjwarner-bp", + "SleeplessByte", + "Smarticles101", + "sshine", + "stkent", + "t0dd", + "Valkryst", + "vasouv", + "Zaldrick" + ], + "files": { + "solution": [ + "src/main/java/Hamming.java" + ], + "test": [ + "src/test/java/HammingTest.java" + ], + "example": [ + ".meta/src/reference/java/Hamming.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Calculate the Hamming difference between two DNA strands.", + "source": "The Calculating Point Mutations problem at Rosalind", + "source_url": "https://rosalind.info/problems/hamm/" +} diff --git a/tests/hamming/no-string-isempty/expected_analysis.json b/tests/hamming/no-string-isempty/expected_analysis.json new file mode 100644 index 00000000..9a477899 --- /dev/null +++ b/tests/hamming/no-string-isempty/expected_analysis.json @@ -0,0 +1,10 @@ +{"comments": [ + { + "comment": "java.hamming.should_use_string_is_empty", + "type": "informative" + }, + { + "comment": "java.general.feedback_request", + "type": "informative" + } +]} \ No newline at end of file diff --git a/tests/hamming/no-string-isempty/expected_tags.json b/tests/hamming/no-string-isempty/expected_tags.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/tests/hamming/no-string-isempty/expected_tags.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/hamming/no-string-isempty/src/main/java/Hamming.java b/tests/hamming/no-string-isempty/src/main/java/Hamming.java new file mode 100644 index 00000000..702abd88 --- /dev/null +++ b/tests/hamming/no-string-isempty/src/main/java/Hamming.java @@ -0,0 +1,32 @@ +import java.util.stream.IntStream; + +/** Optimal solution, but does not use String.isEmpty. */ +class Hamming { + private final int hammingDistance; + + Hamming(String leftStrand, String rightStrand) { + validateStrandsHaveEqualLength(leftStrand, rightStrand); + + hammingDistance = (int) IntStream.range(0, leftStrand.length()) + .filter(index -> leftStrand.charAt(index) != rightStrand.charAt(index)) + .count(); + } + + private void validateStrandsHaveEqualLength() { + if (leftStrand.length() == rightStrand.length()) { + return; + } + if (leftStrand.length() == 0) { + throw new IllegalArgumentException("left strand must not be empty."); + } + if (rightStrand.length() == 0) { + throw new IllegalArgumentException("right strand must not be empty."); + } + throw new IllegalArgumentException( + "leftStrand and rightStrand must be of equal length."); + } + + int getHammingDistance() { + return hammingDistance; + } +} diff --git a/tests/hamming/optimal-solutions/validation-and-calculation-in-helper-method/.meta/config.json b/tests/hamming/optimal-solutions/validation-and-calculation-in-helper-method/.meta/config.json new file mode 100644 index 00000000..5e2dba3a --- /dev/null +++ b/tests/hamming/optimal-solutions/validation-and-calculation-in-helper-method/.meta/config.json @@ -0,0 +1,49 @@ +{ + "authors": [ + "wdjunaidi" + ], + "contributors": [ + "c-thornton", + "ChristianWilkie", + "FridaTveit", + "javaeeeee", + "jmrunkle", + "jonnynabors", + "jtigger", + "kytrinyx", + "lemoncurry", + "matthewmorgan", + "michael-berger-FR", + "michaelspets", + "mirkoperillo", + "msomji", + "muzimuzhi", + "odzeno", + "sjwarner-bp", + "SleeplessByte", + "Smarticles101", + "sshine", + "stkent", + "t0dd", + "Valkryst", + "vasouv", + "Zaldrick" + ], + "files": { + "solution": [ + "src/main/java/Hamming.java" + ], + "test": [ + "src/test/java/HammingTest.java" + ], + "example": [ + ".meta/src/reference/java/Hamming.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Calculate the Hamming difference between two DNA strands.", + "source": "The Calculating Point Mutations problem at Rosalind", + "source_url": "https://rosalind.info/problems/hamm/" +} diff --git a/tests/hamming/optimal-solutions/validation-and-calculation-in-helper-method/expected_analysis.json b/tests/hamming/optimal-solutions/validation-and-calculation-in-helper-method/expected_analysis.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/tests/hamming/optimal-solutions/validation-and-calculation-in-helper-method/expected_analysis.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/hamming/optimal-solutions/validation-and-calculation-in-helper-method/expected_tags.json b/tests/hamming/optimal-solutions/validation-and-calculation-in-helper-method/expected_tags.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/tests/hamming/optimal-solutions/validation-and-calculation-in-helper-method/expected_tags.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/hamming/optimal-solutions/validation-and-calculation-in-helper-method/src/main/java/Hamming.java b/tests/hamming/optimal-solutions/validation-and-calculation-in-helper-method/src/main/java/Hamming.java new file mode 100644 index 00000000..8565b81e --- /dev/null +++ b/tests/hamming/optimal-solutions/validation-and-calculation-in-helper-method/src/main/java/Hamming.java @@ -0,0 +1,32 @@ +class Hamming { + + private int HammingDistance; + + Hamming(String leftStrand, String rightStrand) { + HammingDistance = calculateHammingDistance(leftStrand, rightStrand); + } + + private int calculateHammingDistance(String leftStrand, String rightStrand) { + int distance = 0; + + if (leftStrand.length() == rightStrand.length()) { + for (int i = 0; i < leftStrand.length(); i++) { + if (leftStrand.charAt(i) != rightStrand.charAt(i)) { + distance++; + } + } + } else if (leftStrand.isEmpty()) { + throw new IllegalArgumentException("left strand must not be empty."); + } else if (rightStrand.isEmpty()) { + throw new IllegalArgumentException("right strand must not be empty."); + } else { + throw new IllegalArgumentException("leftStrand and rightStrand must be of equal length."); + } + return distance; + } + + int getHammingDistance() { + return HammingDistance; + } + +} diff --git a/tests/hamming/optimal-solutions/validation-in-helper-method/.meta/config.json b/tests/hamming/optimal-solutions/validation-in-helper-method/.meta/config.json new file mode 100644 index 00000000..5e2dba3a --- /dev/null +++ b/tests/hamming/optimal-solutions/validation-in-helper-method/.meta/config.json @@ -0,0 +1,49 @@ +{ + "authors": [ + "wdjunaidi" + ], + "contributors": [ + "c-thornton", + "ChristianWilkie", + "FridaTveit", + "javaeeeee", + "jmrunkle", + "jonnynabors", + "jtigger", + "kytrinyx", + "lemoncurry", + "matthewmorgan", + "michael-berger-FR", + "michaelspets", + "mirkoperillo", + "msomji", + "muzimuzhi", + "odzeno", + "sjwarner-bp", + "SleeplessByte", + "Smarticles101", + "sshine", + "stkent", + "t0dd", + "Valkryst", + "vasouv", + "Zaldrick" + ], + "files": { + "solution": [ + "src/main/java/Hamming.java" + ], + "test": [ + "src/test/java/HammingTest.java" + ], + "example": [ + ".meta/src/reference/java/Hamming.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Calculate the Hamming difference between two DNA strands.", + "source": "The Calculating Point Mutations problem at Rosalind", + "source_url": "https://rosalind.info/problems/hamm/" +} diff --git a/tests/hamming/optimal-solutions/validation-in-helper-method/expected_analysis.json b/tests/hamming/optimal-solutions/validation-in-helper-method/expected_analysis.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/tests/hamming/optimal-solutions/validation-in-helper-method/expected_analysis.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/hamming/optimal-solutions/validation-in-helper-method/expected_tags.json b/tests/hamming/optimal-solutions/validation-in-helper-method/expected_tags.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/tests/hamming/optimal-solutions/validation-in-helper-method/expected_tags.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/hamming/optimal-solutions/validation-in-helper-method/src/main/java/Hamming.java b/tests/hamming/optimal-solutions/validation-in-helper-method/src/main/java/Hamming.java new file mode 100644 index 00000000..9bc80a49 --- /dev/null +++ b/tests/hamming/optimal-solutions/validation-in-helper-method/src/main/java/Hamming.java @@ -0,0 +1,32 @@ +import java.util.stream.IntStream; + +/** Optimal solution using a method for validation. */ +class Hamming { + private final int hammingDistance; + + Hamming(String leftStrand, String rightStrand) { + validateStrandsHaveEqualLength(leftStrand, rightStrand); + + hammingDistance = (int) IntStream.range(0, leftStrand.length()) + .filter(index -> leftStrand.charAt(index) != rightStrand.charAt(index)) + .count(); + } + + private void validateStrandsHaveEqualLength() { + if (leftStrand.length() == rightStrand.length()) { + return; + } + if (leftStrand.isEmpty()) { + throw new IllegalArgumentException("left strand must not be empty."); + } + if (rightStrand.isEmpty()) { + throw new IllegalArgumentException("right strand must not be empty."); + } + throw new IllegalArgumentException( + "leftStrand and rightStrand must be of equal length."); + } + + int getHammingDistance() { + return hammingDistance; + } +} \ No newline at end of file diff --git a/tests/hamming/src/main/java/Hamming.java b/tests/hamming/src/main/java/Hamming.java deleted file mode 100644 index a3998156..00000000 --- a/tests/hamming/src/main/java/Hamming.java +++ /dev/null @@ -1,53 +0,0 @@ -class Hamming { - - private String leftStrand; - private String rightStrand; - - Hamming(String leftStrand, String rightStrand) { - - validate(leftStrand, rightStrand); - this.leftStrand = leftStrand; - this.rightStrand = rightStrand; - } - - - private void validate(String leftStrand, String rightStrand) { - validateNotNull(leftStrand, rightStrand); - validateNotOneEmpty(leftStrand, rightStrand); - validateSameLength(leftStrand, rightStrand); - } - - private void validateNotNull(String leftStrand, String rightStrand) { - if (leftStrand == null || rightStrand == null) { - throw new IllegalArgumentException("Either left or right stand is null"); - } - } - - private void validateNotOneEmpty(String leftStrand, String rightStrand) { - if (leftStrand.length() == 0 && rightStrand.length() > 0) { - throw new IllegalArgumentException("left strand must not be empty."); - } else if (rightStrand.length() == 0 && leftStrand.length() > 0) { - throw new IllegalArgumentException("right strand must not be empty."); - } - } - - private void validateSameLength(String leftStrand, String rightStrand) { - if (leftStrand.length() != rightStrand.length()) { - throw new IllegalArgumentException("leftStrand and rightStrand must be of equal length."); - } - } - - int getHammingDistance() { - - int strandLen = this.leftStrand.length(); - int diffCount = 0; - for (int i = 0; i < strandLen; i++) { - if (this.leftStrand.charAt(i) != this.rightStrand.charAt(i)) { - diffCount++; - } - } - - return diffCount; - } - -} diff --git a/tests/hamming/using-char-literals/.meta/config.json b/tests/hamming/using-char-literals/.meta/config.json new file mode 100644 index 00000000..5e2dba3a --- /dev/null +++ b/tests/hamming/using-char-literals/.meta/config.json @@ -0,0 +1,49 @@ +{ + "authors": [ + "wdjunaidi" + ], + "contributors": [ + "c-thornton", + "ChristianWilkie", + "FridaTveit", + "javaeeeee", + "jmrunkle", + "jonnynabors", + "jtigger", + "kytrinyx", + "lemoncurry", + "matthewmorgan", + "michael-berger-FR", + "michaelspets", + "mirkoperillo", + "msomji", + "muzimuzhi", + "odzeno", + "sjwarner-bp", + "SleeplessByte", + "Smarticles101", + "sshine", + "stkent", + "t0dd", + "Valkryst", + "vasouv", + "Zaldrick" + ], + "files": { + "solution": [ + "src/main/java/Hamming.java" + ], + "test": [ + "src/test/java/HammingTest.java" + ], + "example": [ + ".meta/src/reference/java/Hamming.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Calculate the Hamming difference between two DNA strands.", + "source": "The Calculating Point Mutations problem at Rosalind", + "source_url": "https://rosalind.info/problems/hamm/" +} diff --git a/tests/hamming/using-char-literals/expected_analysis.json b/tests/hamming/using-char-literals/expected_analysis.json new file mode 100644 index 00000000..f6731e06 --- /dev/null +++ b/tests/hamming/using-char-literals/expected_analysis.json @@ -0,0 +1,10 @@ +{"comments": [ + { + "comment": "java.hamming.avoid_character_literals", + "type": "actionable" + }, + { + "comment": "java.general.feedback_request", + "type": "informative" + } +]} \ No newline at end of file diff --git a/tests/hamming/using-char-literals/expected_tags.json b/tests/hamming/using-char-literals/expected_tags.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/tests/hamming/using-char-literals/expected_tags.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/hamming/using-char-literals/src/main/java/Hamming.java b/tests/hamming/using-char-literals/src/main/java/Hamming.java new file mode 100644 index 00000000..6e677a0f --- /dev/null +++ b/tests/hamming/using-char-literals/src/main/java/Hamming.java @@ -0,0 +1,50 @@ +import java.util.stream.IntStream; + +/** Should not be checking character literals. */ +class Hamming { + private final int hammingDistance; + + Hamming(String leftStrand, String rightStrand) { + validateStrandsHaveEqualLength(leftStrand, rightStrand); + + hammingDistance = calculateHammingDistance(leftStrand, rightStrand); + } + + private int calculateHammingDistance() { + return (int) IntStream.range(0, leftStrand.length()) + .filter(index -> nucleotidesDiffer(leftStrand.charAt(index), rightStrand.charAt(index))) + .count(); + } + + private boolean nucleotidesDiffer(char leftNucleotide, char rightNucleotide) { + switch (leftNucleotide) { + case 'C': + return rightNucleotide == 'A' || rightNucleotide == 'G' || rightNucleotide == 'T'; + case 'A': + return rightNucleotide == 'C' || rightNucleotide == 'G' || rightNucleotide == 'T'; + case 'G': + return rightNucleotide == 'A' || rightNucleotide == 'C' || rightNucleotide == 'T'; + case 'T': + return rightNucleotide == 'A' || rightNucleotide == 'G' || rightNucleotide == 'C'; + } + return false; // unknown nucleotide + } + + private void validateStrandsHaveEqualLength() { + if (leftStrand.length() == rightStrand.length()) { + return; + } + if (leftStrand.isEmpty()) { + throw new IllegalArgumentException("left strand must not be empty."); + } + if (rightStrand.isEmpty()) { + throw new IllegalArgumentException("right strand must not be empty."); + } + throw new IllegalArgumentException( + "leftStrand and rightStrand must be of equal length."); + } + + int getHammingDistance() { + return hammingDistance; + } +} diff --git a/tests/hamming/using-stream-reduce/.meta/config.json b/tests/hamming/using-stream-reduce/.meta/config.json new file mode 100644 index 00000000..5e2dba3a --- /dev/null +++ b/tests/hamming/using-stream-reduce/.meta/config.json @@ -0,0 +1,49 @@ +{ + "authors": [ + "wdjunaidi" + ], + "contributors": [ + "c-thornton", + "ChristianWilkie", + "FridaTveit", + "javaeeeee", + "jmrunkle", + "jonnynabors", + "jtigger", + "kytrinyx", + "lemoncurry", + "matthewmorgan", + "michael-berger-FR", + "michaelspets", + "mirkoperillo", + "msomji", + "muzimuzhi", + "odzeno", + "sjwarner-bp", + "SleeplessByte", + "Smarticles101", + "sshine", + "stkent", + "t0dd", + "Valkryst", + "vasouv", + "Zaldrick" + ], + "files": { + "solution": [ + "src/main/java/Hamming.java" + ], + "test": [ + "src/test/java/HammingTest.java" + ], + "example": [ + ".meta/src/reference/java/Hamming.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Calculate the Hamming difference between two DNA strands.", + "source": "The Calculating Point Mutations problem at Rosalind", + "source_url": "https://rosalind.info/problems/hamm/" +} diff --git a/tests/hamming/using-stream-reduce/expected_analysis.json b/tests/hamming/using-stream-reduce/expected_analysis.json new file mode 100644 index 00000000..930e90ef --- /dev/null +++ b/tests/hamming/using-stream-reduce/expected_analysis.json @@ -0,0 +1,10 @@ +{"comments": [ + { + "comment": "java.hamming.should_use_stream_filter_and_count", + "type": "actionable" + }, + { + "comment": "java.general.feedback_request", + "type": "informative" + } +]} \ No newline at end of file diff --git a/tests/hamming/using-stream-reduce/expected_tags.json b/tests/hamming/using-stream-reduce/expected_tags.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/tests/hamming/using-stream-reduce/expected_tags.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/hamming/using-stream-reduce/src/main/java/Hamming.java b/tests/hamming/using-stream-reduce/src/main/java/Hamming.java new file mode 100644 index 00000000..eba757d8 --- /dev/null +++ b/tests/hamming/using-stream-reduce/src/main/java/Hamming.java @@ -0,0 +1,34 @@ +import java.util.stream.IntStream; + +/** Using .filter().count() is more readable than using .reduce(). */ +class Hamming { + private final int hammingDistance; + + Hamming(String leftStrand, String rightStrand) { + validateStrandsHaveEqualLength(leftStrand, rightStrand); + + hammingDistance = (int) IntStream.range(0, leftStrand.length()) + .reduce( + 0, + (acc, i) -> + (leftStrand.charAt(i) != rightStrand.charAt(i)) ? acc + 1 : acc); + } + + private void validateStrandsHaveEqualLength() { + if (leftStrand.length() == rightStrand.length()) { + return; + } + if (leftStrand.isEmpty()) { + throw new IllegalArgumentException("left strand must not be empty."); + } + if (rightStrand.isEmpty()) { + throw new IllegalArgumentException("right strand must not be empty."); + } + throw new IllegalArgumentException( + "leftStrand and rightStrand must be of equal length."); + } + + int getHammingDistance() { + return hammingDistance; + } +} diff --git a/tests/hamming/using-string-tochararray/.meta/config.json b/tests/hamming/using-string-tochararray/.meta/config.json new file mode 100644 index 00000000..5e2dba3a --- /dev/null +++ b/tests/hamming/using-string-tochararray/.meta/config.json @@ -0,0 +1,49 @@ +{ + "authors": [ + "wdjunaidi" + ], + "contributors": [ + "c-thornton", + "ChristianWilkie", + "FridaTveit", + "javaeeeee", + "jmrunkle", + "jonnynabors", + "jtigger", + "kytrinyx", + "lemoncurry", + "matthewmorgan", + "michael-berger-FR", + "michaelspets", + "mirkoperillo", + "msomji", + "muzimuzhi", + "odzeno", + "sjwarner-bp", + "SleeplessByte", + "Smarticles101", + "sshine", + "stkent", + "t0dd", + "Valkryst", + "vasouv", + "Zaldrick" + ], + "files": { + "solution": [ + "src/main/java/Hamming.java" + ], + "test": [ + "src/test/java/HammingTest.java" + ], + "example": [ + ".meta/src/reference/java/Hamming.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Calculate the Hamming difference between two DNA strands.", + "source": "The Calculating Point Mutations problem at Rosalind", + "source_url": "https://rosalind.info/problems/hamm/" +} diff --git a/tests/hamming/using-string-tochararray/expected_analysis.json b/tests/hamming/using-string-tochararray/expected_analysis.json new file mode 100644 index 00000000..14eaad19 --- /dev/null +++ b/tests/hamming/using-string-tochararray/expected_analysis.json @@ -0,0 +1,10 @@ +{"comments": [ + { + "comment": "java.hamming.must_use_string_char_at_or_code_point_at", + "type": "actionable" + }, + { + "comment": "java.general.feedback_request", + "type": "informative" + } +]} \ No newline at end of file diff --git a/tests/hamming/using-string-tochararray/expected_tags.json b/tests/hamming/using-string-tochararray/expected_tags.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/tests/hamming/using-string-tochararray/expected_tags.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/hamming/using-string-tochararray/src/main/java/Hamming.java b/tests/hamming/using-string-tochararray/src/main/java/Hamming.java new file mode 100644 index 00000000..4fc3a9ec --- /dev/null +++ b/tests/hamming/using-string-tochararray/src/main/java/Hamming.java @@ -0,0 +1,35 @@ +import java.util.stream.IntStream; + +/** Optimal solution, but uses String.toCharArray. */ +class Hamming { + private final int hammingDistance; + + Hamming(String leftStrand, String rightStrand) { + validateStrandsHaveEqualLength(leftStrand, rightStrand); + + char[] left = leftStrand.toCharArray(); + char[] right = rightStrand.toCharArray(); + + hammingDistance = (int) IntStream.range(0, leftStrand.length()) + .filter(index -> left[index] != right[index]) + .count(); + } + + private void validateStrandsHaveEqualLength() { + if (leftStrand.length() == rightStrand.length()) { + return; + } + if (leftStrand.isEmpty()) { + throw new IllegalArgumentException("left strand must not be empty."); + } + if (rightStrand.isEmpty()) { + throw new IllegalArgumentException("right strand must not be empty."); + } + throw new IllegalArgumentException( + "leftStrand and rightStrand must be of equal length."); + } + + int getHammingDistance() { + return hammingDistance; + } +} diff --git a/tests/hello-world/README.md b/tests/hello-world/README.md deleted file mode 100644 index d4fede7b..00000000 --- a/tests/hello-world/README.md +++ /dev/null @@ -1 +0,0 @@ -This test is designed to receive no comments at all from the analyzer. diff --git a/tests/hello-world/src/main/java/Greeter.java b/tests/hello-world/src/main/java/Greeter.java deleted file mode 100644 index 1f5a5e00..00000000 --- a/tests/hello-world/src/main/java/Greeter.java +++ /dev/null @@ -1,5 +0,0 @@ -class Greeter { - String getGreeting() { - return "Hello, World!"; - } -} diff --git a/tests/two-fer/README.md b/tests/two-fer/README.md deleted file mode 100644 index 918dc2c4..00000000 --- a/tests/two-fer/README.md +++ /dev/null @@ -1,4 +0,0 @@ -This test is designed to receive comments from multiple analyzers: - -- The global analyzer should complain about the use of a `main` method and print statements -- The `two-fer` analyzer should complain about multiple return statements. diff --git a/tests/two-fer/hard-coded-test-cases/.meta/config.json b/tests/two-fer/hard-coded-test-cases/.meta/config.json new file mode 100644 index 00000000..e5238df8 --- /dev/null +++ b/tests/two-fer/hard-coded-test-cases/.meta/config.json @@ -0,0 +1,39 @@ +{ + "authors": [ + "Smarticles101" + ], + "contributors": [ + "FridaTveit", + "ikhadykin", + "jmrunkle", + "jssander", + "kytrinyx", + "lemoncurry", + "msomji", + "muzimuzhi", + "rdavid1099", + "sjwarner-bp", + "SleeplessByte", + "sshine", + "stkent", + "uzilan", + "Valkryst", + "ymoskovits" + ], + "files": { + "solution": [ + "src/main/java/Twofer.java" + ], + "test": [ + "src/test/java/TwoferTest.java" + ], + "example": [ + ".meta/src/reference/java/Twofer.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Create a sentence of the form \"One for X, one for me.\".", + "source_url": "https://github.com/exercism/problem-specifications/issues/757" +} \ No newline at end of file diff --git a/tests/two-fer/hard-coded-test-cases/expected_analysis.json b/tests/two-fer/hard-coded-test-cases/expected_analysis.json new file mode 100644 index 00000000..2a5979ce --- /dev/null +++ b/tests/two-fer/hard-coded-test-cases/expected_analysis.json @@ -0,0 +1,10 @@ +{"comments": [ + { + "comment": "java.general.avoid_hard_coded_test_cases", + "type": "essential" + }, + { + "comment": "java.general.feedback_request", + "type": "informative" + } +]} \ No newline at end of file diff --git a/tests/two-fer/hard-coded-test-cases/expected_tags.json b/tests/two-fer/hard-coded-test-cases/expected_tags.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/tests/two-fer/hard-coded-test-cases/expected_tags.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/two-fer/hard-coded-test-cases/src/main/java/Twofer.java b/tests/two-fer/hard-coded-test-cases/src/main/java/Twofer.java new file mode 100644 index 00000000..4c013fb6 --- /dev/null +++ b/tests/two-fer/hard-coded-test-cases/src/main/java/Twofer.java @@ -0,0 +1,13 @@ +/** Cannot hard-code the strings. */ +public class Twofer { + public String twofer(String name) { + if (name == null) { + // fall through + } else if (name.equals("Alice")) { + return "One for Alice, one for me."; + } else if (name.equals("Bob")) { + return "One for Bob, one for me."; + } + return "One for you, one for me."; + } +} diff --git a/tests/two-fer/optimal-solution/.meta/config.json b/tests/two-fer/optimal-solution/.meta/config.json new file mode 100644 index 00000000..e5238df8 --- /dev/null +++ b/tests/two-fer/optimal-solution/.meta/config.json @@ -0,0 +1,39 @@ +{ + "authors": [ + "Smarticles101" + ], + "contributors": [ + "FridaTveit", + "ikhadykin", + "jmrunkle", + "jssander", + "kytrinyx", + "lemoncurry", + "msomji", + "muzimuzhi", + "rdavid1099", + "sjwarner-bp", + "SleeplessByte", + "sshine", + "stkent", + "uzilan", + "Valkryst", + "ymoskovits" + ], + "files": { + "solution": [ + "src/main/java/Twofer.java" + ], + "test": [ + "src/test/java/TwoferTest.java" + ], + "example": [ + ".meta/src/reference/java/Twofer.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Create a sentence of the form \"One for X, one for me.\".", + "source_url": "https://github.com/exercism/problem-specifications/issues/757" +} \ No newline at end of file diff --git a/tests/two-fer/optimal-solution/expected_analysis.json b/tests/two-fer/optimal-solution/expected_analysis.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/tests/two-fer/optimal-solution/expected_analysis.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/two-fer/optimal-solution/expected_tags.json b/tests/two-fer/optimal-solution/expected_tags.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/tests/two-fer/optimal-solution/expected_tags.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/two-fer/optimal-solution/src/main/java/Twofer.java b/tests/two-fer/optimal-solution/src/main/java/Twofer.java new file mode 100644 index 00000000..95f4fb91 --- /dev/null +++ b/tests/two-fer/optimal-solution/src/main/java/Twofer.java @@ -0,0 +1,5 @@ +public class Twofer { + public String twofer(String rawName) { + return "One for " + name == null ? "you" : name + ", one for me."; + } +} diff --git a/tests/two-fer/src/main/java/Twofer.java b/tests/two-fer/src/main/java/Twofer.java deleted file mode 100644 index c780a4f8..00000000 --- a/tests/two-fer/src/main/java/Twofer.java +++ /dev/null @@ -1,15 +0,0 @@ -class Twofer { - public String twofer(String name) { - if (name == null) { - return "Two for you, two for me."; - } - - return String.format("Two for %s, two for me.", name); - } - - public static void main(String[] args) { - TwoFer twoFer = new TwoFer(); - System.out.println(twoFer.twofer(null)); - System.out.println(twoFer.twofer("John")); - } -} diff --git a/tests/two-fer/using-if-statement/.meta/config.json b/tests/two-fer/using-if-statement/.meta/config.json new file mode 100644 index 00000000..e5238df8 --- /dev/null +++ b/tests/two-fer/using-if-statement/.meta/config.json @@ -0,0 +1,39 @@ +{ + "authors": [ + "Smarticles101" + ], + "contributors": [ + "FridaTveit", + "ikhadykin", + "jmrunkle", + "jssander", + "kytrinyx", + "lemoncurry", + "msomji", + "muzimuzhi", + "rdavid1099", + "sjwarner-bp", + "SleeplessByte", + "sshine", + "stkent", + "uzilan", + "Valkryst", + "ymoskovits" + ], + "files": { + "solution": [ + "src/main/java/Twofer.java" + ], + "test": [ + "src/test/java/TwoferTest.java" + ], + "example": [ + ".meta/src/reference/java/Twofer.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Create a sentence of the form \"One for X, one for me.\".", + "source_url": "https://github.com/exercism/problem-specifications/issues/757" +} \ No newline at end of file diff --git a/tests/two-fer/using-if-statement/expected_analysis.json b/tests/two-fer/using-if-statement/expected_analysis.json new file mode 100644 index 00000000..77d84dde --- /dev/null +++ b/tests/two-fer/using-if-statement/expected_analysis.json @@ -0,0 +1,10 @@ +{"comments": [ + { + "comment": "java.two-fer.use_ternary_operator", + "type": "actionable" + }, + { + "comment": "java.general.feedback_request", + "type": "informative" + } +]} \ No newline at end of file diff --git a/tests/two-fer/using-if-statement/expected_tags.json b/tests/two-fer/using-if-statement/expected_tags.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/tests/two-fer/using-if-statement/expected_tags.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/two-fer/using-if-statement/src/main/java/Twofer.java b/tests/two-fer/using-if-statement/src/main/java/Twofer.java new file mode 100644 index 00000000..1a8aff27 --- /dev/null +++ b/tests/two-fer/using-if-statement/src/main/java/Twofer.java @@ -0,0 +1,7 @@ +public class Twofer { + public String twofer(String rawName) { + String name = rawName; + if (name == null) name = "you"; + return "One for " + name + ", one for me."; + } +} diff --git a/tests/two-fer/using-multiple-returns/.meta/config.json b/tests/two-fer/using-multiple-returns/.meta/config.json new file mode 100644 index 00000000..e5238df8 --- /dev/null +++ b/tests/two-fer/using-multiple-returns/.meta/config.json @@ -0,0 +1,39 @@ +{ + "authors": [ + "Smarticles101" + ], + "contributors": [ + "FridaTveit", + "ikhadykin", + "jmrunkle", + "jssander", + "kytrinyx", + "lemoncurry", + "msomji", + "muzimuzhi", + "rdavid1099", + "sjwarner-bp", + "SleeplessByte", + "sshine", + "stkent", + "uzilan", + "Valkryst", + "ymoskovits" + ], + "files": { + "solution": [ + "src/main/java/Twofer.java" + ], + "test": [ + "src/test/java/TwoferTest.java" + ], + "example": [ + ".meta/src/reference/java/Twofer.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Create a sentence of the form \"One for X, one for me.\".", + "source_url": "https://github.com/exercism/problem-specifications/issues/757" +} \ No newline at end of file diff --git a/tests/two-fer/using-multiple-returns/expected_analysis.json b/tests/two-fer/using-multiple-returns/expected_analysis.json new file mode 100644 index 00000000..e7bcae52 --- /dev/null +++ b/tests/two-fer/using-multiple-returns/expected_analysis.json @@ -0,0 +1,10 @@ +{"comments": [ + { + "comment": "java.two-fer.use_one_return", + "type": "actionable" + }, + { + "comment": "java.general.feedback_request", + "type": "informative" + } +]} \ No newline at end of file diff --git a/tests/two-fer/using-multiple-returns/expected_tags.json b/tests/two-fer/using-multiple-returns/expected_tags.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/tests/two-fer/using-multiple-returns/expected_tags.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/two-fer/using-multiple-returns/src/main/java/Twofer.java b/tests/two-fer/using-multiple-returns/src/main/java/Twofer.java new file mode 100644 index 00000000..e60a460d --- /dev/null +++ b/tests/two-fer/using-multiple-returns/src/main/java/Twofer.java @@ -0,0 +1,6 @@ +public class Twofer { + public String twofer(String name) { + if (name == null) return "One for you, one for me."; + return "One for " + name + ", one for me."; + } +} diff --git a/tests/two-fer/using-string-format/.meta/config.json b/tests/two-fer/using-string-format/.meta/config.json new file mode 100644 index 00000000..e5238df8 --- /dev/null +++ b/tests/two-fer/using-string-format/.meta/config.json @@ -0,0 +1,39 @@ +{ + "authors": [ + "Smarticles101" + ], + "contributors": [ + "FridaTveit", + "ikhadykin", + "jmrunkle", + "jssander", + "kytrinyx", + "lemoncurry", + "msomji", + "muzimuzhi", + "rdavid1099", + "sjwarner-bp", + "SleeplessByte", + "sshine", + "stkent", + "uzilan", + "Valkryst", + "ymoskovits" + ], + "files": { + "solution": [ + "src/main/java/Twofer.java" + ], + "test": [ + "src/test/java/TwoferTest.java" + ], + "example": [ + ".meta/src/reference/java/Twofer.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Create a sentence of the form \"One for X, one for me.\".", + "source_url": "https://github.com/exercism/problem-specifications/issues/757" +} \ No newline at end of file diff --git a/tests/two-fer/using-string-format/expected_analysis.json b/tests/two-fer/using-string-format/expected_analysis.json new file mode 100644 index 00000000..f2cd1d99 --- /dev/null +++ b/tests/two-fer/using-string-format/expected_analysis.json @@ -0,0 +1,10 @@ +{"comments": [ + { + "comment": "java.two-fer.avoid_string_format", + "type": "actionable" + }, + { + "comment": "java.general.feedback_request", + "type": "informative" + } +]} \ No newline at end of file diff --git a/tests/two-fer/using-string-format/expected_tags.json b/tests/two-fer/using-string-format/expected_tags.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/tests/two-fer/using-string-format/expected_tags.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/two-fer/using-string-format/src/main/java/Twofer.java b/tests/two-fer/using-string-format/src/main/java/Twofer.java new file mode 100644 index 00000000..6fe6875e --- /dev/null +++ b/tests/two-fer/using-string-format/src/main/java/Twofer.java @@ -0,0 +1,5 @@ +public class Twofer { + public String twofer(String name) { + return String.format("One for %s, one for me.", name == null ? "you" : name); + } +} diff --git a/tests/unknown-exercise/README.md b/tests/unknown-exercise/README.md deleted file mode 100644 index 2609a95e..00000000 --- a/tests/unknown-exercise/README.md +++ /dev/null @@ -1,2 +0,0 @@ -This test is designed to analyze a solution for which no exercise analyzer is implemented. -It should still receive feedback from the global analyzer. diff --git a/tests/unknown-exercise/src/main/java/UnknownExercise.java b/tests/unknown-exercise/src/main/java/UnknownExercise.java deleted file mode 100644 index 75afaef6..00000000 --- a/tests/unknown-exercise/src/main/java/UnknownExercise.java +++ /dev/null @@ -1,10 +0,0 @@ -class UnknownExercise { - int calculate() { - return 42; - } - - public static void main(String[] args) { - var exercise = new UnknownExercise(); - System.out.println(exercise.calculate()); - } -} From e035a50580bb914ebc59e6e89ef0be4056ca75e3 Mon Sep 17 00:00:00 2001 From: Sander Ploegsma Date: Sun, 21 Jan 2024 15:59:00 +0100 Subject: [PATCH 2/4] Remove exercise analyzer unit tests --- src/test/java/analyzer/AnalyzerTest.java | 14 +---- .../exercises/GlobalAnalyzerTest.java | 4 +- .../hamming/HammingAnalyzerTest.java | 57 ------------------- .../exercises/twofer/TwoferAnalyzerTest.java | 50 ---------------- .../hamming/ConstructorTooLong.java.txt | 37 ------------ .../DoesNotThrowInConstructor.java.txt | 18 ------ .../exercises/hamming/MethodTooLong.java.txt | 41 ------------- .../MustUseCharAtOrCodePointAt.java.txt | 35 ------------ .../hamming/NestedCalculation.java.txt | 32 ----------- .../hamming/NestedValidation.java.txt | 53 ----------------- .../NoCalculationOfHammingDistance.java.txt | 30 ---------- .../NoConditionalInConstructor.java.txt | 14 ----- .../exercises/hamming/NoConstructor.java.txt | 15 ----- .../NoGetHammingDistanceMethod.java.txt | 6 -- .../exercises/hamming/NoHammingClass.java.txt | 4 -- ...lculationDelegatedFromConstructor.java.txt | 36 ------------ ...onDelegatedFromGetHammingDistance.java.txt | 40 ------------- ...thCalculationInGetHammingDistance.java.txt | 34 ----------- .../OptimalWithValidationMethod.java.txt | 32 ----------- .../hamming/ShouldUseStringIsEmpty.java.txt | 32 ----------- .../hamming/UsesCharacterLiterals.java.txt | 50 ---------------- .../hamming/UsesStreamReduce.java.txt | 34 ----------- .../twofer/HardCodedTestCases.java.txt | 15 ----- .../twofer/NoConditionalLogic.java.txt | 8 --- .../exercises/twofer/NoTwoferClass.java.txt | 4 -- .../exercises/twofer/NoTwoferMethod.java.txt | 6 -- .../exercises/twofer/Optimal.java.txt | 8 --- .../twofer/OptimalNoTernary.java.txt | 10 ---- .../exercises/twofer/UsesLambda.java.txt | 11 ---- .../exercises/twofer/UsesLoop.java.txt | 11 ---- .../twofer/UsesMultipleReturns.java.txt | 9 --- .../twofer/UsesStringFormat.java.txt | 8 --- 32 files changed, 4 insertions(+), 754 deletions(-) delete mode 100644 src/test/java/analyzer/exercises/hamming/HammingAnalyzerTest.java delete mode 100644 src/test/java/analyzer/exercises/twofer/TwoferAnalyzerTest.java delete mode 100644 src/test/resources/analyzer/exercises/hamming/ConstructorTooLong.java.txt delete mode 100644 src/test/resources/analyzer/exercises/hamming/DoesNotThrowInConstructor.java.txt delete mode 100644 src/test/resources/analyzer/exercises/hamming/MethodTooLong.java.txt delete mode 100644 src/test/resources/analyzer/exercises/hamming/MustUseCharAtOrCodePointAt.java.txt delete mode 100644 src/test/resources/analyzer/exercises/hamming/NestedCalculation.java.txt delete mode 100644 src/test/resources/analyzer/exercises/hamming/NestedValidation.java.txt delete mode 100644 src/test/resources/analyzer/exercises/hamming/NoCalculationOfHammingDistance.java.txt delete mode 100644 src/test/resources/analyzer/exercises/hamming/NoConditionalInConstructor.java.txt delete mode 100644 src/test/resources/analyzer/exercises/hamming/NoConstructor.java.txt delete mode 100644 src/test/resources/analyzer/exercises/hamming/NoGetHammingDistanceMethod.java.txt delete mode 100644 src/test/resources/analyzer/exercises/hamming/NoHammingClass.java.txt delete mode 100644 src/test/resources/analyzer/exercises/hamming/OptimalWithCalculationDelegatedFromConstructor.java.txt delete mode 100644 src/test/resources/analyzer/exercises/hamming/OptimalWithCalculationDelegatedFromGetHammingDistance.java.txt delete mode 100644 src/test/resources/analyzer/exercises/hamming/OptimalWithCalculationInGetHammingDistance.java.txt delete mode 100644 src/test/resources/analyzer/exercises/hamming/OptimalWithValidationMethod.java.txt delete mode 100644 src/test/resources/analyzer/exercises/hamming/ShouldUseStringIsEmpty.java.txt delete mode 100644 src/test/resources/analyzer/exercises/hamming/UsesCharacterLiterals.java.txt delete mode 100644 src/test/resources/analyzer/exercises/hamming/UsesStreamReduce.java.txt delete mode 100644 src/test/resources/analyzer/exercises/twofer/HardCodedTestCases.java.txt delete mode 100644 src/test/resources/analyzer/exercises/twofer/NoConditionalLogic.java.txt delete mode 100644 src/test/resources/analyzer/exercises/twofer/NoTwoferClass.java.txt delete mode 100644 src/test/resources/analyzer/exercises/twofer/NoTwoferMethod.java.txt delete mode 100644 src/test/resources/analyzer/exercises/twofer/Optimal.java.txt delete mode 100644 src/test/resources/analyzer/exercises/twofer/OptimalNoTernary.java.txt delete mode 100644 src/test/resources/analyzer/exercises/twofer/UsesLambda.java.txt delete mode 100644 src/test/resources/analyzer/exercises/twofer/UsesLoop.java.txt delete mode 100644 src/test/resources/analyzer/exercises/twofer/UsesMultipleReturns.java.txt delete mode 100644 src/test/resources/analyzer/exercises/twofer/UsesStringFormat.java.txt diff --git a/src/test/java/analyzer/AnalyzerTest.java b/src/test/java/analyzer/AnalyzerTest.java index 899653f6..fe6a312b 100644 --- a/src/test/java/analyzer/AnalyzerTest.java +++ b/src/test/java/analyzer/AnalyzerTest.java @@ -1,25 +1,15 @@ package analyzer; import com.github.javaparser.StaticJavaParser; -import com.github.javaparser.ast.CompilationUnit; import java.util.List; public abstract class AnalyzerTest { protected abstract Analyzer getAnalyzer(); - protected Analysis analyzeResourceFile(String resourceFileName) { - var resource = getClass().getResourceAsStream(resourceFileName); - return analyze(StaticJavaParser.parse(resource)); - } - - protected Analysis analyzeString(String javaCode) { - return analyze(StaticJavaParser.parse(javaCode)); - } - - private Analysis analyze(CompilationUnit compilationUnit) { + protected Analysis analyze(String javaCode) { var analysis = new Analysis(); - getAnalyzer().analyze(List.of(compilationUnit), analysis); + getAnalyzer().analyze(List.of(StaticJavaParser.parse(javaCode)), analysis); return analysis; } } diff --git a/src/test/java/analyzer/exercises/GlobalAnalyzerTest.java b/src/test/java/analyzer/exercises/GlobalAnalyzerTest.java index 33885058..bb81ee88 100644 --- a/src/test/java/analyzer/exercises/GlobalAnalyzerTest.java +++ b/src/test/java/analyzer/exercises/GlobalAnalyzerTest.java @@ -20,7 +20,7 @@ protected Analyzer getAnalyzer() { @MethodSource @ParameterizedTest public void solutionsWithMainMethod(String solution) { - var actual = analyzeString(solution); + var actual = analyze(solution); assertThat(actual.getComments()).contains(new DoNotUseMainMethod()); } @@ -44,7 +44,7 @@ public static void main(String[] args) {} @MethodSource @ParameterizedTest public void solutionsWithPrintStatements(String solution) { - var actual = analyzeString(solution); + var actual = analyze(solution); assertThat(actual.getComments()).contains(new AvoidPrintStatements()); } diff --git a/src/test/java/analyzer/exercises/hamming/HammingAnalyzerTest.java b/src/test/java/analyzer/exercises/hamming/HammingAnalyzerTest.java deleted file mode 100644 index 91bd901f..00000000 --- a/src/test/java/analyzer/exercises/hamming/HammingAnalyzerTest.java +++ /dev/null @@ -1,57 +0,0 @@ -package analyzer.exercises.hamming; - -import analyzer.Analyzer; -import analyzer.Comment; -import analyzer.AnalyzerTest; -import analyzer.comments.ConstructorTooLong; -import analyzer.comments.MethodTooLong; -import analyzer.comments.UseProperClassName; -import analyzer.comments.UseProperMethodName; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import java.util.stream.Stream; - -import static org.assertj.core.api.Assertions.assertThat; - -public class HammingAnalyzerTest extends AnalyzerTest { - @Override - protected Analyzer getAnalyzer() { - return new HammingAnalyzer(); - } - - private static Stream testCases() { - return Stream.of( - Arguments.of("NoHammingClass.java.txt", new Comment[]{new UseProperClassName("Hamming")}), - Arguments.of("NoGetHammingDistanceMethod.java.txt", new Comment[]{new UseProperMethodName("getHammingDistance")}), - Arguments.of("NoConstructor.java.txt", new Comment[]{new MustUseConstructor()}), - Arguments.of("NoConditionalInConstructor.java.txt", new Comment[]{new MustUseConditionalLogicInConstructor()}), - Arguments.of("DoesNotThrowInConstructor.java.txt", new Comment[]{new MustThrowInConstructor()}), - Arguments.of("NoCalculationOfHammingDistance.java.txt", new Comment[]{new MustCalculateHammingDistance()}), - Arguments.of("UsesCharacterLiterals.java.txt", new Comment[]{new AvoidCharacterLiterals()}), - Arguments.of("MustUseCharAtOrCodePointAt.java.txt", new Comment[]{new MustUseStringCharAtOrCodePointAt()}), - Arguments.of("NestedValidation.java.txt", new Comment[]{new CalculateDistanceInConstructor()}), - Arguments.of("NestedCalculation.java.txt", new Comment[0]), - Arguments.of("ShouldUseStringIsEmpty.java.txt", new Comment[]{new ShouldUseStringIsEmpty()}), - Arguments.of("OptimalWithCalculationInGetHammingDistance.java.txt", new Comment[]{new CalculateDistanceInConstructor()}), - Arguments.of("OptimalWithCalculationDelegatedFromGetHammingDistance.java.txt", new Comment[]{new CalculateDistanceInConstructor()}), - Arguments.of("ConstructorTooLong.java.txt", new Comment[]{new ConstructorTooLong("Hamming")}), - Arguments.of("MethodTooLong.java.txt", new Comment[]{new MethodTooLong("calculateHammingDistance")}), - Arguments.of("UsesStreamReduce.java.txt", new Comment[]{new ShouldUseStreamFilterAndCount()}), - Arguments.of("OptimalWithCalculationDelegatedFromConstructor.java.txt", new Comment[0]), - Arguments.of("OptimalWithValidationMethod.java.txt", new Comment[0])); - } - - @MethodSource("testCases") - @ParameterizedTest(name = "{0}") - public void testCommentsOnSolution(String solutionFile, Comment... expectedComments) { - var actual = analyzeResourceFile(getResourceFileName(solutionFile)); - - assertThat(actual.getComments()).containsExactly(expectedComments); - } - - private static String getResourceFileName(String testFileName) { - return "/analyzer/exercises/hamming/" + testFileName; - } -} diff --git a/src/test/java/analyzer/exercises/twofer/TwoferAnalyzerTest.java b/src/test/java/analyzer/exercises/twofer/TwoferAnalyzerTest.java deleted file mode 100644 index 594c8096..00000000 --- a/src/test/java/analyzer/exercises/twofer/TwoferAnalyzerTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package analyzer.exercises.twofer; - -import analyzer.Analyzer; -import analyzer.Comment; -import analyzer.AnalyzerTest; -import analyzer.comments.AvoidHardCodedTestCases; -import analyzer.comments.UseProperClassName; -import analyzer.comments.UseProperMethodName; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import java.util.stream.Stream; - -import static org.assertj.core.api.Assertions.assertThat; - -public class TwoferAnalyzerTest extends AnalyzerTest { - - @Override - protected Analyzer getAnalyzer() { - return new TwoferAnalyzer(); - } - - private static Stream testCases() { - return Stream.of( - Arguments.of("NoTwoferClass.java.txt", new Comment[]{new UseProperClassName("Twofer")}), - Arguments.of("NoTwoferMethod.java.txt", new Comment[]{new UseProperMethodName("twofer")}), - Arguments.of("UsesLambda.java.txt", new Comment[0]), - Arguments.of("UsesLoop.java.txt", new Comment[0]), - Arguments.of("HardCodedTestCases.java.txt", new Comment[]{new AvoidHardCodedTestCases()}), - Arguments.of("NoConditionalLogic.java.txt", new Comment[]{new UseConditionalLogic()}), - Arguments.of("UsesStringFormat.java.txt", new Comment[]{new AvoidStringFormat()}), - Arguments.of("UsesMultipleReturns.java.txt", new Comment[]{new UseOneReturn()}), - Arguments.of("OptimalNoTernary.java.txt", new Comment[]{new UseTernaryOperator()}), - Arguments.of("Optimal.java.txt", new Comment[0]) - ); - } - - @MethodSource("testCases") - @ParameterizedTest(name = "{0}") - public void testCommentsOnSolution(String solutionFile, Comment... expectedComments) { - var actual = analyzeResourceFile(getResourceFileName(solutionFile)); - - assertThat(actual.getComments()).containsExactly(expectedComments); - } - - private static String getResourceFileName(String testFileName) { - return "/analyzer/exercises/twofer/" + testFileName; - } -} diff --git a/src/test/resources/analyzer/exercises/hamming/ConstructorTooLong.java.txt b/src/test/resources/analyzer/exercises/hamming/ConstructorTooLong.java.txt deleted file mode 100644 index 822e460f..00000000 --- a/src/test/resources/analyzer/exercises/hamming/ConstructorTooLong.java.txt +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Optimal solution, but the constructor does too much. - * We use a simple heuristic based on line length. - */ -class Hamming { - private final int hammingDistance; - - Hamming(String leftStrand, String rightStrand) { - if (leftStrand.length() != rightStrand.length()) { - if (leftStrand.isEmpty()) { - throw new IllegalArgumentException("left strand must not be empty."); - } - if (rightStrand.isEmpty()) { - throw new IllegalArgumentException("right strand must not be empty."); - } - throw new IllegalArgumentException( - "leftStrand and rightStrand must be of equal length."); - } - - int distance = 0; - - for (int i = 0; - i < leftStrand.length(); - i++) { - if (leftStrand.charAt(i) - != rightStrand.charAt(i)) { - distance++; - } - } - - hammingDistance = distance; - } - - int getHammingDistance() { - return hammingDistance; - } -} \ No newline at end of file diff --git a/src/test/resources/analyzer/exercises/hamming/DoesNotThrowInConstructor.java.txt b/src/test/resources/analyzer/exercises/hamming/DoesNotThrowInConstructor.java.txt deleted file mode 100644 index 87e1870b..00000000 --- a/src/test/resources/analyzer/exercises/hamming/DoesNotThrowInConstructor.java.txt +++ /dev/null @@ -1,18 +0,0 @@ -import java.util.stream.IntStream; - -/** Constructor must throw IllegalArgumentException. */ -class Hamming { - private final int hammingDistance; - - Hamming(String leftStrand, String rightStrand) { - if (leftStrand.isEmpty()) { - this.hammingDistance = 0; - } else { - this.hammingDistance = 1; - } - } - - int getHammingDistance() { - return hammingDistance; - } -} \ No newline at end of file diff --git a/src/test/resources/analyzer/exercises/hamming/MethodTooLong.java.txt b/src/test/resources/analyzer/exercises/hamming/MethodTooLong.java.txt deleted file mode 100644 index acde91b8..00000000 --- a/src/test/resources/analyzer/exercises/hamming/MethodTooLong.java.txt +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Optimal solution, but the helper method does too much. - * We use a simple heuristic based on line length. - */ -class Hamming { - private final int hammingDistance; - - Hamming(String leftStrand, String rightStrand) { - hammingDistance = calculateHammingDistance(leftStrand, rightStrand); - } - - private int calculateHammingDistance(String leftStrand, String rightStrand) { - if (leftStrand.length() != rightStrand.length()) { - if (leftStrand.isEmpty()) { - throw new IllegalArgumentException("left strand must not be empty."); - } - if (rightStrand.isEmpty()) { - throw new IllegalArgumentException("right strand must not be empty."); - } - throw new IllegalArgumentException( - "leftStrand and rightStrand must be of equal length."); - } - - int distance = 0; - - for (int i = 0; - i < leftStrand.length(); - i++) { - if (leftStrand.charAt(i) - != rightStrand.charAt(i)) { - distance++; - } - } - - return distance; - } - - int getHammingDistance() { - return hammingDistance; - } -} \ No newline at end of file diff --git a/src/test/resources/analyzer/exercises/hamming/MustUseCharAtOrCodePointAt.java.txt b/src/test/resources/analyzer/exercises/hamming/MustUseCharAtOrCodePointAt.java.txt deleted file mode 100644 index b7946ca6..00000000 --- a/src/test/resources/analyzer/exercises/hamming/MustUseCharAtOrCodePointAt.java.txt +++ /dev/null @@ -1,35 +0,0 @@ -import java.util.stream.IntStream; - -/** Optimal solution, but uses String.toCharArray. */ -class Hamming { - private final int hammingDistance; - - Hamming(String leftStrand, String rightStrand) { - validateStrandsHaveEqualLength(leftStrand, rightStrand); - - char[] left = leftStrand.toCharArray(); - char[] right = rightStrand.toCharArray(); - - hammingDistance = (int) IntStream.range(0, leftStrand.length()) - .filter(index -> left[index] != right[index]) - .count(); - } - - private void validateStrandsHaveEqualLength() { - if (leftStrand.length() == rightStrand.length()) { - return; - } - if (leftStrand.isEmpty()) { - throw new IllegalArgumentException("left strand must not be empty."); - } - if (rightStrand.isEmpty()) { - throw new IllegalArgumentException("right strand must not be empty."); - } - throw new IllegalArgumentException( - "leftStrand and rightStrand must be of equal length."); - } - - int getHammingDistance() { - return hammingDistance; - } -} \ No newline at end of file diff --git a/src/test/resources/analyzer/exercises/hamming/NestedCalculation.java.txt b/src/test/resources/analyzer/exercises/hamming/NestedCalculation.java.txt deleted file mode 100644 index e8c2b161..00000000 --- a/src/test/resources/analyzer/exercises/hamming/NestedCalculation.java.txt +++ /dev/null @@ -1,32 +0,0 @@ -class Hamming { - - private int HammingDistance; - - Hamming(String leftStrand, String rightStrand) { - HammingDistance = calculateHammingDistance(leftStrand, rightStrand); - } - - private int calculateHammingDistance(String leftStrand, String rightStrand) { - int distance = 0; - - if (leftStrand.length() == rightStrand.length()) { - for (int i = 0; i < leftStrand.length(); i++) { - if (leftStrand.charAt(i) != rightStrand.charAt(i)) { - distance++; - } - } - } else if (leftStrand.isEmpty()) { - throw new IllegalArgumentException("left strand must not be empty."); - } else if (rightStrand.isEmpty()) { - throw new IllegalArgumentException("right strand must not be empty."); - } else { - throw new IllegalArgumentException("leftStrand and rightStrand must be of equal length."); - } - return distance; - } - - int getHammingDistance() { - return HammingDistance; - } - -} diff --git a/src/test/resources/analyzer/exercises/hamming/NestedValidation.java.txt b/src/test/resources/analyzer/exercises/hamming/NestedValidation.java.txt deleted file mode 100644 index 43bd0a73..00000000 --- a/src/test/resources/analyzer/exercises/hamming/NestedValidation.java.txt +++ /dev/null @@ -1,53 +0,0 @@ -class Hamming { - - private String leftStrand; - private String rightStrand; - - Hamming(String leftStrand, String rightStrand) { - - validate(leftStrand, rightStrand); - this.leftStrand = leftStrand; - this.rightStrand = rightStrand; - } - - - private void validate(String leftStrand, String rightStrand) { - validateNotNull(leftStrand, rightStrand); - validateNotOneEmpty(leftStrand, rightStrand); - validateSameLength(leftStrand, rightStrand); - } - - private void validateNotNull(String leftStrand, String rightStrand) { - if (leftStrand == null || rightStrand == null) { - throw new IllegalArgumentException("Either left or right stand is null"); - } - } - - private void validateNotOneEmpty(String leftStrand, String rightStrand) { - if (leftStrand.isEmpty() && !rightStrand.isEmpty()) { - throw new IllegalArgumentException("left strand must not be empty."); - } else if (!leftStrand.isEmpty() && rightStrand.isEmpty()) { - throw new IllegalArgumentException("right strand must not be empty."); - } - } - - private void validateSameLength(String leftStrand, String rightStrand) { - if (leftStrand.length() != rightStrand.length()) { - throw new IllegalArgumentException("leftStrand and rightStrand must be of equal length."); - } - } - - int getHammingDistance() { - - int strandLen = this.leftStrand.length(); - int diffCount = 0; - for (int i = 0; i < strandLen; i++) { - if (this.leftStrand.charAt(i) != this.rightStrand.charAt(i)) { - diffCount++; - } - } - - return diffCount; - } - -} diff --git a/src/test/resources/analyzer/exercises/hamming/NoCalculationOfHammingDistance.java.txt b/src/test/resources/analyzer/exercises/hamming/NoCalculationOfHammingDistance.java.txt deleted file mode 100644 index 4a62b051..00000000 --- a/src/test/resources/analyzer/exercises/hamming/NoCalculationOfHammingDistance.java.txt +++ /dev/null @@ -1,30 +0,0 @@ -import java.util.stream.IntStream; - -/** Must actually calculate the hamming distance somewhere. */ -class Hamming { - private final int hammingDistance; - - Hamming(String leftStrand, String rightStrand) { - validateStrandsHaveEqualLength(leftStrand, rightStrand); - - hammingDistance = 0; - } - - private void validateStrandsHaveEqualLength() { - if (leftStrand.length() == rightStrand.length()) { - return; - } - if (leftStrand.isEmpty()) { - throw new IllegalArgumentException("left strand must not be empty."); - } - if (rightStrand.isEmpty()) { - throw new IllegalArgumentException("right strand must not be empty."); - } - throw new IllegalArgumentException( - "leftStrand and rightStrand must be of equal length."); - } - - int getHammingDistance() { - return hammingDistance; - } -} \ No newline at end of file diff --git a/src/test/resources/analyzer/exercises/hamming/NoConditionalInConstructor.java.txt b/src/test/resources/analyzer/exercises/hamming/NoConditionalInConstructor.java.txt deleted file mode 100644 index 8d389c12..00000000 --- a/src/test/resources/analyzer/exercises/hamming/NoConditionalInConstructor.java.txt +++ /dev/null @@ -1,14 +0,0 @@ -import java.util.stream.IntStream; - -/** Constructor must have conditional logic. */ -class Hamming { - private final int hammingDistance; - - Hamming(String leftStrand, String rightStrand) { - this.hammingDistance = 0; - } - - int getHammingDistance() { - return hammingDistance; - } -} \ No newline at end of file diff --git a/src/test/resources/analyzer/exercises/hamming/NoConstructor.java.txt b/src/test/resources/analyzer/exercises/hamming/NoConstructor.java.txt deleted file mode 100644 index d38d1bb4..00000000 --- a/src/test/resources/analyzer/exercises/hamming/NoConstructor.java.txt +++ /dev/null @@ -1,15 +0,0 @@ -import java.util.stream.IntStream; - -/** Must use a custom constructor that takes two strings. */ -class Hamming { - private final int hammingDistance; - - /** Not the right type params. */ - Hamming(int hammingDistance) { - this.hammingDistance = hammingDistance; - } - - int getHammingDistance() { - return hammingDistance; - } -} \ No newline at end of file diff --git a/src/test/resources/analyzer/exercises/hamming/NoGetHammingDistanceMethod.java.txt b/src/test/resources/analyzer/exercises/hamming/NoGetHammingDistanceMethod.java.txt deleted file mode 100644 index 56f8cbec..00000000 --- a/src/test/resources/analyzer/exercises/hamming/NoGetHammingDistanceMethod.java.txt +++ /dev/null @@ -1,6 +0,0 @@ -package analyzer.exercises.hamming; - -/** There must be a getHammingDistance method. */ -public class Hamming { - public void notGetHammingDistanceMethod() {} -} \ No newline at end of file diff --git a/src/test/resources/analyzer/exercises/hamming/NoHammingClass.java.txt b/src/test/resources/analyzer/exercises/hamming/NoHammingClass.java.txt deleted file mode 100644 index a2206578..00000000 --- a/src/test/resources/analyzer/exercises/hamming/NoHammingClass.java.txt +++ /dev/null @@ -1,4 +0,0 @@ -package analyzer.exercises.hamming; - -/** There must be a Hamming class. */ -public class NoHammingClass {} \ No newline at end of file diff --git a/src/test/resources/analyzer/exercises/hamming/OptimalWithCalculationDelegatedFromConstructor.java.txt b/src/test/resources/analyzer/exercises/hamming/OptimalWithCalculationDelegatedFromConstructor.java.txt deleted file mode 100644 index bc0417cb..00000000 --- a/src/test/resources/analyzer/exercises/hamming/OptimalWithCalculationDelegatedFromConstructor.java.txt +++ /dev/null @@ -1,36 +0,0 @@ -import java.util.stream.IntStream; - -/** Optimal solution with calculation delegated from constructor. */ -class Hamming { - private final int hammingDistance; - - Hamming(String leftStrand, String rightStrand) { - validateStrandsHaveEqualLength(leftStrand, rightStrand); - - hammingDistance = calculateDistance(leftStrand, rightStrand); - } - - private int calculateDistance(String leftStrand, String rightStrand) { - return (int) IntStream.range(0, leftStrand.length()) - .filter(index -> leftStrand.charAt(index) != rightStrand.charAt(index)) - .count(); - } - - private void validateStrandsHaveEqualLength() { - if (leftStrand.length() == rightStrand.length()) { - return; - } - if (leftStrand.isEmpty()) { - throw new IllegalArgumentException("left strand must not be empty."); - } - if (rightStrand.isEmpty()) { - throw new IllegalArgumentException("right strand must not be empty."); - } - throw new IllegalArgumentException( - "leftStrand and rightStrand must be of equal length."); - } - - int getHammingDistance() { - return hammingDistance; - } -} \ No newline at end of file diff --git a/src/test/resources/analyzer/exercises/hamming/OptimalWithCalculationDelegatedFromGetHammingDistance.java.txt b/src/test/resources/analyzer/exercises/hamming/OptimalWithCalculationDelegatedFromGetHammingDistance.java.txt deleted file mode 100644 index 5e5e3802..00000000 --- a/src/test/resources/analyzer/exercises/hamming/OptimalWithCalculationDelegatedFromGetHammingDistance.java.txt +++ /dev/null @@ -1,40 +0,0 @@ -import java.util.stream.IntStream; - -/** Optimal solution with calculation delegated to getHammingDistance. */ -class Hamming { - private final String leftStrand; - private final String rightStrand; - private Integer hammingDistance; - - Hamming(String leftStrand, String rightStrand) { - validateStrandsHaveEqualLength(leftStrand, rightStrand); - - this.leftStrand = leftStrand; - this.rightStrand = rightStrand; - } - - private void validateStrandsHaveEqualLength() { - if (leftStrand.length() == rightStrand.length()) { - return; - } - if (leftStrand.isEmpty()) { - throw new IllegalArgumentException("left strand must not be empty."); - } - if (rightStrand.isEmpty()) { - throw new IllegalArgumentException("right strand must not be empty."); - } - throw new IllegalArgumentException( - "leftStrand and rightStrand must be of equal length."); - } - - int getHammingDistance() { - if (hammingDistance == null) hammingDistance = calculateDistance(); - return hammingDistance; - } - - private int calculateDistance() { - return (int) IntStream.range(0, leftStrand.length()) - .filter(index -> leftStrand.charAt(index) != rightStrand.charAt(index)) - .count(); - } -} \ No newline at end of file diff --git a/src/test/resources/analyzer/exercises/hamming/OptimalWithCalculationInGetHammingDistance.java.txt b/src/test/resources/analyzer/exercises/hamming/OptimalWithCalculationInGetHammingDistance.java.txt deleted file mode 100644 index 824f039c..00000000 --- a/src/test/resources/analyzer/exercises/hamming/OptimalWithCalculationInGetHammingDistance.java.txt +++ /dev/null @@ -1,34 +0,0 @@ -import java.util.stream.IntStream; - -/** Optimal solution with calculation in getHammingDistance. */ -class Hamming { - private final String leftStrand; - private final String rightStrand; - - Hamming(String leftStrand, String rightStrand) { - validateStrandsHaveEqualLength(leftStrand, rightStrand); - - this.leftStrand = leftStrand; - this.rightStrand = rightStrand; - } - - private void validateStrandsHaveEqualLength() { - if (leftStrand.length() == rightStrand.length()) { - return; - } - if (leftStrand.isEmpty()) { - throw new IllegalArgumentException("left strand must not be empty."); - } - if (rightStrand.isEmpty()) { - throw new IllegalArgumentException("right strand must not be empty."); - } - throw new IllegalArgumentException( - "leftStrand and rightStrand must be of equal length."); - } - - int getHammingDistance() { - return (int) IntStream.range(0, leftStrand.length()) - .filter(index -> leftStrand.charAt(index) != rightStrand.charAt(index)) - .count(); - } -} \ No newline at end of file diff --git a/src/test/resources/analyzer/exercises/hamming/OptimalWithValidationMethod.java.txt b/src/test/resources/analyzer/exercises/hamming/OptimalWithValidationMethod.java.txt deleted file mode 100644 index 9bc80a49..00000000 --- a/src/test/resources/analyzer/exercises/hamming/OptimalWithValidationMethod.java.txt +++ /dev/null @@ -1,32 +0,0 @@ -import java.util.stream.IntStream; - -/** Optimal solution using a method for validation. */ -class Hamming { - private final int hammingDistance; - - Hamming(String leftStrand, String rightStrand) { - validateStrandsHaveEqualLength(leftStrand, rightStrand); - - hammingDistance = (int) IntStream.range(0, leftStrand.length()) - .filter(index -> leftStrand.charAt(index) != rightStrand.charAt(index)) - .count(); - } - - private void validateStrandsHaveEqualLength() { - if (leftStrand.length() == rightStrand.length()) { - return; - } - if (leftStrand.isEmpty()) { - throw new IllegalArgumentException("left strand must not be empty."); - } - if (rightStrand.isEmpty()) { - throw new IllegalArgumentException("right strand must not be empty."); - } - throw new IllegalArgumentException( - "leftStrand and rightStrand must be of equal length."); - } - - int getHammingDistance() { - return hammingDistance; - } -} \ No newline at end of file diff --git a/src/test/resources/analyzer/exercises/hamming/ShouldUseStringIsEmpty.java.txt b/src/test/resources/analyzer/exercises/hamming/ShouldUseStringIsEmpty.java.txt deleted file mode 100644 index 37b222ed..00000000 --- a/src/test/resources/analyzer/exercises/hamming/ShouldUseStringIsEmpty.java.txt +++ /dev/null @@ -1,32 +0,0 @@ -import java.util.stream.IntStream; - -/** Optimal solution, but does not use String.isEmpty. */ -class Hamming { - private final int hammingDistance; - - Hamming(String leftStrand, String rightStrand) { - validateStrandsHaveEqualLength(leftStrand, rightStrand); - - hammingDistance = (int) IntStream.range(0, leftStrand.length()) - .filter(index -> leftStrand.charAt(index) != rightStrand.charAt(index)) - .count(); - } - - private void validateStrandsHaveEqualLength() { - if (leftStrand.length() == rightStrand.length()) { - return; - } - if (leftStrand.length() == 0) { - throw new IllegalArgumentException("left strand must not be empty."); - } - if (rightStrand.length() == 0) { - throw new IllegalArgumentException("right strand must not be empty."); - } - throw new IllegalArgumentException( - "leftStrand and rightStrand must be of equal length."); - } - - int getHammingDistance() { - return hammingDistance; - } -} \ No newline at end of file diff --git a/src/test/resources/analyzer/exercises/hamming/UsesCharacterLiterals.java.txt b/src/test/resources/analyzer/exercises/hamming/UsesCharacterLiterals.java.txt deleted file mode 100644 index 2ab8373f..00000000 --- a/src/test/resources/analyzer/exercises/hamming/UsesCharacterLiterals.java.txt +++ /dev/null @@ -1,50 +0,0 @@ -import java.util.stream.IntStream; - -/** Should not be checking character literals. */ -class Hamming { - private final int hammingDistance; - - Hamming(String leftStrand, String rightStrand) { - validateStrandsHaveEqualLength(leftStrand, rightStrand); - - hammingDistance = calculateHammingDistance(leftStrand, rightStrand); - } - - private int calculateHammingDistance() { - return (int) IntStream.range(0, leftStrand.length()) - .filter(index -> nucleotidesDiffer(leftStrand.charAt(index), rightStrand.charAt(index))) - .count(); - } - - private boolean nucleotidesDiffer(char leftNucleotide, char rightNucleotide) { - switch (leftNucleotide) { - case 'C': - return rightNucleotide == 'A' || rightNucleotide == 'G' || rightNucleotide == 'T'; - case 'A': - return rightNucleotide == 'C' || rightNucleotide == 'G' || rightNucleotide == 'T'; - case 'G': - return rightNucleotide == 'A' || rightNucleotide == 'C' || rightNucleotide == 'T'; - case 'T': - return rightNucleotide == 'A' || rightNucleotide == 'G' || rightNucleotide == 'C'; - } - return false; // unknown nucleotide - } - - private void validateStrandsHaveEqualLength() { - if (leftStrand.length() == rightStrand.length()) { - return; - } - if (leftStrand.isEmpty()) { - throw new IllegalArgumentException("left strand must not be empty."); - } - if (rightStrand.isEmpty()) { - throw new IllegalArgumentException("right strand must not be empty."); - } - throw new IllegalArgumentException( - "leftStrand and rightStrand must be of equal length."); - } - - int getHammingDistance() { - return hammingDistance; - } -} \ No newline at end of file diff --git a/src/test/resources/analyzer/exercises/hamming/UsesStreamReduce.java.txt b/src/test/resources/analyzer/exercises/hamming/UsesStreamReduce.java.txt deleted file mode 100644 index d65d872d..00000000 --- a/src/test/resources/analyzer/exercises/hamming/UsesStreamReduce.java.txt +++ /dev/null @@ -1,34 +0,0 @@ -import java.util.stream.IntStream; - -/** Optimal solution using a method for validation. */ -class Hamming { - private final int hammingDistance; - - Hamming(String leftStrand, String rightStrand) { - validateStrandsHaveEqualLength(leftStrand, rightStrand); - - hammingDistance = (int) IntStream.range(0, leftStrand.length()) - .reduce( - 0, - (acc, i) -> - (leftStrand.charAt(i) != rightStrand.charAt(i)) ? acc + 1 : acc); - } - - private void validateStrandsHaveEqualLength() { - if (leftStrand.length() == rightStrand.length()) { - return; - } - if (leftStrand.isEmpty()) { - throw new IllegalArgumentException("left strand must not be empty."); - } - if (rightStrand.isEmpty()) { - throw new IllegalArgumentException("right strand must not be empty."); - } - throw new IllegalArgumentException( - "leftStrand and rightStrand must be of equal length."); - } - - int getHammingDistance() { - return hammingDistance; - } -} \ No newline at end of file diff --git a/src/test/resources/analyzer/exercises/twofer/HardCodedTestCases.java.txt b/src/test/resources/analyzer/exercises/twofer/HardCodedTestCases.java.txt deleted file mode 100644 index e3945ce5..00000000 --- a/src/test/resources/analyzer/exercises/twofer/HardCodedTestCases.java.txt +++ /dev/null @@ -1,15 +0,0 @@ -package analyzer.exercises.twofer; - -/** Cannot hard-code the strings. */ -public class Twofer { - public String twofer(String name) { - if (name == null) { - // fall through - } else if (name.equals("Alice")) { - return "One for Alice, one for me."; - } else if (name.equals("Bob")) { - return "One for Bob, one for me."; - } - return "One for you, one for me."; - } -} \ No newline at end of file diff --git a/src/test/resources/analyzer/exercises/twofer/NoConditionalLogic.java.txt b/src/test/resources/analyzer/exercises/twofer/NoConditionalLogic.java.txt deleted file mode 100644 index e187582a..00000000 --- a/src/test/resources/analyzer/exercises/twofer/NoConditionalLogic.java.txt +++ /dev/null @@ -1,8 +0,0 @@ -package analyzer.exercises.twofer; - -/** Missing necessary conditional logic. */ -public class Twofer { - public String twofer(String name) { - return "One for you, one for me."; - } -} \ No newline at end of file diff --git a/src/test/resources/analyzer/exercises/twofer/NoTwoferClass.java.txt b/src/test/resources/analyzer/exercises/twofer/NoTwoferClass.java.txt deleted file mode 100644 index 583d314e..00000000 --- a/src/test/resources/analyzer/exercises/twofer/NoTwoferClass.java.txt +++ /dev/null @@ -1,4 +0,0 @@ -package analyzer.exercises.twofer; - -/** Empty class for testing that the class must be named correctly. */ -public class NoTwoferClass {} \ No newline at end of file diff --git a/src/test/resources/analyzer/exercises/twofer/NoTwoferMethod.java.txt b/src/test/resources/analyzer/exercises/twofer/NoTwoferMethod.java.txt deleted file mode 100644 index 698a7265..00000000 --- a/src/test/resources/analyzer/exercises/twofer/NoTwoferMethod.java.txt +++ /dev/null @@ -1,6 +0,0 @@ -package analyzer.exercises.twofer; - -/** Empty class for testing that there must be a twofer method. */ -public class Twofer { - public void notTwoferMethod() {} -} \ No newline at end of file diff --git a/src/test/resources/analyzer/exercises/twofer/Optimal.java.txt b/src/test/resources/analyzer/exercises/twofer/Optimal.java.txt deleted file mode 100644 index 4c4e95a1..00000000 --- a/src/test/resources/analyzer/exercises/twofer/Optimal.java.txt +++ /dev/null @@ -1,8 +0,0 @@ -package analyzer.exercises.twofer; - -/** Optimal solution. */ -public class Twofer { - public String twofer(String rawName) { - return "One for " + name == null ? "you" : name + ", one for me."; - } -} \ No newline at end of file diff --git a/src/test/resources/analyzer/exercises/twofer/OptimalNoTernary.java.txt b/src/test/resources/analyzer/exercises/twofer/OptimalNoTernary.java.txt deleted file mode 100644 index 27294dcb..00000000 --- a/src/test/resources/analyzer/exercises/twofer/OptimalNoTernary.java.txt +++ /dev/null @@ -1,10 +0,0 @@ -package analyzer.exercises.twofer; - -/** Better to use ternary over an if statement. */ -public class Twofer { - public String twofer(String rawName) { - String name = rawName; - if (name == null) name = "you"; - return "One for " + name + ", one for me."; - } -} \ No newline at end of file diff --git a/src/test/resources/analyzer/exercises/twofer/UsesLambda.java.txt b/src/test/resources/analyzer/exercises/twofer/UsesLambda.java.txt deleted file mode 100644 index d66b75fb..00000000 --- a/src/test/resources/analyzer/exercises/twofer/UsesLambda.java.txt +++ /dev/null @@ -1,11 +0,0 @@ -package analyzer.exercises.twofer; - -/** Using lambdas probably deserves a mentor review. */ -public class Twofer { - public String twofer(String name) { - Predicate isNull = s -> s == null; - if (isNull.test(name)) - return "One for you, one for me."; - return "One for " + name + ", one for me."; - } -} \ No newline at end of file diff --git a/src/test/resources/analyzer/exercises/twofer/UsesLoop.java.txt b/src/test/resources/analyzer/exercises/twofer/UsesLoop.java.txt deleted file mode 100644 index 76b9a315..00000000 --- a/src/test/resources/analyzer/exercises/twofer/UsesLoop.java.txt +++ /dev/null @@ -1,11 +0,0 @@ -package analyzer.exercises.twofer; - -/** Using loops deserves mentor review. */ -public class Twofer { - public String twofer(String name) { - for (int i = 0; i < 10; i++) { - // noop - } - return "One for " + name + ", one for me."; - } -} \ No newline at end of file diff --git a/src/test/resources/analyzer/exercises/twofer/UsesMultipleReturns.java.txt b/src/test/resources/analyzer/exercises/twofer/UsesMultipleReturns.java.txt deleted file mode 100644 index 81e2b648..00000000 --- a/src/test/resources/analyzer/exercises/twofer/UsesMultipleReturns.java.txt +++ /dev/null @@ -1,9 +0,0 @@ -package analyzer.exercises.twofer; - -/** Multiple returns are unnecessary. */ -public class Twofer { - public String twofer(String name) { - if (name == null) return "One for you, one for me."; - return "One for " + name + ", one for me."; - } -} \ No newline at end of file diff --git a/src/test/resources/analyzer/exercises/twofer/UsesStringFormat.java.txt b/src/test/resources/analyzer/exercises/twofer/UsesStringFormat.java.txt deleted file mode 100644 index bec68090..00000000 --- a/src/test/resources/analyzer/exercises/twofer/UsesStringFormat.java.txt +++ /dev/null @@ -1,8 +0,0 @@ -package analyzer.exercises.twofer; - -/** String.format is too slow. */ -public class Twofer { - public String twofer(String name) { - return String.format("One for %s, one for me.", name == null ? "you" : name); - } -} \ No newline at end of file From 3f86eee49b076fee94f8ddc6e922e2e07598a54b Mon Sep 17 00:00:00 2001 From: Sander Ploegsma Date: Sun, 21 Jan 2024 15:59:13 +0100 Subject: [PATCH 3/4] Remove checks for correct class/method name --- .../exercises/hamming/HammingAnalyzer.java | 10 ------- .../exercises/hamming/HammingWalker.java | 29 ++++--------------- .../exercises/twofer/TwoferAnalyzer.java | 6 +--- .../exercises/twofer/TwoferWalker.java | 16 ++++------ 4 files changed, 13 insertions(+), 48 deletions(-) diff --git a/src/main/java/analyzer/exercises/hamming/HammingAnalyzer.java b/src/main/java/analyzer/exercises/hamming/HammingAnalyzer.java index 2dc1ca79..45e91855 100644 --- a/src/main/java/analyzer/exercises/hamming/HammingAnalyzer.java +++ b/src/main/java/analyzer/exercises/hamming/HammingAnalyzer.java @@ -20,16 +20,6 @@ public void analyze(List compilationUnits, Analysis analysis) { compilationUnits.forEach(cu -> cu.walk(ClassOrInterfaceDeclaration.class, walker)); - if (!walker.hasHammingClass()) { - analysis.addComment(new UseProperClassName("Hamming")); - return; - } - - if (!walker.hasGetHammingDistanceMethod()) { - analysis.addComment(new UseProperMethodName("getHammingDistance")); - return; - } - if (!walker.hasConstructor()) { analysis.addComment(new MustUseConstructor()); return; diff --git a/src/main/java/analyzer/exercises/hamming/HammingWalker.java b/src/main/java/analyzer/exercises/hamming/HammingWalker.java index a3d39927..25180374 100644 --- a/src/main/java/analyzer/exercises/hamming/HammingWalker.java +++ b/src/main/java/analyzer/exercises/hamming/HammingWalker.java @@ -1,7 +1,5 @@ package analyzer.exercises.hamming; -import static com.google.common.collect.ImmutableSet.toImmutableSet; - import com.github.javaparser.Range; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.body.ConstructorDeclaration; @@ -10,19 +8,12 @@ import com.github.javaparser.ast.expr.LambdaExpr; import com.github.javaparser.ast.expr.MethodCallExpr; import com.github.javaparser.ast.nodeTypes.NodeWithRange; -import com.github.javaparser.ast.stmt.BlockStmt; -import com.github.javaparser.ast.stmt.ForEachStmt; -import com.github.javaparser.ast.stmt.ForStmt; -import com.github.javaparser.ast.stmt.Statement; -import com.github.javaparser.ast.stmt.ThrowStmt; -import com.github.javaparser.ast.stmt.WhileStmt; +import com.github.javaparser.ast.stmt.*; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableListMultimap; import com.google.common.collect.ListMultimap; import com.google.common.collect.Multimaps; -import static com.google.common.collect.MoreCollectors.toOptional; - import java.util.HashSet; import java.util.List; import java.util.Optional; @@ -30,17 +21,19 @@ import java.util.function.Consumer; import java.util.stream.Stream; +import static com.google.common.collect.ImmutableSet.toImmutableSet; +import static com.google.common.collect.MoreCollectors.toOptional; + class HammingWalker implements Consumer { private ClassOrInterfaceDeclaration hammingClass; private List constructors = ImmutableList.of(); private ConstructorDeclaration constructor; private ListMultimap methods = ImmutableListMultimap.of(); - private Set methodsCalledByConstructor = new HashSet<>(); + private final Set methodsCalledByConstructor = new HashSet<>(); private boolean constructorHasIfStatements; private boolean constructorThrowsIllegalArgumentDirectly; private boolean constructorMayCalculateDistanceDirectly; - private MethodDeclaration getHammingDistanceMethod; - private Set methodsCalledByGetHammingDistance = new HashSet<>(); + private final Set methodsCalledByGetHammingDistance = new HashSet<>(); private boolean getHammingDistanceMayCalculateDistanceDirectly; @Override @@ -128,8 +121,6 @@ private Optional findGetHammingDistanceMethod() { } private void walkGetHammingDistanceMethod(MethodDeclaration getHammingDistanceMethod) { - this.getHammingDistanceMethod = getHammingDistanceMethod; - getHammingDistanceMethod.getBody().ifPresent(this::walkGetHammingDistanceMethod); } @@ -178,14 +169,6 @@ private Stream getMethodsCalledBy(BlockStmt body) { .flatMap(this::getMethodCallNames); } - public boolean hasHammingClass() { - return hammingClass != null; - } - - public boolean hasGetHammingDistanceMethod() { - return getHammingDistanceMethod != null; - } - public boolean hasConstructor() { return constructor != null; } diff --git a/src/main/java/analyzer/exercises/twofer/TwoferAnalyzer.java b/src/main/java/analyzer/exercises/twofer/TwoferAnalyzer.java index a2b5a93f..7ba26fad 100644 --- a/src/main/java/analyzer/exercises/twofer/TwoferAnalyzer.java +++ b/src/main/java/analyzer/exercises/twofer/TwoferAnalyzer.java @@ -17,11 +17,7 @@ public void analyze(List compilationUnits, Analysis analysis) { compilationUnits.forEach(cu -> cu.walk(walker)); - if (!walker.hasClassTwofer) { - analysis.addComment(new UseProperClassName("Twofer")); - } else if (!walker.hasMethodTwofer) { - analysis.addComment(new UseProperMethodName("twofer")); - } else if (walker.hasHardCodedTestCases) { + if (walker.hasHardCodedTestCases) { analysis.addComment(new AvoidHardCodedTestCases()); } else if (walker.usesLambda) { // could be used later for additional comments? diff --git a/src/main/java/analyzer/exercises/twofer/TwoferWalker.java b/src/main/java/analyzer/exercises/twofer/TwoferWalker.java index 0be43980..38536a92 100644 --- a/src/main/java/analyzer/exercises/twofer/TwoferWalker.java +++ b/src/main/java/analyzer/exercises/twofer/TwoferWalker.java @@ -1,15 +1,15 @@ package analyzer.exercises.twofer; import com.github.javaparser.ast.Node; -import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; -import com.github.javaparser.ast.body.MethodDeclaration; -import com.github.javaparser.ast.expr.*; +import com.github.javaparser.ast.expr.ConditionalExpr; +import com.github.javaparser.ast.expr.LambdaExpr; +import com.github.javaparser.ast.expr.MethodCallExpr; +import com.github.javaparser.ast.expr.StringLiteralExpr; import com.github.javaparser.ast.stmt.*; + import java.util.function.Consumer; class TwoferWalker implements Consumer { - boolean hasClassTwofer; - boolean hasMethodTwofer; boolean hasHardCodedTestCases; boolean usesIfStatement; boolean usesConditional; @@ -21,11 +21,7 @@ class TwoferWalker implements Consumer { @Override public void accept(Node node) { - if (node instanceof ClassOrInterfaceDeclaration) { - this.hasClassTwofer = ((ClassOrInterfaceDeclaration) node).getName().toString().equals("Twofer"); - } else if (node instanceof MethodDeclaration methodDeclaration && methodDeclaration.getNameAsString().equals("twofer")) { - this.hasMethodTwofer = true; - } else if (node instanceof StringLiteralExpr && !this.hasHardCodedTestCases) { + if (node instanceof StringLiteralExpr && !this.hasHardCodedTestCases) { this.hasHardCodedTestCases = node.toString().contains("Alice") || node.toString().contains("Bob"); } else if (node instanceof ReturnStmt) { this.returnCount++; From c83ab27395ea5c2e08d9efefe0d1e92b4c0ee3d8 Mon Sep 17 00:00:00 2001 From: Sander Ploegsma Date: Mon, 22 Jan 2024 13:57:48 +0100 Subject: [PATCH 4/4] Fix error when src/main/java does not exist in submission --- src/main/java/analyzer/Main.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/analyzer/Main.java b/src/main/java/analyzer/Main.java index 911c6cc7..2710db13 100644 --- a/src/main/java/analyzer/Main.java +++ b/src/main/java/analyzer/Main.java @@ -40,7 +40,12 @@ private static Options validateOptions(String... args) { } private static List parseInput(Options options) throws IOException { - var sourceRoot = new SourceRoot(Path.of(options.inputDirectory, "src/main/java")); + var sourceDirectory = Path.of(options.inputDirectory, "src/main/java"); + if (!sourceDirectory.toFile().exists()) { + return List.of(); + } + + var sourceRoot = new SourceRoot(sourceDirectory); var compilationUnits = new ArrayList(); for (ParseResult parseResult : sourceRoot.tryToParse()) { compilationUnits.add(parseResult.getResult().get());