diff --git a/.github/workflows/check-deprecated-exercises.yml b/.github/workflows/check-deprecated-exercises.yml new file mode 100644 index 000000000..0f011b79e --- /dev/null +++ b/.github/workflows/check-deprecated-exercises.yml @@ -0,0 +1,21 @@ +name: Deprecated + +on: + pull_request: + paths: + - "exercises/**" + push: + branches: + - main + workflow_dispatch: + +jobs: + test-deprecated: + name: Check for deprecated exercises + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 + with: + fetch-depth: 0 + - name: Test deprecated exercises using test-deprecated-exercises + run: bin/test-deprecated-exercises diff --git a/.github/workflows/java.yml b/.github/workflows/java.yml index 1a4953152..598a68e40 100644 --- a/.github/workflows/java.yml +++ b/.github/workflows/java.yml @@ -13,11 +13,11 @@ on: jobs: build: name: Check if tests compile cleanly with starter sources - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 - name: Set up JDK 1.17 - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 + uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e with: java-version: 17 distribution: "temurin" @@ -27,11 +27,11 @@ jobs: lint: name: Lint Java files using Checkstyle - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 - name: Set up JDK 1.17 - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 + uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e with: java-version: 17 distribution: "temurin" @@ -39,16 +39,60 @@ jobs: run: ./gradlew check --exclude-task test --continue working-directory: exercises - test: + test-all: name: Test all exercises using java-test-runner - runs-on: ubuntu-22.04 + if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 - name: Test all exercises using java-test-runner run: bin/test-with-test-runner + - name: Print summary + run: | + if [ -f exercises/build/summary.txt ]; then + echo "===== TEST SUMMARY =====" + cat exercises/build/summary.txt + echo "========================" + else + echo "===== ALL TESTS PASSED =====" + echo "No summary file was generated." + echo "=============================" + fi + if: always() - name: Archive test results - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f with: name: test-results path: exercises/**/build/results.json if: failure() + + test-changed: + name: Test changed exercises using gradlew + if: github.event_name == 'pull_request' + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 + with: + fetch-depth: 0 + - name: Test changed exercises using java-test-runner + run: bin/test-changed-exercise + - name: Print summary + run: | + if [ -f exercises/build/summary.txt ]; then + echo "===== TEST SUMMARY =====" + cat exercises/build/summary.txt + echo "========================" + else + echo "===== ALL TESTS PASSED =====" + echo "No summary file was generated." + echo "=============================" + fi + if: always() + - name: Archive test results + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f + with: + name: test-results + path: | + exercises/**/build/results.txt + exercises/**/build/results.json + if: failure() diff --git a/.github/workflows/markdown.yml b/.github/workflows/markdown.yml index 9bcd9dc76..8339bd4db 100644 --- a/.github/workflows/markdown.yml +++ b/.github/workflows/markdown.yml @@ -15,8 +15,8 @@ permissions: jobs: lint: name: Lint Markdown files - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 - name: Lint markdown - uses: DavidAnson/markdownlint-cli2-action@05f32210e84442804257b2a6f20b273450ec8265 + uses: DavidAnson/markdownlint-cli2-action@07035fd053f7be764496c0f8d8f9f41f98305101 diff --git a/.github/workflows/run-configlet-sync.yml b/.github/workflows/run-configlet-sync.yml new file mode 100644 index 000000000..b49cbffe8 --- /dev/null +++ b/.github/workflows/run-configlet-sync.yml @@ -0,0 +1,10 @@ +name: Run Configlet Sync + +on: + workflow_dispatch: + schedule: + - cron: '0 0 15 * *' + +jobs: + call-gha-workflow: + uses: exercism/github-actions/.github/workflows/configlet-sync.yml@main diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index de4283ca1..56151b2c9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -209,7 +209,7 @@ Each problem/submodule has three source sets: ### Update/sync Gradle versions -Please read [How to Update Gradle](../reference/how-to-update-gradle.md) +Please read [How to Update Gradle](reference/how-to-update-gradle.md) ## Contributing to Concept Exercises diff --git a/POLICIES.md b/POLICIES.md index 14a857e2a..09d803f04 100644 --- a/POLICIES.md +++ b/POLICIES.md @@ -51,7 +51,7 @@ References: [[1](https://github.com/exercism/java/issues/177#issuecomment-261291 > throw new UnsupportedOperationException("Delete this statement and write your own implementation."); > ``` > -> - Exercises of difficulty 5 or higher: copy the StubTemplate.java file (provided [here](https://github.com/exercism/java/blob/main/resources/exercise-template/src/main/java/ExerciseName.java)) and rename it to fit the exercise. For example, for the exercise linked-list the file could be named LinkedList.java. Then either (1) add hints to the hints.md file (which gets merged into the README.md for the exercise) or (2) provide stubs as above for exercises that demand complicated method signatures. +> - Exercises of difficulty 5 or higher: copy the StubTemplate.java file (provided in [this template file](https://github.com/exercism/java/blob/main/resources/exercise-template/src/main/java/ExerciseName.java)) and rename it to fit the exercise. For example, for the exercise linked-list the file could be named LinkedList.java. Then either (1) add hints to the hints.md file (which gets merged into the README.md for the exercise) or (2) provide stubs as above for exercises that demand complicated method signatures. References: [[1](https://github.com/exercism/java/issues/178)], [[2](https://github.com/exercism/java/pull/683#discussion_r125506930)], [[3](https://github.com/exercism/java/issues/977)], [[4](https://github.com/exercism/java/issues/1721)] @@ -108,7 +108,7 @@ References: [[1](https://github.com/exercism/java/issues/365#issuecomment-292533 ### Good first issues -> Aim to keep 10-20 small and straightforward issues open at any given time. Identify any such issues by applying the "good first issue" label. You can view the current list of these issues [here](https://github.com/exercism/java/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22). +> Aim to keep 10-20 small and straightforward issues open at any given time. Identify any such issues by applying the "good first issue" label. You can view the current list of labeled issues [on GitHub](https://github.com/exercism/java/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22). References: [[1](https://github.com/exercism/java/issues/220#issue-196447088)], [[2](https://github.com/exercism/java/issues/1669)] diff --git a/bin/test-changed-exercise b/bin/test-changed-exercise new file mode 100755 index 000000000..b18a488e8 --- /dev/null +++ b/bin/test-changed-exercise @@ -0,0 +1,78 @@ +#!/usr/bin/env bash +set -eo pipefail + +# Determine the base branch of the PR +BASE_BRANCH=${GITHUB_BASE_REF:-main} + +# Fetch full history for proper diff +git fetch origin "$BASE_BRANCH" + +# Compute merge base +MERGE_BASE=$(git merge-base HEAD origin/"$BASE_BRANCH") + +# Get changed files relative to merge base +changed_files=$(git diff --name-only "$MERGE_BASE" HEAD) + +# If any Gradle build file changed, run the full suite and exit +if echo "$changed_files" | grep -qE '\.(gradle|gradlew|bat)$|settings\.gradle'; then + echo "Gradle build files changed, running full test suite..." + ./bin/test-with-test-runner + exit 0 +fi + +# Extract unique exercise directories +changed_exercises=$(echo "$changed_files" | \ + grep -E '^exercises/(practice|concept)/[^/]+/.+\.java$' | \ + cut -d/ -f1-3 | sort -u) + +if [ -z "$changed_exercises" ]; then + echo "No relevant exercises changed, skipping tests." + exit 0 +fi + +# Print exercises +echo "Changed exercises detected:" +echo "$changed_exercises" +echo "----------------------------------------" + +summary_dir="exercises/build" +summary_file="${summary_dir}/summary.txt" +mkdir -p "$summary_dir" + +# Run tests +exit_code=0 +for dir in $changed_exercises; do + slug=$(basename "$dir") + + echo "========================================" + echo "=== Running tests for $slug ===" + echo "========================================" + + results_path="$dir/build/results.txt" + mkdir -p "$(dirname "$results_path")" + + if [[ $dir == exercises/practice/* ]]; then + ./exercises/gradlew -p exercises ":practice:$slug:test" 2>&1 | tee "$results_path" || true + elif [[ $dir == exercises/concept/* ]]; then + ./exercises/gradlew -p exercises ":concept:$slug:test" 2>&1 | tee "$results_path" || true + fi + + # Detect failure + if grep -q "FAILED" "$results_path"; then + exit_code=1 + + # Determine practice/slug or concept/slug + relative_path=$(echo "$dir" | sed 's|^exercises/||') + + # Create summary.txt with header only on first failure + if [ ! -f "$summary_file" ]; then + echo "The following exercises have test failures or test errors:" > "$summary_file" + fi + + # Append the correct path (practice/slug or concept/slug) + echo "$relative_path" >> "$summary_file" + fi + +done + +exit $exit_code \ No newline at end of file diff --git a/bin/test-deprecated-exercises b/bin/test-deprecated-exercises new file mode 100755 index 000000000..5260d6b6c --- /dev/null +++ b/bin/test-deprecated-exercises @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +set -eo pipefail + +# Determine the base branch of the PR +BASE_BRANCH=${GITHUB_BASE_REF:-main} + +# Fetch full history for proper diff +git fetch origin "$BASE_BRANCH" + +# Compute merge base +MERGE_BASE=$(git merge-base HEAD origin/"$BASE_BRANCH") + +# Get changed files relative to merge base +changed_files=$(git diff --name-only "$MERGE_BASE" HEAD) + +# Extract unique exercise directories +changed_exercises=$(echo "$changed_files" | grep -E '^exercises/(practice|concept)/' || true) +changed_exercises=$(echo "$changed_exercises" | cut -d/ -f1-3 | sort -u) + +# Early exit if no exercise changed +if [ -z "$changed_exercises" ]; then + echo "No exercises changed!" + exit 0 +fi + +# Load deprecated exercises from config.json +deprecated_exercises=$(jq -r ' + [ + (.exercises.concept[]? | select(.status=="deprecated") | "exercises/concept/" + .slug), + (.exercises.practice[]? | select(.status=="deprecated") | "exercises/practice/" + .slug) + ] | .[] +' config.json) + +# Check for deprecated ones +for ex in $changed_exercises; do + if echo "$deprecated_exercises" | grep -qx "$ex"; then + echo "❌ Deprecated exercise changed: $ex" + exit 1 + fi +done + +echo "✅ No deprecated exercises changed!" diff --git a/bin/test-with-test-runner b/bin/test-with-test-runner index eed2d74b0..5e5dc8889 100755 --- a/bin/test-with-test-runner +++ b/bin/test-with-test-runner @@ -12,6 +12,10 @@ docker pull exercism/java-test-runner exit_code=0 +summary_dir="exercises/build" +summary_file="${summary_dir}/summary.txt" +mkdir -p "$summary_dir" + function run_test_runner() { local slug=$1 local solution_dir=$2 @@ -56,6 +60,18 @@ function verify_exercise() { if [[ $(jq -r '.status' "${results_file}") != "pass" ]]; then echo "${slug}: ${implementation_file_key} solution did not pass the tests" + + # Determine practice/slug or concept/slug + local relative_path=$(echo "$dir" | sed -E 's|.*/exercises/||') + + # Create summary.txt with header only on first failure + if [ ! -f "$summary_file" ]; then + echo "The following exercises have test failures or test errors:" > "$summary_file" + fi + + # Append the correct path (practice/slug or concept/slug) + echo "$relative_path" >> "$summary_file" + exit_code=1 fi diff --git a/concepts/chars/.meta/config.json b/concepts/chars/.meta/config.json index 7f86b573e..bcf21a72c 100644 --- a/concepts/chars/.meta/config.json +++ b/concepts/chars/.meta/config.json @@ -3,5 +3,7 @@ "authors": [ "ystromm" ], - "contributors": [] + "contributors": [ + "kahgoh" + ] } diff --git a/concepts/chars/about.md b/concepts/chars/about.md index ff5616166..d6ae4bd75 100644 --- a/concepts/chars/about.md +++ b/concepts/chars/about.md @@ -1,6 +1,108 @@ # About -`char`s are generally easy to use. -They can be extracted from strings, added back (by means of a string builder), defined and initialised using literals with single quotes, as in `char ch = 'A';`, assigned and compared. +The Java `char` primitive type is a 16 bit representation of a single Unicode character. -The Character class encapsulates the char value. +~~~~exercism/note +The `char` type is based on the [original Unicode specification][unicode-specification], which used 16 bits to represent characters. +This is enough to cover most of the common letters and covers characters in the range 0x0000 to 0xFFFF. +The specification has since expanded the range of possible characters up to 0x01FFFF. + +[unicode-specification]: https://www.unicode.org/versions/Unicode1.0.0/ +~~~~ + +Multiple `char`s can comprise a string, such as `"word"`, or `char`s can be processed independently. +A `char` literal is surrounded by single quotes (e.g. `'A'`). + +```java +char lowerA = 'a'; +char upperB = 'B'; +``` + +## Getting the `char`s of a `String` + +The `String.toCharArray` method returns a String's chars as an array. +As mentioned in [arrays][concept-arrays], you can use a `for` loop to iterate over the array. + +```java +String text = "Hello"; +char[] asArray = text.toCharArray(); + +for (char ch: asArray) { + System.out.println(ch); +} + +// Outputs: +// H +// e +// l +// l +// o +``` + +## The [Character][docs-character] class + +There are many builtin library methods to inspect and manipulate `char`s. +These can be found as static methods of the [`java.lang.Character`][docs-character] class. +Here are some examples: + +```java +Character.isWhitespace(' '); // true +Character.isWhitespace('#'); // false + +Character.isLetter('a'); // true +Character.isLetter('3'); // false + +Character.isDigit('6'); // true +Character.isDigit('?'); // false +``` + +~~~~exercism/note +Some methods in the Character class have an overload so that it can take either an `char` or `int`. +For example, `isDigit` has one that accepts a [`char`][is-digit-char] and another an [`int`][is-digit-int]. +As mentioned earlier, the `char` type can only represent the characters in the range from 0x0000 to 0xFFFF. +The `int`, however, can represent all characters, hence the `int` overloads. + +[is-digit-char]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Character.html#isDigit(char) +[is-digit-int]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Character.html#isDigit(int) +~~~~ + +## Adding a `char` to a `String` + +The `+` operator can be used to add a `char` to a `String`. + +```java +'a' + " banana" // => "a banana" +"banana " + 'a' // => "banana a" +``` + +~~~~exercism/caution +Becareful _not_ to use `+` to join two `char`s together to form a `String`! +Adding two `char`s this way gives an `int`, _not_ a `String`! +For example: + +```java +'b' + 'c'; +// => 197 (not the String "bc") +``` + +This is because Java promotes the `char` to an `int` (see [4.2 Primitive Types and Values ][jls-primitives] of the [Java Language Specification][jls-main]). + +[jls-main]: https://docs.oracle.com/javase/specs/jls/se21/html/ +[jls-primitives]: https://docs.oracle.com/javase/specs/jls/se21/html/jls-4.html#jls-4.2 +~~~~ + +However, when there are many characters to be added, it can be more efficient to use a [`StringBuilder`][docs-stringBuilder] instead: + +```java +StringBuilder builder = new StringBuilder(); +builder.append('a'); +builder.append('b'); +builder.append('c'); + +String builtString = builder.toString(); +// => abc +``` + +[concept-arrays]: https://exercism.org/tracks/java/concepts/arrays +[docs-character]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Character.html +[docs-stringBuilder]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/StringBuilder.html diff --git a/concepts/chars/introduction.md b/concepts/chars/introduction.md index 12fdaf086..bb80baba7 100644 --- a/concepts/chars/introduction.md +++ b/concepts/chars/introduction.md @@ -1,12 +1,87 @@ # Introduction -The Java `char` type represents the smallest addressable components of text. -Multiple `char`s can comprise a string such as `"word"` or `char`s can be processed independently. -Their literals have single quotes e.g. `'A'`. +## chars + +The Java `char` primitive type is a 16 bit representation of a single character. +Multiple `char`s can comprise a string, such as `"word"`, or `char`s can be processed independently. +A `char` literal is surrounded by single quotes (e.g. `'A'`). + +```java +char lowerA = 'a'; +char upperB = 'B'; +``` + +## Getting the `char`s of a `String` + +The `String.toCharArray` method returns a String's chars as an array. +As mentioned in arrays, you can use a `for` loop to iterate over the array. + +```java +String text = "Hello"; +char[] asArray = text.toCharArray(); + +for (char ch: asArray) { + System.out.println(ch); +} + +// Outputs: +// H +// e +// l +// l +// o +``` + +## The Character class There are many builtin library methods to inspect and manipulate `char`s. These can be found as static methods of the `java.lang.Character` class. +Here are some examples: + +```java +Character.isWhitespace(' '); // true +Character.isWhitespace('#'); // false + +Character.isLetter('a'); // true +Character.isLetter('3'); // false + +Character.isDigit('6'); // true +Character.isDigit('?'); // false +``` + +## Adding a `char` to a `String` + +The `+` operator can be used to add a `char` to a `String`. + +```java +'a' + " banana" // => "a banana" +"banana " + 'a' // => "banana a" +``` + +~~~~exercism/caution +Becareful _not_ to use `+` to join two `char`s together to form a `String`! +Adding two `char`s this way gives an `int`, _not_ a `String`! +For example: + +```java +'b' + 'c'; +// => 197 (not the String "bc") +``` + +This is because Java promotes the `char` to an `int` (see [4.2 Primitive Types and Values ][jls-primitives] of the [Java Language Specification][jls-main]). + +[jls-main]: https://docs.oracle.com/javase/specs/jls/se21/html/ +[jls-primitives]: https://docs.oracle.com/javase/specs/jls/se21/html/jls-4.html#jls-4.2 +~~~~ + +However, when there are many characters to be added, it can be more efficient to use a `StringBuilder` instead: + +```java +StringBuilder builder = new StringBuilder(); +builder.append('a'); +builder.append('b'); +builder.append('c'); -`char`s are sometimes used in conjunction with a `StringBuilder` object. -This object has methods that allow a string to be constructed character by character and manipulated. -At the end of the process `toString` can be called on it to output a complete string. +String builtString = builder.toString(); +// => abc +``` diff --git a/concepts/chars/links.json b/concepts/chars/links.json index bf2b4a182..b78281499 100644 --- a/concepts/chars/links.json +++ b/concepts/chars/links.json @@ -1,12 +1,10 @@ [ { - "url":"https://docs.oracle.com/javase/8/docs/api/java/lang/Character.html", + "url":"https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Character.html", "description":"javadoc" }, { - "url": "https://docs.oracle.com/javase/tutorial/i18n/text/unicode.html", - "description": "unicode" + "url": "https://dev.java/learn/numbers-strings/characters/", + "description": "characters" } - - ] diff --git a/concepts/classes/introduction.md b/concepts/classes/introduction.md index 7a488babe..08c04a5aa 100644 --- a/concepts/classes/introduction.md +++ b/concepts/classes/introduction.md @@ -33,7 +33,7 @@ class Car { ``` One can optionally assign an initial value to a field. -If a field does _not_ specify an initial value, it wll be set to its type's default value. +If a field does _not_ specify an initial value, it will be set to its type's default value. An instance's field values can be accessed and updated using dot-notation. ```java diff --git a/concepts/datetime/about.md b/concepts/datetime/about.md index 2724d5cdb..8ab1fbad6 100644 --- a/concepts/datetime/about.md +++ b/concepts/datetime/about.md @@ -47,13 +47,13 @@ These methods return a _new_ `LocalDate` instance and do not update the existing ```java LocalDate date = LocalDate.of(2007, 12, 3); -date.addDays(3); +date.plusDays(3); // => 2007-12-06 -date.addMonths(1); +date.plusMonths(1); // => 2008-01-03 -date.addYears(1); +date.plusYears(1); // => 2008-12-03 ``` diff --git a/concepts/datetime/introduction.md b/concepts/datetime/introduction.md index afb15b114..2b9513189 100644 --- a/concepts/datetime/introduction.md +++ b/concepts/datetime/introduction.md @@ -41,7 +41,7 @@ These methods return a _new_ `LocalDate` instance and do not update the existing ```java LocalDate date = LocalDate.of(2007, 12, 3); -date.addDays(3); +date.plusDays(3); // => 2007-12-06 ``` diff --git a/concepts/exceptions/.meta/config.json b/concepts/exceptions/.meta/config.json index 1c6bc8bb3..ef26a0098 100644 --- a/concepts/exceptions/.meta/config.json +++ b/concepts/exceptions/.meta/config.json @@ -1,5 +1,5 @@ { "blurb": "Exceptions are thrown when an error that needs special handling occurs.", "authors": ["sanderploegsma"], - "contributors": [] + "contributors": ["BahaaMohamed98"] } diff --git a/concepts/exceptions/about.md b/concepts/exceptions/about.md index 96e2bc4a5..d3a4f5946 100644 --- a/concepts/exceptions/about.md +++ b/concepts/exceptions/about.md @@ -8,11 +8,12 @@ An exception is an event that occurs during the execution of a program that disr Exceptions are raised explicitly in Java, and the act of raising an exception is called _throwing an exception_. The act of handling an exception is called _catching an exception_. -Java distinguishes three types of exceptions: +In Java, all exceptions are subclasses of the `Exception` class, which itself is a subclass of `Throwable`. + +Java distinguishes two types of exceptions: 1. Checked exceptions 2. Unchecked exceptions -3. Errors ### Checked exceptions @@ -21,7 +22,7 @@ An example of a checked exception is the `FileNotFoundException` which occurs wh This type of exception is checked at compile-time: methods that throw checked exceptions should specify this in their method signature, and code calling a method that might throw a checked exception is required to handle it or the code will not compile. -All exceptions in Java that do not inherit from `RuntimeException` or `Error` are considered checked exceptions. +All checked exceptions are subclasses of `Exception` that do not extend `RuntimeException`. ### Unchecked exceptions @@ -30,17 +31,7 @@ An example of an unchecked exception is the `NullPointerException` which occurs This type of exception is not checked at compile-time: methods that throw unchecked exceptions are not required to specify this in their method signature, and code calling a method that might throw an unchecked exception is not required to handle it. -All exceptions in Java that inherit from `RuntimeException` are considered unchecked exceptions. - -### Errors - -_Errors_ are exceptional conditions that are external to an application. -An example of an error is the `OutOfMemoryError` which occurs when an application is trying to use more memory than is available on the system. - -Like unchecked exceptions, errors are not checked at compile-time. -They are not usually thrown from application code. - -All exceptions in Java that inherit from `Error` are considered errors. +All unchecked exceptions inherit from `RuntimeException`, which itself is an extension of `Exception`. ## Throwing exceptions @@ -135,6 +126,17 @@ Withdrawal failed: Cannot withdraw a negative amount Current balance: 5.0 ``` +## Errors + +Java also has a separate category called _Errors_ which are serious problems that are external to an application. +An example of an error is the `OutOfMemoryError` which occurs when an application is trying to use more memory than is available on the system. + +Like unchecked exceptions, errors are not checked at compile-time. +The difference is that they represent system level problems and are generally thrown by the Java Virtual machine or environment instead of the application. +Applications should generally not attempt to catch or handle them. + +All errors in Java inherit from the `Error` class. + ## When not to use exceptions As stated previously, exceptions are events that disrupt the normal flow of instructions, and are used to handle _exceptional events_. diff --git a/concepts/exceptions/introduction.md b/concepts/exceptions/introduction.md index 586f6f1ea..c50113113 100644 --- a/concepts/exceptions/introduction.md +++ b/concepts/exceptions/introduction.md @@ -8,11 +8,12 @@ An exception is an event that occurs during the execution of a program that disr Exceptions are raised explicitly in Java, and the act of raising an exception is called _throwing an exception_. The act of handling an exception is called _catching an exception_. -Java distinguishes three types of exceptions: +In Java, all exceptions are subclasses of the `Exception` class, which itself is a subclass of `Throwable`. + +Java distinguishes two types of exceptions: 1. Checked exceptions 2. Unchecked exceptions -3. Errors ### Checked exceptions @@ -21,7 +22,7 @@ An example of a checked exception is the `FileNotFoundException` which occurs wh This type of exception is checked at compile-time: methods that throw checked exceptions should specify this in their method signature, and code calling a method that might throw a checked exception is required to handle it or the code will not compile. -All exceptions in Java that do not inherit from `RuntimeException` or `Error` are considered checked exceptions. +All checked exceptions are subclasses of `Exception` that do not extend `RuntimeException`. ### Unchecked exceptions @@ -30,17 +31,7 @@ An example of an unchecked exception is the `NullPointerException` which occurs This type of exception is not checked at compile-time: methods that throw unchecked exceptions are not required to specify this in their method signature, and code calling a method that might throw an unchecked exception is not required to handle it. -All exceptions in Java that inherit from `RuntimeException` are considered unchecked exceptions. - -### Errors - -_Errors_ are exceptional conditions that are external to an application. -An example of an error is the `OutOfMemoryError` which occurs when an application is trying to use more memory than is available on the system. - -Like unchecked exceptions, errors are not checked at compile-time. -They are not usually thrown from application code. - -All exceptions in Java that inherit from `Error` are considered errors. +All unchecked exceptions inherit from `RuntimeException`, which itself is an extension of `Exception`. ## Throwing exceptions @@ -134,3 +125,14 @@ Withdrawing -10.0 Withdrawal failed: Cannot withdraw a negative amount Current balance: 5.0 ``` + +## Errors + +Java also has a separate category called _Errors_ which are serious problems that are external to an application. +An example of an error is the `OutOfMemoryError` which occurs when an application is trying to use more memory than is available on the system. + +Like unchecked exceptions, errors are not checked at compile-time. +The difference is that they represent system level problems and are generally thrown by the Java Virtual machine or environment instead of the application. +Applications should generally not attempt to catch or handle them. + +All errors in Java inherit from the `Error` class. diff --git a/concepts/inheritance/about.md b/concepts/inheritance/about.md index 4d1698bb8..bd6dd590e 100644 --- a/concepts/inheritance/about.md +++ b/concepts/inheritance/about.md @@ -18,7 +18,7 @@ There are four access modifiers: - `protected` - default (No keyword required) -You can read more about them [here][access-modifiers] +You can read more about them [in this article][access-modifiers] ## Inheritance vs Composition diff --git a/concepts/switch-statement/about.md b/concepts/switch-statement/about.md index 9d53f54cb..2c89c5c04 100644 --- a/concepts/switch-statement/about.md +++ b/concepts/switch-statement/about.md @@ -145,7 +145,7 @@ Starting with Java 14 (available as a preview before in Java 12 and 13) it is po However if you use the new `->` notation it must be followed by either: a single statement/expression, a `throw` statement or a `{}` block. No more confusion! -You can find more information on enhanced switch [here][switch1], [here][switch2] and on the [oracle documentation][oracle-doc]. +You can find more information on enhanced switch in [this article][switch1] and [this one][switch2], along with the official [Oracle documentation][oracle-doc]. In addition, a feature called `Guarded Patterns` was added in Java 21, which allows you to do checks in the case label itself. @@ -160,7 +160,7 @@ return switch (day) { }; ``` -You can find more information on the switch expression on Java 21 [here][switch-on-Java-21] +You can find more information on the switch expression on Java 21 in [this blog][switch-on-Java-21] [yield-keyword]: https://www.codejava.net/java-core/the-java-language/yield-keyword-in-java [switch1]: https://www.vojtechruzicka.com/java-enhanced-switch/ diff --git a/config.json b/config.json index 7c8f6b933..92dfd05b1 100644 --- a/config.json +++ b/config.json @@ -105,6 +105,7 @@ "chars" ], "prerequisites": [ + "arrays", "strings" ], "status": "active" @@ -809,6 +810,16 @@ ], "difficulty": 4 }, + { + "slug": "rate-limiter", + "name": "Rate Limiter", + "uuid": "b4b0c60e-4ce1-488e-948f-bcb6821c773c", + "practices": [], + "prerequisites": [ + "generic-types" + ], + "difficulty": 4 + }, { "slug": "rotational-cipher", "name": "Rotational Cipher", @@ -842,6 +853,17 @@ ], "difficulty": 4 }, + { + "slug": "split-second-stopwatch", + "name": "Split-Second Stopwatch", + "uuid": "9510c0ae-9977-4260-8991-0e8e849094b0", + "practices": [], + "prerequisites": [ + "exceptions", + "if-else-statements" + ], + "difficulty": 4 + }, { "slug": "sum-of-multiples", "name": "Sum of Multiples", @@ -854,6 +876,18 @@ ], "difficulty": 4 }, + { + "slug": "swift-scheduling", + "name": "Swift Scheduling", + "uuid": "7f5388dc-ce0e-40d4-98d1-7a00aeae018d", + "practices": [], + "prerequisites": [ + "if-else-statements", + "datetime", + "strings" + ], + "difficulty": 4 + }, { "slug": "triangle", "name": "Triangle", @@ -1054,6 +1088,19 @@ ], "difficulty": 5 }, + { + "slug": "relative-distance", + "name": "Relative Distance", + "uuid": "a3cf95fd-c7c1-4199-a253-7bae8d1aba9a", + "practices": [ + "maps" + ], + "prerequisites": [ + "lists", + "maps" + ], + "difficulty": 5 + }, { "slug": "robot-name", "name": "Robot Name", @@ -1164,6 +1211,20 @@ ], "difficulty": 6 }, + { + "slug": "baffling-birthdays", + "name": "Baffling Birthdays", + "uuid": "b534049a-5920-4906-9091-0fa6d81a3636", + "practices": [], + "prerequisites": [ + "for-loops", + "lists", + "sets", + "randomness", + "datetime" + ], + "difficulty": 6 + }, { "slug": "bank-account", "name": "Bank Account", @@ -1226,6 +1287,18 @@ ], "difficulty": 6 }, + { + "slug": "flower-field", + "name": "Flower Field", + "uuid": "bddd180a-d634-454a-af03-4d625f77e1e2", + "practices": [], + "prerequisites": [ + "constructors", + "lists", + "strings" + ], + "difficulty": 6 + }, { "slug": "food-chain", "name": "Food Chain", @@ -1259,6 +1332,14 @@ ], "difficulty": 6 }, + { + "slug": "intergalactic-transmission", + "name": "Intergalactic Transmission", + "uuid": "b1c6dfc2-414b-45b2-9277-8b9f8bb3bcf3", + "practices": [], + "prerequisites": [], + "difficulty": 6 + }, { "slug": "linked-list", "name": "Linked List", @@ -1276,12 +1357,9 @@ "name": "Minesweeper", "uuid": "416a1489-12af-4593-8540-0f55285c96b4", "practices": [], - "prerequisites": [ - "constructors", - "lists", - "strings" - ], - "difficulty": 6 + "prerequisites": [], + "difficulty": 6, + "status": "deprecated" }, { "slug": "parallel-letter-frequency", @@ -1294,6 +1372,18 @@ ], "difficulty": 6 }, + { + "slug": "piecing-it-together", + "name": "Piecing It Together", + "uuid": "be303729-ad8a-4f4c-a235-6828a6734f05", + "practices": [], + "prerequisites": [ + "exceptions", + "for-loops", + "if-else-statements" + ], + "difficulty": 6 + }, { "slug": "queen-attack", "name": "Queen Attack", diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md index 239409351..57cf6d012 100644 --- a/docs/INSTALLATION.md +++ b/docs/INSTALLATION.md @@ -9,7 +9,7 @@ Here at Exercism we recommend using [Eclipse Temurin by Adoptium][adoptium]. ## Supported Java versions -Exercism's Java track supports Java 21 LTS and earlier. +Exercism's Java track supports Java 25 LTS and earlier. ## Installing Eclipse Temurin diff --git a/exercises/build.gradle b/exercises/build.gradle index 734815214..c35dc4fc1 100644 --- a/exercises/build.gradle +++ b/exercises/build.gradle @@ -79,7 +79,7 @@ subprojects { // configuration of the linter checkstyle { toolVersion '10.7.0' - configFile file("checkstyle.xml") + configFile file("$rootDir/checkstyle.xml") sourceSets = [project.sourceSets.main, project.sourceSets.test] } diff --git a/exercises/checkstyle.xml b/exercises/checkstyle.xml index aee09b5d8..8746c0e28 100644 --- a/exercises/checkstyle.xml +++ b/exercises/checkstyle.xml @@ -155,7 +155,7 @@ page at http://checkstyle.sourceforge.net/config.html --> - + diff --git a/exercises/concept/annalyns-infiltration/gradle/wrapper/gradle-wrapper.jar b/exercises/concept/annalyns-infiltration/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/concept/annalyns-infiltration/gradle/wrapper/gradle-wrapper.jar and b/exercises/concept/annalyns-infiltration/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/concept/annalyns-infiltration/gradle/wrapper/gradle-wrapper.properties b/exercises/concept/annalyns-infiltration/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/concept/annalyns-infiltration/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/concept/annalyns-infiltration/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/concept/annalyns-infiltration/gradlew b/exercises/concept/annalyns-infiltration/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/concept/annalyns-infiltration/gradlew +++ b/exercises/concept/annalyns-infiltration/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/concept/annalyns-infiltration/gradlew.bat b/exercises/concept/annalyns-infiltration/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/concept/annalyns-infiltration/gradlew.bat +++ b/exercises/concept/annalyns-infiltration/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/concept/annalyns-infiltration/src/test/java/AnnalynsInfiltrationTest.java b/exercises/concept/annalyns-infiltration/src/test/java/AnnalynsInfiltrationTest.java index 4f7fe3864..7514451bf 100644 --- a/exercises/concept/annalyns-infiltration/src/test/java/AnnalynsInfiltrationTest.java +++ b/exercises/concept/annalyns-infiltration/src/test/java/AnnalynsInfiltrationTest.java @@ -9,7 +9,7 @@ public class AnnalynsInfiltrationTest { @Test @Tag("task:1") @DisplayName("The canFastAttack method returns false when knight is awake") - public void cannot_execute_fast_attack_if_knight_is_awake() { + public void cannotExecuteFastAttackIfKnightIsAwake() { boolean knightIsAwake = true; assertThat(AnnalynsInfiltration.canFastAttack(knightIsAwake)).isFalse(); } @@ -17,7 +17,7 @@ public void cannot_execute_fast_attack_if_knight_is_awake() { @Test @Tag("task:1") @DisplayName("The canFastAttack method returns true when knight is sleeping") - public void can_execute_fast_attack_if_knight_is_sleeping() { + public void canExecuteFastAttackIfKnightIsSleeping() { boolean knightIsAwake = false; assertThat(AnnalynsInfiltration.canFastAttack(knightIsAwake)).isTrue(); } @@ -25,7 +25,7 @@ public void can_execute_fast_attack_if_knight_is_sleeping() { @Test @Tag("task:2") @DisplayName("The canSpy method returns false when everyone is sleeping") - public void cannot_spy_if_everyone_is_sleeping() { + public void cannotSpyIfEveryoneIsSleeping() { boolean knightIsAwake = false; boolean archerIsAwake = false; boolean prisonerIsAwake = false; @@ -35,7 +35,7 @@ public void cannot_spy_if_everyone_is_sleeping() { @Test @Tag("task:2") @DisplayName("The canSpy method returns true when everyone but knight is sleeping") - public void can_spy_if_everyone_but_knight_is_sleeping() { + public void canSpyIfEveryoneButKnightIsSleeping() { boolean knightIsAwake = true; boolean archerIsAwake = false; boolean prisonerIsAwake = false; @@ -45,7 +45,7 @@ public void can_spy_if_everyone_but_knight_is_sleeping() { @Test @Tag("task:2") @DisplayName("The canSpy method returns true when everyone but archer is sleeping") - public void can_spy_if_everyone_but_archer_is_sleeping() { + public void canSpyIfEveryoneButArcherIsSleeping() { boolean knightIsAwake = false; boolean archerIsAwake = true; boolean prisonerIsAwake = false; @@ -55,7 +55,7 @@ public void can_spy_if_everyone_but_archer_is_sleeping() { @Test @Tag("task:2") @DisplayName("The canSpy method returns true when everyone but prisoner is sleeping") - public void can_spy_if_everyone_but_prisoner_is_sleeping() { + public void canSpyIfEveryoneButPrisonerIsSleeping() { boolean knightIsAwake = false; boolean archerIsAwake = false; boolean prisonerIsAwake = true; @@ -65,7 +65,7 @@ public void can_spy_if_everyone_but_prisoner_is_sleeping() { @Test @Tag("task:2") @DisplayName("The canSpy method returns true when only knight is sleeping") - public void can_spy_if_only_knight_is_sleeping() { + public void canSpyIfOnlyKnightIsSleeping() { boolean knightIsAwake = false; boolean archerIsAwake = true; boolean prisonerIsAwake = true; @@ -75,7 +75,7 @@ public void can_spy_if_only_knight_is_sleeping() { @Test @Tag("task:2") @DisplayName("The canSpy method returns true when only archer is sleeping") - public void can_spy_if_only_archer_is_sleeping() { + public void canSpyIfOnlyArcherIsSleeping() { boolean knightIsAwake = true; boolean archerIsAwake = false; boolean prisonerIsAwake = true; @@ -85,7 +85,7 @@ public void can_spy_if_only_archer_is_sleeping() { @Test @Tag("task:2") @DisplayName("The canSpy method returns true when only prisoner is sleeping") - public void can_spy_if_only_prisoner_is_sleeping() { + public void canSpyIfOnlyPrisonerIsSleeping() { boolean knightIsAwake = true; boolean archerIsAwake = true; boolean prisonerIsAwake = false; @@ -95,7 +95,7 @@ public void can_spy_if_only_prisoner_is_sleeping() { @Test @Tag("task:2") @DisplayName("The canSpy method returns true when everyone is awake") - public void can_spy_if_everyone_is_awake() { + public void canSpyIfEveryoneIsAwake() { boolean knightIsAwake = true; boolean archerIsAwake = true; boolean prisonerIsAwake = true; @@ -105,7 +105,7 @@ public void can_spy_if_everyone_is_awake() { @Test @Tag("task:3") @DisplayName("The canSignalPrisoner method returns true when prisoner is awake and archer is sleeping") - public void can_signal_prisoner_if_archer_is_sleeping_and_prisoner_is_awake() { + public void canSignalPrisonerIfArcherIsSleepingAndPrisonerIsAwake() { boolean archerIsAwake = false; boolean prisonerIsAwake = true; assertThat(AnnalynsInfiltration.canSignalPrisoner(archerIsAwake, prisonerIsAwake)).isTrue(); @@ -114,7 +114,7 @@ public void can_signal_prisoner_if_archer_is_sleeping_and_prisoner_is_awake() { @Test @Tag("task:3") @DisplayName("The canSignalPrisoner method returns false when prisoner is sleeping and archer is awake") - public void cannot_signal_prisoner_if_archer_is_awake_and_prisoner_is_sleeping() { + public void cannotSignalPrisonerIfArcherIsAwakeAndPrisonerIsSleeping() { boolean archerIsAwake = true; boolean prisonerIsAwake = false; assertThat(AnnalynsInfiltration.canSignalPrisoner(archerIsAwake, prisonerIsAwake)).isFalse(); @@ -123,7 +123,7 @@ public void cannot_signal_prisoner_if_archer_is_awake_and_prisoner_is_sleeping() @Test @Tag("task:3") @DisplayName("The canSignalPrisoner method returns false when both prisoner and archer are sleeping") - public void cannot_signal_prisoner_if_archer_and_prisoner_are_both_sleeping() { + public void cannotSignalPrisonerIfArcherAndPrisonerAreBothSleeping() { boolean archerIsAwake = false; boolean prisonerIsAwake = false; assertThat(AnnalynsInfiltration.canSignalPrisoner(archerIsAwake, prisonerIsAwake)).isFalse(); @@ -132,7 +132,7 @@ public void cannot_signal_prisoner_if_archer_and_prisoner_are_both_sleeping() { @Test @Tag("task:3") @DisplayName("The canSignalPrisoner method returns false when both prisoner and archer are awake") - public void cannot_signal_prisoner_if_archer_and_prisoner_are_both_awake() { + public void cannotSignalPrisonerIfArcherAndPrisonerAreBothAwake() { boolean archerIsAwake = true; boolean prisonerIsAwake = true; assertThat(AnnalynsInfiltration.canSignalPrisoner(archerIsAwake, prisonerIsAwake)).isFalse(); @@ -141,7 +141,7 @@ public void cannot_signal_prisoner_if_archer_and_prisoner_are_both_awake() { @Test @Tag("task:4") @DisplayName("The canFreePrisoner method returns false when everyone is awake and pet dog is present") - public void cannot_release_prisoner_if_everyone_is_awake_and_pet_dog_is_present() { + public void cannotReleasePrisonerIfEveryoneIsAwakeAndPetDogIsPresent() { boolean knightIsAwake = true; boolean archerIsAwake = true; boolean prisonerIsAwake = true; @@ -153,7 +153,7 @@ public void cannot_release_prisoner_if_everyone_is_awake_and_pet_dog_is_present( @Test @Tag("task:4") @DisplayName("The canFreePrisoner method returns false when everyone is awake and pet dog is absent") - public void cannot_release_prisoner_if_everyone_is_awake_and_pet_dog_is_absent() { + public void cannotReleasePrisonerIfEveryoneIsAwakeAndPetDogIsAbsent() { boolean knightIsAwake = true; boolean archerIsAwake = true; boolean prisonerIsAwake = true; @@ -165,7 +165,7 @@ public void cannot_release_prisoner_if_everyone_is_awake_and_pet_dog_is_absent() @Test @Tag("task:4") @DisplayName("The canFreePrisoner method returns true when everyone is sleeping and pet dog is present") - public void can_release_prisoner_if_everyone_is_asleep_and_pet_dog_is_present() { + public void canReleasePrisonerIfEveryoneIsAsleepAndPetDogIsPresent() { boolean knightIsAwake = false; boolean archerIsAwake = false; boolean prisonerIsAwake = false; @@ -177,7 +177,7 @@ public void can_release_prisoner_if_everyone_is_asleep_and_pet_dog_is_present() @Test @Tag("task:4") @DisplayName("The canFreePrisoner method returns false when everyone is sleeping and pet dog is absent") - public void cannot_release_prisoner_if_everyone_is_asleep_and_pet_dog_is_absent() { + public void cannotReleasePrisonerIfEveryoneIsAsleepAndPetDogIsAbsent() { boolean knightIsAwake = false; boolean archerIsAwake = false; boolean prisonerIsAwake = false; @@ -189,7 +189,7 @@ public void cannot_release_prisoner_if_everyone_is_asleep_and_pet_dog_is_absent( @Test @Tag("task:4") @DisplayName("The canFreePrisoner method returns true when only prisoner is awake and pet dog is present") - public void can_release_prisoner_if_only_prisoner_is_awake_and_pet_dog_is_present() { + public void canReleasePrisonerIfOnlyPrisonerIsAwakeAndPetDogIsPresent() { boolean knightIsAwake = false; boolean archerIsAwake = false; boolean prisonerIsAwake = true; @@ -201,7 +201,7 @@ public void can_release_prisoner_if_only_prisoner_is_awake_and_pet_dog_is_presen @Test @Tag("task:4") @DisplayName("The canFreePrisoner method returns true when only prisoner is awake and pet dog is absent") - public void can_release_prisoner_if_only_prisoner_is_awake_and_pet_dog_is_absent() { + public void canReleasePrisonerIfOnlyPrisonerIsAwakeAndPetDogIsAbsent() { boolean knightIsAwake = false; boolean archerIsAwake = false; boolean prisonerIsAwake = true; @@ -213,7 +213,7 @@ public void can_release_prisoner_if_only_prisoner_is_awake_and_pet_dog_is_absent @Test @Tag("task:4") @DisplayName("The canFreePrisoner method returns false when only archer is awake and pet dog is present") - public void cannot_release_prisoner_if_only_archer_is_awake_and_pet_dog_is_present() { + public void cannotReleasePrisonerIfOnlyArcherIsAwakeAndPetDogIsPresent() { boolean knightIsAwake = false; boolean archerIsAwake = true; boolean prisonerIsAwake = false; @@ -225,7 +225,7 @@ public void cannot_release_prisoner_if_only_archer_is_awake_and_pet_dog_is_prese @Test @Tag("task:4") @DisplayName("The canFreePrisoner method returns false when only archer is awake and pet dog is absent") - public void cannot_release_prisoner_if_only_archer_is_awake_and_pet_dog_is_absent() { + public void cannotReleasePrisonerIfOnlyArcherIsAwakeAndPetDogIsAbsent() { boolean knightIsAwake = false; boolean archerIsAwake = true; boolean prisonerIsAwake = false; @@ -237,7 +237,7 @@ public void cannot_release_prisoner_if_only_archer_is_awake_and_pet_dog_is_absen @Test @Tag("task:4") @DisplayName("The canFreePrisoner method returns true when only knight is awake and pet dog is present") - public void can_release_prisoner_if_only_knight_is_awake_and_pet_dog_is_present() { + public void canReleasePrisonerIfOnlyKnightIsAwakeAndPetDogIsPresent() { boolean knightIsAwake = true; boolean archerIsAwake = false; boolean prisonerIsAwake = false; @@ -249,7 +249,7 @@ public void can_release_prisoner_if_only_knight_is_awake_and_pet_dog_is_present( @Test @Tag("task:4") @DisplayName("The canFreePrisoner method returns false when only knight is awake and pet dog is absent") - public void cannot_release_prisoner_if_only_knight_is_awake_and_pet_dog_is_absent() { + public void cannotReleasePrisonerIfOnlyKnightIsAwakeAndPetDogIsAbsent() { boolean knightIsAwake = true; boolean archerIsAwake = false; boolean prisonerIsAwake = false; @@ -261,7 +261,7 @@ public void cannot_release_prisoner_if_only_knight_is_awake_and_pet_dog_is_absen @Test @Tag("task:4") @DisplayName("The canFreePrisoner method returns false when only knight is sleeping and pet dog is present") - public void cannot_release_prisoner_if_only_knight_is_asleep_and_pet_dog_is_present() { + public void cannotReleasePrisonerIfOnlyKnightIsAsleepAndPetDogIsPresent() { boolean knightIsAwake = false; boolean archerIsAwake = true; boolean prisonerIsAwake = true; @@ -273,7 +273,7 @@ public void cannot_release_prisoner_if_only_knight_is_asleep_and_pet_dog_is_pres @Test @Tag("task:4") @DisplayName("The canFreePrisoner method returns false when only knight is sleeping and pet dog is absent") - public void cannot_release_prisoner_if_only_knight_is_asleep_and_pet_dog_is_absent() { + public void cannotReleasePrisonerIfOnlyKnightIsAsleepAndPetDogIsAbsent() { boolean knightIsAwake = false; boolean archerIsAwake = true; boolean prisonerIsAwake = true; @@ -285,7 +285,7 @@ public void cannot_release_prisoner_if_only_knight_is_asleep_and_pet_dog_is_abse @Test @Tag("task:4") @DisplayName("The canFreePrisoner method returns true when only archer is sleeping and pet dog is present") - public void can_release_prisoner_if_only_archer_is_asleep_and_pet_dog_is_present() { + public void canReleasePrisonerIfOnlyArcherIsAsleepAndPetDogIsPresent() { boolean knightIsAwake = true; boolean archerIsAwake = false; boolean prisonerIsAwake = true; @@ -297,7 +297,7 @@ public void can_release_prisoner_if_only_archer_is_asleep_and_pet_dog_is_present @Test @Tag("task:4") @DisplayName("The canFreePrisoner method returns false when only archer is sleeping and pet dog is absent") - public void cannot_release_prisoner_if_only_archer_is_asleep_and_pet_dog_is_absent() { + public void cannotReleasePrisonerIfOnlyArcherIsAsleepAndPetDogIsAbsent() { boolean knightIsAwake = true; boolean archerIsAwake = false; boolean prisonerIsAwake = true; @@ -309,7 +309,7 @@ public void cannot_release_prisoner_if_only_archer_is_asleep_and_pet_dog_is_abse @Test @Tag("task:4") @DisplayName("The canFreePrisoner method returns false when only prisoner is sleeping and pet dog is present") - public void cannot_release_prisoner_if_only_prisoner_is_asleep_and_pet_dog_is_present() { + public void cannotReleasePrisonerIfOnlyPrisonerIsAsleepAndPetDogIsPresent() { boolean knightIsAwake = true; boolean archerIsAwake = true; boolean prisonerIsAwake = false; @@ -321,7 +321,7 @@ public void cannot_release_prisoner_if_only_prisoner_is_asleep_and_pet_dog_is_pr @Test @Tag("task:4") @DisplayName("The canFreePrisoner method returns false when only prisoner is sleeping and pet dog is absent") - public void cannot_release_prisoner_if_only_prisoner_is_asleep_and_pet_dog_is_absent() { + public void cannotReleasePrisonerIfOnlyPrisonerIsAsleepAndPetDogIsAbsent() { boolean knightIsAwake = true; boolean archerIsAwake = true; boolean prisonerIsAwake = false; diff --git a/exercises/concept/bird-watcher/gradle/wrapper/gradle-wrapper.jar b/exercises/concept/bird-watcher/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/concept/bird-watcher/gradle/wrapper/gradle-wrapper.jar and b/exercises/concept/bird-watcher/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/concept/bird-watcher/gradle/wrapper/gradle-wrapper.properties b/exercises/concept/bird-watcher/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/concept/bird-watcher/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/concept/bird-watcher/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/concept/bird-watcher/gradlew b/exercises/concept/bird-watcher/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/concept/bird-watcher/gradlew +++ b/exercises/concept/bird-watcher/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/concept/bird-watcher/gradlew.bat b/exercises/concept/bird-watcher/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/concept/bird-watcher/gradlew.bat +++ b/exercises/concept/bird-watcher/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/concept/bird-watcher/src/test/java/BirdWatcherTest.java b/exercises/concept/bird-watcher/src/test/java/BirdWatcherTest.java index 80ff5f8e2..5b1746082 100644 --- a/exercises/concept/bird-watcher/src/test/java/BirdWatcherTest.java +++ b/exercises/concept/bird-watcher/src/test/java/BirdWatcherTest.java @@ -16,7 +16,7 @@ public class BirdWatcherTest { private static final int TODAY = 4; private BirdWatcher birdWatcher; - private int lastWeek[] = {DAY1, DAY2, DAY3, DAY4, DAY5, DAY6, TODAY}; + private final int[] lastWeek = {DAY1, DAY2, DAY3, DAY4, DAY5, DAY6, TODAY}; @BeforeEach public void setUp() { @@ -61,6 +61,13 @@ public void itShouldNotHaveDaysWithoutBirds() { assertThat(birdWatcher.hasDayWithoutBirds()).isFalse(); } + @Test + @Tag("task:4") + @DisplayName("The hasDayWithoutBirds method returns true if the last day has zero visits") + public void itHasLastDayWithoutBirds() { + birdWatcher = new BirdWatcher(new int[]{1, 2, 5, 3, 7, 8, 0}); + assertThat(birdWatcher.hasDayWithoutBirds()).isTrue(); + } @Test @Tag("task:5") diff --git a/exercises/concept/booking-up-for-beauty/.docs/introduction.md b/exercises/concept/booking-up-for-beauty/.docs/introduction.md index 2baa59e0f..ed132331c 100644 --- a/exercises/concept/booking-up-for-beauty/.docs/introduction.md +++ b/exercises/concept/booking-up-for-beauty/.docs/introduction.md @@ -43,7 +43,7 @@ These methods return a _new_ `LocalDate` instance and do not update the existing ```java LocalDate date = LocalDate.of(2007, 12, 3); -date.addDays(3); +date.plusDays(3); // => 2007-12-06 ``` diff --git a/exercises/concept/booking-up-for-beauty/gradle/wrapper/gradle-wrapper.jar b/exercises/concept/booking-up-for-beauty/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/concept/booking-up-for-beauty/gradle/wrapper/gradle-wrapper.jar and b/exercises/concept/booking-up-for-beauty/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/concept/booking-up-for-beauty/gradle/wrapper/gradle-wrapper.properties b/exercises/concept/booking-up-for-beauty/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/concept/booking-up-for-beauty/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/concept/booking-up-for-beauty/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/concept/booking-up-for-beauty/gradlew b/exercises/concept/booking-up-for-beauty/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/concept/booking-up-for-beauty/gradlew +++ b/exercises/concept/booking-up-for-beauty/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/concept/booking-up-for-beauty/gradlew.bat b/exercises/concept/booking-up-for-beauty/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/concept/booking-up-for-beauty/gradlew.bat +++ b/exercises/concept/booking-up-for-beauty/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/concept/calculator-conundrum/.docs/introduction.md b/exercises/concept/calculator-conundrum/.docs/introduction.md index e9b19e65f..49103a297 100644 --- a/exercises/concept/calculator-conundrum/.docs/introduction.md +++ b/exercises/concept/calculator-conundrum/.docs/introduction.md @@ -10,11 +10,12 @@ An exception is an event that occurs during the execution of a program that disr Exceptions are raised explicitly in Java, and the act of raising an exception is called _throwing an exception_. The act of handling an exception is called _catching an exception_. -Java distinguishes three types of exceptions: +In Java, all exceptions are subclasses of the `Exception` class, which itself is a subclass of `Throwable`. + +Java distinguishes two types of exceptions: 1. Checked exceptions 2. Unchecked exceptions -3. Errors #### Checked exceptions @@ -23,7 +24,7 @@ An example of a checked exception is the `FileNotFoundException` which occurs wh This type of exception is checked at compile-time: methods that throw checked exceptions should specify this in their method signature, and code calling a method that might throw a checked exception is required to handle it or the code will not compile. -All exceptions in Java that do not inherit from `RuntimeException` or `Error` are considered checked exceptions. +All checked exceptions are subclasses of `Exception` that do not extend `RuntimeException`. #### Unchecked exceptions @@ -32,17 +33,7 @@ An example of an unchecked exception is the `NullPointerException` which occurs This type of exception is not checked at compile-time: methods that throw unchecked exceptions are not required to specify this in their method signature, and code calling a method that might throw an unchecked exception is not required to handle it. -All exceptions in Java that inherit from `RuntimeException` are considered unchecked exceptions. - -#### Errors - -_Errors_ are exceptional conditions that are external to an application. -An example of an error is the `OutOfMemoryError` which occurs when an application is trying to use more memory than is available on the system. - -Like unchecked exceptions, errors are not checked at compile-time. -They are not usually thrown from application code. - -All exceptions in Java that inherit from `Error` are considered errors. +All unchecked exceptions inherit from `RuntimeException`, which itself is an extension of `Exception`. ### Throwing exceptions @@ -136,3 +127,14 @@ Withdrawing -10.0 Withdrawal failed: Cannot withdraw a negative amount Current balance: 5.0 ``` + +### Errors + +Java also has a separate category called _Errors_ which are serious problems that are external to an application. +An example of an error is the `OutOfMemoryError` which occurs when an application is trying to use more memory than is available on the system. + +Like unchecked exceptions, errors are not checked at compile-time. +The difference is that they represent system level problems and are generally thrown by the Java Virtual machine or environment instead of the application. +Applications should generally not attempt to catch or handle them. + +All errors in Java inherit from the `Error` class. diff --git a/exercises/concept/calculator-conundrum/.meta/design.md b/exercises/concept/calculator-conundrum/.meta/design.md index 5163b002c..5134eb08a 100644 --- a/exercises/concept/calculator-conundrum/.meta/design.md +++ b/exercises/concept/calculator-conundrum/.meta/design.md @@ -18,3 +18,15 @@ - `conditionals-if`: know how to do conditional logic. - `switch-statement`: know how to work with a `switch` statement. + +## Analyzer + +This exercise could benefit from the following rules in the [analyzer]: + +- `essential`: Verify that the solution is using the try catch statement for the division. +- `actionable`: If the solution is wrapping all the code in a try catch statement, instruct the student to only use the `try catch` for the division statement +- `actionable`: If the solution uses only `if` statement, instruct the student that he/she can use the `switch case` statement to perform the operations. +- `informative`: If the solution does not throw the exception for `Operation cannot be null` and `Operation cannot be empty` at the beginning, suggest the fail-fast approach to the student. + Inform this way of implementation can be less error-prone and more readable as suggested by Martin Fowler: + +[analyzer]: https://github.com/exercism/java-analyzer diff --git a/exercises/concept/calculator-conundrum/gradle/wrapper/gradle-wrapper.jar b/exercises/concept/calculator-conundrum/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/concept/calculator-conundrum/gradle/wrapper/gradle-wrapper.jar and b/exercises/concept/calculator-conundrum/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/concept/calculator-conundrum/gradle/wrapper/gradle-wrapper.properties b/exercises/concept/calculator-conundrum/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/concept/calculator-conundrum/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/concept/calculator-conundrum/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/concept/calculator-conundrum/gradlew b/exercises/concept/calculator-conundrum/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/concept/calculator-conundrum/gradlew +++ b/exercises/concept/calculator-conundrum/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/concept/calculator-conundrum/gradlew.bat b/exercises/concept/calculator-conundrum/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/concept/calculator-conundrum/gradlew.bat +++ b/exercises/concept/calculator-conundrum/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/concept/captains-log/gradle/wrapper/gradle-wrapper.jar b/exercises/concept/captains-log/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/concept/captains-log/gradle/wrapper/gradle-wrapper.jar and b/exercises/concept/captains-log/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/concept/captains-log/gradle/wrapper/gradle-wrapper.properties b/exercises/concept/captains-log/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/concept/captains-log/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/concept/captains-log/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/concept/captains-log/gradlew b/exercises/concept/captains-log/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/concept/captains-log/gradlew +++ b/exercises/concept/captains-log/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/concept/captains-log/gradlew.bat b/exercises/concept/captains-log/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/concept/captains-log/gradlew.bat +++ b/exercises/concept/captains-log/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/concept/cars-assemble/gradle/wrapper/gradle-wrapper.jar b/exercises/concept/cars-assemble/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/concept/cars-assemble/gradle/wrapper/gradle-wrapper.jar and b/exercises/concept/cars-assemble/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/concept/cars-assemble/gradle/wrapper/gradle-wrapper.properties b/exercises/concept/cars-assemble/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/concept/cars-assemble/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/concept/cars-assemble/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/concept/cars-assemble/gradlew b/exercises/concept/cars-assemble/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/concept/cars-assemble/gradlew +++ b/exercises/concept/cars-assemble/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/concept/cars-assemble/gradlew.bat b/exercises/concept/cars-assemble/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/concept/cars-assemble/gradlew.bat +++ b/exercises/concept/cars-assemble/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/concept/football-match-reports/.docs/instructions.md b/exercises/concept/football-match-reports/.docs/instructions.md index f255c3a13..2c668b663 100644 --- a/exercises/concept/football-match-reports/.docs/instructions.md +++ b/exercises/concept/football-match-reports/.docs/instructions.md @@ -27,11 +27,11 @@ FootballMatchReports.onField(10); // => "striker" ``` -## 2. Raise an alert if an unknown shirt number is encountered +## 2. Output "invalid" if the shirt number is not part of the official list -Modify the `FootballMatchReports.onField()` method to throw an `IllegalArgumentException` when a shirt number outside the range 1-11 is processed. +Modify the `FootballMatchReports.onField()` method to return 'invalid' when a shirt number outside the range 1-11 is processed. ```java FootballMatchReports.onField(13); -// => Throw IllegalArgumentException +// => "invalid" ``` diff --git a/exercises/concept/football-match-reports/.meta/config.json b/exercises/concept/football-match-reports/.meta/config.json index 9b291514e..74d3894b7 100644 --- a/exercises/concept/football-match-reports/.meta/config.json +++ b/exercises/concept/football-match-reports/.meta/config.json @@ -2,6 +2,9 @@ "authors": [ "Azumix" ], + "contributors": [ + "AlvesJorge" + ], "files": { "solution": [ "src/main/java/FootballMatchReports.java" diff --git a/exercises/concept/football-match-reports/.meta/src/reference/java/FootballMatchReports.java b/exercises/concept/football-match-reports/.meta/src/reference/java/FootballMatchReports.java index d18f55ac6..c99abc7b0 100644 --- a/exercises/concept/football-match-reports/.meta/src/reference/java/FootballMatchReports.java +++ b/exercises/concept/football-match-reports/.meta/src/reference/java/FootballMatchReports.java @@ -30,7 +30,7 @@ public static String onField(int shirtNum) { playerDescription = "striker"; break; default: - throw new IllegalArgumentException(); + playerDescription = "invalid"; } return playerDescription; } diff --git a/exercises/concept/football-match-reports/gradle/wrapper/gradle-wrapper.jar b/exercises/concept/football-match-reports/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/concept/football-match-reports/gradle/wrapper/gradle-wrapper.jar and b/exercises/concept/football-match-reports/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/concept/football-match-reports/gradle/wrapper/gradle-wrapper.properties b/exercises/concept/football-match-reports/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/concept/football-match-reports/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/concept/football-match-reports/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/concept/football-match-reports/gradlew b/exercises/concept/football-match-reports/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/concept/football-match-reports/gradlew +++ b/exercises/concept/football-match-reports/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/concept/football-match-reports/gradlew.bat b/exercises/concept/football-match-reports/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/concept/football-match-reports/gradlew.bat +++ b/exercises/concept/football-match-reports/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/concept/football-match-reports/src/test/java/FootballMatchReportsTest.java b/exercises/concept/football-match-reports/src/test/java/FootballMatchReportsTest.java index aeaeada1d..82024e6f5 100644 --- a/exercises/concept/football-match-reports/src/test/java/FootballMatchReportsTest.java +++ b/exercises/concept/football-match-reports/src/test/java/FootballMatchReportsTest.java @@ -3,35 +3,34 @@ import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; public class FootballMatchReportsTest { @Test @Tag("task:1") @DisplayName("The onField method returns the correct description of player with shirt number 1") - public void test_goal() { + public void testGoal() { assertThat(FootballMatchReports.onField(1)).isEqualTo("goalie"); } @Test @Tag("task:1") @DisplayName("The onField method returns the correct description of player with shirt number 2") - public void test_left_back() { + public void testLeftBack() { assertThat(FootballMatchReports.onField(2)).isEqualTo("left back"); } @Test @Tag("task:1") @DisplayName("The onField method returns the correct description of player with shirt number 5") - public void test_right_back() { + public void testRightBack() { assertThat(FootballMatchReports.onField(5)).isEqualTo("right back"); } @Test @Tag("task:1") @DisplayName("The onField method returns the correct description of players with shirt numbers 3 and 4") - public void test_center_back() { + public void testCenterBack() { assertThat(FootballMatchReports.onField(3)).isEqualTo("center back"); assertThat(FootballMatchReports.onField(4)).isEqualTo("center back"); } @@ -39,7 +38,7 @@ public void test_center_back() { @Test @Tag("task:1") @DisplayName("The onField method returns the correct description of players with shirt numbers 6, 7 and 8") - public void test_midfielder() { + public void testMidfielder() { assertThat(FootballMatchReports.onField(6)).isEqualTo("midfielder"); assertThat(FootballMatchReports.onField(7)).isEqualTo("midfielder"); assertThat(FootballMatchReports.onField(8)).isEqualTo("midfielder"); @@ -48,37 +47,35 @@ public void test_midfielder() { @Test @Tag("task:1") @DisplayName("The onField method returns the correct description of player with shirt number 9") - public void test_left_wing() { + public void testLeftWing() { assertThat(FootballMatchReports.onField(9)).isEqualTo("left wing"); } @Test @Tag("task:1") @DisplayName("The onField method returns the correct description of player with shirt number 10") - public void test_striker() { + public void testStriker() { assertThat(FootballMatchReports.onField(10)).isEqualTo("striker"); } @Test @Tag("task:1") @DisplayName("The onField method returns the correct description of player with shirt number 11") - public void test_right_wing() { + public void testRightWing() { assertThat(FootballMatchReports.onField(11)).isEqualTo("right wing"); } @Test @Tag("task:2") - @DisplayName("The onField method throws IllegalArgumentException for unknown shirt number") - public void test_exception() { - assertThatExceptionOfType(IllegalArgumentException.class) - .isThrownBy(() -> FootballMatchReports.onField(13)); + @DisplayName("The onField method returns 'invalid' for invalid shirt number") + public void testException() { + assertThat(FootballMatchReports.onField(13)).isEqualTo("invalid"); } @Test @Tag("task:2") - @DisplayName("The onField method throws IllegalArgumentException for negative shirt number") - public void test_exception_negative_number() { - assertThatExceptionOfType(IllegalArgumentException.class) - .isThrownBy(() -> FootballMatchReports.onField(-1)); + @DisplayName("The onField method returns 'invalid' for negative shirt number") + public void testExceptionNegativeNumber() { + assertThat(FootballMatchReports.onField(-1)).isEqualTo("invalid"); } } diff --git a/exercises/concept/gotta-snatch-em-all/gradle/wrapper/gradle-wrapper.jar b/exercises/concept/gotta-snatch-em-all/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/concept/gotta-snatch-em-all/gradle/wrapper/gradle-wrapper.jar and b/exercises/concept/gotta-snatch-em-all/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/concept/gotta-snatch-em-all/gradle/wrapper/gradle-wrapper.properties b/exercises/concept/gotta-snatch-em-all/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/concept/gotta-snatch-em-all/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/concept/gotta-snatch-em-all/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/concept/gotta-snatch-em-all/gradlew b/exercises/concept/gotta-snatch-em-all/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/concept/gotta-snatch-em-all/gradlew +++ b/exercises/concept/gotta-snatch-em-all/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/concept/gotta-snatch-em-all/gradlew.bat b/exercises/concept/gotta-snatch-em-all/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/concept/gotta-snatch-em-all/gradlew.bat +++ b/exercises/concept/gotta-snatch-em-all/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/concept/international-calling-connoisseur/.docs/hints.md b/exercises/concept/international-calling-connoisseur/.docs/hints.md index 056edd53d..8bedc370b 100644 --- a/exercises/concept/international-calling-connoisseur/.docs/hints.md +++ b/exercises/concept/international-calling-connoisseur/.docs/hints.md @@ -22,7 +22,7 @@ ## 5. Find a country's dialing code -- There is a [way][map-values-docs] to get an iterable collection of values in a map. +- There is a [way][map-entry-set-docs] to get an iterable collection of entries in a map, which allows you to go through the key-value pairs. ## 6. Update the country's dialing code @@ -35,5 +35,5 @@ [map-get-docs]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Map.html#get(java.lang.Object) [map-contains-key-docs]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Map.html#containsKey(java.lang.Object) [map-contains-value-docs]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Map.html#containsValue(java.lang.Object) -[map-values-docs]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Map.html#values() +[map-entry-set-docs]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Map.html#entrySet() [map-remove-docs]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Map.html#remove(java.lang.Object) diff --git a/exercises/concept/international-calling-connoisseur/.docs/instructions.md b/exercises/concept/international-calling-connoisseur/.docs/instructions.md index e8f728f0f..106844176 100644 --- a/exercises/concept/international-calling-connoisseur/.docs/instructions.md +++ b/exercises/concept/international-calling-connoisseur/.docs/instructions.md @@ -31,7 +31,7 @@ dialingCodes.setDialingCode(679, "Fiji"); ## 3. Lookup a dialing code's country -Implement the `getCountry` method that takes a map of dialing codes and a dialing code and returns the country name with the dialing code. +Implement the `getCountry` method that takes a dialing code and returns the country name with the dialing code. ```java DialingCodes dialingCodes = new DialingCodes(); @@ -63,7 +63,7 @@ dialingCodes.addNewDialingCode(39, "Vatican City"); Its rare, but mistakes can be made. To correct the mistake, we will need to know what dialing code the country is currently mapped to. -To find which dialing code needs to be corrected, implement the `findDialingCode` method that takes in a map of dialing codes and a country and returns the country's dialing code. +To find which dialing code needs to be corrected, implement the `findDialingCode` method that takes a country and returns the country's dialing code. Return `null` if the country is _not_ in the map. ```java diff --git a/exercises/concept/international-calling-connoisseur/gradle/wrapper/gradle-wrapper.jar b/exercises/concept/international-calling-connoisseur/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/concept/international-calling-connoisseur/gradle/wrapper/gradle-wrapper.jar and b/exercises/concept/international-calling-connoisseur/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/concept/international-calling-connoisseur/gradle/wrapper/gradle-wrapper.properties b/exercises/concept/international-calling-connoisseur/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/concept/international-calling-connoisseur/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/concept/international-calling-connoisseur/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/concept/international-calling-connoisseur/gradlew b/exercises/concept/international-calling-connoisseur/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/concept/international-calling-connoisseur/gradlew +++ b/exercises/concept/international-calling-connoisseur/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/concept/international-calling-connoisseur/gradlew.bat b/exercises/concept/international-calling-connoisseur/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/concept/international-calling-connoisseur/gradlew.bat +++ b/exercises/concept/international-calling-connoisseur/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/concept/jedliks-toy-car/.meta/design.md b/exercises/concept/jedliks-toy-car/.meta/design.md index f99cef1f7..2a1b40eb1 100644 --- a/exercises/concept/jedliks-toy-car/.meta/design.md +++ b/exercises/concept/jedliks-toy-car/.meta/design.md @@ -28,3 +28,15 @@ - `strings`: know how to do basic string interpolation. - `numbers`: know how to compare numbers. - `conditionals`: know how to do conditional logic. + +## Analyzer + +This exercise could benefit from the following rules in the [analyzer]: + +- `essential`: Verify that the solution keeps the void type for the drive function. +- `essential`: Verify that the solution has fields in the class +- `actionable`: If the solution defines the fields as `public`, instruct the student to use `private` and explain the encapsulation principle. +- `informative`: If the solution does not use a primitive as a type for the fields, inform the student to use it. + Explain that the values cannot be null and it is less error-prone + +[analyzer]: https://github.com/exercism/java-analyzer diff --git a/exercises/concept/jedliks-toy-car/gradle/wrapper/gradle-wrapper.jar b/exercises/concept/jedliks-toy-car/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/concept/jedliks-toy-car/gradle/wrapper/gradle-wrapper.jar and b/exercises/concept/jedliks-toy-car/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/concept/jedliks-toy-car/gradle/wrapper/gradle-wrapper.properties b/exercises/concept/jedliks-toy-car/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/concept/jedliks-toy-car/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/concept/jedliks-toy-car/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/concept/jedliks-toy-car/gradlew b/exercises/concept/jedliks-toy-car/gradlew old mode 100644 new mode 100755 index 1aa94a426..adff685a0 --- a/exercises/concept/jedliks-toy-car/gradlew +++ b/exercises/concept/jedliks-toy-car/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/concept/jedliks-toy-car/gradlew.bat b/exercises/concept/jedliks-toy-car/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/concept/jedliks-toy-car/gradlew.bat +++ b/exercises/concept/jedliks-toy-car/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/concept/jedliks-toy-car/src/test/java/JedliksToyCarTest.java b/exercises/concept/jedliks-toy-car/src/test/java/JedliksToyCarTest.java index 19db64391..279cf07a0 100644 --- a/exercises/concept/jedliks-toy-car/src/test/java/JedliksToyCarTest.java +++ b/exercises/concept/jedliks-toy-car/src/test/java/JedliksToyCarTest.java @@ -8,7 +8,7 @@ public class JedliksToyCarTest { @Test @Tag("task:1") @DisplayName("The static buy method returns a new remote controlled car instance") - public void buy_new_car_returns_instance() { + public void buyNewCarReturnsInstance() { JedliksToyCar car = JedliksToyCar.buy(); assertThat(car).isNotNull(); } @@ -16,7 +16,7 @@ public void buy_new_car_returns_instance() { @Test @Tag("task:1") @DisplayName("The static buy method returns each time a new remote controlled car instance") - public void buy_new_car_returns_new_car_each_time() { + public void buyNewCarReturnsNewCarEachTime() { JedliksToyCar car1 = JedliksToyCar.buy(); JedliksToyCar car2 = JedliksToyCar.buy(); assertThat(car1).isNotEqualTo(car2); @@ -25,7 +25,7 @@ public void buy_new_car_returns_new_car_each_time() { @Test @Tag("task:2") @DisplayName("The distanceDisplay method shows 0 meters message on a new car") - public void new_car_distance_display() { + public void newCarDistanceDisplay() { JedliksToyCar car = new JedliksToyCar(); assertThat(car.distanceDisplay()).isEqualTo("Driven 0 meters"); } @@ -33,7 +33,7 @@ public void new_car_distance_display() { @Test @Tag("task:3") @DisplayName("The batteryDisplay method shows full battery message on a new car") - public void new_car_battery_display() { + public void newCarBatteryDisplay() { JedliksToyCar car = new JedliksToyCar(); assertThat(car.batteryDisplay()).isEqualTo("Battery at 100%"); } @@ -41,7 +41,7 @@ public void new_car_battery_display() { @Test @Tag("task:4") @DisplayName("The distanceDisplay method shows the correct message after driving once") - public void distance_display_after_driving_once() { + public void distanceDisplayAfterDrivingOnce() { JedliksToyCar car = new JedliksToyCar(); car.drive(); assertThat(car.distanceDisplay()).isEqualTo("Driven 20 meters"); @@ -50,7 +50,7 @@ public void distance_display_after_driving_once() { @Test @Tag("task:4") @DisplayName("The distanceDisplay method shows the correct message after driving multiple times") - public void distance_display_after_driving_multiple_times() { + public void distanceDisplayAfterDrivingMultipleTimes() { JedliksToyCar car = new JedliksToyCar(); for (int i = 0; i < 17; i++) { @@ -63,7 +63,7 @@ public void distance_display_after_driving_multiple_times() { @Test @Tag("task:5") @DisplayName("The batteryDisplay method shows the correct message after driving once") - public void battery_display_after_driving_once() { + public void batteryDisplayAfterDrivingOnce() { JedliksToyCar car = new JedliksToyCar(); car.drive(); @@ -73,7 +73,7 @@ public void battery_display_after_driving_once() { @Test @Tag("task:5") @DisplayName("The batteryDisplay method shows the correct battery percentage after driving multiple times") - public void battery_display_after_driving_multiple_times() { + public void batteryDisplayAfterDrivingMultipleTimes() { JedliksToyCar car = new JedliksToyCar(); for (int i = 0; i < 23; i++) { @@ -86,7 +86,7 @@ public void battery_display_after_driving_multiple_times() { @Test @Tag("task:5") @DisplayName("The batteryDisplay method shows battery empty after draining all battery") - public void battery_display_when_battery_empty() { + public void batteryDisplayWhenBatteryEmpty() { JedliksToyCar car = new JedliksToyCar(); // Drain the battery @@ -103,7 +103,7 @@ public void battery_display_when_battery_empty() { @Test @Tag("task:6") @DisplayName("The distanceDisplay method shows the correct message after driving and draining all battery") - public void distance_display_when_battery_empty() { + public void distanceDisplayWhenBatteryEmpty() { JedliksToyCar car = new JedliksToyCar(); // Drain the battery diff --git a/exercises/concept/karls-languages/gradle/wrapper/gradle-wrapper.jar b/exercises/concept/karls-languages/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/concept/karls-languages/gradle/wrapper/gradle-wrapper.jar and b/exercises/concept/karls-languages/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/concept/karls-languages/gradle/wrapper/gradle-wrapper.properties b/exercises/concept/karls-languages/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/concept/karls-languages/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/concept/karls-languages/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/concept/karls-languages/gradlew b/exercises/concept/karls-languages/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/concept/karls-languages/gradlew +++ b/exercises/concept/karls-languages/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/concept/karls-languages/gradlew.bat b/exercises/concept/karls-languages/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/concept/karls-languages/gradlew.bat +++ b/exercises/concept/karls-languages/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/concept/lasagna/gradle/wrapper/gradle-wrapper.jar b/exercises/concept/lasagna/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/concept/lasagna/gradle/wrapper/gradle-wrapper.jar and b/exercises/concept/lasagna/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/concept/lasagna/gradle/wrapper/gradle-wrapper.properties b/exercises/concept/lasagna/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/concept/lasagna/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/concept/lasagna/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/concept/lasagna/gradlew b/exercises/concept/lasagna/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/concept/lasagna/gradlew +++ b/exercises/concept/lasagna/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/concept/lasagna/gradlew.bat b/exercises/concept/lasagna/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/concept/lasagna/gradlew.bat +++ b/exercises/concept/lasagna/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/concept/lasagna/src/test/java/LasagnaTest.java b/exercises/concept/lasagna/src/test/java/LasagnaTest.java index 7b1676129..6200d47c5 100644 --- a/exercises/concept/lasagna/src/test/java/LasagnaTest.java +++ b/exercises/concept/lasagna/src/test/java/LasagnaTest.java @@ -11,7 +11,7 @@ public class LasagnaTest { @Test @Tag("task:1") @DisplayName("Implemented the expectedMinutesInOven method") - public void implemented_expected_minutes_in_oven() { + public void implementedExpectedMinutesInOven() { assertThat(new Lasagna().hasMethod("expectedMinutesInOven")) .withFailMessage("Method expectedMinutesInOven must be created") .isTrue(); @@ -26,14 +26,14 @@ public void implemented_expected_minutes_in_oven() { @Test @Tag("task:1") @DisplayName("The expectedMinutesInOven method returns the correct value") - public void expected_minutes_in_oven() { + public void expectedMinutesInOven() { assertThat(new Lasagna().expectedMinutesInOven()).isEqualTo(40); } @Test @Tag("task:2") @DisplayName("Implemented the remainingMinutesInOven method") - public void implemented_remaining_minutes_in_oven() { + public void implementedRemainingMinutesInOven() { assertThat(new Lasagna().hasMethod("remainingMinutesInOven", int.class)) .withFailMessage("Method remainingMinutesInOven must be created") .isTrue(); @@ -48,14 +48,14 @@ public void implemented_remaining_minutes_in_oven() { @Test @Tag("task:2") @DisplayName("The remainingMinutesInOven method calculates and returns the correct value") - public void remaining_minutes_in_oven() { + public void remainingMinutesInOven() { assertThat(new Lasagna().remainingMinutesInOven(25)).isEqualTo(15); } @Test @Tag("task:3") @DisplayName("Implemented the preparationTimeInMinutes method") - public void implemented_preparation_time_in_minutes() { + public void implementedPreparationTimeInMinutes() { assertThat(new Lasagna().hasMethod("preparationTimeInMinutes", int.class)) .withFailMessage("Method preparationTimeInMinutes must be created") .isTrue(); @@ -70,21 +70,21 @@ public void implemented_preparation_time_in_minutes() { @Test @Tag("task:3") @DisplayName("The preparationTimeInMinutes method calculates the correct value for single layer") - public void preparation_time_in_minutes_for_one_layer() { + public void preparationTimeInMinutesForOneLayer() { assertThat(new Lasagna().preparationTimeInMinutes(1)).isEqualTo(2); } @Test @Tag("task:3") @DisplayName("The preparationTimeInMinutes method calculates the correct value for multiple layers") - public void preparation_time_in_minutes_for_multiple_layers() { + public void preparationTimeInMinutesForMultipleLayers() { assertThat(new Lasagna().preparationTimeInMinutes(4)).isEqualTo(8); } @Test @Tag("task:4") @DisplayName("Implemented the totalTimeInMinutes method") - public void implemented_total_time_in_minutes() { + public void implementedTotalTimeInMinutes() { assertThat(new Lasagna().hasMethod("totalTimeInMinutes", int.class, int.class)) .withFailMessage("Method totalTimeInMinutes must be created") .isTrue(); @@ -99,14 +99,14 @@ public void implemented_total_time_in_minutes() { @Test @Tag("task:4") @DisplayName("The totalTimeInMinutes method calculates the correct value for single layer") - public void total_time_in_minutes_for_one_layer() { + public void totalTimeInMinutesForOneLayer() { assertThat(new Lasagna().totalTimeInMinutes(1, 30)).isEqualTo(32); } @Test @Tag("task:4") @DisplayName("The totalTimeInMinutes method calculates the correct value for multiple layers") - public void total_time_in_minutes_for_multiple_layers() { + public void totalTimeInMinutesForMultipleLayers() { assertThat(new Lasagna().totalTimeInMinutes(4, 8)).isEqualTo(16); } } diff --git a/exercises/concept/log-levels/.docs/hints.md b/exercises/concept/log-levels/.docs/hints.md index 8453667c5..2e5bce849 100644 --- a/exercises/concept/log-levels/.docs/hints.md +++ b/exercises/concept/log-levels/.docs/hints.md @@ -7,12 +7,12 @@ ## 1. Get message from a log line - Different options to search for text in a string are explored in [this tutorial][tutorial-search-text-in-string]. -- How to split strings can be seen [here][tutorial-split-strings] +- How to split strings can be seen in [this tutorial][tutorial-split-strings] - Removing white space is [built-in][tutorial-trim-white-space]. ## 2. Get log level from a log line -- Changing a `String`'s casing is explored [here][tutorial-changing-case-upper] and [here][tutorial-changing-case-lower]. +- Changing a `String`'s casing is explored in [this changing to upper case][tutorial-changing-case-upper] and [this changing to lower case][tutorial-changing-case-lower] tutorial. ## 3. Reformat a log line diff --git a/exercises/concept/log-levels/gradle/wrapper/gradle-wrapper.jar b/exercises/concept/log-levels/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/concept/log-levels/gradle/wrapper/gradle-wrapper.jar and b/exercises/concept/log-levels/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/concept/log-levels/gradle/wrapper/gradle-wrapper.properties b/exercises/concept/log-levels/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/concept/log-levels/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/concept/log-levels/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/concept/log-levels/gradlew b/exercises/concept/log-levels/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/concept/log-levels/gradlew +++ b/exercises/concept/log-levels/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/concept/log-levels/gradlew.bat b/exercises/concept/log-levels/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/concept/log-levels/gradlew.bat +++ b/exercises/concept/log-levels/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/concept/log-levels/src/test/java/LogLevelsTest.java b/exercises/concept/log-levels/src/test/java/LogLevelsTest.java index 2fa83e375..65dd46629 100644 --- a/exercises/concept/log-levels/src/test/java/LogLevelsTest.java +++ b/exercises/concept/log-levels/src/test/java/LogLevelsTest.java @@ -8,56 +8,56 @@ public class LogLevelsTest { @Test @Tag("task:1") @DisplayName("The message method returns the log line's message of an error log") - public void error_message() { + public void errorMessage() { assertThat(LogLevels.message("[ERROR]: Stack overflow")).isEqualTo("Stack overflow"); } @Test @Tag("task:1") @DisplayName("The message method returns the log line's message of a warning log") - public void warning_message() { + public void warningMessage() { assertThat(LogLevels.message("[WARNING]: Disk almost full")).isEqualTo("Disk almost full"); } @Test @Tag("task:1") @DisplayName("The message method returns the log line's message of an info log") - public void info_message() { + public void infoMessage() { assertThat(LogLevels.message("[INFO]: File moved")).isEqualTo("File moved"); } @Test @Tag("task:1") @DisplayName("The message method returns the log line's message after removing leading and trailing spaces") - public void message_with_leading_and_trailing_white_space() { + public void messageWithLeadingAndTrailingWhiteSpace() { assertThat(LogLevels.message("[WARNING]: \tTimezone not set \r\n")).isEqualTo("Timezone not set"); } @Test @Tag("task:2") @DisplayName("The logLevel method returns the log level of an error log line") - public void error_log_level() { + public void errorLogLevel() { assertThat(LogLevels.logLevel("[ERROR]: Disk full")).isEqualTo("error"); } @Test @Tag("task:2") @DisplayName("The logLevel method returns the log level of a warning log line") - public void warning_log_level() { + public void warningLogLevel() { assertThat(LogLevels.logLevel("[WARNING]: Unsafe password")).isEqualTo("warning"); } @Test @Tag("task:2") @DisplayName("The logLevel method returns the log level of an info log line") - public void info_log_level() { + public void infoLogLevel() { assertThat(LogLevels.logLevel("[INFO]: Timezone changed")).isEqualTo("info"); } @Test @Tag("task:3") @DisplayName("The reformat method correctly reformats an error log line") - public void error_reformat() { + public void errorReformat() { assertThat(LogLevels.reformat("[ERROR]: Segmentation fault")) .isEqualTo("Segmentation fault (error)"); } @@ -65,7 +65,7 @@ public void error_reformat() { @Test @Tag("task:3") @DisplayName("The reformat method correctly reformats a warning log line") - public void warning_reformat() { + public void warningReformat() { assertThat(LogLevels.reformat("[WARNING]: Decreased performance")) .isEqualTo("Decreased performance (warning)"); } @@ -73,7 +73,7 @@ public void warning_reformat() { @Test @Tag("task:3") @DisplayName("The reformat method correctly reformats an info log line") - public void info_reformat() { + public void infoReformat() { assertThat(LogLevels.reformat("[INFO]: Disk defragmented")) .isEqualTo("Disk defragmented (info)"); } @@ -81,7 +81,7 @@ public void info_reformat() { @Test @Tag("task:3") @DisplayName("The reformat method correctly reformats an error log line removing spaces") - public void reformat_with_leading_and_trailing_white_space() { + public void reformatWithLeadingAndTrailingWhiteSpace() { assertThat(LogLevels.reformat("[ERROR]: \t Corrupt disk\t \t \r\n")) .isEqualTo("Corrupt disk (error)"); } diff --git a/exercises/concept/logs-logs-logs/gradle/wrapper/gradle-wrapper.jar b/exercises/concept/logs-logs-logs/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/concept/logs-logs-logs/gradle/wrapper/gradle-wrapper.jar and b/exercises/concept/logs-logs-logs/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/concept/logs-logs-logs/gradle/wrapper/gradle-wrapper.properties b/exercises/concept/logs-logs-logs/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/concept/logs-logs-logs/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/concept/logs-logs-logs/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/concept/logs-logs-logs/gradlew b/exercises/concept/logs-logs-logs/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/concept/logs-logs-logs/gradlew +++ b/exercises/concept/logs-logs-logs/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/concept/logs-logs-logs/gradlew.bat b/exercises/concept/logs-logs-logs/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/concept/logs-logs-logs/gradlew.bat +++ b/exercises/concept/logs-logs-logs/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/concept/need-for-speed/gradle/wrapper/gradle-wrapper.jar b/exercises/concept/need-for-speed/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/concept/need-for-speed/gradle/wrapper/gradle-wrapper.jar and b/exercises/concept/need-for-speed/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/concept/need-for-speed/gradle/wrapper/gradle-wrapper.properties b/exercises/concept/need-for-speed/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/concept/need-for-speed/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/concept/need-for-speed/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/concept/need-for-speed/gradlew b/exercises/concept/need-for-speed/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/concept/need-for-speed/gradlew +++ b/exercises/concept/need-for-speed/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/concept/need-for-speed/gradlew.bat b/exercises/concept/need-for-speed/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/concept/need-for-speed/gradlew.bat +++ b/exercises/concept/need-for-speed/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/concept/need-for-speed/src/test/java/NeedForSpeedTest.java b/exercises/concept/need-for-speed/src/test/java/NeedForSpeedTest.java index a5f130e3f..2848f34fb 100644 --- a/exercises/concept/need-for-speed/src/test/java/NeedForSpeedTest.java +++ b/exercises/concept/need-for-speed/src/test/java/NeedForSpeedTest.java @@ -10,7 +10,7 @@ public class NeedForSpeedTest { @Test @Tag("task:3") @DisplayName("The distanceDriven method returns 0 on a new car") - public void new_remote_control_car_has_not_driven_any_distance() { + public void newRemoteControlCarHasNotDrivenAnyDistance() { int speed = 10; int batteryDrain = 2; var car = new NeedForSpeed(speed, batteryDrain); @@ -21,7 +21,7 @@ public void new_remote_control_car_has_not_driven_any_distance() { @Test @Tag("task:3") @DisplayName("The distanceDriven method returns 5 after driving once") - public void drive_increases_distance_driven_with_speed() { + public void driveIncreasesDistanceDrivenWithSpeed() { int speed = 5; int batteryDrain = 1; var car = new NeedForSpeed(speed, batteryDrain); @@ -34,7 +34,7 @@ public void drive_increases_distance_driven_with_speed() { @Test @Tag("task:3") @DisplayName("The distanceDriven method returns the correct distance after driving multiple times") - public void drive_does_not_increase_distance_driven_when_battery_drained() { + public void driveDoesNotIncreaseDistanceDrivenWhenBatteryDrained() { int speed = 9; int batteryDrain = 50; var car = new NeedForSpeed(speed, batteryDrain); @@ -52,7 +52,7 @@ public void drive_does_not_increase_distance_driven_when_battery_drained() { @Test @Tag("task:4") @DisplayName("The batteryDrained method returns false when car never drove") - public void new_remote_control_car_battery_is_not_drained() { + public void newRemoteControlCarBatteryIsNotDrained() { int speed = 15; int batteryDrain = 3; var car = new NeedForSpeed(speed, batteryDrain); @@ -63,7 +63,7 @@ public void new_remote_control_car_battery_is_not_drained() { @Test @Tag("task:4") @DisplayName("The batteryDrained method returns false when there's not enough battery") - public void new_remote_control_car_that_can_only_drive_once() { + public void newRemoteControlCarThatCanOnlyDriveOnce() { var car = new NeedForSpeed(1, 99); car.drive(); assertThat(car.batteryDrained()).isTrue(); @@ -74,7 +74,7 @@ public void new_remote_control_car_that_can_only_drive_once() { @Test @Tag("task:4") @DisplayName("The batteryDrained method returns false when car battery did not completely drain after driving") - public void drive_to_almost_drain_battery() { + public void driveToAlmostDrainBattery() { int speed = 2; int batteryDrain = 1; var car = new NeedForSpeed(speed, batteryDrain); @@ -90,7 +90,7 @@ public void drive_to_almost_drain_battery() { @Test @Tag("task:4") @DisplayName("The batteryDrained method returns true when battery completely drained after driving") - public void drive_until_battery_is_drained() { + public void driveUntilBatteryIsDrained() { int speed = 2; int batteryDrain = 1; var car = new NeedForSpeed(speed, batteryDrain); @@ -106,7 +106,7 @@ public void drive_until_battery_is_drained() { @Test @Tag("task:5") @DisplayName("The distanceDriven method returns 0 on a new nitro car") - public void nitro_car_has_not_driven_any_distance() { + public void nitroCarHasNotDrivenAnyDistance() { var car = NeedForSpeed.nitro(); assertThat(car.distanceDriven()).isEqualTo(0); } @@ -114,7 +114,7 @@ public void nitro_car_has_not_driven_any_distance() { @Test @Tag("task:5") @DisplayName("The batteryDrained method returns false when nitro car never drove") - public void nitro_car_has_battery_not_drained() { + public void nitroCarHasBatteryNotDrained() { var car = NeedForSpeed.nitro(); assertThat(car.batteryDrained()).isFalse(); } @@ -122,7 +122,7 @@ public void nitro_car_has_battery_not_drained() { @Test @Tag("task:5") @DisplayName("The distanceDriven method returns the correct distance after driving a nitro car") - public void nitro_car_has_correct_speed() { + public void nitroCarHasCorrectSpeed() { var car = NeedForSpeed.nitro(); car.drive(); assertThat(car.distanceDriven()).isEqualTo(50); @@ -131,7 +131,7 @@ public void nitro_car_has_correct_speed() { @Test @Tag("task:5") @DisplayName("The batteryDrained method returns false when nitro battery did not completely drain after driving") - public void nitro_has_correct_battery_drain() { + public void nitroHasCorrectBatteryDrain() { var car = NeedForSpeed.nitro(); // The battery is almost drained @@ -145,7 +145,7 @@ public void nitro_has_correct_battery_drain() { @Test @Tag("task:5") @DisplayName("The batteryDrained method returns true when nitro battery completely drained after driving") - public void nitro_battery_completely_drains() { + public void nitroBatteryCompletelyDrains() { var car = NeedForSpeed.nitro(); // The battery is drained @@ -159,7 +159,7 @@ public void nitro_battery_completely_drains() { @Test @Tag("task:6") @DisplayName("The canFinishRace method returns true when car can finish a race") - public void car_can_finish_with_car_that_can_easily_finish() { + public void carCanFinishWithCarThatCanEasilyFinish() { int speed = 10; int batteryDrain = 2; var car = new NeedForSpeed(speed, batteryDrain); @@ -173,7 +173,7 @@ public void car_can_finish_with_car_that_can_easily_finish() { @Test @Tag("task:6") @DisplayName("The canFinishRace method returns true when car can just finish a race") - public void car_can_finish_with_car_that_can_just_finish() { + public void carCanFinishWithCarThatCanJustFinish() { int speed = 2; int batteryDrain = 10; var car = new NeedForSpeed(speed, batteryDrain); @@ -187,7 +187,7 @@ public void car_can_finish_with_car_that_can_just_finish() { @Test @Tag("task:6") @DisplayName("The canFinishRace method returns false when car just cannot finish a race") - public void car_can_finish_with_car_that_just_cannot_finish() { + public void carCanFinishWithCarThatJustCannotFinish() { int speed = 3; int batteryDrain = 20; var car = new NeedForSpeed(speed, batteryDrain); @@ -201,7 +201,7 @@ public void car_can_finish_with_car_that_just_cannot_finish() { @Test @Tag("task:6") @DisplayName("The canFinishRace method returns false when car cannot finish a race") - public void car_can_finish_with_car_that_cannot_finish() { + public void carCanFinishWithCarThatCannotFinish() { int speed = 1; int batteryDrain = 20; var car = new NeedForSpeed(speed, batteryDrain); diff --git a/exercises/concept/remote-control-competition/.docs/hints.md b/exercises/concept/remote-control-competition/.docs/hints.md index 1b48b5515..fbd4ebfa7 100644 --- a/exercises/concept/remote-control-competition/.docs/hints.md +++ b/exercises/concept/remote-control-competition/.docs/hints.md @@ -15,7 +15,7 @@ ## 3. Allow the production cars to be ranked - See [this discussion][sort] of sorting. -- See [here][comparable] for default comparison of objects. +- See [Comparable's Javadocs][comparable] for default comparison of objects. [interfaces]: https://docs.oracle.com/javase/tutorial/java/concepts/interface.html [sort]: https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html diff --git a/exercises/concept/remote-control-competition/gradle/wrapper/gradle-wrapper.jar b/exercises/concept/remote-control-competition/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/concept/remote-control-competition/gradle/wrapper/gradle-wrapper.jar and b/exercises/concept/remote-control-competition/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/concept/remote-control-competition/gradle/wrapper/gradle-wrapper.properties b/exercises/concept/remote-control-competition/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/concept/remote-control-competition/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/concept/remote-control-competition/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/concept/remote-control-competition/gradlew b/exercises/concept/remote-control-competition/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/concept/remote-control-competition/gradlew +++ b/exercises/concept/remote-control-competition/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/concept/remote-control-competition/gradlew.bat b/exercises/concept/remote-control-competition/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/concept/remote-control-competition/gradlew.bat +++ b/exercises/concept/remote-control-competition/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/concept/salary-calculator/.docs/hints.md b/exercises/concept/salary-calculator/.docs/hints.md index 1c74c7964..68df6d809 100644 --- a/exercises/concept/salary-calculator/.docs/hints.md +++ b/exercises/concept/salary-calculator/.docs/hints.md @@ -2,7 +2,7 @@ ## General -- Refer to examples [here][ternary-operator-first] and [here][ternary-operator-second] for guidance on using _ternary operators_. +- Refer to examples in [this article][ternary-operator-first] and [this one][ternary-operator-second] for guidance on using _ternary operators_. ## 1. Determine the salary multiplier diff --git a/exercises/concept/salary-calculator/gradle/wrapper/gradle-wrapper.jar b/exercises/concept/salary-calculator/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/concept/salary-calculator/gradle/wrapper/gradle-wrapper.jar and b/exercises/concept/salary-calculator/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/concept/salary-calculator/gradle/wrapper/gradle-wrapper.properties b/exercises/concept/salary-calculator/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/concept/salary-calculator/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/concept/salary-calculator/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/concept/salary-calculator/gradlew b/exercises/concept/salary-calculator/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/concept/salary-calculator/gradlew +++ b/exercises/concept/salary-calculator/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/concept/salary-calculator/gradlew.bat b/exercises/concept/salary-calculator/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/concept/salary-calculator/gradlew.bat +++ b/exercises/concept/salary-calculator/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/concept/secrets/gradle/wrapper/gradle-wrapper.jar b/exercises/concept/secrets/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/concept/secrets/gradle/wrapper/gradle-wrapper.jar and b/exercises/concept/secrets/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/concept/secrets/gradle/wrapper/gradle-wrapper.properties b/exercises/concept/secrets/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/concept/secrets/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/concept/secrets/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/concept/secrets/gradlew b/exercises/concept/secrets/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/concept/secrets/gradlew +++ b/exercises/concept/secrets/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/concept/secrets/gradlew.bat b/exercises/concept/secrets/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/concept/secrets/gradlew.bat +++ b/exercises/concept/secrets/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/concept/squeaky-clean/.docs/introduction.md b/exercises/concept/squeaky-clean/.docs/introduction.md index 15e81f074..016475918 100644 --- a/exercises/concept/squeaky-clean/.docs/introduction.md +++ b/exercises/concept/squeaky-clean/.docs/introduction.md @@ -2,13 +2,88 @@ ## Chars -The Java `char` type represents the smallest addressable components of text. -Multiple `char`s can comprise a string such as `"word"` or `char`s can be processed independently. -Their literals have single quotes e.g. `'A'`. +### chars + +The Java `char` primitive type is a 16 bit representation of a single character. +Multiple `char`s can comprise a string, such as `"word"`, or `char`s can be processed independently. +A `char` literal is surrounded by single quotes (e.g. `'A'`). + +```java +char lowerA = 'a'; +char upperB = 'B'; +``` + +### Getting the `char`s of a `String` + +The `String.toCharArray` method returns a String's chars as an array. +As mentioned in arrays, you can use a `for` loop to iterate over the array. + +```java +String text = "Hello"; +char[] asArray = text.toCharArray(); + +for (char ch: asArray) { + System.out.println(ch); +} + +// Outputs: +// H +// e +// l +// l +// o +``` + +### The Character class There are many builtin library methods to inspect and manipulate `char`s. These can be found as static methods of the `java.lang.Character` class. +Here are some examples: + +```java +Character.isWhitespace(' '); // true +Character.isWhitespace('#'); // false + +Character.isLetter('a'); // true +Character.isLetter('3'); // false + +Character.isDigit('6'); // true +Character.isDigit('?'); // false +``` + +### Adding a `char` to a `String` + +The `+` operator can be used to add a `char` to a `String`. + +```java +'a' + " banana" // => "a banana" +"banana " + 'a' // => "banana a" +``` + +~~~~exercism/caution +Becareful _not_ to use `+` to join two `char`s together to form a `String`! +Adding two `char`s this way gives an `int`, _not_ a `String`! +For example: + +```java +'b' + 'c'; +// => 197 (not the String "bc") +``` + +This is because Java promotes the `char` to an `int` (see [4.2 Primitive Types and Values ][jls-primitives] of the [Java Language Specification][jls-main]). + +[jls-main]: https://docs.oracle.com/javase/specs/jls/se21/html/ +[jls-primitives]: https://docs.oracle.com/javase/specs/jls/se21/html/jls-4.html#jls-4.2 +~~~~ + +However, when there are many characters to be added, it can be more efficient to use a `StringBuilder` instead: + +```java +StringBuilder builder = new StringBuilder(); +builder.append('a'); +builder.append('b'); +builder.append('c'); -`char`s are sometimes used in conjunction with a `StringBuilder` object. -This object has methods that allow a string to be constructed character by character and manipulated. -At the end of the process `toString` can be called on it to output a complete string. +String builtString = builder.toString(); +// => abc +``` diff --git a/exercises/concept/squeaky-clean/.meta/config.json b/exercises/concept/squeaky-clean/.meta/config.json index b8380b192..70df5ac7d 100644 --- a/exercises/concept/squeaky-clean/.meta/config.json +++ b/exercises/concept/squeaky-clean/.meta/config.json @@ -4,6 +4,7 @@ ], "contributors": [ "jagdish-15", + "kahgoh", "manumafe98", "mrDonoghue", "sanderploegsma" diff --git a/exercises/concept/squeaky-clean/gradle/wrapper/gradle-wrapper.jar b/exercises/concept/squeaky-clean/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/concept/squeaky-clean/gradle/wrapper/gradle-wrapper.jar and b/exercises/concept/squeaky-clean/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/concept/squeaky-clean/gradle/wrapper/gradle-wrapper.properties b/exercises/concept/squeaky-clean/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/concept/squeaky-clean/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/concept/squeaky-clean/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/concept/squeaky-clean/gradlew b/exercises/concept/squeaky-clean/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/concept/squeaky-clean/gradlew +++ b/exercises/concept/squeaky-clean/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/concept/squeaky-clean/gradlew.bat b/exercises/concept/squeaky-clean/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/concept/squeaky-clean/gradlew.bat +++ b/exercises/concept/squeaky-clean/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/concept/squeaky-clean/src/test/java/SqueakyCleanTest.java b/exercises/concept/squeaky-clean/src/test/java/SqueakyCleanTest.java index 19688de55..e85a60495 100644 --- a/exercises/concept/squeaky-clean/src/test/java/SqueakyCleanTest.java +++ b/exercises/concept/squeaky-clean/src/test/java/SqueakyCleanTest.java @@ -16,7 +16,7 @@ public void empty() { @Test @Tag("task:1") @DisplayName("The clean method returns the same string when invoked on a single letter string") - public void single_letter() { + public void singleLetter() { assertThat(SqueakyClean.clean("A")).isEqualTo("A"); } @@ -37,56 +37,56 @@ public void spaces() { @Test @Tag("task:1") @DisplayName("The clean method replaces leading and trailing whitespaces with underscores") - public void leading_and_trailing_spaces() { + public void leadingAndTrailingSpaces() { assertThat(SqueakyClean.clean(" myId ")).isEqualTo("_myId_"); } @Test @Tag("task:2") @DisplayName("The clean method converts kebab to camel case after removing a dash") - public void kebab_to_camel_case() { + public void kebabToCamelCase() { assertThat(SqueakyClean.clean("a-bc")).isEqualTo("aBc"); } @Test @Tag("task:2") @DisplayName("The clean method returns a string in camel case after removing a dash and replaces a whitespace") - public void kebab_to_camel_case_and_number() { + public void kebabToCamelCaseAndNumber() { assertThat(SqueakyClean.clean("a-C ")).isEqualTo("aC_"); } @Test @Tag("task:2") @DisplayName("The clean method returns a string in camel case and replaces leading and trailing whitespaces") - public void kebab_to_camel_case_and_spaces() { + public void kebabToCamelCaseAndSpaces() { assertThat(SqueakyClean.clean(" hello-world ")).isEqualTo("_helloWorld_"); } @Test @Tag("task:3") @DisplayName("The clean method converts leetspeak to normal text after replacing numbers with chars") - public void leetspeak_to_normal_text() { + public void leetspeakToNormalText() { assertThat(SqueakyClean.clean("H3ll0 W0rld")).isEqualTo("Hello_World"); } @Test @Tag("task:3") @DisplayName("The clean method converts leetspeak to normal text with spaces and special characters") - public void leetspeak_to_normal_text_with_spaces_and_special_characters() { + public void leetspeakToNormalTextWithSpacesAndSpecialCharacters() { assertThat(SqueakyClean.clean("¡1337sp34k is fun!")).isEqualTo("leetspeak_is_fun"); } @Test @Tag("task:4") @DisplayName("The clean method removes all characters that are not letters") - public void special_characters() { + public void specialCharacters() { assertThat(SqueakyClean.clean("a$#.b")).isEqualTo("ab"); } @Test @Tag("task:4") @DisplayName("The clean method removes all characters that are not letters and replaces spaces") - public void special_characters_and_spaces() { + public void specialCharactersAndSpaces() { assertThat(SqueakyClean.clean("¡hello world!. ")).isEqualTo("hello_world_"); } } diff --git a/exercises/concept/tim-from-marketing/gradle/wrapper/gradle-wrapper.jar b/exercises/concept/tim-from-marketing/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/concept/tim-from-marketing/gradle/wrapper/gradle-wrapper.jar and b/exercises/concept/tim-from-marketing/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/concept/tim-from-marketing/gradle/wrapper/gradle-wrapper.properties b/exercises/concept/tim-from-marketing/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/concept/tim-from-marketing/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/concept/tim-from-marketing/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/concept/tim-from-marketing/gradlew b/exercises/concept/tim-from-marketing/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/concept/tim-from-marketing/gradlew +++ b/exercises/concept/tim-from-marketing/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/concept/tim-from-marketing/gradlew.bat b/exercises/concept/tim-from-marketing/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/concept/tim-from-marketing/gradlew.bat +++ b/exercises/concept/tim-from-marketing/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/concept/wizards-and-warriors-2/gradle/wrapper/gradle-wrapper.jar b/exercises/concept/wizards-and-warriors-2/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/concept/wizards-and-warriors-2/gradle/wrapper/gradle-wrapper.jar and b/exercises/concept/wizards-and-warriors-2/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/concept/wizards-and-warriors-2/gradle/wrapper/gradle-wrapper.properties b/exercises/concept/wizards-and-warriors-2/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/concept/wizards-and-warriors-2/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/concept/wizards-and-warriors-2/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/concept/wizards-and-warriors-2/gradlew b/exercises/concept/wizards-and-warriors-2/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/concept/wizards-and-warriors-2/gradlew +++ b/exercises/concept/wizards-and-warriors-2/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/concept/wizards-and-warriors-2/gradlew.bat b/exercises/concept/wizards-and-warriors-2/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/concept/wizards-and-warriors-2/gradlew.bat +++ b/exercises/concept/wizards-and-warriors-2/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/concept/wizards-and-warriors/.docs/hints.md b/exercises/concept/wizards-and-warriors/.docs/hints.md index ab6871b2f..d9d52fc58 100644 --- a/exercises/concept/wizards-and-warriors/.docs/hints.md +++ b/exercises/concept/wizards-and-warriors/.docs/hints.md @@ -13,7 +13,7 @@ The whole inheritance concept has a lot to do with the concepts around [overridi ## 2. Describe a Warrior - In Java, the `toString()` method is actually present inside the `Object` class (which is a superclass to all the classes in Java). - You can read more about it [here][object-class-java]. + You can read more about it at the official [Oracle documentation][object-class-java]. - To override this method inside your implementation class, you should have a method with same name i.e. `toString()` and same return type i.e. `String`. - The `toString()` method must be `public`. @@ -34,7 +34,7 @@ The whole inheritance concept has a lot to do with the concepts around [overridi ## 6. Describe a Wizard - In Java, the `toString()` method is actually present inside the `Object` class (which is a superclass to all the classes in Java). - You can read more about it [here][object-class-java]. + You can read more about it at the official [Oracle documentation][object-class-java]. - To override this method inside your implementation class, you should have a method with same name i.e. `toString()` and same return type i.e. `String`. - The `toString()` method must be `public`. diff --git a/exercises/concept/wizards-and-warriors/gradle/wrapper/gradle-wrapper.jar b/exercises/concept/wizards-and-warriors/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/concept/wizards-and-warriors/gradle/wrapper/gradle-wrapper.jar and b/exercises/concept/wizards-and-warriors/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/concept/wizards-and-warriors/gradle/wrapper/gradle-wrapper.properties b/exercises/concept/wizards-and-warriors/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/concept/wizards-and-warriors/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/concept/wizards-and-warriors/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/concept/wizards-and-warriors/gradlew b/exercises/concept/wizards-and-warriors/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/concept/wizards-and-warriors/gradlew +++ b/exercises/concept/wizards-and-warriors/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/concept/wizards-and-warriors/gradlew.bat b/exercises/concept/wizards-and-warriors/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/concept/wizards-and-warriors/gradlew.bat +++ b/exercises/concept/wizards-and-warriors/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/gradle/wrapper/gradle-wrapper.jar b/exercises/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/gradle/wrapper/gradle-wrapper.jar and b/exercises/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/gradle/wrapper/gradle-wrapper.properties b/exercises/gradle/wrapper/gradle-wrapper.properties index b82aa23a4..23449a2b5 100644 --- a/exercises/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/exercises/gradlew b/exercises/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/gradlew +++ b/exercises/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/gradlew.bat b/exercises/gradlew.bat index 93e3f59f1..c4bdd3ab8 100644 --- a/exercises/gradlew.bat +++ b/exercises/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -43,11 +45,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,22 +59,21 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/acronym/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/acronym/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/acronym/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/acronym/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/acronym/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/acronym/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/acronym/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/acronym/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/acronym/gradlew b/exercises/practice/acronym/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/acronym/gradlew +++ b/exercises/practice/acronym/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/acronym/gradlew.bat b/exercises/practice/acronym/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/acronym/gradlew.bat +++ b/exercises/practice/acronym/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/acronym/src/test/java/AcronymTest.java b/exercises/practice/acronym/src/test/java/AcronymTest.java index 4cc09f4cf..09b419c4a 100644 --- a/exercises/practice/acronym/src/test/java/AcronymTest.java +++ b/exercises/practice/acronym/src/test/java/AcronymTest.java @@ -1,11 +1,13 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; public class AcronymTest { - + @Test + @DisplayName("basic") public void basic() { assertThat(new Acronym("Portable Network Graphics").get()) .isEqualTo("PNG"); @@ -13,6 +15,7 @@ public void basic() { @Disabled("Remove to run test") @Test + @DisplayName("lowercase words") public void lowercaseWords() { assertThat(new Acronym("Ruby on Rails").get()) .isEqualTo("ROR"); @@ -20,6 +23,7 @@ public void lowercaseWords() { @Disabled("Remove to run test") @Test + @DisplayName("punctuation") public void punctuation() { assertThat(new Acronym("First In, First Out").get()) .isEqualTo("FIFO"); @@ -27,6 +31,7 @@ public void punctuation() { @Disabled("Remove to run test") @Test + @DisplayName("all caps word") public void nonAcronymAllCapsWord() { assertThat(new Acronym("GNU Image Manipulation Program").get()) .isEqualTo("GIMP"); @@ -34,6 +39,7 @@ public void nonAcronymAllCapsWord() { @Disabled("Remove to run test") @Test + @DisplayName("punctuation without whitespace") public void punctuationWithoutWhitespace() { assertThat(new Acronym("Complementary metal-oxide semiconductor").get()) .isEqualTo("CMOS"); @@ -41,6 +47,7 @@ public void punctuationWithoutWhitespace() { @Disabled("Remove to run test") @Test + @DisplayName("very long abbreviation") public void veryLongAbbreviation() { assertThat(new Acronym("Rolling On The Floor Laughing So Hard That My Dogs Came Over And Licked Me").get()) .isEqualTo("ROTFLSHTMDCOALM"); @@ -48,6 +55,7 @@ public void veryLongAbbreviation() { @Disabled("Remove to run test") @Test + @DisplayName("consecutive delimiters") public void consecutiveDelimiters() { assertThat(new Acronym("Something - I made up from thin air").get()) .isEqualTo("SIMUFTA"); @@ -55,6 +63,7 @@ public void consecutiveDelimiters() { @Disabled("Remove to run test") @Test + @DisplayName("apostrophes") public void apostrophes() { assertThat(new Acronym("Halley's Comet").get()) .isEqualTo("HC"); @@ -62,6 +71,7 @@ public void apostrophes() { @Disabled("Remove to run test") @Test + @DisplayName("underscore emphasis") public void underscoreEmphasis() { assertThat(new Acronym("The Road _Not_ Taken").get()) .isEqualTo("TRNT"); diff --git a/exercises/practice/affine-cipher/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/affine-cipher/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/affine-cipher/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/affine-cipher/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/affine-cipher/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/affine-cipher/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/affine-cipher/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/affine-cipher/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/affine-cipher/gradlew b/exercises/practice/affine-cipher/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/affine-cipher/gradlew +++ b/exercises/practice/affine-cipher/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/affine-cipher/gradlew.bat b/exercises/practice/affine-cipher/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/affine-cipher/gradlew.bat +++ b/exercises/practice/affine-cipher/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/affine-cipher/src/test/java/AffineCipherTest.java b/exercises/practice/affine-cipher/src/test/java/AffineCipherTest.java index d37c96ade..25bad1a0b 100644 --- a/exercises/practice/affine-cipher/src/test/java/AffineCipherTest.java +++ b/exercises/practice/affine-cipher/src/test/java/AffineCipherTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -9,18 +10,20 @@ public class AffineCipherTest { private AffineCipher affineCipher = new AffineCipher(); @Test + @DisplayName("encode yes") public void testEncodeYes() { assertThat(affineCipher.encode("yes", 5, 7)).isEqualTo("xbt"); } @Disabled("Remove to run test") @Test + @DisplayName("encode no") public void testEncodeNo() { assertThat(affineCipher.encode("no", 15, 18)).isEqualTo("fu"); } - @Disabled("Remove to run test") + @DisplayName("encode OMG") @Test public void testEncodeOMG() { assertThat(affineCipher.encode("OMG", 21, 3)).isEqualTo("lvz"); @@ -28,18 +31,21 @@ public void testEncodeOMG() { @Disabled("Remove to run test") @Test - public void testEncodeO_M_G() { + @DisplayName("encode O M G") + public void testEncodeOMGWithSpaces() { assertThat(affineCipher.encode("O M G", 25, 47)).isEqualTo("hjp"); } @Disabled("Remove to run test") @Test + @DisplayName("encode mindblowingly") public void testEncodeMindBlowingly() { assertThat(affineCipher.encode("mindblowingly", 11, 15)).isEqualTo("rzcwa gnxzc dgt"); } @Disabled("Remove to run test") @Test + @DisplayName("encode numbers") public void testEncodeNumbers() { assertThat(affineCipher.encode("Testing,1 2 3, testing.", 3, 4)) .isEqualTo("jqgjc rw123 jqgjc rw"); @@ -47,6 +53,7 @@ public void testEncodeNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("encode deep thought") public void testEncodeDeepThought() { assertThat(affineCipher.encode("Truth is fiction.", 5, 17)) .isEqualTo("iynia fdqfb ifje"); @@ -54,6 +61,7 @@ public void testEncodeDeepThought() { @Disabled("Remove to run test") @Test + @DisplayName("encode all the letters") public void testEncodeAllTheLetters() { assertThat(affineCipher.encode("The quick brown fox jumps over the lazy dog.", 17, 33)) .isEqualTo("swxtj npvyk lruol iejdc blaxk swxmh qzglf"); @@ -61,6 +69,7 @@ public void testEncodeAllTheLetters() { @Disabled("Remove to run test") @Test + @DisplayName("encode with a not coprime to m") public void testEncodeThrowsMeaningfulException() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> affineCipher.encode("This is a test", 6, 17)) @@ -69,6 +78,7 @@ public void testEncodeThrowsMeaningfulException() { @Disabled("Remove to run test") @Test + @DisplayName("decode exercism") public void testDecodeExercism() { assertThat(affineCipher.decode("tytgn fjr", 3, 7)) .isEqualTo("exercism"); @@ -76,6 +86,7 @@ public void testDecodeExercism() { @Disabled("Remove to run test") @Test + @DisplayName("decode a sentence") public void testDecodeSentence() { assertThat(affineCipher.decode("qdwju nqcro muwhn odqun oppmd aunwd o", 19, 16)) .isEqualTo("anobstacleisoftenasteppingstone"); @@ -83,6 +94,7 @@ public void testDecodeSentence() { @Disabled("Remove to run test") @Test + @DisplayName("decode numbers") public void testDecodeNumbers() { assertThat(affineCipher.decode("odpoz ub123 odpoz ub", 25, 7)) .isEqualTo("testing123testing"); @@ -90,6 +102,7 @@ public void testDecodeNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("decode all the letters") public void testDecodeAllTheLetters() { assertThat(affineCipher.decode("swxtj npvyk lruol iejdc blaxk swxmh qzglf", 17, 33)) .isEqualTo("thequickbrownfoxjumpsoverthelazydog"); @@ -97,6 +110,7 @@ public void testDecodeAllTheLetters() { @Disabled("Remove to run test") @Test + @DisplayName("decode with no spaces in input") public void testDecodeWithNoSpaces() { assertThat(affineCipher.decode("swxtjnpvyklruoliejdcblaxkswxmhqzglf", 17, 33)) .isEqualTo("thequickbrownfoxjumpsoverthelazydog"); @@ -104,6 +118,7 @@ public void testDecodeWithNoSpaces() { @Disabled("Remove to run test") @Test + @DisplayName("decode with too many spaces") public void testDecodeWithTooManySpaces() { assertThat(affineCipher.decode("vszzm cly yd cg qdp", 15, 16)) .isEqualTo("jollygreengiant"); @@ -111,6 +126,7 @@ public void testDecodeWithTooManySpaces() { @Disabled("Remove to run test") @Test + @DisplayName("decode with a not coprime to m") public void testDecodeThrowsMeaningfulException() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> affineCipher.decode("Test", 13, 5)) diff --git a/exercises/practice/all-your-base/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/all-your-base/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/all-your-base/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/all-your-base/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/all-your-base/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/all-your-base/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/all-your-base/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/all-your-base/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/all-your-base/gradlew b/exercises/practice/all-your-base/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/all-your-base/gradlew +++ b/exercises/practice/all-your-base/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/all-your-base/gradlew.bat b/exercises/practice/all-your-base/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/all-your-base/gradlew.bat +++ b/exercises/practice/all-your-base/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/all-your-base/src/test/java/BaseConverterTest.java b/exercises/practice/all-your-base/src/test/java/BaseConverterTest.java index c84e97af0..c2ca95a70 100644 --- a/exercises/practice/all-your-base/src/test/java/BaseConverterTest.java +++ b/exercises/practice/all-your-base/src/test/java/BaseConverterTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -7,6 +8,7 @@ public class BaseConverterTest { @Test + @DisplayName("single bit one to decimal") public void testSingleBitOneToDecimal() { BaseConverter baseConverter = new BaseConverter(2, new int[]{1}); @@ -16,6 +18,7 @@ public void testSingleBitOneToDecimal() { @Disabled("Remove to run test") @Test + @DisplayName("binary to single decimal") public void testBinaryToSingleDecimal() { BaseConverter baseConverter = new BaseConverter(2, new int[]{1, 0, 1}); @@ -25,6 +28,7 @@ public void testBinaryToSingleDecimal() { @Disabled("Remove to run test") @Test + @DisplayName("single decimal to binary") public void testSingleDecimalToBinary() { BaseConverter baseConverter = new BaseConverter(10, new int[]{5}); @@ -34,6 +38,7 @@ public void testSingleDecimalToBinary() { @Disabled("Remove to run test") @Test + @DisplayName("binary to multiple decimal") public void testBinaryToMultipleDecimal() { BaseConverter baseConverter = new BaseConverter(2, new int[]{1, 0, 1, 0, 1, 0}); @@ -43,6 +48,7 @@ public void testBinaryToMultipleDecimal() { @Disabled("Remove to run test") @Test + @DisplayName("decimal to binary") public void testDecimalToBinary() { BaseConverter baseConverter = new BaseConverter(10, new int[]{4, 2}); @@ -52,6 +58,7 @@ public void testDecimalToBinary() { @Disabled("Remove to run test") @Test + @DisplayName("trinary to hexadecimal") public void testTrinaryToHexadecimal() { BaseConverter baseConverter = new BaseConverter(3, new int[]{1, 1, 2, 0}); @@ -61,6 +68,7 @@ public void testTrinaryToHexadecimal() { @Disabled("Remove to run test") @Test + @DisplayName("hexadecimal to trinary") public void testHexadecimalToTrinary() { BaseConverter baseConverter = new BaseConverter(16, new int[]{2, 10}); @@ -70,6 +78,7 @@ public void testHexadecimalToTrinary() { @Disabled("Remove to run test") @Test + @DisplayName("15-bit integer") public void test15BitInteger() { BaseConverter baseConverter = new BaseConverter(97, new int[]{3, 46, 60}); @@ -79,6 +88,7 @@ public void test15BitInteger() { @Disabled("Remove to run test") @Test + @DisplayName("empty list") public void testEmptyDigits() { BaseConverter baseConverter = new BaseConverter(2, new int[]{}); @@ -88,6 +98,7 @@ public void testEmptyDigits() { @Disabled("Remove to run test") @Test + @DisplayName("single zero") public void testSingleZero() { BaseConverter baseConverter = new BaseConverter(10, new int[]{0}); @@ -97,6 +108,7 @@ public void testSingleZero() { @Disabled("Remove to run test") @Test + @DisplayName("multiple zeros") public void testMultipleZeros() { BaseConverter baseConverter = new BaseConverter(10, new int[]{0, 0, 0}); @@ -106,6 +118,7 @@ public void testMultipleZeros() { @Disabled("Remove to run test") @Test + @DisplayName("leading zeros") public void testLeadingZeros() { BaseConverter baseConverter = new BaseConverter(7, new int[]{0, 6, 0}); @@ -115,22 +128,25 @@ public void testLeadingZeros() { @Disabled("Remove to run test") @Test + @DisplayName("input base is one") public void testFirstBaseIsOne() { assertThatExceptionOfType(IllegalArgumentException.class) - .isThrownBy(() -> new BaseConverter(1, new int[]{1})) + .isThrownBy(() -> new BaseConverter(1, new int[]{0})) .withMessage("Bases must be at least 2."); } @Disabled("Remove to run test") @Test + @DisplayName("input base is zero") public void testFirstBaseIsZero() { assertThatExceptionOfType(IllegalArgumentException.class) - .isThrownBy(() -> new BaseConverter(0, new int[]{1})) + .isThrownBy(() -> new BaseConverter(0, new int[]{})) .withMessage("Bases must be at least 2."); } @Disabled("Remove to run test") @Test + @DisplayName("input base is negative") public void testFirstBaseIsNegative() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> new BaseConverter(-2, new int[]{1})) @@ -139,6 +155,7 @@ public void testFirstBaseIsNegative() { @Disabled("Remove to run test") @Test + @DisplayName("negative digit") public void testNegativeDigit() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> new BaseConverter(2, new int[]{1, -1, 1, 0, 1, 0})) @@ -147,6 +164,7 @@ public void testNegativeDigit() { @Disabled("Remove to run test") @Test + @DisplayName("invalid positive digit") public void testInvalidPositiveDigit() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> new BaseConverter(2, new int[]{1, 2, 1, 0, 1, 0})) @@ -155,6 +173,7 @@ public void testInvalidPositiveDigit() { @Disabled("Remove to run test") @Test + @DisplayName("output base is one") public void testSecondBaseIsOne() { BaseConverter baseConverter = new BaseConverter(2, new int[]{1, 0, 1, 0, 1, 0}); @@ -166,6 +185,7 @@ public void testSecondBaseIsOne() { @Disabled("Remove to run test") @Test + @DisplayName("output base is zero") public void testSecondBaseIsZero() { BaseConverter baseConverter = new BaseConverter(10, new int[]{7}); @@ -176,6 +196,7 @@ public void testSecondBaseIsZero() { @Disabled("Remove to run test") @Test + @DisplayName("output base is negative") public void testSecondBaseIsNegative() { BaseConverter baseConverter = new BaseConverter(2, new int[]{1}); diff --git a/exercises/practice/allergies/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/allergies/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/allergies/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/allergies/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/allergies/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/allergies/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/allergies/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/allergies/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/allergies/gradlew b/exercises/practice/allergies/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/allergies/gradlew +++ b/exercises/practice/allergies/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/allergies/gradlew.bat b/exercises/practice/allergies/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/allergies/gradlew.bat +++ b/exercises/practice/allergies/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/allergies/src/test/java/AllergiesTest.java b/exercises/practice/allergies/src/test/java/AllergiesTest.java index 851b40656..cd0ae5cf7 100644 --- a/exercises/practice/allergies/src/test/java/AllergiesTest.java +++ b/exercises/practice/allergies/src/test/java/AllergiesTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -9,6 +10,7 @@ public class AllergiesTest { // Testing for eggs allergy @Test + @DisplayName("not allergic to anything") public void eggsNotAllergicToAnything() { Allergies allergies = new Allergies(0); @@ -17,6 +19,7 @@ public void eggsNotAllergicToAnything() { @Disabled("Remove to run test") @Test + @DisplayName("allergic only to eggs") public void eggsAllergicOnlyToEggs() { Allergies allergies = new Allergies(1); @@ -25,6 +28,7 @@ public void eggsAllergicOnlyToEggs() { @Disabled("Remove to run test") @Test + @DisplayName("allergic to eggs and something else") public void eggsAllergicToEggsAndSomethingElse() { Allergies allergies = new Allergies(3); @@ -33,6 +37,7 @@ public void eggsAllergicToEggsAndSomethingElse() { @Disabled("Remove to run test") @Test + @DisplayName("allergic to something, but not eggs") public void eggsAllergicToSomethingButNotEggs() { Allergies allergies = new Allergies(2); @@ -41,6 +46,7 @@ public void eggsAllergicToSomethingButNotEggs() { @Disabled("Remove to run test") @Test + @DisplayName("allergic to everything") public void eggsAllergicToEverything() { Allergies allergies = new Allergies(255); @@ -51,6 +57,7 @@ public void eggsAllergicToEverything() { // Testing for peanuts allergy @Test + @DisplayName("not allergic to anything") public void peanutsNotAllergicToAnything() { Allergies allergies = new Allergies(0); @@ -59,6 +66,7 @@ public void peanutsNotAllergicToAnything() { @Disabled("Remove to run test") @Test + @DisplayName("allergic only to peanuts") public void peanutsAllergicOnlyToPeanuts() { Allergies allergies = new Allergies(2); @@ -67,6 +75,7 @@ public void peanutsAllergicOnlyToPeanuts() { @Disabled("Remove to run test") @Test + @DisplayName("allergic to peanuts and something else") public void peanutsAllergicToPeanutsAndSomethingElse() { Allergies allergies = new Allergies(7); @@ -75,6 +84,7 @@ public void peanutsAllergicToPeanutsAndSomethingElse() { @Disabled("Remove to run test") @Test + @DisplayName("allergic to something, but not peanuts") public void peanutsAllergicToSomethingButNotPeanuts() { Allergies allergies = new Allergies(5); @@ -83,6 +93,7 @@ public void peanutsAllergicToSomethingButNotPeanuts() { @Disabled("Remove to run test") @Test + @DisplayName("allergic to everything") public void peanutsAllergicToEverything() { Allergies allergies = new Allergies(255); @@ -93,6 +104,7 @@ public void peanutsAllergicToEverything() { // Testing for shellfish allergy @Test + @DisplayName("not allergic to anything") public void shellfishNotAllergicToAnything() { Allergies allergies = new Allergies(0); @@ -101,6 +113,7 @@ public void shellfishNotAllergicToAnything() { @Disabled("Remove to run test") @Test + @DisplayName("allergic only to shellfish") public void shellfishAllergicOnlyToShellfish() { Allergies allergies = new Allergies(4); @@ -109,6 +122,7 @@ public void shellfishAllergicOnlyToShellfish() { @Disabled("Remove to run test") @Test + @DisplayName("allergic to shellfish and something else") public void shellfishAllergicToShellfishAndSomethingElse() { Allergies allergies = new Allergies(14); @@ -117,6 +131,7 @@ public void shellfishAllergicToShellfishAndSomethingElse() { @Disabled("Remove to run test") @Test + @DisplayName("allergic to something, but not shellfish") public void shellfishAllergicToSomethingButNotShellfish() { Allergies allergies = new Allergies(10); @@ -125,6 +140,7 @@ public void shellfishAllergicToSomethingButNotShellfish() { @Disabled("Remove to run test") @Test + @DisplayName("allergic to everything") public void shellfishAllergicToEverything() { Allergies allergies = new Allergies(255); @@ -135,6 +151,7 @@ public void shellfishAllergicToEverything() { // Testing for strawberries allergy @Test + @DisplayName("not allergic to anything") public void strawberriesNotAllergicToAnything() { Allergies allergies = new Allergies(0); @@ -143,6 +160,7 @@ public void strawberriesNotAllergicToAnything() { @Disabled("Remove to run test") @Test + @DisplayName("allergic only to strawberries") public void strawberriesAllergicOnlyToStrawberries() { Allergies allergies = new Allergies(8); @@ -151,6 +169,7 @@ public void strawberriesAllergicOnlyToStrawberries() { @Disabled("Remove to run test") @Test + @DisplayName("allergic to strawberries and something else") public void strawberriesAllergicToStrawberriesAndSomethingElse() { Allergies allergies = new Allergies(28); @@ -159,6 +178,7 @@ public void strawberriesAllergicToStrawberriesAndSomethingElse() { @Disabled("Remove to run test") @Test + @DisplayName("allergic to something, but not strawberries") public void strawberriesAllergicToSomethingButNotStrawberries() { Allergies allergies = new Allergies(20); @@ -167,6 +187,7 @@ public void strawberriesAllergicToSomethingButNotStrawberries() { @Disabled("Remove to run test") @Test + @DisplayName("allergic to everything") public void strawberriesAllergicToEverything() { Allergies allergies = new Allergies(255); @@ -177,6 +198,7 @@ public void strawberriesAllergicToEverything() { // Testing for tomatoes allergy @Test + @DisplayName("not allergic to anything") public void tomatoesNotAllergicToAnything() { Allergies allergies = new Allergies(0); @@ -185,6 +207,7 @@ public void tomatoesNotAllergicToAnything() { @Disabled("Remove to run test") @Test + @DisplayName("allergic only to tomatoes") public void tomatoesAllergicOnlyToTomatoes() { Allergies allergies = new Allergies(16); @@ -193,6 +216,7 @@ public void tomatoesAllergicOnlyToTomatoes() { @Disabled("Remove to run test") @Test + @DisplayName("allergic to tomatoes and something else") public void tomatoesAllergicToTomatoesAndSomethingElse() { Allergies allergies = new Allergies(56); @@ -201,6 +225,7 @@ public void tomatoesAllergicToTomatoesAndSomethingElse() { @Disabled("Remove to run test") @Test + @DisplayName("allergic to something, but not tomatoes") public void tomatoesAllergicToSomethingButNotTomatoes() { Allergies allergies = new Allergies(40); @@ -209,6 +234,7 @@ public void tomatoesAllergicToSomethingButNotTomatoes() { @Disabled("Remove to run test") @Test + @DisplayName("allergic to everything") public void tomatoesAllergicToEverything() { Allergies allergies = new Allergies(255); @@ -219,6 +245,7 @@ public void tomatoesAllergicToEverything() { // Testing for chocolate allergy @Test + @DisplayName("not allergic to anything") public void chocolateNotAllergicToAnything() { Allergies allergies = new Allergies(0); @@ -227,6 +254,7 @@ public void chocolateNotAllergicToAnything() { @Disabled("Remove to run test") @Test + @DisplayName("allergic only to chocolate") public void chocolateAllergicOnlyToChocolate() { Allergies allergies = new Allergies(32); @@ -235,6 +263,7 @@ public void chocolateAllergicOnlyToChocolate() { @Disabled("Remove to run test") @Test + @DisplayName("allergic to chocolate and something else") public void chocolateAllergicToChocolateAndSomethingElse() { Allergies allergies = new Allergies(112); @@ -243,6 +272,7 @@ public void chocolateAllergicToChocolateAndSomethingElse() { @Disabled("Remove to run test") @Test + @DisplayName("allergic to something, but not chocolate") public void chocolateAllergicToSomethingButNotChocolate() { Allergies allergies = new Allergies(80); @@ -251,6 +281,7 @@ public void chocolateAllergicToSomethingButNotChocolate() { @Disabled("Remove to run test") @Test + @DisplayName("allergic to everything") public void chocolateAllergicToEverything() { Allergies allergies = new Allergies(255); @@ -261,6 +292,7 @@ public void chocolateAllergicToEverything() { // Testing for pollen allergy @Test + @DisplayName("not allergic to anything") public void pollenNotAllergicToAnything() { Allergies allergies = new Allergies(0); @@ -269,6 +301,7 @@ public void pollenNotAllergicToAnything() { @Disabled("Remove to run test") @Test + @DisplayName("allergic only to pollen") public void pollenAllergicOnlyToPollen() { Allergies allergies = new Allergies(64); @@ -277,6 +310,7 @@ public void pollenAllergicOnlyToPollen() { @Disabled("Remove to run test") @Test + @DisplayName("allergic to pollen and something else") public void pollenAllergicToPollenAndSomethingElse() { Allergies allergies = new Allergies(224); @@ -285,6 +319,7 @@ public void pollenAllergicToPollenAndSomethingElse() { @Disabled("Remove to run test") @Test + @DisplayName("allergic to something, but not pollen") public void pollenAllergicToSomethingButNotPollen() { Allergies allergies = new Allergies(160); @@ -293,6 +328,7 @@ public void pollenAllergicToSomethingButNotPollen() { @Disabled("Remove to run test") @Test + @DisplayName("allergic to everything") public void pollenAllergicToEverything() { Allergies allergies = new Allergies(255); @@ -303,6 +339,7 @@ public void pollenAllergicToEverything() { // Testing for cats allergy @Test + @DisplayName("not allergic to anything") public void catsNotAllergicToAnything() { Allergies allergies = new Allergies(0); @@ -311,6 +348,7 @@ public void catsNotAllergicToAnything() { @Disabled("Remove to run test") @Test + @DisplayName("allergic only to cats") public void catsAllergicOnlyToCats() { Allergies allergies = new Allergies(128); @@ -319,6 +357,7 @@ public void catsAllergicOnlyToCats() { @Disabled("Remove to run test") @Test + @DisplayName("allergic to cats and something else") public void catsAllergicToCatsAndSomethingElse() { Allergies allergies = new Allergies(192); @@ -327,6 +366,7 @@ public void catsAllergicToCatsAndSomethingElse() { @Disabled("Remove to run test") @Test + @DisplayName("allergic to something, but not cats") public void catsAllergicToSomethingButNotCats() { Allergies allergies = new Allergies(64); @@ -335,6 +375,7 @@ public void catsAllergicToSomethingButNotCats() { @Disabled("Remove to run test") @Test + @DisplayName("allergic to everything") public void catsAllergicToEverything() { Allergies allergies = new Allergies(255); @@ -346,6 +387,7 @@ public void catsAllergicToEverything() { @Disabled("Remove to run test") @Test + @DisplayName("no allergies") public void listNoAllergies() { Allergies allergies = new Allergies(0); @@ -354,6 +396,7 @@ public void listNoAllergies() { @Disabled("Remove to run test") @Test + @DisplayName("just eggs") public void listJustEggs() { Allergies allergies = new Allergies(1); @@ -363,6 +406,7 @@ public void listJustEggs() { @Disabled("Remove to run test") @Test + @DisplayName("just peanuts") public void listJustPeanuts() { Allergies allergies = new Allergies(2); @@ -372,6 +416,7 @@ public void listJustPeanuts() { @Disabled("Remove to run test") @Test + @DisplayName("just strawberries") public void listJustStrawberries() { Allergies allergies = new Allergies(8); @@ -381,6 +426,7 @@ public void listJustStrawberries() { @Disabled("Remove to run test") @Test + @DisplayName("eggs and peanuts") public void listEggsAndPeanuts() { Allergies allergies = new Allergies(3); @@ -392,6 +438,7 @@ public void listEggsAndPeanuts() { @Disabled("Remove to run test") @Test + @DisplayName("more than eggs but not peanuts") public void listoMoreThanEggsButNotPeanuts() { Allergies allergies = new Allergies(5); @@ -403,6 +450,7 @@ public void listoMoreThanEggsButNotPeanuts() { @Disabled("Remove to run test") @Test + @DisplayName("lots of stuff") public void listManyAllergies() { Allergies allergies = new Allergies(248); @@ -417,6 +465,7 @@ public void listManyAllergies() { @Disabled("Remove to run test") @Test + @DisplayName("everything") public void listEverything() { Allergies allergies = new Allergies(255); @@ -434,6 +483,7 @@ public void listEverything() { @Disabled("Remove to run test") @Test + @DisplayName("no allergen score parts") public void listNoAllergenScoreParts() { Allergies allergies = new Allergies(509); @@ -450,6 +500,7 @@ public void listNoAllergenScoreParts() { @Disabled("Remove to run test") @Test + @DisplayName("no allergen score parts without highest valid score") public void listNoAllergenScorePartsWithoutHighestValidScore() { Allergies allergies = new Allergies(257); diff --git a/exercises/practice/alphametics/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/alphametics/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/alphametics/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/alphametics/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/alphametics/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/alphametics/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/alphametics/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/alphametics/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/alphametics/gradlew b/exercises/practice/alphametics/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/alphametics/gradlew +++ b/exercises/practice/alphametics/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/alphametics/gradlew.bat b/exercises/practice/alphametics/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/alphametics/gradlew.bat +++ b/exercises/practice/alphametics/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/alphametics/src/test/java/AlphameticsTest.java b/exercises/practice/alphametics/src/test/java/AlphameticsTest.java index 93aef51be..8661a8de3 100644 --- a/exercises/practice/alphametics/src/test/java/AlphameticsTest.java +++ b/exercises/practice/alphametics/src/test/java/AlphameticsTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static java.util.Map.entry; @@ -8,6 +9,7 @@ public class AlphameticsTest { @Test + @DisplayName("puzzle with three letters") public void testThreeLetters() throws UnsolvablePuzzleException { assertThat(new Alphametics("I + BB == ILL").solve()) .containsOnly( @@ -18,6 +20,7 @@ public void testThreeLetters() throws UnsolvablePuzzleException { @Disabled("Remove to run test") @Test + @DisplayName("solution must have unique value for each letter") public void testUniqueValue() { Alphametics alphametics = new Alphametics("A == B"); @@ -27,6 +30,7 @@ public void testUniqueValue() { @Disabled("Remove to run test") @Test + @DisplayName("leading zero solution is invalid") public void testLeadingZero() { Alphametics alphametics = new Alphametics("ACA + DD == BD"); @@ -36,6 +40,7 @@ public void testLeadingZero() { @Disabled("Remove to run test") @Test + @DisplayName("puzzle with two digits final carry") public void testTwoDigitsFinalCarry() throws UnsolvablePuzzleException { assertThat(new Alphametics("A + A + A + A + A + A + A + A + A + A + A + B == BCC").solve()) .containsOnly( @@ -46,6 +51,7 @@ public void testTwoDigitsFinalCarry() throws UnsolvablePuzzleException { @Disabled("Remove to run test") @Test + @DisplayName("puzzle with four letters") public void testFourLetters() throws UnsolvablePuzzleException { assertThat(new Alphametics("AS + A == MOM").solve()) .containsOnly( @@ -57,6 +63,7 @@ public void testFourLetters() throws UnsolvablePuzzleException { @Disabled("Remove to run test") @Test + @DisplayName("puzzle with six letters") public void testSixLetters() throws UnsolvablePuzzleException { assertThat(new Alphametics("NO + NO + TOO == LATE").solve()) .containsOnly( @@ -70,6 +77,7 @@ public void testSixLetters() throws UnsolvablePuzzleException { @Disabled("Remove to run test") @Test + @DisplayName("puzzle with seven letters") public void testSevenLetters() throws UnsolvablePuzzleException { assertThat(new Alphametics("HE + SEES + THE == LIGHT").solve()) .containsOnly( @@ -84,6 +92,7 @@ public void testSevenLetters() throws UnsolvablePuzzleException { @Disabled("Remove to run test") @Test + @DisplayName("puzzle with eight letters") public void testEightLetters() throws UnsolvablePuzzleException { assertThat(new Alphametics("SEND + MORE == MONEY").solve()) .containsOnly( @@ -99,6 +108,7 @@ public void testEightLetters() throws UnsolvablePuzzleException { @Disabled("Remove to run test") @Test + @DisplayName("puzzle with ten letters") public void testTenLetters() throws UnsolvablePuzzleException { assertThat(new Alphametics("AND + A + STRONG + OFFENSE + AS + A + GOOD == DEFENSE").solve()) .containsOnly( @@ -116,7 +126,8 @@ public void testTenLetters() throws UnsolvablePuzzleException { @Disabled("Remove to run test") @Test - public void testTenLetters41Addends() throws UnsolvablePuzzleException { + @DisplayName("puzzle with ten letters and 199 addends") + public void testTenLetters199Addends() throws UnsolvablePuzzleException { assertThat(new Alphametics("THIS + A + FIRE + THEREFORE + FOR + ALL + HISTORIES + I + TELL + A + " + "TALE + THAT + FALSIFIES + ITS + TITLE + TIS + A + LIE + THE + TALE + OF + THE + LAST + FIRE + " + "HORSES + LATE + AFTER + THE + FIRST + FATHERS + FORESEE + THE + HORRORS + THE + LAST + FREE + " + diff --git a/exercises/practice/anagram/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/anagram/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/anagram/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/anagram/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/anagram/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/anagram/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/anagram/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/anagram/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/anagram/gradlew b/exercises/practice/anagram/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/anagram/gradlew +++ b/exercises/practice/anagram/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/anagram/gradlew.bat b/exercises/practice/anagram/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/anagram/gradlew.bat +++ b/exercises/practice/anagram/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/anagram/src/test/java/AnagramTest.java b/exercises/practice/anagram/src/test/java/AnagramTest.java index e5434291a..79a3a261b 100644 --- a/exercises/practice/anagram/src/test/java/AnagramTest.java +++ b/exercises/practice/anagram/src/test/java/AnagramTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.Arrays; @@ -9,6 +10,7 @@ public class AnagramTest { @Test + @DisplayName("no matches") public void testNoMatches() { Anagram detector = new Anagram("diaper"); @@ -20,6 +22,7 @@ public void testNoMatches() { @Disabled("Remove to run test") @Test + @DisplayName("detects two anagrams") public void testDetectsTwoAnagrams() { Anagram detector = new Anagram("solemn"); @@ -29,6 +32,7 @@ public void testDetectsTwoAnagrams() { @Disabled("Remove to run test") @Test + @DisplayName("does not detect anagram subsets") public void testEliminateAnagramSubsets() { Anagram detector = new Anagram("good"); @@ -37,6 +41,7 @@ public void testEliminateAnagramSubsets() { @Disabled("Remove to run test") @Test + @DisplayName("detects anagram") public void testDetectLongerAnagram() { Anagram detector = new Anagram("listen"); @@ -48,6 +53,7 @@ public void testDetectLongerAnagram() { @Disabled("Remove to run test") @Test + @DisplayName("detects three anagrams") public void testDetectMultipleAnagramsForLongerWord() { Anagram detector = new Anagram("allergy"); assertThat( @@ -64,6 +70,7 @@ public void testDetectMultipleAnagramsForLongerWord() { @Disabled("Remove to run test") @Test + @DisplayName("detects multiple anagrams with different case") public void testDetectsMultipleAnagramsWithDifferentCase() { Anagram detector = new Anagram("nose"); @@ -73,6 +80,7 @@ public void testDetectsMultipleAnagramsWithDifferentCase() { @Disabled("Remove to run test") @Test + @DisplayName("does not detect non-anagrams with identical checksum") public void testEliminateAnagramsWithSameChecksum() { Anagram detector = new Anagram("mass"); @@ -82,6 +90,7 @@ public void testEliminateAnagramsWithSameChecksum() { @Disabled("Remove to run test") @Test + @DisplayName("detects anagrams case-insensitively") public void testCaseInsensitiveWhenBothAnagramAndSubjectStartWithUpperCaseLetter() { Anagram detector = new Anagram("Orchestra"); @@ -93,6 +102,7 @@ public void testCaseInsensitiveWhenBothAnagramAndSubjectStartWithUpperCaseLetter @Disabled("Remove to run test") @Test + @DisplayName("detects anagrams using case-insensitive subject") public void testCaseInsensitiveWhenSubjectStartsWithUpperCaseLetter() { Anagram detector = new Anagram("Orchestra"); @@ -104,6 +114,7 @@ public void testCaseInsensitiveWhenSubjectStartsWithUpperCaseLetter() { @Disabled("Remove to run test") @Test + @DisplayName("detects anagrams using case-insensitive possible matches") public void testCaseInsensitiveWhenAnagramStartsWithUpperCaseLetter() { Anagram detector = new Anagram("orchestra"); @@ -115,6 +126,7 @@ public void testCaseInsensitiveWhenAnagramStartsWithUpperCaseLetter() { @Disabled("Remove to run test") @Test + @DisplayName("does not detect an anagram if the original word is repeated") public void testIdenticalWordRepeatedIsNotAnagram() { Anagram detector = new Anagram("go"); @@ -124,6 +136,7 @@ public void testIdenticalWordRepeatedIsNotAnagram() { @Disabled("Remove to run test") @Test + @DisplayName("anagrams must use all letters exactly once") public void testAnagramMustUseAllLettersExactlyOnce() { Anagram detector = new Anagram("tapper"); @@ -133,6 +146,7 @@ public void testAnagramMustUseAllLettersExactlyOnce() { @Disabled("Remove to run test") @Test + @DisplayName("words are not anagrams of themselves") public void testWordsAreNotAnagramsOfThemselvesCaseInsensitive() { Anagram detector = new Anagram("BANANA"); @@ -142,6 +156,7 @@ public void testWordsAreNotAnagramsOfThemselvesCaseInsensitive() { @Disabled("Remove to run test") @Test + @DisplayName("words are not anagrams of themselves even if letter case is partially different") public void testWordsAreNotAnagramsOfThemselvesEvenIfLetterCaseIsPartiallyDifferent() { Anagram detector = new Anagram("BANANA"); @@ -151,6 +166,7 @@ public void testWordsAreNotAnagramsOfThemselvesEvenIfLetterCaseIsPartiallyDiffer @Disabled("Remove to run test") @Test + @DisplayName("words are not anagrams of themselves even if letter case is completely different") public void testWordsAreNotAnagramsOfThemselvesEvenIfLetterCaseIsCompletelyDifferent() { Anagram detector = new Anagram("BANANA"); @@ -160,6 +176,7 @@ public void testWordsAreNotAnagramsOfThemselvesEvenIfLetterCaseIsCompletelyDiffe @Disabled("Remove to run test") @Test + @DisplayName("words other than themselves can be anagrams") public void testWordsOtherThanThemselvesCanBeAnagrams() { Anagram detector = new Anagram("LISTEN"); @@ -169,6 +186,7 @@ public void testWordsOtherThanThemselvesCanBeAnagrams() { @Disabled("Remove to run test") @Test + @DisplayName("handles case of greek letters") public void testHandlesCaseOfGreekLetters() { Anagram detector = new Anagram("ΑΒΓ"); @@ -178,6 +196,7 @@ public void testHandlesCaseOfGreekLetters() { @Disabled("Remove to run test") @Test + @DisplayName("different characters may have the same bytes") public void testDifferentCharactersWithSameBytes() { Anagram detector = new Anagram("a⬂"); diff --git a/exercises/practice/armstrong-numbers/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/armstrong-numbers/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/armstrong-numbers/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/armstrong-numbers/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/armstrong-numbers/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/armstrong-numbers/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/armstrong-numbers/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/armstrong-numbers/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/armstrong-numbers/gradlew b/exercises/practice/armstrong-numbers/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/armstrong-numbers/gradlew +++ b/exercises/practice/armstrong-numbers/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/armstrong-numbers/gradlew.bat b/exercises/practice/armstrong-numbers/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/armstrong-numbers/gradlew.bat +++ b/exercises/practice/armstrong-numbers/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/armstrong-numbers/src/test/java/ArmstrongNumbersTest.java b/exercises/practice/armstrong-numbers/src/test/java/ArmstrongNumbersTest.java index ea08d7259..8977970dc 100644 --- a/exercises/practice/armstrong-numbers/src/test/java/ArmstrongNumbersTest.java +++ b/exercises/practice/armstrong-numbers/src/test/java/ArmstrongNumbersTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -14,6 +15,7 @@ public void setup() { } @Test + @DisplayName("Zero is an Armstrong number") public void zeroIsArmstrongNumber() { assertThat(armstrongNumbers.isArmstrongNumber(0)) .isTrue(); @@ -21,6 +23,7 @@ public void zeroIsArmstrongNumber() { @Disabled("Remove to run test") @Test + @DisplayName("Single-digit numbers are Armstrong numbers") public void singleDigitsAreArmstrongNumbers() { assertThat(armstrongNumbers.isArmstrongNumber(5)) .isTrue(); @@ -28,6 +31,7 @@ public void singleDigitsAreArmstrongNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("There are no two-digit Armstrong numbers") public void noTwoDigitArmstrongNumbers() { assertThat(armstrongNumbers.isArmstrongNumber(10)) .isFalse(); @@ -35,6 +39,7 @@ public void noTwoDigitArmstrongNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("Three-digit number that is an Armstrong number") public void threeDigitNumberIsArmstrongNumber() { assertThat(armstrongNumbers.isArmstrongNumber(153)) .isTrue(); @@ -42,6 +47,7 @@ public void threeDigitNumberIsArmstrongNumber() { @Disabled("Remove to run test") @Test + @DisplayName("Three-digit number that is not an Armstrong number") public void threeDigitNumberIsNotArmstrongNumber() { assertThat(armstrongNumbers.isArmstrongNumber(100)) .isFalse(); @@ -49,6 +55,7 @@ public void threeDigitNumberIsNotArmstrongNumber() { @Disabled("Remove to run test") @Test + @DisplayName("Four-digit number that is an Armstrong number") public void fourDigitNumberIsArmstrongNumber() { assertThat(armstrongNumbers.isArmstrongNumber(9474)) .isTrue(); @@ -56,6 +63,7 @@ public void fourDigitNumberIsArmstrongNumber() { @Disabled("Remove to run test") @Test + @DisplayName("Four-digit number that is not an Armstrong number") public void fourDigitNumberIsNotArmstrongNumber() { assertThat(armstrongNumbers.isArmstrongNumber(9475)) .isFalse(); @@ -63,6 +71,7 @@ public void fourDigitNumberIsNotArmstrongNumber() { @Disabled("Remove to run test") @Test + @DisplayName("Seven-digit number that is an Armstrong number") public void sevenDigitNumberIsArmstrongNumber() { assertThat(armstrongNumbers.isArmstrongNumber(9926315)) .isTrue(); @@ -70,6 +79,7 @@ public void sevenDigitNumberIsArmstrongNumber() { @Disabled("Remove to run test") @Test + @DisplayName("Seven-digit number that is not an Armstrong number") public void sevenDigitNumberIsNotArmstrongNumber() { assertThat(armstrongNumbers.isArmstrongNumber(9926314)) .isFalse(); diff --git a/exercises/practice/atbash-cipher/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/atbash-cipher/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/atbash-cipher/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/atbash-cipher/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/atbash-cipher/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/atbash-cipher/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/atbash-cipher/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/atbash-cipher/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/atbash-cipher/gradlew b/exercises/practice/atbash-cipher/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/atbash-cipher/gradlew +++ b/exercises/practice/atbash-cipher/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/atbash-cipher/gradlew.bat b/exercises/practice/atbash-cipher/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/atbash-cipher/gradlew.bat +++ b/exercises/practice/atbash-cipher/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/atbash-cipher/src/test/java/AtbashTest.java b/exercises/practice/atbash-cipher/src/test/java/AtbashTest.java index f656a69dc..c914f8b28 100644 --- a/exercises/practice/atbash-cipher/src/test/java/AtbashTest.java +++ b/exercises/practice/atbash-cipher/src/test/java/AtbashTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -14,36 +15,42 @@ public void setup() { } @Test + @DisplayName("encode yes") public void testEncodeYes() { assertThat(atbash.encode("yes")).isEqualTo("bvh"); } @Disabled("Remove to run test") @Test + @DisplayName("encode no") public void testEncodeNo() { assertThat(atbash.encode("no")).isEqualTo("ml"); } @Disabled("Remove to run test") @Test + @DisplayName("encode OMG") public void testEncodeOmgInCapital() { assertThat(atbash.encode("OMG")).isEqualTo("lnt"); } @Disabled("Remove to run test") @Test + @DisplayName("encode spaces") public void testEncodeOmgWithSpaces() { assertThat(atbash.encode("O M G")).isEqualTo("lnt"); } @Disabled("Remove to run test") @Test + @DisplayName("encode mindblowingly") public void testEncodeMindBlowingly() { assertThat(atbash.encode("mindblowingly")).isEqualTo("nrmwy oldrm tob"); } @Disabled("Remove to run test") @Test + @DisplayName("encode numbers") public void testEncodeNumbers() { assertThat(atbash.encode("Testing,1 2 3, testing.")) .isEqualTo("gvhgr mt123 gvhgr mt"); @@ -51,6 +58,7 @@ public void testEncodeNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("encode deep thought") public void testEncodeDeepThought() { assertThat(atbash.encode("Truth is fiction.")) .isEqualTo("gifgs rhurx grlm"); @@ -58,6 +66,7 @@ public void testEncodeDeepThought() { @Disabled("Remove to run test") @Test + @DisplayName("encode all the letters") public void testEncodeAllTheLetters() { assertThat(atbash.encode("The quick brown fox jumps over the lazy dog.")) .isEqualTo("gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt"); @@ -65,12 +74,14 @@ public void testEncodeAllTheLetters() { @Disabled("Remove to run test") @Test + @DisplayName("decode exercism") public void testDecodeExercism() { assertThat(atbash.decode("vcvix rhn")).isEqualTo("exercism"); } @Disabled("Remove to run test") @Test + @DisplayName("decode a sentence") public void testDecodeASentence() { assertThat(atbash.decode("zmlyh gzxov rhlug vmzhg vkkrm thglm v")) .isEqualTo("anobstacleisoftenasteppingstone"); @@ -78,6 +89,7 @@ public void testDecodeASentence() { @Disabled("Remove to run test") @Test + @DisplayName("decode numbers") public void testDecodeNumbers() { assertThat(atbash.decode("gvhgr mt123 gvhgr mt")) .isEqualTo("testing123testing"); @@ -85,6 +97,7 @@ public void testDecodeNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("decode all the letters") public void testDecodeAllTheLetters() { assertThat(atbash.decode("gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt")) .isEqualTo("thequickbrownfoxjumpsoverthelazydog"); @@ -92,12 +105,14 @@ public void testDecodeAllTheLetters() { @Disabled("Remove to run test") @Test + @DisplayName("decode with too many spaces") public void testDecodeWithTooManySpaces() { assertThat(atbash.decode("vc vix r hn")).isEqualTo("exercism"); } @Disabled("Remove to run test") @Test + @DisplayName("decode with no spaces") public void testDecodeWithNoSpaces() { assertThat(atbash.decode("zmlyhgzxovrhlugvmzhgvkkrmthglmv")) .isEqualTo("anobstacleisoftenasteppingstone"); diff --git a/exercises/practice/baffling-birthdays/.docs/instructions.md b/exercises/practice/baffling-birthdays/.docs/instructions.md new file mode 100644 index 000000000..a01ec8679 --- /dev/null +++ b/exercises/practice/baffling-birthdays/.docs/instructions.md @@ -0,0 +1,23 @@ +# Instructions + +Your task is to estimate the birthday paradox's probabilities. + +To do this, you need to: + +- Generate random birthdates. +- Check if a collection of randomly generated birthdates contains at least two with the same birthday. +- Estimate the probability that at least two people in a group share the same birthday for different group sizes. + +~~~~exercism/note +A birthdate includes the full date of birth (year, month, and day), whereas a birthday refers only to the month and day, which repeat each year. +Two birthdates with the same month and day correspond to the same birthday. +~~~~ + +~~~~exercism/caution +The birthday paradox assumes that: + +- There are 365 possible birthdays (no leap years). +- Each birthday is equally likely (uniform distribution). + +Your implementation must follow these assumptions. +~~~~ diff --git a/exercises/practice/baffling-birthdays/.docs/introduction.md b/exercises/practice/baffling-birthdays/.docs/introduction.md new file mode 100644 index 000000000..97dabd1e6 --- /dev/null +++ b/exercises/practice/baffling-birthdays/.docs/introduction.md @@ -0,0 +1,25 @@ +# Introduction + +Fresh out of college, you're throwing a huge party to celebrate with friends and family. +Over 70 people have shown up, including your mildly eccentric Uncle Ted. + +In one of his usual antics, he bets you £100 that at least two people in the room share the same birthday. +That sounds ridiculous — there are many more possible birthdays than there are guests, so you confidently accept. + +To your astonishment, after collecting the birthdays of just 32 guests, you've already found two guests that share the same birthday. +Accepting your loss, you hand Uncle Ted his £100, but something feels off. + +The next day, curiosity gets the better of you. +A quick web search leads you to the [birthday paradox][birthday-problem], which reveals that with just 23 people, the probability of a shared birthday exceeds 50%. + +Ah. So _that's_ why Uncle Ted was so confident. + +Determined to turn the tables, you start looking up other paradoxes; next time, _you'll_ be the one making the bets. + +~~~~exercism/note +The birthday paradox is a [veridical paradox][veridical-paradox]: even though it feels wrong, it is actually true. + +[veridical-paradox]: https://en.wikipedia.org/wiki/Paradox#Quine's_classification +~~~~ + +[birthday-problem]: https://en.wikipedia.org/wiki/Birthday_problem diff --git a/exercises/practice/baffling-birthdays/.meta/config.json b/exercises/practice/baffling-birthdays/.meta/config.json new file mode 100644 index 000000000..6e401cb62 --- /dev/null +++ b/exercises/practice/baffling-birthdays/.meta/config.json @@ -0,0 +1,22 @@ +{ + "authors": [ + "Baboushka" + ], + "files": { + "solution": [ + "src/main/java/BafflingBirthdays.java" + ], + "test": [ + "src/test/java/BafflingBirthdaysTest.java" + ], + "example": [ + ".meta/src/reference/java/BafflingBirthdays.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Estimate the birthday paradox's probabilities.", + "source": "Erik Schierboom", + "source_url": "https://github.com/exercism/problem-specifications/pull/2539" +} diff --git a/exercises/practice/baffling-birthdays/.meta/src/reference/java/BafflingBirthdays.java b/exercises/practice/baffling-birthdays/.meta/src/reference/java/BafflingBirthdays.java new file mode 100644 index 000000000..ef58bc2c0 --- /dev/null +++ b/exercises/practice/baffling-birthdays/.meta/src/reference/java/BafflingBirthdays.java @@ -0,0 +1,48 @@ +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.concurrent.ThreadLocalRandom; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +class BafflingBirthdays { + private static final int nonLeapYear = 2001; + private static final int daysInYear = 365; + + boolean sharedBirthday(List birthdates) { + Set seen = new HashSet<>(); + for (LocalDate birthdate : birthdates) { + if (!seen.add(birthdate.getMonth().toString() + birthdate.getDayOfMonth())) { + return true; + } + } + return false; + } + + List randomBirthdates(int groupSize) { + if (groupSize <= 0) { + return List.of(); + } + List birthdates = new ArrayList<>(groupSize); + ThreadLocalRandom random = ThreadLocalRandom.current(); + for (int i = 0; i < groupSize; i++) { + int dayOfYear = random.nextInt(1, daysInYear + 1); + birthdates.add(LocalDate.ofYearDay(nonLeapYear, dayOfYear)); + } + return birthdates; + } + + double estimatedProbabilityOfSharedBirthday(int groupSize) { + if (groupSize <= 1) { + return 0.0; + } + if (groupSize > daysInYear) { + return 100.0; + } + double probabilityNoSharedBirthday = 1.0; + for (int k = 0; k < groupSize; k++) { + probabilityNoSharedBirthday *= (daysInYear - k) / (double) daysInYear; + } + return (1 - probabilityNoSharedBirthday) * 100.0; + } +} diff --git a/exercises/practice/baffling-birthdays/.meta/tests.toml b/exercises/practice/baffling-birthdays/.meta/tests.toml new file mode 100644 index 000000000..c76afb466 --- /dev/null +++ b/exercises/practice/baffling-birthdays/.meta/tests.toml @@ -0,0 +1,61 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[716dcc2b-8fe4-4fc9-8c48-cbe70d8e6b67] +description = "shared birthday -> one birthdate" + +[f7b3eb26-bcfc-4c1e-a2de-af07afc33f45] +description = "shared birthday -> two birthdates with same year, month, and day" + +[7193409a-6e16-4bcb-b4cc-9ffe55f79b25] +description = "shared birthday -> two birthdates with same year and month, but different day" + +[d04db648-121b-4b72-93e8-d7d2dced4495] +description = "shared birthday -> two birthdates with same month and day, but different year" + +[3c8bd0f0-14c6-4d4c-975a-4c636bfdc233] +description = "shared birthday -> two birthdates with same year, but different month and day" + +[df5daba6-0879-4480-883c-e855c99cdaa3] +description = "shared birthday -> two birthdates with different year, month, and day" + +[0c17b220-cbb9-4bd7-872f-373044c7b406] +description = "shared birthday -> multiple birthdates without shared birthday" + +[966d6b0b-5c0a-4b8c-bc2d-64939ada49f8] +description = "shared birthday -> multiple birthdates with one shared birthday" + +[b7937d28-403b-4500-acce-4d9fe3a9620d] +description = "shared birthday -> multiple birthdates with more than one shared birthday" + +[70b38cea-d234-4697-b146-7d130cd4ee12] +description = "random birthdates -> generate requested number of birthdates" + +[d9d5b7d3-5fea-4752-b9c1-3fcd176d1b03] +description = "random birthdates -> years are not leap years" + +[d1074327-f68c-4c8a-b0ff-e3730d0f0521] +description = "random birthdates -> months are random" + +[7df706b3-c3f5-471d-9563-23a4d0577940] +description = "random birthdates -> days are random" + +[89a462a4-4265-4912-9506-fb027913f221] +description = "estimated probability of at least one shared birthday -> for one person" + +[ec31c787-0ebb-4548-970c-5dcb4eadfb5f] +description = "estimated probability of at least one shared birthday -> among ten people" + +[b548afac-a451-46a3-9bb0-cb1f60c48e2f] +description = "estimated probability of at least one shared birthday -> among twenty-three people" + +[e43e6b9d-d77b-4f6c-a960-0fc0129a0bc5] +description = "estimated probability of at least one shared birthday -> among seventy people" diff --git a/exercises/practice/baffling-birthdays/build.gradle b/exercises/practice/baffling-birthdays/build.gradle new file mode 100644 index 000000000..d28f35dee --- /dev/null +++ b/exercises/practice/baffling-birthdays/build.gradle @@ -0,0 +1,25 @@ +plugins { + id "java" +} + +repositories { + mavenCentral() +} + +dependencies { + testImplementation platform("org.junit:junit-bom:5.10.0") + testImplementation "org.junit.jupiter:junit-jupiter" + testImplementation "org.assertj:assertj-core:3.25.1" + + testRuntimeOnly "org.junit.platform:junit-platform-launcher" +} + +test { + useJUnitPlatform() + + testLogging { + exceptionFormat = "full" + showStandardStreams = true + events = ["passed", "failed", "skipped"] + } +} diff --git a/exercises/practice/baffling-birthdays/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/baffling-birthdays/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..f8e1ee312 Binary files /dev/null and b/exercises/practice/baffling-birthdays/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/baffling-birthdays/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/baffling-birthdays/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..4d97ea344 --- /dev/null +++ b/exercises/practice/baffling-birthdays/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/exercises/practice/baffling-birthdays/gradlew b/exercises/practice/baffling-birthdays/gradlew new file mode 100644 index 000000000..adff685a0 --- /dev/null +++ b/exercises/practice/baffling-birthdays/gradlew @@ -0,0 +1,248 @@ +#!/bin/sh + +# +# Copyright © 2015 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/exercises/practice/baffling-birthdays/gradlew.bat b/exercises/practice/baffling-birthdays/gradlew.bat new file mode 100644 index 000000000..c4bdd3ab8 --- /dev/null +++ b/exercises/practice/baffling-birthdays/gradlew.bat @@ -0,0 +1,93 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/exercises/practice/baffling-birthdays/src/main/java/BafflingBirthdays.java b/exercises/practice/baffling-birthdays/src/main/java/BafflingBirthdays.java new file mode 100644 index 000000000..5e1925081 --- /dev/null +++ b/exercises/practice/baffling-birthdays/src/main/java/BafflingBirthdays.java @@ -0,0 +1,16 @@ +import java.time.LocalDate; +import java.util.List; + +class BafflingBirthdays { + boolean sharedBirthday(List birthdates) { + throw new UnsupportedOperationException("Delete this statement and write your own implementation."); + } + + List randomBirthdates(int groupSize) { + throw new UnsupportedOperationException("Delete this statement and write your own implementation."); + } + + double estimatedProbabilityOfSharedBirthday(int groupSize) { + throw new UnsupportedOperationException("Delete this statement and write your own implementation."); + } +} \ No newline at end of file diff --git a/exercises/practice/baffling-birthdays/src/test/java/BafflingBirthdaysTest.java b/exercises/practice/baffling-birthdays/src/test/java/BafflingBirthdaysTest.java new file mode 100644 index 000000000..0726301dc --- /dev/null +++ b/exercises/practice/baffling-birthdays/src/test/java/BafflingBirthdaysTest.java @@ -0,0 +1,176 @@ +import java.time.LocalDate; +import java.util.List; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static java.time.Month.APRIL; +import static java.time.Month.AUGUST; +import static java.time.Month.DECEMBER; +import static java.time.Month.FEBRUARY; +import static java.time.Month.JANUARY; +import static java.time.Month.JULY; +import static java.time.Month.MAY; +import static java.time.Month.NOVEMBER; +import static java.time.Month.OCTOBER; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.data.Offset.offset; + +public class BafflingBirthdaysTest { + private BafflingBirthdays birthdays = new BafflingBirthdays(); + + @Test + @DisplayName("one birthdate") + public void oneBirthdateTest() { + assertThat(birthdays.sharedBirthday(List.of( + LocalDate.of(2000, JANUARY, 1) + ))).isFalse(); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("two birthdates with same year, month, and day") + public void twoBirthdatesWithSameYearMonthAndDayTest() { + assertThat(birthdays.sharedBirthday(List.of( + LocalDate.of(2000, JANUARY, 1), + LocalDate.of(2000, JANUARY, 1) + ))).isTrue(); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("two birthdates with same year and month, but different day") + public void twoBirthdatesWithSameYearAndMonthButDifferentDayTest() { + assertThat(birthdays.sharedBirthday(List.of( + LocalDate.of(2012, MAY, 9), + LocalDate.of(2012, MAY, 17) + ))).isFalse(); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("two birthdates with same month and day, but different year") + public void twoBirthdatesWithSameMonthAndDayButDifferentYearTest() { + assertThat(birthdays.sharedBirthday(List.of( + LocalDate.of(1999, OCTOBER, 23), + LocalDate.of(1988, OCTOBER, 23) + ))).isTrue(); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("two birthdates with same year, but different month and day") + public void twoBirthdatesWithSameYearButDifferentMonthAndDayTest() { + assertThat(birthdays.sharedBirthday(List.of( + LocalDate.of(2007, DECEMBER, 19), + LocalDate.of(2007, APRIL, 27) + ))).isFalse(); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("two birthdates with different year, month, and day") + public void twoBirthdatesWithDifferentYearMonthAndDayTest() { + assertThat(birthdays.sharedBirthday(List.of( + LocalDate.of(1997, AUGUST, 4), + LocalDate.of(1963, NOVEMBER, 23) + ))).isFalse(); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("multiple birthdates without shared birthday") + public void multipleBirthdatesWithoutSharedBirthdayTest() { + assertThat(birthdays.sharedBirthday(List.of( + LocalDate.of(1966, AUGUST, 29), + LocalDate.of(1977, FEBRUARY, 12), + LocalDate.of(2001, DECEMBER, 25), + LocalDate.of(1980, NOVEMBER, 10) + ))).isFalse(); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("multiple birthdates with one shared birthday") + public void multipleBirthdatesWithOneSharedBirthdayTest() { + assertThat(birthdays.sharedBirthday(List.of( + LocalDate.of(1966, AUGUST, 29), + LocalDate.of(1977, FEBRUARY, 12), + LocalDate.of(2001, AUGUST, 29), + LocalDate.of(1980, NOVEMBER, 10) + ))).isTrue(); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("multiple birthdates with more than one shared birthday") + public void multipleBirthdatesWithMoreThanOneSharedBirthdayTest() { + assertThat(birthdays.sharedBirthday(List.of( + LocalDate.of(1966, JULY, 29), + LocalDate.of(1977, FEBRUARY, 12), + LocalDate.of(2001, DECEMBER, 25), + LocalDate.of(1980, JULY, 29), + LocalDate.of(2019, FEBRUARY, 12) + ))).isTrue(); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("generate requested number of birthdates") + public void generateRequestedNumberOfBirthdatesTest() { + int groupSize = 50; + assertThat(birthdays.randomBirthdates(groupSize).size()).isEqualTo(groupSize); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("years are not leap years") + public void yearsAreNotLeapYearsTest() { + assertThat(birthdays.randomBirthdates(100)).noneMatch(LocalDate::isLeapYear); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("months are random") + public void monthsAreRandomTest() { + assertThat(birthdays.randomBirthdates(500).stream().map(LocalDate::getMonth).distinct()) + .hasSizeGreaterThanOrEqualTo(7); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("days are random") + public void daysAreRandomTest() { + assertThat(birthdays.randomBirthdates(500).stream().map(LocalDate::getDayOfMonth).distinct()) + .hasSizeGreaterThanOrEqualTo(11); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("estimated probability of at least one shared birthday case for one person") + public void estimatedProbabilityOfAtLeastOneSharedBirthdayForOnePersonTest() { + assertThat(birthdays.estimatedProbabilityOfSharedBirthday(1)).isEqualTo(0.0); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("estimated probability of at least one shared birthday case among ten people") + public void estimatedProbabilityOfAtLeastOneSharedBirthdayAmongTenPeopleTest() { + assertThat(birthdays.estimatedProbabilityOfSharedBirthday(10)).isCloseTo(11.694818, offset(1.0)); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("estimated probability of at least one shared birthday case among twenty-three people") + public void estimatedProbabilityOfAtLeastOneSharedBirthdayAmongTwentyThreePeopleTest() { + assertThat(birthdays.estimatedProbabilityOfSharedBirthday(23)).isCloseTo(50.729723, offset(1.0)); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("estimated probability of at least one shared birthday case among seventy people") + public void estimatedProbabilityOfAtLeastOneSharedBirthdayAmongSeventyPeopleTest() { + assertThat(birthdays.estimatedProbabilityOfSharedBirthday(70)).isCloseTo(99.915958, offset(1.0)); + } +} diff --git a/exercises/practice/bank-account/.approaches/config.json b/exercises/practice/bank-account/.approaches/config.json new file mode 100644 index 000000000..1739dcd4a --- /dev/null +++ b/exercises/practice/bank-account/.approaches/config.json @@ -0,0 +1,45 @@ +{ + "introduction": { + "authors": [ + "kahgoh" + ] + }, + "approaches": [ + { + "uuid": "78d753b0-aa58-43dc-83c0-9ea41496de84", + "slug": "synchronized-methods", + "title": "Synchronized methods", + "blurb": "Use synchronized methods to prevent methods from running simultaneously in different threads", + "authors": [ + "kahgoh" + ] + }, + { + "uuid": "5f3b0152-02eb-40d5-9104-5edc30b4447e", + "slug": "synchronized-statements", + "title": "Synchronized statements", + "blurb": "Use an object to prevent threads from running blocks of code at the same time", + "authors": [ + "kahgoh" + ] + }, + { + "uuid": "0acd6f2b-27d0-4ae6-9c22-22b0b2047039", + "slug": "reentrant-lock", + "title": "Reentrant lock", + "blurb": "Use an ReentrantLock to explicitly acquire and release locks", + "authors": [ + "kahgoh" + ] + }, + { + "uuid": "4ad42f88-f750-4af9-bbbd-d8b2dc5e8078", + "slug": "readwrite-lock", + "title": "Readwrite lock", + "blurb": "Use separate read and write locks to achieve greater concurrency", + "authors": [ + "kahgoh" + ] + } + ] +} diff --git a/exercises/practice/bank-account/.approaches/introduction.md b/exercises/practice/bank-account/.approaches/introduction.md new file mode 100644 index 000000000..ac8d3c506 --- /dev/null +++ b/exercises/practice/bank-account/.approaches/introduction.md @@ -0,0 +1,351 @@ +# Introduction + +In Bank Account, you are tasked with implementing a number of operations that can be performed on a bank account. +However, these operations may be performed by multiple threads at the same time. + +## General guidance + +The key to solving Bank Account is to prevent an account from being updated from multiple threads at the same time. +For example, consider an account that begins with $0. +A $10 deposit is made twice. +Each transaction starts a thread. +If the threads happen to start simultaneously, they might both see the account starting $0. +They each add $10 to this amount and update the account accordingly. +In this case, each thread sets the amount to $10 even though the transaction was made twice. + +The problem here is that both threads saw that there was $0 in the account prior to adding the deposit. +Instead, each thread needs to take turns to process the deposit for the account so that they can process the transaction one at a time. +This way, the later thread can "see" the deposited amount from the first thread. + +## Approach: Synchronized methods + +```java +class BankAccount { + private int balance = 0; + private boolean isClosed = true; + + synchronized void open() throws BankAccountActionInvalidException { + if (!isClosed) { + throw new BankAccountActionInvalidException("Account already open"); + } + isClosed = false; + balance = 0; + } + + synchronized void close() throws BankAccountActionInvalidException { + if (isClosed) { + throw new BankAccountActionInvalidException("Account not open"); + } + isClosed = true; + } + + synchronized int getBalance() throws BankAccountActionInvalidException { + checkIfClosed(); + return balance; + } + + synchronized void deposit(int amount) throws BankAccountActionInvalidException { + checkIfClosed(); + checkIfValidAmount(amount); + + balance += amount; + } + + synchronized void withdraw(int amount) throws BankAccountActionInvalidException { + checkIfClosed(); + checkIfValidAmount(amount); + checkIfEnoughMoneyInAccount(amount); + + balance -= amount; + } + + private void checkIfValidAmount(int amount) throws BankAccountActionInvalidException { + if (amount < 0) { + throw new BankAccountActionInvalidException("Cannot deposit or withdraw negative amount"); + } + } + + private void checkIfEnoughMoneyInAccount(int amount) throws BankAccountActionInvalidException { + if (balance == 0) { + throw new BankAccountActionInvalidException("Cannot withdraw money from an empty account"); + } + if (balance - amount < 0) { + throw new BankAccountActionInvalidException("Cannot withdraw more money than is currently in the account"); + } + } + + private void checkIfClosed() throws BankAccountActionInvalidException { + if (isClosed) { + throw new BankAccountActionInvalidException("Account closed"); + } + } +} +``` + +For more information, check the [Synchronized methods approach][approach-synchronized-methods]. + +## Approach: Synchronized statements + +```java +class BankAccount { + private final Object lock = new Object(); + private int balance = 0; + private boolean isClosed = true; + + void open() throws BankAccountActionInvalidException { + synchronized(lock) { + if (!isClosed) { + throw new BankAccountActionInvalidException("Account already open"); + } + isClosed = false; + balance = 0; + } + } + + void close() throws BankAccountActionInvalidException { + synchronized(lock) { + if (isClosed) { + throw new BankAccountActionInvalidException("Account not open"); + } + isClosed = true; + } + } + + int getBalance() throws BankAccountActionInvalidException { + synchronized(lock) { + checkIfClosed(); + return balance; + } + } + + void deposit(int amount) throws BankAccountActionInvalidException { + synchronized(lock) { + checkIfClosed(); + checkIfValidAmount(amount); + + balance += amount; + } + } + + void withdraw(int amount) throws BankAccountActionInvalidException { + synchronized(lock) { + checkIfClosed(); + checkIfValidAmount(amount); + checkIfEnoughMoneyInAccount(amount); + + balance -= amount; + } + } + + private void checkIfValidAmount(int amount) throws BankAccountActionInvalidException { + if (amount < 0) { + throw new BankAccountActionInvalidException("Cannot deposit or withdraw negative amount"); + } + } + + private void checkIfEnoughMoneyInAccount(int amount) throws BankAccountActionInvalidException { + if (balance == 0) { + throw new BankAccountActionInvalidException("Cannot withdraw money from an empty account"); + } + if (balance - amount < 0) { + throw new BankAccountActionInvalidException("Cannot withdraw more money than is currently in the account"); + } + } + + private void checkIfClosed() throws BankAccountActionInvalidException { + if (isClosed) { + throw new BankAccountActionInvalidException("Account closed"); + } + } +} +``` + +For more information, check the [Synchronized statements approach][approach-synchronized-statements]. + +## Approach: Reentrant lock + +```java +import java.util.concurrent.locks.ReentrantLock; + +class BankAccount { + + private final ReentrantLock lock = new ReentrantLock(); + + private boolean isOpen = false; + private int balance = 0; + + void open() throws BankAccountActionInvalidException { + lock.lock(); + try { + if (isOpen) { + throw new BankAccountActionInvalidException("Account already open"); + } + isOpen = true; + balance = 0; + } finally { + lock.unlock(); + } + } + + void close() throws BankAccountActionInvalidException { + lock.lock(); + try { + if (!isOpen) { + throw new BankAccountActionInvalidException("Account not open"); + } + isOpen = false; + } finally { + lock.unlock(); + } + } + + int getBalance() throws BankAccountActionInvalidException { + lock.lock(); + try { + if (!isOpen) { + throw new BankAccountActionInvalidException("Account closed"); + } + return balance; + } finally { + lock.unlock(); + } + } + + void deposit(int amount) throws BankAccountActionInvalidException { + lock.lock(); + try { + if (!isOpen) { + throw new BankAccountActionInvalidException("Account closed"); + } + if (amount < 0) { + throw new BankAccountActionInvalidException("Cannot deposit or withdraw negative amount"); + } + balance += amount; + } finally { + lock.unlock(); + } + } + + void withdraw(int amount) throws BankAccountActionInvalidException { + lock.lock(); + try { + if (!isOpen) { + throw new BankAccountActionInvalidException("Account closed"); + } + if (amount > balance) { + throw new BankAccountActionInvalidException("Cannot withdraw more money than is currently in the account"); + } + if (amount < 0) { + throw new BankAccountActionInvalidException("Cannot deposit or withdraw negative amount"); + } + balance -= amount; + } finally { + lock.unlock(); + } + } + +} +``` + +For more information, check the [Reentrant lock approach][approach-reentrant-lock]. + +## Approach: Read write lock + +```java +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +class BankAccount { + + private final ReadWriteLock lock = new ReentrantReadWriteLock(); + + private boolean isOpen = false; + + private int balance = 0; + + void open() throws BankAccountActionInvalidException { + lock.writeLock().lock(); + try { + if (isOpen) { + throw new BankAccountActionInvalidException("Account already open"); + } + isOpen = true; + balance = 0; + } finally { + lock.writeLock().unlock(); + } + } + + void close() throws BankAccountActionInvalidException { + lock.writeLock().lock(); + try { + if (!isOpen) { + throw new BankAccountActionInvalidException("Account not open"); + } + isOpen = false; + } finally { + lock.writeLock().unlock(); + } + } + + int getBalance() throws BankAccountActionInvalidException { + lock.readLock().lock(); + try { + if (!isOpen) { + throw new BankAccountActionInvalidException("Account closed"); + } + return balance; + } finally { + lock.readLock().unlock(); + } + } + + void deposit(int amount) throws BankAccountActionInvalidException { + lock.writeLock().lock(); + try { + if (!isOpen) { + throw new BankAccountActionInvalidException("Account closed"); + } + if (amount < 0) { + throw new BankAccountActionInvalidException("Cannot deposit or withdraw negative amount"); + } + balance += amount; + } finally { + lock.writeLock().unlock(); + } + } + + void withdraw(int amount) throws BankAccountActionInvalidException { + lock.writeLock().lock(); + try { + if (!isOpen) { + throw new BankAccountActionInvalidException("Account closed"); + } + if (amount > balance) { + throw new BankAccountActionInvalidException("Cannot withdraw more money than is currently in the account"); + } + if (amount < 0) { + throw new BankAccountActionInvalidException("Cannot deposit or withdraw negative amount"); + } + balance -= amount; + } finally { + lock.writeLock().unlock(); + } + } +} +``` + +For more information, check the [Read write lock approach][approach-read-write-lock]. + +## Which approach to use? + +- The synchronized methods is the simplest, requiring no extra objects to be created. +- Synchronized statements provide greater control over which code statements are performed with a lock and which object is to be used as the lock. +- The read write lock allows greater concurrency by letting multiple read operations, such as `getBalance`, run in parallel. + However, it requires the lock to be explicitly released. + +[approach-read-write-lock]: https://exercism.org/tracks/java/exercises/bank-account/approaches/readwrite-lock +[approach-reentrant-lock]: https://exercism.org/tracks/java/exercises/bank-acconuunt/approaches/reentrant-lock +[approach-synchronized-methods]: https://exercism.org/tracks/java/exercises/bank-account/approaches/synchronized-methods +[approach-synchronized-statements]: https://exercism.org/tracks/java/exercises/bank-account/approaches/synchronzied-statements diff --git a/exercises/practice/bank-account/.approaches/readwrite-lock/content.md b/exercises/practice/bank-account/.approaches/readwrite-lock/content.md new file mode 100644 index 000000000..5db33cc0a --- /dev/null +++ b/exercises/practice/bank-account/.approaches/readwrite-lock/content.md @@ -0,0 +1,108 @@ +# Readwrite Lock + +```java +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +class BankAccount { + + private final ReadWriteLock lock = new ReentrantReadWriteLock(); + + private boolean isOpen = false; + + private int balance = 0; + + void open() throws BankAccountActionInvalidException { + lock.writeLock().lock(); + try { + if (isOpen) { + throw new BankAccountActionInvalidException("Account already open"); + } + isOpen = true; + balance = 0; + } finally { + lock.writeLock().unlock(); + } + } + + void close() throws BankAccountActionInvalidException { + lock.writeLock().lock(); + try { + if (!isOpen) { + throw new BankAccountActionInvalidException("Account not open"); + } + isOpen = false; + } finally { + lock.writeLock().unlock(); + } + } + + int getBalance() throws BankAccountActionInvalidException { + lock.readLock().lock(); + try { + if (!isOpen) { + throw new BankAccountActionInvalidException("Account closed"); + } + return balance; + } finally { + lock.readLock().unlock(); + } + } + + void deposit(int amount) throws BankAccountActionInvalidException { + lock.writeLock().lock(); + try { + if (!isOpen) { + throw new BankAccountActionInvalidException("Account closed"); + } + if (amount < 0) { + throw new BankAccountActionInvalidException("Cannot deposit or withdraw negative amount"); + } + balance += amount; + } finally { + lock.writeLock().unlock(); + } + } + + void withdraw(int amount) throws BankAccountActionInvalidException { + lock.writeLock().lock(); + try { + if (!isOpen) { + throw new BankAccountActionInvalidException("Account closed"); + } + if (amount > balance) { + throw new BankAccountActionInvalidException("Cannot withdraw more money than is currently in the account"); + } + if (amount < 0) { + throw new BankAccountActionInvalidException("Cannot deposit or withdraw negative amount"); + } + balance -= amount; + } finally { + lock.writeLock().unlock(); + } + } +} +``` + +A [ReadWriteLock][docs-readwritelock] provides two types of locks - one for reading, the other for writing. +[ReentrantReadWriteLock][docs-reentrantreadwritelock] is an implementation of a [ReadWriteLock][docs-readwritelock]. + +Read locks are intended for read-only type operations, such as `getBalance`, and are acquired by calling `readLock().lock()` on the [ReadWriteLock][docs-readwritelock]. +Multiple threads are allowed to acquire read locks at the same time because they are expected to only read data. +This means multiple threads can run `getBalance` at the same time. + +Write locks are for write operations, such as `withdraw` and `deposit`. +It is also used in `open` and `close` as they change the state of the `BankAccount` (they "write" to the `isOpen` field). +Write locks are acquired by calling `writeLock().lock()` on the [ReadWriteLock][docs-readwritelock]. + +Only one thread can hold a write lock at a time. +Therefore, `withdraw`, `deposit`, `open` and `close` can not run at the same time. +Additionally, a thread must _also_ wait for _all_ read locks to be released to obtain a write lock. +Similarly, threads must wait for write locks to be released before they are granted a read lock. +This means `getBalance` also can not run at the same time as any of the `withdraw`, `deposit`, `open` and `close` methods. + +The locks are released in the `finally` block to ensure they are released, even when an exception is thrown. + +[docs-readwritelock]: https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/concurrent/locks/ReadWriteLock.html +[docs-reentrantreadwritelock]: https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/concurrent/locks/ReentrantReadWriteLock.html diff --git a/exercises/practice/bank-account/.approaches/readwrite-lock/snippet.txt b/exercises/practice/bank-account/.approaches/readwrite-lock/snippet.txt new file mode 100644 index 000000000..45fcdf98d --- /dev/null +++ b/exercises/practice/bank-account/.approaches/readwrite-lock/snippet.txt @@ -0,0 +1,7 @@ +private final ReadWriteLock lock = new ReentrantReadWriteLock(); +lock.readLock().lock(); +try { + balance += amount; +} finally { + lock.readLock().unlock(); +} \ No newline at end of file diff --git a/exercises/practice/bank-account/.approaches/reentrant-lock/content.md b/exercises/practice/bank-account/.approaches/reentrant-lock/content.md new file mode 100644 index 000000000..efa9f9512 --- /dev/null +++ b/exercises/practice/bank-account/.approaches/reentrant-lock/content.md @@ -0,0 +1,96 @@ +# Reentrant Lock + +```java +import java.util.concurrent.locks.ReentrantLock; + +class BankAccount { + + private final ReentrantLock lock = new ReentrantLock(); + + private boolean isOpen = false; + private int balance = 0; + + void open() throws BankAccountActionInvalidException { + lock.lock(); + try { + if (isOpen) { + throw new BankAccountActionInvalidException("Account already open"); + } + isOpen = true; + balance = 0; + } finally { + lock.unlock(); + } + } + + void close() throws BankAccountActionInvalidException { + lock.lock(); + try { + if (!isOpen) { + throw new BankAccountActionInvalidException("Account not open"); + } + isOpen = false; + } finally { + lock.unlock(); + } + } + + int getBalance() throws BankAccountActionInvalidException { + lock.lock(); + try { + if (!isOpen) { + throw new BankAccountActionInvalidException("Account closed"); + } + return balance; + } finally { + lock.unlock(); + } + } + + void deposit(int amount) throws BankAccountActionInvalidException { + lock.lock(); + try { + if (!isOpen) { + throw new BankAccountActionInvalidException("Account closed"); + } + if (amount < 0) { + throw new BankAccountActionInvalidException("Cannot deposit or withdraw negative amount"); + } + balance += amount; + } finally { + lock.unlock(); + } + } + + void withdraw(int amount) throws BankAccountActionInvalidException { + lock.lock(); + try { + if (!isOpen) { + throw new BankAccountActionInvalidException("Account closed"); + } + if (amount > balance) { + throw new BankAccountActionInvalidException("Cannot withdraw more money than is currently in the account"); + } + if (amount < 0) { + throw new BankAccountActionInvalidException("Cannot deposit or withdraw negative amount"); + } + balance -= amount; + } finally { + lock.unlock(); + } + } + +} +``` + +A [ReentrantLock][docs-reentrantlock] object represents a lock that threads must acquire to perform certain operations. +It is used here by the operation methods to ensure they are not trying to update the bank account at the same time. + +The lock is requested by calling [lock][docs-reentrantlock-lock]. +The lock is released at the end of the operation by calling [unlock][docs-reentrantlock-unlock] in a `finally` block. +This is important to ensure that the lock is released when it is no longer needed, especially if an exception is thrown. +The re-entrant nature of the lock means a thread will be granted a lock again if it already has the lock. + +[docs-reentrantlock]: https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/concurrent/locks/ReentrantLock.html +[docs-reentrantlock-lock]: https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/concurrent/locks/ReentrantLock.html#lock() +[docs-reentrantlock-unlock]: https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/concurrent/locks/ReentrantLock.html#unlock() diff --git a/exercises/practice/bank-account/.approaches/reentrant-lock/snippet.txt b/exercises/practice/bank-account/.approaches/reentrant-lock/snippet.txt new file mode 100644 index 000000000..2014610f8 --- /dev/null +++ b/exercises/practice/bank-account/.approaches/reentrant-lock/snippet.txt @@ -0,0 +1,7 @@ +private final ReentrantLock lock = new ReentrantLock(); +lock.lock(); +try { + balance += amount; +} finally { + lock.unlock(); +} \ No newline at end of file diff --git a/exercises/practice/bank-account/.approaches/synchronized-methods/content.md b/exercises/practice/bank-account/.approaches/synchronized-methods/content.md new file mode 100644 index 000000000..7c1730694 --- /dev/null +++ b/exercises/practice/bank-account/.approaches/synchronized-methods/content.md @@ -0,0 +1,77 @@ +# Synchronized methods + +```java +class BankAccount { + private int balance = 0; + private boolean isClosed = true; + + synchronized void open() throws BankAccountActionInvalidException { + if (!isClosed) { + throw new BankAccountActionInvalidException("Account already open"); + } + isClosed = false; + balance = 0; + } + + synchronized void close() throws BankAccountActionInvalidException { + if (isClosed) { + throw new BankAccountActionInvalidException("Account not open"); + } + isClosed = true; + } + + synchronized int getBalance() throws BankAccountActionInvalidException { + checkIfClosed(); + return balance; + } + + synchronized void deposit(int amount) throws BankAccountActionInvalidException { + checkIfClosed(); + checkIfValidAmount(amount); + + balance += amount; + } + + synchronized void withdraw(int amount) throws BankAccountActionInvalidException { + checkIfClosed(); + checkIfValidAmount(amount); + checkIfEnoughMoneyInAccount(amount); + + balance -= amount; + } + + private void checkIfValidAmount(int amount) throws BankAccountActionInvalidException { + if (amount < 0) { + throw new BankAccountActionInvalidException("Cannot deposit or withdraw negative amount"); + } + } + + private void checkIfEnoughMoneyInAccount(int amount) throws BankAccountActionInvalidException { + if (balance == 0) { + throw new BankAccountActionInvalidException("Cannot withdraw money from an empty account"); + } + if (balance - amount < 0) { + throw new BankAccountActionInvalidException("Cannot withdraw more money than is currently in the account"); + } + } + + private void checkIfClosed() throws BankAccountActionInvalidException { + if (isClosed) { + throw new BankAccountActionInvalidException("Account closed"); + } + } +} +``` + +Each operation method is marked `synchronized`. +This tells the thread to acquire a lock on the `BankAccount` object _before_ executing the method. +If any other thread holds a lock on the `BankAccount` object, it must wait for the other thread to release the lock. + +~~~~exercism/note +In Java, the is one other way to acquire a lock on the `BankAccount` object - [synchronized statements][approach-synchronized-statements]. +Since synchronized methods use a lock on the `BankAccount` object, it will also have to wait for locks on the `BankAccount` that are used by [synchronized statements][approach-synchronized-statements] to be reused. + +[approach-synchronized-statements]: https://exercism.org/tracks/java/exercises/bank-account/approaches/synchronzied-statements +~~~~ + +The lock is automatically released when the method finishes. diff --git a/exercises/practice/bank-account/.approaches/synchronized-methods/snippet.txt b/exercises/practice/bank-account/.approaches/synchronized-methods/snippet.txt new file mode 100644 index 000000000..61ca7d4ec --- /dev/null +++ b/exercises/practice/bank-account/.approaches/synchronized-methods/snippet.txt @@ -0,0 +1,3 @@ +synchronized void deposit(int amount) throws BankAccountActionInvalidException { + balance += amount; +} \ No newline at end of file diff --git a/exercises/practice/bank-account/.approaches/synchronized-statements/content.md b/exercises/practice/bank-account/.approaches/synchronized-statements/content.md new file mode 100644 index 000000000..8d17806b1 --- /dev/null +++ b/exercises/practice/bank-account/.approaches/synchronized-statements/content.md @@ -0,0 +1,123 @@ +# Synchronized statements + +```java +class BankAccount { + private final Object lock = new Object(); + private int balance = 0; + private boolean isClosed = true; + + void open() throws BankAccountActionInvalidException { + synchronized(lock) { + if (!isClosed) { + throw new BankAccountActionInvalidException("Account already open"); + } + isClosed = false; + balance = 0; + } + } + + void close() throws BankAccountActionInvalidException { + synchronized(lock) { + if (isClosed) { + throw new BankAccountActionInvalidException("Account not open"); + } + isClosed = true; + } + } + + int getBalance() throws BankAccountActionInvalidException { + synchronized(lock) { + checkIfClosed(); + return balance; + } + } + + void deposit(int amount) throws BankAccountActionInvalidException { + synchronized(lock) { + checkIfClosed(); + checkIfValidAmount(amount); + + balance += amount; + } + } + + void withdraw(int amount) throws BankAccountActionInvalidException { + synchronized(lock) { + checkIfClosed(); + checkIfValidAmount(amount); + checkIfEnoughMoneyInAccount(amount); + + balance -= amount; + } + } + + private void checkIfValidAmount(int amount) throws BankAccountActionInvalidException { + if (amount < 0) { + throw new BankAccountActionInvalidException("Cannot deposit or withdraw negative amount"); + } + } + + private void checkIfEnoughMoneyInAccount(int amount) throws BankAccountActionInvalidException { + if (balance == 0) { + throw new BankAccountActionInvalidException("Cannot withdraw money from an empty account"); + } + if (balance - amount < 0) { + throw new BankAccountActionInvalidException("Cannot withdraw more money than is currently in the account"); + } + } + + private void checkIfClosed() throws BankAccountActionInvalidException { + if (isClosed) { + throw new BankAccountActionInvalidException("Account closed"); + } + } +} +``` + +In this approach, the operation methods, such as `open`, `close`, `deposit` and `withdraw`, perform their operations in a `synchronized` code block. +A lock is acquired on the synchronized object (`lock`) before the statements inside the block are executed. +If another thread has a lock on the object, it must wait for it to be released. +The lock is released after the block is executed. + +## Using `this` as the synchronized object + +Any object can be used as the lock, including `this`. +For example: + +```java +int getBalance() throws BankAccountActionInvalidException { + synchronized(this) { + checkIfClosed(); + return balance; + } +} +``` + +This is the same as using a [synchronized method][approach-synchronized-methods], which requires a lock on the same `this` object to run the method. +For example: + +```java +synchronized int getBalance() throws BankAccountActionInvalidException { + checkIfClosed(); + return balance; +} +``` + +When using [synchronized methods][approach-synchronized-methods] and `synchronized(this)`, it is important to keep in mind that it may be trying to acquire a lock on the same instance. +For example: + +```java +BankAccount account = new BankAccount(); + +Thread thread1 = new Thread(() -> { + account.withdraw(5); +}); + +Thread thread2 = new Thread(() -> { + synchronized (account) { + // Code in here can not run at same time as account.withdraw in thread1. + } +}); +``` + +[approach-synchronized-methods]: https://exercism.org/tracks/java/exercises/bank-account/approaches/synchronized-methods diff --git a/exercises/practice/bank-account/.approaches/synchronized-statements/snippet.txt b/exercises/practice/bank-account/.approaches/synchronized-statements/snippet.txt new file mode 100644 index 000000000..6b3a368fb --- /dev/null +++ b/exercises/practice/bank-account/.approaches/synchronized-statements/snippet.txt @@ -0,0 +1,7 @@ +private final Object lock = new Object(); + +void deposit(int amount) throws BankAccountActionInvalidException { + synchronized(lock) { + balance += amount; + } +} \ No newline at end of file diff --git a/exercises/practice/bank-account/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/bank-account/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/bank-account/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/bank-account/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/bank-account/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/bank-account/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/bank-account/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/bank-account/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/bank-account/gradlew b/exercises/practice/bank-account/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/bank-account/gradlew +++ b/exercises/practice/bank-account/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/bank-account/gradlew.bat b/exercises/practice/bank-account/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/bank-account/gradlew.bat +++ b/exercises/practice/bank-account/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/bank-account/src/test/java/BankAccountTest.java b/exercises/practice/bank-account/src/test/java/BankAccountTest.java index 35b4e04a0..8c6d65de7 100644 --- a/exercises/practice/bank-account/src/test/java/BankAccountTest.java +++ b/exercises/practice/bank-account/src/test/java/BankAccountTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.Random; @@ -15,6 +16,7 @@ public void setUp() { } @Test + @DisplayName("Newly opened account has zero balance") public void newlyOpenedAccountHasEmptyBalance() throws BankAccountActionInvalidException { bankAccount.open(); @@ -23,6 +25,7 @@ public void newlyOpenedAccountHasEmptyBalance() throws BankAccountActionInvalidE @Disabled("Remove to run test") @Test + @DisplayName("Single deposit") public void singleDeposit() throws BankAccountActionInvalidException { bankAccount.open(); bankAccount.deposit(100); @@ -32,6 +35,7 @@ public void singleDeposit() throws BankAccountActionInvalidException { @Disabled("Remove to run test") @Test + @DisplayName("Multiple deposits") public void multipleDeposits() throws BankAccountActionInvalidException { bankAccount.open(); bankAccount.deposit(100); @@ -42,6 +46,7 @@ public void multipleDeposits() throws BankAccountActionInvalidException { @Disabled("Remove to run test") @Test + @DisplayName("Withdraw once") public void withdrawOnce() throws BankAccountActionInvalidException { bankAccount.open(); bankAccount.deposit(100); @@ -52,6 +57,7 @@ public void withdrawOnce() throws BankAccountActionInvalidException { @Disabled("Remove to run test") @Test + @DisplayName("Withdraw twice") public void withdrawTwice() throws BankAccountActionInvalidException { bankAccount.open(); bankAccount.deposit(100); @@ -63,6 +69,7 @@ public void withdrawTwice() throws BankAccountActionInvalidException { @Disabled("Remove to run test") @Test + @DisplayName("Can do multiple operations sequentially") public void canDoMultipleOperationsSequentially() throws BankAccountActionInvalidException { bankAccount.open(); bankAccount.deposit(100); @@ -76,6 +83,7 @@ public void canDoMultipleOperationsSequentially() throws BankAccountActionInvali @Disabled("Remove to run test") @Test + @DisplayName("Cannot check balance of closed account") public void cannotCheckBalanceOfClosedAccount() throws BankAccountActionInvalidException { bankAccount.open(); bankAccount.close(); @@ -87,6 +95,7 @@ public void cannotCheckBalanceOfClosedAccount() throws BankAccountActionInvalidE @Disabled("Remove to run test") @Test + @DisplayName("Cannot deposit into closed account") public void cannotDepositIntoClosedAccount() throws BankAccountActionInvalidException { bankAccount.open(); bankAccount.close(); @@ -98,6 +107,7 @@ public void cannotDepositIntoClosedAccount() throws BankAccountActionInvalidExce @Disabled("Remove to run test") @Test + @DisplayName("Cannot deposit into unopened account") public void cannotDepositIntoUnopenedAccount() { assertThatExceptionOfType(BankAccountActionInvalidException.class) .isThrownBy(() -> bankAccount.deposit(50)) @@ -106,6 +116,7 @@ public void cannotDepositIntoUnopenedAccount() { @Disabled("Remove to run test") @Test + @DisplayName("Cannot withdraw from closed account") public void cannotWithdrawFromClosedAccount() throws BankAccountActionInvalidException { bankAccount.open(); bankAccount.close(); @@ -117,6 +128,7 @@ public void cannotWithdrawFromClosedAccount() throws BankAccountActionInvalidExc @Disabled("Remove to run test") @Test + @DisplayName("Cannot close an account that was not opened") public void cannotCloseAnAccountThatWasNotOpened() { assertThatExceptionOfType(BankAccountActionInvalidException.class) .isThrownBy(bankAccount::close) @@ -125,6 +137,7 @@ public void cannotCloseAnAccountThatWasNotOpened() { @Disabled("Remove to run test") @Test + @DisplayName("Cannot open an already opened account") public void cannotOpenAnAlreadyOpenedAccount() throws BankAccountActionInvalidException { bankAccount.open(); @@ -135,6 +148,7 @@ public void cannotOpenAnAlreadyOpenedAccount() throws BankAccountActionInvalidEx @Disabled("Remove to run test") @Test + @DisplayName("Reopened account does not retain balance") public void reopenedAccountDoesNotRetainBalance() throws BankAccountActionInvalidException { bankAccount.open(); bankAccount.deposit(50); @@ -146,7 +160,8 @@ public void reopenedAccountDoesNotRetainBalance() throws BankAccountActionInvali @Disabled("Remove to run test") @Test - public void cannotWithdrawMoreThanWasDeposited() throws BankAccountActionInvalidException { + @DisplayName("Cannot withdraw more than deposited") + public void cannotWithdrawMoreThanDeposited() throws BankAccountActionInvalidException { bankAccount.open(); bankAccount.deposit(25); @@ -157,6 +172,7 @@ public void cannotWithdrawMoreThanWasDeposited() throws BankAccountActionInvalid @Disabled("Remove to run test") @Test + @DisplayName("Cannot withdraw negative") public void cannotWithdrawNegativeAmount() throws BankAccountActionInvalidException { bankAccount.open(); bankAccount.deposit(100); @@ -168,6 +184,7 @@ public void cannotWithdrawNegativeAmount() throws BankAccountActionInvalidExcept @Disabled("Remove to run test") @Test + @DisplayName("Cannot deposit negative") public void cannotDepositNegativeAmount() throws BankAccountActionInvalidException { bankAccount.open(); @@ -178,6 +195,7 @@ public void cannotDepositNegativeAmount() throws BankAccountActionInvalidExcepti @Disabled("Remove to run test") @Test + @DisplayName("Can handle concurrent transactions") public void canHandleConcurrentTransactions() throws BankAccountActionInvalidException, InterruptedException { bankAccount.open(); bankAccount.deposit(1000); diff --git a/exercises/practice/binary-search-tree/.docs/instructions.md b/exercises/practice/binary-search-tree/.docs/instructions.md index c9bbba5b9..7625220e9 100644 --- a/exercises/practice/binary-search-tree/.docs/instructions.md +++ b/exercises/practice/binary-search-tree/.docs/instructions.md @@ -19,29 +19,52 @@ All data in the left subtree is less than or equal to the current node's data, a For example, if we had a node containing the data 4, and we added the data 2, our tree would look like this: +![A graph with root node 4 and a single child node 2.](https://assets.exercism.org/images/exercises/binary-search-tree/tree-4-2.svg) + +```text 4 / 2 +``` If we then added 6, it would look like this: +![A graph with root node 4 and two child nodes 2 and 6.](https://assets.exercism.org/images/exercises/binary-search-tree/tree-4-2-6.svg) + +```text 4 / \ 2 6 +``` If we then added 3, it would look like this +![A graph with root node 4, two child nodes 2 and 6, and a grandchild node 3.](https://assets.exercism.org/images/exercises/binary-search-tree/tree-4-2-6-3.svg) + +```text 4 / \ 2 6 \ 3 +``` And if we then added 1, 5, and 7, it would look like this +![A graph with root node 4, two child nodes 2 and 6, and four grandchild nodes 1, 3, 5 and 7.](https://assets.exercism.org/images/exercises/binary-search-tree/tree-4-2-6-1-3-5-7.svg) + +```text 4 / \ / \ 2 6 / \ / \ 1 3 5 7 +``` + +## Credit + +The images were created by [habere-et-dispertire][habere-et-dispertire] using [PGF/TikZ][pgf-tikz] by Till Tantau. + +[habere-et-dispertire]: https://exercism.org/profiles/habere-et-dispertire +[pgf-tikz]: https://en.wikipedia.org/wiki/PGF/TikZ diff --git a/exercises/practice/binary-search-tree/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/binary-search-tree/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/binary-search-tree/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/binary-search-tree/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/binary-search-tree/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/binary-search-tree/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/binary-search-tree/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/binary-search-tree/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/binary-search-tree/gradlew b/exercises/practice/binary-search-tree/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/binary-search-tree/gradlew +++ b/exercises/practice/binary-search-tree/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/binary-search-tree/gradlew.bat b/exercises/practice/binary-search-tree/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/binary-search-tree/gradlew.bat +++ b/exercises/practice/binary-search-tree/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/binary-search-tree/src/test/java/BinarySearchTreeTest.java b/exercises/practice/binary-search-tree/src/test/java/BinarySearchTreeTest.java index 1d16df93c..f6d8f1478 100644 --- a/exercises/practice/binary-search-tree/src/test/java/BinarySearchTreeTest.java +++ b/exercises/practice/binary-search-tree/src/test/java/BinarySearchTreeTest.java @@ -4,11 +4,13 @@ import static org.assertj.core.api.Assertions.assertThat; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; public class BinarySearchTreeTest { @Test + @DisplayName("data is retained") public void dataIsRetained() { BinarySearchTree binarySearchTree = new BinarySearchTree<>(); @@ -24,6 +26,7 @@ public void dataIsRetained() { @Disabled("Remove to run test") @Test + @DisplayName("insert data at proper node") public void insertsLess() { BinarySearchTree binarySearchTree = new BinarySearchTree<>(); @@ -45,6 +48,7 @@ public void insertsLess() { @Disabled("Remove to run test") @Test + @DisplayName("same number at left node") public void insertsSame() { BinarySearchTree binarySearchTree = new BinarySearchTree<>(); String expectedRoot = "4"; @@ -65,6 +69,7 @@ public void insertsSame() { @Disabled("Remove to run test") @Test + @DisplayName("greater number at right node") public void insertsRight() { BinarySearchTree binarySearchTree = new BinarySearchTree<>(); int expectedRoot = 4; @@ -85,6 +90,7 @@ public void insertsRight() { @Disabled("Remove to run test") @Test + @DisplayName("can create complex tree") public void createsComplexTree() { BinarySearchTree binarySearchTree = new BinarySearchTree<>(); List expected = List.of('4', '2', '6', '1', '3', '5', '7'); @@ -97,6 +103,7 @@ public void createsComplexTree() { @Disabled("Remove to run test") @Test + @DisplayName("can sort single number") public void sortsSingleElement() { BinarySearchTree binarySearchTree = new BinarySearchTree<>(); List expected = Collections.singletonList("2"); @@ -108,6 +115,7 @@ public void sortsSingleElement() { @Disabled("Remove to run test") @Test + @DisplayName("can sort if second number is smaller than first") public void sortsCollectionOfTwoIfSecondInsertedIsSmallerThanFirst() { BinarySearchTree binarySearchTree = new BinarySearchTree<>(); List expected = List.of(1, 2); @@ -120,6 +128,7 @@ public void sortsCollectionOfTwoIfSecondInsertedIsSmallerThanFirst() { @Disabled("Remove to run test") @Test + @DisplayName("can sort if second number is same as first") public void sortsCollectionOfTwoIfSecondNumberisSameAsFirst() { BinarySearchTree binarySearchTree = new BinarySearchTree<>(); List expected = List.of('2', '2'); @@ -132,6 +141,7 @@ public void sortsCollectionOfTwoIfSecondNumberisSameAsFirst() { @Disabled("Remove to run test") @Test + @DisplayName("can sort if second number is greater than first") public void sortsCollectionOfTwoIfSecondInsertedIsBiggerThanFirst() { BinarySearchTree binarySearchTree = new BinarySearchTree<>(); List expected = List.of('2', '3'); @@ -144,6 +154,7 @@ public void sortsCollectionOfTwoIfSecondInsertedIsBiggerThanFirst() { @Disabled("Remove to run test") @Test + @DisplayName("can sort complex tree") public void iteratesOverComplexTree() { BinarySearchTree binarySearchTree = new BinarySearchTree<>(); List expected = List.of("1", "2", "3", "5", "6", "7"); diff --git a/exercises/practice/binary-search/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/binary-search/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/binary-search/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/binary-search/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/binary-search/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/binary-search/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/binary-search/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/binary-search/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/binary-search/gradlew b/exercises/practice/binary-search/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/binary-search/gradlew +++ b/exercises/practice/binary-search/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/binary-search/gradlew.bat b/exercises/practice/binary-search/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/binary-search/gradlew.bat +++ b/exercises/practice/binary-search/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/binary-search/src/test/java/BinarySearchTest.java b/exercises/practice/binary-search/src/test/java/BinarySearchTest.java index f586f744c..4846489c9 100644 --- a/exercises/practice/binary-search/src/test/java/BinarySearchTest.java +++ b/exercises/practice/binary-search/src/test/java/BinarySearchTest.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.Collections; @@ -10,6 +11,7 @@ public class BinarySearchTest { @Test + @DisplayName("finds a value in an array with one element") public void findsAValueInAnArrayWithOneElement() throws ValueNotFoundException { List listOfUnitLength = Collections.singletonList(6); @@ -20,6 +22,7 @@ public void findsAValueInAnArrayWithOneElement() throws ValueNotFoundException { @Disabled("Remove to run test") @Test + @DisplayName("finds a value in the middle of an array") public void findsAValueInTheMiddleOfAnArray() throws ValueNotFoundException { List sortedList = List.of(1, 3, 4, 6, 8, 9, 11); @@ -30,6 +33,7 @@ public void findsAValueInTheMiddleOfAnArray() throws ValueNotFoundException { @Disabled("Remove to run test") @Test + @DisplayName("finds a value at the beginning of an array") public void findsAValueAtTheBeginningOfAnArray() throws ValueNotFoundException { List sortedList = List.of(1, 3, 4, 6, 8, 9, 11); @@ -40,6 +44,7 @@ public void findsAValueAtTheBeginningOfAnArray() throws ValueNotFoundException { @Disabled("Remove to run test") @Test + @DisplayName("finds a value at the end of an array") public void findsAValueAtTheEndOfAnArray() throws ValueNotFoundException { List sortedList = List.of(1, 3, 4, 6, 8, 9, 11); @@ -50,6 +55,7 @@ public void findsAValueAtTheEndOfAnArray() throws ValueNotFoundException { @Disabled("Remove to run test") @Test + @DisplayName("finds a value in an array of odd length") public void findsAValueInAnArrayOfOddLength() throws ValueNotFoundException { List sortedListOfOddLength = List.of(1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 634); @@ -60,6 +66,7 @@ public void findsAValueInAnArrayOfOddLength() throws ValueNotFoundException { @Disabled("Remove to run test") @Test + @DisplayName("finds a value in an array of even length") public void findsAValueInAnArrayOfEvenLength() throws ValueNotFoundException { List sortedListOfEvenLength = List.of(1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377); @@ -70,6 +77,7 @@ public void findsAValueInAnArrayOfEvenLength() throws ValueNotFoundException { @Disabled("Remove to run test") @Test + @DisplayName("identifies that a value is not included in the array") public void identifiesThatAValueIsNotFoundInTheArray() { List sortedList = List.of(1, 3, 4, 6, 8, 9, 11); @@ -82,6 +90,7 @@ public void identifiesThatAValueIsNotFoundInTheArray() { @Disabled("Remove to run test") @Test + @DisplayName("a value smaller than the array's smallest value is not found") public void aValueSmallerThanTheArraysSmallestValueIsNotFound() { List sortedList = List.of(1, 3, 4, 6, 8, 9, 11); @@ -94,6 +103,7 @@ public void aValueSmallerThanTheArraysSmallestValueIsNotFound() { @Disabled("Remove to run test") @Test + @DisplayName("a value larger than the array's largest value is not found") public void aValueLargerThanTheArraysLargestValueIsNotFound() throws ValueNotFoundException { List sortedList = List.of(1, 3, 4, 6, 8, 9, 11); @@ -106,6 +116,7 @@ public void aValueLargerThanTheArraysLargestValueIsNotFound() throws ValueNotFou @Disabled("Remove to run test") @Test + @DisplayName("nothing is found in an empty array") public void nothingIsFoundInAnEmptyArray() throws ValueNotFoundException { List emptyList = Collections.emptyList(); @@ -118,6 +129,7 @@ public void nothingIsFoundInAnEmptyArray() throws ValueNotFoundException { @Disabled("Remove to run test") @Test + @DisplayName("nothing is found when the left and right bounds cross") public void nothingIsFoundWhenTheLeftAndRightBoundCross() throws ValueNotFoundException { List sortedList = List.of(1, 2); diff --git a/exercises/practice/bob/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/bob/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/bob/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/bob/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/bob/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/bob/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/bob/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/bob/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/bob/gradlew b/exercises/practice/bob/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/bob/gradlew +++ b/exercises/practice/bob/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/bob/gradlew.bat b/exercises/practice/bob/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/bob/gradlew.bat +++ b/exercises/practice/bob/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/bob/src/test/java/BobTest.java b/exercises/practice/bob/src/test/java/BobTest.java index 801315b42..756fb93f8 100644 --- a/exercises/practice/bob/src/test/java/BobTest.java +++ b/exercises/practice/bob/src/test/java/BobTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.BeforeEach; import static org.assertj.core.api.Assertions.assertThat; @@ -14,6 +15,7 @@ public void setUp() { } @Test + @DisplayName("stating something") public void saySomething() { assertThat(bob.hey("Tom-ay-to, tom-aaaah-to.")) .isEqualTo("Whatever."); @@ -21,6 +23,7 @@ public void saySomething() { @Disabled("Remove to run test") @Test + @DisplayName("shouting") public void shouting() { assertThat(bob.hey("WATCH OUT!")) .isEqualTo("Whoa, chill out!"); @@ -28,6 +31,7 @@ public void shouting() { @Disabled("Remove to run test") @Test + @DisplayName("shouting gibberish") public void shoutingGibberish() { assertThat(bob.hey("FCECDFCAAB")) .isEqualTo("Whoa, chill out!"); @@ -35,6 +39,7 @@ public void shoutingGibberish() { @Disabled("Remove to run test") @Test + @DisplayName("asking a question") public void askingAQuestion() { assertThat(bob.hey("Does this cryogenic chamber make me look fat?")) .isEqualTo("Sure."); @@ -42,6 +47,7 @@ public void askingAQuestion() { @Disabled("Remove to run test") @Test + @DisplayName("asking a numeric question") public void askingANumericQuestion() { assertThat(bob.hey("You are, what, like 15?")) .isEqualTo("Sure."); @@ -49,6 +55,7 @@ public void askingANumericQuestion() { @Disabled("Remove to run test") @Test + @DisplayName("asking gibberish") public void askingGibberish() { assertThat(bob.hey("fffbbcbeab?")) .isEqualTo("Sure."); @@ -56,6 +63,7 @@ public void askingGibberish() { @Disabled("Remove to run test") @Test + @DisplayName("talking forcefully") public void talkingForcefully() { assertThat(bob.hey("Hi there!")) .isEqualTo("Whatever."); @@ -63,6 +71,7 @@ public void talkingForcefully() { @Disabled("Remove to run test") @Test + @DisplayName("using acronyms in regular speech") public void usingAcronymsInRegularSpeech() { assertThat(bob.hey("It's OK if you don't want to go work for NASA.")) .isEqualTo("Whatever."); @@ -70,6 +79,7 @@ public void usingAcronymsInRegularSpeech() { @Disabled("Remove to run test") @Test + @DisplayName("forceful question") public void forcefulQuestions() { assertThat(bob.hey("WHAT'S GOING ON?")) .isEqualTo("Calm down, I know what I'm doing!"); @@ -77,6 +87,7 @@ public void forcefulQuestions() { @Disabled("Remove to run test") @Test + @DisplayName("shouting numbers") public void shoutingNumbers() { assertThat(bob.hey("1, 2, 3 GO!")) .isEqualTo("Whoa, chill out!"); @@ -84,6 +95,7 @@ public void shoutingNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("no letters") public void onlyNumbers() { assertThat(bob.hey("1, 2, 3")) .isEqualTo("Whatever."); @@ -91,6 +103,7 @@ public void onlyNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("question with no letters") public void questionWithOnlyNumbers() { assertThat(bob.hey("4?")) .isEqualTo("Sure."); @@ -98,6 +111,7 @@ public void questionWithOnlyNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("shouting with special characters") public void shoutingWithSpecialCharacters() { assertThat(bob.hey("ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!")) .isEqualTo("Whoa, chill out!"); @@ -105,6 +119,7 @@ public void shoutingWithSpecialCharacters() { @Disabled("Remove to run test") @Test + @DisplayName("shouting with no exclamation mark") public void shoutingWithNoExclamationMark() { assertThat(bob.hey("I HATE THE DENTIST")) .isEqualTo("Whoa, chill out!"); @@ -112,6 +127,7 @@ public void shoutingWithNoExclamationMark() { @Disabled("Remove to run test") @Test + @DisplayName("statement containing question mark") public void statementContainingQuestionMark() { assertThat(bob.hey("Ending with ? means a question.")) .isEqualTo("Whatever."); @@ -119,6 +135,7 @@ public void statementContainingQuestionMark() { @Disabled("Remove to run test") @Test + @DisplayName("non-letters with question") public void nonLettersWithQuestion() { assertThat(bob.hey(":) ?")) .isEqualTo("Sure."); @@ -126,6 +143,7 @@ public void nonLettersWithQuestion() { @Disabled("Remove to run test") @Test + @DisplayName("prattling on") public void prattlingOn() { assertThat(bob.hey("Wait! Hang on. Are you going to be OK?")) .isEqualTo("Sure."); @@ -133,6 +151,7 @@ public void prattlingOn() { @Disabled("Remove to run test") @Test + @DisplayName("silence") public void silence() { assertThat(bob.hey("")) .isEqualTo("Fine. Be that way!"); @@ -140,6 +159,7 @@ public void silence() { @Disabled("Remove to run test") @Test + @DisplayName("prolonged silence") public void prolongedSilence() { assertThat(bob.hey(" ")) .isEqualTo("Fine. Be that way!"); @@ -147,6 +167,7 @@ public void prolongedSilence() { @Disabled("Remove to run test") @Test + @DisplayName("alternate silence") public void alternateSilence() { assertThat(bob.hey("\t\t\t\t\t\t\t\t\t\t")) .isEqualTo("Fine. Be that way!"); @@ -154,6 +175,7 @@ public void alternateSilence() { @Disabled("Remove to run test") @Test + @DisplayName("starting with whitespace") public void startingWithWhitespace() { assertThat(bob.hey(" hmmmmmmm...")) .isEqualTo("Whatever."); @@ -161,6 +183,7 @@ public void startingWithWhitespace() { @Disabled("Remove to run test") @Test + @DisplayName("ending with whitespace") public void endingWithWhiteSpace() { assertThat(bob.hey("Okay if like my spacebar quite a bit? ")) .isEqualTo("Sure."); @@ -168,6 +191,7 @@ public void endingWithWhiteSpace() { @Disabled("Remove to run test") @Test + @DisplayName("other whitespace") public void otherWhiteSpace() { assertThat(bob.hey("\n\r \t")) .isEqualTo("Fine. Be that way!"); @@ -175,6 +199,7 @@ public void otherWhiteSpace() { @Disabled("Remove to run test") @Test + @DisplayName("non-question ending with whitespace") public void nonQuestionEndingWithWhiteSpace() { assertThat(bob.hey("This is a statement ending with whitespace ")) .isEqualTo("Whatever."); @@ -182,6 +207,7 @@ public void nonQuestionEndingWithWhiteSpace() { @Disabled("Remove to run test") @Test + @DisplayName("multiple line question") public void multipleLineQuestion() { assertThat(bob.hey("\nDoes this cryogenic chamber make\n me look fat?")) .isEqualTo("Sure."); diff --git a/exercises/practice/book-store/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/book-store/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/book-store/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/book-store/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/book-store/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/book-store/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/book-store/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/book-store/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/book-store/gradlew b/exercises/practice/book-store/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/book-store/gradlew +++ b/exercises/practice/book-store/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/book-store/gradlew.bat b/exercises/practice/book-store/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/book-store/gradlew.bat +++ b/exercises/practice/book-store/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/book-store/src/test/java/BookStoreTest.java b/exercises/practice/book-store/src/test/java/BookStoreTest.java index 920b83658..bbcbbcfb9 100644 --- a/exercises/practice/book-store/src/test/java/BookStoreTest.java +++ b/exercises/practice/book-store/src/test/java/BookStoreTest.java @@ -1,6 +1,7 @@ import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.Arrays; @@ -23,6 +24,7 @@ public void setUp() { } @Test + @DisplayName("Only a single book") public void onlyASingleBook() { List books = Collections.singletonList(1); assertThat(bookStore.calculateBasketCost(books)) @@ -31,6 +33,7 @@ public void onlyASingleBook() { @Disabled("Remove to run test") @Test + @DisplayName("Two of the same book") public void twoOfSameBook() { List books = Arrays.asList(2, 2); assertThat(bookStore.calculateBasketCost(books)) @@ -39,6 +42,7 @@ public void twoOfSameBook() { @Disabled("Remove to run test") @Test + @DisplayName("Empty basket") public void emptyBasket() { List books = Collections.emptyList(); assertThat(bookStore.calculateBasketCost(books)) @@ -47,6 +51,7 @@ public void emptyBasket() { @Disabled("Remove to run test") @Test + @DisplayName("Two different books") public void twoDifferentBooks() { List books = Arrays.asList(1, 2); assertThat(bookStore.calculateBasketCost(books)) @@ -55,6 +60,7 @@ public void twoDifferentBooks() { @Disabled("Remove to run test") @Test + @DisplayName("Three different books") public void threeDifferentBooks() { List books = Arrays.asList(1, 2, 3); assertThat(bookStore.calculateBasketCost(books)) @@ -63,6 +69,7 @@ public void threeDifferentBooks() { @Disabled("Remove to run test") @Test + @DisplayName("Four different books") public void fourDifferentBooks() { List books = Arrays.asList(1, 2, 3, 4); assertThat(bookStore.calculateBasketCost(books)) @@ -71,6 +78,7 @@ public void fourDifferentBooks() { @Disabled("Remove to run test") @Test + @DisplayName("Five different books") public void fiveDifferentBooks() { List books = Arrays.asList(1, 2, 3, 4, 5); assertThat(bookStore.calculateBasketCost(books)) @@ -79,6 +87,7 @@ public void fiveDifferentBooks() { @Disabled("Remove to run test") @Test + @DisplayName("Two groups of four is cheaper than group of five plus group of three") public void twoGroupsOfFourIsCheaperThanGroupOfFivePlusGroupOfThree() { List books = Arrays.asList(1, 1, 2, 2, 3, 3, 4, 5); assertThat(bookStore.calculateBasketCost(books)) @@ -87,6 +96,7 @@ public void twoGroupsOfFourIsCheaperThanGroupOfFivePlusGroupOfThree() { @Disabled("Remove to run test") @Test + @DisplayName("Two groups of four is cheaper than groups of five and three") public void twoGroupsOfFourIsCheaperThanGroupsOfFiveAndThree() { List books = Arrays.asList(1, 1, 2, 3, 4, 4, 5, 5); assertThat(bookStore.calculateBasketCost(books)) @@ -95,6 +105,7 @@ public void twoGroupsOfFourIsCheaperThanGroupsOfFiveAndThree() { @Disabled("Remove to run test") @Test + @DisplayName("Group of four plus group of two is cheaper than two groups of three") public void groupOfFourPlusGroupOfTwoIsCheaperThanTwoGroupsOfThree() { List books = Arrays.asList(1, 1, 2, 2, 3, 4); assertThat(bookStore.calculateBasketCost(books)) @@ -103,6 +114,7 @@ public void groupOfFourPlusGroupOfTwoIsCheaperThanTwoGroupsOfThree() { @Disabled("Remove to run test") @Test + @DisplayName("Two each of first four books and one copy each of rest") public void twoEachOfFirst4BooksAnd1CopyEachOfRest() { List books = Arrays.asList(1, 1, 2, 2, 3, 3, 4, 4, 5); assertThat(bookStore.calculateBasketCost(books)) @@ -111,6 +123,7 @@ public void twoEachOfFirst4BooksAnd1CopyEachOfRest() { @Disabled("Remove to run test") @Test + @DisplayName("Two copies of each book") public void twoCopiesOfEachBook() { List books = Arrays.asList(1, 1, 2, 2, 3, 3, 4, 4, 5, 5); assertThat(bookStore.calculateBasketCost(books)) @@ -119,7 +132,8 @@ public void twoCopiesOfEachBook() { @Disabled("Remove to run test") @Test - public void threeCopiesOfFirstBookAnd2EachOfRemaining() { + @DisplayName("Three copies of first book and two each of remaining") + public void threeCopiesOfFirstBookAndTwoEachOfRemaining() { List books = Arrays.asList(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 1); assertThat(bookStore.calculateBasketCost(books)) .isCloseTo(68.00, Assertions.offset(EQUALITY_TOLERANCE)); @@ -127,7 +141,8 @@ public void threeCopiesOfFirstBookAnd2EachOfRemaining() { @Disabled("Remove to run test") @Test - public void threeEachOFirst2BooksAnd2EachOfRemainingBooks() { + @DisplayName("Three each of first two books and two each of remaining books") + public void threeEachOfFirstTwoBooksAndTwoEachOfRemainingBooks() { List books = Arrays.asList(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 1, 2); assertThat(bookStore.calculateBasketCost(books)) .isCloseTo(75.20, Assertions.offset(EQUALITY_TOLERANCE)); @@ -135,6 +150,7 @@ public void threeEachOFirst2BooksAnd2EachOfRemainingBooks() { @Disabled("Remove to run test") @Test + @DisplayName("Four groups of four are cheaper than two groups each of five and three") public void fourGroupsOfFourAreCheaperThanTwoGroupsEachOfFiveAndThree() { List books = Arrays.asList(1, 1, 2, 2, 3, 3, 4, 5, 1, 1, 2, 2, 3, 3, 4, 5); assertThat(bookStore.calculateBasketCost(books)) @@ -143,6 +159,9 @@ public void fourGroupsOfFourAreCheaperThanTwoGroupsEachOfFiveAndThree() { @Disabled("Remove to run test") @Test + @DisplayName( + "Check that groups of four are created properly even when there are more groups of three than groups of five" + ) public void groupsOfFourAreCreatedEvenWhenThereAreMoreGroupsOfThreeThanGroupsOfFive() { List books = Arrays.asList(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 5, 5); assertThat(bookStore.calculateBasketCost(books)) @@ -151,6 +170,7 @@ public void groupsOfFourAreCreatedEvenWhenThereAreMoreGroupsOfThreeThanGroupsOfF @Disabled("Remove to run test") @Test + @DisplayName("One group of one and four is cheaper than one group of two and three") public void oneGroupOfOneAndFourIsCheaperThanOneGroupOfTwoAndThree() { List books = Arrays.asList(1, 1, 2, 3, 4); assertThat(bookStore.calculateBasketCost(books)) @@ -159,6 +179,7 @@ public void oneGroupOfOneAndFourIsCheaperThanOneGroupOfTwoAndThree() { @Disabled("Remove to run test") @Test + @DisplayName("One group of one and two plus three groups of four is cheaper than one group of each size") public void oneGroupOfOneAndTwoPlusThreeGroupsOfFourIsCheaperThanOneGroupOfEachSize() { List books = Arrays.asList(1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5); assertThat(bookStore.calculateBasketCost(books)) diff --git a/exercises/practice/bottle-song/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/bottle-song/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/bottle-song/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/bottle-song/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/bottle-song/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/bottle-song/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/bottle-song/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/bottle-song/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/bottle-song/gradlew b/exercises/practice/bottle-song/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/bottle-song/gradlew +++ b/exercises/practice/bottle-song/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/bottle-song/gradlew.bat b/exercises/practice/bottle-song/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/bottle-song/gradlew.bat +++ b/exercises/practice/bottle-song/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/bottle-song/src/test/java/BottleSongTest.java b/exercises/practice/bottle-song/src/test/java/BottleSongTest.java index a47a7edc8..7d5ce0a97 100644 --- a/exercises/practice/bottle-song/src/test/java/BottleSongTest.java +++ b/exercises/practice/bottle-song/src/test/java/BottleSongTest.java @@ -1,6 +1,7 @@ -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -14,6 +15,7 @@ public void setup() { } @Test + @DisplayName("first generic verse") public void firstGenericVerse() { assertThat(bottleSong.recite(10, 1)).isEqualTo( "Ten green bottles hanging on the wall,\n" + @@ -25,6 +27,7 @@ public void firstGenericVerse() { @Disabled("Remove to run test") @Test + @DisplayName("last generic verse") public void lastGenericVerse() { assertThat(bottleSong.recite(3, 1)).isEqualTo( "Three green bottles hanging on the wall,\n" + @@ -36,6 +39,7 @@ public void lastGenericVerse() { @Disabled("Remove to run test") @Test + @DisplayName("verse with 2 bottles") public void verseWithTwoBottles() { assertThat(bottleSong.recite(2, 1)).isEqualTo( "Two green bottles hanging on the wall,\n" + @@ -47,6 +51,7 @@ public void verseWithTwoBottles() { @Disabled("Remove to run test") @Test + @DisplayName("verse with 1 bottle") public void verseWithOneBottle() { assertThat(bottleSong.recite(1, 1)).isEqualTo( "One green bottle hanging on the wall,\n" + @@ -58,6 +63,7 @@ public void verseWithOneBottle() { @Disabled("Remove to run test") @Test + @DisplayName("first two verses") public void firstTwoVerses() { assertThat(bottleSong.recite(10, 2)).isEqualTo( "Ten green bottles hanging on the wall,\n" + @@ -74,6 +80,7 @@ public void firstTwoVerses() { @Disabled("Remove to run test") @Test + @DisplayName("last three verses") public void lastThreeVerses() { assertThat(bottleSong.recite(3, 3)).isEqualTo( "Three green bottles hanging on the wall,\n" + @@ -95,6 +102,7 @@ public void lastThreeVerses() { @Disabled("Remove to run test") @Test + @DisplayName("all verses") public void allVerses() { assertThat(bottleSong.recite(10, 10)) .isEqualTo( diff --git a/exercises/practice/bowling/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/bowling/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/bowling/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/bowling/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/bowling/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/bowling/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/bowling/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/bowling/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/bowling/gradlew b/exercises/practice/bowling/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/bowling/gradlew +++ b/exercises/practice/bowling/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/bowling/gradlew.bat b/exercises/practice/bowling/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/bowling/gradlew.bat +++ b/exercises/practice/bowling/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/bowling/src/test/java/BowlingGameTest.java b/exercises/practice/bowling/src/test/java/BowlingGameTest.java index 7b63a4fc1..a8fbcad96 100644 --- a/exercises/practice/bowling/src/test/java/BowlingGameTest.java +++ b/exercises/practice/bowling/src/test/java/BowlingGameTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -14,6 +15,7 @@ private void playGame(int[] rolls) { } @Test + @DisplayName("should be able to score a game with all zeros") public void shouldBeAbleToScoreAGameWithAllZeros() { int[] rolls = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; @@ -23,6 +25,7 @@ public void shouldBeAbleToScoreAGameWithAllZeros() { @Disabled("Remove to run test") @Test + @DisplayName("should be able to score a game with no strikes or spares") public void shouldBeAbleToScoreAGameWithNoStrikesOrSpares() { int[] rolls = {3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6}; @@ -32,6 +35,7 @@ public void shouldBeAbleToScoreAGameWithNoStrikesOrSpares() { @Disabled("Remove to run test") @Test + @DisplayName("a spare followed by zeros is worth ten points") public void aSpareFollowedByZerosIsWorthTenPoints() { int[] rolls = {6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; @@ -41,6 +45,7 @@ public void aSpareFollowedByZerosIsWorthTenPoints() { @Disabled("Remove to run test") @Test + @DisplayName("points scored in the roll after a spare are counted twice") public void pointsScoredInTheRollAfterASpareAreCountedTwice() { int[] rolls = {6, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; @@ -50,6 +55,7 @@ public void pointsScoredInTheRollAfterASpareAreCountedTwice() { @Disabled("Remove to run test") @Test + @DisplayName("consecutive spares each get a one roll bonus") public void consecutiveSparesEachGetAOneRollBonus() { int[] rolls = {5, 5, 3, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; @@ -59,6 +65,7 @@ public void consecutiveSparesEachGetAOneRollBonus() { @Disabled("Remove to run test") @Test + @DisplayName("a spare in the last frame gets a one roll bonus that is counted once") public void aSpareInTheLastFrameGetsAOneRollBonusThatIsCountedOnce() { int[] rolls = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 7}; @@ -68,6 +75,7 @@ public void aSpareInTheLastFrameGetsAOneRollBonusThatIsCountedOnce() { @Disabled("Remove to run test") @Test + @DisplayName("a strike earns ten points in a frame with a single roll") public void aStrikeEarnsTenPointsInFrameWithASingleRoll() { int[] rolls = {10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; @@ -77,6 +85,7 @@ public void aStrikeEarnsTenPointsInFrameWithASingleRoll() { @Disabled("Remove to run test") @Test + @DisplayName("points scored in the two rolls after a strike are counted twice as a bonus") public void pointsScoredInTheTwoRollsAfterAStrikeAreCountedTwiceAsABonus() { int[] rolls = {10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; @@ -86,6 +95,7 @@ public void pointsScoredInTheTwoRollsAfterAStrikeAreCountedTwiceAsABonus() { @Disabled("Remove to run test") @Test + @DisplayName("consecutive strikes each get the two roll bonus") public void consecutiveStrikesEachGetTheTwoRollBonus() { int[] rolls = {10, 10, 10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; @@ -95,6 +105,7 @@ public void consecutiveStrikesEachGetTheTwoRollBonus() { @Disabled("Remove to run test") @Test + @DisplayName("a strike in the last frame gets a two roll bonus that is counted once") public void aStrikeInTheLastFrameGetsATwoRollBonusThatIsCountedOnce() { int[] rolls = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 1}; @@ -104,6 +115,7 @@ public void aStrikeInTheLastFrameGetsATwoRollBonusThatIsCountedOnce() { @Disabled("Remove to run test") @Test + @DisplayName("rolling a spare with the two roll bonus does not get a bonus roll") public void rollingASpareWithTheTwoRollBonusDoesNotGetABonusRoll() { int[] rolls = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 3}; @@ -113,6 +125,7 @@ public void rollingASpareWithTheTwoRollBonusDoesNotGetABonusRoll() { @Disabled("Remove to run test") @Test + @DisplayName("strikes with the two roll bonus do not get bonus rolls") public void strikesWithTheTwoRollBonusDoNotGetBonusRolls() { int[] rolls = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10}; @@ -122,6 +135,7 @@ public void strikesWithTheTwoRollBonusDoNotGetBonusRolls() { @Disabled("Remove to run test") @Test + @DisplayName("last two strikes followed by only last bonus with non strike points") public void lastTwoStrikesFollowedByOnlyLastBonusWithNonStrikePoints() { int[] rolls = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 0, 1}; @@ -131,6 +145,7 @@ public void lastTwoStrikesFollowedByOnlyLastBonusWithNonStrikePoints() { @Disabled("Remove to run test") @Test + @DisplayName("a strike with the one roll bonus after a spare in the last frame does not get a bonus") public void aStrikeWithTheOneRollBonusAfterASpareInTheLastFrameDoesNotGetABonus() { int[] rolls = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 10}; @@ -140,6 +155,7 @@ public void aStrikeWithTheOneRollBonusAfterASpareInTheLastFrameDoesNotGetABonus( @Disabled("Remove to run test") @Test + @DisplayName("all strikes is a perfect game") public void allStrikesIsAPerfectGame() { int[] rolls = {10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}; @@ -149,6 +165,7 @@ public void allStrikesIsAPerfectGame() { @Disabled("Remove to run test") @Test + @DisplayName("rolls cannot score negative points") public void rollsCanNotScoreNegativePoints() { int[] rolls = {-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; @@ -159,6 +176,7 @@ public void rollsCanNotScoreNegativePoints() { @Disabled("Remove to run test") @Test + @DisplayName("a roll cannot score more than 10 points") public void aRollCanNotScoreMoreThan10Points() { int[] rolls = {11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; @@ -169,6 +187,7 @@ public void aRollCanNotScoreMoreThan10Points() { @Disabled("Remove to run test") @Test + @DisplayName("two rolls in a frame cannot score more than 10 points") public void twoRollsInAFrameCanNotScoreMoreThan10Points() { int[] rolls = {5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; @@ -179,6 +198,7 @@ public void twoRollsInAFrameCanNotScoreMoreThan10Points() { @Disabled("Remove to run test") @Test + @DisplayName("bonus roll after a strike in the last frame cannot score more than 10 points") public void bonusRollAfterAStrikeInTheLastFrameCanNotScoreMoreThan10Points() { int[] rolls = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 0}; @@ -189,6 +209,7 @@ public void bonusRollAfterAStrikeInTheLastFrameCanNotScoreMoreThan10Points() { @Disabled("Remove to run test") @Test + @DisplayName("two bonus rolls after a strike in the last frame cannot score more than 10 points") public void twoBonusRollsAfterAStrikeInTheLastFrameCanNotScoreMoreThan10Points() { int[] rolls = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 5, 6}; @@ -199,6 +220,7 @@ public void twoBonusRollsAfterAStrikeInTheLastFrameCanNotScoreMoreThan10Points() @Disabled("Remove to run test") @Test + @DisplayName("two bonus rolls after a strike in the last frame can score more than 10 points if one is a strike") public void twoBonusRollsAfterAStrikeInTheLastFrameCanScoreMoreThan10PointsIfOneIsAStrike() { int[] rolls = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 6}; @@ -209,6 +231,9 @@ public void twoBonusRollsAfterAStrikeInTheLastFrameCanScoreMoreThan10PointsIfOne @Disabled("Remove to run test") @Test + @DisplayName( + "the second bonus rolls after a strike in the last frame cannot be a strike if the first one is not a strike" + ) public void theSecondBonusRollsAfterAStrikeInTheLastFrameCanNotBeAStrikeIfTheFirstOneIsNotAStrike() { int[] rolls = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 6, 10}; @@ -219,6 +244,7 @@ public void theSecondBonusRollsAfterAStrikeInTheLastFrameCanNotBeAStrikeIfTheFir @Disabled("Remove to run test") @Test + @DisplayName("second bonus roll after a strike in the last frame cannot score more than 10 points") public void secondBonusRollAfterAStrikeInTheLastFrameCanNotScoreMoreThan10Points() { int[] rolls = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 11}; @@ -229,6 +255,7 @@ public void secondBonusRollAfterAStrikeInTheLastFrameCanNotScoreMoreThan10Points @Disabled("Remove to run test") @Test + @DisplayName("an unstarted game cannot be scored") public void anUnstartedGameCanNotBeScored() { int[] rolls = new int[0]; @@ -241,6 +268,7 @@ public void anUnstartedGameCanNotBeScored() { @Disabled("Remove to run test") @Test + @DisplayName("an incomplete game cannot be scored") public void anIncompleteGameCanNotBeScored() { int[] rolls = {0, 0}; @@ -253,6 +281,7 @@ public void anIncompleteGameCanNotBeScored() { @Disabled("Remove to run test") @Test + @DisplayName("cannot roll if game already has ten frames") public void canNotRollIfGameAlreadyHasTenFrames() { int[] rolls = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; @@ -263,6 +292,7 @@ public void canNotRollIfGameAlreadyHasTenFrames() { @Disabled("Remove to run test") @Test + @DisplayName("bonus rolls for a strike in the last frame must be rolled before score can be calculated") public void bonusRollsForAStrikeInTheLastFrameMustBeRolledBeforeScoreCanBeCalculated() { int[] rolls = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10}; @@ -275,6 +305,7 @@ public void bonusRollsForAStrikeInTheLastFrameMustBeRolledBeforeScoreCanBeCalcul @Disabled("Remove to run test") @Test + @DisplayName("both bonus rolls for a strike in the last frame must be rolled before score can be calculated") public void bothBonusRollsForAStrikeInTheLastFrameMustBeRolledBeforeScoreCanBeCalculated() { int[] rolls = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10}; @@ -287,6 +318,7 @@ public void bothBonusRollsForAStrikeInTheLastFrameMustBeRolledBeforeScoreCanBeCa @Disabled("Remove to run test") @Test + @DisplayName("bonus roll for a spare in the last frame must be rolled before score can be calculated") public void bonusRollForASpareInTheLastFrameMustBeRolledBeforeScoreCanBeCalculated() { int[] rolls = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3}; @@ -299,6 +331,7 @@ public void bonusRollForASpareInTheLastFrameMustBeRolledBeforeScoreCanBeCalculat @Disabled("Remove to run test") @Test + @DisplayName("cannot roll after bonus roll for spare") public void canNotRollAfterBonusRollForSpare() { int[] rolls = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 2, 2}; @@ -309,6 +342,7 @@ public void canNotRollAfterBonusRollForSpare() { @Disabled("Remove to run test") @Test + @DisplayName("cannot roll after bonus rolls for strike") public void canNotRollAfterBonusRollForStrike() { int[] rolls = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 2, 2}; diff --git a/exercises/practice/change/.approaches/config.json b/exercises/practice/change/.approaches/config.json index 00716db81..c24280ab1 100644 --- a/exercises/practice/change/.approaches/config.json +++ b/exercises/practice/change/.approaches/config.json @@ -2,20 +2,41 @@ "introduction": { "authors": [ "jagdish-15" + ], + "contributors": [ + "kahgoh" ] }, "approaches": [ { "uuid": "d0b615ca-3a02-4d66-ad10-e0c513062189", - "slug": "dynamic-programming", - "title": "Dynamic Programming Approach", - "blurb": "Use dynamic programming to find the most efficient change combination.", + "slug": "dynamic-programming-top-down", + "title": "Dynamic Programming: Top Down", + "blurb": "Break the required amount into smaller amounts and reuse saved results to quickly find the final result.", "authors": [ "jagdish-15" ], "contributors": [ "kahgoh" ] + }, + { + "uuid": "daf47878-1607-4f22-b2df-1049f3d6802c", + "slug": "dynamic-programming-bottom-up", + "title": "Dynamic Programming: Bottom Up", + "blurb": "Start from the available coins and calculate the amounts that can be made from them.", + "authors": [ + "kahgoh" + ] + }, + { + "uuid": "06ae63ec-5bf3-41a0-89e3-2772e4cdbf5d", + "slug": "recursive", + "title": "Recursive", + "blurb": "Use recursion to recursively find the most efficient change for a given amount.", + "authors": [ + "kahgoh" + ] } ] } diff --git a/exercises/practice/change/.approaches/dynamic-programming-bottom-up/content.md b/exercises/practice/change/.approaches/dynamic-programming-bottom-up/content.md new file mode 100644 index 000000000..84983df5e --- /dev/null +++ b/exercises/practice/change/.approaches/dynamic-programming-bottom-up/content.md @@ -0,0 +1,84 @@ +# Dynamic Programming - Bottom up + +```java +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +class ChangeCalculator { + + private final List currencyCoins; + + ChangeCalculator(List currencyCoins) { + this.currencyCoins = List.copyOf(currencyCoins); + } + + List computeMostEfficientChange(int grandTotal) { + if (grandTotal < 0) { + throw new IllegalArgumentException("Negative totals are not allowed."); + } + if (grandTotal == 0) { + return Collections.emptyList(); + } + Set reachableTotals = new HashSet<>(); + ArrayDeque> queue = new ArrayDeque<>(currencyCoins.stream().map(List::of).toList()); + + while (!queue.isEmpty()) { + List next = queue.poll(); + int total = next.stream().mapToInt(Integer::intValue).sum(); + if (total == grandTotal) { + return next; + } + if (total < grandTotal && reachableTotals.add(total)) { + for (Integer coin : currencyCoins) { + List toCheck = new ArrayList<>(next); + toCheck.add(coin); + queue.offer(toCheck); + } + } + } + + throw new IllegalArgumentException("The total " + grandTotal + " cannot be represented in the given currency."); + } +} +``` + +This approach starts from the coins and calculates which amounts can be made up by the coins. + +The `grandTotal` is first validated to ensure that it is a positive number greater than 0. +Two data structures are then created: + +- a queue to maintain a combination of coins to check +- a set to keep track of the totals from the combinations that have been seen + +The queue is initialized with a number of combinations that consist just each of the coins. +For example, if the available coins are 5, 10 and 20, then the queue begins with three combinations: + +- the first combination has just 5 +- the second has just 10 +- the third has just 20 + +Thus, the queue contains `[[5], [10], [20]]`. + +For each combination in the queue, the loop calculates the sum of the combination. +If the sum equals the desired total, it has found the combination. +Otherwise new combinations are added to the queue by adding each of the coins to the end of the combination: + +- less than the desired total, and: +- the total has _not_ yet been "seen" (the Set's [add][set-add] method returns `true` if a new item is being added and `false` if it is already in the Set) + +~~~~exercism/note +If the total has been "seen", there is no need to recheck the amounts because shorter combinations are always checked before longer combinations. +So, if the total is encountered again, we must have found a shorter combination to reach the same amount earlier. +~~~~ + +Continuing with the above example, the first combination contains just `5`. +When this is processed, the combinations `[5, 5]`, `[5, 10]` and `[5, 20]` would be added to the end of the queue and the queue becomes `[[10], [20],[5 ,5], [5, 10], [5, 20]]` for the next iteration. +Adding to the end of the queue ensures that the shorter combinations are checked first and allows the combination to simply be returned when the total is reached. + +The total can not be reached when there are no combinations in the queue. + +[set-add]: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Set.html#add(E) diff --git a/exercises/practice/change/.approaches/dynamic-programming-bottom-up/snippet.txt b/exercises/practice/change/.approaches/dynamic-programming-bottom-up/snippet.txt new file mode 100644 index 000000000..354ea1739 --- /dev/null +++ b/exercises/practice/change/.approaches/dynamic-programming-bottom-up/snippet.txt @@ -0,0 +1,8 @@ +while (!queue.isEmpty()) { + int total = next.stream().mapToInt(Integer::intValue).sum(); + if (total < grandTotal && reachableTotals.add(total)) { + for (Integer coin : currencyCoins) { + queue.add(append(next, coin)); + } + } +} \ No newline at end of file diff --git a/exercises/practice/change/.approaches/dynamic-programming/content.md b/exercises/practice/change/.approaches/dynamic-programming-top-down/content.md similarity index 98% rename from exercises/practice/change/.approaches/dynamic-programming/content.md rename to exercises/practice/change/.approaches/dynamic-programming-top-down/content.md index 640c58a47..06dbf9ba8 100644 --- a/exercises/practice/change/.approaches/dynamic-programming/content.md +++ b/exercises/practice/change/.approaches/dynamic-programming-top-down/content.md @@ -1,4 +1,4 @@ -# Dynamic Programming Approach +# Dynamic Programming - Top Down ```java import java.util.List; @@ -12,7 +12,7 @@ class ChangeCalculator { } List computeMostEfficientChange(int grandTotal) { - if (grandTotal < 0) + if (grandTotal < 0) throw new IllegalArgumentException("Negative totals are not allowed."); List> coinsUsed = new ArrayList<>(grandTotal + 1); @@ -64,5 +64,5 @@ It minimizes the number of coins needed by breaking down the problem into smalle ## Time and Space Complexity The time complexity of this approach is **O(n * m)**, where `n` is the `grandTotal` and `m` is the number of available coin denominations. This is because we iterate over all coin denominations for each amount up to `grandTotal`. - + The space complexity is **O(n)** due to the list `coinsUsed`, which stores the most efficient coin combination for each total up to `grandTotal`. diff --git a/exercises/practice/change/.approaches/dynamic-programming-top-down/snippet.txt b/exercises/practice/change/.approaches/dynamic-programming-top-down/snippet.txt new file mode 100644 index 000000000..d79e5e5f6 --- /dev/null +++ b/exercises/practice/change/.approaches/dynamic-programming-top-down/snippet.txt @@ -0,0 +1,8 @@ +for (int i = 1; i <= grandTotal; i++) { + for (int coin: currencyCoins) { + List currentCombination = coinsUsed.get(i - coin).add(coin); + if (bestCombination == null || currentCombination.size() < bestCombination.size()) + bestCombination = currentCombination; + } + coinsUsed.add(bestCombination); +} \ No newline at end of file diff --git a/exercises/practice/change/.approaches/dynamic-programming/snippet.txt b/exercises/practice/change/.approaches/dynamic-programming/snippet.txt deleted file mode 100644 index 25f90e6f5..000000000 --- a/exercises/practice/change/.approaches/dynamic-programming/snippet.txt +++ /dev/null @@ -1,8 +0,0 @@ -class ChangeCalculator { - private final List currencyCoins; - - ChangeCalculator(List currencyCoins) { - this.currencyCoins = currencyCoins; - } - // computeMostEfficientChange method -} diff --git a/exercises/practice/change/.approaches/introduction.md b/exercises/practice/change/.approaches/introduction.md index 672aae038..de92106d8 100644 --- a/exercises/practice/change/.approaches/introduction.md +++ b/exercises/practice/change/.approaches/introduction.md @@ -1,14 +1,64 @@ -# Introduction +# Introduction -There is an idiomatic approach to solving "Change." -You can use [dynamic programming][dynamic-programming] to calculate the minimum number of coins required for a given total. +There are a couple of different ways to solve "Change". +The [recursive approach][approach-recursive] uses recursion to find most efficient change for remaining amounts assuming a coin is included. +[Dynamic programming][dynamic-programming] calculates the solution starting from the required total ([the top][approach-dynamic-programming-top-down]) or from the amounts that can be covered by the coins ([the bottom][approach-dynamic-programming-bottom-up]). ## General guidance The key to solving "Change" is understanding that not all totals can be reached with the available coin denominations. The solution needs to figure out which totals can be achieved and how to combine the coins optimally. -## Approach: Dynamic Programming +## Approach: Recursive + +```java +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +class ChangeCalculator { + + private final List currencyCoins; + + ChangeCalculator(List currencyCoins) { + this.currencyCoins = List.copyOf(currencyCoins); + } + + List computeMostEfficientChange(int grandTotal) { + if (grandTotal < 0) { + throw new IllegalArgumentException("Negative totals are not allowed."); + } + if (grandTotal == 0) { + return Collections.emptyList(); + } + + return currencyCoins.stream().map(coin -> { + int remaining = grandTotal - coin; + if (remaining == 0) { + return List.of(coin); + } + + try { + List result = new ArrayList<>(computeMostEfficientChange(remaining)); + result.add(coin); + result.sort(Integer::compare); + return result; + } catch (IllegalArgumentException e) { + return Collections.emptyList(); + } + }) + .filter(c -> !c.isEmpty()) + .min(Comparator.comparingInt(List::size)) + .orElseThrow(() -> new IllegalArgumentException("The total " + grandTotal + " cannot be represented in the given currency.")); + + } +} +``` + +For a detailed look at the code and logic, see the full explanation in the [Recursive Approach][approach-recursive]. + +## Approach: Dynamic Programming - Top down ```java import java.util.List; @@ -22,7 +72,7 @@ class ChangeCalculator { } List computeMostEfficientChange(int grandTotal) { - if (grandTotal < 0) + if (grandTotal < 0) throw new IllegalArgumentException("Negative totals are not allowed."); List> coinsUsed = new ArrayList<>(grandTotal + 1); @@ -49,7 +99,64 @@ class ChangeCalculator { } ``` -For a detailed look at the code and logic, see the full explanation in the [Dynamic Programming Approach][approach-dynamic-programming]. +For a detailed look at the code and logic, see the full explanation in the [Dynamic Programming - Top Down][approach-dynamic-programming-top-down]. + +## Approach: Dyanmic Programming - Bottom up + +```java +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +class ChangeCalculator { + + private final List currencyCoins; + + ChangeCalculator(List currencyCoins) { + this.currencyCoins = List.copyOf(currencyCoins); + } + + List computeMostEfficientChange(int grandTotal) { + if (grandTotal < 0) { + throw new IllegalArgumentException("Negative totals are not allowed."); + } + if (grandTotal == 0) { + return Collections.emptyList(); + } + Set reachableTotals = new HashSet<>(); + ArrayDeque> queue = new ArrayDeque<>(currencyCoins.stream().map(List::of).toList()); + + while (!queue.isEmpty()) { + List next = queue.poll(); + int total = next.stream().mapToInt(Integer::intValue).sum(); + if (total == grandTotal) { + return next; + } + if (total < grandTotal && reachableTotals.add(total)) { + for (Integer coin : currencyCoins) { + List toCheck = new ArrayList<>(next); + toCheck.add(coin); + queue.offer(toCheck); + } + } + } + + throw new IllegalArgumentException("The total " + grandTotal + " cannot be represented in the given currency."); + } +} +``` + +For a detailed look at the code and logic, see the full explanation in the [Dynamic Programming - Bottom Up][approach-dynamic-programming-bottom-up]. + +## Which approach to use? + +The recursive approach is generally inefficient compared to either dynamic programming approach because the recursion requires recalculating the most efficient change for certain amounts. +Both dynamic programming approaches avoids this by building on the results computed previously at each step. -[approach-dynamic-programming]: https://exercism.org/tracks/java/exercises/change/approaches/dynamic-programming +[approach-recursive]: https://exercism.org/tracks/java/exercises/change/approaches/recursive +[approach-dynamic-programming-top-down]: https://exercism.org/tracks/java/exercises/change/approaches/dynamic-programming-top-down +[approach-dynamic-programming-bottom-up]: https://exercism.org/tracks/java/exercises/change/approaches/dynamic-programming-bottom-up [dynamic-programming]: https://en.wikipedia.org/wiki/Dynamic_programming diff --git a/exercises/practice/change/.approaches/recursive/content.md b/exercises/practice/change/.approaches/recursive/content.md new file mode 100644 index 000000000..25ef36dd4 --- /dev/null +++ b/exercises/practice/change/.approaches/recursive/content.md @@ -0,0 +1,56 @@ +# Recursive + +```java +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +class ChangeCalculator { + + private final List currencyCoins; + + ChangeCalculator(List currencyCoins) { + this.currencyCoins = List.copyOf(currencyCoins); + } + + List computeMostEfficientChange(int grandTotal) { + if (grandTotal < 0) { + throw new IllegalArgumentException("Negative totals are not allowed."); + } + if (grandTotal == 0) { + return Collections.emptyList(); + } + + return currencyCoins.stream().map(coin -> { + int remaining = grandTotal - coin; + if (remaining == 0) { + return List.of(coin); + } + + try { + List result = new ArrayList<>(computeMostEfficientChange(remaining)); + result.add(coin); + result.sort(Integer::compare); + return result; + } catch (IllegalArgumentException e) { + return Collections.emptyList(); + } + }) + .filter(c -> !c.isEmpty()) + .min(Comparator.comparingInt(List::size)) + .orElseThrow(() -> new IllegalArgumentException("The total " + grandTotal + " cannot be represented in the given currency.")); + + } +} +``` + +The recursive approach works by iterating through the available coins and recursively calling itself to find the most efficient change with it. +It starts by validating the `grandTotal` argument. +If valid, use a stream to go through the available coins and determines how much change is still required if the coin is included. +If no more change is required, the most efficient change consists simply of the coin on its own. +Otherwise it will recursively call itself to find the most efficient change for the remaining amount. +The recursive call is done in a `try-catch` block because the method throws an `IllegalArgumentionException` if the change can not be made. +An empty list is used to indicate when the change can not be made in the stream. +The stream filters out the empty list in the next step before finding the smallest list. +If the stream is empty, an `IllegalArgumentException` is thrown to indicate the change could not be made. diff --git a/exercises/practice/change/.approaches/recursive/snippet.txt b/exercises/practice/change/.approaches/recursive/snippet.txt new file mode 100644 index 000000000..64c6f9df8 --- /dev/null +++ b/exercises/practice/change/.approaches/recursive/snippet.txt @@ -0,0 +1,7 @@ +List computeMostEfficientChange(int grandTotal) { + if (remaining == 0) + return List.of(coin); + + return currencyCoins.stream().map(coin -> + new ArrayList<>(computeMostEfficientChange(remaining)).add(coin)); +} \ No newline at end of file diff --git a/exercises/practice/change/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/change/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/change/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/change/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/change/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/change/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/change/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/change/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/change/gradlew b/exercises/practice/change/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/change/gradlew +++ b/exercises/practice/change/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/change/gradlew.bat b/exercises/practice/change/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/change/gradlew.bat +++ b/exercises/practice/change/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/change/src/test/java/ChangeCalculatorTest.java b/exercises/practice/change/src/test/java/ChangeCalculatorTest.java index e685c28d0..b88c316d3 100644 --- a/exercises/practice/change/src/test/java/ChangeCalculatorTest.java +++ b/exercises/practice/change/src/test/java/ChangeCalculatorTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static java.util.Arrays.asList; @@ -8,7 +9,8 @@ public class ChangeCalculatorTest { @Test - public void testChangeFor1Cent() { + @DisplayName("change for 1 cent") + public void testChangeForOneCent() { ChangeCalculator changeCalculator = new ChangeCalculator(asList(1, 5, 10, 25)); assertThat(changeCalculator.computeMostEfficientChange(1)) @@ -17,6 +19,7 @@ public void testChangeFor1Cent() { @Disabled("Remove to run test") @Test + @DisplayName("single coin change") public void testChangeThatCanBeGivenInASingleCoin() { ChangeCalculator changeCalculator = new ChangeCalculator(asList(1, 5, 10, 25, 100)); @@ -26,6 +29,7 @@ public void testChangeThatCanBeGivenInASingleCoin() { @Disabled("Remove to run test") @Test + @DisplayName("multiple coin change") public void testChangeThatMustBeGivenInMultipleCoins() { ChangeCalculator changeCalculator = new ChangeCalculator(asList(1, 5, 10, 25, 100)); @@ -35,6 +39,7 @@ public void testChangeThatMustBeGivenInMultipleCoins() { @Disabled("Remove to run test") @Test + @DisplayName("change with Lilliputian Coins") public void testLilliputianCurrency() { ChangeCalculator changeCalculator = new ChangeCalculator(asList(1, 4, 15, 20, 50)); @@ -44,6 +49,7 @@ public void testLilliputianCurrency() { @Disabled("Remove to run test") @Test + @DisplayName("change with Lower Elbonia Coins") public void testLowerElbonianCurrency() { ChangeCalculator changeCalculator = new ChangeCalculator(asList(1, 5, 10, 21, 25)); @@ -53,6 +59,7 @@ public void testLowerElbonianCurrency() { @Disabled("Remove to run test") @Test + @DisplayName("large target values") public void testLargeAmountOfChange() { ChangeCalculator changeCalculator = new ChangeCalculator(asList(1, 2, 5, 10, 20, 50, 100)); @@ -62,6 +69,7 @@ public void testLargeAmountOfChange() { @Disabled("Remove to run test") @Test + @DisplayName("possible change without unit coins available") public void testPossibleChangeWithoutUnitCoinAvailable() { ChangeCalculator changeCalculator = new ChangeCalculator(asList(2, 5, 10, 20, 50)); @@ -71,6 +79,7 @@ public void testPossibleChangeWithoutUnitCoinAvailable() { @Disabled("Remove to run test") @Test + @DisplayName("another possible change without unit coins available") public void testAnotherPossibleChangeWithoutUnitCoinAvailable() { ChangeCalculator changeCalculator = new ChangeCalculator(asList(4, 5)); @@ -80,6 +89,7 @@ public void testAnotherPossibleChangeWithoutUnitCoinAvailable() { @Disabled("Remove to run test") @Test + @DisplayName("a greedy approach is not optimal") public void testAGreedyApproachIsNotOptimal() { ChangeCalculator changeCalculator = new ChangeCalculator(asList(1, 10, 11)); @@ -89,6 +99,7 @@ public void testAGreedyApproachIsNotOptimal() { @Disabled("Remove to run test") @Test + @DisplayName("no coins make 0 change") public void testZeroChange() { ChangeCalculator changeCalculator = new ChangeCalculator(asList(1, 5, 10, 21, 25)); @@ -98,6 +109,7 @@ public void testZeroChange() { @Disabled("Remove to run test") @Test + @DisplayName("error testing for change smaller than the smallest of coins") public void testChangeLessThanSmallestCoinInCurrencyCannotBeRepresented() { ChangeCalculator changeCalculator = new ChangeCalculator(asList(5, 10)); @@ -108,6 +120,7 @@ public void testChangeLessThanSmallestCoinInCurrencyCannotBeRepresented() { @Disabled("Remove to run test") @Test + @DisplayName("error if no combination can add up to target") public void testChangeLargerThanAllCoinsInCurrencyThatCannotBeRepresented() { ChangeCalculator changeCalculator = new ChangeCalculator(asList(5, 10)); @@ -118,6 +131,7 @@ public void testChangeLargerThanAllCoinsInCurrencyThatCannotBeRepresented() { @Disabled("Remove to run test") @Test + @DisplayName("cannot find negative change values") public void testNegativeChangeIsRejected() { ChangeCalculator changeCalculator = new ChangeCalculator(asList(1, 2, 5)); diff --git a/exercises/practice/circular-buffer/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/circular-buffer/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/circular-buffer/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/circular-buffer/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/circular-buffer/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/circular-buffer/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/circular-buffer/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/circular-buffer/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/circular-buffer/gradlew b/exercises/practice/circular-buffer/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/circular-buffer/gradlew +++ b/exercises/practice/circular-buffer/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/circular-buffer/gradlew.bat b/exercises/practice/circular-buffer/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/circular-buffer/gradlew.bat +++ b/exercises/practice/circular-buffer/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/circular-buffer/src/test/java/CircularBufferTest.java b/exercises/practice/circular-buffer/src/test/java/CircularBufferTest.java index 1596b3535..6ecbc1930 100644 --- a/exercises/practice/circular-buffer/src/test/java/CircularBufferTest.java +++ b/exercises/practice/circular-buffer/src/test/java/CircularBufferTest.java @@ -2,11 +2,13 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; public class CircularBufferTest { @Test + @DisplayName("reading empty buffer should fail") public void readingFromEmptyBufferShouldThrowException() { CircularBuffer buffer = new CircularBuffer<>(1); @@ -17,6 +19,7 @@ public void readingFromEmptyBufferShouldThrowException() { @Disabled("Remove to run test") @Test + @DisplayName("can read an item just written") public void canReadItemJustWritten() throws BufferIOException { CircularBuffer buffer = new CircularBuffer<>(1); @@ -26,6 +29,7 @@ public void canReadItemJustWritten() throws BufferIOException { @Disabled("Remove to run test") @Test + @DisplayName("each item may only be read once") public void canReadItemOnlyOnce() throws BufferIOException { CircularBuffer buffer = new CircularBuffer<>(1); @@ -39,6 +43,7 @@ public void canReadItemOnlyOnce() throws BufferIOException { @Disabled("Remove to run test") @Test + @DisplayName("items are read in the order they are written") public void readsItemsInOrderWritten() throws BufferIOException { CircularBuffer buffer = new CircularBuffer<>(2); @@ -50,6 +55,7 @@ public void readsItemsInOrderWritten() throws BufferIOException { @Disabled("Remove to run test") @Test + @DisplayName("full buffer can't be written to") public void fullBufferCantBeWrittenTo() throws BufferIOException { CircularBuffer buffer = new CircularBuffer<>(1); @@ -62,6 +68,7 @@ public void fullBufferCantBeWrittenTo() throws BufferIOException { @Disabled("Remove to run test") @Test + @DisplayName("a read frees up capacity for another write") public void readFreesUpSpaceForWrite() throws BufferIOException { CircularBuffer buffer = new CircularBuffer<>(1); @@ -73,6 +80,7 @@ public void readFreesUpSpaceForWrite() throws BufferIOException { @Disabled("Remove to run test") @Test + @DisplayName("read position is maintained even across multiple writes") public void maintainsReadPositionAcrossWrites() throws BufferIOException { CircularBuffer buffer = new CircularBuffer<>(3); @@ -86,6 +94,7 @@ public void maintainsReadPositionAcrossWrites() throws BufferIOException { @Disabled("Remove to run test") @Test + @DisplayName("items cleared out of buffer can't be read") public void cantReadClearedItems() throws BufferIOException { CircularBuffer buffer = new CircularBuffer<>(1); @@ -99,6 +108,7 @@ public void cantReadClearedItems() throws BufferIOException { @Disabled("Remove to run test") @Test + @DisplayName("clear frees up capacity for another write") public void clearFreesUpCapacity() throws BufferIOException { CircularBuffer buffer = new CircularBuffer<>(1); @@ -110,6 +120,7 @@ public void clearFreesUpCapacity() throws BufferIOException { @Disabled("Remove to run test") @Test + @DisplayName("clear does nothing on empty buffer") public void clearDoesNothingOnEmptyBuffer() throws BufferIOException { CircularBuffer buffer = new CircularBuffer<>(1); @@ -120,6 +131,7 @@ public void clearDoesNothingOnEmptyBuffer() throws BufferIOException { @Disabled("Remove to run test") @Test + @DisplayName("overwrite acts like write on non-full buffer") public void overwriteActsLikeWriteOnNonFullBuffer() throws BufferIOException { CircularBuffer buffer = new CircularBuffer<>(2); @@ -131,6 +143,7 @@ public void overwriteActsLikeWriteOnNonFullBuffer() throws BufferIOException { @Disabled("Remove to run test") @Test + @DisplayName("overwrite replaces the oldest item on full buffer") public void overwriteRemovesOldestElementOnFullBuffer() throws BufferIOException { CircularBuffer buffer = new CircularBuffer<>(2); @@ -143,6 +156,7 @@ public void overwriteRemovesOldestElementOnFullBuffer() throws BufferIOException @Disabled("Remove to run test") @Test + @DisplayName("overwrite replaces the oldest item remaining in buffer following a read") public void overwriteDoesntRemoveAnAlreadyReadElement() throws BufferIOException { CircularBuffer buffer = new CircularBuffer<>(3); @@ -159,6 +173,7 @@ public void overwriteDoesntRemoveAnAlreadyReadElement() throws BufferIOException @Disabled("Remove to run test") @Test + @DisplayName("initial clear does not affect wrapping around") public void initialClearDoesNotAffectWrappingAround() throws BufferIOException { CircularBuffer buffer = new CircularBuffer<>(2); diff --git a/exercises/practice/clock/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/clock/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/clock/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/clock/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/clock/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/clock/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/clock/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/clock/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/clock/gradlew b/exercises/practice/clock/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/clock/gradlew +++ b/exercises/practice/clock/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/clock/gradlew.bat b/exercises/practice/clock/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/clock/gradlew.bat +++ b/exercises/practice/clock/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/clock/src/test/java/ClockAddTest.java b/exercises/practice/clock/src/test/java/ClockAddTest.java index 34c22e06b..1a82b687e 100644 --- a/exercises/practice/clock/src/test/java/ClockAddTest.java +++ b/exercises/practice/clock/src/test/java/ClockAddTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -7,6 +8,7 @@ public class ClockAddTest { @Disabled("Remove to run test") @Test + @DisplayName("add minutes") public void addMinutes() { Clock clock = new Clock(10, 0); clock.add(3); @@ -16,6 +18,7 @@ public void addMinutes() { @Disabled("Remove to run test") @Test + @DisplayName("add no minutes") public void addNoMinutes() { Clock clock = new Clock(6, 41); clock.add(0); @@ -25,6 +28,7 @@ public void addNoMinutes() { @Disabled("Remove to run test") @Test + @DisplayName("add to next hour") public void addToNextHour() { Clock clock = new Clock(0, 45); clock.add(40); @@ -34,6 +38,7 @@ public void addToNextHour() { @Disabled("Remove to run test") @Test + @DisplayName("add more than one hour") public void addMoreThanOneHour() { Clock clock = new Clock(10, 0); clock.add(61); @@ -43,6 +48,7 @@ public void addMoreThanOneHour() { @Disabled("Remove to run test") @Test + @DisplayName("add more than two hours with carry") public void addMoreThanTwoHoursWithCarry() { Clock clock = new Clock(0, 45); clock.add(160); @@ -52,6 +58,7 @@ public void addMoreThanTwoHoursWithCarry() { @Disabled("Remove to run test") @Test + @DisplayName("add across midnight") public void addAcrossMidnight() { Clock clock = new Clock(23, 59); clock.add(2); @@ -61,6 +68,7 @@ public void addAcrossMidnight() { @Disabled("Remove to run test") @Test + @DisplayName("add more than one day (1500 min = 25 hrs)") public void addMoreThanOneDay() { Clock clock = new Clock(5, 32); clock.add(1500); @@ -70,6 +78,7 @@ public void addMoreThanOneDay() { @Disabled("Remove to run test") @Test + @DisplayName("add more than two days") public void addMoreThanTwoDays() { Clock clock = new Clock(1, 1); clock.add(3500); @@ -79,6 +88,7 @@ public void addMoreThanTwoDays() { @Disabled("Remove to run test") @Test + @DisplayName("subtract minutes") public void subtractMinutes() { Clock clock = new Clock(10, 3); clock.add(-3); @@ -88,6 +98,7 @@ public void subtractMinutes() { @Disabled("Remove to run test") @Test + @DisplayName("subtract to previous hour") public void subtractToPreviousHour() { Clock clock = new Clock(10, 3); clock.add(-30); @@ -97,6 +108,7 @@ public void subtractToPreviousHour() { @Disabled("Remove to run test") @Test + @DisplayName("subtract more than an hour") public void subtractMoreThanAnHour() { Clock clock = new Clock(10, 3); clock.add(-70); @@ -106,6 +118,7 @@ public void subtractMoreThanAnHour() { @Disabled("Remove to run test") @Test + @DisplayName("subtract across midnight") public void subtractAcrossMidnight() { Clock clock = new Clock(0, 3); clock.add(-4); @@ -115,6 +128,7 @@ public void subtractAcrossMidnight() { @Disabled("Remove to run test") @Test + @DisplayName("subtract more than two hours") public void subtractMoreThanTwoHours() { Clock clock = new Clock(0, 0); clock.add(-160); @@ -124,6 +138,7 @@ public void subtractMoreThanTwoHours() { @Disabled("Remove to run test") @Test + @DisplayName("subtract more than two hours with borrow") public void subtractMoreThanTwoHoursWithBorrow() { Clock clock = new Clock(6, 15); clock.add(-160); @@ -133,6 +148,7 @@ public void subtractMoreThanTwoHoursWithBorrow() { @Disabled("Remove to run test") @Test + @DisplayName("subtract more than one day (1500 min = 25 hrs)") public void subtractMoreThanOneDay() { Clock clock = new Clock(5, 32); clock.add(-1500); @@ -142,6 +158,7 @@ public void subtractMoreThanOneDay() { @Disabled("Remove to run test") @Test + @DisplayName("subtract more than two days") public void subtractMoreThanTwoDays() { Clock clock = new Clock(2, 20); clock.add(-3000); diff --git a/exercises/practice/clock/src/test/java/ClockCreationTest.java b/exercises/practice/clock/src/test/java/ClockCreationTest.java index 84f68d60d..674d1fee7 100644 --- a/exercises/practice/clock/src/test/java/ClockCreationTest.java +++ b/exercises/practice/clock/src/test/java/ClockCreationTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -6,120 +7,140 @@ public class ClockCreationTest { @Test + @DisplayName("on the hour") public void canPrintTimeOnTheHour() { assertThat(new Clock(8, 0).toString()).isEqualTo("08:00"); } @Disabled("Remove to run test") @Test + @DisplayName("past the hour") public void canPrintTimeWithMinutes() { assertThat(new Clock(11, 9).toString()).isEqualTo("11:09"); } @Disabled("Remove to run test") @Test + @DisplayName("midnight is zero hours") public void midnightPrintsAsZero() { assertThat(new Clock(24, 0).toString()).isEqualTo("00:00"); } @Disabled("Remove to run test") @Test + @DisplayName("hour rolls over") public void hourRollsOver() { assertThat(new Clock(25, 0).toString()).isEqualTo("01:00"); } @Disabled("Remove to run test") @Test + @DisplayName("hour rolls over continuously") public void hourRollsOverContinuously() { assertThat(new Clock(100, 0).toString()).isEqualTo("04:00"); } @Disabled("Remove to run test") @Test + @DisplayName("sixty minutes is next hour") public void sixtyMinutesIsNextHour() { assertThat(new Clock(1, 60).toString()).isEqualTo("02:00"); } @Disabled("Remove to run test") @Test + @DisplayName("minutes roll over") public void minutesRollOver() { assertThat(new Clock(0, 160).toString()).isEqualTo("02:40"); } @Disabled("Remove to run test") @Test + @DisplayName("minutes roll over continuously") public void minutesRollOverContinuously() { assertThat(new Clock(0, 1723).toString()).isEqualTo("04:43"); } @Disabled("Remove to run test") @Test + @DisplayName("hour and minutes roll over") public void hourAndMinutesRollOver() { assertThat(new Clock(25, 160).toString()).isEqualTo("03:40"); } @Disabled("Remove to run test") @Test + @DisplayName("hour and minutes roll over continuously") public void hourAndMinutesRollOverContinuously() { assertThat(new Clock(201, 3001).toString()).isEqualTo("11:01"); } @Disabled("Remove to run test") @Test + @DisplayName("hour and minutes roll over to exactly midnight") public void hourAndMinutesRollOverToExactlyMidnight() { assertThat(new Clock(72, 8640).toString()).isEqualTo("00:00"); } @Disabled("Remove to run test") @Test + @DisplayName("negative hour") public void negativeHour() { assertThat(new Clock(-1, 15).toString()).isEqualTo("23:15"); } @Disabled("Remove to run test") @Test + @DisplayName("negative hour rolls over") public void negativeHourRollsOver() { assertThat(new Clock(-25, 0).toString()).isEqualTo("23:00"); } @Disabled("Remove to run test") @Test + @DisplayName("negative hour rolls over continuously") public void negativeHourRollsOverContinuously() { assertThat(new Clock(-91, 0).toString()).isEqualTo("05:00"); } @Disabled("Remove to run test") @Test + @DisplayName("negative minutes") public void negativeMinutes() { assertThat(new Clock(1, -40).toString()).isEqualTo("00:20"); } @Disabled("Remove to run test") @Test + @DisplayName("negative minutes roll over") public void negativeMinutesRollOver() { assertThat(new Clock(1, -160).toString()).isEqualTo("22:20"); } @Disabled("Remove to run test") @Test + @DisplayName("negative minutes roll over continuously") public void negativeMinutesRollOverContinuously() { assertThat(new Clock(1, -4820).toString()).isEqualTo("16:40"); } @Disabled("Remove to run test") @Test + @DisplayName("negative sixty minutes is previous hour") public void negativeSixtyMinutesIsPreviousHour() { assertThat(new Clock(2, -60).toString()).isEqualTo("01:00"); } @Disabled("Remove to run test") @Test + @DisplayName("negative hour and minutes both roll over") public void negativeHourAndMinutesBothRollOver() { assertThat(new Clock(-25, -160).toString()).isEqualTo("20:20"); } @Disabled("Remove to run test") @Test + @DisplayName("negative hour and minutes both roll over continuously") public void negativeHourAndMinutesBothRollOverContinuously() { assertThat(new Clock(-121, -5810).toString()).isEqualTo("22:10"); } diff --git a/exercises/practice/clock/src/test/java/ClockEqualTest.java b/exercises/practice/clock/src/test/java/ClockEqualTest.java index 0ec041f71..d73687773 100644 --- a/exercises/practice/clock/src/test/java/ClockEqualTest.java +++ b/exercises/practice/clock/src/test/java/ClockEqualTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -7,6 +8,7 @@ public class ClockEqualTest { @Disabled("Remove to run test") @Test + @DisplayName("clocks with same time") public void clocksWithSameTimeAreEqual() { assertThat(new Clock(15, 37)) .isEqualTo(new Clock(15, 37)); @@ -14,6 +16,7 @@ public void clocksWithSameTimeAreEqual() { @Disabled("Remove to run test") @Test + @DisplayName("clocks a minute apart") public void clocksAMinuteApartAreNotEqual() { assertThat(new Clock(15, 36)) .isNotEqualTo(new Clock(15, 37)); @@ -21,6 +24,7 @@ public void clocksAMinuteApartAreNotEqual() { @Disabled("Remove to run test") @Test + @DisplayName("clocks an hour apart") public void clocksAnHourApartAreNotEqual() { assertThat(new Clock(14, 37)) .isNotEqualTo(new Clock(15, 37)); @@ -28,6 +32,7 @@ public void clocksAnHourApartAreNotEqual() { @Disabled("Remove to run test") @Test + @DisplayName("clocks with hour overflow") public void clocksWithHourOverflow() { assertThat(new Clock(34, 37)) .isEqualTo(new Clock(10, 37)); @@ -35,6 +40,7 @@ public void clocksWithHourOverflow() { @Disabled("Remove to run test") @Test + @DisplayName("clocks with hour overflow by several days") public void clocksWithHourOverflowBySeveralDays() { assertThat(new Clock(99, 11)) .isEqualTo(new Clock(3, 11)); @@ -42,6 +48,7 @@ public void clocksWithHourOverflowBySeveralDays() { @Disabled("Remove to run test") @Test + @DisplayName("clocks with negative hour") public void clocksWithNegateHour() { assertThat(new Clock(-2, 40)) .isEqualTo(new Clock(22, 40)); @@ -49,6 +56,7 @@ public void clocksWithNegateHour() { @Disabled("Remove to run test") @Test + @DisplayName("clocks with negative hour that wraps") public void clocksWithNegativeHourThatWraps() { assertThat(new Clock(-31, 3)) .isEqualTo(new Clock(17, 3)); @@ -56,6 +64,7 @@ public void clocksWithNegativeHourThatWraps() { @Disabled("Remove to run test") @Test + @DisplayName("clocks with negative hour that wraps multiple times") public void clocksWithNegativeHourThatWrapsMultipleTimes() { assertThat(new Clock(-83, 49)) .isEqualTo(new Clock(13, 49)); @@ -63,6 +72,7 @@ public void clocksWithNegativeHourThatWrapsMultipleTimes() { @Disabled("Remove to run test") @Test + @DisplayName("clocks with minute overflow") public void clocksWithMinuteOverflow() { assertThat(new Clock(0, 1441)) .isEqualTo(new Clock(0, 1)); @@ -70,6 +80,7 @@ public void clocksWithMinuteOverflow() { @Disabled("Remove to run test") @Test + @DisplayName("clocks with minute overflow by several days") public void clocksWithMinuteOverflowBySeveralDays() { assertThat(new Clock(2, 4322)) .isEqualTo(new Clock(2, 2)); @@ -77,6 +88,7 @@ public void clocksWithMinuteOverflowBySeveralDays() { @Disabled("Remove to run test") @Test + @DisplayName("clocks with negative minute") public void clocksWithNegativeMinutes() { assertThat(new Clock(3, -20)) .isEqualTo(new Clock(2, 40)); @@ -84,6 +96,7 @@ public void clocksWithNegativeMinutes() { @Disabled("Remove to run test") @Test + @DisplayName("clocks with negative minute that wraps") public void clocksWithNegativeMinutesThatWraps() { assertThat(new Clock(5, -1490)) .isEqualTo(new Clock(4, 10)); @@ -91,6 +104,7 @@ public void clocksWithNegativeMinutesThatWraps() { @Disabled("Remove to run test") @Test + @DisplayName("clocks with negative minute that wraps multiple times") public void clocksWithNegativeMinutesThatWrapsMultipleTimes() { assertThat(new Clock(6, -4305)) .isEqualTo(new Clock(6, 15)); @@ -98,6 +112,7 @@ public void clocksWithNegativeMinutesThatWrapsMultipleTimes() { @Disabled("Remove to run test") @Test + @DisplayName("clocks with negative hours and minutes") public void clocksWithNegativeHoursAndMinutes() { assertThat(new Clock(-12, -268)) .isEqualTo(new Clock(7, 32)); @@ -105,6 +120,7 @@ public void clocksWithNegativeHoursAndMinutes() { @Disabled("Remove to run test") @Test + @DisplayName("clocks with negative hours and minutes that wrap") public void clocksWithNegativeHoursAndMinutesThatWrap() { assertThat(new Clock(-54, -11513)) .isEqualTo(new Clock(18, 7)); @@ -112,6 +128,7 @@ public void clocksWithNegativeHoursAndMinutesThatWrap() { @Disabled("Remove to run test") @Test + @DisplayName("full clock and zeroed clock") public void clocksWithFullClockAndZeroedClockAreEqual() { assertThat(new Clock(24, 0)) .isEqualTo(new Clock(0, 0)); diff --git a/exercises/practice/collatz-conjecture/.approaches/introduction.md b/exercises/practice/collatz-conjecture/.approaches/introduction.md index 9965c8ffc..6717d2046 100644 --- a/exercises/practice/collatz-conjecture/.approaches/introduction.md +++ b/exercises/practice/collatz-conjecture/.approaches/introduction.md @@ -1,6 +1,6 @@ # Introduction -There are at east a couple of ways to solve Collatz Conjecture. +There are at least a couple of ways to solve Collatz Conjecture. One approach is to use a [`while`][while-loop] loop to iterate to the answer. Another approach is to use `IntStream.iterate()` to iterate to the answer. diff --git a/exercises/practice/collatz-conjecture/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/collatz-conjecture/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/collatz-conjecture/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/collatz-conjecture/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/collatz-conjecture/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/collatz-conjecture/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/collatz-conjecture/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/collatz-conjecture/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/collatz-conjecture/gradlew b/exercises/practice/collatz-conjecture/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/collatz-conjecture/gradlew +++ b/exercises/practice/collatz-conjecture/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/collatz-conjecture/gradlew.bat b/exercises/practice/collatz-conjecture/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/collatz-conjecture/gradlew.bat +++ b/exercises/practice/collatz-conjecture/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/collatz-conjecture/src/test/java/CollatzCalculatorTest.java b/exercises/practice/collatz-conjecture/src/test/java/CollatzCalculatorTest.java index 708d608dc..c095ffdf6 100644 --- a/exercises/practice/collatz-conjecture/src/test/java/CollatzCalculatorTest.java +++ b/exercises/practice/collatz-conjecture/src/test/java/CollatzCalculatorTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -9,30 +10,35 @@ public class CollatzCalculatorTest { private CollatzCalculator collatzCalculator = new CollatzCalculator(); @Test + @DisplayName("zero steps for one") public void testZeroStepsRequiredWhenStartingFrom1() { assertThat(collatzCalculator.computeStepCount(1)).isEqualTo(0); } @Disabled("Remove to run test") @Test + @DisplayName("divide if even") public void testCorrectNumberOfStepsWhenAllStepsAreDivisions() { assertThat(collatzCalculator.computeStepCount(16)).isEqualTo(4); } @Disabled("Remove to run test") @Test + @DisplayName("even and odd steps") public void testCorrectNumberOfStepsWhenBothStepTypesAreNeeded() { assertThat(collatzCalculator.computeStepCount(12)).isEqualTo(9); } @Disabled("Remove to run test") @Test + @DisplayName("large number of even and odd steps") public void testAVeryLargeInput() { assertThat(collatzCalculator.computeStepCount(1000000)).isEqualTo(152); } @Disabled("Remove to run test") @Test + @DisplayName("zero is an error") public void testZeroIsConsideredInvalidInput() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> collatzCalculator.computeStepCount(0)) @@ -41,6 +47,7 @@ public void testZeroIsConsideredInvalidInput() { @Disabled("Remove to run test") @Test + @DisplayName("negative value is an error") public void testNegativeIntegerIsConsideredInvalidInput() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> collatzCalculator.computeStepCount(-15)) diff --git a/exercises/practice/complex-numbers/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/complex-numbers/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/complex-numbers/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/complex-numbers/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/complex-numbers/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/complex-numbers/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/complex-numbers/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/complex-numbers/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/complex-numbers/gradlew b/exercises/practice/complex-numbers/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/complex-numbers/gradlew +++ b/exercises/practice/complex-numbers/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/complex-numbers/gradlew.bat b/exercises/practice/complex-numbers/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/complex-numbers/gradlew.bat +++ b/exercises/practice/complex-numbers/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/complex-numbers/src/test/java/ComplexNumberTest.java b/exercises/practice/complex-numbers/src/test/java/ComplexNumberTest.java index 1d479ea68..d9edc378a 100644 --- a/exercises/practice/complex-numbers/src/test/java/ComplexNumberTest.java +++ b/exercises/practice/complex-numbers/src/test/java/ComplexNumberTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -24,6 +25,7 @@ private void assertComplexNumbersEqual(ComplexNumber c1, ComplexNumber c2) { // Tests @Test + @DisplayName("Real part of a purely real number") public void testRealPartOfPurelyRealNumber() { double expected = 1.0; double actual = new ComplexNumber(1.0, 0).getReal(); @@ -32,6 +34,7 @@ public void testRealPartOfPurelyRealNumber() { @Disabled("Remove to run test") @Test + @DisplayName("Real part of a purely imaginary number") public void testRealPartOfPurelyImaginaryNumber() { double expected = 0.0; double actual = new ComplexNumber(0, 1.0).getReal(); @@ -40,6 +43,7 @@ public void testRealPartOfPurelyImaginaryNumber() { @Disabled("Remove to run test") @Test + @DisplayName("Real part of a number with real and imaginary part") public void testRealPartOfNumberWithRealAndImaginaryParts() { double expected = 1.0; double actual = new ComplexNumber(1.0, 2.0).getReal(); @@ -48,6 +52,7 @@ public void testRealPartOfNumberWithRealAndImaginaryParts() { @Disabled("Remove to run test") @Test + @DisplayName("Imaginary part of a purely real number") public void testImaginaryPartOfPurelyRealNumber() { double expected = 0.0; double actual = new ComplexNumber(1.0, 0).getImaginary(); @@ -56,6 +61,7 @@ public void testImaginaryPartOfPurelyRealNumber() { @Disabled("Remove to run test") @Test + @DisplayName("Imaginary part of a purely imaginary number") public void testImaginaryPartOfPurelyImaginaryNumber() { double expected = 1.0; double actual = new ComplexNumber(0, 1.0).getImaginary(); @@ -64,6 +70,7 @@ public void testImaginaryPartOfPurelyImaginaryNumber() { @Disabled("Remove to run test") @Test + @DisplayName("Imaginary part of a number with real and imaginary part") public void testImaginaryPartOfNumberWithRealAndImaginaryParts() { double expected = 2.0; double actual = new ComplexNumber(1.0, 2.0).getImaginary(); @@ -72,6 +79,7 @@ public void testImaginaryPartOfNumberWithRealAndImaginaryParts() { @Disabled("Remove to run test") @Test + @DisplayName("Imaginary unit") public void testImaginaryUnitExhibitsDefiningProperty() { ComplexNumber expected = new ComplexNumber(-1.0, 0); ComplexNumber actual = new ComplexNumber(0, 1.0).multiply(new ComplexNumber(0, 1.0)); @@ -80,6 +88,7 @@ public void testImaginaryUnitExhibitsDefiningProperty() { @Disabled("Remove to run test") @Test + @DisplayName("Add purely real numbers") public void testAdditionWithPurelyRealNumbers() { ComplexNumber expected = new ComplexNumber(3.0, 0); ComplexNumber actual = new ComplexNumber(1.0, 0).add(new ComplexNumber(2.0, 0)); @@ -88,6 +97,7 @@ public void testAdditionWithPurelyRealNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("Add purely imaginary numbers") public void testAdditionWithPurelyImaginaryNumbers() { ComplexNumber expected = new ComplexNumber(0, 3.0); ComplexNumber actual = new ComplexNumber(0, 1.0).add(new ComplexNumber(0, 2.0)); @@ -96,6 +106,7 @@ public void testAdditionWithPurelyImaginaryNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("Add numbers with real and imaginary part") public void testAdditionWithRealAndImaginaryParts() { ComplexNumber expected = new ComplexNumber(4.0, 6.0); ComplexNumber actual = new ComplexNumber(1.0, 2.0).add(new ComplexNumber(3.0, 4.0)); @@ -104,6 +115,7 @@ public void testAdditionWithRealAndImaginaryParts() { @Disabled("Remove to run test") @Test + @DisplayName("Subtract purely real numbers") public void testSubtractionWithPurelyRealNumbers() { ComplexNumber expected = new ComplexNumber(-1.0, 0.0); ComplexNumber actual = new ComplexNumber(1.0, 0.0).subtract(new ComplexNumber(2.0, 0.0)); @@ -112,6 +124,7 @@ public void testSubtractionWithPurelyRealNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("Subtract purely imaginary numbers") public void testSubtractionWithPurelyImaginaryNumbers() { ComplexNumber expected = new ComplexNumber(0, -1.0); ComplexNumber actual = new ComplexNumber(0, 1.0).subtract(new ComplexNumber(0, 2.0)); @@ -120,6 +133,7 @@ public void testSubtractionWithPurelyImaginaryNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("Subtract numbers with real and imaginary part") public void testSubtractionWithRealAndImaginaryParts() { ComplexNumber expected = new ComplexNumber(-2.0, -2.0); ComplexNumber actual = new ComplexNumber(1.0, 2.0).subtract(new ComplexNumber(3.0, 4.0)); @@ -128,6 +142,7 @@ public void testSubtractionWithRealAndImaginaryParts() { @Disabled("Remove to run test") @Test + @DisplayName("Multiply purely real numbers") public void testMultiplicationWithPurelyRealNumbers() { ComplexNumber expected = new ComplexNumber(2.0, 0); ComplexNumber actual = new ComplexNumber(1.0, 0).multiply(new ComplexNumber(2.0, 0)); @@ -136,6 +151,7 @@ public void testMultiplicationWithPurelyRealNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("Multiply purely imaginary numbers") public void testMultiplicationWithPurelyImaginaryNumbers() { ComplexNumber expected = new ComplexNumber(-2.0, 0); ComplexNumber actual = new ComplexNumber(0, 1.0).multiply(new ComplexNumber(0, 2.0)); @@ -144,6 +160,7 @@ public void testMultiplicationWithPurelyImaginaryNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("Multiply numbers with real and imaginary part") public void testMultiplicationWithRealAndImaginaryParts() { ComplexNumber expected = new ComplexNumber(-5.0, 10.0); ComplexNumber actual = new ComplexNumber(1.0, 2.0).multiply(new ComplexNumber(3.0, 4.0)); @@ -152,6 +169,7 @@ public void testMultiplicationWithRealAndImaginaryParts() { @Disabled("Remove to run test") @Test + @DisplayName("Divide purely real numbers") public void testDivisionWithPurelyRealNumbers() { ComplexNumber expected = new ComplexNumber(0.5, 0); ComplexNumber actual = new ComplexNumber(1.0, 0).divide(new ComplexNumber(2.0, 0)); @@ -160,6 +178,7 @@ public void testDivisionWithPurelyRealNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("Divide purely imaginary numbers") public void testDivisionWithPurelyImaginaryNumbers() { ComplexNumber expected = new ComplexNumber(0.5, 0); ComplexNumber actual = new ComplexNumber(0, 1.0).divide(new ComplexNumber(0, 2.0)); @@ -168,6 +187,7 @@ public void testDivisionWithPurelyImaginaryNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("Divide numbers with real and imaginary part") public void testDivisionWithRealAndImaginaryParts() { ComplexNumber expected = new ComplexNumber(0.44, 0.08); ComplexNumber actual = new ComplexNumber(1.0, 2.0).divide(new ComplexNumber(3.0, 4.0)); @@ -176,6 +196,7 @@ public void testDivisionWithRealAndImaginaryParts() { @Disabled("Remove to run test") @Test + @DisplayName("Absolute value of a positive purely real number") public void testAbsoluteValueOfPositivePurelyRealNumber() { double expected = 5.0; double actual = new ComplexNumber(5.0, 0).abs(); @@ -184,6 +205,7 @@ public void testAbsoluteValueOfPositivePurelyRealNumber() { @Disabled("Remove to run test") @Test + @DisplayName("Absolute value of a negative purely real number") public void testAbsoluteValueOfNegativePurelyRealNumber() { double expected = 5.0; double actual = new ComplexNumber(-5.0, 0).abs(); @@ -192,6 +214,7 @@ public void testAbsoluteValueOfNegativePurelyRealNumber() { @Disabled("Remove to run test") @Test + @DisplayName("Absolute value of a purely imaginary number with positive imaginary part") public void testAbsoluteValueOfPurelyImaginaryNumberWithPositiveImaginaryPart() { double expected = 5.0; double actual = new ComplexNumber(0, 5.0).abs(); @@ -200,6 +223,7 @@ public void testAbsoluteValueOfPurelyImaginaryNumberWithPositiveImaginaryPart() @Disabled("Remove to run test") @Test + @DisplayName("Absolute value of a purely imaginary number with negative imaginary part") public void testAbsoluteValueOfPurelyImaginaryNumberWithNegativeImaginaryPart() { double expected = 5.0; double actual = new ComplexNumber(0, -5.0).abs(); @@ -208,6 +232,7 @@ public void testAbsoluteValueOfPurelyImaginaryNumberWithNegativeImaginaryPart() @Disabled("Remove to run test") @Test + @DisplayName("Absolute value of a number with real and imaginary part") public void testAbsoluteValueOfNumberWithRealAndImaginaryParts() { double expected = 5.0; double actual = new ComplexNumber(3.0, 4.0).abs(); @@ -216,6 +241,7 @@ public void testAbsoluteValueOfNumberWithRealAndImaginaryParts() { @Disabled("Remove to run test") @Test + @DisplayName("Conjugate a purely real number") public void testConjugationOfPurelyRealNumber() { ComplexNumber expected = new ComplexNumber(5.0, 0); ComplexNumber actual = new ComplexNumber(5.0, 0).conjugate(); @@ -224,6 +250,7 @@ public void testConjugationOfPurelyRealNumber() { @Disabled("Remove to run test") @Test + @DisplayName("Conjugate a purely imaginary number") public void testConjugationOfPurelyImaginaryNumber() { ComplexNumber expected = new ComplexNumber(0, -5.0); ComplexNumber actual = new ComplexNumber(0, 5.0).conjugate(); @@ -232,6 +259,7 @@ public void testConjugationOfPurelyImaginaryNumber() { @Disabled("Remove to run test") @Test + @DisplayName("Conjugate a number with real and imaginary part") public void testConjugationOfNumberWithRealAndImaginaryParts() { ComplexNumber expected = new ComplexNumber(1.0, -1.0); ComplexNumber actual = new ComplexNumber(1.0, 1.0).conjugate(); @@ -240,6 +268,7 @@ public void testConjugationOfNumberWithRealAndImaginaryParts() { @Disabled("Remove to run test") @Test + @DisplayName("Euler's identity/formula") public void testExponentialOfPurelyImaginaryNumber() { ComplexNumber expected = new ComplexNumber(-1.0, 0); ComplexNumber actual = new ComplexNumber(0, Math.PI).exponentialOf(); @@ -248,6 +277,7 @@ public void testExponentialOfPurelyImaginaryNumber() { @Disabled("Remove to run test") @Test + @DisplayName("Exponential of 0") public void testExponentialOfZero() { ComplexNumber expected = new ComplexNumber(1.0, 0); ComplexNumber actual = new ComplexNumber(0, 0).exponentialOf(); @@ -256,6 +286,7 @@ public void testExponentialOfZero() { @Disabled("Remove to run test") @Test + @DisplayName("Exponential of a purely real number") public void testExponentialOfPurelyRealNumber() { ComplexNumber expected = new ComplexNumber(Math.E, 0); ComplexNumber actual = new ComplexNumber(1.0, 0).exponentialOf(); @@ -264,6 +295,7 @@ public void testExponentialOfPurelyRealNumber() { @Disabled("Remove to run test") @Test + @DisplayName("Exponential resulting in a number with real and imaginary part") public void testExponentialOfNumberWithRealAndImaginaryParts() { ComplexNumber expected = new ComplexNumber(1, 1); ComplexNumber actual = new ComplexNumber(Math.log(2.0) / 2, Math.PI / 4).exponentialOf(); diff --git a/exercises/practice/connect/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/connect/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/connect/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/connect/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/connect/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/connect/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/connect/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/connect/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/connect/gradlew b/exercises/practice/connect/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/connect/gradlew +++ b/exercises/practice/connect/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/connect/gradlew.bat b/exercises/practice/connect/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/connect/gradlew.bat +++ b/exercises/practice/connect/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/connect/src/test/java/ConnectTest.java b/exercises/practice/connect/src/test/java/ConnectTest.java index e6bfa17c8..0bc3a12a2 100644 --- a/exercises/practice/connect/src/test/java/ConnectTest.java +++ b/exercises/practice/connect/src/test/java/ConnectTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -6,6 +7,7 @@ public class ConnectTest { @Test + @DisplayName("an empty board has no winner") public void anEmptyBoardHasNoWinner() { //GIVEN @@ -27,6 +29,7 @@ public void anEmptyBoardHasNoWinner() { @Disabled("Remove to run test") @Test + @DisplayName("X can win on a 1x1 board") public void xCanWinOnA1x1Board() { //GIVEN @@ -45,6 +48,7 @@ public void xCanWinOnA1x1Board() { @Disabled("Remove to run test") @Test + @DisplayName("O can win on a 1x1 board") public void oCanWinOnA1x1Board() { //GIVEN @@ -63,6 +67,7 @@ public void oCanWinOnA1x1Board() { @Disabled("Remove to run test") @Test + @DisplayName("only edges does not make a winner") public void onlyEdgesDoesNotMakeAWinner() { //GIVEN @@ -84,6 +89,7 @@ public void onlyEdgesDoesNotMakeAWinner() { @Disabled("Remove to run test") @Test + @DisplayName("illegal diagonal does not make a winner") public void illegalDiagonalDoesNotMakeAWinner() { //GIVEN @@ -106,6 +112,7 @@ public void illegalDiagonalDoesNotMakeAWinner() { @Disabled("Remove to run test") @Test + @DisplayName("nobody wins crossing adjacent angles") public void nobodyWinsCrossingAdjacentAngles() { //GIVEN @@ -128,6 +135,7 @@ public void nobodyWinsCrossingAdjacentAngles() { @Disabled("Remove to run test") @Test + @DisplayName("X wins crossing from left to right") public void xWinsCrossingFromLeftToRight() { //GIVEN @@ -150,6 +158,7 @@ public void xWinsCrossingFromLeftToRight() { @Disabled("Remove to run test") @Test + @DisplayName("O wins crossing from top to bottom") public void oWinsCrossingFromTopToBottom() { //GIVEN @@ -172,6 +181,7 @@ public void oWinsCrossingFromTopToBottom() { @Disabled("Remove to run test") @Test + @DisplayName("X wins using a convoluted path") public void xWinsUsingConvolutedPath() { //GIVEN @@ -194,6 +204,7 @@ public void xWinsUsingConvolutedPath() { @Disabled("Remove to run test") @Test + @DisplayName("X wins using a spiral path") public void xWinsUsingASpiralPath() { //GIVEN diff --git a/exercises/practice/crypto-square/.meta/config.json b/exercises/practice/crypto-square/.meta/config.json index 83572a7b4..5f8c77cc7 100644 --- a/exercises/practice/crypto-square/.meta/config.json +++ b/exercises/practice/crypto-square/.meta/config.json @@ -21,6 +21,7 @@ "sshine", "stkent", "vdemeester", + "Xinri", "Zaldrick" ], "files": { diff --git a/exercises/practice/crypto-square/.meta/tests.toml b/exercises/practice/crypto-square/.meta/tests.toml index 085d142ea..94ef0819f 100644 --- a/exercises/practice/crypto-square/.meta/tests.toml +++ b/exercises/practice/crypto-square/.meta/tests.toml @@ -32,3 +32,8 @@ description = "8 character plaintext results in 3 chunks, the last one with a tr [fbcb0c6d-4c39-4a31-83f6-c473baa6af80] description = "54 character plaintext results in 7 chunks, the last two with trailing spaces" +include = false + +[33fd914e-fa44-445b-8f38-ff8fbc9fe6e6] +description = "54 character plaintext results in 8 chunks, the last two with trailing spaces" +reimplements = "fbcb0c6d-4c39-4a31-83f6-c473baa6af80" diff --git a/exercises/practice/crypto-square/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/crypto-square/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/crypto-square/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/crypto-square/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/crypto-square/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/crypto-square/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/crypto-square/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/crypto-square/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/crypto-square/gradlew b/exercises/practice/crypto-square/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/crypto-square/gradlew +++ b/exercises/practice/crypto-square/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/crypto-square/gradlew.bat b/exercises/practice/crypto-square/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/crypto-square/gradlew.bat +++ b/exercises/practice/crypto-square/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/crypto-square/src/test/java/CryptoSquareTest.java b/exercises/practice/crypto-square/src/test/java/CryptoSquareTest.java index 59eb4fc70..9b9225487 100644 --- a/exercises/practice/crypto-square/src/test/java/CryptoSquareTest.java +++ b/exercises/practice/crypto-square/src/test/java/CryptoSquareTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -6,6 +7,7 @@ public class CryptoSquareTest { @Test + @DisplayName("empty plaintext results in an empty ciphertext") public void emptyPlaintextResultsInEmptyCiphertext() { CryptoSquare cryptoSquare = new CryptoSquare(""); String expectedOutput = ""; @@ -15,6 +17,7 @@ public void emptyPlaintextResultsInEmptyCiphertext() { @Disabled("Remove to run test") @Test + @DisplayName("normalization results in empty plaintext") public void normalizationResultsInEmptyCiphertext() { CryptoSquare cryptoSquare = new CryptoSquare("... --- ..."); String expectedOutput = ""; @@ -24,6 +27,7 @@ public void normalizationResultsInEmptyCiphertext() { @Disabled("Remove to run test") @Test + @DisplayName("Lowercase") public void lettersAreLowerCasedDuringEncryption() { CryptoSquare cryptoSquare = new CryptoSquare("A"); String expectedOutput = "a"; @@ -33,6 +37,7 @@ public void lettersAreLowerCasedDuringEncryption() { @Disabled("Remove to run test") @Test + @DisplayName("Remove spaces") public void spacesAreRemovedDuringEncryption() { CryptoSquare cryptoSquare = new CryptoSquare(" b "); String expectedOutput = "b"; @@ -42,6 +47,7 @@ public void spacesAreRemovedDuringEncryption() { @Disabled("Remove to run test") @Test + @DisplayName("Remove punctuation") public void punctuationIsRemovedDuringEncryption() { CryptoSquare cryptoSquare = new CryptoSquare("@1,%!"); String expectedOutput = "1"; @@ -51,6 +57,7 @@ public void punctuationIsRemovedDuringEncryption() { @Disabled("Remove to run test") @Test + @DisplayName("9 character plaintext results in 3 chunks of 3 characters") public void nineCharacterPlaintextResultsInThreeChunksOfThreeCharacters() { CryptoSquare cryptoSquare = new CryptoSquare("This is fun!"); String expectedOutput = "tsf hiu isn"; @@ -60,6 +67,7 @@ public void nineCharacterPlaintextResultsInThreeChunksOfThreeCharacters() { @Disabled("Remove to run test") @Test + @DisplayName("8 character plaintext results in 3 chunks, the last one with a trailing space") public void eightCharacterPlaintextResultsInThreeChunksWithATrailingSpace() { CryptoSquare cryptoSquare = new CryptoSquare("Chill out."); String expectedOutput = "clu hlt io "; @@ -69,7 +77,8 @@ public void eightCharacterPlaintextResultsInThreeChunksWithATrailingSpace() { @Disabled("Remove to run test") @Test - public void fiftyFourCharacterPlaintextResultsInSevenChunksWithTrailingSpaces() { + @DisplayName("54 character plaintext results in 8 chunks, the last two with trailing spaces") + public void fiftyFourCharacterPlaintextResultsInEightChunksWithTrailingSpaces() { CryptoSquare cryptoSquare = new CryptoSquare("If man was meant to stay on the ground, god would have " + "given us roots."); String expectedOutput = "imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau "; diff --git a/exercises/practice/custom-set/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/custom-set/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/custom-set/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/custom-set/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/custom-set/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/custom-set/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/custom-set/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/custom-set/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/custom-set/gradlew b/exercises/practice/custom-set/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/custom-set/gradlew +++ b/exercises/practice/custom-set/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/custom-set/gradlew.bat b/exercises/practice/custom-set/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/custom-set/gradlew.bat +++ b/exercises/practice/custom-set/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/custom-set/src/test/java/CustomSetTest.java b/exercises/practice/custom-set/src/test/java/CustomSetTest.java index 4f32727c4..1032ecd50 100644 --- a/exercises/practice/custom-set/src/test/java/CustomSetTest.java +++ b/exercises/practice/custom-set/src/test/java/CustomSetTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.Arrays; @@ -9,6 +10,7 @@ public class CustomSetTest { @Test + @DisplayName("Returns true if the set contains no elements") public void setsWithNoElementsAreEmpty() { CustomSet customSet = new CustomSet<>(Collections.emptyList()); assertThat(customSet.isEmpty()).isTrue(); @@ -16,6 +18,7 @@ public void setsWithNoElementsAreEmpty() { @Disabled("Remove to run test") @Test + @DisplayName("sets with elements are not empty") public void setsWithElementsAreNotEmpty() { CustomSet customSet = new CustomSet<>(Collections.singletonList('1')); assertThat(customSet.isEmpty()).isFalse(); @@ -23,6 +26,7 @@ public void setsWithElementsAreNotEmpty() { @Disabled("Remove to run test") @Test + @DisplayName("nothing is contained in an empty set") public void nothingIsContainedInAnEmptySet() { CustomSet customSet = new CustomSet<>(Collections.emptyList()); assertThat(customSet.contains("1")).isFalse(); @@ -30,6 +34,7 @@ public void nothingIsContainedInAnEmptySet() { @Disabled("Remove to run test") @Test + @DisplayName("when the element is in the set") public void whenTheElementIsInTheSet() { CustomSet customSet = new CustomSet<>(Arrays.asList(1, 2, 3)); assertThat(customSet.contains(1)).isTrue(); @@ -37,6 +42,7 @@ public void whenTheElementIsInTheSet() { @Disabled("Remove to run test") @Test + @DisplayName("when the element is not in the set") public void whenTheElementIsNotInTheSet() { CustomSet customSet = new CustomSet<>(Arrays.asList('1', '2', '3')); assertThat(customSet.contains('4')).isFalse(); @@ -44,6 +50,7 @@ public void whenTheElementIsNotInTheSet() { @Disabled("Remove to run test") @Test + @DisplayName("empty set is a subset of another empty set") public void emptySetIsASubsetOfAnotherEmptySet() { CustomSet customSet = new CustomSet<>(Collections.emptyList()); CustomSet secondCustomSet = new CustomSet<>(Collections.emptyList()); @@ -52,6 +59,7 @@ public void emptySetIsASubsetOfAnotherEmptySet() { @Disabled("Remove to run test") @Test + @DisplayName("empty set is a subset of non-empty set") public void emptySetIsASubsetOfNonEmptySet() { CustomSet customSet = new CustomSet<>(Collections.singletonList(1)); CustomSet secondCustomSet = new CustomSet<>(Collections.emptyList()); @@ -60,6 +68,7 @@ public void emptySetIsASubsetOfNonEmptySet() { @Disabled("Remove to run test") @Test + @DisplayName("non-empty set is not a subset of empty set") public void nonEmptySetIsNotASubsetOfEmptySet() { CustomSet customSet = new CustomSet<>(Collections.emptyList()); CustomSet secondCustomSet = new CustomSet<>(Collections.singletonList('1')); @@ -68,6 +77,7 @@ public void nonEmptySetIsNotASubsetOfEmptySet() { @Disabled("Remove to run test") @Test + @DisplayName("set is a subset of set with exact same elements") public void setIsASubsetOfSetWithExactSameElements() { CustomSet customSet = new CustomSet<>(Arrays.asList("1", "2", "3")); CustomSet secondCustomSet = new CustomSet<>(Arrays.asList("1", "2", "3")); @@ -76,6 +86,7 @@ public void setIsASubsetOfSetWithExactSameElements() { @Disabled("Remove to run test") @Test + @DisplayName("set is a subset of larger set with same elements") public void setIsASubsetOfLargerSetWithSameElements() { CustomSet customSet = new CustomSet<>(Arrays.asList(4, 1, 2, 3)); CustomSet secondCustomSet = new CustomSet<>(Arrays.asList(1, 2, 3)); @@ -84,6 +95,7 @@ public void setIsASubsetOfLargerSetWithSameElements() { @Disabled("Remove to run test") @Test + @DisplayName("set is not a subset of set that does not contain its elements") public void setIsNotASubsetOfSetThatDoesNotContainItsElements() { CustomSet customSet = new CustomSet<>(Arrays.asList('4', '1', '3')); CustomSet secondCustomSet = new CustomSet<>(Arrays.asList('1', '2', '3')); @@ -92,6 +104,7 @@ public void setIsNotASubsetOfSetThatDoesNotContainItsElements() { @Disabled("Remove to run test") @Test + @DisplayName("the empty set is disjoint with itself") public void theEmptySetIsDisjointWithItself() { CustomSet customSet = new CustomSet<>(Collections.emptyList()); CustomSet secondCustomSet = new CustomSet<>(Collections.emptyList()); @@ -100,6 +113,7 @@ public void theEmptySetIsDisjointWithItself() { @Disabled("Remove to run test") @Test + @DisplayName("empty set is disjoint with non-empty set") public void emptySetIsDisjointWithNonEmptySet() { CustomSet customSet = new CustomSet<>(Collections.emptyList()); CustomSet secondCustomSet = new CustomSet<>(Collections.singletonList(1)); @@ -108,6 +122,7 @@ public void emptySetIsDisjointWithNonEmptySet() { @Disabled("Remove to run test") @Test + @DisplayName("non-empty set is disjoint with empty set") public void nonEmptySetIsDisjointWithEmptySet() { CustomSet customSet = new CustomSet<>(Collections.singletonList('1')); CustomSet secondCustomSet = new CustomSet<>(Collections.emptyList()); @@ -116,6 +131,7 @@ public void nonEmptySetIsDisjointWithEmptySet() { @Disabled("Remove to run test") @Test + @DisplayName("sets are not disjoint if they share an element") public void setsAreNotDisjointIfTheyShareAnElement() { CustomSet customSet = new CustomSet<>(Arrays.asList("1", "2")); CustomSet secondCustomSet = new CustomSet<>(Arrays.asList("2", "3")); @@ -124,6 +140,7 @@ public void setsAreNotDisjointIfTheyShareAnElement() { @Disabled("Remove to run test") @Test + @DisplayName("sets are disjoint if they share no elements") public void setsAreDisjointIfTheyShareNoElements() { CustomSet customSet = new CustomSet<>(Arrays.asList(1, 2)); CustomSet secondCustomSet = new CustomSet<>(Arrays.asList(3, 4)); @@ -132,6 +149,7 @@ public void setsAreDisjointIfTheyShareNoElements() { @Disabled("Remove to run test") @Test + @DisplayName("empty sets are equal") public void emptySetsAreEqual() { CustomSet customSet = new CustomSet<>(Collections.emptyList()); CustomSet secondCustomSet = new CustomSet<>(Collections.emptyList()); @@ -140,6 +158,7 @@ public void emptySetsAreEqual() { @Disabled("Remove to run test") @Test + @DisplayName("empty set is not equal to non-empty set") public void emptySetIsNotEqualToNonEmptySet() { CustomSet customSet = new CustomSet<>(Collections.emptyList()); CustomSet secondCustomSet = new CustomSet<>(Arrays.asList("1", "2", "3")); @@ -148,6 +167,7 @@ public void emptySetIsNotEqualToNonEmptySet() { @Disabled("Remove to run test") @Test + @DisplayName("non-empty set is not equal to empty set") public void nonEmptySetIsNotEqualToEmptySet() { CustomSet customSet = new CustomSet<>(Arrays.asList(1, 2, 3)); CustomSet secondCustomSet = new CustomSet<>(Collections.emptyList()); @@ -156,6 +176,7 @@ public void nonEmptySetIsNotEqualToEmptySet() { @Disabled("Remove to run test") @Test + @DisplayName("sets with the same elements are equal") public void setsWithTheSameElementsAreEqual() { CustomSet customSet = new CustomSet<>(Arrays.asList('1', '2')); CustomSet secondCustomSet = new CustomSet<>(Arrays.asList('2', '1')); @@ -164,6 +185,7 @@ public void setsWithTheSameElementsAreEqual() { @Disabled("Remove to run test") @Test + @DisplayName("sets with different elements are not equal") public void setsWithDifferentElementsAreNotEqual() { CustomSet customSet = new CustomSet<>(Arrays.asList("1", "2", "3")); CustomSet secondCustomSet = new CustomSet<>(Arrays.asList("1", "2", "4")); @@ -172,6 +194,7 @@ public void setsWithDifferentElementsAreNotEqual() { @Disabled("Remove to run test") @Test + @DisplayName("set is not equal to larger set with same elements") public void setIsNotEqualToLargerSetWithSameElements() { CustomSet customSet = new CustomSet<>(Arrays.asList("1", "2", "3")); CustomSet secondCustomSet = new CustomSet<>(Arrays.asList("1", "2", "3", "4")); @@ -180,6 +203,7 @@ public void setIsNotEqualToLargerSetWithSameElements() { @Disabled("Remove to run test") @Test + @DisplayName("set is equal to a set constructed from an array with duplicates") public void secondSetWithDuplicatesIsEqualToFirstSet() { CustomSet customSet = new CustomSet<>(Collections.singletonList("1")); CustomSet secondCustomSet = new CustomSet<>(Arrays.asList("1", "1")); @@ -188,6 +212,7 @@ public void secondSetWithDuplicatesIsEqualToFirstSet() { @Disabled("Remove to run test") @Test + @DisplayName("difference removes all duplicates in the first set") public void firstSetWithDuplicatesIsEqualToSecondSet() { CustomSet customSet = new CustomSet<>(Arrays.asList("1", "1")); CustomSet secondCustomSet = new CustomSet<>(Collections.singletonList("1")); @@ -196,6 +221,7 @@ public void firstSetWithDuplicatesIsEqualToSecondSet() { @Disabled("Remove to run test") @Test + @DisplayName("add to empty set") public void addToEmptySet() { int element = 3; CustomSet expected = new CustomSet<>(Collections.unmodifiableList(Collections.singletonList(element))); @@ -211,6 +237,7 @@ public void addToEmptySet() { @Disabled("Remove to run test") @Test + @DisplayName("add to non-empty set") public void addToNonEmptySet() { char element = '3'; CustomSet expected = new CustomSet<>(Collections.unmodifiableList( @@ -226,6 +253,7 @@ public void addToNonEmptySet() { @Disabled("Remove to run test") @Test + @DisplayName("adding an existing element does not change the set") public void addingAnExistingElementDoesNotChangeTheSet() { String element = "3"; CustomSet expected = new CustomSet<>(Collections.unmodifiableList(Arrays.asList("1", "2", "3"))); @@ -239,6 +267,7 @@ public void addingAnExistingElementDoesNotChangeTheSet() { @Disabled("Remove to run test") @Test + @DisplayName("intersection of two empty sets is an empty set") public void intersectionOfTwoEmptySetsIsAnEmptySet() { CustomSet actual = new CustomSet(Collections.emptyList()) .getIntersection(new CustomSet<>(Collections.emptyList())); @@ -249,6 +278,7 @@ public void intersectionOfTwoEmptySetsIsAnEmptySet() { @Disabled("Remove to run test") @Test + @DisplayName("intersection of an empty set and non-empty set is an empty set") public void intersectionOfAnEmptySetAndNonEmptySetIsAnEmptySet() { CustomSet actual = new CustomSet(Collections.emptyList()) .getIntersection(new CustomSet<>(Arrays.asList('3', '2', '5'))); @@ -259,6 +289,7 @@ public void intersectionOfAnEmptySetAndNonEmptySetIsAnEmptySet() { @Disabled("Remove to run test") @Test + @DisplayName("intersection of a non-empty set and an empty set is an empty set") public void intersectionOfANonEmptySetAndAnEmptySetIsAnEmptySet() { CustomSet actual = new CustomSet<>(Arrays.asList("1", "2", "3", "4")) .getIntersection(new CustomSet<>(Collections.emptyList())); @@ -270,6 +301,7 @@ public void intersectionOfANonEmptySetAndAnEmptySetIsAnEmptySet() { @Disabled("Remove to run test") @Test + @DisplayName("intersection of two sets with no shared elements is an empty set") public void intersectionOfTwoSetsWithNoSharedElementsIsAnEmptySet() { CustomSet actual = new CustomSet<>(Arrays.asList(1, 2, 3)) .getIntersection(new CustomSet<>(Arrays.asList(4, 5, 6))); @@ -280,6 +312,7 @@ public void intersectionOfTwoSetsWithNoSharedElementsIsAnEmptySet() { @Disabled("Remove to run test") @Test + @DisplayName("intersection of two sets with shared elements is a set of the shared elements") public void intersectionOfTwoSetsWithSharedElementsIsASetOfTheSharedElements() { CustomSet expected = new CustomSet<>(Collections.unmodifiableList(Arrays.asList('2', '3'))); CustomSet actual = new CustomSet<>(Arrays.asList('1', '2', '3', '4')) @@ -292,6 +325,7 @@ public void intersectionOfTwoSetsWithSharedElementsIsASetOfTheSharedElements() { @Disabled("Remove to run test") @Test + @DisplayName("difference of two empty sets is an empty set") public void differenceOfTwoEmptySetsIsAnEmptySet() { CustomSet actual = new CustomSet(Collections.emptyList()) .getDifference(new CustomSet<>(Collections.emptyList())); @@ -302,6 +336,7 @@ public void differenceOfTwoEmptySetsIsAnEmptySet() { @Disabled("Remove to run test") @Test + @DisplayName("difference of empty set and non-empty set is an empty set") public void differenceOfAnEmptySetAndNonEmptySetIsAnEmptySet() { CustomSet actual = new CustomSet(Collections.emptyList()) .getDifference(new CustomSet<>(Arrays.asList(3, 2, 5))); @@ -312,6 +347,7 @@ public void differenceOfAnEmptySetAndNonEmptySetIsAnEmptySet() { @Disabled("Remove to run test") @Test + @DisplayName("difference of a non-empty set and an empty set is the non-empty set") public void differenceOfANonEmptySetAndAnEmptySetIsTheNonEmptySet() { CustomSet expected = new CustomSet<>(Collections.unmodifiableList( Arrays.asList('1', '2', '3', '4'))); @@ -325,6 +361,7 @@ public void differenceOfANonEmptySetAndAnEmptySetIsTheNonEmptySet() { @Disabled("Remove to run test") @Test + @DisplayName("difference of two non-empty sets is a set of elements that are only in the first set") public void differenceOfTwoNonEmptySetsIsASetOfElementsThatAreOnlyInTheFirstSet() { CustomSet expected = new CustomSet<>(Collections.unmodifiableList(Arrays.asList("1", "3"))); CustomSet actual = new CustomSet<>(Arrays.asList("3", "2", "1")) @@ -338,6 +375,7 @@ public void differenceOfTwoNonEmptySetsIsASetOfElementsThatAreOnlyInTheFirstSet( @Disabled("Remove to run test") @Test + @DisplayName("union of empty sets is an empty set") public void unionOfTwoEmptySetsIsAnEmptySet() { CustomSet actual = new CustomSet(Collections.emptyList()) .getUnion(new CustomSet<>(Collections.emptyList())); @@ -348,6 +386,7 @@ public void unionOfTwoEmptySetsIsAnEmptySet() { @Disabled("Remove to run test") @Test + @DisplayName("union of an empty set and non-empty set is the non-empty set") public void unionOfAnEmptySetAndNonEmptySetIsTheNonEmptySet() { CustomSet expected = new CustomSet<>(Collections.unmodifiableList(Collections.singletonList('2'))); CustomSet actual = new CustomSet(Collections.emptyList()) @@ -360,6 +399,7 @@ public void unionOfAnEmptySetAndNonEmptySetIsTheNonEmptySet() { @Disabled("Remove to run test") @Test + @DisplayName("union of a non-empty set and empty set is the non-empty set") public void unionOfANonEmptySetAndAnEmptySetIsTheNonEmptySet() { CustomSet expected = new CustomSet<>(Collections.unmodifiableList(Arrays.asList("1", "3"))); CustomSet actual = new CustomSet<>(Arrays.asList("1", "3")) @@ -372,6 +412,7 @@ public void unionOfANonEmptySetAndAnEmptySetIsTheNonEmptySet() { @Disabled("Remove to run test") @Test + @DisplayName("union of non-empty sets contains all unique elements") public void unionOfTwoNonEmptySetsContainsAllUniqueElements() { CustomSet expected = new CustomSet<>(Collections.unmodifiableList(Arrays.asList(3, 2, 1))); CustomSet actual = new CustomSet<>(Arrays.asList(1, 3)) diff --git a/exercises/practice/darts/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/darts/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/darts/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/darts/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/darts/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/darts/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/darts/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/darts/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/darts/gradlew b/exercises/practice/darts/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/darts/gradlew +++ b/exercises/practice/darts/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/darts/gradlew.bat b/exercises/practice/darts/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/darts/gradlew.bat +++ b/exercises/practice/darts/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/darts/src/test/java/DartsTest.java b/exercises/practice/darts/src/test/java/DartsTest.java index f6e10baed..45376bfe4 100644 --- a/exercises/practice/darts/src/test/java/DartsTest.java +++ b/exercises/practice/darts/src/test/java/DartsTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -7,60 +8,70 @@ public class DartsTest { Darts darts = new Darts(); @Test + @DisplayName("Missed target") public void missedTarget() { assertThat(darts.score(-9, 9)).isEqualTo(0); } @Disabled("Remove to run test") @Test + @DisplayName("On the outer circle") public void onTheOuterCircle() { assertThat(darts.score(0, 10)).isEqualTo(1); } @Disabled("Remove to run test") @Test + @DisplayName("On the middle circle") public void onTheMiddleCircle() { assertThat(darts.score(-5, 0)).isEqualTo(5); } @Disabled("Remove to run test") @Test + @DisplayName("On the inner circle") public void onTheInnerCircle() { assertThat(darts.score(0, -1)).isEqualTo(10); } @Disabled("Remove to run test") @Test + @DisplayName("Exactly on center") public void exactlyOnCentre() { assertThat(darts.score(0, 0)).isEqualTo(10); } @Disabled("Remove to run test") @Test + @DisplayName("Near the center") public void nearTheCentre() { assertThat(darts.score(-0.1, -0.1)).isEqualTo(10); } @Disabled("Remove to run test") @Test + @DisplayName("Just within the inner circle") public void justWithinTheInnerCircle() { assertThat(darts.score(0.7, 0.7)).isEqualTo(10); } @Disabled("Remove to run test") @Test + @DisplayName("Just outside the inner circle") public void justOutsideTheInnerCircle() { assertThat(darts.score(0.8, -0.8)).isEqualTo(5); } @Disabled("Remove to run test") @Test + @DisplayName("Just within the middle circle") public void justWithinTheMiddleCircle() { assertThat(darts.score(-3.5, 3.5)).isEqualTo(5); } @Disabled("Remove to run test") @Test + @DisplayName("Just outside the middle circle") public void justOutsideTheMiddleCircle() { assertThat(darts.score(-3.6, -3.6)).isEqualTo(1); } @@ -68,18 +79,21 @@ public void justOutsideTheMiddleCircle() { @Disabled("Remove to run test") @Test + @DisplayName("Just within the outer circle") public void justWithinTheOuterCircle() { assertThat(darts.score(-7.0, 7.0)).isEqualTo(1); } @Disabled("Remove to run test") @Test + @DisplayName("Just outside the outer circle") public void justOutsideTheOuterCircle() { assertThat(darts.score(7.1, -7.1)).isEqualTo(0); } @Disabled("Remove to run test") @Test + @DisplayName("Asymmetric position between the inner and middle circles") public void asymmetricPositionBetweenTheInnerAndMiddleCircles() { assertThat(darts.score(0.5, -4)).isEqualTo(5); } diff --git a/exercises/practice/diamond/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/diamond/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/diamond/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/diamond/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/diamond/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/diamond/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/diamond/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/diamond/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/diamond/gradlew b/exercises/practice/diamond/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/diamond/gradlew +++ b/exercises/practice/diamond/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/diamond/gradlew.bat b/exercises/practice/diamond/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/diamond/gradlew.bat +++ b/exercises/practice/diamond/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/diamond/src/test/java/DiamondPrinterTest.java b/exercises/practice/diamond/src/test/java/DiamondPrinterTest.java index 3388aeefe..6608faeac 100644 --- a/exercises/practice/diamond/src/test/java/DiamondPrinterTest.java +++ b/exercises/practice/diamond/src/test/java/DiamondPrinterTest.java @@ -1,7 +1,8 @@ import static org.assertj.core.api.Assertions.assertThat; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; public class DiamondPrinterTest { @@ -14,6 +15,7 @@ public void setUp() { } @Test + @DisplayName("Degenerate case with a single 'A' row") public void testOneByOneDiamond() { assertThat(diamondPrinter.printToList('A')) .containsExactly("A"); @@ -21,6 +23,7 @@ public void testOneByOneDiamond() { @Disabled("Remove to run test") @Test + @DisplayName("Degenerate case with no row containing 3 distinct groups of spaces") public void testTwoByTwoDiamond() { assertThat(diamondPrinter.printToList('B')) .containsExactly( @@ -31,6 +34,7 @@ public void testTwoByTwoDiamond() { @Disabled("Remove to run test") @Test + @DisplayName("Smallest non-degenerate case with odd diamond side length") public void testThreeByThreeDiamond() { assertThat(diamondPrinter.printToList('C')) .containsExactly( @@ -43,6 +47,7 @@ public void testThreeByThreeDiamond() { @Disabled("Remove to run test") @Test + @DisplayName("Smallest non-degenerate case with even diamond side length") public void testFourByFourDiamond() { assertThat(diamondPrinter.printToList('D')) .containsExactly( @@ -57,6 +62,7 @@ public void testFourByFourDiamond() { @Disabled("Remove to run test") @Test + @DisplayName("Largest possible diamond") public void testFullDiamond() { assertThat(diamondPrinter.printToList('Z')) .containsExactly( diff --git a/exercises/practice/difference-of-squares/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/difference-of-squares/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/difference-of-squares/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/difference-of-squares/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/difference-of-squares/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/difference-of-squares/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/difference-of-squares/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/difference-of-squares/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/difference-of-squares/gradlew b/exercises/practice/difference-of-squares/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/difference-of-squares/gradlew +++ b/exercises/practice/difference-of-squares/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/difference-of-squares/gradlew.bat b/exercises/practice/difference-of-squares/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/difference-of-squares/gradlew.bat +++ b/exercises/practice/difference-of-squares/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/difference-of-squares/src/test/java/DifferenceOfSquaresCalculatorTest.java b/exercises/practice/difference-of-squares/src/test/java/DifferenceOfSquaresCalculatorTest.java index 3df042fdf..93d3af7a4 100644 --- a/exercises/practice/difference-of-squares/src/test/java/DifferenceOfSquaresCalculatorTest.java +++ b/exercises/practice/difference-of-squares/src/test/java/DifferenceOfSquaresCalculatorTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -14,6 +15,7 @@ public void setUp() { } @Test + @DisplayName("square of sum 1") public void testSquareOfSumUpToOne() { int expected = 1; int actual = calculator.computeSquareOfSumTo(1); @@ -22,6 +24,7 @@ public void testSquareOfSumUpToOne() { @Disabled("Remove to run test") @Test + @DisplayName("square of sum 5") public void testSquareOfSumUpToFive() { int expected = 225; int actual = calculator.computeSquareOfSumTo(5); @@ -30,6 +33,7 @@ public void testSquareOfSumUpToFive() { @Disabled("Remove to run test") @Test + @DisplayName("square of sum 100") public void testSquareOfSumUpToHundred() { int expected = 25502500; int actual = calculator.computeSquareOfSumTo(100); @@ -38,6 +42,7 @@ public void testSquareOfSumUpToHundred() { @Disabled("Remove to run test") @Test + @DisplayName("sum of squares 1") public void testSumOfSquaresUpToOne() { int expected = 1; int actual = calculator.computeSumOfSquaresTo(1); @@ -46,6 +51,7 @@ public void testSumOfSquaresUpToOne() { @Disabled("Remove to run test") @Test + @DisplayName("sum of squares 5") public void testSumOfSquaresUpToFive() { int expected = 55; int actual = calculator.computeSumOfSquaresTo(5); @@ -54,6 +60,7 @@ public void testSumOfSquaresUpToFive() { @Disabled("Remove to run test") @Test + @DisplayName("sum of squares 100") public void testSumOfSquaresUpToHundred() { int expected = 338350; int actual = calculator.computeSumOfSquaresTo(100); @@ -62,6 +69,7 @@ public void testSumOfSquaresUpToHundred() { @Disabled("Remove to run test") @Test + @DisplayName("difference of squares 1") public void testDifferenceOfSquaresUpToOne() { int expected = 0; int actual = calculator.computeDifferenceOfSquares(1); @@ -70,6 +78,7 @@ public void testDifferenceOfSquaresUpToOne() { @Disabled("Remove to run test") @Test + @DisplayName("difference of squares 5") public void testDifferenceOfSquaresUpToFive() { int expected = 170; int actual = calculator.computeDifferenceOfSquares(5); @@ -78,6 +87,7 @@ public void testDifferenceOfSquaresUpToFive() { @Disabled("Remove to run test") @Test + @DisplayName("difference of squares 100") public void testDifferenceOfSquaresUpToHundred() { int expected = 25164150; int actual = calculator.computeDifferenceOfSquares(100); diff --git a/exercises/practice/dnd-character/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/dnd-character/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/dnd-character/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/dnd-character/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/dnd-character/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/dnd-character/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/dnd-character/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/dnd-character/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/dnd-character/gradlew b/exercises/practice/dnd-character/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/dnd-character/gradlew +++ b/exercises/practice/dnd-character/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/dnd-character/gradlew.bat b/exercises/practice/dnd-character/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/dnd-character/gradlew.bat +++ b/exercises/practice/dnd-character/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/dnd-character/src/test/java/DnDCharacterTest.java b/exercises/practice/dnd-character/src/test/java/DnDCharacterTest.java index 1c9afc921..c54ad52ac 100644 --- a/exercises/practice/dnd-character/src/test/java/DnDCharacterTest.java +++ b/exercises/practice/dnd-character/src/test/java/DnDCharacterTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.List; @@ -10,150 +11,175 @@ public class DnDCharacterTest { private DnDCharacter dndCharacter = new DnDCharacter(); @Test + @DisplayName("ability modifier for score 3 is -4") public void testAbilityModifierForScore3IsNegative4() { assertThat(dndCharacter.modifier(3)).isEqualTo(-4); } @Disabled("Remove to run test") @Test + @DisplayName("ability modifier for score 4 is -3") public void testAbilityModifierForScore4IsNegative3() { assertThat(dndCharacter.modifier(4)).isEqualTo(-3); } @Disabled("Remove to run test") @Test + @DisplayName("ability modifier for score 5 is -3") public void testAbilityModifierForScore5IsNegative3() { assertThat(dndCharacter.modifier(5)).isEqualTo(-3); } @Disabled("Remove to run test") @Test + @DisplayName("ability modifier for score 6 is -2") public void testAbilityModifierForScore6IsNegative2() { assertThat(dndCharacter.modifier(6)).isEqualTo(-2); } @Disabled("Remove to run test") @Test + @DisplayName("ability modifier for score 7 is -2") public void testAbilityModifierForScore7IsNegative2() { assertThat(dndCharacter.modifier(7)).isEqualTo(-2); } @Disabled("Remove to run test") @Test + @DisplayName("ability modifier for score 8 is -1") public void testAbilityModifierForScore8IsNegative1() { assertThat(dndCharacter.modifier(8)).isEqualTo(-1); } @Disabled("Remove to run test") @Test + @DisplayName("ability modifier for score 9 is -1") public void testAbilityModifierForScore9IsNegative1() { assertThat(dndCharacter.modifier(9)).isEqualTo(-1); } @Disabled("Remove to run test") @Test + @DisplayName("ability modifier for score 10 is 0") public void testAbilityModifierForScore10Is0() { assertThat(dndCharacter.modifier(10)).isEqualTo(0); } @Disabled("Remove to run test") @Test + @DisplayName("ability modifier for score 11 is 0") public void testAbilityModifierForScore11Is0() { assertThat(dndCharacter.modifier(11)).isEqualTo(0); } @Disabled("Remove to run test") @Test + @DisplayName("ability modifier for score 12 is +1") public void testAbilityModifierForScore12Is1() { assertThat(dndCharacter.modifier(12)).isEqualTo(1); } @Disabled("Remove to run test") @Test + @DisplayName("ability modifier for score 13 is +1") public void testAbilityModifierForScore13Is1() { assertThat(dndCharacter.modifier(13)).isEqualTo(1); } @Disabled("Remove to run test") @Test + @DisplayName("ability modifier for score 14 is +2") public void testAbilityModifierForScore14Is2() { assertThat(dndCharacter.modifier(14)).isEqualTo(2); } @Disabled("Remove to run test") @Test + @DisplayName("ability modifier for score 15 is +2") public void testAbilityModifierForScore15Is2() { assertThat(dndCharacter.modifier(15)).isEqualTo(2); } @Disabled("Remove to run test") @Test + @DisplayName("ability modifier for score 16 is +3") public void testAbilityModifierForScore16Is3() { assertThat(dndCharacter.modifier(16)).isEqualTo(3); } @Disabled("Remove to run test") @Test + @DisplayName("ability modifier for score 17 is +3") public void testAbilityModifierForScore17Is3() { assertThat(dndCharacter.modifier(17)).isEqualTo(3); } @Disabled("Remove to run test") @Test + @DisplayName("ability modifier for score 18 is +4") public void testAbilityModifierForScore18Is4() { assertThat(dndCharacter.modifier(18)).isEqualTo(4); } @Disabled("Remove to run test") @Test + @DisplayName("Rolling uses 4 dice") public void test4DiceWereUsedForRollingScores() { assertThat(dndCharacter.rollDice().size()).isEqualTo(4); } @Disabled("Remove to run test") @Test + @DisplayName("Dice values are between 1 and 6 inclusive") public void testDiceValuesBetween1And6() { assertThat(dndCharacter.rollDice()).allMatch(d -> d >= 1 && d <= 6); } @Disabled("Remove to run test") @Test + @DisplayName("Ability uses 3 largest numbers from scores in descending order") public void testAbilityCalculationsUses3LargestNumbersFromScoresInDescendingOrder() { assertThat(dndCharacter.ability(List.of(4, 3, 2, 1))).isEqualTo(9); } @Disabled("Remove to run test") @Test + @DisplayName("Ability uses 3 largest numbers from scores in ascending order") public void testAbilityCalculationsUses3LargestNumbersFromFromScoresInAscendingOrder() { assertThat(dndCharacter.ability(List.of(1, 2, 3, 4))).isEqualTo(9); } @Disabled("Remove to run test") @Test + @DisplayName("Ability uses 3 largest numbers from scores in random order") public void testAbilityCalculationsUses3LargestNumbersFromScoresInRandomOrder() { assertThat(dndCharacter.ability(List.of(2, 4, 3, 1))).isEqualTo(9); } @Disabled("Remove to run test") @Test + @DisplayName("Ability with all lowest equal numbers yields 3") public void testAbilityCalculationsWithLowestEqualNumbers() { assertThat(dndCharacter.ability(List.of(1, 1, 1, 1))).isEqualTo(3); } @Disabled("Remove to run test") @Test + @DisplayName("Ability with all highest equal numbers yields 18") public void testAbilityCalculationsWithHighestEqualNumbers() { assertThat(dndCharacter.ability(List.of(6, 6, 6, 6))).isEqualTo(18); } @Disabled("Remove to run test") @Test + @DisplayName("Ability calculation with two lowest numbers") public void testAbilityCalculationsWithTwoLowestNumbers() { assertThat(dndCharacter.ability(List.of(3, 5, 3, 4))).isEqualTo(12); } @Disabled("Remove to run test") @Test + @DisplayName("Ability calculation does not mutate input scores") public void testAbilityCalculationDoesNotChangeInputScores() { List scores = List.of(1, 2, 3, 4); dndCharacter.ability(scores); @@ -164,6 +190,7 @@ public void testAbilityCalculationDoesNotChangeInputScores() { @Disabled("Remove to run test") @Test + @DisplayName("random character is valid") public void testRandomCharacterIsValid() { for (int i = 0; i < 1000; i++) { DnDCharacter character = new DnDCharacter(); @@ -179,6 +206,7 @@ public void testRandomCharacterIsValid() { @Disabled("Remove to run test") @Test + @DisplayName("each ability is only calculated once") public void testEachAbilityIsOnlyCalculatedOnce() { assertThat(dndCharacter.getStrength()).isEqualTo(dndCharacter.getStrength()); assertThat(dndCharacter.getDexterity()).isEqualTo(dndCharacter.getDexterity()); @@ -190,6 +218,7 @@ public void testEachAbilityIsOnlyCalculatedOnce() { @Disabled("Remove to run test") @Test + @DisplayName("Each randomly created character should be unique in attributes") public void testUniqueCharacterIsCreated() { DnDCharacter uniqueDnDCharacter = new DnDCharacter(); for (int i = 0; i < 1000; i++) { diff --git a/exercises/practice/dominoes/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/dominoes/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/dominoes/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/dominoes/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/dominoes/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/dominoes/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/dominoes/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/dominoes/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/dominoes/gradlew b/exercises/practice/dominoes/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/dominoes/gradlew +++ b/exercises/practice/dominoes/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/dominoes/gradlew.bat b/exercises/practice/dominoes/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/dominoes/gradlew.bat +++ b/exercises/practice/dominoes/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/dominoes/src/test/java/DominoesTest.java b/exercises/practice/dominoes/src/test/java/DominoesTest.java index 76f2e4931..d1570eb77 100644 --- a/exercises/practice/dominoes/src/test/java/DominoesTest.java +++ b/exercises/practice/dominoes/src/test/java/DominoesTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.ArrayList; @@ -12,6 +13,7 @@ public class DominoesTest { @Test + @DisplayName("empty input = empty output") public void emtpyInputEmptyOutputTest() throws ChainNotFoundException { Dominoes dominoes = new Dominoes(); @@ -24,6 +26,7 @@ public void emtpyInputEmptyOutputTest() throws ChainNotFoundException { @Disabled("Remove to run test") @Test + @DisplayName("singleton input = singleton output") public void singletonInputSingletonOutput() throws ChainNotFoundException { Dominoes dominoes = new Dominoes(); @@ -37,6 +40,7 @@ public void singletonInputSingletonOutput() throws ChainNotFoundException { @Disabled("Remove to run test") @Test + @DisplayName("singleton that can't be chained") public void singletonCantBeChainedTest() { Dominoes dominoes = new Dominoes(); @@ -50,6 +54,7 @@ public void singletonCantBeChainedTest() { @Disabled("Remove to run test") @Test + @DisplayName("three elements") public void threeElementsTest() throws ChainNotFoundException { Dominoes dominoes = new Dominoes(); @@ -63,6 +68,7 @@ public void threeElementsTest() throws ChainNotFoundException { @Disabled("Remove to run test") @Test + @DisplayName("can reverse dominoes") public void canReverseDominoesTest() throws ChainNotFoundException { Dominoes dominoes = new Dominoes(); @@ -76,6 +82,7 @@ public void canReverseDominoesTest() throws ChainNotFoundException { @Disabled("Remove to run test") @Test + @DisplayName("can't be chained") public void cantBeChainedTest() { Dominoes dominoes = new Dominoes(); @@ -89,6 +96,7 @@ public void cantBeChainedTest() { @Disabled("Remove to run test") @Test + @DisplayName("disconnected - simple") public void disconnectedSimpleTest() { Dominoes dominoes = new Dominoes(); @@ -102,6 +110,7 @@ public void disconnectedSimpleTest() { @Disabled("Remove to run test") @Test + @DisplayName("disconnected - double loop") public void disconnectedDoubleLoopTest() { Dominoes dominoes = new Dominoes(); @@ -115,6 +124,7 @@ public void disconnectedDoubleLoopTest() { @Disabled("Remove to run test") @Test + @DisplayName("disconnected - single isolated") public void disconnectedSingleIsolatedTest() { Dominoes dominoes = new Dominoes(); @@ -128,6 +138,7 @@ public void disconnectedSingleIsolatedTest() { @Disabled("Remove to run test") @Test + @DisplayName("need backtrack") public void needBacktrackTest() throws ChainNotFoundException { Dominoes dominoes = new Dominoes(); @@ -142,6 +153,7 @@ public void needBacktrackTest() throws ChainNotFoundException { @Disabled("Remove to run test") @Test + @DisplayName("separate loops") public void separateLoopsTest() throws ChainNotFoundException { Dominoes dominoes = new Dominoes(); @@ -156,6 +168,7 @@ public void separateLoopsTest() throws ChainNotFoundException { @Disabled("Remove to run test") @Test + @DisplayName("nine elements") public void nineElementsTest() throws ChainNotFoundException { Dominoes dominoes = new Dominoes(); Domino[] dominoesArray = {new Domino(1, 2), new Domino(5, 3), new Domino(3, 1), @@ -170,6 +183,7 @@ public void nineElementsTest() throws ChainNotFoundException { @Disabled("Remove to run test") @Test + @DisplayName("separate three-domino loops") public void separateThreeDominoLoopsTest() { Dominoes dominoes = new Dominoes(); diff --git a/exercises/practice/dot-dsl/.docs/instructions.md b/exercises/practice/dot-dsl/.docs/instructions.md index b3a63996d..5e65ebef9 100644 --- a/exercises/practice/dot-dsl/.docs/instructions.md +++ b/exercises/practice/dot-dsl/.docs/instructions.md @@ -22,7 +22,7 @@ Write a Domain Specific Language similar to the Graphviz dot language. Our DSL is similar to the Graphviz dot language in that our DSL will be used to create graph data structures. However, unlike the DOT Language, our DSL will be an internal DSL for use only in our language. -More information about the difference between internal and external DSLs can be found [here][fowler-dsl]. +[Learn more about the difference between internal and external DSLs][fowler-dsl]. [dsl]: https://en.wikipedia.org/wiki/Domain-specific_language [dot-language]: https://en.wikipedia.org/wiki/DOT_(graph_description_language) diff --git a/exercises/practice/dot-dsl/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/dot-dsl/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/dot-dsl/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/dot-dsl/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/dot-dsl/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/dot-dsl/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/dot-dsl/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/dot-dsl/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/dot-dsl/gradlew b/exercises/practice/dot-dsl/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/dot-dsl/gradlew +++ b/exercises/practice/dot-dsl/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/dot-dsl/gradlew.bat b/exercises/practice/dot-dsl/gradlew.bat index 93e3f59f1..c4bdd3ab8 100644 --- a/exercises/practice/dot-dsl/gradlew.bat +++ b/exercises/practice/dot-dsl/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -43,11 +45,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,22 +59,21 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/eliuds-eggs/.docs/introduction.md b/exercises/practice/eliuds-eggs/.docs/introduction.md index 819897480..2b2e5c43d 100644 --- a/exercises/practice/eliuds-eggs/.docs/introduction.md +++ b/exercises/practice/eliuds-eggs/.docs/introduction.md @@ -58,7 +58,7 @@ The position information encoding is calculated as follows: ### Decimal number on the display -16 +8 ### Actual eggs in the coop diff --git a/exercises/practice/eliuds-eggs/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/eliuds-eggs/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/eliuds-eggs/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/eliuds-eggs/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/eliuds-eggs/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/eliuds-eggs/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/eliuds-eggs/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/eliuds-eggs/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/eliuds-eggs/gradlew b/exercises/practice/eliuds-eggs/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/eliuds-eggs/gradlew +++ b/exercises/practice/eliuds-eggs/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/eliuds-eggs/gradlew.bat b/exercises/practice/eliuds-eggs/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/eliuds-eggs/gradlew.bat +++ b/exercises/practice/eliuds-eggs/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/error-handling/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/error-handling/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/error-handling/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/error-handling/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/error-handling/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/error-handling/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/error-handling/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/error-handling/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/error-handling/gradlew b/exercises/practice/error-handling/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/error-handling/gradlew +++ b/exercises/practice/error-handling/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/error-handling/gradlew.bat b/exercises/practice/error-handling/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/error-handling/gradlew.bat +++ b/exercises/practice/error-handling/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/error-handling/src/test/java/ErrorHandlingTest.java b/exercises/practice/error-handling/src/test/java/ErrorHandlingTest.java index c7864c7ad..7459b687f 100644 --- a/exercises/practice/error-handling/src/test/java/ErrorHandlingTest.java +++ b/exercises/practice/error-handling/src/test/java/ErrorHandlingTest.java @@ -1,16 +1,18 @@ -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; - import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.Optional; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + public class ErrorHandlingTest { private ErrorHandling errorHandling = new ErrorHandling(); @Test + @DisplayName("Throws IllegalArgumentException") public void testThrowIllegalArgumentException() { assertThatExceptionOfType(Exception.class) .isThrownBy(() -> errorHandling.handleErrorByThrowingIllegalArgumentException()); @@ -18,6 +20,7 @@ public void testThrowIllegalArgumentException() { @Disabled("Remove to run test") @Test + @DisplayName("Throws IllegalArgumentException with provided detail message") public void testThrowIllegalArgumentExceptionWithDetailMessage() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> errorHandling.handleErrorByThrowingIllegalArgumentExceptionWithDetailMessage( @@ -27,6 +30,7 @@ public void testThrowIllegalArgumentExceptionWithDetailMessage() { @Disabled("Remove to run test") @Test + @DisplayName("Throws any checked exception") public void testThrowAnyCheckedException() { assertThatExceptionOfType(Exception.class) .isThrownBy(() -> errorHandling.handleErrorByThrowingAnyCheckedException()) @@ -35,6 +39,7 @@ public void testThrowAnyCheckedException() { @Disabled("Remove to run test") @Test + @DisplayName("Throws any checked exception with provided detail message") public void testThrowAnyCheckedExceptionWithDetailMessage() { assertThatExceptionOfType(Exception.class) .isThrownBy(() -> errorHandling.handleErrorByThrowingAnyCheckedExceptionWithDetailMessage( @@ -45,6 +50,7 @@ public void testThrowAnyCheckedExceptionWithDetailMessage() { @Disabled("Remove to run test") @Test + @DisplayName("Throws any unchecked exception") public void testThrowAnyUncheckedException() { assertThatExceptionOfType(RuntimeException.class) .isThrownBy(() -> errorHandling.handleErrorByThrowingAnyUncheckedException()); @@ -52,6 +58,7 @@ public void testThrowAnyUncheckedException() { @Disabled("Remove to run test") @Test + @DisplayName("Throws any unchecked exception with provided detail message") public void testThrowAnyUncheckedExceptionWithDetailMessage() { assertThatExceptionOfType(RuntimeException.class) .isThrownBy(() -> errorHandling.handleErrorByThrowingAnyUncheckedExceptionWithDetailMessage( @@ -61,6 +68,7 @@ public void testThrowAnyUncheckedExceptionWithDetailMessage() { @Disabled("Remove to run test") @Test + @DisplayName("Throws custom checked exception") public void testThrowCustomCheckedException() { assertThatExceptionOfType(CustomCheckedException.class) .isThrownBy(() -> errorHandling.handleErrorByThrowingCustomCheckedException()); @@ -68,6 +76,7 @@ public void testThrowCustomCheckedException() { @Disabled("Remove to run test") @Test + @DisplayName("Throws custom checked exception with provided detail message") public void testThrowCustomCheckedExceptionWithDetailMessage() { assertThatExceptionOfType(CustomCheckedException.class) .isThrownBy(() -> errorHandling.handleErrorByThrowingCustomCheckedExceptionWithDetailMessage( @@ -77,6 +86,7 @@ public void testThrowCustomCheckedExceptionWithDetailMessage() { @Disabled("Remove to run test") @Test + @DisplayName("Throws custom unchecked exception") public void testThrowCustomUncheckedException() { assertThatExceptionOfType(CustomUncheckedException.class) .isThrownBy(() -> errorHandling.handleErrorByThrowingCustomUncheckedException()); @@ -84,6 +94,7 @@ public void testThrowCustomUncheckedException() { @Disabled("Remove to run test") @Test + @DisplayName("Throws custom unchecked exception with provided detail message") public void testThrowCustomUncheckedExceptionWithDetailMessage() { assertThatExceptionOfType(CustomUncheckedException.class) .isThrownBy(() -> errorHandling.handleErrorByThrowingCustomUncheckedExceptionWithDetailMessage( @@ -93,6 +104,7 @@ public void testThrowCustomUncheckedExceptionWithDetailMessage() { @Disabled("Remove to run test") @Test + @DisplayName("Handles error by throwing Optional instance") public void testReturnOptionalInstance() { Optional successfulResult = errorHandling.handleErrorByReturningOptionalInstance("1"); assertThat(successfulResult).isPresent().hasValue(1); diff --git a/exercises/practice/etl/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/etl/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/etl/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/etl/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/etl/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/etl/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/etl/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/etl/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/etl/gradlew b/exercises/practice/etl/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/etl/gradlew +++ b/exercises/practice/etl/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/etl/gradlew.bat b/exercises/practice/etl/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/etl/gradlew.bat +++ b/exercises/practice/etl/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/etl/src/test/java/EtlTest.java b/exercises/practice/etl/src/test/java/EtlTest.java index c25755690..4ef9292aa 100644 --- a/exercises/practice/etl/src/test/java/EtlTest.java +++ b/exercises/practice/etl/src/test/java/EtlTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.Arrays; @@ -14,6 +15,7 @@ public class EtlTest { private final Etl etl = new Etl(); @Test + @DisplayName("single letter") public void testTransformOneValue() { Map> old = new HashMap>() { { @@ -34,6 +36,7 @@ public void testTransformOneValue() { @Disabled("Remove to run test") @Test + @DisplayName("single score with multiple letters") public void testTransformMoreValues() { Map> old = new HashMap>() { { @@ -58,6 +61,7 @@ public void testTransformMoreValues() { @Disabled("Remove to run test") @Test + @DisplayName("multiple scores with multiple letters") public void testMoreKeys() { Map> old = new HashMap>() { { @@ -82,6 +86,7 @@ public void testMoreKeys() { @Disabled("Remove to run test") @Test + @DisplayName("multiple scores with differing numbers of letters") public void testFullDataset() { Map> old = new HashMap>() { { diff --git a/exercises/practice/flatten-array/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/flatten-array/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/flatten-array/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/flatten-array/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/flatten-array/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/flatten-array/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/flatten-array/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/flatten-array/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/flatten-array/gradlew b/exercises/practice/flatten-array/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/flatten-array/gradlew +++ b/exercises/practice/flatten-array/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/flatten-array/gradlew.bat b/exercises/practice/flatten-array/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/flatten-array/gradlew.bat +++ b/exercises/practice/flatten-array/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/flatten-array/src/test/java/FlattenerTest.java b/exercises/practice/flatten-array/src/test/java/FlattenerTest.java index a9f94e280..2a5fb4323 100644 --- a/exercises/practice/flatten-array/src/test/java/FlattenerTest.java +++ b/exercises/practice/flatten-array/src/test/java/FlattenerTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static java.util.Arrays.asList; @@ -17,6 +18,7 @@ public void setUp() { } @Test + @DisplayName("empty") public void testEmpty() { assertThat(flattener.flatten(emptyList())) .isEmpty(); @@ -24,6 +26,7 @@ public void testEmpty() { @Disabled("Remove to run test") @Test + @DisplayName("no nesting") public void testFlatListIsPreserved() { assertThat(flattener.flatten(asList(0, '1', "two"))) .containsExactly(0, '1', "two"); @@ -31,6 +34,7 @@ public void testFlatListIsPreserved() { @Disabled("Remove to run test") @Test + @DisplayName("flattens a nested array") public void testNestedList() { assertThat(flattener.flatten(singletonList(emptyList()))) .isEmpty(); @@ -38,6 +42,7 @@ public void testNestedList() { @Disabled("Remove to run test") @Test + @DisplayName("flattens array with just integers present") public void testASingleLevelOfNestingWithNoNulls() { assertThat(flattener.flatten(asList(1, asList('2', 3, 4, 5, "six", "7"), 8))) .containsExactly(1, '2', 3, 4, 5, "six", "7", 8); @@ -45,6 +50,7 @@ public void testASingleLevelOfNestingWithNoNulls() { @Disabled("Remove to run test") @Test + @DisplayName("5 level nesting") public void testFiveLevelsOfNestingWithNoNulls() { assertThat(flattener.flatten( asList(0, @@ -59,6 +65,7 @@ public void testFiveLevelsOfNestingWithNoNulls() { @Disabled("Remove to run test") @Test + @DisplayName("6 level nesting") public void testSixLevelsOfNestingWithNoNulls() { assertThat(flattener.flatten( asList("one", @@ -71,6 +78,7 @@ public void testSixLevelsOfNestingWithNoNulls() { @Disabled("Remove to run test") @Test + @DisplayName("null values are omitted from the final result") public void testNullValuesAreOmitted() { assertThat(flattener.flatten(asList("1", "two", null))) .containsExactly("1", "two"); @@ -78,6 +86,7 @@ public void testNullValuesAreOmitted() { @Disabled("Remove to run test") @Test + @DisplayName("consecutive null values at the front of the list are omitted from the final result") public void testConsecutiveNullValuesAtFrontOfListAreOmitted() { assertThat(flattener.flatten(asList(null, null, 3))) .containsExactly(3); @@ -85,6 +94,7 @@ public void testConsecutiveNullValuesAtFrontOfListAreOmitted() { @Disabled("Remove to run test") @Test + @DisplayName("consecutive null values in the middle of the list are omitted from the final result") public void testConsecutiveNullValuesInMiddleOfListAreOmitted() { assertThat(flattener.flatten(asList(1, null, null, "4"))) .containsExactly(1, "4"); @@ -92,6 +102,7 @@ public void testConsecutiveNullValuesInMiddleOfListAreOmitted() { @Disabled("Remove to run test") @Test + @DisplayName("6 level nest list with null values") public void testSixLevelsOfNestingWithNulls() { assertThat(flattener.flatten( asList("0", @@ -107,6 +118,7 @@ public void testSixLevelsOfNestingWithNulls() { @Disabled("Remove to run test") @Test + @DisplayName("all values in nested list are null") public void testNestedListsFullOfNullsOnly() { assertThat(flattener.flatten( asList(null, diff --git a/exercises/practice/flower-field/.docs/instructions.md b/exercises/practice/flower-field/.docs/instructions.md new file mode 100644 index 000000000..bbdae0c2c --- /dev/null +++ b/exercises/practice/flower-field/.docs/instructions.md @@ -0,0 +1,26 @@ +# Instructions + +Your task is to add flower counts to empty squares in a completed Flower Field garden. +The garden itself is a rectangle board composed of squares that are either empty (`' '`) or a flower (`'*'`). + +For each empty square, count the number of flowers adjacent to it (horizontally, vertically, diagonally). +If the empty square has no adjacent flowers, leave it empty. +Otherwise replace it with the count of adjacent flowers. + +For example, you may receive a 5 x 4 board like this (empty spaces are represented here with the '·' character for display on screen): + +```text +·*·*· +··*·· +··*·· +····· +``` + +Which your code should transform into this: + +```text +1*3*1 +13*31 +·2*2· +·111· +``` diff --git a/exercises/practice/flower-field/.docs/introduction.md b/exercises/practice/flower-field/.docs/introduction.md new file mode 100644 index 000000000..af9b61536 --- /dev/null +++ b/exercises/practice/flower-field/.docs/introduction.md @@ -0,0 +1,7 @@ +# Introduction + +[Flower Field][history] is a compassionate reimagining of the popular game Minesweeper. +The object of the game is to find all the flowers in the garden using numeric hints that indicate how many flowers are directly adjacent (horizontally, vertically, diagonally) to a square. +"Flower Field" shipped in regional versions of Microsoft Windows in Italy, Germany, South Korea, Japan and Taiwan. + +[history]: https://web.archive.org/web/20020409051321fw_/http://rcm.usr.dsi.unimi.it/rcmweb/fnm/ diff --git a/exercises/practice/flower-field/.meta/config.json b/exercises/practice/flower-field/.meta/config.json new file mode 100644 index 000000000..54dc83896 --- /dev/null +++ b/exercises/practice/flower-field/.meta/config.json @@ -0,0 +1,41 @@ +{ + "authors": [ + "stkent" + ], + "contributors": [ + "aadityakulkarni", + "BNAndras", + "FridaTveit", + "hgvanpariya", + "jmrunkle", + "jsertel", + "kytrinyx", + "lemoncurry", + "matthewmorgan", + "matthewstyler", + "morrme", + "msomji", + "muzimuzhi", + "redshirt4", + "SleeplessByte", + "Smarticles101", + "sshine", + "vivshaw", + "Zaldrick" + ], + "files": { + "solution": [ + "src/main/java/FlowerFieldBoard.java" + ], + "test": [ + "src/test/java/FlowerFieldBoardTest.java" + ], + "example": [ + ".meta/src/reference/java/FlowerFieldBoard.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Mark all the flowers in a garden." +} diff --git a/exercises/practice/flower-field/.meta/src/reference/java/FlowerFieldBoard.java b/exercises/practice/flower-field/.meta/src/reference/java/FlowerFieldBoard.java new file mode 100644 index 000000000..0fa97e128 --- /dev/null +++ b/exercises/practice/flower-field/.meta/src/reference/java/FlowerFieldBoard.java @@ -0,0 +1,75 @@ +import java.util.ArrayList; +import java.util.List; + +final class FlowerFieldBoard { + + private static final char FLOWER_CHAR = '*'; + + private static final char SPACE_CHAR = ' '; + + private final List rawRepresentation; + + private final int numberOfRows; + + private final int numberOfColumns; + + FlowerFieldBoard(final List rawRepresentation) { + this.rawRepresentation = rawRepresentation; + this.numberOfRows = rawRepresentation.size(); + this.numberOfColumns = rawRepresentation.isEmpty() ? 0 : rawRepresentation.get(0).length(); + } + + List withNumbers() { + final List result = new ArrayList<>(); + + for (int rowNumber = 0; rowNumber < numberOfRows; rowNumber++) { + result.add(getRowWithNumbers(rowNumber)); + } + + return result; + } + + private String getRowWithNumbers(final int rowNumber) { + StringBuilder result = new StringBuilder(numberOfColumns); + + for (int columnNumber = 0; columnNumber < numberOfColumns; columnNumber++) { + result.append(getCellNumber(rowNumber, columnNumber)); + } + + return result.toString(); + } + + private char getCellNumber(final int rowNumber, final int columnNumber) { + // If (rowNumber, columnNumber) is a flower, we're done. + if (rawRepresentation.get(rowNumber).charAt(columnNumber) == FLOWER_CHAR) { + return FLOWER_CHAR; + } + + final int flowerCount = computeFlowerCountAround(rowNumber, columnNumber); + + // If computed count is positive, add it to the annotated row. Otherwise, add a blank space. + return flowerCount > 0 ? Character.forDigit(flowerCount, 10) : SPACE_CHAR; + } + + private int computeFlowerCountAround(final int rowNumber, final int columnNumber) { + int result = 0; + + // Compute row and column ranges to inspect (respecting board edges). + final int minRowToInspect = Math.max(rowNumber - 1, 0); + final int maxRowToInspect = Math.min(rowNumber + 1, numberOfRows - 1); + final int minColToInspect = Math.max(columnNumber - 1, 0); + final int maxColToInspect = Math.min(columnNumber + 1, numberOfColumns - 1); + + // Count flowers in the cells surrounding (row, col). + for (int rowToInspect = minRowToInspect; rowToInspect <= maxRowToInspect; rowToInspect++) { + for (int colToInspect = minColToInspect; colToInspect <= maxColToInspect; colToInspect++) { + if (rawRepresentation.get(rowToInspect).charAt(colToInspect) == FLOWER_CHAR) { + result += 1; + } + } + } + + return result; + } + +} diff --git a/exercises/practice/flower-field/.meta/tests.toml b/exercises/practice/flower-field/.meta/tests.toml new file mode 100644 index 000000000..965ba8fd4 --- /dev/null +++ b/exercises/practice/flower-field/.meta/tests.toml @@ -0,0 +1,49 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[237ff487-467a-47e1-9b01-8a891844f86c] +description = "no rows" + +[4b4134ec-e20f-439c-a295-664c38950ba1] +description = "no columns" + +[d774d054-bbad-4867-88ae-069cbd1c4f92] +description = "no flowers" + +[225176a0-725e-43cd-aa13-9dced501f16e] +description = "garden full of flowers" + +[3f345495-f1a5-4132-8411-74bd7ca08c49] +description = "flower surrounded by spaces" + +[6cb04070-4199-4ef7-a6fa-92f68c660fca] +description = "space surrounded by flowers" + +[272d2306-9f62-44fe-8ab5-6b0f43a26338] +description = "horizontal line" + +[c6f0a4b2-58d0-4bf6-ad8d-ccf4144f1f8e] +description = "horizontal line, flowers at edges" + +[a54e84b7-3b25-44a8-b8cf-1753c8bb4cf5] +description = "vertical line" + +[b40f42f5-dec5-4abc-b167-3f08195189c1] +description = "vertical line, flowers at edges" + +[58674965-7b42-4818-b930-0215062d543c] +description = "cross" + +[dd9d4ca8-9e68-4f78-a677-a2a70fd7a7b8] +description = "large garden" + +[6e4ac13a-3e43-4728-a2e3-3551d4b1a996] +description = "multiple adjacent flowers" diff --git a/exercises/practice/flower-field/build.gradle b/exercises/practice/flower-field/build.gradle new file mode 100644 index 000000000..d28f35dee --- /dev/null +++ b/exercises/practice/flower-field/build.gradle @@ -0,0 +1,25 @@ +plugins { + id "java" +} + +repositories { + mavenCentral() +} + +dependencies { + testImplementation platform("org.junit:junit-bom:5.10.0") + testImplementation "org.junit.jupiter:junit-jupiter" + testImplementation "org.assertj:assertj-core:3.25.1" + + testRuntimeOnly "org.junit.platform:junit-platform-launcher" +} + +test { + useJUnitPlatform() + + testLogging { + exceptionFormat = "full" + showStandardStreams = true + events = ["passed", "failed", "skipped"] + } +} diff --git a/exercises/practice/flower-field/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/flower-field/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..f8e1ee312 Binary files /dev/null and b/exercises/practice/flower-field/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/flower-field/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/flower-field/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..4d97ea344 --- /dev/null +++ b/exercises/practice/flower-field/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/exercises/practice/flower-field/gradlew b/exercises/practice/flower-field/gradlew new file mode 100755 index 000000000..adff685a0 --- /dev/null +++ b/exercises/practice/flower-field/gradlew @@ -0,0 +1,248 @@ +#!/bin/sh + +# +# Copyright © 2015 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/exercises/practice/flower-field/gradlew.bat b/exercises/practice/flower-field/gradlew.bat new file mode 100644 index 000000000..c4bdd3ab8 --- /dev/null +++ b/exercises/practice/flower-field/gradlew.bat @@ -0,0 +1,93 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/exercises/practice/flower-field/src/main/java/FlowerFieldBoard.java b/exercises/practice/flower-field/src/main/java/FlowerFieldBoard.java new file mode 100644 index 000000000..db059db34 --- /dev/null +++ b/exercises/practice/flower-field/src/main/java/FlowerFieldBoard.java @@ -0,0 +1,13 @@ +import java.util.List; + +class FlowerFieldBoard { + + FlowerFieldBoard(List boardRows) { + throw new UnsupportedOperationException("Delete this statement and write your own implementation."); + } + + List withNumbers() { + throw new UnsupportedOperationException("Delete this statement and write your own implementation."); + } + +} \ No newline at end of file diff --git a/exercises/practice/flower-field/src/test/java/FlowerFieldBoardTest.java b/exercises/practice/flower-field/src/test/java/FlowerFieldBoardTest.java new file mode 100644 index 000000000..58f995293 --- /dev/null +++ b/exercises/practice/flower-field/src/test/java/FlowerFieldBoardTest.java @@ -0,0 +1,269 @@ +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.Collections; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class FlowerFieldBoardTest { + + @Test + @DisplayName("no rows") + public void testInputBoardWithNoRowsAndNoColumns() { + List inputBoard = Collections.emptyList(); + List expectedNumberedBoard = Collections.emptyList(); + List actualNumberedBoard = new FlowerFieldBoard(inputBoard).withNumbers(); + + assertThat(actualNumberedBoard).isEqualTo(expectedNumberedBoard); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("no columns") + public void testInputBoardWithOneRowAndNoColumns() { + List inputBoard = List.of(""); + List expectedNumberedBoard = List.of(""); + List actualNumberedBoard = new FlowerFieldBoard(inputBoard).withNumbers(); + + assertThat(actualNumberedBoard).isEqualTo(expectedNumberedBoard); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("no flowers") + public void testInputBoardWithNoFlowers() { + List inputBoard = List.of( + " ", + " ", + " " + ); + + List expectedNumberedBoard = List.of( + " ", + " ", + " " + ); + + List actualNumberedBoard = new FlowerFieldBoard(inputBoard).withNumbers(); + + assertThat(actualNumberedBoard).isEqualTo(expectedNumberedBoard); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("garden full of flowers") + public void testInputBoardWithOnlyFlowers() { + List inputBoard = List.of( + "***", + "***", + "***" + ); + + List expectedNumberedBoard = List.of( + "***", + "***", + "***" + ); + + List actualNumberedBoard = new FlowerFieldBoard(inputBoard).withNumbers(); + + assertThat(actualNumberedBoard).isEqualTo(expectedNumberedBoard); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("flower surrounded by spaces") + public void testInputBoardWithSingleFlowerAtCenter() { + List inputBoard = List.of( + " ", + " * ", + " " + ); + + List expectedNumberedBoard = List.of( + "111", + "1*1", + "111" + ); + + List actualNumberedBoard = new FlowerFieldBoard(inputBoard).withNumbers(); + + assertThat(actualNumberedBoard).isEqualTo(expectedNumberedBoard); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("space surrounded by flowers") + public void testInputBoardWithFlowersAroundPerimeter() { + List inputBoard = List.of( + "***", + "* *", + "***" + ); + + List expectedNumberedBoard = List.of( + "***", + "*8*", + "***" + ); + + List actualNumberedBoard = new FlowerFieldBoard(inputBoard).withNumbers(); + + assertThat(actualNumberedBoard).isEqualTo(expectedNumberedBoard); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("horizontal line") + public void testInputBoardWithSingleRowAndTwoFlowers() { + List inputBoard = List.of( + " * * " + ); + + List expectedNumberedBoard = List.of( + "1*2*1" + ); + + List actualNumberedBoard = new FlowerFieldBoard(inputBoard).withNumbers(); + + assertThat(actualNumberedBoard).isEqualTo(expectedNumberedBoard); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("horizontal line, flowers at edges") + public void testInputBoardWithSingleRowAndTwoFlowersAtEdges() { + List inputBoard = List.of( + "* *" + ); + + List expectedNumberedBoard = List.of( + "*1 1*" + ); + + List actualNumberedBoard = new FlowerFieldBoard(inputBoard).withNumbers(); + + assertThat(actualNumberedBoard).isEqualTo(expectedNumberedBoard); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("vertical line") + public void testInputBoardWithSingleColumnAndTwoFlowers() { + List inputBoard = List.of( + " ", + "*", + " ", + "*", + " " + ); + + List expectedNumberedBoard = List.of( + "1", + "*", + "2", + "*", + "1" + ); + + List actualNumberedBoard = new FlowerFieldBoard(inputBoard).withNumbers(); + + assertThat(actualNumberedBoard).isEqualTo(expectedNumberedBoard); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("vertical line, flowers at edges") + public void testInputBoardWithSingleColumnAndTwoFlowersAtEdges() { + List inputBoard = List.of( + "*", + " ", + " ", + " ", + "*" + ); + + List expectedNumberedBoard = List.of( + "*", + "1", + " ", + "1", + "*" + ); + + List actualNumberedBoard = new FlowerFieldBoard(inputBoard).withNumbers(); + + assertThat(actualNumberedBoard).isEqualTo(expectedNumberedBoard); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("cross") + public void testInputBoardWithFlowersInCross() { + List inputBoard = List.of( + " * ", + " * ", + "*****", + " * ", + " * " + ); + + List expectedNumberedBoard = List.of( + " 2*2 ", + "25*52", + "*****", + "25*52", + " 2*2 " + ); + + List actualNumberedBoard = new FlowerFieldBoard(inputBoard).withNumbers(); + + assertThat(actualNumberedBoard).isEqualTo(expectedNumberedBoard); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("large garden") + public void testLargeInputBoard() { + List inputBoard = List.of( + " * * ", + " * ", + " * ", + " * *", + " * * ", + " " + ); + + List expectedNumberedBoard = List.of( + "1*22*1", + "12*322", + " 123*2", + "112*4*", + "1*22*2", + "111111" + ); + + List actualNumberedBoard = new FlowerFieldBoard(inputBoard).withNumbers(); + + assertThat(actualNumberedBoard).isEqualTo(expectedNumberedBoard); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("multiple adjacent flowers") + public void testMultipleAdjacentFlowers() { + List inputBoard = List.of( + " ** " + ); + + List expectedNumberedBoard = List.of( + "1**1" + ); + + List actualNumberedBoard = new FlowerFieldBoard(inputBoard).withNumbers(); + + assertThat(actualNumberedBoard).isEqualTo(expectedNumberedBoard); + } +} diff --git a/exercises/practice/food-chain/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/food-chain/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/food-chain/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/food-chain/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/food-chain/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/food-chain/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/food-chain/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/food-chain/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/food-chain/gradlew b/exercises/practice/food-chain/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/food-chain/gradlew +++ b/exercises/practice/food-chain/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/food-chain/gradlew.bat b/exercises/practice/food-chain/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/food-chain/gradlew.bat +++ b/exercises/practice/food-chain/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/food-chain/src/test/java/FoodChainTest.java b/exercises/practice/food-chain/src/test/java/FoodChainTest.java index a0f5caa57..43e7a0746 100644 --- a/exercises/practice/food-chain/src/test/java/FoodChainTest.java +++ b/exercises/practice/food-chain/src/test/java/FoodChainTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -13,6 +14,7 @@ public void setup() { } @Test + @DisplayName("fly") public void fly() { int verse = 1; String expected = "I know an old lady who swallowed a fly.\n" + @@ -23,6 +25,7 @@ public void fly() { @Test @Disabled("Remove to run test.") + @DisplayName("spider") public void spider() { int verse = 2; String expected = "I know an old lady who swallowed a spider.\n" + @@ -35,6 +38,7 @@ public void spider() { @Test @Disabled("Remove to run test.") + @DisplayName("bird") public void bird() { int verse = 3; String expected = "I know an old lady who swallowed a bird.\n" + @@ -49,6 +53,7 @@ public void bird() { @Test @Disabled("Remove to run test.") + @DisplayName("cat") public void cat() { int verse = 4; String expected = "I know an old lady who swallowed a cat.\n" + @@ -65,6 +70,7 @@ public void cat() { @Test @Disabled("Remove to run test.") + @DisplayName("dog") public void dog() { int verse = 5; String expected = "I know an old lady who swallowed a dog.\n" + @@ -81,6 +87,7 @@ public void dog() { @Test @Disabled("Remove to run test.") + @DisplayName("goat") public void goat() { int verse = 6; String expected = "I know an old lady who swallowed a goat.\n" + @@ -98,6 +105,7 @@ public void goat() { @Test @Disabled("Remove to run test.") + @DisplayName("cow") public void cow() { int verse = 7; String expected = "I know an old lady who swallowed a cow.\n" + @@ -116,6 +124,7 @@ public void cow() { @Test @Disabled("Remove to run test.") + @DisplayName("horse") public void horse() { int verse = 8; String expected = "I know an old lady who swallowed a horse.\n" + @@ -127,6 +136,7 @@ public void horse() { @Test @Disabled("Remove to run test.") + @DisplayName("multiple verses") public void multipleVerses() { int startVerse = 1; int endVerse = 3; @@ -151,6 +161,7 @@ public void multipleVerses() { @Test @Disabled("Remove to run test.") + @DisplayName("full song") public void wholeSong() { int startVerse = 1; int endVerse = 8; diff --git a/exercises/practice/forth/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/forth/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/forth/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/forth/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/forth/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/forth/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/forth/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/forth/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/forth/gradlew b/exercises/practice/forth/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/forth/gradlew +++ b/exercises/practice/forth/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/forth/gradlew.bat b/exercises/practice/forth/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/forth/gradlew.bat +++ b/exercises/practice/forth/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/forth/src/test/java/ForthEvaluatorTest.java b/exercises/practice/forth/src/test/java/ForthEvaluatorTest.java index bd36657b3..9a7c23e01 100644 --- a/exercises/practice/forth/src/test/java/ForthEvaluatorTest.java +++ b/exercises/practice/forth/src/test/java/ForthEvaluatorTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.Arrays; @@ -13,6 +14,7 @@ public class ForthEvaluatorTest { private ForthEvaluator forthEvaluator = new ForthEvaluator(); @Test + @DisplayName("numbers just get pushed onto the stack") public void testNumbersAreJustPushedOntoTheStack() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("1 2 3 4 5"))) .containsExactly(1, 2, 3, 4, 5); @@ -20,6 +22,7 @@ public void testNumbersAreJustPushedOntoTheStack() { @Disabled("Remove to run test") @Test + @DisplayName("pushes negative numbers onto the stack") public void testNegativeNumbersArePushedOntoTheStack() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("-1 -2 -3 -4 -5"))) .containsExactly(-1, -2, -3, -4, -5); @@ -27,6 +30,7 @@ public void testNegativeNumbersArePushedOntoTheStack() { @Disabled("Remove to run test") @Test + @DisplayName("can add two numbers") public void testTwoNumbersCanBeAdded() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("1 2 +"))) .containsExactly(3); @@ -34,6 +38,7 @@ public void testTwoNumbersCanBeAdded() { @Disabled("Remove to run test") @Test + @DisplayName("errors if there is nothing on the stack") public void testErrorIfAdditionAttemptedWithNothingOnTheStack() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> forthEvaluator.evaluateProgram(Collections.singletonList("+"))) @@ -42,6 +47,7 @@ public void testErrorIfAdditionAttemptedWithNothingOnTheStack() { @Disabled("Remove to run test") @Test + @DisplayName("errors if there is only one value on the stack") public void testErrorIfAdditionAttemptedWithOneNumberOnTheStack() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> forthEvaluator.evaluateProgram(Collections.singletonList("1 +"))) @@ -50,6 +56,7 @@ public void testErrorIfAdditionAttemptedWithOneNumberOnTheStack() { @Disabled("Remove to run test") @Test + @DisplayName("more than two values on the stack") public void testAdditionForMoreThanTwoValuesOnTheStack() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("1 2 3 +"))) .containsExactly(1, 5); @@ -57,6 +64,7 @@ public void testAdditionForMoreThanTwoValuesOnTheStack() { @Disabled("Remove to run test") @Test + @DisplayName("can subtract two numbers") public void testTwoNumbersCanBeSubtracted() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("3 4 -"))) .containsExactly(-1); @@ -64,6 +72,7 @@ public void testTwoNumbersCanBeSubtracted() { @Disabled("Remove to run test") @Test + @DisplayName("errors if there is nothing on the stack") public void testErrorIfSubtractionAttemptedWithNothingOnTheStack() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> forthEvaluator.evaluateProgram(Collections.singletonList("-"))) @@ -73,6 +82,7 @@ public void testErrorIfSubtractionAttemptedWithNothingOnTheStack() { @Disabled("Remove to run test") @Test + @DisplayName("errors if there is only one value on the stack") public void testErrorIfSubtractionAttemptedWithOneNumberOnTheStack() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> forthEvaluator.evaluateProgram(Collections.singletonList("1 -"))) @@ -81,6 +91,7 @@ public void testErrorIfSubtractionAttemptedWithOneNumberOnTheStack() { @Disabled("Remove to run test") @Test + @DisplayName("more than two values on the stack") public void testSubtractionForMoreThanTwoValuesOnTheStack() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("1 12 3 -"))) .containsExactly(1, 9); @@ -88,12 +99,14 @@ public void testSubtractionForMoreThanTwoValuesOnTheStack() { @Disabled("Remove to run test") @Test + @DisplayName("can multiply two numbers") public void testTwoNumbersCanBeMultiplied() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("2 4 *"))).containsExactly(8); } @Disabled("Remove to run test") @Test + @DisplayName("errors if there is nothing on the stack") public void testErrorIfMultiplicationAttemptedWithNothingOnTheStack() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> forthEvaluator.evaluateProgram(Collections.singletonList("*"))) @@ -102,6 +115,7 @@ public void testErrorIfMultiplicationAttemptedWithNothingOnTheStack() { @Disabled("Remove to run test") @Test + @DisplayName("errors if there is only one value on the stack") public void testErrorIfMultiplicationAttemptedWithOneNumberOnTheStack() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> forthEvaluator.evaluateProgram(Collections.singletonList("1 *"))) @@ -110,6 +124,7 @@ public void testErrorIfMultiplicationAttemptedWithOneNumberOnTheStack() { @Disabled("Remove to run test") @Test + @DisplayName("more than two values on the stack") public void testMultiplicationForMoreThanTwoValuesOnTheStack() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("1 2 3 *"))) .containsExactly(1, 6); @@ -117,18 +132,21 @@ public void testMultiplicationForMoreThanTwoValuesOnTheStack() { @Disabled("Remove to run test") @Test + @DisplayName("can divide two numbers") public void testTwoNumbersCanBeDivided() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("12 3 /"))).containsExactly(4); } @Disabled("Remove to run test") @Test + @DisplayName("performs integer division") public void testThatIntegerDivisionIsUsed() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("8 3 /"))).containsExactly(2); } @Disabled("Remove to run test") @Test + @DisplayName("errors if dividing by zero") public void testErrorIfDividingByZero() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> forthEvaluator.evaluateProgram(Collections.singletonList("4 0 /"))) @@ -137,6 +155,7 @@ public void testErrorIfDividingByZero() { @Disabled("Remove to run test") @Test + @DisplayName("errors if there is nothing on the stack") public void testErrorIfDivisionAttemptedWithNothingOnTheStack() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> forthEvaluator.evaluateProgram(Collections.singletonList("/"))) @@ -145,6 +164,7 @@ public void testErrorIfDivisionAttemptedWithNothingOnTheStack() { @Disabled("Remove to run test") @Test + @DisplayName("errors if there is only one value on the stack") public void testErrorIfDivisionAttemptedWithOneNumberOnTheStack() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> forthEvaluator.evaluateProgram(Collections.singletonList("1 /"))) @@ -153,6 +173,7 @@ public void testErrorIfDivisionAttemptedWithOneNumberOnTheStack() { @Disabled("Remove to run test") @Test + @DisplayName("more than two values on the stack") public void testDivisionForMoreThanTwoValuesOnTheStack() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("1 12 3 /"))) .containsExactly(1, 4); @@ -160,42 +181,49 @@ public void testDivisionForMoreThanTwoValuesOnTheStack() { @Disabled("Remove to run test") @Test + @DisplayName("addition and subtraction") public void testCombinedAdditionAndSubtraction() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("1 2 + 4 -"))).containsExactly(-1); } @Disabled("Remove to run test") @Test + @DisplayName("multiplication and division") public void testCombinedMultiplicationAndDivision() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("2 4 * 3 /"))).containsExactly(2); } @Disabled("Remove to run test") @Test + @DisplayName("multiplication and addition") public void testCombinedMultiplicationAndAddition() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("1 3 4 * +"))).containsExactly(13); } @Disabled("Remove to run test") @Test + @DisplayName("addition and multiplication") public void testCombinedAdditionAndMultiplication() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("1 3 4 + *"))).containsExactly(7); } @Disabled("Remove to run test") @Test + @DisplayName("copies a value on the stack") public void testDupCopiesAValueOnTheStack() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("1 dup"))).containsExactly(1, 1); } @Disabled("Remove to run test") @Test + @DisplayName("copies the top value on the stack") public void testDupCopiesTopValueOnTheStack() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("1 2 dup"))).containsExactly(1, 2, 2); } @Disabled("Remove to run test") @Test + @DisplayName("errors if there is nothing on the stack") public void testErrorIfDuplicatingAttemptedWithNothingOnTheStack() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> forthEvaluator.evaluateProgram(Collections.singletonList("dup"))) @@ -204,18 +232,21 @@ public void testErrorIfDuplicatingAttemptedWithNothingOnTheStack() { @Disabled("Remove to run test") @Test + @DisplayName("removes the top value on the stack if it is the only one") public void testDropRemovesTheTopValueOnTheStackIfItIsTheOnlyOne() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("1 drop"))).isEmpty(); } @Disabled("Remove to run test") @Test + @DisplayName("removes the top value on the stack if it is not the only one") public void testDropRemovesTheTopValueOnTheStackIfItIsNotTheOnlyOne() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("1 2 drop"))).containsExactly(1); } @Disabled("Remove to run test") @Test + @DisplayName("errors if there is nothing on the stack") public void testErrorIfDroppingAttemptedWithNothingOnTheStack() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> forthEvaluator.evaluateProgram(Collections.singletonList("drop"))) @@ -224,12 +255,14 @@ public void testErrorIfDroppingAttemptedWithNothingOnTheStack() { @Disabled("Remove to run test") @Test + @DisplayName("swaps the top two values on the stack if they are the only ones") public void testSwapSwapsTheTopTwosValueOnTheStackIfTheyAreTheOnlyOnes() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("1 2 swap"))).containsExactly(2, 1); } @Disabled("Remove to run test") @Test + @DisplayName("swaps the top two values on the stack if they are not the only ones") public void testSwapSwapsTheTopTwosValueOnTheStackIfTheyAreNotTheOnlyOnes() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("1 2 3 swap"))) .containsExactly(1, 3, 2); @@ -237,6 +270,7 @@ public void testSwapSwapsTheTopTwosValueOnTheStackIfTheyAreNotTheOnlyOnes() { @Disabled("Remove to run test") @Test + @DisplayName("errors if there is nothing on the stack") public void testErrorIfSwappingAttemptedWithNothingOnTheStack() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> forthEvaluator.evaluateProgram(Collections.singletonList("swap"))) @@ -245,6 +279,7 @@ public void testErrorIfSwappingAttemptedWithNothingOnTheStack() { @Disabled("Remove to run test") @Test + @DisplayName("errors if there is only one value on the stack") public void testErrorIfSwappingAttemptedWithOneNumberOnTheStack() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> forthEvaluator.evaluateProgram(Collections.singletonList("1 swap"))) @@ -253,6 +288,7 @@ public void testErrorIfSwappingAttemptedWithOneNumberOnTheStack() { @Disabled("Remove to run test") @Test + @DisplayName("copies the second element if there are only two") public void testOverCopiesTheSecondElementIfThereAreOnlyTwo() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("1 2 over"))) .containsExactly(1, 2, 1); @@ -260,6 +296,7 @@ public void testOverCopiesTheSecondElementIfThereAreOnlyTwo() { @Disabled("Remove to run test") @Test + @DisplayName("copies the second element if there are more than two") public void testOverCopiesTheSecondElementIfThereAreMoreThanTwo() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("1 2 3 over"))) .containsExactly(1, 2, 3, 2); @@ -267,6 +304,7 @@ public void testOverCopiesTheSecondElementIfThereAreMoreThanTwo() { @Disabled("Remove to run test") @Test + @DisplayName("errors if there is nothing on the stack") public void testErrorIfOveringAttemptedWithNothingOnTheStack() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> forthEvaluator.evaluateProgram(Collections.singletonList("over"))) @@ -275,6 +313,7 @@ public void testErrorIfOveringAttemptedWithNothingOnTheStack() { @Disabled("Remove to run test") @Test + @DisplayName("errors if there is only one value on the stack") public void testErrorIfOveringAttemptedWithOneNumberOnTheStack() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> forthEvaluator.evaluateProgram(Collections.singletonList("1 over"))) @@ -283,6 +322,7 @@ public void testErrorIfOveringAttemptedWithOneNumberOnTheStack() { @Disabled("Remove to run test") @Test + @DisplayName("can consist of built-in words") public void testUserDefinedOperatorsCanConsistOfBuiltInOperators() { assertThat(forthEvaluator.evaluateProgram(Arrays.asList(": dup-twice dup dup ;", "1 dup-twice"))) .containsExactly(1, 1, 1); @@ -290,6 +330,7 @@ public void testUserDefinedOperatorsCanConsistOfBuiltInOperators() { @Disabled("Remove to run test") @Test + @DisplayName("execute in the right order") public void testUserDefinedOperatorsAreEvaluatedInTheCorrectOrder() { assertThat(forthEvaluator.evaluateProgram(Arrays.asList(": countup 1 2 3 ;", "countup"))) .containsExactly(1, 2, 3); @@ -297,6 +338,7 @@ public void testUserDefinedOperatorsAreEvaluatedInTheCorrectOrder() { @Disabled("Remove to run test") @Test + @DisplayName("can override other user-defined words") public void testCanRedefineAUserDefinedOperator() { assertThat(forthEvaluator.evaluateProgram(Arrays.asList(": foo dup ;", ": foo dup dup ;", "1 foo"))) .containsExactly(1, 1, 1); @@ -304,6 +346,7 @@ public void testCanRedefineAUserDefinedOperator() { @Disabled("Remove to run test") @Test + @DisplayName("can override built-in words") public void testCanOverrideBuiltInWordOperators() { assertThat(forthEvaluator.evaluateProgram(Arrays.asList(": swap dup ;", "1 swap"))) .containsExactly(1, 1); @@ -311,6 +354,7 @@ public void testCanOverrideBuiltInWordOperators() { @Disabled("Remove to run test") @Test + @DisplayName("can override built-in operators") public void testCanOverrideBuiltInArithmeticOperators() { assertThat(forthEvaluator.evaluateProgram(Arrays.asList(": + * ;", "3 4 +"))) .containsExactly(12); @@ -318,6 +362,7 @@ public void testCanOverrideBuiltInArithmeticOperators() { @Disabled("Remove to run test") @Test + @DisplayName("can use different words with the same name") public void testCanUseDifferentWordsWithTheSameName() { assertThat(forthEvaluator.evaluateProgram(Arrays.asList(": foo 5 ;", ": bar foo ;", ": foo 6 ;", "bar foo"))) .containsExactly(5, 6); @@ -325,6 +370,7 @@ public void testCanUseDifferentWordsWithTheSameName() { @Disabled("Remove to run test") @Test + @DisplayName("can define word that uses word with the same name") public void testCanDefineWordThatUsesWordWithTheSameName() { assertThat(forthEvaluator.evaluateProgram(Arrays.asList(": foo 10 ;", ": foo foo 1 + ;", "foo"))) .containsExactly(11); @@ -332,6 +378,7 @@ public void testCanDefineWordThatUsesWordWithTheSameName() { @Disabled("Remove to run test") @Test + @DisplayName("cannot redefine non-negative numbers") public void testCannotRedefineNonNegativeNumbers() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> forthEvaluator.evaluateProgram(Collections.singletonList(": 1 2 ;"))) @@ -340,6 +387,7 @@ public void testCannotRedefineNonNegativeNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("cannot redefine negative numbers") public void testCannotRedefineNegativeNumbers() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> forthEvaluator.evaluateProgram(Collections.singletonList(": -1 2 ;"))) @@ -348,6 +396,7 @@ public void testCannotRedefineNegativeNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("errors if executing a non-existent word") public void testErrorIfEvaluatingAnUndefinedOperator() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> forthEvaluator.evaluateProgram(Collections.singletonList("foo"))) @@ -356,6 +405,7 @@ public void testErrorIfEvaluatingAnUndefinedOperator() { @Disabled("Remove to run test") @Test + @DisplayName("DUP is case-insensitive") public void testDupIsCaseInsensitive() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("1 DUP Dup dup"))) .containsExactly(1, 1, 1, 1); @@ -363,6 +413,7 @@ public void testDupIsCaseInsensitive() { @Disabled("Remove to run test") @Test + @DisplayName("DROP is case-insensitive") public void testDropIsCaseInsensitive() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("1 2 3 4 DROP Drop drop"))) .containsExactly(1); @@ -370,6 +421,7 @@ public void testDropIsCaseInsensitive() { @Disabled("Remove to run test") @Test + @DisplayName("SWAP is case-insensitive") public void testSwapIsCaseInsensitive() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("1 2 SWAP 3 Swap 4 swap"))) .containsExactly(2, 3, 4, 1); @@ -377,6 +429,7 @@ public void testSwapIsCaseInsensitive() { @Disabled("Remove to run test") @Test + @DisplayName("OVER is case-insensitive") public void testOverIsCaseInsensitive() { assertThat(forthEvaluator.evaluateProgram(Collections.singletonList("1 2 OVER Over over"))) .containsExactly(1, 2, 1, 2, 1); @@ -384,6 +437,7 @@ public void testOverIsCaseInsensitive() { @Disabled("Remove to run test") @Test + @DisplayName("user-defined words are case-insensitive") public void testUserDefinedWordsAreCaseInsensitive() { assertThat(forthEvaluator.evaluateProgram(Arrays.asList(": foo dup ;", "1 FOO Foo foo"))) .containsExactly(1, 1, 1, 1); @@ -391,6 +445,7 @@ public void testUserDefinedWordsAreCaseInsensitive() { @Disabled("Remove to run test") @Test + @DisplayName("definitions are case-insensitive") public void testDefinitionsAreCaseInsensitive() { assertThat(forthEvaluator.evaluateProgram(Arrays.asList(": SWAP DUP Dup dup ;", "1 swap"))) .containsExactly(1, 1, 1, 1); @@ -398,6 +453,7 @@ public void testDefinitionsAreCaseInsensitive() { @Disabled @Test + @DisplayName("only defines locally") public void testDefinitionsAreOnlyDefinedLocally() { ForthEvaluator firstInstance = new ForthEvaluator(); ForthEvaluator secondInstance = new ForthEvaluator(); diff --git a/exercises/practice/game-of-life/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/game-of-life/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/game-of-life/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/game-of-life/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/game-of-life/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/game-of-life/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/game-of-life/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/game-of-life/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/game-of-life/gradlew b/exercises/practice/game-of-life/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/game-of-life/gradlew +++ b/exercises/practice/game-of-life/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/game-of-life/gradlew.bat b/exercises/practice/game-of-life/gradlew.bat index 93e3f59f1..c4bdd3ab8 100644 --- a/exercises/practice/game-of-life/gradlew.bat +++ b/exercises/practice/game-of-life/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -43,11 +45,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,22 +59,21 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/gigasecond/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/gigasecond/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/gigasecond/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/gigasecond/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/gigasecond/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/gigasecond/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/gigasecond/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/gigasecond/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/gigasecond/gradlew b/exercises/practice/gigasecond/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/gigasecond/gradlew +++ b/exercises/practice/gigasecond/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/gigasecond/gradlew.bat b/exercises/practice/gigasecond/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/gigasecond/gradlew.bat +++ b/exercises/practice/gigasecond/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/gigasecond/src/test/java/GigasecondTest.java b/exercises/practice/gigasecond/src/test/java/GigasecondTest.java index 6b190f606..2f5872fdd 100644 --- a/exercises/practice/gigasecond/src/test/java/GigasecondTest.java +++ b/exercises/practice/gigasecond/src/test/java/GigasecondTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.time.LocalDate; @@ -10,6 +11,7 @@ public class GigasecondTest { @Test + @DisplayName("date only specification of time") public void modernTime() { Gigasecond gigaSecond = new Gigasecond(LocalDate.of(2011, Month.APRIL, 25)); @@ -18,6 +20,7 @@ public void modernTime() { @Disabled("Remove to run test") @Test + @DisplayName("second test for date only specification of time") public void afterEpochTime() { Gigasecond gigaSecond = new Gigasecond(LocalDate.of(1977, Month.JUNE, 13)); @@ -26,6 +29,7 @@ public void afterEpochTime() { @Disabled("Remove to run test") @Test + @DisplayName("third test for date only specification of time") public void beforeEpochTime() { Gigasecond gigaSecond = new Gigasecond(LocalDate.of(1959, Month.JULY, 19)); @@ -34,6 +38,7 @@ public void beforeEpochTime() { @Disabled("Remove to run test") @Test + @DisplayName("full time specified") public void withFullTimeSpecified() { Gigasecond gigaSecond = new Gigasecond(LocalDateTime.of(2015, Month.JANUARY, 24, 22, 0, 0)); @@ -42,6 +47,7 @@ public void withFullTimeSpecified() { @Disabled("Remove to run test") @Test + @DisplayName("full time with day roll-over") public void withFullTimeSpecifiedAndDayRollover() { Gigasecond gigaSecond = new Gigasecond(LocalDateTime.of(2015, Month.JANUARY, 24, 23, 59, 59)); @@ -50,6 +56,7 @@ public void withFullTimeSpecifiedAndDayRollover() { @Disabled("Remove to run test") @Test + @DisplayName("does not mutate the input") public void doesNotMutateInput() { LocalDateTime input = LocalDateTime.of(2015, Month.JANUARY, 24, 23, 59, 59); new Gigasecond(input).getDateTime(); diff --git a/exercises/practice/go-counting/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/go-counting/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/go-counting/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/go-counting/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/go-counting/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/go-counting/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/go-counting/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/go-counting/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/go-counting/gradlew b/exercises/practice/go-counting/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/go-counting/gradlew +++ b/exercises/practice/go-counting/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/go-counting/gradlew.bat b/exercises/practice/go-counting/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/go-counting/gradlew.bat +++ b/exercises/practice/go-counting/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/go-counting/src/test/java/GoCountingTest.java b/exercises/practice/go-counting/src/test/java/GoCountingTest.java index 48e14dc78..2b336088c 100644 --- a/exercises/practice/go-counting/src/test/java/GoCountingTest.java +++ b/exercises/practice/go-counting/src/test/java/GoCountingTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.awt.*; @@ -18,6 +19,7 @@ public class GoCountingTest { " W "; @Test + @DisplayName("Black corner territory on 5x5 board") public void blackCorner5x5BoardTest() { GoCounting gocounting = new GoCounting(board5x5); @@ -32,6 +34,7 @@ public void blackCorner5x5BoardTest() { @Disabled("Remove to run test") @Test + @DisplayName("White center territory on 5x5 board") public void whiteCenter5x5BoardTest() { GoCounting gocounting = new GoCounting(board5x5); @@ -44,6 +47,7 @@ public void whiteCenter5x5BoardTest() { @Disabled("Remove to run test") @Test + @DisplayName("Open corner territory on 5x5 board") public void openCorner5x5BoardTest() { GoCounting gocounting = new GoCounting(board5x5); @@ -58,6 +62,7 @@ public void openCorner5x5BoardTest() { @Disabled("Remove to run test") @Test + @DisplayName("A stone and not a territory on 5x5 board") public void stoneNotTerritory5x5Board() { GoCounting gocounting = new GoCounting(board5x5); @@ -69,6 +74,7 @@ public void stoneNotTerritory5x5Board() { @Disabled("Remove to run test") @Test + @DisplayName("Invalid because X is too low for 5x5 board") public void invalidXTooLow5x5Board() { GoCounting gocounting = new GoCounting(board5x5); @@ -79,6 +85,7 @@ public void invalidXTooLow5x5Board() { @Disabled("Remove to run test") @Test + @DisplayName("Invalid because X is too high for 5x5 board") public void invalidXTooHigh5x5Board() { GoCounting gocounting = new GoCounting(board5x5); @@ -89,6 +96,7 @@ public void invalidXTooHigh5x5Board() { @Disabled("Remove to run test") @Test + @DisplayName("Invalid because Y is too low for 5x5 board") public void invalidYTooLow5x5Board() { GoCounting gocounting = new GoCounting(board5x5); @@ -99,6 +107,7 @@ public void invalidYTooLow5x5Board() { @Disabled("Remove to run test") @Test + @DisplayName("Invalid because Y is too high for 5x5 board") public void invalidYTooHigh5x5Board() { GoCounting gocounting = new GoCounting(board5x5); @@ -109,6 +118,7 @@ public void invalidYTooHigh5x5Board() { @Disabled("Remove to run test") @Test + @DisplayName("One territory is the whole board") public void oneTerritoryIsWholeBoardTest() { GoCounting gocounting = new GoCounting(" "); @@ -127,6 +137,7 @@ public void oneTerritoryIsWholeBoardTest() { @Disabled("Remove to run test") @Test + @DisplayName("Two territory rectangular board") public void twoTerritoryRectangularBoardTest() { GoCounting gocounting = new GoCounting(" BW \n BW "); @@ -150,6 +161,7 @@ public void twoTerritoryRectangularBoardTest() { @Disabled("Remove to run test") @Test + @DisplayName("Two region rectangular board") public void twoRegionRectangularBoardTest() { GoCounting gocounting = new GoCounting(" B "); diff --git a/exercises/practice/grade-school/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/grade-school/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/grade-school/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/grade-school/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/grade-school/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/grade-school/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/grade-school/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/grade-school/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/grade-school/gradlew b/exercises/practice/grade-school/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/grade-school/gradlew +++ b/exercises/practice/grade-school/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/grade-school/gradlew.bat b/exercises/practice/grade-school/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/grade-school/gradlew.bat +++ b/exercises/practice/grade-school/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/grade-school/src/test/java/SchoolTest.java b/exercises/practice/grade-school/src/test/java/SchoolTest.java index 6363b8bd8..10a7fd728 100644 --- a/exercises/practice/grade-school/src/test/java/SchoolTest.java +++ b/exercises/practice/grade-school/src/test/java/SchoolTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -13,18 +14,21 @@ public void setUp() { } @Test + @DisplayName("Roster is empty when no student is added") public void rosterReturnsAnEmptyListIfThereAreNoStudentsEnrolled() { assertThat(school.roster()).isEmpty(); } @Disabled("Remove to run test") @Test + @DisplayName("Add a student") public void addAStudent() { assertThat(school.add("Aimee", 2)).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("Student is added to the roster") public void addingAStudentAddsThemToTheSortedRoster() { school.add("Aimee", 2); @@ -33,6 +37,7 @@ public void addingAStudentAddsThemToTheSortedRoster() { @Disabled("Remove to run test") @Test + @DisplayName("Adding multiple students in the same grade in the roster") public void addingMultipleStudentsInTheSameGrade() { assertThat(school.add("Blair", 2)).isTrue(); assertThat(school.add("James", 2)).isTrue(); @@ -41,6 +46,7 @@ public void addingMultipleStudentsInTheSameGrade() { @Disabled("Remove to run test") @Test + @DisplayName("Multiple students in the same grade are added to the roster") public void addingMoreStudentsAddsThemToTheSameSortedRoster() { school.add("Blair", 2); school.add("James", 2); @@ -51,6 +57,7 @@ public void addingMoreStudentsAddsThemToTheSameSortedRoster() { @Disabled("Remove to run test") @Test + @DisplayName("Cannot add student to same grade in the roster more than once") public void cannotAddStudentsToSameGradeInTheRosterMoreThanOnce() { assertThat(school.add("Blair", 2)).isTrue(); assertThat(school.add("James", 2)).isTrue(); @@ -60,6 +67,7 @@ public void cannotAddStudentsToSameGradeInTheRosterMoreThanOnce() { @Disabled("Remove to run test") @Test + @DisplayName("Student not added to same grade in the roster more than once") public void studentNotAddedToSameGradeInTheRosterMoreThanOnce() { school.add("Blair", 2); school.add("James", 2); @@ -71,6 +79,7 @@ public void studentNotAddedToSameGradeInTheRosterMoreThanOnce() { @Disabled("Remove to run test") @Test + @DisplayName("Adding students in multiple grades") public void addingStudentsInMultipleGrades() { assertThat(school.add("Chelsea", 3)).isTrue(); assertThat(school.add("Logan", 7)).isTrue(); @@ -78,6 +87,7 @@ public void addingStudentsInMultipleGrades() { @Disabled("Remove to run test") @Test + @DisplayName("Students in multiple grades are added to the roster") public void addingStudentsToDifferentGradesAddsThemToTheSameSortedRoster() { school.add("Chelsea", 3); school.add("Logan", 7); @@ -87,6 +97,7 @@ public void addingStudentsToDifferentGradesAddsThemToTheSameSortedRoster() { @Disabled("Remove to run test") @Test + @DisplayName("Cannot add same student to multiple grades in the roster") public void cannotAddSameStudentToMultipleGradesInTheRoster() { assertThat(school.add("Blair", 2)).isTrue(); assertThat(school.add("James", 2)).isTrue(); @@ -96,6 +107,7 @@ public void cannotAddSameStudentToMultipleGradesInTheRoster() { @Disabled("Remove to run test") @Test + @DisplayName("Student not added to multiple grades in the roster") public void studentNotAddedToMultipleGradesInTheRoster() { school.add("Blair", 2); school.add("James", 2); @@ -107,6 +119,7 @@ public void studentNotAddedToMultipleGradesInTheRoster() { @Disabled("Remove to run test") @Test + @DisplayName("Students are sorted by grades in the roster") public void studentsAreSortedByGradeInTheRoster() { school.add("Jim", 3); school.add("Peter", 2); @@ -117,6 +130,7 @@ public void studentsAreSortedByGradeInTheRoster() { @Disabled("Remove to run test") @Test + @DisplayName("Students are sorted by name in the roster") public void studentsAreSortedByNameInTheRoster() { school.add("Peter", 2); school.add("Zoe", 2); @@ -127,6 +141,7 @@ public void studentsAreSortedByNameInTheRoster() { @Disabled("Remove to run test") @Test + @DisplayName("Students are sorted by grades and then by name in the roster") public void studentsAreSortedByGradeAndThenByNameInTheRoster() { school.add("Peter", 2); school.add("Anna", 1); @@ -141,12 +156,14 @@ public void studentsAreSortedByGradeAndThenByNameInTheRoster() { @Disabled("Remove to run test") @Test + @DisplayName("Grade is empty if no students in the roster") public void gradeIsEmptyIfNoStudentsInTheRoster() { assertThat(school.grade(1)).isEmpty(); } @Disabled("Remove to run test") @Test + @DisplayName("Grade is empty if no students in that grade") public void gradeIsEmptyIfNoStudentsInThatGrade() { school.add("Peter", 2); school.add("Zoe", 2); @@ -158,6 +175,7 @@ public void gradeIsEmptyIfNoStudentsInThatGrade() { @Disabled("Remove to run test") @Test + @DisplayName("Student not added to same grade more than once") public void studentNotAddedToTheSameGradeMoreThanOnce() { school.add("Blair", 2); school.add("James", 2); @@ -169,6 +187,7 @@ public void studentNotAddedToTheSameGradeMoreThanOnce() { @Disabled("Remove to run test") @Test + @DisplayName("Student not added to multiple grades") public void studentNotAddedToMultipleGrades() { school.add("Blair", 2); school.add("James", 2); @@ -181,6 +200,7 @@ public void studentNotAddedToMultipleGrades() { @Disabled("Remove to run test") @Test + @DisplayName("Students are sorted by name in a grade") public void studentsAreSortedByNameInAGrade() { school.add("Franklin", 5); school.add("Bradley", 5); diff --git a/exercises/practice/grains/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/grains/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/grains/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/grains/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/grains/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/grains/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/grains/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/grains/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/grains/gradlew b/exercises/practice/grains/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/grains/gradlew +++ b/exercises/practice/grains/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/grains/gradlew.bat b/exercises/practice/grains/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/grains/gradlew.bat +++ b/exercises/practice/grains/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/grains/src/test/java/GrainsTest.java b/exercises/practice/grains/src/test/java/GrainsTest.java index 2b5a47689..a09e48e88 100644 --- a/exercises/practice/grains/src/test/java/GrainsTest.java +++ b/exercises/practice/grains/src/test/java/GrainsTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.math.BigInteger; @@ -11,6 +12,7 @@ public class GrainsTest { private Grains grains = new Grains(); @Test + @DisplayName("returns the number of grains on the square") public void countAtSquare1() { BigInteger result = grains.grainsOnSquare(1); assertThat(result).isEqualTo(new BigInteger("1")); @@ -18,6 +20,7 @@ public void countAtSquare1() { @Disabled("Remove to run test") @Test + @DisplayName("grains on square 2") public void countAtSquare2() { BigInteger result = grains.grainsOnSquare(2); assertThat(result).isEqualTo(new BigInteger("2")); @@ -25,6 +28,7 @@ public void countAtSquare2() { @Disabled("Remove to run test") @Test + @DisplayName("grains on square 3") public void countAtSquare3() { BigInteger result = grains.grainsOnSquare(3); assertThat(result).isEqualTo(new BigInteger("4")); @@ -32,6 +36,7 @@ public void countAtSquare3() { @Disabled("Remove to run test") @Test + @DisplayName("grains on square 4") public void countAtSquare4() { BigInteger result = grains.grainsOnSquare(4); assertThat(result).isEqualTo(new BigInteger("8")); @@ -39,6 +44,7 @@ public void countAtSquare4() { @Disabled("Remove to run test") @Test + @DisplayName("grains on square 16") public void countAtSquare16() { BigInteger result = grains.grainsOnSquare(16); assertThat(result).isEqualTo(new BigInteger("32768")); @@ -46,6 +52,7 @@ public void countAtSquare16() { @Disabled("Remove to run test") @Test + @DisplayName("grains on square 32") public void countAtSquare32() { BigInteger result = grains.grainsOnSquare(32); assertThat(result).isEqualTo(new BigInteger("2147483648")); @@ -53,6 +60,7 @@ public void countAtSquare32() { @Disabled("Remove to run test") @Test + @DisplayName("grains on square 64") public void countAtSquare64() { BigInteger result = grains.grainsOnSquare(64); assertThat(result).isEqualTo(new BigInteger("9223372036854775808")); @@ -60,6 +68,7 @@ public void countAtSquare64() { @Disabled("Remove to run test") @Test + @DisplayName("square 0 is invalid") public void errorOnNullBoardSize() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> grains.grainsOnSquare(0)) @@ -68,6 +77,7 @@ public void errorOnNullBoardSize() { @Disabled("Remove to run test") @Test + @DisplayName("negative square is invalid") public void errorOnNegativeBoardSize() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> grains.grainsOnSquare(-1)) @@ -76,6 +86,7 @@ public void errorOnNegativeBoardSize() { @Disabled("Remove to run test") @Test + @DisplayName("square greater than 64 is invalid") public void errorOnExcessiveBoardSize() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> grains.grainsOnSquare(65)) @@ -84,6 +95,7 @@ public void errorOnExcessiveBoardSize() { @Disabled("Remove to run test") @Test + @DisplayName("returns the total number of grains on the board") public void totalNumberOfGrainsOnABoard() { BigInteger total = grains.grainsOnBoard(); assertThat(total).isEqualTo(new BigInteger("18446744073709551615")); diff --git a/exercises/practice/grep/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/grep/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/grep/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/grep/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/grep/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/grep/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/grep/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/grep/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/grep/gradlew b/exercises/practice/grep/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/grep/gradlew +++ b/exercises/practice/grep/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/grep/gradlew.bat b/exercises/practice/grep/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/grep/gradlew.bat +++ b/exercises/practice/grep/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/grep/src/test/java/GrepToolTest.java b/exercises/practice/grep/src/test/java/GrepToolTest.java index 54c194ca2..d6d27816d 100644 --- a/exercises/practice/grep/src/test/java/GrepToolTest.java +++ b/exercises/practice/grep/src/test/java/GrepToolTest.java @@ -1,6 +1,7 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.io.IOException; @@ -66,6 +67,7 @@ public void tearDown() throws IOException { } @Test + @DisplayName("One file, one match, no flags") public void oneFileOneMatchNoFlags() { String expected = "Of Atreus, Agamemnon, King of men."; @@ -80,6 +82,7 @@ public void oneFileOneMatchNoFlags() { @Disabled("Remove to run test") @Test + @DisplayName("One file, one match, print line numbers flag") public void oneFileOneMatchPrintLineNumbersFlag() { String expected = "2:Of that Forbidden Tree, whose mortal tast"; @@ -94,6 +97,7 @@ public void oneFileOneMatchPrintLineNumbersFlag() { @Disabled("Remove to run test") @Test + @DisplayName("One file, one match, case-insensitive flag") public void oneFileOneMatchCaseInsensitiveFlag() { String expected = "Of that Forbidden Tree, whose mortal tast"; @@ -108,6 +112,7 @@ public void oneFileOneMatchCaseInsensitiveFlag() { @Disabled("Remove to run test") @Test + @DisplayName("One file, one match, print file names flag") public void oneFileOneMatchPrintFileNamesFlag() { String expected = "paradise-lost.txt"; @@ -122,6 +127,7 @@ public void oneFileOneMatchPrintFileNamesFlag() { @Disabled("Remove to run test") @Test + @DisplayName("One file, one match, match entire lines flag") public void oneFileOneMatchEntireLinesFlag() { String expected = "With loss of Eden, till one greater Man"; @@ -136,6 +142,7 @@ public void oneFileOneMatchEntireLinesFlag() { @Disabled("Remove to run test") @Test + @DisplayName("One file, one match, multiple flags") public void oneFileOneMatchMultipleFlags() { String expected = "9:Of Atreus, Agamemnon, King of men."; @@ -150,6 +157,7 @@ public void oneFileOneMatchMultipleFlags() { @Disabled("Remove to run test") @Test + @DisplayName("One file, several matches, no flags") public void oneFileSeveralMatchesNoFlags() { String expected = "Nor how it may concern my modesty,\n" + "But I beseech your grace that I may know\n" @@ -166,6 +174,7 @@ public void oneFileSeveralMatchesNoFlags() { @Disabled("Remove to run test") @Test + @DisplayName("One file, several matches, print line numbers flag") public void oneFileSeveralMatchesPrintLineNumbersFlag() { String expected = "3:Nor how it may concern my modesty,\n" + "5:But I beseech your grace that I may know\n" @@ -182,6 +191,7 @@ public void oneFileSeveralMatchesPrintLineNumbersFlag() { @Disabled("Remove to run test") @Test + @DisplayName("One file, several matches, match entire lines flag") public void oneFileSeveralMatchesMatchEntireLineFlag() { String expected = ""; @@ -196,6 +206,7 @@ public void oneFileSeveralMatchesMatchEntireLineFlag() { @Disabled("Remove to run test") @Test + @DisplayName("One file, several matches, case-insensitive flag") public void oneFileSeveralMatchesCaseInsensitiveFlag() { String expected = "Achilles sing, O Goddess! Peleus' son;\n" + "The noble Chief Achilles from the son"; @@ -211,6 +222,7 @@ public void oneFileSeveralMatchesCaseInsensitiveFlag() { @Disabled("Remove to run test") @Test + @DisplayName("One file, several matches, inverted flag") public void oneFileSeveralMatchesInvertedFlag() { String expected = "Brought Death into the World, and all our woe,\n" + "With loss of Eden, till one greater Man\n" @@ -229,6 +241,7 @@ public void oneFileSeveralMatchesInvertedFlag() { @Disabled("Remove to run test") @Test + @DisplayName("One file, no matches, various flags") public void oneFileNoMatchesVariousFlags() { String expected = ""; @@ -243,6 +256,7 @@ public void oneFileNoMatchesVariousFlags() { @Disabled("Remove to run test") @Test + @DisplayName("One file, one match, file flag takes precedence over line flag") public void oneFileOneMatchFileFlagTakesPrecedenceOverLineFlag() { String expected = "iliad.txt"; @@ -257,6 +271,7 @@ public void oneFileOneMatchFileFlagTakesPrecedenceOverLineFlag() { @Disabled("Remove to run test") @Test + @DisplayName("One file, several matches, inverted and match entire lines flags") public void oneFileSeveralMatchesInvertedAndMatchEntireLinesFlags() { String expected = "Achilles sing, O Goddess! Peleus' son;\n" + "His wrath pernicious, who ten thousand woes\n" @@ -278,6 +293,7 @@ public void oneFileSeveralMatchesInvertedAndMatchEntireLinesFlags() { @Disabled("Remove to run test") @Test + @DisplayName("Multiple files, one match, no flags") public void multipleFilesOneMatchNoFlags() { String expected = "iliad.txt:Of Atreus, Agamemnon, King of men."; @@ -292,6 +308,7 @@ public void multipleFilesOneMatchNoFlags() { @Disabled("Remove to run test") @Test + @DisplayName("Multiple files, several matches, no flags") public void multipleFilesSeveralMatchesNoFlags() { String expected = "midsummer-night.txt:Nor how it may concern my modesty,\n" + "midsummer-night.txt:But I beseech your grace that I may know\n" @@ -308,6 +325,7 @@ public void multipleFilesSeveralMatchesNoFlags() { @Disabled("Remove to run test") @Test + @DisplayName("Multiple files, several matches, print line numbers flag") public void multipleFilesSeveralMatchesPrintLineNumbersFlag() { String expected = "midsummer-night.txt:5:But I beseech your grace that I may know\n" + "midsummer-night.txt:6:The worst that may befall me in this case,\n" @@ -325,6 +343,7 @@ public void multipleFilesSeveralMatchesPrintLineNumbersFlag() { @Disabled("Remove to run test") @Test + @DisplayName("Multiple files, one match, print file names flag") public void multipleFilesOneMatchPrintFileNamesFlag() { String expected = "iliad.txt\n" + "paradise-lost.txt"; @@ -340,6 +359,7 @@ public void multipleFilesOneMatchPrintFileNamesFlag() { @Disabled("Remove to run test") @Test + @DisplayName("Multiple files, several matches, case-insensitive flag") public void multipleFilesSeveralMatchesCaseInsensitiveFlag() { String expected = "iliad.txt:Caused to Achaia's host, sent many a soul\n" + "iliad.txt:Illustrious into Ades premature,\n" @@ -363,6 +383,7 @@ public void multipleFilesSeveralMatchesCaseInsensitiveFlag() { @Disabled("Remove to run test") @Test + @DisplayName("Multiple files, several matches, inverted flag") public void multipleFilesSeveralMatchesInvertedFlag() { String expected = "iliad.txt:Achilles sing, O Goddess! Peleus' son;\n" + "iliad.txt:The noble Chief Achilles from the son\n" @@ -379,6 +400,7 @@ public void multipleFilesSeveralMatchesInvertedFlag() { @Disabled("Remove to run test") @Test + @DisplayName("Multiple files, one match, match entire lines flag") public void multipleFilesOneMatchEntireLinesFlag() { String expected = "midsummer-night.txt:But I beseech your grace that I may know"; @@ -393,6 +415,7 @@ public void multipleFilesOneMatchEntireLinesFlag() { @Disabled("Remove to run test") @Test + @DisplayName("Multiple files, one match, multiple flags") public void multipleFilesOneMatchMultipleFlags() { String expected = "paradise-lost.txt:4:With loss of Eden, till one greater Man"; @@ -407,6 +430,7 @@ public void multipleFilesOneMatchMultipleFlags() { @Disabled("Remove to run test") @Test + @DisplayName("Multiple files, no matches, various flags") public void multipleFilesNoMatchesVariousFlags() { String expected = ""; @@ -421,6 +445,7 @@ public void multipleFilesNoMatchesVariousFlags() { @Disabled("Remove to run test") @Test + @DisplayName("Multiple files, several matches, file flag takes precedence over line number flag") public void multipleFilesSeveralMatchesFileFlagTakesPrecedenceOverLineNumberFlag() { String expected = "iliad.txt\n" + "paradise-lost.txt"; @@ -436,6 +461,7 @@ public void multipleFilesSeveralMatchesFileFlagTakesPrecedenceOverLineNumberFlag @Disabled("Remove to run test") @Test + @DisplayName("Multiple files, several matches, inverted and match entire lines flags") public void multipleFilesSeveralMatchesInvertedAndMatchEntireLinesFlags() { String expected = "iliad.txt:Achilles sing, O Goddess! Peleus' son;\n" + "iliad.txt:His wrath pernicious, who ten thousand woes\n" diff --git a/exercises/practice/hamming/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/hamming/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/hamming/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/hamming/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/hamming/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/hamming/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/hamming/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/hamming/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/hamming/gradlew b/exercises/practice/hamming/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/hamming/gradlew +++ b/exercises/practice/hamming/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/hamming/gradlew.bat b/exercises/practice/hamming/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/hamming/gradlew.bat +++ b/exercises/practice/hamming/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/hamming/src/test/java/HammingTest.java b/exercises/practice/hamming/src/test/java/HammingTest.java index 5f9082e35..26f22491f 100644 --- a/exercises/practice/hamming/src/test/java/HammingTest.java +++ b/exercises/practice/hamming/src/test/java/HammingTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -7,36 +8,42 @@ public class HammingTest { @Test + @DisplayName("empty strands") public void testNoDistanceBetweenEmptyStrands() { assertThat(new Hamming("", "").getHammingDistance()).isEqualTo(0); } @Disabled("Remove to run test") @Test + @DisplayName("single letter identical strands") public void testNoDistanceBetweenShortIdenticalStrands() { assertThat(new Hamming("A", "A").getHammingDistance()).isEqualTo(0); } @Disabled("Remove to run test") @Test + @DisplayName("single letter different strands") public void testCompleteDistanceInSingleLetterDifferentStrands() { assertThat(new Hamming("G", "T").getHammingDistance()).isEqualTo(1); } @Disabled("Remove to run test") @Test + @DisplayName("long identical strands") public void testDistanceInLongIdenticalStrands() { assertThat(new Hamming("GGACTGAAATCTG", "GGACTGAAATCTG").getHammingDistance()).isEqualTo(0); } @Disabled("Remove to run test") @Test + @DisplayName("long different strands") public void testDistanceInLongDifferentStrands() { assertThat(new Hamming("GGACGGATTCTG", "AGGACGGATTCT").getHammingDistance()).isEqualTo(9); } @Disabled("Remove to run test") @Test + @DisplayName("disallow first strand longer") public void testValidatesFirstStrandNotLonger() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> new Hamming("AATG", "AAA")) @@ -45,6 +52,7 @@ public void testValidatesFirstStrandNotLonger() { @Disabled("Remove to run test") @Test + @DisplayName("disallow second strand longer") public void testValidatesSecondStrandNotLonger() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> new Hamming("ATA", "AGTG")) @@ -53,6 +61,7 @@ public void testValidatesSecondStrandNotLonger() { @Disabled("Remove to run test") @Test + @DisplayName("disallow left empty strand") public void testDisallowLeftEmptyStrand() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> new Hamming("", "G")) @@ -61,6 +70,7 @@ public void testDisallowLeftEmptyStrand() { @Disabled("Remove to run test") @Test + @DisplayName("disallow right empty strand") public void testDisallowRightEmptyStrand() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> new Hamming("G", "")) diff --git a/exercises/practice/hangman/build.gradle b/exercises/practice/hangman/build.gradle index 15df104cc..a55dc26f3 100644 --- a/exercises/practice/hangman/build.gradle +++ b/exercises/practice/hangman/build.gradle @@ -12,6 +12,8 @@ dependencies { testImplementation platform("org.junit:junit-bom:5.10.0") testImplementation "org.junit.jupiter:junit-jupiter" testImplementation "org.assertj:assertj-core:3.25.1" + + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } test { diff --git a/exercises/practice/hangman/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/hangman/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/hangman/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/hangman/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/hangman/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/hangman/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/hangman/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/hangman/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/hangman/gradlew b/exercises/practice/hangman/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/hangman/gradlew +++ b/exercises/practice/hangman/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/hangman/gradlew.bat b/exercises/practice/hangman/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/hangman/gradlew.bat +++ b/exercises/practice/hangman/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/hangman/src/test/java/HangmanTest.java b/exercises/practice/hangman/src/test/java/HangmanTest.java index df60dbee9..d4bbe13da 100644 --- a/exercises/practice/hangman/src/test/java/HangmanTest.java +++ b/exercises/practice/hangman/src/test/java/HangmanTest.java @@ -1,8 +1,10 @@ import io.reactivex.Observable; import io.reactivex.ObservableEmitter; import io.reactivex.disposables.Disposable; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.ArrayList; @@ -22,6 +24,7 @@ public void init() { } @Test + @DisplayName("Initial game state is set correctly") public void initialization() { Observable result = hangman.play( Observable.fromArray("secret"), @@ -39,6 +42,7 @@ public void initialization() { @Disabled("Remove to run test") @Test + @DisplayName("First correct guess updates discovered and guess lists") public void firstGuess() { Observable result = hangman.play( Observable.fromArray("secret"), @@ -54,6 +58,7 @@ public void firstGuess() { @Disabled("Remove to run test") @Test + @DisplayName("First incorrect guess registers a miss and adds a part") public void firstMiss() { Observable result = hangman.play( Observable.fromArray("secret"), @@ -69,6 +74,7 @@ public void firstMiss() { @Disabled("Remove to run test") @Test + @DisplayName("Game in progress accumulates guesses, misses and parts correctly") public void gameInProgress() { Observable result = hangman.play( Observable.fromArray("secret"), @@ -84,6 +90,7 @@ public void gameInProgress() { @Disabled("Remove to run test") @Test + @DisplayName("Winning the game results in WIN status") public void wonGame() { Observable result = hangman.play( Observable.fromArray("secret"), @@ -97,6 +104,7 @@ public void wonGame() { @Disabled("Remove to run test") @Test + @DisplayName("Losing the game results in LOSS status") public void lostGame() { Observable result = hangman.play( Observable.fromArray("secret"), @@ -118,6 +126,7 @@ public void lostGame() { @Disabled("Remove to run test") @Test + @DisplayName("Handles consecutive games correctly with ordered emissions") public void consecutiveGames() { // This test setup is more complex because we have to order the emission of values in the // different observers. @@ -189,6 +198,7 @@ Observable createLetterObservable(ObservableEmitter[] emitters, Runnable emit) { @Disabled("Remove to run test") @Test + @DisplayName("Cannot play the same guess twice") public void cannotPlayAGuessTwice() { Observable result = hangman.play( Observable.fromArray("secret"), @@ -201,6 +211,7 @@ public void cannotPlayAGuessTwice() { @Disabled("Remove to run test") @Test + @DisplayName("Cannot play the same miss twice") public void cannotPlayAMissTwice() { Observable result = hangman.play( Observable.fromArray("secret"), diff --git a/exercises/practice/hello-world/.docs/instructions.append.md b/exercises/practice/hello-world/.docs/instructions.append.md index f70c88daa..f1580cb34 100644 --- a/exercises/practice/hello-world/.docs/instructions.append.md +++ b/exercises/practice/hello-world/.docs/instructions.append.md @@ -112,13 +112,13 @@ Seeing both kinds can be instructive and interesting. Mentors review submitted solutions for the track they've chosen to mentor to help users learn as much as possible. -To read more about mentoring, go to the following [link][Mentoring]. +To read more about mentoring, go to the [Exercism docs][Mentoring]. ### Contribute to Exercism The entire of Exercism is Open Source and is a labor of love for over 100 maintainers and many more contributors. -A starting point to jumping in and becoming a contributor can be found [here][Contributing]. +A starting point to jumping in and becoming a contributor can be found in the [Exercism contributing guide][Contributing]. [Tutorial]: #tutorial [Introduction]: #introduction diff --git a/exercises/practice/hello-world/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/hello-world/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/hello-world/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/hello-world/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/hello-world/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/hello-world/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/hello-world/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/hello-world/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/hello-world/gradlew b/exercises/practice/hello-world/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/hello-world/gradlew +++ b/exercises/practice/hello-world/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/hello-world/gradlew.bat b/exercises/practice/hello-world/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/hello-world/gradlew.bat +++ b/exercises/practice/hello-world/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/hello-world/src/test/java/GreeterTest.java b/exercises/practice/hello-world/src/test/java/GreeterTest.java index fc25c1891..cd5fb79a3 100644 --- a/exercises/practice/hello-world/src/test/java/GreeterTest.java +++ b/exercises/practice/hello-world/src/test/java/GreeterTest.java @@ -1,3 +1,4 @@ +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -5,6 +6,7 @@ public class GreeterTest { @Test + @DisplayName("Say Hi!") public void testThatGreeterReturnsTheCorrectGreeting() { assertThat(new Greeter().getGreeting()).isEqualTo("Hello, World!"); } diff --git a/exercises/practice/high-scores/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/high-scores/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/high-scores/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/high-scores/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/high-scores/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/high-scores/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/high-scores/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/high-scores/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/high-scores/gradlew b/exercises/practice/high-scores/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/high-scores/gradlew +++ b/exercises/practice/high-scores/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/high-scores/gradlew.bat b/exercises/practice/high-scores/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/high-scores/gradlew.bat +++ b/exercises/practice/high-scores/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/high-scores/src/test/java/HighScoresTest.java b/exercises/practice/high-scores/src/test/java/HighScoresTest.java index 15fd8eaa4..282d09c6e 100644 --- a/exercises/practice/high-scores/src/test/java/HighScoresTest.java +++ b/exercises/practice/high-scores/src/test/java/HighScoresTest.java @@ -1,6 +1,7 @@ import java.util.Arrays; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -8,6 +9,7 @@ public class HighScoresTest { @Test + @DisplayName("List of scores") public void shouldReturnListOfScores() { HighScores highScores = new HighScores(Arrays.asList(30, 50, 20, 70)); assertThat(highScores.scores()).isEqualTo(Arrays.asList(30, 50, 20, 70)); @@ -15,6 +17,7 @@ public void shouldReturnListOfScores() { @Test @Disabled("Remove to run test") + @DisplayName("Latest score") public void shouldReturnLatestAddedScore() { HighScores highScores = new HighScores(Arrays.asList(100, 0, 90, 30)); assertThat(highScores.latest()).isEqualTo(30); @@ -22,6 +25,7 @@ public void shouldReturnLatestAddedScore() { @Test @Disabled("Remove to run test") + @DisplayName("Personal best") public void shouldReturnPersonalBest() { HighScores highScores = new HighScores(Arrays.asList(40, 100, 70)); assertThat(highScores.personalBest()).isEqualTo(100); @@ -29,6 +33,7 @@ public void shouldReturnPersonalBest() { @Test @Disabled("Remove to run test") + @DisplayName("Personal top three from a list of scores") public void shouldReturnPersonalTopThreeFromListOfScores() { HighScores highScores = new HighScores(Arrays.asList(10, 30, 90, 30, 100, 20, 10, 0, 30, 40, 40, 70, 70)); assertThat(highScores.personalTopThree()).isEqualTo(Arrays.asList(100, 90, 70)); @@ -36,6 +41,7 @@ public void shouldReturnPersonalTopThreeFromListOfScores() { @Test @Disabled("Remove to run test") + @DisplayName("Personal top highest to lowest") public void shouldReturnPersonalTopThreeSortedHighestToLowest() { HighScores highScores = new HighScores(Arrays.asList(20, 10, 30)); assertThat(highScores.personalTopThree()).isEqualTo(Arrays.asList(30, 20, 10)); @@ -43,6 +49,7 @@ public void shouldReturnPersonalTopThreeSortedHighestToLowest() { @Test @Disabled("Remove to run test") + @DisplayName("Personal top when there is a tie") public void shouldReturnPersonalTopThreeWhenThereIsATie() { HighScores highScores = new HighScores(Arrays.asList(40, 20, 40, 30)); assertThat(highScores.personalTopThree()).isEqualTo(Arrays.asList(40, 40, 30)); @@ -50,6 +57,7 @@ public void shouldReturnPersonalTopThreeWhenThereIsATie() { @Test @Disabled("Remove to run test") + @DisplayName("Personal top when there are less than 3") public void shouldReturnPersonalTopWhenThereIsLessThanThreeScores() { HighScores highScores = new HighScores(Arrays.asList(30, 70)); assertThat(highScores.personalTopThree()).isEqualTo(Arrays.asList(70, 30)); @@ -57,6 +65,7 @@ public void shouldReturnPersonalTopWhenThereIsLessThanThreeScores() { @Test @Disabled("Remove to run test") + @DisplayName("Personal top when there is only one") public void shouldReturnPersonalTopWhenThereIsOnlyOneScore() { HighScores highScores = new HighScores(Arrays.asList(40)); assertThat(highScores.personalTopThree()).isEqualTo(Arrays.asList(40)); @@ -64,6 +73,7 @@ public void shouldReturnPersonalTopWhenThereIsOnlyOneScore() { @Test @Disabled("Remove to run test") + @DisplayName("Latest score after personal top scores") public void callingLatestAfterPersonalTopThree() { HighScores highScores = new HighScores(Arrays.asList(70, 50, 20, 30)); highScores.personalTopThree(); @@ -72,6 +82,7 @@ public void callingLatestAfterPersonalTopThree() { @Test @Disabled("Remove to run test") + @DisplayName("Scores after personal top scores") public void callingScoresAfterPersonalTopThree() { HighScores highScores = new HighScores(Arrays.asList(30, 50, 20, 70)); highScores.personalTopThree(); @@ -80,6 +91,7 @@ public void callingScoresAfterPersonalTopThree() { @Test @Disabled("Remove to run test") + @DisplayName("Latest score after personal best") public void callingLatestAfterPersonalBest() { HighScores highScores = new HighScores(Arrays.asList(20, 70, 15, 25, 30)); highScores.personalBest(); @@ -88,6 +100,7 @@ public void callingLatestAfterPersonalBest() { @Test @Disabled("Remove to run test") + @DisplayName("Scores after personal best") public void callingScoresAfterPersonalBest() { HighScores highScores = new HighScores(Arrays.asList(20, 70, 15, 25, 30)); highScores.personalBest(); diff --git a/exercises/practice/house/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/house/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/house/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/house/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/house/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/house/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/house/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/house/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/house/gradlew b/exercises/practice/house/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/house/gradlew +++ b/exercises/practice/house/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/house/gradlew.bat b/exercises/practice/house/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/house/gradlew.bat +++ b/exercises/practice/house/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/house/src/test/java/HouseTest.java b/exercises/practice/house/src/test/java/HouseTest.java index 08c3d3c2e..4841a9d14 100644 --- a/exercises/practice/house/src/test/java/HouseTest.java +++ b/exercises/practice/house/src/test/java/HouseTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.BeforeEach; import static org.assertj.core.api.Assertions.assertThat; @@ -14,6 +15,7 @@ public void setup() { } @Test + @DisplayName("verse one - the house that jack built") public void verseOne() { assertThat(house.verse(1)).isEqualTo( "This is the house that Jack built."); @@ -21,6 +23,7 @@ public void verseOne() { @Disabled("Remove to run test") @Test + @DisplayName("verse two - the malt that lay") public void verseTwo() { assertThat(house.verse(2)).isEqualTo( "This is the malt " + @@ -30,6 +33,7 @@ public void verseTwo() { @Disabled("Remove to run test") @Test + @DisplayName("verse three - the rat that ate") public void verseThree() { assertThat(house.verse(3)).isEqualTo( "This is the rat " + @@ -39,6 +43,7 @@ public void verseThree() { @Disabled("Remove to run test") @Test + @DisplayName("verse four - the cat that killed") public void verseFour() { assertThat(house.verse(4)).isEqualTo( "This is the cat " + @@ -49,6 +54,7 @@ public void verseFour() { @Disabled("Remove to run test") @Test + @DisplayName("verse five - the dog that worried") public void verseFive() { assertThat(house.verse(5)).isEqualTo( "This is the dog " + @@ -60,6 +66,7 @@ public void verseFive() { @Disabled("Remove to run test") @Test + @DisplayName("verse six - the cow with the crumpled horn") public void verseSix() { assertThat(house.verse(6)).isEqualTo( "This is the cow with the crumpled horn " + @@ -72,6 +79,7 @@ public void verseSix() { @Disabled("Remove to run test") @Test + @DisplayName("verse seven - the maiden all forlorn") public void verseSeven() { assertThat(house.verse(7)).isEqualTo( "This is the maiden all forlorn " + @@ -85,6 +93,7 @@ public void verseSeven() { @Disabled("Remove to run test") @Test + @DisplayName("verse eight - the man all tattered and torn") public void verseEight() { assertThat(house.verse(8)).isEqualTo( "This is the man all tattered and torn " + @@ -99,6 +108,7 @@ public void verseEight() { @Disabled("Remove to run test") @Test + @DisplayName("verse nine - the priest all shaven and shorn") public void verseNine() { assertThat(house.verse(9)).isEqualTo( "This is the priest all shaven and shorn " + @@ -114,6 +124,7 @@ public void verseNine() { @Disabled("Remove to run test") @Test + @DisplayName("verse 10 - the rooster that crowed in the morn") public void verse10() { assertThat(house.verse(10)).isEqualTo( "This is the rooster that crowed in the morn " + @@ -130,6 +141,7 @@ public void verse10() { @Disabled("Remove to run test") @Test + @DisplayName("verse 11 - the farmer sowing his corn") public void verse11() { assertThat(house.verse(11)).isEqualTo( "This is the farmer sowing his corn " + @@ -147,6 +159,7 @@ public void verse11() { @Disabled("Remove to run test") @Test + @DisplayName("verse 12 - the horse and the hound and the horn") public void verse12() { assertThat(house.verse(12)).isEqualTo( "This is the horse and the hound and the horn " + @@ -165,6 +178,7 @@ public void verse12() { @Disabled("Remove to run test") @Test + @DisplayName("multiple verses") public void multipleVerses() { int startVerse = 4; int endVerse = 8; @@ -204,6 +218,7 @@ public void multipleVerses() { @Disabled("Remove to run test") @Test + @DisplayName("full rhyme") public void wholeRhyme() { assertThat(house.sing()).isEqualTo( "This is the house that Jack built.\n" + diff --git a/exercises/practice/intergalactic-transmission/.docs/instructions.append.md b/exercises/practice/intergalactic-transmission/.docs/instructions.append.md new file mode 100644 index 000000000..a5f1cad0d --- /dev/null +++ b/exercises/practice/intergalactic-transmission/.docs/instructions.append.md @@ -0,0 +1,3 @@ +# Instructions append + +Although we're dealing with bytes of data, the inputs and outputs are `List` (instead of `byte[]`) to avoid the need to cast or convert negative values for bytes 128 to 255. diff --git a/exercises/practice/intergalactic-transmission/.docs/instructions.md b/exercises/practice/intergalactic-transmission/.docs/instructions.md new file mode 100644 index 000000000..549708817 --- /dev/null +++ b/exercises/practice/intergalactic-transmission/.docs/instructions.md @@ -0,0 +1,54 @@ +# Instructions + +Your job is to help implement + +- the transmitter, which calculates the transmission sequence, and +- the receiver, which decodes it. + +A parity bit is simple way of detecting transmission errors. +The transmitters and receivers can only transmit and receive _exactly_ eight bits at a time (including the parity bit). +The parity bit is set so that there is an _even_ number of 1 bits in each transmission, and the parity bit is always the first bit from the right. +So if the receiver receives `11000001`, `01110101` or `01000000` (i.e. a transmission with an odd number of 1 bits), it knows there is an error. + +However, messages are rarely this short, and need to be transmitted in a sequence when they are longer. + +For example, consider the message `11000000 00000001 11000000 11011110` (or `C0 01 C0 DE` in hex). + +Since each transmission contains exactly eight bits, it can only contain seven bits of data and the parity bit. +A parity bit must then be inserted after every seven bits of data: + +```text +11000000 00000001 11000000 11011110 + ↑ ↑ ↑ ↑ (7th bits) +``` + +The transmission sequence for this message looks like this: + +```text +1100000_ 0000000_ 0111000_ 0001101_ 1110 + ↑ ↑ ↑ ↑ (parity bits) +``` + +The data in the first transmission in the sequence (`1100000`) has two 1 bits (an even number), so the parity bit is 0. +The first transmission becomes `11000000` (or `C0` in hex). + +The data in the next transmission (`0000000`) has zero 1 bits (an even number again), so the parity bit is 0 again. +The second transmission thus becomes `00000000` (or `00` in hex). + +The data for the next two transmissions (`0111000` and `0001101`) have three 1 bits. +Their parity bits are set to 1 so that they have an even number of 1 bits in the transmission. +They are transmitted as `01110001` and `00011011` (or `71` and `1B` in hex). + +The last transmission (`1110`) has only four bits of data. +Since exactly eight bits are transmitted at a time and the parity bit is the rightmost bit, three 0 bits and then the parity bit are added to make up eight bits. +It now looks like this (where `_` is the parity bit): + +```text +1110 000_ + ↑↑↑ (added 0 bits) +``` + +There is an odd number of 1 bits again, so the parity bit is 1. +The last transmission in the sequence becomes `11100001` (or `E1` in hex). + +The entire transmission sequence for this message is `11000000 00000000 01110001 00011011 11100001` (or `C0 00 71 1B E1` in hex). diff --git a/exercises/practice/intergalactic-transmission/.docs/introduction.md b/exercises/practice/intergalactic-transmission/.docs/introduction.md new file mode 100644 index 000000000..f19dffbea --- /dev/null +++ b/exercises/practice/intergalactic-transmission/.docs/introduction.md @@ -0,0 +1,23 @@ +# Introduction + +Trillions upon trillions of messages zip between Earth and neighboring galaxies every millisecond. +But transmitting over such long distances is tricky. +Pesky solar flares, temporal distortions, stray forces, and even the flap of a space butterfly's wing can cause a random bit to change during transmission. + +Now imagine the consequences: + +- Crashing the Intergalactic Share Market when "buy low" turns to "sell now". +- Losing contact with the Kepler Whirl system when "save new worm hole" becomes "cave new worm hole". +- Or plunging the universe into existential horror by replacing a cowboy emoji 🤠 with a clown emoji 🤡. + +Detecting corrupted messages isn't just important — it's critical. +The receiver _must_ know when something has gone wrong before disaster strikes. + +But how? +Scientists and engineers from across the universe have been battling this problem for eons. +Entire cosmic AI superclusters churn through the data. +And then, one day, a legend resurfaces — an ancient, powerful method, whispered in debugging forums, muttered by engineers who've seen too much... + +The Parity Bit! + +A method so simple, so powerful, that it might just save interstellar communication. diff --git a/exercises/practice/intergalactic-transmission/.meta/config.json b/exercises/practice/intergalactic-transmission/.meta/config.json new file mode 100644 index 000000000..f0bc8ae9d --- /dev/null +++ b/exercises/practice/intergalactic-transmission/.meta/config.json @@ -0,0 +1,22 @@ +{ + "authors": [ + "jagdish-15" + ], + "files": { + "solution": [ + "src/main/java/IntergalacticTransmission.java" + ], + "test": [ + "src/test/java/IntergalacticTransmissionTest.java" + ], + "example": [ + ".meta/src/reference/java/IntergalacticTransmission.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Add parity bits to a message for transmission", + "source": "Kah Goh", + "source_url": "https://github.com/exercism/problem-specifications/pull/2543" +} diff --git a/exercises/practice/intergalactic-transmission/.meta/src/reference/java/IntergalacticTransmission.java b/exercises/practice/intergalactic-transmission/.meta/src/reference/java/IntergalacticTransmission.java new file mode 100644 index 000000000..d27721e1d --- /dev/null +++ b/exercises/practice/intergalactic-transmission/.meta/src/reference/java/IntergalacticTransmission.java @@ -0,0 +1,82 @@ +import java.util.ArrayList; +import java.util.List; + +public class IntergalacticTransmission { + + private static final byte INIT_UPPER_MASK = (byte) 0xFE; + + public static List getTransmitSequence(List message) { + List transmitSeq = new ArrayList<>(); + byte carry = 0; + byte upperMask = INIT_UPPER_MASK; + + for (int i = 0; i < message.size(); i++) { + byte currentByte = message.get(i).byteValue(); + + if (upperMask == 0) { + transmitSeq.add((int) addParity(carry) & 0xFF); + carry = 0; + upperMask = (byte) 0xFE; + } + + int shiftPlaces = Integer.numberOfTrailingZeros(upperMask & 0xFF); + int current = ((carry & 0xFF) << (8 - shiftPlaces)) | ((currentByte & 0xFF) >>> shiftPlaces); + transmitSeq.add((int) addParity((byte) current) & 0xFF); + + carry = (byte) (currentByte & ~upperMask); + upperMask = (byte) (upperMask << 1); + } + + if (upperMask != INIT_UPPER_MASK) { + byte lastGroup = (byte) ((carry & 0xFF) << Integer.bitCount(upperMask & 0xFF)); + transmitSeq.add((int) addParity(lastGroup) & 0xFF); + } + + return transmitSeq; + } + + private static byte addParity(byte source) { + if (Integer.bitCount(source & 0x7F) % 2 == 0) { + return (byte) (source << 1); + } else { + return (byte) ((source << 1) | 1); + } + } + + public static List decodeSequence(List receivedSeq) { + if (receivedSeq.isEmpty()) { + return new ArrayList<>(); + } + + List decodedMessage = new ArrayList<>(); + byte byteToAdd = 0x00; + byte upperMask = (byte) 0xFF; + + for (int i = 0; i < receivedSeq.size(); i++) { + byte currentByte = receivedSeq.get(i).byteValue(); + + if (upperMask == (byte) 0xFF) { + byteToAdd = getByteData(currentByte); + upperMask = (byte) 0x80; + continue; + } + + byte currentByteData = getByteData(currentByte); + int shiftPlaces = Integer.numberOfTrailingZeros(upperMask & 0xFF); + byte contribution = (byte) ((currentByteData & 0xFF) >>> shiftPlaces); + decodedMessage.add((byteToAdd | contribution) & 0xFF); + + byteToAdd = (byte) (((currentByteData & ~(upperMask | 0x01)) & 0xFF) << Integer.bitCount(upperMask & 0xFF)); + upperMask = (byte) (((upperMask & 0xFF) >>> 1) | 0x80); + } + + return decodedMessage; + } + + private static byte getByteData(byte data) { + if (Integer.bitCount(data & 0xFF) % 2 != 0) { + throw new IllegalArgumentException("Byte has incorrect parity"); + } + return (byte) (data & 0xFE); + } +} diff --git a/exercises/practice/intergalactic-transmission/.meta/tests.toml b/exercises/practice/intergalactic-transmission/.meta/tests.toml new file mode 100644 index 000000000..64a8aaced --- /dev/null +++ b/exercises/practice/intergalactic-transmission/.meta/tests.toml @@ -0,0 +1,88 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[f99d4046-b429-4582-9324-f0bcac7ab51c] +description = "calculate transmit sequences -> empty message" + +[ee27ea2d-8999-4f23-9275-8f6879545f86] +description = "calculate transmit sequences -> 0x00 is transmitted as 0x0000" + +[97f27f98-8020-402d-be85-f21ba54a6df0] +description = "calculate transmit sequences -> 0x02 is transmitted as 0x0300" + +[24712fb9-0336-4e2f-835e-d2350f29c420] +description = "calculate transmit sequences -> 0x06 is transmitted as 0x0600" + +[7630b5a9-dba1-4178-b2a0-4a376f7414e0] +description = "calculate transmit sequences -> 0x05 is transmitted as 0x0581" + +[ab4fe80b-ef8e-4a99-b4fb-001937af415d] +description = "calculate transmit sequences -> 0x29 is transmitted as 0x2881" + +[4e200d84-593b-4449-b7c0-4de1b6a0955e] +description = "calculate transmit sequences -> 0xc001c0de is transmitted as 0xc000711be1" + +[fbc537e9-6b21-4f4a-8c2b-9cf9b702a9b7] +description = "calculate transmit sequences -> six byte message" + +[d5b75adf-b5fc-4f77-b4ab-77653e30f07c] +description = "calculate transmit sequences -> seven byte message" + +[6d8b297b-da1d-435e-bcd7-55fbb1400e73] +description = "calculate transmit sequences -> eight byte message" + +[54a0642a-d5aa-490c-be89-8e171a0cab6f] +description = "calculate transmit sequences -> twenty byte message" + +[9a8084dd-3336-474c-90cb-8a852524604d] +description = "decode received messages -> empty message" + +[879af739-0094-4736-9127-bd441b1ddbbf] +description = "decode received messages -> zero message" + +[7a89eeef-96c5-4329-a246-ec181a8e959a] +description = "decode received messages -> 0x0300 is decoded to 0x02" + +[3e515af7-8b62-417f-960c-3454bca7f806] +description = "decode received messages -> 0x0581 is decoded to 0x05" + +[a1b4a3f7-9f05-4b7a-b86e-d7c6fc3f16a9] +description = "decode received messages -> 0x2881 is decoded to 0x29" + +[2e99d617-4c91-4ad5-9217-e4b2447d6e4a] +description = "decode received messages -> first byte has wrong parity" + +[507e212d-3dae-42e8-88b4-2223838ff8d2] +description = "decode received messages -> second byte has wrong parity" + +[b985692e-6338-46c7-8cea-bc38996d4dfd] +description = "decode received messages -> 0xcf4b00 is decoded to 0xce94" + +[7a1f4d48-696d-4679-917c-21b7da3ff3fd] +description = "decode received messages -> 0xe2566500 is decoded to 0xe2ad90" + +[467549dc-a558-443b-80c5-ff3d4eb305d4] +description = "decode received messages -> six byte message" + +[1f3be5fb-093a-4661-9951-c1c4781c71ea] +description = "decode received messages -> seven byte message" + +[6065b8b3-9dcd-45c9-918c-b427cfdb28c1] +description = "decode received messages -> last byte has wrong parity" + +[98af97b7-9cca-4c4c-9de3-f70e227a4cb1] +description = "decode received messages -> eight byte message" + +[aa7d4785-2bb9-43a4-a38a-203325c464fb] +description = "decode received messages -> twenty byte message" + +[4c86e034-b066-42ac-8497-48f9bc1723c1] +description = "decode received messages -> wrong parity on 16th byte" diff --git a/exercises/practice/intergalactic-transmission/build.gradle b/exercises/practice/intergalactic-transmission/build.gradle new file mode 100644 index 000000000..d28f35dee --- /dev/null +++ b/exercises/practice/intergalactic-transmission/build.gradle @@ -0,0 +1,25 @@ +plugins { + id "java" +} + +repositories { + mavenCentral() +} + +dependencies { + testImplementation platform("org.junit:junit-bom:5.10.0") + testImplementation "org.junit.jupiter:junit-jupiter" + testImplementation "org.assertj:assertj-core:3.25.1" + + testRuntimeOnly "org.junit.platform:junit-platform-launcher" +} + +test { + useJUnitPlatform() + + testLogging { + exceptionFormat = "full" + showStandardStreams = true + events = ["passed", "failed", "skipped"] + } +} diff --git a/exercises/practice/intergalactic-transmission/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/intergalactic-transmission/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..f8e1ee312 Binary files /dev/null and b/exercises/practice/intergalactic-transmission/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/intergalactic-transmission/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/intergalactic-transmission/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..4d97ea344 --- /dev/null +++ b/exercises/practice/intergalactic-transmission/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/exercises/practice/intergalactic-transmission/gradlew b/exercises/practice/intergalactic-transmission/gradlew new file mode 100755 index 000000000..adff685a0 --- /dev/null +++ b/exercises/practice/intergalactic-transmission/gradlew @@ -0,0 +1,248 @@ +#!/bin/sh + +# +# Copyright © 2015 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/exercises/practice/intergalactic-transmission/gradlew.bat b/exercises/practice/intergalactic-transmission/gradlew.bat new file mode 100644 index 000000000..c4bdd3ab8 --- /dev/null +++ b/exercises/practice/intergalactic-transmission/gradlew.bat @@ -0,0 +1,93 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/exercises/practice/intergalactic-transmission/src/main/java/IntergalacticTransmission.java b/exercises/practice/intergalactic-transmission/src/main/java/IntergalacticTransmission.java new file mode 100644 index 000000000..57541078f --- /dev/null +++ b/exercises/practice/intergalactic-transmission/src/main/java/IntergalacticTransmission.java @@ -0,0 +1,13 @@ +import java.util.List; + +public class IntergalacticTransmission { + + public static List getTransmitSequence(List message) { + throw new UnsupportedOperationException("Delete this statement and write your own implementation."); + } + + public static List decodeSequence(List sequence) { + throw new UnsupportedOperationException("Delete this statement and write your own implementation."); + } + +} diff --git a/exercises/practice/intergalactic-transmission/src/test/java/IntergalacticTransmissionTest.java b/exercises/practice/intergalactic-transmission/src/test/java/IntergalacticTransmissionTest.java new file mode 100644 index 000000000..9c26e13e5 --- /dev/null +++ b/exercises/practice/intergalactic-transmission/src/test/java/IntergalacticTransmissionTest.java @@ -0,0 +1,277 @@ +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class IntergalacticTransmissionTest { + + @Test + @DisplayName("calculate transmit sequences") + public void calculateTransmitSequencesEmptyMessage() { + List input = List.of(); + List expected = List.of(); + assertThat(IntergalacticTransmission.getTransmitSequence(input)) + .isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("0x00 is transmitted as 0x0000") + public void calculateTransmitSequences0x00IsTransmittedAs0x0000() { + List input = List.of(0x00); + List expected = List.of(0x00, 0x00); + assertThat(IntergalacticTransmission.getTransmitSequence(input)) + .isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("0x02 is transmitted as 0x0300") + public void calculateTransmitSequences0x02IsTransmittedAs0x0300() { + List input = List.of(0x02); + List expected = List.of(0x03, 0x00); + assertThat(IntergalacticTransmission.getTransmitSequence(input)) + .isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("0x06 is transmitted as 0x0600") + public void calculateTransmitSequences0x06IsTransmittedAs0x0600() { + List input = List.of(0x06); + List expected = List.of(0x06, 0x00); + assertThat(IntergalacticTransmission.getTransmitSequence(input)) + .isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("0x05 is transmitted as 0x0581") + public void calculateTransmitSequences0x05IsTransmittedAs0x0581() { + List input = List.of(0x05); + List expected = List.of(0x05, 0x81); + assertThat(IntergalacticTransmission.getTransmitSequence(input)) + .isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("0x29 is transmitted as 0x2881") + public void calculateTransmitSequences0x29IsTransmittedAs0x2881() { + List input = List.of(0x29); + List expected = List.of(0x28, 0x81); + assertThat(IntergalacticTransmission.getTransmitSequence(input)) + .isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("0xc001c0de is transmitted as 0xc000711be1") + public void calculateTransmitSequences0xc001c0deIsTransmittedAs0xc000711be1() { + List input = List.of(0xc0, 0x01, 0xc0, 0xde); + List expected = List.of(0xc0, 0x00, 0x71, 0x1b, 0xe1); + assertThat(IntergalacticTransmission.getTransmitSequence(input)) + .isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("six byte message") + public void calculateTransmitSequencesSixByteMessage() { + List input = List.of(0x47, 0x72, 0x65, 0x61, 0x74, 0x21); + List expected = List.of(0x47, 0xb8, 0x99, 0xac, 0x17, 0xa0, 0x84); + assertThat(IntergalacticTransmission.getTransmitSequence(input)) + .isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("at 7 bytes long, no padding is required") + public void calculateTransmitSequencesSevenByteMessage() { + List input = List.of(0x47, 0x72, 0x65, 0x61, 0x74, 0x31, 0x21); + List expected = List.of(0x47, 0xb8, 0x99, 0xac, 0x17, 0xa0, 0xc5, 0x42); + assertThat(IntergalacticTransmission.getTransmitSequence(input)) + .isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("eight byte message") + public void calculateTransmitSequencesEightByteMessage() { + List input = List.of(0xc0, 0x01, 0x13, 0x37, 0xc0, 0xde, 0x21, 0x21); + List expected = List.of(0xc0, 0x00, 0x44, 0x66, 0x7d, 0x06, 0x78, 0x42, 0x21, 0x81); + assertThat(IntergalacticTransmission.getTransmitSequence(input)) + .isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("twenty byte message") + public void calculateTransmitSequencesTwentyByteMessage() { + List input = List.of( + 0x45, 0x78, 0x65, 0x72, 0x63, 0x69, 0x73, 0x6d, 0x20, 0x69, + 0x73, 0x20, 0x61, 0x77, 0x65, 0x73, 0x6f, 0x6d, 0x65, 0x21); + List expected = List.of( + 0x44, 0xbd, 0x18, 0xaf, 0x27, 0x1b, 0xa5, 0xe7, 0x6c, 0x90, + 0x1b, 0x2e, 0x33, 0x03, 0x84, 0xee, 0x65, 0xb8, 0xdb, 0xed, + 0xd7, 0x28, 0x84); + assertThat(IntergalacticTransmission.getTransmitSequence(input)) + .isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("empty message") + public void decodeReceivedMessagesEmptyMessage() { + List input = List.of(); + List expected = List.of(); + assertThat(IntergalacticTransmission.decodeSequence(input)) + .isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("zero message") + public void decodeReceivedMessagesZeroMessage() { + List input = List.of(0x00, 0x00); + List expected = List.of(0x00); + assertThat(IntergalacticTransmission.decodeSequence(input)) + .isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("0x0300 is decoded to 0x02") + public void decodeReceivedMessages0x0300IsDecodedTo0x02() { + List input = List.of(0x03, 0x00); + List expected = List.of(0x02); + assertThat(IntergalacticTransmission.decodeSequence(input)) + .isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("0x0581 is decoded to 0x05") + public void decodeReceivedMessages0x0581IsDecodedTo0x05() { + List input = List.of(0x05, 0x81); + List expected = List.of(0x05); + assertThat(IntergalacticTransmission.decodeSequence(input)) + .isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("0x2881 is decoded to 0x29") + public void decodeReceivedMessages0x2881IsDecodedTo0x29() { + List input = List.of(0x28, 0x81); + List expected = List.of(0x29); + assertThat(IntergalacticTransmission.decodeSequence(input)) + .isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("first byte has wrong parity") + public void decodeFirstByteWrongParity() { + List input = List.of(0x07, 0x00); + assertThrows(IllegalArgumentException.class, () + -> IntergalacticTransmission.decodeSequence(input)); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("second byte has wrong parity") + public void decodeSecondByteWrongParity() { + List input = List.of(0x03, 0x68); + assertThrows(IllegalArgumentException.class, () + -> IntergalacticTransmission.decodeSequence(input)); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("0xcf4b00 is decoded to 0xce94") + public void decode0xcf4b00To0xce94() { + List input = List.of(0xcf, 0x4b, 0x00); + List expected = List.of(0xce, 0x94); + assertThat(IntergalacticTransmission.decodeSequence(input)) + .isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("0xe2566500 is decoded to 0xe2ad90") + public void decode0xe2566500To0xe2ad90() { + List input = List.of(0xe2, 0x56, 0x65, 0x00); + List expected = List.of(0xe2, 0xad, 0x90); + assertThat(IntergalacticTransmission.decodeSequence(input)) + .isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("six byte message") + public void decodeSixByteMessage() { + List input = List.of(0x47, 0xb8, 0x99, 0xac, 0x17, 0xa0, 0x84); + List expected = List.of(0x47, 0x72, 0x65, 0x61, 0x74, 0x21); + assertThat(IntergalacticTransmission.decodeSequence(input)) + .isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("seven byte message") + public void decodeSevenByteMessage() { + List input = List.of(0x47, 0xb8, 0x99, 0xac, 0x17, 0xa0, 0xc5, 0x42); + List expected = List.of(0x47, 0x72, 0x65, 0x61, 0x74, 0x31, 0x21); + assertThat(IntergalacticTransmission.decodeSequence(input)) + .isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("last byte has wrong parity") + public void decodeLastByteWrongParity() { + List input = List.of(0x47, 0xb8, 0x99, 0xac, 0x17, 0xa0, 0xc5, 0x43); + assertThrows(IllegalArgumentException.class, () + -> IntergalacticTransmission.decodeSequence(input)); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("eight byte message") + public void decodeEightByteMessage() { + List input = List.of(0xc0, 0x00, 0x44, 0x66, 0x7d, 0x06, 0x78, 0x42, 0x21, 0x81); + List expected = List.of(0xc0, 0x01, 0x13, 0x37, 0xc0, 0xde, 0x21, 0x21); + assertThat(IntergalacticTransmission.decodeSequence(input)) + .isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("twenty byte message") + public void decodeTwentyByteMessage() { + List input = List.of( + 0x44, 0xbd, 0x18, 0xaf, 0x27, 0x1b, 0xa5, 0xe7, 0x6c, 0x90, 0x1b, + 0x2e, 0x33, 0x03, 0x84, 0xee, 0x65, 0xb8, 0xdb, 0xed, 0xd7, 0x28, 0x84); + List expected = List.of( + 0x45, 0x78, 0x65, 0x72, 0x63, 0x69, 0x73, 0x6d, 0x20, 0x69, + 0x73, 0x20, 0x61, 0x77, 0x65, 0x73, 0x6f, 0x6d, 0x65, 0x21); + assertThat(IntergalacticTransmission.decodeSequence(input)) + .isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("wrong parity on 16th byte") + public void decodeWrongParityOn16thByte() { + List input = List.of( + 0x44, 0xbd, 0x18, 0xaf, 0x27, 0x1b, 0xa5, 0xe7, 0x6c, 0x90, + 0x1b, 0x2e, 0x33, 0x03, 0x84, 0xef, 0x65, 0xb8, 0xdb, 0xed, 0xd7, 0x28, 0x84); + assertThrows(IllegalArgumentException.class, () + -> IntergalacticTransmission.decodeSequence(input)); + } +} diff --git a/exercises/practice/isbn-verifier/.meta/tests.toml b/exercises/practice/isbn-verifier/.meta/tests.toml index 6d5a84599..17e18d47a 100644 --- a/exercises/practice/isbn-verifier/.meta/tests.toml +++ b/exercises/practice/isbn-verifier/.meta/tests.toml @@ -30,6 +30,12 @@ description = "invalid character in isbn is not treated as zero" [28025280-2c39-4092-9719-f3234b89c627] description = "X is only valid as a check digit" +[8005b57f-f194-44ee-88d2-a77ac4142591] +description = "only one check digit is allowed" + +[fdb14c99-4cf8-43c5-b06d-eb1638eff343] +description = "X is not substituted by the value 10" + [f6294e61-7e79-46b3-977b-f48789a4945b] description = "valid isbn without separating dashes" diff --git a/exercises/practice/isbn-verifier/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/isbn-verifier/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/isbn-verifier/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/isbn-verifier/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/isbn-verifier/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/isbn-verifier/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/isbn-verifier/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/isbn-verifier/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/isbn-verifier/gradlew b/exercises/practice/isbn-verifier/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/isbn-verifier/gradlew +++ b/exercises/practice/isbn-verifier/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/isbn-verifier/gradlew.bat b/exercises/practice/isbn-verifier/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/isbn-verifier/gradlew.bat +++ b/exercises/practice/isbn-verifier/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/isbn-verifier/src/test/java/IsbnVerifierTest.java b/exercises/practice/isbn-verifier/src/test/java/IsbnVerifierTest.java index 65483a772..2848b63c5 100644 --- a/exercises/practice/isbn-verifier/src/test/java/IsbnVerifierTest.java +++ b/exercises/practice/isbn-verifier/src/test/java/IsbnVerifierTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -13,120 +14,154 @@ public void setUp() { } @Test + @DisplayName("valid isbn") public void validIsbnNumber() { assertThat(isbnVerifier.isValid("3-598-21508-8")).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("invalid isbn check digit") public void invalidIsbnCheckDigit() { assertThat(isbnVerifier.isValid("3-598-21508-9")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("valid isbn with a check digit of 10") public void validIsbnNumberWithCheckDigitOfTen() { assertThat(isbnVerifier.isValid("3-598-21507-X")).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("valid isbn with check digit padded with letters is invalid") public void validIsbnNumberWithCheckDigitPaddedWithLettersIsInvalid() { assertThat(isbnVerifier.isValid("ABCDEFG3-598-21507-XQWERTYUI")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("check digit is a character other than X") public void checkDigitIsACharacterOtherThanX() { assertThat(isbnVerifier.isValid("3-598-21507-A")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("invalid check digit in isbn is not treated as zero") public void invalidCheckDigitInIsbn() { assertThat(isbnVerifier.isValid("4-598-21507-B")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("invalid character in isbn is not treated as zero") public void invalidCharacterInIsbn() { assertThat(isbnVerifier.isValid("3-598-P1581-X")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("X is only valid as a check digit") public void xIsOnlyValidAsACheckDigit() { assertThat(isbnVerifier.isValid("3-598-2X507-9")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("only one check digit is allowed") + public void onlyOneCheckDigitIsAllowed() { + assertThat(isbnVerifier.isValid("3-598-21508-96")).isFalse(); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("X is not substituted by the value 10") + public void xIsNotSubstitutedByTheValue10() { + assertThat(isbnVerifier.isValid("3-598-2X507-5")).isFalse(); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("valid isbn without separating dashes") public void validIsbnWithoutSeparatingDashes() { assertThat(isbnVerifier.isValid("3598215088")).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("isbn without separating dashes and X as check digit") public void isbnWithoutSeparatingDashesAndXAsCheckDigit() { assertThat(isbnVerifier.isValid("359821507X")).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("isbn without check digit and dashes") public void isbnWithoutCheckDigitAndDashes() { assertThat(isbnVerifier.isValid("359821507")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("too long isbn and no dashes") public void tooLongIsbnAndNoDashes() { assertThat(isbnVerifier.isValid("3598215078X")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("too short isbn") public void tooShortIsbn() { assertThat(isbnVerifier.isValid("00")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("isbn without check digit") public void isbnWithoutCheckDigit() { assertThat(isbnVerifier.isValid("3-598-21507")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("check digit of X should not be used for 0") public void checkDigitOfXShouldNotBeUsedForZero() { assertThat(isbnVerifier.isValid("3-598-21515-X")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("empty isbn") public void emptyIsbn() { assertThat(isbnVerifier.isValid("")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("input is 9 characters") public void inputIsNineCharacters() { assertThat(isbnVerifier.isValid("134456729")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("invalid characters are not ignored after checking length") public void invalidCharactersAreNotIgnoredAfterCheckingLength() { assertThat(isbnVerifier.isValid("3132P34035")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("invalid characters are not ignored before checking length") public void invalidCharactersAreNotIgnoredBeforeCheckingLength() { assertThat(isbnVerifier.isValid("3598P215088")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("input is too long but contains a valid isbn") public void inputIsTooLongButContainsAValidIsbn() { assertThat(isbnVerifier.isValid("98245726788")).isFalse(); } diff --git a/exercises/practice/isogram/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/isogram/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/isogram/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/isogram/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/isogram/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/isogram/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/isogram/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/isogram/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/isogram/gradlew b/exercises/practice/isogram/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/isogram/gradlew +++ b/exercises/practice/isogram/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/isogram/gradlew.bat b/exercises/practice/isogram/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/isogram/gradlew.bat +++ b/exercises/practice/isogram/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/isogram/src/test/java/IsogramCheckerTest.java b/exercises/practice/isogram/src/test/java/IsogramCheckerTest.java index 88fccfc29..cdc73f73c 100644 --- a/exercises/practice/isogram/src/test/java/IsogramCheckerTest.java +++ b/exercises/practice/isogram/src/test/java/IsogramCheckerTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -13,84 +14,98 @@ public void setUp() { } @Test + @DisplayName("empty string") public void testEmptyString() { assertThat(isogramChecker.isIsogram("")).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("isogram with only lower case characters") public void testLowercaseIsogram() { assertThat(isogramChecker.isIsogram("isogram")).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("word with one duplicated character") public void testNotIsogram() { assertThat(isogramChecker.isIsogram("eleven")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("word with one duplicated character from the end of the alphabet") public void testDuplicateEndAlphabet() { assertThat(isogramChecker.isIsogram("zzyzx")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("longest reported english isogram") public void testMediumLongIsogram() { assertThat(isogramChecker.isIsogram("subdermatoglyphic")).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("word with duplicated character in mixed case") public void testCaseInsensitive() { assertThat(isogramChecker.isIsogram("Alphabet")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("word with duplicated character in mixed case, lowercase first") public void testDuplicateMixedCase() { assertThat(isogramChecker.isIsogram("alphAbet")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("hypothetical isogrammic word with hyphen") public void testIsogramWithHyphen() { assertThat(isogramChecker.isIsogram("thumbscrew-japingly")).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("hypothetical word with duplicated character following hyphen") public void testIsogramWithDuplicatedCharAfterHyphen() { assertThat(isogramChecker.isIsogram("thumbscrew-jappingly")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("isogram with duplicated hyphen") public void testIsogramWithDuplicatedHyphen() { assertThat(isogramChecker.isIsogram("six-year-old")).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("made-up name that is an isogram") public void testMadeUpNameThatIsAnIsogram() { assertThat(isogramChecker.isIsogram("Emily Jung Schwartzkopf")).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("duplicated character in the middle") public void testDuplicatedCharacterInTheMiddleIsNotIsogram() { assertThat(isogramChecker.isIsogram("accentor")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("same first and last characters") public void testSameFirstAndLast() { assertThat(new IsogramChecker().isIsogram("angola")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("word with duplicated character and with two hyphens") public void testDuplicatedCharacterAndTwoHyphens() { assertThat(new IsogramChecker().isIsogram("up-to-date")).isFalse(); } diff --git a/exercises/practice/killer-sudoku-helper/.docs/instructions.md b/exercises/practice/killer-sudoku-helper/.docs/instructions.md index fdafdca8f..9f5cb1368 100644 --- a/exercises/practice/killer-sudoku-helper/.docs/instructions.md +++ b/exercises/practice/killer-sudoku-helper/.docs/instructions.md @@ -74,7 +74,7 @@ You can also find Killer Sudokus in varying difficulty in numerous newspapers, a ## Credit -The screenshots above have been generated using [F-Puzzles.com](https://www.f-puzzles.com/), a Puzzle Setting Tool by Eric Fox. +The screenshots above have been generated using F-Puzzles.com, a Puzzle Setting Tool by Eric Fox. [sudoku-rules]: https://masteringsudoku.com/sudoku-rules-beginners/ [killer-guide]: https://masteringsudoku.com/killer-sudoku/ diff --git a/exercises/practice/killer-sudoku-helper/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/killer-sudoku-helper/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/killer-sudoku-helper/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/killer-sudoku-helper/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/killer-sudoku-helper/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/killer-sudoku-helper/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/killer-sudoku-helper/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/killer-sudoku-helper/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/killer-sudoku-helper/gradlew b/exercises/practice/killer-sudoku-helper/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/killer-sudoku-helper/gradlew +++ b/exercises/practice/killer-sudoku-helper/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/killer-sudoku-helper/gradlew.bat b/exercises/practice/killer-sudoku-helper/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/killer-sudoku-helper/gradlew.bat +++ b/exercises/practice/killer-sudoku-helper/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/kindergarten-garden/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/kindergarten-garden/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/kindergarten-garden/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/kindergarten-garden/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/kindergarten-garden/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/kindergarten-garden/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/kindergarten-garden/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/kindergarten-garden/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/kindergarten-garden/gradlew b/exercises/practice/kindergarten-garden/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/kindergarten-garden/gradlew +++ b/exercises/practice/kindergarten-garden/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/kindergarten-garden/gradlew.bat b/exercises/practice/kindergarten-garden/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/kindergarten-garden/gradlew.bat +++ b/exercises/practice/kindergarten-garden/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/kindergarten-garden/src/test/java/KindergartenGardenTest.java b/exercises/practice/kindergarten-garden/src/test/java/KindergartenGardenTest.java index eb7ab61f2..e2b511869 100644 --- a/exercises/practice/kindergarten-garden/src/test/java/KindergartenGardenTest.java +++ b/exercises/practice/kindergarten-garden/src/test/java/KindergartenGardenTest.java @@ -1,12 +1,12 @@ - -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Disabled; - +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; public class KindergartenGardenTest { @Test + @DisplayName("garden with single student") public void singleStudent() { String garden = "RC\nGG"; String student = "Alice"; @@ -17,6 +17,7 @@ public void singleStudent() { @Disabled("Remove to run test") @Test + @DisplayName("different garden with single student") public void singleStudent2() { String garden = "VC\nRC"; String student = "Alice"; @@ -27,6 +28,7 @@ public void singleStudent2() { @Disabled("Remove to run test") @Test + @DisplayName("garden with two students") public void twoStudents() { String garden = "VVCG\nVVRC"; String student = "Bob"; @@ -37,6 +39,7 @@ public void twoStudents() { @Disabled("Remove to run test") @Test + @DisplayName("second student's garden") public void oneGardenSecondStudent() { String garden = "VVCCGG\nVVCCGG"; String student = "Bob"; @@ -47,6 +50,7 @@ public void oneGardenSecondStudent() { @Disabled("Remove to run test") @Test + @DisplayName("third student's garden") public void oneGardenThirdStudent() { String garden = "VVCCGG\nVVCCGG"; String student = "Charlie"; @@ -57,6 +61,7 @@ public void oneGardenThirdStudent() { @Disabled("Remove to run test") @Test + @DisplayName("for Alice, first student's garden") public void fullGardenForAlice() { String garden = "VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV"; String student = "Alice"; @@ -67,6 +72,7 @@ public void fullGardenForAlice() { @Disabled("Remove to run test") @Test + @DisplayName("for Bob, second student's garden") public void fullGardenForBob() { String garden = "VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV"; String student = "Bob"; @@ -77,6 +83,7 @@ public void fullGardenForBob() { @Disabled("Remove to run test") @Test + @DisplayName("for Charlie") public void fullGardenForCharlie() { String garden = "VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV"; String student = "Charlie"; @@ -87,6 +94,7 @@ public void fullGardenForCharlie() { @Disabled("Remove to run test") @Test + @DisplayName("for David") public void fullGardenForDavid() { String garden = "VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV"; String student = "David"; @@ -97,6 +105,7 @@ public void fullGardenForDavid() { @Disabled("Remove to run test") @Test + @DisplayName("for Eve") public void fullGardenForEve() { String garden = "VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV"; String student = "Eve"; @@ -107,6 +116,7 @@ public void fullGardenForEve() { @Disabled("Remove to run test") @Test + @DisplayName("for Fred") public void fullGardenForFred() { String garden = "VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV"; String student = "Fred"; @@ -117,6 +127,7 @@ public void fullGardenForFred() { @Disabled("Remove to run test") @Test + @DisplayName("for Ginny") public void fullGardenForGinny() { String garden = "VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV"; String student = "Ginny"; @@ -127,6 +138,7 @@ public void fullGardenForGinny() { @Disabled("Remove to run test") @Test + @DisplayName("for Harriet") public void fullGardenForHarriet() { String garden = "VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV"; String student = "Harriet"; @@ -137,6 +149,7 @@ public void fullGardenForHarriet() { @Disabled("Remove to run test") @Test + @DisplayName("for Ileana") public void fullGardenForIleana() { String garden = "VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV"; String student = "Ileana"; @@ -147,6 +160,7 @@ public void fullGardenForIleana() { @Disabled("Remove to run test") @Test + @DisplayName("for Joseph") public void fullGardenForJoseph() { String garden = "VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV"; String student = "Joseph"; @@ -157,6 +171,7 @@ public void fullGardenForJoseph() { @Disabled("Remove to run test") @Test + @DisplayName("for Kincaid, second to last student's garden") public void fullGardenForKincaid() { String garden = "VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV"; String student = "Kincaid"; @@ -167,6 +182,7 @@ public void fullGardenForKincaid() { @Disabled("Remove to run test") @Test + @DisplayName("for Larry, last student's garden") public void fullGardenForLarry() { String garden = "VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV"; String student = "Larry"; diff --git a/exercises/practice/knapsack/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/knapsack/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/knapsack/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/knapsack/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/knapsack/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/knapsack/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/knapsack/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/knapsack/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/knapsack/gradlew b/exercises/practice/knapsack/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/knapsack/gradlew +++ b/exercises/practice/knapsack/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/knapsack/gradlew.bat b/exercises/practice/knapsack/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/knapsack/gradlew.bat +++ b/exercises/practice/knapsack/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/knapsack/src/test/java/KnapsackTest.java b/exercises/practice/knapsack/src/test/java/KnapsackTest.java index 205d0e56e..166c12cbe 100644 --- a/exercises/practice/knapsack/src/test/java/KnapsackTest.java +++ b/exercises/practice/knapsack/src/test/java/KnapsackTest.java @@ -1,5 +1,6 @@ -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.List; @@ -17,6 +18,7 @@ public void setup() { } @Test + @DisplayName("no items") public void testNoItems() { List items = List.of(); assertThat(knapsack.maximumValue(100, items)).isEqualTo(0); @@ -24,6 +26,7 @@ public void testNoItems() { @Disabled("Remove to run test") @Test + @DisplayName("one item, too heavy") public void testOneItemTooHeavy() { List items = List.of( new Item(100, 1) @@ -34,6 +37,7 @@ public void testOneItemTooHeavy() { @Disabled("Remove to run test") @Test + @DisplayName("five items (cannot be greedy by weight)") public void testFiveItemsCannotBeGreedyByWeight() { List items = List.of( new Item(2, 5), @@ -48,6 +52,7 @@ public void testFiveItemsCannotBeGreedyByWeight() { @Disabled("Remove to run test") @Test + @DisplayName("five items (cannot be greedy by value)") public void testFiveItemsCannotBeGreedyByValue() { List items = List.of( new Item(2, 20), @@ -62,6 +67,7 @@ public void testFiveItemsCannotBeGreedyByValue() { @Disabled("Remove to run test") @Test + @DisplayName("example knapsack") public void testExampleKnapsack() { List items = List.of( new Item(5, 10), @@ -75,6 +81,7 @@ public void testExampleKnapsack() { @Disabled("Remove to run test") @Test + @DisplayName("8 items") public void testEightItems() { List items = List.of( new Item(25, 350), @@ -92,6 +99,7 @@ public void testEightItems() { @Disabled("Remove to run test") @Test + @DisplayName("15 items") public void testFifteenItems() { List items = List.of( new Item(70, 135), diff --git a/exercises/practice/largest-series-product/.meta/config.json b/exercises/practice/largest-series-product/.meta/config.json index b6a57ee6c..c3ba23a98 100644 --- a/exercises/practice/largest-series-product/.meta/config.json +++ b/exercises/practice/largest-series-product/.meta/config.json @@ -22,6 +22,7 @@ "Smarticles101", "sonapraneeth-a", "sshine", + "Xinri", "Zaldrick" ], "files": { diff --git a/exercises/practice/largest-series-product/.meta/tests.toml b/exercises/practice/largest-series-product/.meta/tests.toml index 883169259..982f517cc 100644 --- a/exercises/practice/largest-series-product/.meta/tests.toml +++ b/exercises/practice/largest-series-product/.meta/tests.toml @@ -38,6 +38,11 @@ description = "reports zero if all spans include zero" [5d81aaf7-4f67-4125-bf33-11493cc7eab7] description = "rejects span longer than string length" +include = false + +[0ae1ce53-d9ba-41bb-827f-2fceb64f058b] +description = "rejects span longer than string length" +reimplements = "5d81aaf7-4f67-4125-bf33-11493cc7eab7" [06bc8b90-0c51-4c54-ac22-3ec3893a079e] description = "reports 1 for empty string and empty product (0 span)" @@ -49,6 +54,11 @@ include = false [6d96c691-4374-4404-80ee-2ea8f3613dd4] description = "rejects empty string and nonzero span" +include = false + +[6cf66098-a6af-4223-aab1-26aeeefc7402] +description = "rejects empty string and nonzero span" +reimplements = "6d96c691-4374-4404-80ee-2ea8f3613dd4" [7a38f2d6-3c35-45f6-8d6f-12e6e32d4d74] description = "rejects invalid character in digits" diff --git a/exercises/practice/largest-series-product/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/largest-series-product/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/largest-series-product/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/largest-series-product/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/largest-series-product/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/largest-series-product/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/largest-series-product/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/largest-series-product/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/largest-series-product/gradlew b/exercises/practice/largest-series-product/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/largest-series-product/gradlew +++ b/exercises/practice/largest-series-product/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/largest-series-product/gradlew.bat b/exercises/practice/largest-series-product/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/largest-series-product/gradlew.bat +++ b/exercises/practice/largest-series-product/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/largest-series-product/src/test/java/LargestSeriesProductCalculatorTest.java b/exercises/practice/largest-series-product/src/test/java/LargestSeriesProductCalculatorTest.java index ee7f8a8b2..417878d1e 100644 --- a/exercises/practice/largest-series-product/src/test/java/LargestSeriesProductCalculatorTest.java +++ b/exercises/practice/largest-series-product/src/test/java/LargestSeriesProductCalculatorTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -7,6 +8,7 @@ public class LargestSeriesProductCalculatorTest { @Test + @DisplayName("finds the largest product if span equals length") public void testCorrectlyCalculatesLargestProductWhenSeriesLengthEqualsStringToSearchLength() { LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("29"); long expectedProduct = 18; @@ -18,6 +20,7 @@ public void testCorrectlyCalculatesLargestProductWhenSeriesLengthEqualsStringToS @Disabled("Remove to run test") @Test + @DisplayName("can find the largest product of 2 with numbers in order") public void testCorrectlyCalculatesLargestProductOfLengthTwoWithNumbersInOrder() { LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("0123456789"); long expectedProduct = 72; @@ -29,6 +32,7 @@ public void testCorrectlyCalculatesLargestProductOfLengthTwoWithNumbersInOrder() @Disabled("Remove to run test") @Test + @DisplayName("can find the largest product of 2") public void testCorrectlyCalculatesLargestProductOfLengthTwoWithNumbersNotInOrder() { LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("576802143"); long expectedProduct = 48; @@ -40,6 +44,7 @@ public void testCorrectlyCalculatesLargestProductOfLengthTwoWithNumbersNotInOrde @Disabled("Remove to run test") @Test + @DisplayName("can find the largest product of 3 with numbers in order") public void testCorrectlyCalculatesLargestProductOfLengthThreeWithNumbersInOrder() { LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("0123456789"); long expectedProduct = 504; @@ -51,6 +56,7 @@ public void testCorrectlyCalculatesLargestProductOfLengthThreeWithNumbersInOrder @Disabled("Remove to run test") @Test + @DisplayName("can find the largest product of 3") public void testCorrectlyCalculatesLargestProductOfLengthThreeWithNumbersNotInOrder() { LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("1027839564"); long expectedProduct = 270; @@ -62,6 +68,7 @@ public void testCorrectlyCalculatesLargestProductOfLengthThreeWithNumbersNotInOr @Disabled("Remove to run test") @Test + @DisplayName("can find the largest product of 5 with numbers in order") public void testCorrectlyCalculatesLargestProductOfLengthFiveWithNumbersInOrder() { LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("0123456789"); long expectedProduct = 15120; @@ -73,6 +80,7 @@ public void testCorrectlyCalculatesLargestProductOfLengthFiveWithNumbersInOrder( @Disabled("Remove to run test") @Test + @DisplayName("can get the largest product of a big number") public void testCorrectlyCalculatesLargestProductInLongStringToSearchV1() { LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator( "73167176531330624919225119674426574742355349194934"); @@ -86,6 +94,7 @@ public void testCorrectlyCalculatesLargestProductInLongStringToSearchV1() { @Disabled("Remove to run test") @Test + @DisplayName("reports zero if the only digits are zero") public void testCorrectlyCalculatesLargestProductOfZeroIfAllDigitsAreZeroes() { LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("0000"); long expectedProduct = 0; @@ -97,6 +106,7 @@ public void testCorrectlyCalculatesLargestProductOfZeroIfAllDigitsAreZeroes() { @Disabled("Remove to run test") @Test + @DisplayName("reports zero if all spans include zero") public void testCorrectlyCalculatesLargestProductOfZeroIfAllSeriesOfGivenLengthContainZero() { LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("99099"); long expectedProduct = 0; @@ -108,6 +118,7 @@ public void testCorrectlyCalculatesLargestProductOfZeroIfAllSeriesOfGivenLengthC @Disabled("Remove to run test") @Test + @DisplayName("rejects span longer than string length") public void testSeriesLengthLongerThanLengthOfStringToTestIsRejected() { LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("123"); @@ -118,7 +129,8 @@ public void testSeriesLengthLongerThanLengthOfStringToTestIsRejected() { @Disabled("Remove to run test") @Test - public void testEmptyStringToSearchAndSeriesOfNonZeroLengthIsRejected() { + @DisplayName("rejects empty string and nonzero span") + public void testEmptyStringAndNonZeroSpanIsRejected() { LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator(""); assertThatExceptionOfType(IllegalArgumentException.class) @@ -128,6 +140,7 @@ public void testEmptyStringToSearchAndSeriesOfNonZeroLengthIsRejected() { @Disabled("Remove to run test") @Test + @DisplayName("rejects invalid character in digits") public void testStringToSearchContainingNonDigitCharacterIsRejected() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> new LargestSeriesProductCalculator("1234a5")) @@ -136,6 +149,7 @@ public void testStringToSearchContainingNonDigitCharacterIsRejected() { @Disabled("Remove to run test") @Test + @DisplayName("rejects negative span") public void testNegativeSeriesLengthIsRejected() { LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("12345"); @@ -146,6 +160,7 @@ public void testNegativeSeriesLengthIsRejected() { @Disabled("Remove to run test") @Test + @DisplayName("integer overflow") public void testForIntegerOverflow() { LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("9999999999"); long expectedProduct = 3486784401L; diff --git a/exercises/practice/leap/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/leap/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/leap/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/leap/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/leap/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/leap/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/leap/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/leap/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/leap/gradlew b/exercises/practice/leap/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/leap/gradlew +++ b/exercises/practice/leap/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/leap/gradlew.bat b/exercises/practice/leap/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/leap/gradlew.bat +++ b/exercises/practice/leap/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/leap/src/test/java/LeapTest.java b/exercises/practice/leap/src/test/java/LeapTest.java index b5234d36d..b61e8c2d9 100644 --- a/exercises/practice/leap/src/test/java/LeapTest.java +++ b/exercises/practice/leap/src/test/java/LeapTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -14,54 +15,63 @@ public void setup() { } @Test + @DisplayName("year not divisible by 4 in common year") public void testYearNotDivBy4InCommonYear() { assertThat(leap.isLeapYear(2015)).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("year divisible by 2, not divisible by 4 in common year\"") public void testYearDivBy2NotDivBy4InCommonYear() { assertThat(leap.isLeapYear(1970)).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("year divisible by 4, not divisible by 100 in leap year") public void testYearDivBy4NotDivBy100InLeapYear() { assertThat(leap.isLeapYear(1996)).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("year divisible by 4 and 5 is still a leap year") public void testYearDivBy4And5InLeapYear() { assertThat(leap.isLeapYear(1960)).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("year divisible by 100, not divisible by 400 in common year") public void testYearDivBy100NotDivBy400InCommonYear() { assertThat(leap.isLeapYear(2100)).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("year divisible by 100 but not by 3 is still not a leap year") public void testYearDivBy100NotDivBy3IsNotLeapYear() { assertThat(leap.isLeapYear(1900)).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("year divisible by 400 is leap year") public void testYearDivBy400InLeapYear() { assertThat(leap.isLeapYear(2000)).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("year divisible by 400 but not by 125 is still a leap year") public void testYearDivBy400NotDivBy125IsLeapYear() { assertThat(leap.isLeapYear(2400)).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("year divisible by 200, not divisible by 400 in common year") public void testYearDivBy200NotDivBy400InCommonYear() { assertThat(leap.isLeapYear(1800)).isFalse(); } diff --git a/exercises/practice/ledger/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/ledger/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/ledger/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/ledger/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/ledger/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/ledger/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/ledger/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/ledger/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/ledger/gradlew b/exercises/practice/ledger/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/ledger/gradlew +++ b/exercises/practice/ledger/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/ledger/gradlew.bat b/exercises/practice/ledger/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/ledger/gradlew.bat +++ b/exercises/practice/ledger/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/ledger/src/test/java/LedgerTest.java b/exercises/practice/ledger/src/test/java/LedgerTest.java index eb7cbfddb..15c022ee4 100644 --- a/exercises/practice/ledger/src/test/java/LedgerTest.java +++ b/exercises/practice/ledger/src/test/java/LedgerTest.java @@ -1,7 +1,8 @@ -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -23,6 +24,7 @@ public void setUp() throws Exception { @Disabled("Remove to run test") @Test + @DisplayName("empty ledger") public void emptyLedgerUS() { var entries = new Ledger.LedgerEntry[] {}; @@ -34,6 +36,7 @@ public void emptyLedgerUS() { @Disabled("Remove to run test") @Test + @DisplayName("one entry") public void oneEntry() { var entries = new Ledger.LedgerEntry[] { ledger.createLedgerEntry("2015-01-01", "Buy present", -1000) @@ -48,6 +51,7 @@ public void oneEntry() { @Disabled("Remove to run test") @Test + @DisplayName("credit and debit") public void creditAndDebit() { var entries = new Ledger.LedgerEntry[] { ledger.createLedgerEntry("2015-01-02", "Get present", 1000), @@ -65,6 +69,7 @@ public void creditAndDebit() { @Disabled("Remove to run test") @Test + @DisplayName("multiple entries on same date ordered by description") public void multipleEntriesOnSameDateOrderedByDescription() { var entries = new Ledger.LedgerEntry[] { ledger.createLedgerEntry("2015-01-01", "Get present", 1000), @@ -82,6 +87,7 @@ public void multipleEntriesOnSameDateOrderedByDescription() { @Disabled("Remove to run test") @Test + @DisplayName("final order tie breaker is change") public void finalOrderTieBreakerIsChange() { var entries = new Ledger.LedgerEntry[] { ledger.createLedgerEntry("2015-01-01", "Something", 0), @@ -101,6 +107,7 @@ public void finalOrderTieBreakerIsChange() { @Disabled("Remove to run test") @Test + @DisplayName("overlong description is truncated") public void overlongDescriptions() { var entries = new Ledger.LedgerEntry[] { ledger.createLedgerEntry("2015-01-01", "Freude schoner Gotterfunken", -123456) @@ -116,6 +123,7 @@ public void overlongDescriptions() { @Disabled("Remove to run test") @Test + @DisplayName("euros") public void euros() { var entries = new Ledger.LedgerEntry[] { ledger.createLedgerEntry("2015-01-01", "Buy present", -1000) @@ -131,6 +139,7 @@ public void euros() { @Disabled("Remove to run test") @Test + @DisplayName("Dutch locale") public void dutchLocale() { var entries = new Ledger.LedgerEntry[] { ledger.createLedgerEntry("2015-03-12", "Buy present", 123456) @@ -146,6 +155,7 @@ public void dutchLocale() { @Disabled("Remove to run test") @Test + @DisplayName("Dutch locale and euros") public void dutchLocaleAndEuros() { var entries = new Ledger.LedgerEntry[] { ledger.createLedgerEntry("2015-03-12", "Buy present", 123456) @@ -161,6 +171,7 @@ public void dutchLocaleAndEuros() { @Disabled("Remove to run test") @Test + @DisplayName("Dutch negative number with 3 digits before decimal point") public void dutchNegativeNumberWith3DigitsBeforeDecimalPoint() { var entries = new Ledger.LedgerEntry[] { ledger.createLedgerEntry("2015-03-12", "Buy present", -12345) @@ -176,6 +187,7 @@ public void dutchNegativeNumberWith3DigitsBeforeDecimalPoint() { @Disabled("Remove to run test") @Test + @DisplayName("American negative number with 3 digits before decimal point") public void americanNegativeNumberWith3DigitsBeforeDecimalPoint() { var entries = new Ledger.LedgerEntry[] { ledger.createLedgerEntry("2015-03-12", "Buy present", -12345) diff --git a/exercises/practice/linked-list/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/linked-list/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/linked-list/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/linked-list/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/linked-list/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/linked-list/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/linked-list/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/linked-list/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/linked-list/gradlew b/exercises/practice/linked-list/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/linked-list/gradlew +++ b/exercises/practice/linked-list/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/linked-list/gradlew.bat b/exercises/practice/linked-list/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/linked-list/gradlew.bat +++ b/exercises/practice/linked-list/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/linked-list/src/test/java/DoublyLinkedListTest.java b/exercises/practice/linked-list/src/test/java/DoublyLinkedListTest.java index b36e5b988..365d92088 100644 --- a/exercises/practice/linked-list/src/test/java/DoublyLinkedListTest.java +++ b/exercises/practice/linked-list/src/test/java/DoublyLinkedListTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -6,6 +7,7 @@ public class DoublyLinkedListTest { @Test + @DisplayName("pop gets element from the list") public void popGetsElementFromTheList() { DoublyLinkedList list = new DoublyLinkedList<>(); @@ -16,6 +18,7 @@ public void popGetsElementFromTheList() { @Disabled("Remove to run test") @Test + @DisplayName("push/pop respectively add/remove at the end of the list") public void pushAndPopRespectivelyAddsAndRemovesAtEndOfList() { DoublyLinkedList list = new DoublyLinkedList<>(); @@ -28,6 +31,7 @@ public void pushAndPopRespectivelyAddsAndRemovesAtEndOfList() { @Disabled("Remove to run test") @Test + @DisplayName("shift gets an element from the list") public void shiftGetsAnElementFromTheList() { DoublyLinkedList list = new DoublyLinkedList<>(); @@ -38,6 +42,7 @@ public void shiftGetsAnElementFromTheList() { @Disabled("Remove to run test") @Test + @DisplayName("shift gets first element from the list") public void shiftGetsFirstElementFromTheList() { DoublyLinkedList list = new DoublyLinkedList<>(); @@ -50,6 +55,7 @@ public void shiftGetsFirstElementFromTheList() { @Disabled("Remove to run test") @Test + @DisplayName("unshift adds element at start of the list") public void unshiftAddsElementAtStartOfTheList() { DoublyLinkedList list = new DoublyLinkedList<>(); @@ -62,6 +68,7 @@ public void unshiftAddsElementAtStartOfTheList() { @Disabled("Remove to run test") @Test + @DisplayName("pop push shift unshift can be used in any order") public void popPushShiftUnshiftCanBeUsedInAnyOrder() { DoublyLinkedList list = new DoublyLinkedList<>(); @@ -84,6 +91,7 @@ public void popPushShiftUnshiftCanBeUsedInAnyOrder() { @Disabled("Remove to run test") @Test + @DisplayName("popping to empty doesn't break the list") public void poppingToEmptyDoesNotBreakTheList() { DoublyLinkedList list = new DoublyLinkedList<>(); @@ -98,6 +106,7 @@ public void poppingToEmptyDoesNotBreakTheList() { @Disabled("Remove to run test") @Test + @DisplayName("shifting to empty doesn't break the list") public void shiftingToEmptyDoesNotBreakTheList() { DoublyLinkedList list = new DoublyLinkedList<>(); diff --git a/exercises/practice/list-ops/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/list-ops/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/list-ops/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/list-ops/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/list-ops/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/list-ops/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/list-ops/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/list-ops/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/list-ops/gradlew b/exercises/practice/list-ops/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/list-ops/gradlew +++ b/exercises/practice/list-ops/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/list-ops/gradlew.bat b/exercises/practice/list-ops/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/list-ops/gradlew.bat +++ b/exercises/practice/list-ops/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/list-ops/src/test/java/ListOpsTest.java b/exercises/practice/list-ops/src/test/java/ListOpsTest.java index f1eb87051..dc44c61da 100644 --- a/exercises/practice/list-ops/src/test/java/ListOpsTest.java +++ b/exercises/practice/list-ops/src/test/java/ListOpsTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.List; @@ -8,12 +9,14 @@ public class ListOpsTest { @Test + @DisplayName("empty lists") public void testAppendingEmptyLists() { assertThat(ListOps.append(List.of(), List.of())).isEmpty(); } @Disabled("Remove to run test") @Test + @DisplayName("list to empty list") public void testAppendingListToEmptyList() { assertThat(ListOps.append(List.of(), List.of('1', '2', '3', '4'))) .containsExactly('1', '2', '3', '4'); @@ -21,6 +24,7 @@ public void testAppendingListToEmptyList() { @Disabled("Remove to run test") @Test + @DisplayName("empty list to list") public void testAppendingEmptyListToList() { assertThat(ListOps.append(List.of('1', '2', '3', '4'), List.of())) .containsExactly('1', '2', '3', '4'); @@ -28,6 +32,7 @@ public void testAppendingEmptyListToList() { @Disabled("Remove to run test") @Test + @DisplayName("non-empty lists") public void testAppendingNonEmptyLists() { assertThat(ListOps.append(List.of("1", "2"), List.of("2", "3", "4", "5"))) .containsExactly("1", "2", "2", "3", "4", "5"); @@ -35,12 +40,14 @@ public void testAppendingNonEmptyLists() { @Disabled("Remove to run test") @Test + @DisplayName("empty list") public void testConcatEmptyList() { assertThat(ListOps.concat(List.of())).isEmpty(); } @Disabled("Remove to run test") @Test + @DisplayName("list of lists") public void testConcatListOfLists() { List> listOfLists = List.of( List.of('1', '2'), @@ -54,6 +61,7 @@ public void testConcatListOfLists() { @Disabled("Remove to run test") @Test + @DisplayName("list of nested lists") public void testConcatListOfNestedLists() { List>> listOfNestedLists = List.of( List.of( @@ -82,6 +90,7 @@ public void testConcatListOfNestedLists() { @Disabled("Remove to run test") @Test + @DisplayName("empty list") public void testFilteringEmptyList() { assertThat(ListOps.filter(List.of(), integer -> integer % 2 == 1)) .isEmpty(); @@ -89,6 +98,7 @@ public void testFilteringEmptyList() { @Disabled("Remove to run test") @Test + @DisplayName("non-empty list") public void testFilteringNonEmptyList() { assertThat(ListOps.filter(List.of(1, 2, 3, 5), integer -> integer % 2 == 1)) .containsExactly(1, 3, 5); @@ -96,24 +106,28 @@ public void testFilteringNonEmptyList() { @Disabled("Remove to run test") @Test + @DisplayName("empty list") public void testSizeOfEmptyList() { assertThat(ListOps.size(List.of())).isEqualTo(0); } @Disabled("Remove to run test") @Test + @DisplayName("non-empty list") public void testSizeOfNonEmptyList() { assertThat(ListOps.size(List.of("one", "two", "three", "four"))).isEqualTo(4); } @Disabled("Remove to run test") @Test + @DisplayName("empty list") public void testTransformingEmptyList() { assertThat(ListOps.map(List.of(), integer -> integer + 1)).isEmpty(); } @Disabled("Remove to run test") @Test + @DisplayName("non-empty list") public void testTransformingNonEmptyList() { assertThat(ListOps.map(List.of(1, 3, 5, 7), integer -> integer + 1)) .containsExactly(2, 4, 6, 8); @@ -121,6 +135,7 @@ public void testTransformingNonEmptyList() { @Disabled("Remove to run test") @Test + @DisplayName("empty list") public void testFoldLeftEmptyList() { assertThat( ListOps.foldLeft( @@ -132,6 +147,7 @@ public void testFoldLeftEmptyList() { @Disabled("Remove to run test") @Test + @DisplayName("direction independent function applied to non-empty list") public void testFoldLeftDirectionIndependentFunctionAppliedToNonEmptyList() { assertThat( ListOps.foldLeft( @@ -143,6 +159,7 @@ public void testFoldLeftDirectionIndependentFunctionAppliedToNonEmptyList() { @Disabled("Remove to run test") @Test + @DisplayName("direction dependent function applied to non-empty list") public void testFoldLeftDirectionDependentFunctionAppliedToNonEmptyList() { assertThat( ListOps.foldLeft( @@ -154,6 +171,7 @@ public void testFoldLeftDirectionDependentFunctionAppliedToNonEmptyList() { @Disabled("Remove to run test") @Test + @DisplayName("empty list") public void testFoldRightEmptyList() { assertThat( ListOps.foldRight( @@ -165,6 +183,7 @@ public void testFoldRightEmptyList() { @Disabled("Remove to run test") @Test + @DisplayName("direction independent function applied to non-empty list") public void testFoldRightDirectionIndependentFunctionAppliedToNonEmptyList() { assertThat( ListOps.foldRight( @@ -176,6 +195,7 @@ public void testFoldRightDirectionIndependentFunctionAppliedToNonEmptyList() { @Disabled("Remove to run test") @Test + @DisplayName("direction dependent function applied to non-empty list") public void testFoldRightDirectionDependentFunctionAppliedToNonEmptyList() { assertThat( ListOps.foldRight( @@ -187,12 +207,14 @@ public void testFoldRightDirectionDependentFunctionAppliedToNonEmptyList() { @Disabled("Remove to run test") @Test + @DisplayName("empty list") public void testReversingEmptyList() { assertThat(ListOps.reverse(List.of())).isEmpty(); } @Disabled("Remove to run test") @Test + @DisplayName("non-empty list") public void testReversingNonEmptyList() { assertThat(ListOps.reverse(List.of('1', '3', '5', '7'))) .containsExactly('7', '5', '3', '1'); @@ -200,6 +222,7 @@ public void testReversingNonEmptyList() { @Disabled("Remove to run test") @Test + @DisplayName("list of lists is not flattened") public void testReversingListOfListIsNotFlattened() { List> listOfLists = List.of( List.of('1', '2'), diff --git a/exercises/practice/luhn/.docs/instructions.md b/exercises/practice/luhn/.docs/instructions.md index 5bbf007b0..7702c6bbb 100644 --- a/exercises/practice/luhn/.docs/instructions.md +++ b/exercises/practice/luhn/.docs/instructions.md @@ -1,6 +1,6 @@ # Instructions -Determine whether a credit card number is valid according to the [Luhn formula][luhn]. +Determine whether a number is valid according to the [Luhn formula][luhn]. The number will be provided as a string. @@ -10,54 +10,59 @@ Strings of length 1 or less are not valid. Spaces are allowed in the input, but they should be stripped before checking. All other non-digit characters are disallowed. -### Example 1: valid credit card number +## Examples -```text -4539 3195 0343 6467 -``` +### Valid credit card number -The first step of the Luhn algorithm is to double every second digit, starting from the right. -We will be doubling +The number to be checked is `4539 3195 0343 6467`. + +The first step of the Luhn algorithm is to start at the end of the number and double every second digit, beginning with the second digit from the right and moving left. ```text 4539 3195 0343 6467 ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ (double these) ``` -If doubling the number results in a number greater than 9 then subtract 9 from the product. -The results of our doubling: +If the result of doubling a digit is greater than 9, we subtract 9 from that result. +We end up with: ```text 8569 6195 0383 3437 ``` -Then sum all of the digits: +Finally, we sum all digits. +If the sum is evenly divisible by 10, the original number is valid. ```text -8+5+6+9+6+1+9+5+0+3+8+3+3+4+3+7 = 80 +8 + 5 + 6 + 9 + 6 + 1 + 9 + 5 + 0 + 3 + 8 + 3 + 3 + 4 + 3 + 7 = 80 ``` -If the sum is evenly divisible by 10, then the number is valid. -This number is valid! +80 is evenly divisible by 10, so number `4539 3195 0343 6467` is valid! + +### Invalid Canadian SIN + +The number to be checked is `066 123 478`. -### Example 2: invalid credit card number +We start at the end of the number and double every second digit, beginning with the second digit from the right and moving left. ```text -8273 1232 7352 0569 +066 123 478 + ↑ ↑ ↑ ↑ (double these) ``` -Double the second digits, starting from the right +If the result of doubling a digit is greater than 9, we subtract 9 from that result. +We end up with: ```text -7253 2262 5312 0539 +036 226 458 ``` -Sum the digits +We sum the digits: ```text -7+2+5+3+2+2+6+2+5+3+1+2+0+5+3+9 = 57 +0 + 3 + 6 + 2 + 2 + 6 + 4 + 5 + 8 = 36 ``` -57 is not evenly divisible by 10, so this number is not valid. +36 is not evenly divisible by 10, so number `066 123 478` is not valid! [luhn]: https://en.wikipedia.org/wiki/Luhn_algorithm diff --git a/exercises/practice/luhn/.docs/introduction.md b/exercises/practice/luhn/.docs/introduction.md index ec2bd709d..dee48006e 100644 --- a/exercises/practice/luhn/.docs/introduction.md +++ b/exercises/practice/luhn/.docs/introduction.md @@ -2,10 +2,10 @@ At the Global Verification Authority, you've just been entrusted with a critical assignment. Across the city, from online purchases to secure logins, countless operations rely on the accuracy of numerical identifiers like credit card numbers, bank account numbers, transaction codes, and tracking IDs. -The Luhn algorithm is a simple checksum formula used to ensure these numbers are valid and error-free. +The Luhn algorithm is a simple checksum formula used to help identify mistyped numbers. A batch of identifiers has just arrived on your desk. All of them must pass the Luhn test to ensure they're legitimate. -If any fail, they'll be flagged as invalid, preventing errors or fraud, such as incorrect transactions or unauthorized access. +If any fail, they'll be flagged as invalid, preventing mistakes such as incorrect transactions or failed account verifications. Can you ensure this is done right? The integrity of many services depends on you. diff --git a/exercises/practice/luhn/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/luhn/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/luhn/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/luhn/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/luhn/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/luhn/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/luhn/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/luhn/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/luhn/gradlew b/exercises/practice/luhn/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/luhn/gradlew +++ b/exercises/practice/luhn/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/luhn/gradlew.bat b/exercises/practice/luhn/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/luhn/gradlew.bat +++ b/exercises/practice/luhn/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/luhn/src/test/java/LuhnValidatorTest.java b/exercises/practice/luhn/src/test/java/LuhnValidatorTest.java index 12d3e5f3f..bc0c6d7dc 100644 --- a/exercises/practice/luhn/src/test/java/LuhnValidatorTest.java +++ b/exercises/practice/luhn/src/test/java/LuhnValidatorTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -13,132 +14,154 @@ public void setUp() { } @Test + @DisplayName("single digit strings can not be valid") public void testSingleDigitStringInvalid() { assertThat(luhnValidator.isValid("1")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("a single zero is invalid") public void testSingleZeroIsInvalid() { assertThat(luhnValidator.isValid("0")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("a simple valid SIN that remains valid if reversed") public void testSimpleValidSINReversedRemainsValid() { assertThat(luhnValidator.isValid("059")).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("a simple valid SIN that becomes invalid if reversed") public void testSimpleValidSINReversedBecomesInvalid() { assertThat(luhnValidator.isValid("59")).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("a valid Canadian SIN") public void testValidCanadianSINValid() { assertThat(luhnValidator.isValid("055 444 285")).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("invalid Canadian SIN") public void testInvalidCanadianSINInvalid() { assertThat(luhnValidator.isValid("055 444 286")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("invalid credit card") public void testInvalidCreditCardInvalid() { assertThat(luhnValidator.isValid("8273 1232 7352 0569")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("invalid long number with an even remainder") public void testInvalidLongNumberWithAnEvenRemainder() { assertThat(luhnValidator.isValid("1 2345 6789 1234 5678 9012")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("invalid long number with a remainder divisible by 5") public void testInvalidLongNumberWithARemainderDivisibleBy5() { assertThat(luhnValidator.isValid("1 2345 6789 1234 5678 9013")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("valid number with an even number of digits") public void testValidNumberWithAnEvenNumberOfDigits() { assertThat(luhnValidator.isValid("095 245 88")).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("valid number with an odd number of spaces") public void testValidNumberWithAnOddNumberOfSpaces() { assertThat(luhnValidator.isValid("234 567 891 234")).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("valid strings with a non-digit added at the end become invalid") public void testValidStringsWithANonDigitAtEndInvalid() { assertThat(luhnValidator.isValid("059a")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("valid strings with punctuation included become invalid") public void testStringContainingPunctuationInvalid() { assertThat(luhnValidator.isValid("055-444-285")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("valid strings with symbols included become invalid") public void testStringContainingSymbolsInvalid() { assertThat(luhnValidator.isValid("055# 444$ 285")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("single zero with space is invalid") public void testSingleSpaceWithZeroInvalid() { assertThat(luhnValidator.isValid(" 0")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("more than a single zero is valid") public void testMoreThanSingleZeroValid() { assertThat(luhnValidator.isValid("0000 0")).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("input digit 9 is correctly converted to output digit 9") public void testDigitNineConvertedToOutputNine() { assertThat(luhnValidator.isValid("091")).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("very long input is valid") public void testVeryLongInputIsValid() { assertThat(luhnValidator.isValid("9999999999 9999999999 9999999999 9999999999")).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("valid luhn with an odd number of digits and non zero first digit") public void testValidLuhnWithOddNumberOfDigitsAndNonZeroFirstDigit() { assertThat(luhnValidator.isValid("109")).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("using ascii value for non-doubled non-digit isn't allowed") public void testUsingASCIIValueForNonDoubledNonDigitNotAllowed() { assertThat(luhnValidator.isValid("055b 444 285")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("using ascii value for doubled non-digit isn't allowed") public void testUsingASCIIValueForDoubledNonDigitNotAllowed() { assertThat(luhnValidator.isValid(":9")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("non-numeric, non-space char in the middle with a sum that's divisible by 10 isn't allowed") public void testNonNumericNonSpaceCharInMiddleWithSumDivisibleBy10IsNotAllowed() { assertThat(luhnValidator.isValid("59%59")).isFalse(); } @@ -150,7 +173,8 @@ public void testNonNumericNonSpaceCharInMiddleWithSumDivisibleBy10IsNotAllowed() */ @Disabled("Remove to run test") @Test - public void testStringContainingSymbolsInvalidJavaTrackSpecific() { + @DisplayName("string containing symbols is invalid (Java track specific)") + public void testStringContainingSymbolsIsInvalidJavaTrackSpecific() { assertThat(luhnValidator.isValid("85&")).isFalse(); } } diff --git a/exercises/practice/markdown/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/markdown/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/markdown/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/markdown/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/markdown/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/markdown/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/markdown/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/markdown/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/markdown/gradlew b/exercises/practice/markdown/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/markdown/gradlew +++ b/exercises/practice/markdown/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/markdown/gradlew.bat b/exercises/practice/markdown/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/markdown/gradlew.bat +++ b/exercises/practice/markdown/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/markdown/src/test/java/MarkdownTest.java b/exercises/practice/markdown/src/test/java/MarkdownTest.java index 10f0823f2..ec0f31d94 100644 --- a/exercises/practice/markdown/src/test/java/MarkdownTest.java +++ b/exercises/practice/markdown/src/test/java/MarkdownTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -14,6 +15,7 @@ public void setup() { } @Test + @DisplayName("parses normal text as a paragraph") public void normalTextAsAParagraph() { String input = "This will be a paragraph"; String expected = "

This will be a paragraph

"; @@ -23,6 +25,7 @@ public void normalTextAsAParagraph() { @Disabled("Remove to run test") @Test + @DisplayName("parsing italics") public void italics() { String input = "_This will be italic_"; String expected = "

This will be italic

"; @@ -32,6 +35,7 @@ public void italics() { @Disabled("Remove to run test") @Test + @DisplayName("parsing bold text") public void boldText() { String input = "__This will be bold__"; String expected = "

This will be bold

"; @@ -41,6 +45,7 @@ public void boldText() { @Disabled("Remove to run test") @Test + @DisplayName("mixed normal, italics and bold text") public void normalItalicsAndBoldText() { String input = "This will _be_ __mixed__"; String expected = "

This will be mixed

"; @@ -50,6 +55,7 @@ public void normalItalicsAndBoldText() { @Disabled("Remove to run test") @Test + @DisplayName("with h1 header level") public void withH1HeaderLevel() { String input = "# This will be an h1"; String expected = "

This will be an h1

"; @@ -59,6 +65,7 @@ public void withH1HeaderLevel() { @Disabled("Remove to run test") @Test + @DisplayName("with h2 header level") public void withH2HeaderLevel() { String input = "## This will be an h2"; String expected = "

This will be an h2

"; @@ -68,6 +75,7 @@ public void withH2HeaderLevel() { @Disabled("Remove to run test") @Test + @DisplayName("with h3 header level") public void withH3HeaderLevel() { String input = "### This will be an h3"; String expected = "

This will be an h3

"; @@ -77,6 +85,7 @@ public void withH3HeaderLevel() { @Disabled("Remove to run test") @Test + @DisplayName("with h4 header level") public void withH4HeaderLevel() { String input = "#### This will be an h4"; String expected = "

This will be an h4

"; @@ -86,6 +95,7 @@ public void withH4HeaderLevel() { @Disabled("Remove to run test") @Test + @DisplayName("with h5 header level") public void withH5HeaderLevel() { String input = "##### This will be an h5"; String expected = "
This will be an h5
"; @@ -95,6 +105,7 @@ public void withH5HeaderLevel() { @Disabled("Remove to run test") @Test + @DisplayName("with h6 header level") public void withH6HeaderLevel() { String input = "###### This will be an h6"; String expected = "
This will be an h6
"; @@ -104,6 +115,7 @@ public void withH6HeaderLevel() { @Disabled("Remove to run test") @Test + @DisplayName("h7 header level is a paragraph") public void h7HeaderLevelIsAParagraph() { String input = "####### This will not be an h7"; String expected = "

####### This will not be an h7

"; @@ -113,6 +125,7 @@ public void h7HeaderLevelIsAParagraph() { @Disabled("Remove to run test") @Test + @DisplayName("unordered lists") public void unorderedLists() { String input = "* Item 1\n* Item 2"; String expected = "
  • Item 1
  • Item 2
"; @@ -122,6 +135,7 @@ public void unorderedLists() { @Disabled("Remove to run test") @Test + @DisplayName("With a little bit of everything") public void aLittleBitOfEverything() { String input = "# Header!\n* __Bold Item__\n* _Italic Item_"; String expected = "

Header!

  • Bold Item
  • Italic Item
"; @@ -131,6 +145,7 @@ public void aLittleBitOfEverything() { @Disabled("Remove to run test") @Test + @DisplayName("with markdown symbols in the header text that should not be interpreted") public void markdownSymbolsInTheHeaderShouldNotBeInterpreted() { String input = "# This is a header with # and * in the text"; String expected = "

This is a header with # and * in the text

"; @@ -140,6 +155,7 @@ public void markdownSymbolsInTheHeaderShouldNotBeInterpreted() { @Disabled("Remove to run test") @Test + @DisplayName("with markdown symbols in the list item text that should not be interpreted") public void markdownSymbolsInTheListItemTextShouldNotBeInterpreted() { String input = "* Item 1 with a # in the text\n* Item 2 with * in the text"; String expected = "
  • Item 1 with a # in the text
  • Item 2 with * in the text
"; @@ -149,6 +165,7 @@ public void markdownSymbolsInTheListItemTextShouldNotBeInterpreted() { @Disabled("Remove to run test") @Test + @DisplayName("with markdown symbols in the paragraph text that should not be interpreted") public void markdownSymbolsInTheParagraphTextShouldNotBeInterpreted() { String input = "This is a paragraph with # and * in the text"; String expected = "

This is a paragraph with # and * in the text

"; @@ -158,6 +175,7 @@ public void markdownSymbolsInTheParagraphTextShouldNotBeInterpreted() { @Disabled("Remove to run test") @Test + @DisplayName("unordered lists close properly with preceding and following lines") public void markdownUnorderedListsCloseProperlyWithPrecedingAndFollowingLines() { String input = "# Start a list\n* Item 1\n* Item 2\nEnd a list"; String expected = "

Start a list

  • Item 1
  • Item 2

End a list

"; diff --git a/exercises/practice/matching-brackets/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/matching-brackets/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/matching-brackets/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/matching-brackets/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/matching-brackets/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/matching-brackets/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/matching-brackets/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/matching-brackets/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/matching-brackets/gradlew b/exercises/practice/matching-brackets/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/matching-brackets/gradlew +++ b/exercises/practice/matching-brackets/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/matching-brackets/gradlew.bat b/exercises/practice/matching-brackets/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/matching-brackets/gradlew.bat +++ b/exercises/practice/matching-brackets/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/matching-brackets/src/test/java/BracketCheckerTest.java b/exercises/practice/matching-brackets/src/test/java/BracketCheckerTest.java index f1a5b5e7e..9051b388c 100644 --- a/exercises/practice/matching-brackets/src/test/java/BracketCheckerTest.java +++ b/exercises/practice/matching-brackets/src/test/java/BracketCheckerTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -6,6 +7,7 @@ public class BracketCheckerTest { @Test + @DisplayName("paired square brackets") public void testPairedSquareBrackets() { BracketChecker bracketChecker = new BracketChecker("[]"); assertThat(bracketChecker.areBracketsMatchedAndNestedCorrectly()).isTrue(); @@ -13,6 +15,7 @@ public void testPairedSquareBrackets() { @Disabled("Remove to run test") @Test + @DisplayName("empty string") public void testEmptyString() { BracketChecker bracketChecker = new BracketChecker(""); assertThat(bracketChecker.areBracketsMatchedAndNestedCorrectly()).isTrue(); @@ -20,6 +23,7 @@ public void testEmptyString() { @Disabled("Remove to run test") @Test + @DisplayName("unpaired brackets") public void testUnpairedBrackets() { BracketChecker bracketChecker = new BracketChecker("[["); assertThat(bracketChecker.areBracketsMatchedAndNestedCorrectly()).isFalse(); @@ -27,6 +31,7 @@ public void testUnpairedBrackets() { @Disabled("Remove to run test") @Test + @DisplayName("wrong ordered brackets") public void testWrongOrderedBrackets() { BracketChecker bracketChecker = new BracketChecker("}{"); assertThat(bracketChecker.areBracketsMatchedAndNestedCorrectly()).isFalse(); @@ -34,6 +39,7 @@ public void testWrongOrderedBrackets() { @Disabled("Remove to run test") @Test + @DisplayName("wrong closing bracket") public void testWrongClosingBracket() { BracketChecker bracketChecker = new BracketChecker("{]"); assertThat(bracketChecker.areBracketsMatchedAndNestedCorrectly()).isFalse(); @@ -41,6 +47,7 @@ public void testWrongClosingBracket() { @Disabled("Remove to run test") @Test + @DisplayName("paired with whitespace") public void testPairedWithWhitespace() { BracketChecker bracketChecker = new BracketChecker("{ }"); assertThat(bracketChecker.areBracketsMatchedAndNestedCorrectly()).isTrue(); @@ -48,6 +55,7 @@ public void testPairedWithWhitespace() { @Disabled("Remove to run test") @Test + @DisplayName("partially paired brackets") public void testPartiallyPairedBrackets() { BracketChecker bracketChecker = new BracketChecker("{[])"); assertThat(bracketChecker.areBracketsMatchedAndNestedCorrectly()).isFalse(); @@ -55,6 +63,7 @@ public void testPartiallyPairedBrackets() { @Disabled("Remove to run test") @Test + @DisplayName("simple nested brackets") public void testSimpleNestedBrackets() { BracketChecker bracketChecker = new BracketChecker("{[]}"); assertThat(bracketChecker.areBracketsMatchedAndNestedCorrectly()).isTrue(); @@ -62,6 +71,7 @@ public void testSimpleNestedBrackets() { @Disabled("Remove to run test") @Test + @DisplayName("several paired brackets") public void testSeveralPairedBrackets() { BracketChecker bracketChecker = new BracketChecker("{}[]"); assertThat(bracketChecker.areBracketsMatchedAndNestedCorrectly()).isTrue(); @@ -69,6 +79,7 @@ public void testSeveralPairedBrackets() { @Disabled("Remove to run test") @Test + @DisplayName("paired and nested brackets") public void testPairedAndNestedBrackets() { BracketChecker bracketChecker = new BracketChecker("([{}({}[])])"); assertThat(bracketChecker.areBracketsMatchedAndNestedCorrectly()).isTrue(); @@ -76,6 +87,7 @@ public void testPairedAndNestedBrackets() { @Disabled("Remove to run test") @Test + @DisplayName("unopened closing brackets") public void testUnopenedClosingBracket() { BracketChecker bracketChecker = new BracketChecker("{[)][]}"); assertThat(bracketChecker.areBracketsMatchedAndNestedCorrectly()).isFalse(); @@ -83,6 +95,7 @@ public void testUnopenedClosingBracket() { @Disabled("Remove to run test") @Test + @DisplayName("unpaired and nested brackets") public void testUnpairedAndNestedBrackets() { BracketChecker bracketChecker = new BracketChecker("([{])"); assertThat(bracketChecker.areBracketsMatchedAndNestedCorrectly()).isFalse(); @@ -90,6 +103,7 @@ public void testUnpairedAndNestedBrackets() { @Disabled("Remove to run test") @Test + @DisplayName("paired and wrong nested brackets") public void testPairedAndWrongNestedBrackets() { BracketChecker bracketChecker = new BracketChecker("[({]})"); assertThat(bracketChecker.areBracketsMatchedAndNestedCorrectly()).isFalse(); @@ -97,6 +111,7 @@ public void testPairedAndWrongNestedBrackets() { @Disabled("Remove to run test") @Test + @DisplayName("paired and wrong nested brackets but innermost are correct") public void testPairedAndWrongNestedBracketsButInnermostAreCorrect() { BracketChecker bracketChecker = new BracketChecker("[({}])"); assertThat(bracketChecker.areBracketsMatchedAndNestedCorrectly()).isFalse(); @@ -104,6 +119,7 @@ public void testPairedAndWrongNestedBracketsButInnermostAreCorrect() { @Disabled("Remove to run test") @Test + @DisplayName("paired and incomplete brackets") public void testPairedAndIncompleteBrackets() { BracketChecker bracketChecker = new BracketChecker("{}["); assertThat(bracketChecker.areBracketsMatchedAndNestedCorrectly()).isFalse(); @@ -111,6 +127,7 @@ public void testPairedAndIncompleteBrackets() { @Disabled("Remove to run test") @Test + @DisplayName("too many closing brackets") public void testTooManyClosingBrackets() { BracketChecker bracketChecker = new BracketChecker("[]]"); assertThat(bracketChecker.areBracketsMatchedAndNestedCorrectly()).isFalse(); @@ -118,13 +135,15 @@ public void testTooManyClosingBrackets() { @Disabled("Remove to run test") @Test + @DisplayName("early unexpected brackets") public void testEarlyUnexpectedBrackets() { BracketChecker bracketChecker = new BracketChecker(")()"); assertThat(bracketChecker.areBracketsMatchedAndNestedCorrectly()).isFalse(); } - + @Disabled("Remove to run test") @Test + @DisplayName("early mismatched brackets") public void testEarlyMismatchedBrackets() { BracketChecker bracketChecker = new BracketChecker("{)()"); assertThat(bracketChecker.areBracketsMatchedAndNestedCorrectly()).isFalse(); @@ -132,6 +151,7 @@ public void testEarlyMismatchedBrackets() { @Disabled("Remove to run test") @Test + @DisplayName("math expression") public void testMathExpression() { BracketChecker bracketChecker = new BracketChecker("(((185 + 223.85) * 15) - 543)/2"); assertThat(bracketChecker.areBracketsMatchedAndNestedCorrectly()).isTrue(); @@ -139,6 +159,7 @@ public void testMathExpression() { @Disabled("Remove to run test") @Test + @DisplayName("complex latex expression") public void testComplexLatexExpression() { BracketChecker bracketChecker = new BracketChecker( "\\left(\\begin{array}{cc} \\frac{1}{3} & x\\\\ \\mathrm{e}^{x} &... x^2 \\end{array}\\right)"); diff --git a/exercises/practice/matrix/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/matrix/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/matrix/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/matrix/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/matrix/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/matrix/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/matrix/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/matrix/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/matrix/gradlew b/exercises/practice/matrix/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/matrix/gradlew +++ b/exercises/practice/matrix/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/matrix/gradlew.bat b/exercises/practice/matrix/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/matrix/gradlew.bat +++ b/exercises/practice/matrix/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/matrix/src/test/java/MatrixTest.java b/exercises/practice/matrix/src/test/java/MatrixTest.java index 3406ea8d7..5eb9ccfb4 100644 --- a/exercises/practice/matrix/src/test/java/MatrixTest.java +++ b/exercises/practice/matrix/src/test/java/MatrixTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -6,6 +7,7 @@ public class MatrixTest { @Test + @DisplayName("extract row from one number matrix") public void extractRowFromOneNumberMatrixTest() { String matrixAsString = "1"; int rowIndex = 1; @@ -18,6 +20,7 @@ public void extractRowFromOneNumberMatrixTest() { @Disabled("Remove to run test") @Test + @DisplayName("can extract row") public void extractRowFromMatrixTest() { String matrixAsString = "1 2\n3 4"; int rowIndex = 2; @@ -30,6 +33,7 @@ public void extractRowFromMatrixTest() { @Disabled("Remove to run test") @Test + @DisplayName("extract row where numbers have different widths") public void extractRowFromDiffWidthsMatrixTest() { String matrixAsString = "1 2\n10 20"; int rowIndex = 2; @@ -42,6 +46,7 @@ public void extractRowFromDiffWidthsMatrixTest() { @Disabled("Remove to run test") @Test + @DisplayName("can extract row from non-square matrix with no corresponding column") public void extractRowFromNonSquareMatrixTest() { String matrixAsString = "1 2 3\n4 5 6\n7 8 9\n8 7 6"; int rowIndex = 4; @@ -54,6 +59,7 @@ public void extractRowFromNonSquareMatrixTest() { @Disabled("Remove to run test") @Test + @DisplayName("extract column from one number matrix") public void extractColumnFromOneNumberMatrixTest() { String matrixAsString = "1"; int columnIndex = 1; @@ -66,6 +72,7 @@ public void extractColumnFromOneNumberMatrixTest() { @Disabled("Remove to run test") @Test + @DisplayName("can extract column") public void extractColumnMatrixTest() { String matrixAsString = "1 2 3\n4 5 6\n7 8 9"; int columnIndex = 3; @@ -78,6 +85,7 @@ public void extractColumnMatrixTest() { @Disabled("Remove to run test") @Test + @DisplayName("can extract column from non-square matrix with no corresponding row") public void extractColumnFromNonSquareMatrixTest() { String matrixAsString = "1 2 3 4\n5 6 7 8\n9 8 7 6"; int columnIndex = 4; @@ -90,6 +98,7 @@ public void extractColumnFromNonSquareMatrixTest() { @Disabled("Remove to run test") @Test + @DisplayName("extract column where numbers have different widths") public void extractColumnFromDiffWidthsMatrixTest() { String matrixAsString = "89 1903 3\n18 3 1\n9 4 800"; int columnIndex = 2; diff --git a/exercises/practice/mazy-mice/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/mazy-mice/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/mazy-mice/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/mazy-mice/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/mazy-mice/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/mazy-mice/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/mazy-mice/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/mazy-mice/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/mazy-mice/gradlew b/exercises/practice/mazy-mice/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/mazy-mice/gradlew +++ b/exercises/practice/mazy-mice/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/mazy-mice/gradlew.bat b/exercises/practice/mazy-mice/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/mazy-mice/gradlew.bat +++ b/exercises/practice/mazy-mice/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/mazy-mice/src/test/java/MazeGeneratorTest.java b/exercises/practice/mazy-mice/src/test/java/MazeGeneratorTest.java index 24e5de663..8b3635f2a 100644 --- a/exercises/practice/mazy-mice/src/test/java/MazeGeneratorTest.java +++ b/exercises/practice/mazy-mice/src/test/java/MazeGeneratorTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.Set; @@ -37,6 +38,7 @@ public void setup() { } @Test + @DisplayName("Maze has correct overall dimensions") public void theDimensionsOfTheMazeAreCorrect() { var maze = sut.generatePerfectMaze(RECTANGLE_ROWS, RECTANGLE_COLUMNS); var expectedWidth = RECTANGLE_COLUMNS * 2 + 1; @@ -49,6 +51,7 @@ public void theDimensionsOfTheMazeAreCorrect() { @Disabled("Remove to run test") @Test + @DisplayName("Maze contains only valid characters") public void theMazeContainsOnlyValidCharacters() { var maze = sut.generatePerfectMaze(RECTANGLE_ROWS, RECTANGLE_COLUMNS); @@ -63,7 +66,8 @@ public void theMazeContainsOnlyValidCharacters() { @Disabled("Remove to run test") @Test - public void theMazeHasOnlyOneEntranceOnTheLeftSide() { + @DisplayName("Maze has a single entrance on the left side") + public void theMazeHasSingleEntranceOnTheLeftSide() { var maze = sut.generatePerfectMaze(RECTANGLE_ROWS, RECTANGLE_COLUMNS); int entranceCount = countEntrances(maze); @@ -74,7 +78,8 @@ public void theMazeHasOnlyOneEntranceOnTheLeftSide() { @Disabled("Remove to run test") @Test - public void theMazeHasSingleExitOnTheRightSideOfTheMaze() { + @DisplayName("Maze has a single exit on the right side") + public void theMazeHasSingleExitOnTheRightSide() { var maze = sut.generatePerfectMaze(RECTANGLE_ROWS, RECTANGLE_COLUMNS); int exitCount = countExits(maze); @@ -85,6 +90,7 @@ public void theMazeHasSingleExitOnTheRightSideOfTheMaze() { @Disabled("Remove to run test") @Test + @DisplayName("Maze is different each time it is generated") public void aMazeIsDifferentEachTimeItIsGenerated() { var maze1 = sut.generatePerfectMaze(RECTANGLE_ROWS, RECTANGLE_COLUMNS); var maze2 = sut.generatePerfectMaze(RECTANGLE_ROWS, RECTANGLE_COLUMNS); @@ -96,6 +102,27 @@ public void aMazeIsDifferentEachTimeItIsGenerated() { @Disabled("Remove to run test") @Test + @DisplayName("Maze is generated perfectly (single path, no isolated cells)") + public void theMazeIsPerfect() { + var maze = sut.generatePerfectMaze(RECTANGLE_ROWS, RECTANGLE_COLUMNS); + + assertThatMazeHasSinglePath(maze); + assertThatMazeHasNoIsolatedSections(maze); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("Maze with a seed is generated perfectly (single path, no isolated cells)") + public void theMazeIsPerfectWithSeed() { + var maze = sut.generatePerfectMaze(RECTANGLE_ROWS, RECTANGLE_COLUMNS, SEED_ONE); + + assertThatMazeHasSinglePath(maze); + assertThatMazeHasNoIsolatedSections(maze); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("Mazes generated with same seed are identical") public void twoMazesWithSameSeedShouldBeEqual() { var maze1 = sut.generatePerfectMaze(RECTANGLE_ROWS, RECTANGLE_COLUMNS, SEED_ONE); var maze2 = sut.generatePerfectMaze(RECTANGLE_ROWS, RECTANGLE_COLUMNS, SEED_ONE); @@ -107,6 +134,7 @@ public void twoMazesWithSameSeedShouldBeEqual() { @Disabled("Remove to run test") @Test + @DisplayName("Mazes generated with different seeds are different") public void twoMazesWithDifferentSeedsShouldNotBeEqual() { var maze1 = sut.generatePerfectMaze(RECTANGLE_ROWS, RECTANGLE_COLUMNS, SEED_ONE); var maze2 = sut.generatePerfectMaze(RECTANGLE_ROWS, RECTANGLE_COLUMNS, SEED_TWO); @@ -118,24 +146,7 @@ public void twoMazesWithDifferentSeedsShouldNotBeEqual() { @Disabled("Remove to run test") @Test - public void theMazeIsPerfect() { - var maze = sut.generatePerfectMaze(RECTANGLE_ROWS, RECTANGLE_COLUMNS); - - assertThatMazeHasSinglePath(maze); - assertThatMazeHasNoIsolatedSections(maze); - } - - @Disabled("Remove to run test") - @Test - public void theMazeIsPerfectWithSeed() { - var maze = sut.generatePerfectMaze(RECTANGLE_ROWS, RECTANGLE_COLUMNS, SEED_ONE); - - assertThatMazeHasSinglePath(maze); - assertThatMazeHasNoIsolatedSections(maze); - } - - @Disabled("Remove to run test") - @Test + @DisplayName("Throws when rows are less than five") public void shouldThrowExceptionWhenRowsIsLessThanFive() { assertThatIllegalArgumentException() .isThrownBy(() -> sut.generatePerfectMaze(0, RECTANGLE_COLUMNS)); @@ -143,6 +154,7 @@ public void shouldThrowExceptionWhenRowsIsLessThanFive() { @Disabled("Remove to run test") @Test + @DisplayName("Throws when columns are less than five") public void shouldThrowExceptionWhenColumnsIsLessThanFive() { assertThatIllegalArgumentException() .isThrownBy(() -> sut.generatePerfectMaze(RECTANGLE_ROWS, 0)); @@ -150,6 +162,7 @@ public void shouldThrowExceptionWhenColumnsIsLessThanFive() { @Disabled("Remove to run test") @Test + @DisplayName("Throws when rows exceed hundred") public void shouldThrowExceptionWhenRowsIsMoreThenHundred() { assertThatIllegalArgumentException() .isThrownBy(() -> sut.generatePerfectMaze(101, RECTANGLE_COLUMNS)); @@ -157,6 +170,7 @@ public void shouldThrowExceptionWhenRowsIsMoreThenHundred() { @Disabled("Remove to run test") @Test + @DisplayName("Throws when columns exceed hundred") public void shouldThrowExceptionWhenColumnsIsMoreThenHundred() { assertThatIllegalArgumentException() .isThrownBy(() -> sut.generatePerfectMaze(RECTANGLE_ROWS, 101)); diff --git a/exercises/practice/meetup/.docs/instructions.md b/exercises/practice/meetup/.docs/instructions.md index 000de2fd1..8b1bda5eb 100644 --- a/exercises/practice/meetup/.docs/instructions.md +++ b/exercises/practice/meetup/.docs/instructions.md @@ -2,7 +2,7 @@ Your task is to find the exact date of a meetup, given a month, year, weekday and week. -There are five week values to consider: `first`, `second`, `third`, `fourth`, `last`, `teenth`. +There are six week values to consider: `first`, `second`, `third`, `fourth`, `last`, `teenth`. For example, you might be asked to find the date for the meetup on the first Monday in January 2018 (January 1, 2018). diff --git a/exercises/practice/meetup/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/meetup/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/meetup/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/meetup/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/meetup/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/meetup/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/meetup/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/meetup/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/meetup/gradlew b/exercises/practice/meetup/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/meetup/gradlew +++ b/exercises/practice/meetup/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/meetup/gradlew.bat b/exercises/practice/meetup/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/meetup/gradlew.bat +++ b/exercises/practice/meetup/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/meetup/src/test/java/MeetupTest.java b/exercises/practice/meetup/src/test/java/MeetupTest.java index 47eab9ad7..193eaa9ea 100644 --- a/exercises/practice/meetup/src/test/java/MeetupTest.java +++ b/exercises/practice/meetup/src/test/java/MeetupTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.time.DayOfWeek; @@ -9,6 +10,7 @@ public class MeetupTest { @Test + @DisplayName("when teenth Monday is the 13th, the first day of the teenth week") public void testMonteenthOfMay2013() { LocalDate expected = LocalDate.of(2013, 5, 13); Meetup meetup = new Meetup(5, 2013); @@ -17,6 +19,7 @@ public void testMonteenthOfMay2013() { @Disabled("Remove to run test") @Test + @DisplayName("when teenth Monday is the 19th, the last day of the teenth week") public void testMonteenthOfAugust2013() { LocalDate expected = LocalDate.of(2013, 8, 19); Meetup meetup = new Meetup(8, 2013); @@ -25,6 +28,7 @@ public void testMonteenthOfAugust2013() { @Disabled("Remove to run test") @Test + @DisplayName("when teenth Monday is some day in the middle of the teenth week") public void testMonteenthOfSeptember2013() { LocalDate expected = LocalDate.of(2013, 9, 16); Meetup meetup = new Meetup(9, 2013); @@ -33,6 +37,7 @@ public void testMonteenthOfSeptember2013() { @Disabled("Remove to run test") @Test + @DisplayName("when teenth Tuesday is the 19th, the last day of the teenth week") public void testTuesteenthOfMarch2013() { LocalDate expected = LocalDate.of(2013, 3, 19); Meetup meetup = new Meetup(3, 2013); @@ -41,6 +46,7 @@ public void testTuesteenthOfMarch2013() { @Disabled("Remove to run test") @Test + @DisplayName("when teenth Tuesday is some day in the middle of the teenth week") public void testTuesteenthOfApril2013() { LocalDate expected = LocalDate.of(2013, 4, 16); Meetup meetup = new Meetup(4, 2013); @@ -49,6 +55,7 @@ public void testTuesteenthOfApril2013() { @Disabled("Remove to run test") @Test + @DisplayName("when teenth Tuesday is the 13th, the first day of the teenth week") public void testTuesteenthOfAugust2013() { LocalDate expected = LocalDate.of(2013, 8, 13); Meetup meetup = new Meetup(8, 2013); @@ -57,6 +64,7 @@ public void testTuesteenthOfAugust2013() { @Disabled("Remove to run test") @Test + @DisplayName("when teenth Wednesday is some day in the middle of the teenth week") public void testWednesteenthOfJanuary2013() { LocalDate expected = LocalDate.of(2013, 1, 16); Meetup meetup = new Meetup(1, 2013); @@ -65,6 +73,7 @@ public void testWednesteenthOfJanuary2013() { @Disabled("Remove to run test") @Test + @DisplayName("when teenth Wednesday is the 13th, the first day of the teenth week") public void testWednesteenthOfFebruary2013() { LocalDate expected = LocalDate.of(2013, 2, 13); Meetup meetup = new Meetup(2, 2013); @@ -73,6 +82,7 @@ public void testWednesteenthOfFebruary2013() { @Disabled("Remove to run test") @Test + @DisplayName("when teenth Wednesday is the 19th, the last day of the teenth week") public void testWednesteenthOfJune2013() { LocalDate expected = LocalDate.of(2013, 6, 19); Meetup meetup = new Meetup(6, 2013); @@ -81,6 +91,7 @@ public void testWednesteenthOfJune2013() { @Disabled("Remove to run test") @Test + @DisplayName("when teenth Thursday is some day in the middle of the teenth week") public void testThursteenthOfMay2013() { LocalDate expected = LocalDate.of(2013, 5, 16); Meetup meetup = new Meetup(5, 2013); @@ -89,6 +100,7 @@ public void testThursteenthOfMay2013() { @Disabled("Remove to run test") @Test + @DisplayName("when teenth Thursday is the 13th, the first day of the teenth week") public void testThursteenthOfJune2013() { LocalDate expected = LocalDate.of(2013, 6, 13); Meetup meetup = new Meetup(6, 2013); @@ -97,6 +109,7 @@ public void testThursteenthOfJune2013() { @Disabled("Remove to run test") @Test + @DisplayName("when teenth Thursday is the 19th, the last day of the teenth week") public void testThursteenthOfSeptember2013() { LocalDate expected = LocalDate.of(2013, 9, 19); Meetup meetup = new Meetup(9, 2013); @@ -105,6 +118,7 @@ public void testThursteenthOfSeptember2013() { @Disabled("Remove to run test") @Test + @DisplayName("when teenth Friday is the 19th, the last day of the teenth week") public void testFriteenthOfApril2013() { LocalDate expected = LocalDate.of(2013, 4, 19); Meetup meetup = new Meetup(4, 2013); @@ -113,6 +127,7 @@ public void testFriteenthOfApril2013() { @Disabled("Remove to run test") @Test + @DisplayName("when teenth Friday is some day in the middle of the teenth week") public void testFriteenthOfAugust2013() { LocalDate expected = LocalDate.of(2013, 8, 16); Meetup meetup = new Meetup(8, 2013); @@ -121,6 +136,7 @@ public void testFriteenthOfAugust2013() { @Disabled("Remove to run test") @Test + @DisplayName("when teenth Friday is the 13th, the first day of the teenth week") public void testFriteenthOfSeptember2013() { LocalDate expected = LocalDate.of(2013, 9, 13); Meetup meetup = new Meetup(9, 2013); @@ -129,6 +145,7 @@ public void testFriteenthOfSeptember2013() { @Disabled("Remove to run test") @Test + @DisplayName("when teenth Saturday is some day in the middle of the teenth week") public void testSaturteenthOfFebruary2013() { LocalDate expected = LocalDate.of(2013, 2, 16); Meetup meetup = new Meetup(2, 2013); @@ -137,6 +154,7 @@ public void testSaturteenthOfFebruary2013() { @Disabled("Remove to run test") @Test + @DisplayName("when teenth Saturday is the 13th, the first day of the teenth week") public void testSaturteenthOfApril2013() { LocalDate expected = LocalDate.of(2013, 4, 13); Meetup meetup = new Meetup(4, 2013); @@ -145,6 +163,7 @@ public void testSaturteenthOfApril2013() { @Disabled("Remove to run test") @Test + @DisplayName("when teenth Saturday is the 19th, the last day of the teenth week") public void testSaturteenthOfOctober2013() { LocalDate expected = LocalDate.of(2013, 10, 19); Meetup meetup = new Meetup(10, 2013); @@ -153,6 +172,7 @@ public void testSaturteenthOfOctober2013() { @Disabled("Remove to run test") @Test + @DisplayName("when teenth Sunday is the 19th, the last day of the teenth week") public void testSunteenthOfMay2013() { LocalDate expected = LocalDate.of(2013, 5, 19); Meetup meetup = new Meetup(5, 2013); @@ -161,6 +181,7 @@ public void testSunteenthOfMay2013() { @Disabled("Remove to run test") @Test + @DisplayName("when teenth Sunday is some day in the middle of the teenth week") public void testSunteenthOfJune2013() { LocalDate expected = LocalDate.of(2013, 6, 16); Meetup meetup = new Meetup(6, 2013); @@ -169,6 +190,7 @@ public void testSunteenthOfJune2013() { @Disabled("Remove to run test") @Test + @DisplayName("when teenth Sunday is the 13th, the first day of the teenth week") public void testSunteenthOfOctober2013() { LocalDate expected = LocalDate.of(2013, 10, 13); Meetup meetup = new Meetup(10, 2013); @@ -177,6 +199,7 @@ public void testSunteenthOfOctober2013() { @Disabled("Remove to run test") @Test + @DisplayName("when first Monday is some day in the middle of the first week") public void testFirstMondayOfMarch2013() { LocalDate expected = LocalDate.of(2013, 3, 4); Meetup meetup = new Meetup(3, 2013); @@ -185,6 +208,7 @@ public void testFirstMondayOfMarch2013() { @Disabled("Remove to run test") @Test + @DisplayName("when first Monday is the 1st, the first day of the first week") public void testFirstMondayOfApril2013() { LocalDate expected = LocalDate.of(2013, 4, 1); Meetup meetup = new Meetup(4, 2013); @@ -193,6 +217,7 @@ public void testFirstMondayOfApril2013() { @Disabled("Remove to run test") @Test + @DisplayName("when first Tuesday is the 7th, the last day of the first week") public void testFirstTuesdayOfMay2013() { LocalDate expected = LocalDate.of(2013, 5, 7); Meetup meetup = new Meetup(5, 2013); @@ -201,6 +226,7 @@ public void testFirstTuesdayOfMay2013() { @Disabled("Remove to run test") @Test + @DisplayName("when first Tuesday is some day in the middle of the first week") public void testFirstTuesdayOfJune2013() { LocalDate expected = LocalDate.of(2013, 6, 4); Meetup meetup = new Meetup(6, 2013); @@ -209,6 +235,7 @@ public void testFirstTuesdayOfJune2013() { @Disabled("Remove to run test") @Test + @DisplayName("when first Wednesday is some day in the middle of the first week") public void testFirstWednesdayOfJuly2013() { LocalDate expected = LocalDate.of(2013, 7, 3); Meetup meetup = new Meetup(7, 2013); @@ -217,6 +244,7 @@ public void testFirstWednesdayOfJuly2013() { @Disabled("Remove to run test") @Test + @DisplayName("when first Wednesday is the 7th, the last day of the first week") public void testFirstWednesdayOfAugust2013() { LocalDate expected = LocalDate.of(2013, 8, 7); Meetup meetup = new Meetup(8, 2013); @@ -225,6 +253,7 @@ public void testFirstWednesdayOfAugust2013() { @Disabled("Remove to run test") @Test + @DisplayName("when first Thursday is some day in the middle of the first wee") public void testFirstThursdayOfSeptember2013() { LocalDate expected = LocalDate.of(2013, 9, 5); Meetup meetup = new Meetup(9, 2013); @@ -233,6 +262,7 @@ public void testFirstThursdayOfSeptember2013() { @Disabled("Remove to run test") @Test + @DisplayName("when first Thursday is another day in the middle of the first week") public void testFirstThursdayOfOctober2013() { LocalDate expected = LocalDate.of(2013, 10, 3); Meetup meetup = new Meetup(10, 2013); @@ -241,6 +271,7 @@ public void testFirstThursdayOfOctober2013() { @Disabled("Remove to run test") @Test + @DisplayName("when first Friday is the 1st, the first day of the first week") public void testFirstFridayOfNovember2013() { LocalDate expected = LocalDate.of(2013, 11, 1); Meetup meetup = new Meetup(11, 2013); @@ -249,6 +280,7 @@ public void testFirstFridayOfNovember2013() { @Disabled("Remove to run test") @Test + @DisplayName("when first Friday is some day in the middle of the first week") public void testFirstFridayOfDecember2013() { LocalDate expected = LocalDate.of(2013, 12, 6); Meetup meetup = new Meetup(12, 2013); @@ -257,6 +289,7 @@ public void testFirstFridayOfDecember2013() { @Disabled("Remove to run test") @Test + @DisplayName("when first Saturday is some day in the middle of the first week") public void testFirstSaturdayOfJanuary2013() { LocalDate expected = LocalDate.of(2013, 1, 5); Meetup meetup = new Meetup(1, 2013); @@ -265,6 +298,7 @@ public void testFirstSaturdayOfJanuary2013() { @Disabled("Remove to run test") @Test + @DisplayName("when first Saturday is another day in the middle of the first week") public void testFirstSaturdayOfFebruary2013() { LocalDate expected = LocalDate.of(2013, 2, 2); Meetup meetup = new Meetup(2, 2013); @@ -273,6 +307,7 @@ public void testFirstSaturdayOfFebruary2013() { @Disabled("Remove to run test") @Test + @DisplayName("when first Sunday is some day in the middle of the first week") public void testFirstSundayOfMarch2013() { LocalDate expected = LocalDate.of(2013, 3, 3); Meetup meetup = new Meetup(3, 2013); @@ -281,6 +316,7 @@ public void testFirstSundayOfMarch2013() { @Disabled("Remove to run test") @Test + @DisplayName("when first Sunday is the 7th, the last day of the first week") public void testFirstSundayOfApril2013() { LocalDate expected = LocalDate.of(2013, 4, 7); Meetup meetup = new Meetup(4, 2013); @@ -289,6 +325,7 @@ public void testFirstSundayOfApril2013() { @Disabled("Remove to run test") @Test + @DisplayName("when second Monday is some day in the middle of the second week") public void testSecondMondayOfMarch2013() { LocalDate expected = LocalDate.of(2013, 3, 11); Meetup meetup = new Meetup(3, 2013); @@ -297,6 +334,7 @@ public void testSecondMondayOfMarch2013() { @Disabled("Remove to run test") @Test + @DisplayName("when second Monday is the 8th, the first day of the second week") public void testSecondMondayOfApril2013() { LocalDate expected = LocalDate.of(2013, 4, 8); Meetup meetup = new Meetup(4, 2013); @@ -305,6 +343,7 @@ public void testSecondMondayOfApril2013() { @Disabled("Remove to run test") @Test + @DisplayName("when second Tuesday is the 14th, the last day of the second week") public void testSecondTuesdayOfMay2013() { LocalDate expected = LocalDate.of(2013, 5, 14); Meetup meetup = new Meetup(5, 2013); @@ -313,6 +352,7 @@ public void testSecondTuesdayOfMay2013() { @Disabled("Remove to run test") @Test + @DisplayName("when second Tuesday is some day in the middle of the second week") public void testSecondTuesdayOfJune2013() { LocalDate expected = LocalDate.of(2013, 6, 11); Meetup meetup = new Meetup(6, 2013); @@ -321,6 +361,7 @@ public void testSecondTuesdayOfJune2013() { @Disabled("Remove to run test") @Test + @DisplayName("when second Wednesday is some day in the middle of the second week") public void testSecondWednesdayOfJuly2013() { LocalDate expected = LocalDate.of(2013, 7, 10); Meetup meetup = new Meetup(7, 2013); @@ -329,6 +370,7 @@ public void testSecondWednesdayOfJuly2013() { @Disabled("Remove to run test") @Test + @DisplayName("when second Wednesday is the 14th, the last day of the second week") public void testSecondWednesdayOfAugust2013() { LocalDate expected = LocalDate.of(2013, 8, 14); Meetup meetup = new Meetup(8, 2013); @@ -337,6 +379,7 @@ public void testSecondWednesdayOfAugust2013() { @Disabled("Remove to run test") @Test + @DisplayName("when second Thursday is some day in the middle of the second week") public void testSecondThursdayOfSeptember2013() { LocalDate expected = LocalDate.of(2013, 9, 12); Meetup meetup = new Meetup(9, 2013); @@ -345,6 +388,7 @@ public void testSecondThursdayOfSeptember2013() { @Disabled("Remove to run test") @Test + @DisplayName("when second Thursday is another day in the middle of the second week") public void testSecondThursdayOfOctober2013() { LocalDate expected = LocalDate.of(2013, 10, 10); Meetup meetup = new Meetup(10, 2013); @@ -353,6 +397,7 @@ public void testSecondThursdayOfOctober2013() { @Disabled("Remove to run test") @Test + @DisplayName("when second Friday is the 8th, the first day of the second week") public void testSecondFridayOfNovember2013() { LocalDate expected = LocalDate.of(2013, 11, 8); Meetup meetup = new Meetup(11, 2013); @@ -361,6 +406,7 @@ public void testSecondFridayOfNovember2013() { @Disabled("Remove to run test") @Test + @DisplayName("when second Friday is some day in the middle of the second week") public void testSecondFridayOfDecember2013() { LocalDate expected = LocalDate.of(2013, 12, 13); Meetup meetup = new Meetup(12, 2013); @@ -369,6 +415,7 @@ public void testSecondFridayOfDecember2013() { @Disabled("Remove to run test") @Test + @DisplayName("when second Saturday is some day in the middle of the second week") public void testSecondSaturdayOfJanuary2013() { LocalDate expected = LocalDate.of(2013, 1, 12); Meetup meetup = new Meetup(1, 2013); @@ -377,6 +424,7 @@ public void testSecondSaturdayOfJanuary2013() { @Disabled("Remove to run test") @Test + @DisplayName("when second Saturday is another day in the middle of the second week") public void testSecondSaturdayOfFebruary2013() { LocalDate expected = LocalDate.of(2013, 2, 9); Meetup meetup = new Meetup(2, 2013); @@ -385,6 +433,7 @@ public void testSecondSaturdayOfFebruary2013() { @Disabled("Remove to run test") @Test + @DisplayName("when second Sunday is some day in the middle of the second week") public void testSecondSundayOfMarch2013() { LocalDate expected = LocalDate.of(2013, 3, 10); Meetup meetup = new Meetup(3, 2013); @@ -393,6 +442,7 @@ public void testSecondSundayOfMarch2013() { @Disabled("Remove to run test") @Test + @DisplayName("when second Sunday is the 14th, the last day of the second week") public void testSecondSundayOfApril2013() { LocalDate expected = LocalDate.of(2013, 4, 14); Meetup meetup = new Meetup(4, 2013); @@ -401,6 +451,7 @@ public void testSecondSundayOfApril2013() { @Disabled("Remove to run test") @Test + @DisplayName("when third Monday is some day in the middle of the third week") public void testThirdMondayOfMarch2013() { LocalDate expected = LocalDate.of(2013, 3, 18); Meetup meetup = new Meetup(3, 2013); @@ -409,6 +460,7 @@ public void testThirdMondayOfMarch2013() { @Disabled("Remove to run test") @Test + @DisplayName("when third Monday is the 15th, the first day of the third week") public void testThirdMondayOfApril2013() { LocalDate expected = LocalDate.of(2013, 4, 15); Meetup meetup = new Meetup(4, 2013); @@ -417,6 +469,7 @@ public void testThirdMondayOfApril2013() { @Disabled("Remove to run test") @Test + @DisplayName("when third Tuesday is the 21st, the last day of the third week") public void testThirdTuesdayOfMay2013() { LocalDate expected = LocalDate.of(2013, 5, 21); Meetup meetup = new Meetup(5, 2013); @@ -425,6 +478,7 @@ public void testThirdTuesdayOfMay2013() { @Disabled("Remove to run test") @Test + @DisplayName("when third Tuesday is some day in the middle of the third week") public void testThirdTuesdayOfJune2013() { LocalDate expected = LocalDate.of(2013, 6, 18); Meetup meetup = new Meetup(6, 2013); @@ -433,6 +487,7 @@ public void testThirdTuesdayOfJune2013() { @Disabled("Remove to run test") @Test + @DisplayName("when third Wednesday is some day in the middle of the third week") public void testThirdWednesdayOfJuly2013() { LocalDate expected = LocalDate.of(2013, 7, 17); Meetup meetup = new Meetup(7, 2013); @@ -441,6 +496,7 @@ public void testThirdWednesdayOfJuly2013() { @Disabled("Remove to run test") @Test + @DisplayName("when third Wednesday is the 21st, the last day of the third week") public void testThirdWednesdayOfAugust2013() { LocalDate expected = LocalDate.of(2013, 8, 21); Meetup meetup = new Meetup(8, 2013); @@ -449,6 +505,7 @@ public void testThirdWednesdayOfAugust2013() { @Disabled("Remove to run test") @Test + @DisplayName("when third Thursday is some day in the middle of the third week") public void testThirdThursdayOfSeptember2013() { LocalDate expected = LocalDate.of(2013, 9, 19); Meetup meetup = new Meetup(9, 2013); @@ -457,6 +514,7 @@ public void testThirdThursdayOfSeptember2013() { @Disabled("Remove to run test") @Test + @DisplayName("when third Thursday is another day in the middle of the third week") public void testThirdThursdayOfOctober2013() { LocalDate expected = LocalDate.of(2013, 10, 17); Meetup meetup = new Meetup(10, 2013); @@ -465,6 +523,7 @@ public void testThirdThursdayOfOctober2013() { @Disabled("Remove to run test") @Test + @DisplayName("when third Friday is the 15th, the first day of the third week") public void testThirdFridayOfNovember2013() { LocalDate expected = LocalDate.of(2013, 11, 15); Meetup meetup = new Meetup(11, 2013); @@ -473,6 +532,7 @@ public void testThirdFridayOfNovember2013() { @Disabled("Remove to run test") @Test + @DisplayName("when third Friday is some day in the middle of the third week") public void testThirdFridayOfDecember2013() { LocalDate expected = LocalDate.of(2013, 12, 20); Meetup meetup = new Meetup(12, 2013); @@ -481,6 +541,7 @@ public void testThirdFridayOfDecember2013() { @Disabled("Remove to run test") @Test + @DisplayName("when third Saturday is some day in the middle of the third week") public void testThirdSaturdayOfJanuary2013() { LocalDate expected = LocalDate.of(2013, 1, 19); Meetup meetup = new Meetup(1, 2013); @@ -489,6 +550,7 @@ public void testThirdSaturdayOfJanuary2013() { @Disabled("Remove to run test") @Test + @DisplayName("when third Saturday is another day in the middle of the third week") public void testThirdSaturdayOfFebruary2013() { LocalDate expected = LocalDate.of(2013, 2, 16); Meetup meetup = new Meetup(2, 2013); @@ -497,6 +559,7 @@ public void testThirdSaturdayOfFebruary2013() { @Disabled("Remove to run test") @Test + @DisplayName("when third Sunday is some day in the middle of the third week") public void testThirdSundayOfMarch2013() { LocalDate expected = LocalDate.of(2013, 3, 17); Meetup meetup = new Meetup(3, 2013); @@ -505,6 +568,7 @@ public void testThirdSundayOfMarch2013() { @Disabled("Remove to run test") @Test + @DisplayName("when third Sunday is the 21st, the last day of the third week") public void testThirdSundayOfApril2013() { LocalDate expected = LocalDate.of(2013, 4, 21); Meetup meetup = new Meetup(4, 2013); @@ -513,6 +577,7 @@ public void testThirdSundayOfApril2013() { @Disabled("Remove to run test") @Test + @DisplayName("when fourth Monday is some day in the middle of the fourth week") public void testFourthMondayOfMarch2013() { LocalDate expected = LocalDate.of(2013, 3, 25); Meetup meetup = new Meetup(3, 2013); @@ -521,6 +586,7 @@ public void testFourthMondayOfMarch2013() { @Disabled("Remove to run test") @Test + @DisplayName("when fourth Monday is the 22nd, the first day of the fourth week") public void testFourthMondayOfApril2013() { LocalDate expected = LocalDate.of(2013, 4, 22); Meetup meetup = new Meetup(4, 2013); @@ -529,6 +595,7 @@ public void testFourthMondayOfApril2013() { @Disabled("Remove to run test") @Test + @DisplayName("when fourth Tuesday is the 28th, the last day of the fourth week") public void testFourthTuesdayOfMay2013() { LocalDate expected = LocalDate.of(2013, 5, 28); Meetup meetup = new Meetup(5, 2013); @@ -537,6 +604,7 @@ public void testFourthTuesdayOfMay2013() { @Disabled("Remove to run test") @Test + @DisplayName("when fourth Tuesday is some day in the middle of the fourth week") public void testFourthTuesdayOfJune2013() { LocalDate expected = LocalDate.of(2013, 6, 25); Meetup meetup = new Meetup(6, 2013); @@ -545,6 +613,7 @@ public void testFourthTuesdayOfJune2013() { @Disabled("Remove to run test") @Test + @DisplayName("when fourth Wednesday is some day in the middle of the fourth week") public void testFourthWednesdayOfJuly2013() { LocalDate expected = LocalDate.of(2013, 7, 24); Meetup meetup = new Meetup(7, 2013); @@ -553,6 +622,7 @@ public void testFourthWednesdayOfJuly2013() { @Disabled("Remove to run test") @Test + @DisplayName("when fourth Wednesday is the 28th, the last day of the fourth week") public void testFourthWednesdayOfAugust2013() { LocalDate expected = LocalDate.of(2013, 8, 28); Meetup meetup = new Meetup(8, 2013); @@ -561,6 +631,7 @@ public void testFourthWednesdayOfAugust2013() { @Disabled("Remove to run test") @Test + @DisplayName("when fourth Thursday is some day in the middle of the fourth week") public void testFourthThursdayOfSeptember2013() { LocalDate expected = LocalDate.of(2013, 9, 26); Meetup meetup = new Meetup(9, 2013); @@ -569,6 +640,7 @@ public void testFourthThursdayOfSeptember2013() { @Disabled("Remove to run test") @Test + @DisplayName("when fourth Thursday is another day in the middle of the fourth week") public void testFourthThursdayOfOctober2013() { LocalDate expected = LocalDate.of(2013, 10, 24); Meetup meetup = new Meetup(10, 2013); @@ -577,6 +649,7 @@ public void testFourthThursdayOfOctober2013() { @Disabled("Remove to run test") @Test + @DisplayName("when fourth Friday is the 22nd, the first day of the fourth week") public void testFourthFridayOfNovember2013() { LocalDate expected = LocalDate.of(2013, 11, 22); Meetup meetup = new Meetup(11, 2013); @@ -585,6 +658,7 @@ public void testFourthFridayOfNovember2013() { @Disabled("Remove to run test") @Test + @DisplayName("when fourth Friday is some day in the middle of the fourth week") public void testFourthFridayOfDecember2013() { LocalDate expected = LocalDate.of(2013, 12, 27); Meetup meetup = new Meetup(12, 2013); @@ -593,6 +667,7 @@ public void testFourthFridayOfDecember2013() { @Disabled("Remove to run test") @Test + @DisplayName("when fourth Saturday is some day in the middle of the fourth week") public void testFourthSaturdayOfJanuary2013() { LocalDate expected = LocalDate.of(2013, 1, 26); Meetup meetup = new Meetup(1, 2013); @@ -601,6 +676,7 @@ public void testFourthSaturdayOfJanuary2013() { @Disabled("Remove to run test") @Test + @DisplayName("when fourth Saturday is another day in the middle of the fourth week") public void testFourthSaturdayOfFebruary2013() { LocalDate expected = LocalDate.of(2013, 2, 23); Meetup meetup = new Meetup(2, 2013); @@ -609,6 +685,7 @@ public void testFourthSaturdayOfFebruary2013() { @Disabled("Remove to run test") @Test + @DisplayName("when fourth Sunday is some day in the middle of the fourth week") public void testFourthSundayOfMarch2013() { LocalDate expected = LocalDate.of(2013, 3, 24); Meetup meetup = new Meetup(3, 2013); @@ -617,6 +694,7 @@ public void testFourthSundayOfMarch2013() { @Disabled("Remove to run test") @Test + @DisplayName("when fourth Sunday is the 28th, the last day of the fourth week") public void testFourthSundayOfApril2013() { LocalDate expected = LocalDate.of(2013, 4, 28); Meetup meetup = new Meetup(4, 2013); @@ -625,6 +703,7 @@ public void testFourthSundayOfApril2013() { @Disabled("Remove to run test") @Test + @DisplayName("last Monday in a month with four Mondays") public void testLastMondayOfMarch2013() { LocalDate expected = LocalDate.of(2013, 3, 25); Meetup meetup = new Meetup(3, 2013); @@ -633,6 +712,7 @@ public void testLastMondayOfMarch2013() { @Disabled("Remove to run test") @Test + @DisplayName("last Monday in a month with five Mondays") public void testLastMondayOfApril2013() { LocalDate expected = LocalDate.of(2013, 4, 29); Meetup meetup = new Meetup(4, 2013); @@ -641,6 +721,7 @@ public void testLastMondayOfApril2013() { @Disabled("Remove to run test") @Test + @DisplayName("last Tuesday in a month with four Tuesdays") public void testLastTuesdayOfMay2013() { LocalDate expected = LocalDate.of(2013, 5, 28); Meetup meetup = new Meetup(5, 2013); @@ -649,6 +730,7 @@ public void testLastTuesdayOfMay2013() { @Disabled("Remove to run test") @Test + @DisplayName("last Tuesday in another month with four Tuesdays") public void testLastTuesdayOfJune2013() { LocalDate expected = LocalDate.of(2013, 6, 25); Meetup meetup = new Meetup(6, 2013); @@ -657,6 +739,7 @@ public void testLastTuesdayOfJune2013() { @Disabled("Remove to run test") @Test + @DisplayName("last Wednesday in a month with five Wednesdays") public void testLastWednesdayOfJuly2013() { LocalDate expected = LocalDate.of(2013, 7, 31); Meetup meetup = new Meetup(7, 2013); @@ -665,6 +748,7 @@ public void testLastWednesdayOfJuly2013() { @Disabled("Remove to run test") @Test + @DisplayName("last Wednesday in a month with four Wednesdays") public void testLastWednesdayOfAugust2013() { LocalDate expected = LocalDate.of(2013, 8, 28); Meetup meetup = new Meetup(8, 2013); @@ -673,6 +757,7 @@ public void testLastWednesdayOfAugust2013() { @Disabled("Remove to run test") @Test + @DisplayName("last Thursday in a month with four Thursdays") public void testLastThursdayOfSeptember2013() { LocalDate expected = LocalDate.of(2013, 9, 26); Meetup meetup = new Meetup(9, 2013); @@ -681,6 +766,7 @@ public void testLastThursdayOfSeptember2013() { @Disabled("Remove to run test") @Test + @DisplayName("last Thursday in a month with five Thursdays") public void testLastThursdayOfOctober2013() { LocalDate expected = LocalDate.of(2013, 10, 31); Meetup meetup = new Meetup(10, 2013); @@ -689,6 +775,7 @@ public void testLastThursdayOfOctober2013() { @Disabled("Remove to run test") @Test + @DisplayName("last Friday in a month with five Fridays") public void testLastFridayOfNovember2013() { LocalDate expected = LocalDate.of(2013, 11, 29); Meetup meetup = new Meetup(11, 2013); @@ -697,6 +784,7 @@ public void testLastFridayOfNovember2013() { @Disabled("Remove to run test") @Test + @DisplayName("last Friday in a month with four Fridays") public void testLastFridayOfDecember2013() { LocalDate expected = LocalDate.of(2013, 12, 27); Meetup meetup = new Meetup(12, 2013); @@ -705,6 +793,7 @@ public void testLastFridayOfDecember2013() { @Disabled("Remove to run test") @Test + @DisplayName("last Saturday in a month with four Saturdays") public void testLastSaturdayOfJanuary2013() { LocalDate expected = LocalDate.of(2013, 1, 26); Meetup meetup = new Meetup(1, 2013); @@ -713,6 +802,7 @@ public void testLastSaturdayOfJanuary2013() { @Disabled("Remove to run test") @Test + @DisplayName("last Saturday in another month with four Saturdays") public void testLastSaturdayOfFebruary2013() { LocalDate expected = LocalDate.of(2013, 2, 23); Meetup meetup = new Meetup(2, 2013); @@ -721,6 +811,7 @@ public void testLastSaturdayOfFebruary2013() { @Disabled("Remove to run test") @Test + @DisplayName("last Sunday in a month with five Sundays") public void testLastSundayOfMarch2013() { LocalDate expected = LocalDate.of(2013, 3, 31); Meetup meetup = new Meetup(3, 2013); @@ -729,6 +820,7 @@ public void testLastSundayOfMarch2013() { @Disabled("Remove to run test") @Test + @DisplayName("last Sunday in a month with four Sundays") public void testLastSundayOfApril2013() { LocalDate expected = LocalDate.of(2013, 4, 28); Meetup meetup = new Meetup(4, 2013); @@ -737,6 +829,7 @@ public void testLastSundayOfApril2013() { @Disabled("Remove to run test") @Test + @DisplayName("when last Wednesday in February in a leap year is the 29th") public void testLastWednesdayOfFebruary2012() { LocalDate expected = LocalDate.of(2012, 2, 29); Meetup meetup = new Meetup(2, 2012); @@ -745,6 +838,7 @@ public void testLastWednesdayOfFebruary2012() { @Disabled("Remove to run test") @Test + @DisplayName("last Wednesday in December that is also the last day of the year") public void testLastWednesdayOfDecember2014() { LocalDate expected = LocalDate.of(2014, 12, 31); Meetup meetup = new Meetup(12, 2014); @@ -753,6 +847,7 @@ public void testLastWednesdayOfDecember2014() { @Disabled("Remove to run test") @Test + @DisplayName("when last Sunday in February in a non-leap year is not the 29th") public void testLastSundayOfFebruary2015() { LocalDate expected = LocalDate.of(2015, 2, 22); Meetup meetup = new Meetup(2, 2015); @@ -761,6 +856,7 @@ public void testLastSundayOfFebruary2015() { @Disabled("Remove to run test") @Test + @DisplayName("when first Friday is the 7th, the last day of the first week") public void testFirstFridayOfDecember2012() { LocalDate expected = LocalDate.of(2012, 12, 7); Meetup meetup = new Meetup(12, 2012); diff --git a/exercises/practice/micro-blog/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/micro-blog/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/micro-blog/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/micro-blog/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/micro-blog/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/micro-blog/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/micro-blog/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/micro-blog/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/micro-blog/gradlew b/exercises/practice/micro-blog/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/micro-blog/gradlew +++ b/exercises/practice/micro-blog/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/micro-blog/gradlew.bat b/exercises/practice/micro-blog/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/micro-blog/gradlew.bat +++ b/exercises/practice/micro-blog/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/micro-blog/src/test/java/MicroBlogTest.java b/exercises/practice/micro-blog/src/test/java/MicroBlogTest.java index b22106041..1b44d5a78 100644 --- a/exercises/practice/micro-blog/src/test/java/MicroBlogTest.java +++ b/exercises/practice/micro-blog/src/test/java/MicroBlogTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -8,6 +9,7 @@ public class MicroBlogTest { private final MicroBlog microBlog = new MicroBlog(); @Test + @DisplayName("English language short") public void englishLanguageShort() { String expected = "Hi"; assertThat(microBlog.truncate("Hi")).isEqualTo(expected); @@ -15,6 +17,7 @@ public void englishLanguageShort() { @Disabled("Remove to run test") @Test + @DisplayName("English language long") public void englishLanguageLong() { String expected = "Hello"; assertThat(microBlog.truncate("Hello there")).isEqualTo(expected); @@ -22,34 +25,39 @@ public void englishLanguageLong() { @Disabled("Remove to run test") @Test - public void germanLanguageShort_broth() { + @DisplayName("German language short (broth)") + public void germanLanguageShortBroth() { String expected = "brühe"; assertThat(microBlog.truncate("brühe")).isEqualTo(expected); } @Disabled("Remove to run test") @Test - public void germanLanguageLong_bearCarpet_to_beards() { + @DisplayName("German language long (bear carpet → beards)") + public void germanLanguageLongBearCarpetToBeards() { String expected = "Bärte"; assertThat(microBlog.truncate("Bärteppich")).isEqualTo(expected); } @Disabled("Remove to run test") @Test - public void bulgarianLanguageShort_good() { + @DisplayName("Bulgarian language short (good)") + public void bulgarianLanguageShortGood() { String expected = "Добър"; assertThat(microBlog.truncate("Добър")).isEqualTo(expected); } @Disabled("Remove to run test") @Test - public void greekLanguageShort_health() { + @DisplayName("Greek language short (health)") + public void greekLanguageShortHealth() { String expected = "υγειά"; assertThat(microBlog.truncate("υγειά")).isEqualTo(expected); } @Disabled("Remove to run test") @Test + @DisplayName("Maths short") public void mathsShort() { String expected = "a=πr²"; assertThat(microBlog.truncate("a=πr²")).isEqualTo(expected); @@ -57,6 +65,7 @@ public void mathsShort() { @Disabled("Remove to run test") @Test + @DisplayName("Maths long") public void mathsLong() { String expected = "∅⊊ℕ⊊ℤ"; assertThat(microBlog.truncate("∅⊊ℕ⊊ℤ⊊ℚ⊊ℝ⊊ℂ")).isEqualTo(expected); @@ -64,6 +73,7 @@ public void mathsLong() { @Disabled("Remove to run test") @Test + @DisplayName("English and emoji short") public void englishAndEmojiShort() { String expected = "Fly 🛫"; assertThat(microBlog.truncate("Fly 🛫")).isEqualTo(expected); @@ -71,6 +81,7 @@ public void englishAndEmojiShort() { @Disabled("Remove to run test") @Test + @DisplayName("Emoji short") public void emojiShort() { String expected = "💇"; assertThat(microBlog.truncate("💇")).isEqualTo(expected); @@ -78,6 +89,7 @@ public void emojiShort() { @Disabled("Remove to run test") @Test + @DisplayName("Emoji long") public void emojiLong() { String expected = "❄🌡🤧🤒🏥"; assertThat(microBlog.truncate("❄🌡🤧🤒🏥🕰😀")).isEqualTo(expected); @@ -85,6 +97,7 @@ public void emojiLong() { @Disabled("Remove to run test") @Test + @DisplayName("Royal Flush?") public void royalFlush() { String expected = "🃎🂸🃅🃋🃍"; assertThat(microBlog.truncate("🃎🂸🃅🃋🃍🃁🃊")).isEqualTo(expected); diff --git a/exercises/practice/nth-prime/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/nth-prime/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/nth-prime/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/nth-prime/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/nth-prime/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/nth-prime/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/nth-prime/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/nth-prime/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/nth-prime/gradlew b/exercises/practice/nth-prime/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/nth-prime/gradlew +++ b/exercises/practice/nth-prime/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/nth-prime/gradlew.bat b/exercises/practice/nth-prime/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/nth-prime/gradlew.bat +++ b/exercises/practice/nth-prime/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/nth-prime/src/test/java/PrimeCalculatorTest.java b/exercises/practice/nth-prime/src/test/java/PrimeCalculatorTest.java index e13c7f23d..10d0bcf29 100644 --- a/exercises/practice/nth-prime/src/test/java/PrimeCalculatorTest.java +++ b/exercises/practice/nth-prime/src/test/java/PrimeCalculatorTest.java @@ -1,8 +1,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; - import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; public class PrimeCalculatorTest { @@ -10,30 +10,35 @@ public class PrimeCalculatorTest { private PrimeCalculator primeCalculator = new PrimeCalculator(); @Test + @DisplayName("first prime") public void testFirstPrime() { assertThat(primeCalculator.nth(1)).isEqualTo(2); } @Disabled("Remove to run test") @Test + @DisplayName("second prime") public void testSecondPrime() { assertThat(primeCalculator.nth(2)).isEqualTo(3); } @Disabled("Remove to run test") @Test + @DisplayName("sixth prime") public void testSixthPrime() { assertThat(primeCalculator.nth(6)).isEqualTo(13); } @Disabled("Remove to run test") @Test + @DisplayName("big prime") public void testBigPrime() { assertThat(primeCalculator.nth(10001)).isEqualTo(104743); } @Disabled("Remove to run test") @Test + @DisplayName("there is no zeroth prime") public void testUndefinedPrime() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> primeCalculator.nth(0)); diff --git a/exercises/practice/nucleotide-count/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/nucleotide-count/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/nucleotide-count/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/nucleotide-count/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/nucleotide-count/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/nucleotide-count/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/nucleotide-count/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/nucleotide-count/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/nucleotide-count/gradlew b/exercises/practice/nucleotide-count/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/nucleotide-count/gradlew +++ b/exercises/practice/nucleotide-count/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/nucleotide-count/gradlew.bat b/exercises/practice/nucleotide-count/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/nucleotide-count/gradlew.bat +++ b/exercises/practice/nucleotide-count/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/nucleotide-count/src/test/java/NucleotideCounterTest.java b/exercises/practice/nucleotide-count/src/test/java/NucleotideCounterTest.java index b47fb836e..d5938268a 100644 --- a/exercises/practice/nucleotide-count/src/test/java/NucleotideCounterTest.java +++ b/exercises/practice/nucleotide-count/src/test/java/NucleotideCounterTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.Map; @@ -9,6 +10,7 @@ public class NucleotideCounterTest { @Test + @DisplayName("empty strand") public void testEmptyDnaStringHasNoNucleotides() { NucleotideCounter nucleotideCounter = new NucleotideCounter(""); @@ -19,6 +21,7 @@ public void testEmptyDnaStringHasNoNucleotides() { @Disabled("Remove to run test") @Test + @DisplayName("can count one nucleotide in single-character input") public void testDnaStringHasOneNucleotide() { NucleotideCounter nucleotideCounter = new NucleotideCounter("G"); @@ -29,6 +32,7 @@ public void testDnaStringHasOneNucleotide() { @Disabled("Remove to run test") @Test + @DisplayName("strand with repeated nucleotide") public void testRepetitiveSequenceWithOnlyGuanine() { NucleotideCounter nucleotideCounter = new NucleotideCounter("GGGGGGG"); @@ -39,6 +43,7 @@ public void testRepetitiveSequenceWithOnlyGuanine() { @Disabled("Remove to run test") @Test + @DisplayName("strand with multiple nucleotides") public void testDnaStringHasMultipleNucleotide() { NucleotideCounter nucleotideCounter = new NucleotideCounter("AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTGTCTGATAGCAGC"); @@ -50,6 +55,7 @@ public void testDnaStringHasMultipleNucleotide() { @Disabled("Remove to run test") @Test + @DisplayName("strand with invalid nucleotides") public void testDnaStringHasInvalidNucleotides() { assertThatThrownBy(() -> new NucleotideCounter("AGXXACT")) .isInstanceOf(IllegalArgumentException.class); diff --git a/exercises/practice/ocr-numbers/.docs/instructions.md b/exercises/practice/ocr-numbers/.docs/instructions.md index 7beb25779..8a391ce4f 100644 --- a/exercises/practice/ocr-numbers/.docs/instructions.md +++ b/exercises/practice/ocr-numbers/.docs/instructions.md @@ -1,79 +1,47 @@ # Instructions -Given a 3 x 4 grid of pipes, underscores, and spaces, determine which number is represented, or whether it is garbled. +Optical Character Recognition or OCR is software that converts images of text into machine-readable text. +Given a grid of characters representing some digits, convert the grid to a string of digits. +If the grid has multiple rows of cells, the rows should be separated in the output with a `","`. -## Step One +- The grid is made of one of more lines of cells. +- Each line of the grid is made of one or more cells. +- Each cell is three columns wide and four rows high (3x4) and represents one digit. +- Digits are drawn using pipes (`"|"`), underscores (`"_"`), and spaces (`" "`). -To begin with, convert a simple binary font to a string containing 0 or 1. +## Edge cases -The binary font uses pipes and underscores, four rows high and three columns wide. +- If the input is not a valid size, your program should indicate there is an error. +- If the input is the correct size, but a cell is not recognizable, your program should output a `"?"` for that character. -```text - _ # - | | # zero. - |_| # - # the fourth row is always blank -``` +## Examples -Is converted to "0" - -```text - # - | # one. - | # - # (blank fourth row) -``` - -Is converted to "1" - -If the input is the correct size, but not recognizable, your program should return '?' - -If the input is the incorrect size, your program should return an error. - -## Step Two - -Update your program to recognize multi-character binary strings, replacing garbled numbers with ? - -## Step Three - -Update your program to recognize all numbers 0 through 9, both individually and as part of a larger string. - -```text - _ - _| -|_ - -``` - -Is converted to "2" +The following input (without the comments) is converted to `"1234567890"`. ```text _ _ _ _ _ _ _ _ # - | _| _||_||_ |_ ||_||_|| | # decimal numbers. + | _| _||_||_ |_ ||_||_|| | # Decimal numbers. ||_ _| | _||_| ||_| _||_| # - # fourth line is always blank + # The fourth line is always blank, ``` -Is converted to "1234567890" - -## Step Four +The following input is converted to `"123,456,789"`. -Update your program to handle multiple numbers, one per line. -When converting several lines, join the lines with commas. + ```text - _ _ + _ _ | _| _| ||_ _| - - _ _ -|_||_ |_ + + _ _ +|_||_ |_ | _||_| - - _ _ _ + + _ _ _ ||_||_| ||_| _| - + ``` -Is converted to "123,456,789". + diff --git a/exercises/practice/ocr-numbers/.docs/introduction.md b/exercises/practice/ocr-numbers/.docs/introduction.md new file mode 100644 index 000000000..366d76062 --- /dev/null +++ b/exercises/practice/ocr-numbers/.docs/introduction.md @@ -0,0 +1,6 @@ +# Introduction + +Your best friend Marta recently landed their dream job working with a local history museum's collections. +Knowing of your interests in programming, they confide in you about an issue at work for an upcoming exhibit on computing history. +A local university's math department had donated several boxes of historical printouts, but given the poor condition of the documents, the decision has been made to digitize the text. +However, the university's old printer had some quirks in how text was represented, and your friend could use your help to extract the data successfully. diff --git a/exercises/practice/ocr-numbers/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/ocr-numbers/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/ocr-numbers/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/ocr-numbers/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/ocr-numbers/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/ocr-numbers/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/ocr-numbers/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/ocr-numbers/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/ocr-numbers/gradlew b/exercises/practice/ocr-numbers/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/ocr-numbers/gradlew +++ b/exercises/practice/ocr-numbers/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/ocr-numbers/gradlew.bat b/exercises/practice/ocr-numbers/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/ocr-numbers/gradlew.bat +++ b/exercises/practice/ocr-numbers/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/ocr-numbers/src/test/java/OpticalCharacterReaderTest.java b/exercises/practice/ocr-numbers/src/test/java/OpticalCharacterReaderTest.java index fbe4c040c..6cc079c23 100644 --- a/exercises/practice/ocr-numbers/src/test/java/OpticalCharacterReaderTest.java +++ b/exercises/practice/ocr-numbers/src/test/java/OpticalCharacterReaderTest.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.Arrays; @@ -9,6 +10,7 @@ public class OpticalCharacterReaderTest { @Test + @DisplayName("Recognizes 0") public void testReaderRecognizesSingle0() { String parsedInput = new OpticalCharacterReader().parse(Arrays.asList( " _ ", @@ -23,6 +25,7 @@ public void testReaderRecognizesSingle0() { @Disabled("Remove to run test") @Test + @DisplayName("Recognizes 1") public void testReaderRecognizesSingle1() { String parsedInput = new OpticalCharacterReader().parse(Arrays.asList( " ", @@ -36,6 +39,7 @@ public void testReaderRecognizesSingle1() { @Disabled("Remove to run test") @Test + @DisplayName("Unreadable but correctly sized inputs return ?") public void testReaderReturnsQuestionMarkForUnreadableButCorrectlySizedInput() { String parsedInput = new OpticalCharacterReader().parse(Arrays.asList( " ", @@ -49,6 +53,7 @@ public void testReaderReturnsQuestionMarkForUnreadableButCorrectlySizedInput() { @Disabled("Remove to run test") @Test + @DisplayName("Input with a number of lines that is not a multiple of four raises an error") public void testReaderThrowsExceptionWhenNumberOfInputLinesIsNotAMultipleOf4() { assertThatExceptionOfType(IllegalArgumentException.class) @@ -63,6 +68,7 @@ public void testReaderThrowsExceptionWhenNumberOfInputLinesIsNotAMultipleOf4() { @Disabled("Remove to run test") @Test + @DisplayName("Input with a number of columns that is not a multiple of three raises an error") public void testReaderThrowsExceptionWhenNumberOfInputColumnsIsNotAMultipleOf3() { @@ -79,6 +85,7 @@ public void testReaderThrowsExceptionWhenNumberOfInputColumnsIsNotAMultipleOf3() @Disabled("Remove to run test") @Test + @DisplayName("Recognizes 110101100") public void testReaderRecognizesBinarySequence110101100() { String parsedInput = new OpticalCharacterReader().parse(Arrays.asList( " _ _ _ _ ", @@ -92,6 +99,7 @@ public void testReaderRecognizesBinarySequence110101100() { @Disabled("Remove to run test") @Test + @DisplayName("Garbled numbers in a string are replaced with ?") public void testReaderReplacesUnreadableDigitsWithQuestionMarksWithinSequence() { String parsedInput = new OpticalCharacterReader().parse(Arrays.asList( " _ _ _ ", @@ -106,6 +114,7 @@ public void testReaderReplacesUnreadableDigitsWithQuestionMarksWithinSequence() @Disabled("Remove to run test") @Test + @DisplayName("Recognizes 2") public void testReaderRecognizesSingle2() { String parsedInput = new OpticalCharacterReader().parse(Arrays.asList( " _ ", @@ -119,6 +128,7 @@ public void testReaderRecognizesSingle2() { @Disabled("Remove to run test") @Test + @DisplayName("Recognizes 3") public void testReaderRecognizesSingle3() { String parsedInput = new OpticalCharacterReader().parse(Arrays.asList( " _ ", @@ -132,6 +142,7 @@ public void testReaderRecognizesSingle3() { @Disabled("Remove to run test") @Test + @DisplayName("Recognizes 4") public void testReaderRecognizesSingle4() { String parsedInput = new OpticalCharacterReader().parse(Arrays.asList( " ", @@ -145,6 +156,7 @@ public void testReaderRecognizesSingle4() { @Disabled("Remove to run test") @Test + @DisplayName("Recognizes 5") public void testReaderRecognizesSingle5() { String parsedInput = new OpticalCharacterReader().parse(Arrays.asList( " _ ", @@ -158,6 +170,7 @@ public void testReaderRecognizesSingle5() { @Disabled("Remove to run test") @Test + @DisplayName("Recognizes 6") public void testReaderRecognizesSingle6() { String parsedInput = new OpticalCharacterReader().parse(Arrays.asList( " _ ", @@ -171,6 +184,7 @@ public void testReaderRecognizesSingle6() { @Disabled("Remove to run test") @Test + @DisplayName("Recognizes 7") public void testReaderRecognizesSingle7() { String parsedInput = new OpticalCharacterReader().parse(Arrays.asList( " _ ", @@ -184,6 +198,7 @@ public void testReaderRecognizesSingle7() { @Disabled("Remove to run test") @Test + @DisplayName("Recognizes 8") public void testReaderRecognizesSingle8() { String parsedInput = new OpticalCharacterReader().parse(Arrays.asList( " _ ", @@ -197,6 +212,7 @@ public void testReaderRecognizesSingle8() { @Disabled("Remove to run test") @Test + @DisplayName("Recognizes 9") public void testReaderRecognizesSingle9() { String parsedInput = new OpticalCharacterReader().parse(Arrays.asList( " _ ", @@ -210,6 +226,7 @@ public void testReaderRecognizesSingle9() { @Disabled("Remove to run test") @Test + @DisplayName("Recognizes string of decimal numbers") public void testReaderRecognizesSequence1234567890() { String parsedInput = new OpticalCharacterReader().parse(Arrays.asList( " _ _ _ _ _ _ _ _ ", @@ -223,6 +240,7 @@ public void testReaderRecognizesSequence1234567890() { @Disabled("Remove to run test") @Test + @DisplayName("Numbers separated by empty lines are recognized. Lines are joined by commas.") public void testReaderRecognizesAndCorrectlyFormatsMultiRowInput() { String parsedInput = new OpticalCharacterReader().parse(Arrays.asList( " _ _ ", diff --git a/exercises/practice/palindrome-products/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/palindrome-products/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/palindrome-products/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/palindrome-products/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/palindrome-products/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/palindrome-products/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/palindrome-products/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/palindrome-products/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/palindrome-products/gradlew b/exercises/practice/palindrome-products/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/palindrome-products/gradlew +++ b/exercises/practice/palindrome-products/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/palindrome-products/gradlew.bat b/exercises/practice/palindrome-products/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/palindrome-products/gradlew.bat +++ b/exercises/practice/palindrome-products/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/palindrome-products/src/test/java/PalindromeCalculatorTest.java b/exercises/practice/palindrome-products/src/test/java/PalindromeCalculatorTest.java index b82b55109..211b4a9b8 100644 --- a/exercises/practice/palindrome-products/src/test/java/PalindromeCalculatorTest.java +++ b/exercises/practice/palindrome-products/src/test/java/PalindromeCalculatorTest.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.Arrays; @@ -15,6 +16,7 @@ public class PalindromeCalculatorTest { private PalindromeCalculator palindromeCalculator = new PalindromeCalculator(); @Test + @DisplayName("find the smallest palindrome from single digit factors") public void smallestPalindromeFromSingleDigitFactors() { List> expected = Collections.unmodifiableList( Arrays.asList( @@ -30,6 +32,7 @@ public void smallestPalindromeFromSingleDigitFactors() { @Disabled("Remove to run test") @Test + @DisplayName("find the largest palindrome from single digit factors") public void largestPalindromeFromSingleDigitFactors() { List> expected = Collections.unmodifiableList( Arrays.asList( @@ -46,6 +49,7 @@ public void largestPalindromeFromSingleDigitFactors() { @Disabled("Remove to run test") @Test + @DisplayName("find the smallest palindrome from double digit factors") public void largestPalindromeFromDoubleDigitFactors() { List> expected = Collections.unmodifiableList( Arrays.asList( @@ -62,6 +66,7 @@ public void largestPalindromeFromDoubleDigitFactors() { @Disabled("Remove to run test") @Test + @DisplayName("find the largest palindrome from double digit factors") public void smallestPalindromeFromDoubleDigitFactors() { List> expected = Collections.unmodifiableList( Arrays.asList( @@ -78,6 +83,7 @@ public void smallestPalindromeFromDoubleDigitFactors() { @Disabled("Remove to run test") @Test + @DisplayName("find the largest palindrome from triple digit factors") public void largestPalindromeFromTripleDigitFactors() { List> expected = Collections.unmodifiableList( Arrays.asList( @@ -94,6 +100,7 @@ public void largestPalindromeFromTripleDigitFactors() { @Disabled("Remove to run test") @Test + @DisplayName("find the smallest palindrome from triple digit factors") public void smallestPalindromeFromTripleDigitFactors() { List> expected = Collections.unmodifiableList( Arrays.asList( @@ -110,6 +117,7 @@ public void smallestPalindromeFromTripleDigitFactors() { @Disabled("Remove to run test") @Test + @DisplayName("find the smallest palindrome from four digit factors") public void smallestPalindromeFromQuadDigitFactors() { List> expected = Collections.unmodifiableList( Arrays.asList( @@ -126,6 +134,7 @@ public void smallestPalindromeFromQuadDigitFactors() { @Disabled("Remove to run test") @Test + @DisplayName("find the largest palindrome from four digit factors") public void largestPalindromeFromQuadDigitFactors() { List> expected = Collections.unmodifiableList( Arrays.asList( @@ -142,6 +151,7 @@ public void largestPalindromeFromQuadDigitFactors() { @Disabled("Remove to run test") @Test + @DisplayName("empty result for smallest if no palindrome in the range") public void emtpyResultSmallestNoPalindromeInRange() { SortedMap>> palindromes = palindromeCalculator.getPalindromeProductsWithFactors(1002, @@ -151,6 +161,7 @@ public void emtpyResultSmallestNoPalindromeInRange() { @Disabled("Remove to run test") @Test + @DisplayName("empty result for largest if no palindrome in the range") public void emptyResultLargestNoPalindromeInRange() { SortedMap>> palindromes = palindromeCalculator.getPalindromeProductsWithFactors(15, @@ -160,6 +171,7 @@ public void emptyResultLargestNoPalindromeInRange() { @Disabled("Remove to run test") @Test + @DisplayName("error result for smallest if min is more than max") public void errorSmallestMinIsMoreThanMax() { assertThatExceptionOfType(IllegalArgumentException.class) @@ -169,6 +181,7 @@ public void errorSmallestMinIsMoreThanMax() { @Disabled("Remove to run test") @Test + @DisplayName("error result for largest if min is more than max") public void errorLargestMinIsMoreThanMax() { assertThatExceptionOfType(IllegalArgumentException.class) @@ -178,6 +191,7 @@ public void errorLargestMinIsMoreThanMax() { @Disabled("Remove to run test") @Test + @DisplayName("smallest product does not use the smallest factor") public void smallestProductDoesNotUseTheSmallestFactor() { List> expected = Collections.unmodifiableList( Arrays.asList( diff --git a/exercises/practice/pangram/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/pangram/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/pangram/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/pangram/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/pangram/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/pangram/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/pangram/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/pangram/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/pangram/gradlew b/exercises/practice/pangram/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/pangram/gradlew +++ b/exercises/practice/pangram/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/pangram/gradlew.bat b/exercises/practice/pangram/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/pangram/gradlew.bat +++ b/exercises/practice/pangram/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/pangram/src/test/java/PangramCheckerTest.java b/exercises/practice/pangram/src/test/java/PangramCheckerTest.java index 63a83513f..981e40172 100644 --- a/exercises/practice/pangram/src/test/java/PangramCheckerTest.java +++ b/exercises/practice/pangram/src/test/java/PangramCheckerTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -14,60 +15,70 @@ public void setup() { } @Test + @DisplayName("empty sentence") public void emptySentenceIsNotPangram() { assertThat(pangramChecker.isPangram("")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("perfect lower case") public void perfectLowerCasePhraseIsPangram() { assertThat(pangramChecker.isPangram("abcdefghijklmnopqrstuvwxyz")).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("only lower case") public void phraseWithOnlyLowerCaseIsPangram() { assertThat(pangramChecker.isPangram("the quick brown fox jumps over the lazy dog")).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("missing the letter 'x'") public void phraseMissingCharacterXIsNotPangram() { assertThat(pangramChecker.isPangram("a quick movement of the enemy will jeopardize five gunboats")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("missing the letter 'h'") public void phraseMissingCharacterHIsNotPangram() { assertThat(pangramChecker.isPangram("five boxing wizards jump quickly at it")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("with underscores") public void phraseWithUnderscoresIsPangram() { assertThat(pangramChecker.isPangram("the_quick_brown_fox_jumps_over_the_lazy_dog")).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("with numbers") public void phraseWithNumbersIsPangram() { assertThat(pangramChecker.isPangram("the 1 quick brown fox jumps over the 2 lazy dogs")).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("missing letters replaced by numbers") public void phraseWithMissingLettersReplacedByNumbersIsNotPangram() { assertThat(pangramChecker.isPangram("7h3 qu1ck brown fox jumps ov3r 7h3 lazy dog")).isFalse(); } @Disabled("Remove to run test") @Test + @DisplayName("mixed case and punctuation") public void phraseWithMixedCaseAndPunctuationIsPangram() { assertThat(pangramChecker.isPangram("\"Five quacking Zephyrs jolt my wax bed.\"")).isTrue(); } @Disabled("Remove to run test") @Test + @DisplayName("case insensitive") public void caseInsensitivePhraseIsNotPangram() { assertThat(pangramChecker.isPangram("abcdefghijklm ABCDEFGHIJKLM")).isFalse(); } diff --git a/exercises/practice/parallel-letter-frequency/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/parallel-letter-frequency/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/parallel-letter-frequency/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/parallel-letter-frequency/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/parallel-letter-frequency/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/parallel-letter-frequency/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/parallel-letter-frequency/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/parallel-letter-frequency/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/parallel-letter-frequency/gradlew b/exercises/practice/parallel-letter-frequency/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/parallel-letter-frequency/gradlew +++ b/exercises/practice/parallel-letter-frequency/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/parallel-letter-frequency/gradlew.bat b/exercises/practice/parallel-letter-frequency/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/parallel-letter-frequency/gradlew.bat +++ b/exercises/practice/parallel-letter-frequency/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/parallel-letter-frequency/src/test/java/ParallelLetterFrequencyTest.java b/exercises/practice/parallel-letter-frequency/src/test/java/ParallelLetterFrequencyTest.java index 1f3e83ba3..cce168b52 100644 --- a/exercises/practice/parallel-letter-frequency/src/test/java/ParallelLetterFrequencyTest.java +++ b/exercises/practice/parallel-letter-frequency/src/test/java/ParallelLetterFrequencyTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.Arrays; @@ -205,6 +206,7 @@ public class ParallelLetterFrequencyTest { "- from the days of the Flood to the Schleswig-Holstein period."; @Test + @DisplayName("no texts") public void testNoTexts() { String[] input = {}; Map expectedOutput = new HashMap<>(); @@ -215,6 +217,7 @@ public void testNoTexts() { @Disabled("Remove to run test") @Test + @DisplayName("one text with one letter") public void testOneTextWithOneLetter() { String[] input = { "a" }; Map expectedOutput = new HashMap<>() { @@ -229,6 +232,7 @@ public void testOneTextWithOneLetter() { @Disabled("Remove to run test") @Test + @DisplayName("one text with multiple letters") public void testOneTextWithMultipleLetters() { String[] input = { "bbcccd" }; Map expectedOutput = new HashMap<>() { @@ -245,6 +249,7 @@ public void testOneTextWithMultipleLetters() { @Disabled("Remove to run test") @Test + @DisplayName("two texts with one letter") public void testTwoTextsWithOneLetter() { String[] input = { "e", "f" }; Map expectedOutput = new HashMap<>() { @@ -260,6 +265,7 @@ public void testTwoTextsWithOneLetter() { @Disabled("Remove to run test") @Test + @DisplayName("two texts with multiple letters") public void testTwoTextsWithMultipleLetters() { String[] input = { "ggh", "hhi" }; Map expectedOutput = new HashMap<>() { @@ -276,6 +282,7 @@ public void testTwoTextsWithMultipleLetters() { @Disabled("Remove to run test") @Test + @DisplayName("ignore letter casing") public void testIgnoreLetterCasing() { String[] input = { "m", "M" }; Map expectedOutput = new HashMap<>() { @@ -290,6 +297,7 @@ public void testIgnoreLetterCasing() { @Disabled("Remove to run test") @Test + @DisplayName("ignore whitespace") public void testIgnoreWhitespace() { String[] input = { " ", "\t", "\r\n" }; Map expectedOutput = new HashMap<>(); @@ -300,6 +308,7 @@ public void testIgnoreWhitespace() { @Disabled("Remove to run test") @Test + @DisplayName("ignore punctuation") public void testIgnorePunctuation() { String[] input = { "!", "?", ";", ",", "." }; Map expectedOutput = new HashMap<>(); @@ -310,6 +319,7 @@ public void testIgnorePunctuation() { @Disabled("Remove to run test") @Test + @DisplayName("ignore numbers") public void testIgnoreNumbers() { String[] input = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; Map expectedOutput = new HashMap<>(); @@ -320,6 +330,7 @@ public void testIgnoreNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("Unicode letters") public void testUnicodeLetters() { String[] input = { "本", "φ", "ほ", "ø" }; Map expectedOutput = new HashMap<>() { @@ -337,6 +348,7 @@ public void testUnicodeLetters() { @Disabled("Remove to run test") @Test + @DisplayName("combination of lower- and uppercase letters, punctuation and white space") public void testCombinationOfLowerAndUppercaseLettersPunctuationAndWhiteSpace() { String[] input = {calculateFrequencies}; Map expectedOutput = new HashMap<>() { @@ -369,26 +381,10 @@ public void testCombinationOfLowerAndUppercaseLettersPunctuationAndWhiteSpace() assertThat(p.countLetters()).isEqualTo(expectedOutput); } - - @Disabled("Remove to run test") - @Test - public void testManySmallTexts() { - String[] input = new String[50]; - Arrays.fill(input, "abbccc"); - Map expectedOutput = new HashMap<>() { - { - put('a', 50); - put('b', 100); - put('c', 150); - } - }; - ParallelLetterFrequency p = new ParallelLetterFrequency(input); - - assertThat(p.countLetters()).isEqualTo(expectedOutput); - } @Disabled("Remove to run test") @Test + @DisplayName("large texts") public void testLargeTexts() { String[] input = { largeTexts1, largeTexts2, largeTexts3, largeTexts4 }; Map expectedOutput = new HashMap<>() { @@ -423,6 +419,24 @@ public void testLargeTexts() { ParallelLetterFrequency p = new ParallelLetterFrequency(input); assertThat(p.countLetters()).isEqualTo(expectedOutput); - } + } + + @Disabled("Remove to run test") + @Test + @DisplayName("many small texts") + public void testManySmallTexts() { + String[] input = new String[50]; + Arrays.fill(input, "abbccc"); + Map expectedOutput = new HashMap<>() { + { + put('a', 50); + put('b', 100); + put('c', 150); + } + }; + ParallelLetterFrequency p = new ParallelLetterFrequency(input); + + assertThat(p.countLetters()).isEqualTo(expectedOutput); + } } diff --git a/exercises/practice/pascals-triangle/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/pascals-triangle/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/pascals-triangle/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/pascals-triangle/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/pascals-triangle/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/pascals-triangle/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/pascals-triangle/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/pascals-triangle/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/pascals-triangle/gradlew b/exercises/practice/pascals-triangle/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/pascals-triangle/gradlew +++ b/exercises/practice/pascals-triangle/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/pascals-triangle/gradlew.bat b/exercises/practice/pascals-triangle/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/pascals-triangle/gradlew.bat +++ b/exercises/practice/pascals-triangle/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/pascals-triangle/src/test/java/PascalsTriangleGeneratorTest.java b/exercises/practice/pascals-triangle/src/test/java/PascalsTriangleGeneratorTest.java index c72c2dc07..becdb0825 100644 --- a/exercises/practice/pascals-triangle/src/test/java/PascalsTriangleGeneratorTest.java +++ b/exercises/practice/pascals-triangle/src/test/java/PascalsTriangleGeneratorTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -9,6 +10,7 @@ public class PascalsTriangleGeneratorTest { new PascalsTriangleGenerator(); @Test + @DisplayName("zero rows") public void testTriangleWithZeroRows() { int[][] expectedOutput = new int[][]{}; @@ -17,6 +19,7 @@ public void testTriangleWithZeroRows() { @Disabled("Remove to run test") @Test + @DisplayName("single row") public void testTriangleWithOneRow() { int[][] expectedOutput = new int[][]{ {1} @@ -27,6 +30,7 @@ public void testTriangleWithOneRow() { @Disabled("Remove to run test") @Test + @DisplayName("two rows") public void testTriangleWithTwoRows() { int[][] expectedOutput = new int[][]{ {1}, @@ -38,6 +42,7 @@ public void testTriangleWithTwoRows() { @Disabled("Remove to run test") @Test + @DisplayName("three rows") public void testTriangleWithThreeRows() { int[][] expectedOutput = new int[][]{ {1}, @@ -50,6 +55,7 @@ public void testTriangleWithThreeRows() { @Disabled("Remove to run test") @Test + @DisplayName("four rows") public void testTriangleWithFourRows() { int[][] expectedOutput = new int[][]{ {1}, @@ -63,6 +69,7 @@ public void testTriangleWithFourRows() { @Disabled("Remove to run test") @Test + @DisplayName("five rows") public void testTriangleWithFiveRows() { int[][] expectedOutput = new int[][]{ {1}, @@ -77,6 +84,7 @@ public void testTriangleWithFiveRows() { @Disabled("Remove to run test") @Test + @DisplayName("six rows") public void testTriangleWithSixRows() { int[][] expectedOutput = new int[][]{ {1}, @@ -92,6 +100,7 @@ public void testTriangleWithSixRows() { @Disabled("Remove to run test") @Test + @DisplayName("ten rows") public void testTriangleWithTenRows() { int[][] expectedOutput = new int[][]{ {1}, diff --git a/exercises/practice/perfect-numbers/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/perfect-numbers/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/perfect-numbers/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/perfect-numbers/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/perfect-numbers/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/perfect-numbers/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/perfect-numbers/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/perfect-numbers/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/perfect-numbers/gradlew b/exercises/practice/perfect-numbers/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/perfect-numbers/gradlew +++ b/exercises/practice/perfect-numbers/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/perfect-numbers/gradlew.bat b/exercises/practice/perfect-numbers/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/perfect-numbers/gradlew.bat +++ b/exercises/practice/perfect-numbers/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/perfect-numbers/src/test/java/NaturalNumberTest.java b/exercises/practice/perfect-numbers/src/test/java/NaturalNumberTest.java index b7387c4b1..58af24598 100644 --- a/exercises/practice/perfect-numbers/src/test/java/NaturalNumberTest.java +++ b/exercises/practice/perfect-numbers/src/test/java/NaturalNumberTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -7,66 +8,77 @@ public class NaturalNumberTest { @Test + @DisplayName("Smallest perfect number is classified correctly") public void testSmallPerfectNumberIsClassifiedCorrectly() { assertThat(new NaturalNumber(6).getClassification()).isEqualTo(Classification.PERFECT); } @Disabled("Remove to run test") @Test + @DisplayName("Medium perfect number is classified correctly") public void testMediumPerfectNumberIsClassifiedCorrectly() { assertThat(new NaturalNumber(28).getClassification()).isEqualTo(Classification.PERFECT); } @Disabled("Remove to run test") @Test + @DisplayName("Large perfect number is classified correctly") public void testLargePerfectNumberIsClassifiedCorrectly() { assertThat(new NaturalNumber(33550336).getClassification()).isEqualTo(Classification.PERFECT); } @Disabled("Remove to run test") @Test + @DisplayName("Smallest abundant number is classified correctly") public void testSmallAbundantNumberIsClassifiedCorrectly() { assertThat(new NaturalNumber(12).getClassification()).isEqualTo(Classification.ABUNDANT); } @Disabled("Remove to run test") @Test + @DisplayName("Medium abundant number is classified correctly") public void testMediumAbundantNumberIsClassifiedCorrectly() { assertThat(new NaturalNumber(30).getClassification()).isEqualTo(Classification.ABUNDANT); } @Disabled("Remove to run test") @Test + @DisplayName("Large abundant number is classified correctly") public void testLargeAbundantNumberIsClassifiedCorrectly() { assertThat(new NaturalNumber(33550335).getClassification()).isEqualTo(Classification.ABUNDANT); } @Disabled("Remove to run test") @Test + @DisplayName("Smallest prime deficient number is classified correctly") public void testSmallestPrimeDeficientNumberIsClassifiedCorrectly() { assertThat(new NaturalNumber(2).getClassification()).isEqualTo(Classification.DEFICIENT); } @Disabled("Remove to run test") @Test + @DisplayName("Smallest non-prime deficient number is classified correctly") public void testSmallestNonPrimeDeficientNumberIsClassifiedCorrectly() { assertThat(new NaturalNumber(4).getClassification()).isEqualTo(Classification.DEFICIENT); } @Disabled("Remove to run test") @Test + @DisplayName("Medium deficient number is classified as DEFICIENT") public void testMediumDeficientNumberIsClassifiedCorrectly() { assertThat(new NaturalNumber(32).getClassification()).isEqualTo(Classification.DEFICIENT); } @Disabled("Remove to run test") @Test + @DisplayName("Large deficient number is classified as DEFICIENT") public void testLargeDeficientNumberIsClassifiedCorrectly() { assertThat(new NaturalNumber(33550337).getClassification()).isEqualTo(Classification.DEFICIENT); } @Disabled("Remove to run test") @Test + @DisplayName("Edge case (no factors other than itself) is classified correctly") /* * The number 1 has no proper divisors (https://en.wikipedia.org/wiki/Divisor#Further_notions_and_facts), and the * additive identity is 0, so the aliquot sum of 1 should be 0. Hence 1 should be classified as deficient. @@ -77,6 +89,7 @@ public void testThatOneIsCorrectlyClassifiedAsDeficient() { @Disabled("Remove to run test") @Test + @DisplayName("Zero is rejected (as it is not a positive integer)") public void testThatNonNegativeIntegerIsRejected() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> new NaturalNumber(0)) @@ -85,6 +98,7 @@ public void testThatNonNegativeIntegerIsRejected() { @Disabled("Remove to run test") @Test + @DisplayName("Negative integer is rejected (as it is not a positive integer)") public void testThatNegativeIntegerIsRejected() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> new NaturalNumber(-1)) diff --git a/exercises/practice/phone-number/.docs/instructions.md b/exercises/practice/phone-number/.docs/instructions.md index 62ba48e96..5d4d3739f 100644 --- a/exercises/practice/phone-number/.docs/instructions.md +++ b/exercises/practice/phone-number/.docs/instructions.md @@ -1,6 +1,6 @@ # Instructions -Clean up user-entered phone numbers so that they can be sent SMS messages. +Clean up phone numbers so that they can be sent SMS messages. The **North American Numbering Plan (NANP)** is a telephone numbering system used by many countries in North America like the United States, Canada or Bermuda. All NANP-countries share the same international country code: `1`. diff --git a/exercises/practice/phone-number/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/phone-number/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/phone-number/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/phone-number/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/phone-number/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/phone-number/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/phone-number/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/phone-number/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/phone-number/gradlew b/exercises/practice/phone-number/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/phone-number/gradlew +++ b/exercises/practice/phone-number/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/phone-number/gradlew.bat b/exercises/practice/phone-number/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/phone-number/gradlew.bat +++ b/exercises/practice/phone-number/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/phone-number/src/test/java/PhoneNumberTest.java b/exercises/practice/phone-number/src/test/java/PhoneNumberTest.java index bfd7c6212..300415b65 100644 --- a/exercises/practice/phone-number/src/test/java/PhoneNumberTest.java +++ b/exercises/practice/phone-number/src/test/java/PhoneNumberTest.java @@ -1,12 +1,14 @@ -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; - import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + public class PhoneNumberTest { @Test + @DisplayName("cleans the number") public void cleansTheNumber() { String expectedNumber = "2234567890"; String actualNumber = new PhoneNumber("(223) 456-7890").getNumber(); @@ -16,6 +18,7 @@ public void cleansTheNumber() { @Disabled("Remove to run test") @Test + @DisplayName("cleans numbers with dots") public void cleansNumbersWithDots() { String expectedNumber = "2234567890"; String actualNumber = new PhoneNumber("223.456.7890").getNumber(); @@ -26,6 +29,7 @@ public void cleansNumbersWithDots() { @Disabled("Remove to run test") @Test + @DisplayName("cleans numbers with multiple spaces") public void cleansNumbersWithMultipleSpaces() { String expectedNumber = "2234567890"; String actualNumber = new PhoneNumber("223 456 7890 ").getNumber(); @@ -35,6 +39,7 @@ public void cleansNumbersWithMultipleSpaces() { @Disabled("Remove to run test") @Test + @DisplayName("invalid when 9 digits") public void invalidWhen9Digits() { assertThatExceptionOfType(IllegalArgumentException.class) @@ -44,6 +49,7 @@ public void invalidWhen9Digits() { @Disabled("Remove to run test") @Test + @DisplayName("invalid when 11 digits does not start with a 1") public void invalidWhen11DigitsDoesNotStartWith1() { assertThatExceptionOfType(IllegalArgumentException.class) @@ -53,6 +59,7 @@ public void invalidWhen11DigitsDoesNotStartWith1() { @Disabled("Remove to run test") @Test + @DisplayName("valid when 11 digits and starting with 1") public void validWhen11DigitsAndStartingWith1() { String expectedNumber = "2234567890"; String actualNumber = new PhoneNumber("12234567890").getNumber(); @@ -62,6 +69,7 @@ public void validWhen11DigitsAndStartingWith1() { @Disabled("Remove to run test") @Test + @DisplayName("valid when 11 digits and starting with 1 even with punctuation") public void validWhen11DigitsAndStartingWith1EvenWithPunctuation() { String expectedNumber = "2234567890"; String actualNumber = new PhoneNumber("+1 (223) 456-7890").getNumber(); @@ -71,6 +79,7 @@ public void validWhen11DigitsAndStartingWith1EvenWithPunctuation() { @Disabled("Remove to run test") @Test + @DisplayName("invalid when more than 11 digits") public void invalidWhenMoreThan11Digits() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> new PhoneNumber("321234567890")) @@ -79,6 +88,7 @@ public void invalidWhenMoreThan11Digits() { @Disabled("Remove to run test") @Test + @DisplayName("invalid with letters") public void invalidWithLetters() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> new PhoneNumber("523-abc-7890")) @@ -87,6 +97,7 @@ public void invalidWithLetters() { @Disabled("Remove to run test") @Test + @DisplayName("invalid with punctuations") public void invalidWithPunctuations() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> new PhoneNumber("523-@:!-7890")) @@ -95,6 +106,7 @@ public void invalidWithPunctuations() { @Disabled("Remove to run test") @Test + @DisplayName("invalid if area code starts with 0") public void invalidIfAreaCodeStartsWith0() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> new PhoneNumber("(023) 456-7890")) @@ -103,6 +115,7 @@ public void invalidIfAreaCodeStartsWith0() { @Disabled("Remove to run test") @Test + @DisplayName("invalid if area code starts with 1") public void invalidIfAreaCodeStartsWith1() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> new PhoneNumber("(123) 456-7890")) @@ -111,6 +124,7 @@ public void invalidIfAreaCodeStartsWith1() { @Disabled("Remove to run test") @Test + @DisplayName("invalid if exchange code starts with 0") public void invalidIfExchangeCodeStartsWith0() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> new PhoneNumber("(223) 056-7890")) @@ -119,6 +133,7 @@ public void invalidIfExchangeCodeStartsWith0() { @Disabled("Remove to run test") @Test + @DisplayName("invalid if exchange code starts with 1") public void invalidIfExchangeCodeStartsWith1() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> new PhoneNumber("(223) 156-7890")) @@ -127,6 +142,7 @@ public void invalidIfExchangeCodeStartsWith1() { @Disabled("Remove to run test") @Test + @DisplayName("invalid if area code starts with 0 on valid 11-digit number") public void invalidIfAreaCodeStartsWith0OnValid11DigitNumber() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> new PhoneNumber("1 (023) 456-7890")) @@ -135,6 +151,7 @@ public void invalidIfAreaCodeStartsWith0OnValid11DigitNumber() { @Disabled("Remove to run test") @Test + @DisplayName("invalid if area code starts with 1 on valid 11-digit number") public void invalidIfAreaCodeStartsWith1OnValid11DigitNumber() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> new PhoneNumber("1 (123) 456-7890")) @@ -143,6 +160,7 @@ public void invalidIfAreaCodeStartsWith1OnValid11DigitNumber() { @Disabled("Remove to run test") @Test + @DisplayName("invalid if exchange code starts with 0 on valid 11-digit number") public void invalidIfExchangeCodeStartsWith0OnValid11DigitNumber() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> new PhoneNumber("1 (223) 056-7890")) @@ -151,6 +169,7 @@ public void invalidIfExchangeCodeStartsWith0OnValid11DigitNumber() { @Disabled("Remove to run test") @Test + @DisplayName("invalid if exchange code starts with 1 on valid 11-digit number") public void invalidIfExchangeCodeStartsWith1OnValid11DigitNumber() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> new PhoneNumber("1 (223) 156-7890")) diff --git a/exercises/practice/piecing-it-together/.docs/instructions.md b/exercises/practice/piecing-it-together/.docs/instructions.md new file mode 100644 index 000000000..c0c966592 --- /dev/null +++ b/exercises/practice/piecing-it-together/.docs/instructions.md @@ -0,0 +1,41 @@ +# Instructions + +Given partial information about a jigsaw puzzle, add the missing pieces. + +If the information is insufficient to complete the details, or if given parts are in contradiction, the user should be notified. + +The full information about the jigsaw puzzle contains the following parts: + +- `pieces`: Total number of pieces +- `border`: Number of border pieces +- `inside`: Number of inside (non-border) pieces +- `rows`: Number of rows +- `columns`: Number of columns +- `aspectRatio`: Aspect ratio of columns to rows +- `format`: Puzzle format, which can be `portrait`, `square`, or `landscape` + +For this exercise, you may assume square pieces, so that the format can be derived from the aspect ratio: + +- If the aspect ratio is less than 1, it's `portrait` +- If it is equal to 1, it's `square` +- If it is greater than 1, it's `landscape` + +## Three examples + +### Portrait + +A portrait jigsaw puzzle with 6 pieces, all of which are border pieces and none are inside pieces. It has 3 rows and 2 columns. The aspect ratio is 1.5 (3/2). + +![A 2 by 3 jigsaw puzzle](https://assets.exercism.org/images/exercises/piecing-it-together/jigsaw-puzzle-2x3.svg) + +### Square + +A square jigsaw puzzle with 9 pieces, all of which are border pieces except for the one in the center, which is an inside piece. It has 3 rows and 3 columns. The aspect ratio is 1 (3/3). + +![A 3 by 3 jigsaw puzzle](https://assets.exercism.org/images/exercises/piecing-it-together/jigsaw-puzzle-3x3.svg) + +### Landscape + +A landscape jigsaw puzzle with 12 pieces, 10 of which are border pieces and 2 are inside pieces. It has 3 rows and 4 columns. The aspect ratio is 1.333333... (4/3). + +![A 4 by 3 jigsaw puzzle](https://assets.exercism.org/images/exercises/piecing-it-together/jigsaw-puzzle-4x3.svg) diff --git a/exercises/practice/piecing-it-together/.docs/introduction.md b/exercises/practice/piecing-it-together/.docs/introduction.md new file mode 100644 index 000000000..2fa20f6c5 --- /dev/null +++ b/exercises/practice/piecing-it-together/.docs/introduction.md @@ -0,0 +1,6 @@ +# Introduction + +Your best friend has started collecting jigsaw puzzles and wants to build a detailed catalog of their collection — recording information such as the total number of pieces, the number of rows and columns, the number of border and inside pieces, aspect ratio, and puzzle format. +Even with your powers combined, it takes multiple hours to solve a single jigsaw puzzle with one thousand pieces — and then you still need to count the rows and columns and calculate the remaining numbers manually. +The even larger puzzles with thousands of pieces look quite daunting now. +"There has to be a better way!" you exclaim and sit down in front of your computer to solve the problem. diff --git a/exercises/practice/piecing-it-together/.meta/config.json b/exercises/practice/piecing-it-together/.meta/config.json new file mode 100644 index 000000000..b58751cb9 --- /dev/null +++ b/exercises/practice/piecing-it-together/.meta/config.json @@ -0,0 +1,25 @@ +{ + "authors": [ + "zamora-carlos" + ], + "files": { + "solution": [ + "src/main/java/PiecingItTogether.java" + ], + "test": [ + "src/test/java/PiecingItTogetherTest.java" + ], + "example": [ + ".meta/src/reference/java/PiecingItTogether.java" + ], + "editor": [ + "src/main/java/JigsawInfo.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Fill in missing jigsaw puzzle details from partial data", + "source": "atk just started another 1000-pieces jigsaw puzzle when this idea hit him", + "source_url": "https://github.com/exercism/problem-specifications/pull/2554" +} diff --git a/exercises/practice/piecing-it-together/.meta/src/reference/java/JigsawInfo.java b/exercises/practice/piecing-it-together/.meta/src/reference/java/JigsawInfo.java new file mode 100644 index 000000000..e08eb8909 --- /dev/null +++ b/exercises/practice/piecing-it-together/.meta/src/reference/java/JigsawInfo.java @@ -0,0 +1,140 @@ +import java.util.Objects; +import java.util.Optional; +import java.util.OptionalDouble; +import java.util.OptionalInt; + +/** + * Represents partial or complete information about a jigsaw puzzle, + * + * NOTE: There is no need to change this file and is treated as read only by the Exercism test runners. + */ +public class JigsawInfo { + private final OptionalInt pieces; + private final OptionalInt border; + private final OptionalInt inside; + private final OptionalInt rows; + private final OptionalInt columns; + private final OptionalDouble aspectRatio; + private final Optional format; + + private JigsawInfo(Builder builder) { + this.pieces = builder.pieces; + this.border = builder.border; + this.inside = builder.inside; + this.rows = builder.rows; + this.columns = builder.columns; + this.aspectRatio = builder.aspectRatio; + this.format = builder.format; + } + + public static class Builder { + private OptionalInt pieces = OptionalInt.empty(); + private OptionalInt border = OptionalInt.empty(); + private OptionalInt inside = OptionalInt.empty(); + private OptionalInt rows = OptionalInt.empty(); + private OptionalInt columns = OptionalInt.empty(); + private OptionalDouble aspectRatio = OptionalDouble.empty(); + private Optional format = Optional.empty(); + + public Builder pieces(int pieces) { + this.pieces = OptionalInt.of(pieces); + return this; + } + + public Builder border(int border) { + this.border = OptionalInt.of(border); + return this; + } + + public Builder inside(int inside) { + this.inside = OptionalInt.of(inside); + return this; + } + + public Builder rows(int rows) { + this.rows = OptionalInt.of(rows); + return this; + } + + public Builder columns(int columns) { + this.columns = OptionalInt.of(columns); + return this; + } + + public Builder aspectRatio(double aspectRatio) { + this.aspectRatio = OptionalDouble.of(aspectRatio); + return this; + } + + public Builder format(String format) { + this.format = Optional.of(format); + return this; + } + + public JigsawInfo build() { + return new JigsawInfo(this); + } + } + + public OptionalInt getPieces() { + return pieces; + } + + public OptionalInt getBorder() { + return border; + } + + public OptionalInt getInside() { + return inside; + } + + public OptionalInt getRows() { + return rows; + } + + public OptionalInt getColumns() { + return columns; + } + + public OptionalDouble getAspectRatio() { + return aspectRatio; + } + + public Optional getFormat() { + return format; + } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + + JigsawInfo that = (JigsawInfo) o; + return Objects.equals(pieces, that.pieces) + && Objects.equals(border, that.border) + && Objects.equals(inside, that.inside) + && Objects.equals(rows, that.rows) + && Objects.equals(columns, that.columns) + && Objects.equals(aspectRatio, that.aspectRatio) + && Objects.equals(format, that.format); + } + + @Override + public int hashCode() { + return Objects.hash(pieces, border, inside, rows, columns, aspectRatio, format); + } + + @Override + public String toString() { + return "JigsawInfo{" + + "pieces=" + pieces + + ", border=" + border + + ", inside=" + inside + + ", rows=" + rows + + ", columns=" + columns + + ", aspectRatio=" + aspectRatio + + ", format=" + format + + '}'; + } +} diff --git a/exercises/practice/piecing-it-together/.meta/src/reference/java/PiecingItTogether.java b/exercises/practice/piecing-it-together/.meta/src/reference/java/PiecingItTogether.java new file mode 100644 index 000000000..ddbb91dc8 --- /dev/null +++ b/exercises/practice/piecing-it-together/.meta/src/reference/java/PiecingItTogether.java @@ -0,0 +1,135 @@ +import java.util.*; + +public class PiecingItTogether { + private static final double DOUBLE_EQUALITY_TOLERANCE = 1e-9; + private static final int MAX_DIMENSION = 1000; + + public static JigsawInfo getCompleteInformation(JigsawInfo input) { + List validGuesses = new ArrayList<>(); + + if (input.getPieces().isPresent()) { + // If pieces is known, we only test divisors of pieces + int pieces = input.getPieces().getAsInt(); + for (int rows = 1; rows <= pieces; rows++) { + if (pieces % rows != 0) { + continue; + } + int columns = pieces / rows; + createValidJigsaw(rows, columns, input).ifPresent(validGuesses::add); + } + } else if (input.getInside().isPresent() && input.getInside().getAsInt() > 0) { + // If inside pieces is non-zero, we only test divisors of inside + int inside = input.getInside().getAsInt(); + for (int innerRows = 1; innerRows <= inside; innerRows++) { + if (inside % innerRows != 0) { + continue; + } + int innerColumns = inside / innerRows; + createValidJigsaw(innerRows + 2, innerColumns + 2, input).ifPresent(validGuesses::add); + } + } else { + // Brute force using border constraint if available + int maxDimension = input.getBorder().isPresent() + ? Math.min(input.getBorder().getAsInt(), MAX_DIMENSION) + : MAX_DIMENSION; + + for (int rows = 1; rows <= maxDimension; rows++) { + for (int columns = 1; columns <= maxDimension; columns++) { + createValidJigsaw(rows, columns, input).ifPresent(validGuesses::add); + } + } + } + + if (validGuesses.size() == 1) { + return validGuesses.get(0); + } else if (validGuesses.size() > 1) { + throw new IllegalArgumentException("Insufficient data"); + } else { + throw new IllegalArgumentException("Contradictory data"); + } + } + + private static String getFormatFromAspect(double aspectRatio) { + if (Math.abs(aspectRatio - 1.0) < DOUBLE_EQUALITY_TOLERANCE) { + return "square"; + } else if (aspectRatio < 1.0) { + return "portrait"; + } else { + return "landscape"; + } + } + + private static JigsawInfo fromRowsAndCols(int rows, int columns) { + int pieces = rows * columns; + int border = (rows == 1 || columns == 1) ? pieces : 2 * (rows + columns - 2); + int inside = pieces - border; + double aspectRatio = (double) columns / rows; + String format = getFormatFromAspect(aspectRatio); + + return new JigsawInfo.Builder() + .pieces(pieces) + .border(border) + .inside(inside) + .rows(rows) + .columns(columns) + .aspectRatio(aspectRatio) + .format(format) + .build(); + } + + /** + * Verifies that all known values in the input match those in the computed result. + * Returns false if any known value conflicts, true if all values are consistent. + * + * @param computed the fully inferred jigsaw information + * @param input the original partial input with possibly empty values + * @return true if all values are consistent, false if any conflict exists + */ + private static boolean isConsistent(JigsawInfo computed, JigsawInfo input) { + return valuesMatch(computed.getPieces(), input.getPieces()) && + valuesMatch(computed.getBorder(), input.getBorder()) && + valuesMatch(computed.getInside(), input.getInside()) && + valuesMatch(computed.getRows(), input.getRows()) && + valuesMatch(computed.getColumns(), input.getColumns()) && + valuesMatch(computed.getAspectRatio(), input.getAspectRatio()) && + valuesMatch(computed.getFormat(), input.getFormat()); + } + + /** + * Attempts to construct a valid jigsaw configuration using the specified number of rows and columns. + * Returns a valid result only if the configuration is consistent with the input. + * + * @param rows number of rows to try + * @param columns number of columns to try + * @param input the original input to check for consistency + * @return an Optional containing a valid configuration, or empty if inconsistent + */ + private static Optional createValidJigsaw(int rows, int columns, JigsawInfo input) { + JigsawInfo candidate = fromRowsAndCols(rows, columns); + return isConsistent(candidate, input) ? Optional.of(candidate) : Optional.empty(); + } + + private static boolean valuesMatch(Optional a, Optional b) { + if (a.isPresent() && b.isPresent()) { + return Objects.equals(a.get(), b.get()); + } + + return true; + } + + private static boolean valuesMatch(OptionalInt a, OptionalInt b) { + if (a.isPresent() && b.isPresent()) { + return a.getAsInt() == b.getAsInt(); + } + + return true; + } + + private static boolean valuesMatch(OptionalDouble a, OptionalDouble b) { + if (a.isPresent() && b.isPresent()) { + return Double.compare(a.getAsDouble(), b.getAsDouble()) == 0; + } + + return true; + } +} diff --git a/exercises/practice/piecing-it-together/.meta/tests.toml b/exercises/practice/piecing-it-together/.meta/tests.toml new file mode 100644 index 000000000..f462c15a3 --- /dev/null +++ b/exercises/practice/piecing-it-together/.meta/tests.toml @@ -0,0 +1,31 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[ad626f23-09a2-4f5f-ba22-eec0671fa2a9] +description = "1000 pieces puzzle with 1.6 aspect ratio" + +[3e0c5919-3561-42f5-b9ed-26d70c20214e] +description = "square puzzle with 32 rows" + +[1126f160-b094-4dc2-bf37-13e36e394867] +description = "400 pieces square puzzle with only inside pieces and aspect ratio" + +[a9743178-5642-4cc0-8fdb-00d6b031c3a0] +description = "1500 pieces landscape puzzle with 30 rows and 1.6 aspect ratio" + +[f6378369-989c-497f-a6e2-f30b1fa76cba] +description = "300 pieces portrait puzzle with 70 border pieces" + +[f53f82ba-5663-4c7e-9e86-57fdbb3e53d2] +description = "puzzle with insufficient data" + +[a3d5c31a-cc74-44bf-b4fc-9e4d65f1ac1a] +description = "puzzle with contradictory data" diff --git a/exercises/practice/piecing-it-together/build.gradle b/exercises/practice/piecing-it-together/build.gradle new file mode 100644 index 000000000..dd3862eb9 --- /dev/null +++ b/exercises/practice/piecing-it-together/build.gradle @@ -0,0 +1,25 @@ +plugins { + id "java" +} + +repositories { + mavenCentral() +} + +dependencies { + testImplementation platform("org.junit:junit-bom:5.10.0") + testImplementation "org.junit.jupiter:junit-jupiter" + testImplementation "org.assertj:assertj-core:3.25.1" + + testRuntimeOnly "org.junit.platform:junit-platform-launcher" +} + +test { + useJUnitPlatform() + + testLogging { + exceptionFormat = "full" + showStandardStreams = true + events = ["passed", "failed", "skipped"] + } +} diff --git a/exercises/practice/piecing-it-together/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/piecing-it-together/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..f8e1ee312 Binary files /dev/null and b/exercises/practice/piecing-it-together/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/piecing-it-together/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/piecing-it-together/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..4d97ea344 --- /dev/null +++ b/exercises/practice/piecing-it-together/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/exercises/practice/piecing-it-together/gradlew b/exercises/practice/piecing-it-together/gradlew new file mode 100755 index 000000000..adff685a0 --- /dev/null +++ b/exercises/practice/piecing-it-together/gradlew @@ -0,0 +1,248 @@ +#!/bin/sh + +# +# Copyright © 2015 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/exercises/practice/piecing-it-together/gradlew.bat b/exercises/practice/piecing-it-together/gradlew.bat new file mode 100644 index 000000000..c4bdd3ab8 --- /dev/null +++ b/exercises/practice/piecing-it-together/gradlew.bat @@ -0,0 +1,93 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/exercises/practice/piecing-it-together/src/main/java/JigsawInfo.java b/exercises/practice/piecing-it-together/src/main/java/JigsawInfo.java new file mode 100644 index 000000000..e08eb8909 --- /dev/null +++ b/exercises/practice/piecing-it-together/src/main/java/JigsawInfo.java @@ -0,0 +1,140 @@ +import java.util.Objects; +import java.util.Optional; +import java.util.OptionalDouble; +import java.util.OptionalInt; + +/** + * Represents partial or complete information about a jigsaw puzzle, + * + * NOTE: There is no need to change this file and is treated as read only by the Exercism test runners. + */ +public class JigsawInfo { + private final OptionalInt pieces; + private final OptionalInt border; + private final OptionalInt inside; + private final OptionalInt rows; + private final OptionalInt columns; + private final OptionalDouble aspectRatio; + private final Optional format; + + private JigsawInfo(Builder builder) { + this.pieces = builder.pieces; + this.border = builder.border; + this.inside = builder.inside; + this.rows = builder.rows; + this.columns = builder.columns; + this.aspectRatio = builder.aspectRatio; + this.format = builder.format; + } + + public static class Builder { + private OptionalInt pieces = OptionalInt.empty(); + private OptionalInt border = OptionalInt.empty(); + private OptionalInt inside = OptionalInt.empty(); + private OptionalInt rows = OptionalInt.empty(); + private OptionalInt columns = OptionalInt.empty(); + private OptionalDouble aspectRatio = OptionalDouble.empty(); + private Optional format = Optional.empty(); + + public Builder pieces(int pieces) { + this.pieces = OptionalInt.of(pieces); + return this; + } + + public Builder border(int border) { + this.border = OptionalInt.of(border); + return this; + } + + public Builder inside(int inside) { + this.inside = OptionalInt.of(inside); + return this; + } + + public Builder rows(int rows) { + this.rows = OptionalInt.of(rows); + return this; + } + + public Builder columns(int columns) { + this.columns = OptionalInt.of(columns); + return this; + } + + public Builder aspectRatio(double aspectRatio) { + this.aspectRatio = OptionalDouble.of(aspectRatio); + return this; + } + + public Builder format(String format) { + this.format = Optional.of(format); + return this; + } + + public JigsawInfo build() { + return new JigsawInfo(this); + } + } + + public OptionalInt getPieces() { + return pieces; + } + + public OptionalInt getBorder() { + return border; + } + + public OptionalInt getInside() { + return inside; + } + + public OptionalInt getRows() { + return rows; + } + + public OptionalInt getColumns() { + return columns; + } + + public OptionalDouble getAspectRatio() { + return aspectRatio; + } + + public Optional getFormat() { + return format; + } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + + JigsawInfo that = (JigsawInfo) o; + return Objects.equals(pieces, that.pieces) + && Objects.equals(border, that.border) + && Objects.equals(inside, that.inside) + && Objects.equals(rows, that.rows) + && Objects.equals(columns, that.columns) + && Objects.equals(aspectRatio, that.aspectRatio) + && Objects.equals(format, that.format); + } + + @Override + public int hashCode() { + return Objects.hash(pieces, border, inside, rows, columns, aspectRatio, format); + } + + @Override + public String toString() { + return "JigsawInfo{" + + "pieces=" + pieces + + ", border=" + border + + ", inside=" + inside + + ", rows=" + rows + + ", columns=" + columns + + ", aspectRatio=" + aspectRatio + + ", format=" + format + + '}'; + } +} diff --git a/exercises/practice/piecing-it-together/src/main/java/PiecingItTogether.java b/exercises/practice/piecing-it-together/src/main/java/PiecingItTogether.java new file mode 100644 index 000000000..d0ba9fa81 --- /dev/null +++ b/exercises/practice/piecing-it-together/src/main/java/PiecingItTogether.java @@ -0,0 +1,5 @@ +public class PiecingItTogether { + public static JigsawInfo getCompleteInformation(JigsawInfo input) { + throw new UnsupportedOperationException("Delete this statement and write your own implementation."); + } +} diff --git a/exercises/practice/piecing-it-together/src/test/java/PiecingItTogetherTest.java b/exercises/practice/piecing-it-together/src/test/java/PiecingItTogetherTest.java new file mode 100644 index 000000000..791302fa3 --- /dev/null +++ b/exercises/practice/piecing-it-together/src/test/java/PiecingItTogetherTest.java @@ -0,0 +1,175 @@ +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class PiecingItTogetherTest { + private static final double DOUBLE_EQUALITY_TOLERANCE = 1e-9; + + @Test + @DisplayName("1000 pieces puzzle with 1.6 aspect ratio") + public void test1000PiecesWithAspectRatio() { + JigsawInfo input = new JigsawInfo.Builder() + .pieces(1000) + .aspectRatio(1.6) + .build(); + + JigsawInfo expected = new JigsawInfo.Builder() + .pieces(1000) + .border(126) + .inside(874) + .rows(25) + .columns(40) + .aspectRatio(1.6) + .format("landscape") + .build(); + + JigsawInfo actual = PiecingItTogether.getCompleteInformation(input); + assertJigsawInfoEquals(actual, expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("square puzzle with 32 rows") + public void testSquarePuzzleWith32Rows() { + JigsawInfo input = new JigsawInfo.Builder() + .rows(32) + .format("square") + .build(); + + JigsawInfo expected = new JigsawInfo.Builder() + .pieces(1024) + .border(124) + .inside(900) + .rows(32) + .columns(32) + .aspectRatio(1.0) + .format("square") + .build(); + + JigsawInfo actual = PiecingItTogether.getCompleteInformation(input); + assertJigsawInfoEquals(actual, expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("400 pieces square puzzle with only inside pieces and aspect ratio") + public void testInsideAndAspectRatioOnly() { + JigsawInfo input = new JigsawInfo.Builder() + .inside(324) + .aspectRatio(1.0) + .build(); + + JigsawInfo expected = new JigsawInfo.Builder() + .pieces(400) + .border(76) + .inside(324) + .rows(20) + .columns(20) + .aspectRatio(1.0) + .format("square") + .build(); + + JigsawInfo actual = PiecingItTogether.getCompleteInformation(input); + assertJigsawInfoEquals(actual, expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("1500 pieces landscape puzzle with 30 rows and 1.6 aspect ratio") + public void testLandscape1500WithRowsAndAspect() { + JigsawInfo input = new JigsawInfo.Builder() + .rows(30) + .aspectRatio(1.6666666666666667) + .build(); + + JigsawInfo expected = new JigsawInfo.Builder() + .pieces(1500) + .border(156) + .inside(1344) + .rows(30) + .columns(50) + .aspectRatio(1.6666666666666667) + .format("landscape") + .build(); + + JigsawInfo actual = PiecingItTogether.getCompleteInformation(input); + assertJigsawInfoEquals(actual, expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("300 pieces portrait puzzle with 70 border pieces") + public void test300PiecesPortraitWithBorder() { + JigsawInfo input = new JigsawInfo.Builder() + .pieces(300) + .border(70) + .format("portrait") + .build(); + + JigsawInfo expected = new JigsawInfo.Builder() + .pieces(300) + .border(70) + .inside(230) + .rows(25) + .columns(12) + .aspectRatio(0.48) + .format("portrait") + .build(); + + JigsawInfo actual = PiecingItTogether.getCompleteInformation(input); + assertJigsawInfoEquals(actual, expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("puzzle with insufficient data") + public void testInsufficientData() { + JigsawInfo input = new JigsawInfo.Builder() + .pieces(1500) + .format("landscape") + .build(); + + assertThatThrownBy(() -> PiecingItTogether.getCompleteInformation(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("Insufficient data"); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("puzzle with contradictory data") + public void testContradictoryData() { + JigsawInfo input = new JigsawInfo.Builder() + .rows(100) + .columns(1000) + .format("square") + .build(); + + assertThatThrownBy(() -> PiecingItTogether.getCompleteInformation(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("Contradictory data"); + } + + /** + * Helper to compare two JigsawInfo objects, + * allowing a small tolerance when comparing aspect ratio doubles. + */ + private void assertJigsawInfoEquals(JigsawInfo actual, JigsawInfo expected) { + assertThat(actual.getPieces()).isEqualTo(expected.getPieces()); + assertThat(actual.getBorder()).isEqualTo(expected.getBorder()); + assertThat(actual.getInside()).isEqualTo(expected.getInside()); + assertThat(actual.getRows()).isEqualTo(expected.getRows()); + assertThat(actual.getColumns()).isEqualTo(expected.getColumns()); + assertThat(actual.getFormat()).isEqualTo(expected.getFormat()); + + Double actualAspect = actual.getAspectRatio() + .orElseThrow(() -> new AssertionError("Missing aspect ratio in actual result")); + Double expectedAspect = expected.getAspectRatio() + .orElseThrow(() -> new AssertionError("Missing aspect ratio in expected result")); + + assertThat(actualAspect).isCloseTo(expectedAspect, + org.assertj.core.api.Assertions.within(DOUBLE_EQUALITY_TOLERANCE)); + } +} diff --git a/exercises/practice/pig-latin/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/pig-latin/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/pig-latin/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/pig-latin/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/pig-latin/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/pig-latin/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/pig-latin/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/pig-latin/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/pig-latin/gradlew b/exercises/practice/pig-latin/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/pig-latin/gradlew +++ b/exercises/practice/pig-latin/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/pig-latin/gradlew.bat b/exercises/practice/pig-latin/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/pig-latin/gradlew.bat +++ b/exercises/practice/pig-latin/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/pig-latin/src/test/java/PigLatinTranslatorTest.java b/exercises/practice/pig-latin/src/test/java/PigLatinTranslatorTest.java index a3fb91d95..0a7466dcd 100644 --- a/exercises/practice/pig-latin/src/test/java/PigLatinTranslatorTest.java +++ b/exercises/practice/pig-latin/src/test/java/PigLatinTranslatorTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -14,138 +15,161 @@ public void setup() { } @Test + @DisplayName("word beginning with a") public void testWordBeginningWithA() { assertThat(pigLatinTranslator.translate("apple")).isEqualTo("appleay"); } @Disabled("Remove to run test") @Test + @DisplayName("word beginning with e") public void testWordBeginningWithE() { assertThat(pigLatinTranslator.translate("ear")).isEqualTo("earay"); } @Disabled("Remove to run test") @Test + @DisplayName("word beginning with i") public void testWordBeginningWithI() { assertThat(pigLatinTranslator.translate("igloo")).isEqualTo("iglooay"); } @Disabled("Remove to run test") @Test + @DisplayName("word beginning with o") public void testWordBeginningWithO() { assertThat(pigLatinTranslator.translate("object")).isEqualTo("objectay"); } @Disabled("Remove to run test") @Test + @DisplayName("word beginning with u") public void testWordBeginningWithU() { assertThat(pigLatinTranslator.translate("under")).isEqualTo("underay"); } @Disabled("Remove to run test") @Test + @DisplayName("word beginning with a vowel and followed by a qu") public void testWordBeginningWithVowelAndFollowedByQu() { assertThat(pigLatinTranslator.translate("equal")).isEqualTo("equalay"); } @Disabled("Remove to run test") @Test + @DisplayName("word beginning with p") public void testWordBeginningWithP() { assertThat(pigLatinTranslator.translate("pig")).isEqualTo("igpay"); } @Disabled("Remove to run test") @Test + @DisplayName("word beginning with k") public void testWordBeginningWithK() { assertThat(pigLatinTranslator.translate("koala")).isEqualTo("oalakay"); } @Disabled("Remove to run test") @Test + @DisplayName("word beginning with x") public void testWordBeginningWithX() { assertThat(pigLatinTranslator.translate("xenon")).isEqualTo("enonxay"); } @Disabled("Remove to run test") @Test + @DisplayName("word beginning with q without a following u") public void testWordBeginningWithQWithoutAFollowingU() { assertThat(pigLatinTranslator.translate("qat")).isEqualTo("atqay"); } @Disabled("Remove to run test") @Test + @DisplayName("word beginning with consonant and vowel containing qu") public void testWordBeginningWithConsonantAndVowelContainingQu() { assertThat(pigLatinTranslator.translate("liquid")).isEqualTo("iquidlay"); } @Disabled("Remove to run test") @Test + @DisplayName("word beginning with ch") public void testChTreatedLikeAConsonantAtTheBeginningOfAWord() { assertThat(pigLatinTranslator.translate("chair")).isEqualTo("airchay"); } @Disabled("Remove to run test") @Test + @DisplayName("word beginning with qu") public void testQuTreatedLikeAConsonantAtTheBeginningOfAWord() { assertThat(pigLatinTranslator.translate("queen")).isEqualTo("eenquay"); } @Disabled("Remove to run test") @Test + @DisplayName("word beginning with qu and a preceding consonant") public void testQuAndAPrecedingConsonantTreatedLikeAConsonantAtTheBeginningOfAWord() { assertThat(pigLatinTranslator.translate("square")).isEqualTo("aresquay"); } @Disabled("Remove to run test") @Test + @DisplayName("word beginning with th") public void testThTreatedLikeAConsonantAtTheBeginningOfAWord() { assertThat(pigLatinTranslator.translate("therapy")).isEqualTo("erapythay"); } @Disabled("Remove to run test") @Test + @DisplayName("word beginning with thr") public void testThrTreatedLikeAConsonantAtTheBeginningOfAWord() { assertThat(pigLatinTranslator.translate("thrush")).isEqualTo("ushthray"); } @Disabled("Remove to run test") @Test + @DisplayName("word beginning with sch") public void testSchTreatedLikeAConsonantAtTheBeginningOfAWord() { assertThat(pigLatinTranslator.translate("school")).isEqualTo("oolschay"); } @Disabled("Remove to run test") @Test + @DisplayName("word beginning with yt") public void testYtTreatedLikeAVowelAtTheBeginningOfAWord() { assertThat(pigLatinTranslator.translate("yttria")).isEqualTo("yttriaay"); } @Disabled("Remove to run test") @Test + @DisplayName("word beginning with xr") public void testXrTreatedLikeAVowelAtTheBeginningOfAWord() { assertThat(pigLatinTranslator.translate("xray")).isEqualTo("xrayay"); } @Disabled("Remove to run test") @Test + @DisplayName("y is treated like a consonant at the beginning of a word") public void testYTreatedLikeAConsonantAtTheBeginningOfAWord() { assertThat(pigLatinTranslator.translate("yellow")).isEqualTo("ellowyay"); } @Disabled("Remove to run test") @Test + @DisplayName("y is treated like a vowel at the end of a consonant cluster") public void testYTreatedLikeAVowelAtTheEndOfAConsonantCluster() { assertThat(pigLatinTranslator.translate("rhythm")).isEqualTo("ythmrhay"); } @Disabled("Remove to run test") @Test + @DisplayName("y as second letter in two letter word") public void testYAsSecondLetterInTwoLetterWord() { assertThat(pigLatinTranslator.translate("my")).isEqualTo("ymay"); } @Disabled("Remove to run test") @Test + @DisplayName("a whole phrase") public void testAWholePhrase() { assertThat(pigLatinTranslator.translate("quick fast run")).isEqualTo("ickquay astfay unray"); } diff --git a/exercises/practice/poker/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/poker/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/poker/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/poker/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/poker/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/poker/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/poker/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/poker/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/poker/gradlew b/exercises/practice/poker/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/poker/gradlew +++ b/exercises/practice/poker/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/poker/gradlew.bat b/exercises/practice/poker/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/poker/gradlew.bat +++ b/exercises/practice/poker/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/poker/src/test/java/PokerTest.java b/exercises/practice/poker/src/test/java/PokerTest.java index 016889229..367b776df 100644 --- a/exercises/practice/poker/src/test/java/PokerTest.java +++ b/exercises/practice/poker/src/test/java/PokerTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.Arrays; @@ -8,6 +9,7 @@ public class PokerTest { @Test + @DisplayName("single hand always wins") public void oneHand() { String hand = "4S 5S 7H 8D JC"; assertThat(new Poker(Collections.singletonList(hand)).getBestHands()) @@ -16,6 +18,7 @@ public void oneHand() { @Disabled("Remove to run test") @Test + @DisplayName("highest card out of all hands wins") public void highestCardWins() { String highest8 = "4D 5S 6S 8D 3C"; String highest10 = "2S 4C 7S 9H 10H"; @@ -26,6 +29,7 @@ public void highestCardWins() { @Disabled("Remove to run test") @Test + @DisplayName("a tie has multiple winners") public void tieHasMultipleWinners() { String highest8 = "4D 5S 6S 8D 3C"; String highest10 = "2S 4C 7S 9H 10H"; @@ -37,6 +41,7 @@ public void tieHasMultipleWinners() { @Disabled("Remove to run test") @Test + @DisplayName("multiple hands with the same high cards, tie compares next highest ranked, down to last card") public void sameHighCards() { String nextHighest3 = "3S 5H 6S 8D 7H"; String nextHighest2 = "2S 5D 6D 8C 7S"; @@ -46,6 +51,7 @@ public void sameHighCards() { @Disabled("Remove to run test") @Test + @DisplayName("winning high card hand also has the lowest card") public void winningWithLowestCard() { String lowest2 = "2S 5H 6S 8D 7H"; String lowest3 = "3S 4D 6D 8C 7S"; @@ -55,6 +61,7 @@ public void winningWithLowestCard() { @Disabled("Remove to run test") @Test + @DisplayName("one pair beats high card") public void nothingVsOnePair() { String nothing = "4S 5H 6C 8D KH"; String pairOf4 = "2S 4H 6S 4D JH"; @@ -64,6 +71,7 @@ public void nothingVsOnePair() { @Disabled("Remove to run test") @Test + @DisplayName("highest pair wins") public void twoPairs() { String pairOf2 = "4S 2H 6S 2D JH"; String pairOf4 = "2S 4H 6C 4D JD"; @@ -73,6 +81,7 @@ public void twoPairs() { @Disabled("Remove to run test") @Test + @DisplayName("both hands have the same pair, high card wins") public void samePair() { String pairOf4Lower = "4H 4S AH JC 3D"; String pairOf4Higher = "4C 4D AS 5D 6C"; @@ -82,6 +91,7 @@ public void samePair() { @Disabled("Remove to run test") @Test + @DisplayName("two pairs beats one pair") public void onePairVsDoublePair() { String pairOf8 = "2S 8H 6S 8D JH"; String doublePair = "4S 5H 4C 8C 5C"; @@ -91,6 +101,7 @@ public void onePairVsDoublePair() { @Disabled("Remove to run test") @Test + @DisplayName("both hands have two pairs, highest ranked pair wins") public void twoDoublePairs() { String doublePair2And8 = "2S 8H 2D 8D 3H"; String doublePair4And5 = "4S 5H 4C 8S 5D"; @@ -100,6 +111,7 @@ public void twoDoublePairs() { @Disabled("Remove to run test") @Test + @DisplayName("both hands have two pairs, with the same highest ranked pair, tie goes to low pair") public void sameHighestPair() { String doublePair2AndQ = "2S QS 2C QD JH"; String doublePairJAndQ = "JD QH JS 8D QC"; @@ -109,6 +121,7 @@ public void sameHighestPair() { @Disabled("Remove to run test") @Test + @DisplayName("both hands have two identically ranked pairs, tie goes to remaining card (kicker)") public void identicallyRankedPairs() { String kicker8 = "JD QH JS 8D QC"; String kicker2 = "JS QS JC 2D QD"; @@ -118,6 +131,7 @@ public void identicallyRankedPairs() { @Disabled("Remove to run test") @Test + @DisplayName("both hands have two pairs that add to the same value, win goes to highest pair") public void twoPairsAddingToSameValue() { String doublePair6And3 = "6S 6H 3S 3H AS"; String doublePair7And2 = "7H 7S 2H 2S AC"; @@ -127,6 +141,7 @@ public void twoPairsAddingToSameValue() { @Disabled("Remove to run test") @Test + @DisplayName("two pairs first ranked by largest pair") public void rankedByLargestPair() { String doublePairs5And4 = "5C 2S 5S 4H 4C"; String doublePairs6And2 = "6S 2S 6H 7C 2C"; @@ -136,6 +151,7 @@ public void rankedByLargestPair() { @Disabled("Remove to run test") @Test + @DisplayName("three of a kind beats two pair") public void doublePairVsThree() { String doublePair2And8 = "2S 8H 2H 8D JH"; String threeOf4 = "4S 5H 4C 8S 4H"; @@ -145,6 +161,7 @@ public void doublePairVsThree() { @Disabled("Remove to run test") @Test + @DisplayName("both hands have three of a kind, tie goes to highest ranked triplet") public void twoThrees() { String threeOf2 = "2S 2H 2C 8D JH"; String threeOf1 = "4S AH AS 8C AD"; @@ -154,6 +171,7 @@ public void twoThrees() { @Disabled("Remove to run test") @Test + @DisplayName("with multiple decks, two players can have same three of a kind, ties go to highest remaining cards") public void sameThreesMultipleDecks() { String remainingCard7 = "5S AH AS 7C AD"; String remainingCard8 = "4S AH AS 8C AD"; @@ -163,6 +181,7 @@ public void sameThreesMultipleDecks() { @Disabled("Remove to run test") @Test + @DisplayName("a straight beats three of a kind") public void threeVsStraight() { String threeOf4 = "4S 5H 4C 8D 4H"; String straight = "3S 4D 2S 6D 5C"; @@ -172,6 +191,7 @@ public void threeVsStraight() { @Disabled("Remove to run test") @Test + @DisplayName("aces can end a straight (10 J Q K A)") public void acesCanEndAStraight() { String hand = "4S 5H 4C 8D 4H"; String straightEndsA = "10D JH QS KD AC"; @@ -181,6 +201,7 @@ public void acesCanEndAStraight() { @Disabled("Remove to run test") @Test + @DisplayName("aces can start a straight (A 2 3 4 5)") public void acesCanStartAStraight() { String hand = "4S 5H 4C 8D 4H"; String straightStartA = "4D AH 3S 2D 5C"; @@ -190,6 +211,7 @@ public void acesCanStartAStraight() { @Disabled("Remove to run test") @Test + @DisplayName("aces cannot be in the middle of a straight (Q K A 2 3)") public void acesCannotBeInMiddleOfStraight() { String hand = "2C 3D 7H 5H 2S"; String straightMiddleA = "QS KH AC 2D 3S"; @@ -199,6 +221,7 @@ public void acesCannotBeInMiddleOfStraight() { @Disabled("Remove to run test") @Test + @DisplayName("both hands with a straight, tie goes to highest ranked card") public void twoStraights() { String straightTo8 = "4S 6C 7S 8D 5H"; String straightTo9 = "5S 7H 8S 9D 6H"; @@ -208,6 +231,7 @@ public void twoStraights() { @Disabled("Remove to run test") @Test + @DisplayName("even though an ace is usually high, a 5-high straight is the lowest-scoring straight") public void theLowestStraightStartsWithAce() { String straight = "2H 3C 4D 5D 6H"; String straightStartA = "4S AH 3S 2D 5H"; @@ -217,6 +241,7 @@ public void theLowestStraightStartsWithAce() { @Disabled("Remove to run test") @Test + @DisplayName("flush beats a straight") public void straightVsFlush() { String straightTo8 = "4C 6H 7D 8D 5H"; String flushTo7 = "2S 4S 5S 6S 7S"; @@ -226,6 +251,7 @@ public void straightVsFlush() { @Disabled("Remove to run test") @Test + @DisplayName("both hands have a flush, tie goes to high card, down to the last one if necessary") public void twoFlushs() { String flushTo9 = "2H 7H 8H 9H 6H"; String flushTo7 = "3S 5S 6S 7S 8S"; @@ -235,6 +261,7 @@ public void twoFlushs() { @Disabled("Remove to run test") @Test + @DisplayName("full house beats a flush") public void flushVsFull() { String flushTo8 = "3H 6H 7H 8H 5H"; String full = "4S 5H 4C 5D 4H"; @@ -244,6 +271,7 @@ public void flushVsFull() { @Disabled("Remove to run test") @Test + @DisplayName("both hands have a full house, tie goes to highest-ranked triplet") public void twoFulls() { String fullOf4By9 = "4H 4S 4D 9S 9D"; String fullOf5By8 = "5H 5S 5D 8S 8D"; @@ -253,6 +281,7 @@ public void twoFulls() { @Disabled("Remove to run test") @Test + @DisplayName("with multiple decks, both hands have a full house with the same triplet, tie goes to the pair") public void twoFullssameThripletMultipleDecks() { String fullOf5By9 = "5H 5S 5D 9S 9D"; String fullOf5By8 = "5H 5S 5D 8S 8D"; @@ -262,6 +291,7 @@ public void twoFullssameThripletMultipleDecks() { @Disabled("Remove to run test") @Test + @DisplayName("four of a kind beats a full house") public void fullVsSquare() { String full = "4S 5H 4D 5D 4H"; String squareOf3 = "3S 3H 2S 3D 3C"; @@ -271,6 +301,7 @@ public void fullVsSquare() { @Disabled("Remove to run test") @Test + @DisplayName("both hands have four of a kind, tie goes to high quad") public void twoSquares() { String squareOf2 = "2S 2H 2C 8D 2D"; String squareOf5 = "4S 5H 5S 5D 5C"; @@ -280,6 +311,7 @@ public void twoSquares() { @Disabled("Remove to run test") @Test + @DisplayName("with multiple decks, both hands with identical four of a kind, tie determined by kicker") public void sameSquaresMultipleDecks() { String kicker2 = "3S 3H 2S 3D 3C"; String kicker4 = "3S 3H 4S 3D 3C"; @@ -289,6 +321,7 @@ public void sameSquaresMultipleDecks() { @Disabled("Remove to run test") @Test + @DisplayName("straight flush beats four of a kind") public void squareVsStraightFlush() { String squareOf5 = "4S 5H 5S 5D 5C"; String straightFlushTo9 = "7S 8S 9S 6S 10S"; @@ -298,6 +331,7 @@ public void squareVsStraightFlush() { @Disabled("Remove to run test") @Test + @DisplayName("aces can end a straight flush (10 J Q K A)") public void acesEndingStraightFlush() { String hand = "KC AH AS AD AC"; String straightFlushEndingWithA = "10C JC QC KC AC"; @@ -307,6 +341,7 @@ public void acesEndingStraightFlush() { @Disabled("Remove to run test") @Test + @DisplayName("aces can start a straight flush (A 2 3 4 5)") public void acesStartingStraightFlush() { String straightFlushStartingWithA = "4H AH 3H 2H 5H"; String hand = "KS AH AS AD AC"; @@ -316,6 +351,7 @@ public void acesStartingStraightFlush() { @Disabled("Remove to run test") @Test + @DisplayName("aces cannot be in the middle of a straight flush (Q K A 2 3)") public void acesCannotBeInMiddleOfStraightFlush() { String straightFlushWithAInMiddle = "QH KH AH 2H 3H"; String hand = "2C AC QC 10C KC"; @@ -325,6 +361,7 @@ public void acesCannotBeInMiddleOfStraightFlush() { @Disabled("Remove to run test") @Test + @DisplayName("both hands have a straight flush, tie goes to highest-ranked card") public void twoStraightFlushes() { String straightFlushTo8 = "4H 6H 7H 8H 5H"; String straightFlushTo9 = "5S 7S 8S 9S 6S"; @@ -334,6 +371,7 @@ public void twoStraightFlushes() { @Disabled("Remove to run test") @Test + @DisplayName("even though an ace is usually high, a 5-high straight flush is the lowest-scoring straight flush") public void straightFlushTo5IsTheLowestScoring() { String straightFlushTo6 = "2H 3H 4H 5H 6H"; String straightFlushTo5 = "4D AD 3D 2D 5D"; diff --git a/exercises/practice/pov/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/pov/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/pov/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/pov/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/pov/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/pov/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/pov/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/pov/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/pov/gradlew b/exercises/practice/pov/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/pov/gradlew +++ b/exercises/practice/pov/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/pov/gradlew.bat b/exercises/practice/pov/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/pov/gradlew.bat +++ b/exercises/practice/pov/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/pov/src/test/java/PovTest.java b/exercises/practice/pov/src/test/java/PovTest.java index 4eeea86a8..844a9be8f 100644 --- a/exercises/practice/pov/src/test/java/PovTest.java +++ b/exercises/practice/pov/src/test/java/PovTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.List; @@ -9,6 +10,7 @@ public class PovTest { @Test + @DisplayName("Results in the same tree if the input tree is a singleton") public void testFromPovGivenSingletonTree() { Tree tree = Tree.of("x"); Tree expected = Tree.of("x"); @@ -17,6 +19,7 @@ public void testFromPovGivenSingletonTree() { @Disabled("Remove to run test") @Test + @DisplayName("Can reroot a tree with a parent and one sibling") public void testFromPovGivenTreeWithParentAndOneSibling() { Tree tree = Tree.of("parent", List.of(Tree.of("x"), @@ -30,6 +33,7 @@ public void testFromPovGivenTreeWithParentAndOneSibling() { @Disabled("Remove to run test") @Test + @DisplayName("Can reroot a tree with a parent and many siblings") public void testFromPovGivenTreeWithParentAndManySibling() { Tree tree = Tree.of("parent", List.of(Tree.of("x"), @@ -48,6 +52,7 @@ public void testFromPovGivenTreeWithParentAndManySibling() { @Disabled("Remove to run test") @Test + @DisplayName("an reroot a tree with new root deeply nested in the tree") public void testFromPovGivenTreeWithNewRootDeeplyNested() { Tree tree = Tree.of("level-0", List.of(Tree.of("level-1", @@ -66,6 +71,7 @@ public void testFromPovGivenTreeWithNewRootDeeplyNested() { @Disabled("Remove to run test") @Test + @DisplayName("Moves children of the new root to same level as former parent") public void testFromPovGivenMovesChildrenOfNewRootToSameLevelAsFormerParent() { Tree tree = Tree.of("parent", List.of(Tree.of("x", @@ -82,6 +88,7 @@ public void testFromPovGivenMovesChildrenOfNewRootToSameLevelAsFormerParent() { @Disabled("Remove to run test") @Test + @DisplayName("Can reroot a complex tree with cousins") public void testFromPovGivenComplexTreeWithCousins() { Tree tree = Tree.of("grandparent", List.of(Tree.of("parent", @@ -110,6 +117,7 @@ public void testFromPovGivenComplexTreeWithCousins() { @Disabled("Remove to run test") @Test + @DisplayName("Errors if target does not exist in a singleton tree") public void testFromPovGivenNonExistentTargetInSingletonTree() { Tree tree = Tree.of("x"); assertThatExceptionOfType(UnsupportedOperationException.class) @@ -119,6 +127,7 @@ public void testFromPovGivenNonExistentTargetInSingletonTree() { @Disabled("Remove to run test") @Test + @DisplayName("Errors if target does not exist in a larger tree") public void testFromPovGivenNonExistentTargetInLargeTree() { Tree tree = Tree.of("parent", List.of(Tree.of("x", @@ -134,6 +143,7 @@ public void testFromPovGivenNonExistentTargetInLargeTree() { @Disabled("Remove to run test") @Test + @DisplayName("Can find path to parent") public void testPathToCanFindPathToParent() { Tree tree = Tree.of("parent", List.of(Tree.of("x"), @@ -158,6 +168,7 @@ public void testPathToCanFindPathToSibling() { @Disabled("Remove to run test") @Test + @DisplayName("Can find path to cousin") public void testPathToCanFindPathToCousin() { Tree tree = Tree.of("grandparent", List.of(Tree.of("parent", @@ -176,6 +187,7 @@ public void testPathToCanFindPathToCousin() { @Disabled("Remove to run test") @Test + @DisplayName("Can find path not involving root") public void testPathToCanFindPathNotEnvolvingRoot() { Tree tree = Tree.of("grandparent", List.of(Tree.of("parent", @@ -189,6 +201,7 @@ public void testPathToCanFindPathNotEnvolvingRoot() { @Disabled("Remove to run test") @Test + @DisplayName("Can find path from nodes other than x") public void testPathToCanFindPathFromNodesOtherThanX() { Tree tree = Tree.of("parent", List.of(Tree.of("a"), @@ -202,6 +215,7 @@ public void testPathToCanFindPathFromNodesOtherThanX() { @Disabled("Remove to run test") @Test + @DisplayName("Errors if destination does not exist") public void testPathWhenDestinationDoesNotExist() { Tree tree = Tree.of("parent", List.of(Tree.of("x", @@ -217,6 +231,7 @@ public void testPathWhenDestinationDoesNotExist() { @Disabled("Remove to run test") @Test + @DisplayName("Errors if source does not exist") public void testPathWhenSourceDoesNotExist() { Tree tree = Tree.of("parent", List.of(Tree.of("x", diff --git a/exercises/practice/prime-factors/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/prime-factors/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/prime-factors/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/prime-factors/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/prime-factors/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/prime-factors/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/prime-factors/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/prime-factors/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/prime-factors/gradlew b/exercises/practice/prime-factors/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/prime-factors/gradlew +++ b/exercises/practice/prime-factors/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/prime-factors/gradlew.bat b/exercises/practice/prime-factors/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/prime-factors/gradlew.bat +++ b/exercises/practice/prime-factors/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/prime-factors/src/test/java/PrimeFactorsCalculatorTest.java b/exercises/practice/prime-factors/src/test/java/PrimeFactorsCalculatorTest.java index 62cc0e3d1..d6f48a710 100644 --- a/exercises/practice/prime-factors/src/test/java/PrimeFactorsCalculatorTest.java +++ b/exercises/practice/prime-factors/src/test/java/PrimeFactorsCalculatorTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -14,72 +15,84 @@ public void setUp() { } @Test + @DisplayName("no factors") public void testNoFactors() { assertThat(primeFactorsCalculator.calculatePrimeFactorsOf(1L)).isEmpty(); } @Disabled("Remove to run test") @Test + @DisplayName("prime number") public void testPrimeNumber() { assertThat(primeFactorsCalculator.calculatePrimeFactorsOf(2L)).containsExactly(2L); } @Disabled("Remove to run test") @Test + @DisplayName("another prime number") public void testAnotherPrimeNumber() { assertThat(primeFactorsCalculator.calculatePrimeFactorsOf(3L)).containsExactly(3L); } @Disabled("Remove to run test") @Test + @DisplayName("square of a prime") public void testSquareOfAPrime() { assertThat(primeFactorsCalculator.calculatePrimeFactorsOf(9L)).containsExactly(3L, 3L); } @Disabled("Remove to run test") @Test + @DisplayName("product of first prime") public void testProductOfFirstPrime() { assertThat(primeFactorsCalculator.calculatePrimeFactorsOf(4L)).containsExactly(2L, 2L); } @Disabled("Remove to run test") @Test + @DisplayName("cube of a prime") public void testCubeOfAPrime() { assertThat(primeFactorsCalculator.calculatePrimeFactorsOf(8L)).containsExactly(2L, 2L, 2L); } @Disabled("Remove to run test") @Test + @DisplayName("product of second prime") public void testProductOfSecondPrime() { assertThat(primeFactorsCalculator.calculatePrimeFactorsOf(625L)).containsExactly(5L, 5L, 5L, 5L); } @Disabled("Remove to run test") @Test + @DisplayName("product of third prime") public void testProductOfThirdPrime() { assertThat(primeFactorsCalculator.calculatePrimeFactorsOf(27L)).containsExactly(3L, 3L, 3L); } @Disabled("Remove to run test") @Test + @DisplayName("product of first and second prime") public void testProductOfFirstAndSecondPrime() { assertThat(primeFactorsCalculator.calculatePrimeFactorsOf(6L)).containsExactly(2L, 3L); } @Disabled("Remove to run test") @Test + @DisplayName("product of primes and non-primes") public void testProductOfPrimesAndNonPrimes() { assertThat(primeFactorsCalculator.calculatePrimeFactorsOf(12L)).containsExactly(2L, 2L, 3L); } @Disabled("Remove to run test") @Test + @DisplayName("product of primes") public void testProductOfPrimes() { assertThat(primeFactorsCalculator.calculatePrimeFactorsOf(901255L)).containsExactly(5L, 17L, 23L, 461L); } @Disabled("Remove to run test") @Test + @DisplayName("factors include a large prime") public void testFactorsIncludingALargePrime() { assertThat(primeFactorsCalculator.calculatePrimeFactorsOf(93819012551L)).containsExactly(11L, 9539L, 894119L); } diff --git a/exercises/practice/protein-translation/.docs/instructions.md b/exercises/practice/protein-translation/.docs/instructions.md index 44880802c..35c953b11 100644 --- a/exercises/practice/protein-translation/.docs/instructions.md +++ b/exercises/practice/protein-translation/.docs/instructions.md @@ -1,36 +1,17 @@ # Instructions -Translate RNA sequences into proteins. +Your job is to translate RNA sequences into proteins. -RNA can be broken into three-nucleotide sequences called codons, and then translated to a protein like so: +RNA strands are made up of three-nucleotide sequences called **codons**. +Each codon translates to an **amino acid**. +When joined together, those amino acids make a protein. -RNA: `"AUGUUUUCU"` => translates to - -Codons: `"AUG", "UUU", "UCU"` -=> which become a protein with the following sequence => - -Protein: `"Methionine", "Phenylalanine", "Serine"` - -There are 64 codons which in turn correspond to 20 amino acids; however, all of the codon sequences and resulting amino acids are not important in this exercise. -If it works for one codon, the program should work for all of them. -However, feel free to expand the list in the test suite to include them all. - -There are also three terminating codons (also known as 'STOP' codons); if any of these codons are encountered (by the ribosome), all translation ends and the protein is terminated. - -All subsequent codons after are ignored, like this: - -RNA: `"AUGUUUUCUUAAAUG"` => - -Codons: `"AUG", "UUU", "UCU", "UAA", "AUG"` => - -Protein: `"Methionine", "Phenylalanine", "Serine"` - -Note the stop codon `"UAA"` terminates the translation and the final methionine is not translated into the protein sequence. - -Below are the codons and resulting amino acids needed for the exercise. +In the real world, there are 64 codons, which in turn correspond to 20 amino acids. +However, for this exercise, you’ll only use a few of the possible 64. +They are listed below: | Codon | Amino Acid | -| :----------------- | :------------ | +| ------------------ | ------------- | | AUG | Methionine | | UUU, UUC | Phenylalanine | | UUA, UUG | Leucine | @@ -40,6 +21,18 @@ Below are the codons and resulting amino acids needed for the exercise. | UGG | Tryptophan | | UAA, UAG, UGA | STOP | +For example, the RNA string “AUGUUUUCU” has three codons: “AUG”, “UUU” and “UCU”. +These map to Methionine, Phenylalanine, and Serine. + +## “STOP” Codons + +You’ll note from the table above that there are three **“STOP” codons**. +If you encounter any of these codons, ignore the rest of the sequence — the protein is complete. + +For example, “AUGUUUUCUUAAAUG” contains a STOP codon (“UAA”). +Once we reach that point, we stop processing. +We therefore only consider the part before it (i.e. “AUGUUUUCU”), not any further codons after it (i.e. “AUG”). + Learn more about [protein translation on Wikipedia][protein-translation]. [protein-translation]: https://en.wikipedia.org/wiki/Translation_(biology) diff --git a/exercises/practice/protein-translation/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/protein-translation/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/protein-translation/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/protein-translation/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/protein-translation/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/protein-translation/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/protein-translation/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/protein-translation/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/protein-translation/gradlew b/exercises/practice/protein-translation/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/protein-translation/gradlew +++ b/exercises/practice/protein-translation/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/protein-translation/gradlew.bat b/exercises/practice/protein-translation/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/protein-translation/gradlew.bat +++ b/exercises/practice/protein-translation/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/protein-translation/src/test/java/ProteinTranslatorTest.java b/exercises/practice/protein-translation/src/test/java/ProteinTranslatorTest.java index 8da14515b..0eced2521 100644 --- a/exercises/practice/protein-translation/src/test/java/ProteinTranslatorTest.java +++ b/exercises/practice/protein-translation/src/test/java/ProteinTranslatorTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -15,126 +16,147 @@ public void setUp() { } @Test + @DisplayName("Empty RNA sequence results in no proteins") public void testEmptyRnaSequenceResultInNoproteins() { assertThat(proteinTranslator.translate("")).isEmpty(); } @Disabled("Remove to run test") @Test + @DisplayName("Methionine RNA sequence") public void testMethionineRnaSequence() { assertThat(proteinTranslator.translate("AUG")).containsExactly("Methionine"); } @Disabled("Remove to run test") @Test + @DisplayName("Phenylalanine RNA sequence 1") public void testPhenylalanineRnaSequence1() { assertThat(proteinTranslator.translate("UUU")).containsExactly("Phenylalanine"); } @Disabled("Remove to run test") @Test + @DisplayName("Phenylalanine RNA sequence 2") public void testPhenylalanineRnaSequence2() { assertThat(proteinTranslator.translate("UUC")).containsExactly("Phenylalanine"); } @Disabled("Remove to run test") @Test + @DisplayName("Leucine RNA sequence 1") public void testLeucineRnaSequence1() { assertThat(proteinTranslator.translate("UUA")).containsExactly("Leucine"); } @Disabled("Remove to run test") @Test + @DisplayName("Leucine RNA sequence 2") public void testLeucineRnaSequence2() { assertThat(proteinTranslator.translate("UUG")).containsExactly("Leucine"); } @Disabled("Remove to run test") @Test + @DisplayName("Serine RNA sequence 1") public void testSerineRnaSequence1() { assertThat(proteinTranslator.translate("UCU")).containsExactly("Serine"); } @Disabled("Remove to run test") @Test + @DisplayName("Serine RNA sequence 2") public void testSerineRnaSequence2() { assertThat(proteinTranslator.translate("UCC")).containsExactly("Serine"); } @Disabled("Remove to run test") @Test + @DisplayName("Serine RNA sequence 3") public void testSerineRnaSequence3() { assertThat(proteinTranslator.translate("UCA")).containsExactly("Serine"); } @Disabled("Remove to run test") @Test + @DisplayName("Serine RNA sequence 4") public void testSerineRnaSequence4() { assertThat(proteinTranslator.translate("UCG")).containsExactly("Serine"); } @Disabled("Remove to run test") @Test + @DisplayName("Tyrosine RNA sequence 1") public void testTyrosineRnaSequence1() { assertThat(proteinTranslator.translate("UAU")).containsExactly("Tyrosine"); } @Disabled("Remove to run test") @Test + @DisplayName("Tyrosine RNA sequence 2") public void testTyrosineRnaSequence2() { assertThat(proteinTranslator.translate("UAC")).containsExactly("Tyrosine"); } @Disabled("Remove to run test") @Test + @DisplayName("Cysteine RNA sequence 1") public void testCysteineRnaSequence1() { assertThat(proteinTranslator.translate("UGU")).containsExactly("Cysteine"); } @Disabled("Remove to run test") @Test + @DisplayName("Cysteine RNA sequence 2") public void testCysteineRnaSequence2() { assertThat(proteinTranslator.translate("UGC")).containsExactly("Cysteine"); } @Disabled("Remove to run test") @Test + @DisplayName("Tryptophan RNA sequence") public void testTryptophanRnaSequence1() { assertThat(proteinTranslator.translate("UGG")).containsExactly("Tryptophan"); } @Disabled("Remove to run test") @Test + @DisplayName("STOP codon RNA sequence 1") public void testStopRnaSequence1() { assertThat(proteinTranslator.translate("UAA")).isEmpty(); } @Disabled("Remove to run test") @Test + @DisplayName("STOP codon RNA sequence 2") public void testStopRnaSequence2() { assertThat(proteinTranslator.translate("UAG")).isEmpty(); } @Disabled("Remove to run test") @Test + @DisplayName("STOP codon RNA sequence 3") public void testStopRnaSequence3() { assertThat(proteinTranslator.translate("UGA")).isEmpty(); } @Disabled("Remove to run test") @Test + @DisplayName("Sequence of two protein codons translates into proteins") public void testSequenceOfTwoProteinCodonsTranslatesIntoProteins() { assertThat(proteinTranslator.translate("UUUUUU")).containsExactly("Phenylalanine", "Phenylalanine"); } @Disabled("Remove to run test") @Test + @DisplayName("Sequence of two different protein codons translates into proteins") public void testSequenceOfTwoDifferentProteinCodonsTranslatesIntoProteins() { assertThat(proteinTranslator.translate("UUAUUG")).containsExactly("Leucine", "Leucine"); } @Disabled("Remove to run test") @Test + @DisplayName("Translate RNA strand into correct protein list") public void testTranslationOfRnaToProteinList() { assertThat(proteinTranslator.translate("AUGUUUUGG")) .containsExactly("Methionine", "Phenylalanine", "Tryptophan"); @@ -142,30 +164,35 @@ public void testTranslationOfRnaToProteinList() { @Disabled("Remove to run test") @Test + @DisplayName("Translation stops if STOP codon at beginning of sequence") public void testTranslationStopsIfStopCodonAtBeginning() { assertThat(proteinTranslator.translate("UAGUGG")).isEmpty(); } @Disabled("Remove to run test") @Test + @DisplayName("Translation stops if STOP codon at end of two-codon sequence") public void testTranslationStopsIfStopCodonAtEnd1() { assertThat(proteinTranslator.translate("UGGUAG")).containsExactly("Tryptophan"); } @Disabled("Remove to run test") @Test + @DisplayName("Translation stops if STOP codon at end of three-codon sequence") public void testTranslationStopsIfStopCodonAtEnd2() { assertThat(proteinTranslator.translate("AUGUUUUAA")).containsExactly("Methionine", "Phenylalanine"); } @Disabled("Remove to run test") @Test + @DisplayName("Translation stops if STOP codon in middle of three-codon sequence") public void testTranslationStopsIfStopCodonInMiddle1() { assertThat(proteinTranslator.translate("UGGUAGUGG")).containsExactly("Tryptophan"); } @Disabled("Remove to run test") @Test + @DisplayName("Translation stops if STOP codon in middle of six-codon sequence") public void testTranslationStopsIfStopCodonInMiddle2() { assertThat(proteinTranslator.translate("UGGUGUUAUUAAUGGUUU")) .containsExactly("Tryptophan", "Cysteine", "Tyrosine"); @@ -173,6 +200,7 @@ public void testTranslationStopsIfStopCodonInMiddle2() { @Disabled("Remove to run test") @Test + @DisplayName("Sequence of two non-STOP codons does not translate to a STOP codon") public void testSequenceOfTwoNonStopCodonsDoNotTranslateToAStopCodon() { assertThat(proteinTranslator.translate("AUGAUG")) .containsExactly("Methionine", "Methionine"); @@ -180,6 +208,7 @@ public void testSequenceOfTwoNonStopCodonsDoNotTranslateToAStopCodon() { @Disabled("Remove to run test") @Test + @DisplayName("Non-existing codon can't translate") public void testNonExistingCodonCantTranslate() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> proteinTranslator.translate("AAA")) @@ -188,6 +217,7 @@ public void testNonExistingCodonCantTranslate() { @Disabled("Remove to run test") @Test + @DisplayName("Unknown amino acids, not part of a codon, can't translate") public void testUnknownAminoAcidsNotPartOfACodonCantTranslate() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> proteinTranslator.translate("XYZ")) @@ -196,6 +226,7 @@ public void testUnknownAminoAcidsNotPartOfACodonCantTranslate() { @Disabled("Remove to run test") @Test + @DisplayName("Incomplete RNA sequence can't translate") public void testIncompleteRnaSequenceCantTranslate() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> proteinTranslator.translate("AUGU")) @@ -204,6 +235,7 @@ public void testIncompleteRnaSequenceCantTranslate() { @Disabled("Remove to run test") @Test + @DisplayName("Incomplete RNA sequence can translate if valid until a STOP codon") public void testIncompleteRnaSequenceCanTranslateIfValidUntilAStopCodon() { assertThat(proteinTranslator.translate("UUCUUCUAAUGGU")).containsExactly("Phenylalanine", "Phenylalanine"); } diff --git a/exercises/practice/proverb/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/proverb/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/proverb/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/proverb/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/proverb/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/proverb/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/proverb/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/proverb/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/proverb/gradlew b/exercises/practice/proverb/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/proverb/gradlew +++ b/exercises/practice/proverb/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/proverb/gradlew.bat b/exercises/practice/proverb/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/proverb/gradlew.bat +++ b/exercises/practice/proverb/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/proverb/src/test/java/ProverbTest.java b/exercises/practice/proverb/src/test/java/ProverbTest.java index 739911e64..854a34b4b 100644 --- a/exercises/practice/proverb/src/test/java/ProverbTest.java +++ b/exercises/practice/proverb/src/test/java/ProverbTest.java @@ -1,11 +1,13 @@ import static org.assertj.core.api.Assertions.assertThat; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; public class ProverbTest { @Test + @DisplayName("zero pieces") public void zeroWordsAreGiven() { String[] words = new String[0]; @@ -14,6 +16,7 @@ public void zeroWordsAreGiven() { @Disabled("Remove to run test") @Test + @DisplayName("one piece") public void singlePieceOfProverb() { String[] words = new String[]{"nail"}; @@ -23,6 +26,7 @@ public void singlePieceOfProverb() { @Disabled("Remove to run test") @Test + @DisplayName("two pieces") public void twoPiecesOfProverb() { String[] words = new String[]{"nail", "shoe"}; @@ -34,6 +38,7 @@ public void twoPiecesOfProverb() { @Disabled("Remove to run test") @Test + @DisplayName("three pieces") public void shortChainOfConsequences() { String[] words = new String[]{"nail", "shoe", "horse"}; @@ -46,6 +51,7 @@ public void shortChainOfConsequences() { @Disabled("Remove to run test") @Test + @DisplayName("full proverb") public void fullProverb() { String[] words = new String[]{"nail", "shoe", "horse", "rider", "message", "battle", "kingdom"}; @@ -62,6 +68,7 @@ public void fullProverb() { @Disabled("Remove to run test") @Test + @DisplayName("four pieces modernized") public void fourPiecesModernizedProverb() { String[] words = new String[]{"pin", "gun", "soldier", "battle"}; diff --git a/exercises/practice/pythagorean-triplet/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/pythagorean-triplet/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/pythagorean-triplet/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/pythagorean-triplet/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/pythagorean-triplet/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/pythagorean-triplet/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/pythagorean-triplet/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/pythagorean-triplet/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/pythagorean-triplet/gradlew b/exercises/practice/pythagorean-triplet/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/pythagorean-triplet/gradlew +++ b/exercises/practice/pythagorean-triplet/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/pythagorean-triplet/gradlew.bat b/exercises/practice/pythagorean-triplet/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/pythagorean-triplet/gradlew.bat +++ b/exercises/practice/pythagorean-triplet/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/pythagorean-triplet/src/test/java/PythagoreanTripletTest.java b/exercises/practice/pythagorean-triplet/src/test/java/PythagoreanTripletTest.java index 83b2705c5..50361fb3a 100644 --- a/exercises/practice/pythagorean-triplet/src/test/java/PythagoreanTripletTest.java +++ b/exercises/practice/pythagorean-triplet/src/test/java/PythagoreanTripletTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.Arrays; @@ -10,6 +11,7 @@ public class PythagoreanTripletTest { @Test + @DisplayName("triplets whose sum is 12") public void tripletsWhoseSumIs12() { List actual = PythagoreanTriplet @@ -23,6 +25,7 @@ public void tripletsWhoseSumIs12() { @Disabled("Remove to run test") @Test + @DisplayName("triplets whose sum is 108") public void tripletsWhoseSumIs108() { List actual = PythagoreanTriplet @@ -36,6 +39,7 @@ public void tripletsWhoseSumIs108() { @Disabled("Remove to run test") @Test + @DisplayName("triplets whose sum is 1000") public void tripletsWhoseSumIs1000() { List actual = PythagoreanTriplet @@ -50,6 +54,7 @@ public void tripletsWhoseSumIs1000() { @Disabled("Remove to run test") @Test + @DisplayName("no matching triplets for 1001") public void tripletsWhoseSumIs1001() { List actual = PythagoreanTriplet @@ -62,6 +67,7 @@ public void tripletsWhoseSumIs1001() { @Disabled("Remove to run test") @Test + @DisplayName("returns all matching triplets") public void tripletsWhoseSumIs90() { List actual = PythagoreanTriplet @@ -77,6 +83,7 @@ public void tripletsWhoseSumIs90() { @Disabled("Remove to run test") @Test + @DisplayName("several matching triplets") public void tripletsWhoseSumIs840() { List actual = PythagoreanTriplet @@ -117,6 +124,7 @@ public void tripletsWhoseSumIs840WithFactorsLessThanOrEqualTo370() { @Disabled("Remove to run test") @Test + @DisplayName("triplets for large number") public void tripletsWhoseSumIs30000() { List actual = PythagoreanTriplet diff --git a/exercises/practice/queen-attack/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/queen-attack/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/queen-attack/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/queen-attack/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/queen-attack/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/queen-attack/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/queen-attack/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/queen-attack/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/queen-attack/gradlew b/exercises/practice/queen-attack/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/queen-attack/gradlew +++ b/exercises/practice/queen-attack/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/queen-attack/gradlew.bat b/exercises/practice/queen-attack/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/queen-attack/gradlew.bat +++ b/exercises/practice/queen-attack/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/queen-attack/src/test/java/QueenAttackCalculatorTest.java b/exercises/practice/queen-attack/src/test/java/QueenAttackCalculatorTest.java index e6b65f5e6..c4f4f70d2 100644 --- a/exercises/practice/queen-attack/src/test/java/QueenAttackCalculatorTest.java +++ b/exercises/practice/queen-attack/src/test/java/QueenAttackCalculatorTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -8,12 +9,14 @@ public class QueenAttackCalculatorTest { @Test + @DisplayName("queen with a valid position") public void testCreateQueenWithAValidPosition() { new Queen(2, 2); } @Disabled("Remove to run test") @Test + @DisplayName("queen must have positive row") public void testCreateQueenMustHavePositiveRow() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> new Queen(-2, 2)) @@ -22,6 +25,7 @@ public void testCreateQueenMustHavePositiveRow() { @Disabled("Remove to run test") @Test + @DisplayName("queen must have row on board") public void testCreateQueenMustHaveRowOnBoard() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> new Queen(8, 4)) @@ -30,6 +34,7 @@ public void testCreateQueenMustHaveRowOnBoard() { @Disabled("Remove to run test") @Test + @DisplayName("queen must have positive column") public void testCreateQueenMustHavePositiveColumn() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> new Queen(2, -2)) @@ -38,6 +43,7 @@ public void testCreateQueenMustHavePositiveColumn() { @Disabled("Remove to run test") @Test + @DisplayName("queen must have column on board") public void testCreateQueenMustHaveColumnOnBoard() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> new Queen(4, 8)) @@ -46,6 +52,7 @@ public void testCreateQueenMustHaveColumnOnBoard() { @Disabled("Remove to run test") @Test + @DisplayName("cannot attack") public void testQueensCannotAttack() { QueenAttackCalculator calculator = new QueenAttackCalculator(new Queen(2, 4), new Queen(6, 6)); @@ -55,6 +62,7 @@ public void testQueensCannotAttack() { @Disabled("Remove to run test") @Test + @DisplayName("can attack on same row") public void testQueensCanAttackOnTheSameRow() { QueenAttackCalculator calculator = new QueenAttackCalculator(new Queen(2, 4), new Queen(2, 6)); @@ -64,6 +72,7 @@ public void testQueensCanAttackOnTheSameRow() { @Disabled("Remove to run test") @Test + @DisplayName("can attack on same column") public void testQueensCanAttackOnTheSameColumn() { QueenAttackCalculator calculator = new QueenAttackCalculator(new Queen(4, 5), new Queen(2, 5)); @@ -73,6 +82,7 @@ public void testQueensCanAttackOnTheSameColumn() { @Disabled("Remove to run test") @Test + @DisplayName("can attack on first diagonal") public void testQueensCanAttackOnFirstDiagonal() { QueenAttackCalculator calculator = new QueenAttackCalculator(new Queen(2, 2), new Queen(0, 4)); @@ -82,6 +92,7 @@ public void testQueensCanAttackOnFirstDiagonal() { @Disabled("Remove to run test") @Test + @DisplayName("can attack on second diagonal") public void testQueensCanAttackOnSecondDiagonal() { QueenAttackCalculator calculator = new QueenAttackCalculator(new Queen(2, 2), new Queen(3, 1)); @@ -91,6 +102,7 @@ public void testQueensCanAttackOnSecondDiagonal() { @Disabled("Remove to run test") @Test + @DisplayName("can attack on third diagonal") public void testQueensCanAttackOnThirdDiagonal() { QueenAttackCalculator calculator = new QueenAttackCalculator(new Queen(2, 2), new Queen(1, 1)); @@ -100,6 +112,7 @@ public void testQueensCanAttackOnThirdDiagonal() { @Disabled("Remove to run test") @Test + @DisplayName("can attack on fourth diagonal") public void testQueensCanAttackOnFourthDiagonal() { QueenAttackCalculator calculator = new QueenAttackCalculator(new Queen(1, 7), new Queen(0, 6)); @@ -109,6 +122,10 @@ public void testQueensCanAttackOnFourthDiagonal() { @Disabled("Remove to run test") @Test + @DisplayName( + "cannot attack if falling diagonals are only the same " + + "when reflected across the longest falling diagonal" + ) public void testQueenCannotAttackIfFallingDiagonalsAreOnlyTheSameWhenReflectedAcrossTheLongestFallingDiagonal() { QueenAttackCalculator calculator = new QueenAttackCalculator(new Queen(4, 1), new Queen(2, 5)); diff --git a/exercises/practice/rail-fence-cipher/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/rail-fence-cipher/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/rail-fence-cipher/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/rail-fence-cipher/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/rail-fence-cipher/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/rail-fence-cipher/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/rail-fence-cipher/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/rail-fence-cipher/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/rail-fence-cipher/gradlew b/exercises/practice/rail-fence-cipher/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/rail-fence-cipher/gradlew +++ b/exercises/practice/rail-fence-cipher/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/rail-fence-cipher/gradlew.bat b/exercises/practice/rail-fence-cipher/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/rail-fence-cipher/gradlew.bat +++ b/exercises/practice/rail-fence-cipher/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/rail-fence-cipher/src/test/java/RailFenceCipherTest.java b/exercises/practice/rail-fence-cipher/src/test/java/RailFenceCipherTest.java index da51a090d..c18e6dd32 100644 --- a/exercises/practice/rail-fence-cipher/src/test/java/RailFenceCipherTest.java +++ b/exercises/practice/rail-fence-cipher/src/test/java/RailFenceCipherTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -8,6 +9,7 @@ public class RailFenceCipherTest { private RailFenceCipher railFenceCipher; @Test + @DisplayName("encode with two rails") public void encodeWithTwoRails() { railFenceCipher = new RailFenceCipher(2); assertThat(railFenceCipher.getEncryptedData("XOXOXOXOXOXOXOXOXO")) @@ -16,6 +18,7 @@ public void encodeWithTwoRails() { @Disabled("Remove to run test") @Test + @DisplayName("encode with three rails") public void encodeWithThreeRails() { railFenceCipher = new RailFenceCipher(3); assertThat(railFenceCipher.getEncryptedData("WEAREDISCOVEREDFLEEATONCE")) @@ -24,6 +27,7 @@ public void encodeWithThreeRails() { @Disabled("Remove to run test") @Test + @DisplayName("encode with ending in the middle") public void encodeWithEndingInTheMiddle() { railFenceCipher = new RailFenceCipher(4); assertThat(railFenceCipher.getEncryptedData("EXERCISES")) @@ -32,6 +36,7 @@ public void encodeWithEndingInTheMiddle() { @Disabled("Remove to run test") @Test + @DisplayName("decode with three rails") public void decodeWithThreeRails() { railFenceCipher = new RailFenceCipher(3); assertThat(railFenceCipher.getDecryptedData("TEITELHDVLSNHDTISEIIEA")) @@ -40,6 +45,7 @@ public void decodeWithThreeRails() { @Disabled("Remove to run test") @Test + @DisplayName("decode with five rails") public void decodeWithFiveRails() { railFenceCipher = new RailFenceCipher(5); assertThat(railFenceCipher.getDecryptedData("EIEXMSMESAORIWSCE")) @@ -48,6 +54,7 @@ public void decodeWithFiveRails() { @Disabled("Remove to run test") @Test + @DisplayName("decode with six rails") public void decodeWithSixRails() { railFenceCipher = new RailFenceCipher(6); assertThat(railFenceCipher.getDecryptedData("133714114238148966225439541018335470986172518171757571896261")) diff --git a/exercises/practice/raindrops/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/raindrops/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/raindrops/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/raindrops/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/raindrops/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/raindrops/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/raindrops/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/raindrops/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/raindrops/gradlew b/exercises/practice/raindrops/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/raindrops/gradlew +++ b/exercises/practice/raindrops/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/raindrops/gradlew.bat b/exercises/practice/raindrops/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/raindrops/gradlew.bat +++ b/exercises/practice/raindrops/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/raindrops/src/test/java/RaindropConverterTest.java b/exercises/practice/raindrops/src/test/java/RaindropConverterTest.java index bd16e9ef5..6499f2144 100644 --- a/exercises/practice/raindrops/src/test/java/RaindropConverterTest.java +++ b/exercises/practice/raindrops/src/test/java/RaindropConverterTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -8,108 +9,126 @@ public class RaindropConverterTest { private RaindropConverter raindropConverter = new RaindropConverter(); @Test + @DisplayName("the sound for 1 is 1") public void soundFor1Is1() { assertThat(raindropConverter.convert(1)).isEqualTo("1"); } @Disabled("Remove to run test") @Test + @DisplayName("the sound for 3 is Pling") public void soundFor3IsPling() { assertThat(raindropConverter.convert(3)).isEqualTo("Pling"); } @Disabled("Remove to run test") @Test + @DisplayName("the sound for 5 is Plang") public void soundFor5IsPlang() { assertThat(raindropConverter.convert(5)).isEqualTo("Plang"); } @Disabled("Remove to run test") @Test + @DisplayName("the sound for 7 is Plong") public void soundFor7IsPlong() { assertThat(raindropConverter.convert(7)).isEqualTo("Plong"); } @Disabled("Remove to run test") @Test + @DisplayName("the sound for 6 is Pling as it has a factor 3") public void soundFor6IsPlingAsItHasFactor3() { assertThat(raindropConverter.convert(6)).isEqualTo("Pling"); } @Disabled("Remove to run test") @Test + @DisplayName("2 to the power 3 does not make a raindrop sound as 3 is the exponent not the base") public void noSoundFor2Cubed() { assertThat(raindropConverter.convert(8)).isEqualTo("8"); } @Disabled("Remove to run test") @Test + @DisplayName("the sound for 9 is Pling as it has a factor 3") public void soundFor9IsPlingAsItHasFactor3() { assertThat(raindropConverter.convert(9)).isEqualTo("Pling"); } @Disabled("Remove to run test") @Test + @DisplayName("the sound for 10 is Plang as it has a factor 5") public void soundFor10IsPlangAsItHasFactor5() { assertThat(raindropConverter.convert(10)).isEqualTo("Plang"); } @Disabled("Remove to run test") @Test + @DisplayName("the sound for 14 is Plong as it has a factor of 7") public void soundFor14IsPlongAsItHasFactor7() { assertThat(raindropConverter.convert(14)).isEqualTo("Plong"); } @Disabled("Remove to run test") @Test + @DisplayName("the sound for 15 is PlingPlang as it has factors 3 and 5") public void soundFor15IsPlingPlangAsItHasFactors3And5() { assertThat(raindropConverter.convert(15)).isEqualTo("PlingPlang"); } @Disabled("Remove to run test") @Test + @DisplayName("the sound for 21 is PlingPlong as it has factors 3 and 7") public void soundFor21IsPlingPlongAsItHasFactors3And7() { assertThat(raindropConverter.convert(21)).isEqualTo("PlingPlong"); } @Disabled("Remove to run test") @Test + @DisplayName("the sound for 25 is Plang as it has a factor 5") public void soundFor25IsPlangAsItHasFactor5() { assertThat(raindropConverter.convert(25)).isEqualTo("Plang"); } @Disabled("Remove to run test") @Test + @DisplayName("the sound for 27 is Pling as it has a factor 3") public void soundFor27IsPlingAsItHasFactor3() { assertThat(raindropConverter.convert(27)).isEqualTo("Pling"); } @Disabled("Remove to run test") @Test + @DisplayName("the sound for 35 is PlangPlong as it has factors 5 and 7") public void soundFor35IsPlangPlongAsItHasFactors5And7() { assertThat(raindropConverter.convert(35)).isEqualTo("PlangPlong"); } @Disabled("Remove to run test") @Test + @DisplayName("the sound for 49 is Plong as it has a factor 7") public void soundFor49IsPlongAsItHasFactor7() { assertThat(raindropConverter.convert(49)).isEqualTo("Plong"); } @Disabled("Remove to run test") @Test + @DisplayName("the sound for 52 is 52") public void noSoundFor52() { assertThat(raindropConverter.convert(52)).isEqualTo("52"); } @Disabled("Remove to run test") @Test + @DisplayName("the sound for 105 is PlingPlangPlong as it has factors 3, 5 and 7") public void soundFor105IsPlingPlangPlongAsItHasFactors3And5And7() { assertThat(raindropConverter.convert(105)).isEqualTo("PlingPlangPlong"); } @Disabled("Remove to run test") @Test + @DisplayName("the sound for 3125 is Plang as it has a factor 5") public void soundFor3125IsPlangAsItHasFactor5() { assertThat(raindropConverter.convert(3125)).isEqualTo("Plang"); } diff --git a/exercises/practice/rate-limiter/.docs/instructions.md b/exercises/practice/rate-limiter/.docs/instructions.md new file mode 100644 index 000000000..1e229cd6e --- /dev/null +++ b/exercises/practice/rate-limiter/.docs/instructions.md @@ -0,0 +1,23 @@ +# Instructions + +Your task is to build a fixed‑window rate limiter. + +Imagine a single server connected to one or more clients. +A client sends a request, the server does some work, and returns a response. +But processing takes time. +If a client sends too many requests too quickly, the server can become overwhelmed — everything slows down or fails. + +A rate limiter is a small component that decides whether to allow or reject a request based on how frequently that client has been making requests. +Different strategies exist; in this exercise you’ll implement a fixed‑window rate limiter. + +Fixed‑window rate limiting groups time into equal‑length windows (for example, every 10 seconds) and allows up to a certain number of requests within each window for each client. +Once the window resets, the allowance refreshes for the next window. +Each client is tracked separately, so another client can make requests within that same period. + +For example, consider a rate limiter configured to limit 2 requests per 10 seconds per client. +Lets say a client sends a request: + +- Being its first request, the request is permitted. +- A second request within 10 seconds after the first one is also permitted. +- However, further requests after that would be denied _until_ at least 10 seconds has elapsed since the first request. +- If a second client sends its first request within 10 seconds with of the first client's first request, it would also be permitted, _regardless_ of whether the first client has sent a second request. diff --git a/exercises/practice/rate-limiter/.meta/config.json b/exercises/practice/rate-limiter/.meta/config.json new file mode 100644 index 000000000..252db1567 --- /dev/null +++ b/exercises/practice/rate-limiter/.meta/config.json @@ -0,0 +1,24 @@ +{ + "authors": [ + "andreatanky" + ], + "files": { + "solution": [ + "src/main/java/RateLimiter.java" + ], + "test": [ + "src/test/java/RateLimiterTest.java" + ], + "example": [ + ".meta/src/reference/java/RateLimiter.java", + ".meta/src/reference/java/TimeSource.java" + ], + "editor": [ + "src/main/java/TimeSource.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Practice stateful logic and time handling by implementing a fixed-window rate limiter" +} diff --git a/exercises/practice/rate-limiter/.meta/src/reference/java/RateLimiter.java b/exercises/practice/rate-limiter/.meta/src/reference/java/RateLimiter.java new file mode 100644 index 000000000..a3cebe23c --- /dev/null +++ b/exercises/practice/rate-limiter/.meta/src/reference/java/RateLimiter.java @@ -0,0 +1,49 @@ +import java.time.Duration; +import java.time.Instant; +import java.util.HashMap; +import java.util.Map; + +public class RateLimiter { + + private static final class WindowState { + Instant windowStart; + int usedCount; + + WindowState(Instant windowStart, int usedCount) { + this.windowStart = windowStart; + this.usedCount = usedCount; + } + } + + private final int limit; + private final Duration windowSize; + private final TimeSource timeSource; + private final Map states = new HashMap<>(); + + public RateLimiter(int limit, Duration windowSize, TimeSource timeSource) { + this.limit = limit; + this.windowSize = windowSize; + this.timeSource = timeSource; + } + + public boolean allow(K clientId) { + Instant now = timeSource.now(); + + WindowState s = states.get(clientId); + if (s == null) { + s = new WindowState(now, 0); + states.put(clientId, s); + } + + if (!now.isBefore(s.windowStart.plus(windowSize))) { + s.windowStart = now; + s.usedCount = 0; + } + + if (s.usedCount < limit) { + s.usedCount += 1; + return true; + } + return false; + } +} diff --git a/exercises/practice/rate-limiter/.meta/src/reference/java/TimeSource.java b/exercises/practice/rate-limiter/.meta/src/reference/java/TimeSource.java new file mode 100644 index 000000000..db3bc2a86 --- /dev/null +++ b/exercises/practice/rate-limiter/.meta/src/reference/java/TimeSource.java @@ -0,0 +1,18 @@ +import java.time.Duration; +import java.time.Instant; + +public class TimeSource { + private Instant now; + + public TimeSource(Instant start) { + this.now = start; + } + + public Instant now() { + return now; + } + + public void advance(Duration d) { + this.now = this.now.plus(d); + } +} diff --git a/exercises/practice/rate-limiter/build.gradle b/exercises/practice/rate-limiter/build.gradle new file mode 100644 index 000000000..d28f35dee --- /dev/null +++ b/exercises/practice/rate-limiter/build.gradle @@ -0,0 +1,25 @@ +plugins { + id "java" +} + +repositories { + mavenCentral() +} + +dependencies { + testImplementation platform("org.junit:junit-bom:5.10.0") + testImplementation "org.junit.jupiter:junit-jupiter" + testImplementation "org.assertj:assertj-core:3.25.1" + + testRuntimeOnly "org.junit.platform:junit-platform-launcher" +} + +test { + useJUnitPlatform() + + testLogging { + exceptionFormat = "full" + showStandardStreams = true + events = ["passed", "failed", "skipped"] + } +} diff --git a/exercises/practice/rate-limiter/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/rate-limiter/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..f8e1ee312 Binary files /dev/null and b/exercises/practice/rate-limiter/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/rate-limiter/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/rate-limiter/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..4d97ea344 --- /dev/null +++ b/exercises/practice/rate-limiter/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/exercises/practice/rate-limiter/gradlew b/exercises/practice/rate-limiter/gradlew new file mode 100755 index 000000000..adff685a0 --- /dev/null +++ b/exercises/practice/rate-limiter/gradlew @@ -0,0 +1,248 @@ +#!/bin/sh + +# +# Copyright © 2015 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/exercises/practice/rate-limiter/gradlew.bat b/exercises/practice/rate-limiter/gradlew.bat new file mode 100644 index 000000000..c4bdd3ab8 --- /dev/null +++ b/exercises/practice/rate-limiter/gradlew.bat @@ -0,0 +1,93 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/exercises/practice/rate-limiter/src/main/java/RateLimiter.java b/exercises/practice/rate-limiter/src/main/java/RateLimiter.java new file mode 100644 index 000000000..8a28ed946 --- /dev/null +++ b/exercises/practice/rate-limiter/src/main/java/RateLimiter.java @@ -0,0 +1,13 @@ +import java.time.Duration; +import java.time.Instant; + +public class RateLimiter { + + public RateLimiter(int limit, Duration windowSize, TimeSource timeSource) { + throw new UnsupportedOperationException("Delete this statement and write your own implementation."); + } + + public boolean allow(K clientId) { + throw new UnsupportedOperationException("Delete this statement and write your own implementation."); + } +} diff --git a/exercises/practice/rate-limiter/src/main/java/TimeSource.java b/exercises/practice/rate-limiter/src/main/java/TimeSource.java new file mode 100644 index 000000000..bc2c998d3 --- /dev/null +++ b/exercises/practice/rate-limiter/src/main/java/TimeSource.java @@ -0,0 +1,21 @@ +import java.time.Duration; +import java.time.Instant; + +/** + * NOTE: There is no need to change this file and is treated as read only by the Exercism test runners. + */ +public class TimeSource { + private Instant now; + + public TimeSource(Instant start) { + this.now = start; + } + + public Instant now() { + return now; + } + + public void advance(Duration d) { + this.now = this.now.plus(d); + } +} diff --git a/exercises/practice/rate-limiter/src/test/java/RateLimiterTest.java b/exercises/practice/rate-limiter/src/test/java/RateLimiterTest.java new file mode 100644 index 000000000..c740b4bf3 --- /dev/null +++ b/exercises/practice/rate-limiter/src/test/java/RateLimiterTest.java @@ -0,0 +1,194 @@ +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import java.time.Duration; +import java.time.Instant; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; + +class RateLimiterTest { + + @Test + @DisplayName("Allows up to window limit") + void allowsUpToLimit() { + TimeSource clock = new TimeSource(Instant.EPOCH); + RateLimiter limiter = new RateLimiter<>(3, Duration.ofNanos(10_000L), clock); + + assertThat(limiter.allow("A")).isTrue(); + clock.advance(Duration.ofNanos(1L)); + assertThat(limiter.allow("A")).isTrue(); + assertThat(limiter.allow("A")).isTrue(); + assertThat(limiter.allow("A")).isFalse(); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("Denies requests just before boundary") + void denyCloseToBoundary() { + TimeSource clock = new TimeSource(Instant.EPOCH); + RateLimiter limiter = new RateLimiter<>(2, Duration.ofNanos(10_000L), clock); + + assertThat(limiter.allow("A")).isTrue(); + assertThat(limiter.allow("A")).isTrue(); + assertThat(limiter.allow("A")).isFalse(); + + // Just before boundary: still same window + clock.advance(Duration.ofNanos(9_999L)); + assertThat(limiter.allow("A")).isFalse(); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("Allows first request at exact boundary") + void allowsNewBoundary() { + TimeSource clock = new TimeSource(Instant.EPOCH); + RateLimiter limiter = new RateLimiter<>(2, Duration.ofNanos(10_000L), clock); + + assertThat(limiter.allow("A")).isTrue(); + assertThat(limiter.allow("A")).isTrue(); + assertThat(limiter.allow("A")).isFalse(); + + // At exact boundary: new window + clock.advance(Duration.ofNanos(10_000L)); + assertThat(limiter.allow("A")).isTrue(); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("Resets at boundary, then counts within window") + void continuesCountingWithinWindowAfterBoundaryReset() { + TimeSource clock = new TimeSource(Instant.EPOCH); + RateLimiter limiter = new RateLimiter<>(2, Duration.ofNanos(5_000L), clock); + + assertThat(limiter.allow("key")).isTrue(); + clock.advance(Duration.ofNanos(1L)); + assertThat(limiter.allow("key")).isTrue(); + assertThat(limiter.allow("key")).isFalse(); + + // Jump to next window + clock.advance(Duration.ofNanos(5_000L)); + assertThat(limiter.allow("key")).isTrue(); + assertThat(limiter.allow("key")).isTrue(); + assertThat(limiter.allow("key")).isFalse(); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("Independent counters/windows per key") + void separateKeysHaveIndependentCountersAndWindows() { + TimeSource clock = new TimeSource(Instant.EPOCH.plusNanos(42L)); + RateLimiter limiter = new RateLimiter<>(1, Duration.ofNanos(100L), clock); + + assertThat(limiter.allow("A")).isTrue(); + // Advance a tiny amount to model time moving between requests + clock.advance(Duration.ofNanos(1L)); + assertThat(limiter.allow("A")).isFalse(); + assertThat(limiter.allow("B")).isTrue(); // independent key + assertThat(limiter.allow("B")).isFalse(); + + clock.advance(Duration.ofNanos(100L)); // new window for both at boundary + assertThat(limiter.allow("A")).isTrue(); + assertThat(limiter.allow("B")).isTrue(); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("Long gaps reset window") + void longGapsResetWindow() { + TimeSource clock = new TimeSource(Instant.EPOCH.plusNanos(1_000L)); + RateLimiter limiter = new RateLimiter<>(2, Duration.ofNanos(50L), clock); + + assertThat(limiter.allow("X")).isTrue(); + clock.advance(Duration.ofNanos(1L)); + assertThat(limiter.allow("X")).isTrue(); + assertThat(limiter.allow("X")).isFalse(); + + // Advance several windows worth + clock.advance(Duration.ofNanos(1_000L)); + assertThat(limiter.allow("X")).isTrue(); + assertThat(limiter.allow("X")).isTrue(); + assertThat(limiter.allow("X")).isFalse(); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("Exact boundary starts a new window each time") + void exactBoundaryIsNewWindowEveryTime() { + TimeSource clock = new TimeSource(Instant.EPOCH); + RateLimiter limiter = new RateLimiter<>(1, Duration.ofNanos(10L), clock); + + assertThat(limiter.allow("k")).isTrue(); + assertThat(limiter.allow("k")).isFalse(); + + // Move exactly to boundary repeatedly; each time should allow once + for (int i = 0; i < 5; i++) { + clock.advance(Duration.ofNanos(10L)); + assertThat(limiter.allow("k")).isTrue(); + assertThat(limiter.allow("k")).isFalse(); + } + } + + + @Disabled("Remove to run test") + @Test + @DisplayName("Supports UUID keys") + void supportsUuidKeys() { + TimeSource clock = new TimeSource(Instant.EPOCH); + RateLimiter limiter = new RateLimiter<>(1, Duration.ofSeconds(1L), clock); + + UUID a = UUID.fromString("00000000-0000-0000-0000-000000000001"); + UUID b = UUID.fromString("00000000-0000-0000-0000-000000000002"); + + assertThat(limiter.allow(a)).isTrue(); + assertThat(limiter.allow(a)).isFalse(); + // Advance slightly so the second client's window anchors later + clock.advance(Duration.ofMillis(1L)); + assertThat(limiter.allow(b)).isTrue(); + assertThat(limiter.allow(b)).isFalse(); + + // Advance exactly one second to hit the window boundary + clock.advance(Duration.ofSeconds(1L)); + assertThat(limiter.allow(a)).isTrue(); + assertThat(limiter.allow(b)).isTrue(); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("Supports Integer keys") + void supportsIntegerKeys() { + TimeSource clock = new TimeSource(Instant.EPOCH); + RateLimiter limiter = new RateLimiter<>(1, Duration.ofNanos(100L), clock); + + assertThat(limiter.allow(42)).isTrue(); + assertThat(limiter.allow(42)).isFalse(); + clock.advance(Duration.ofNanos(1L)); + assertThat(limiter.allow(84)).isTrue(); // independent key of different type + assertThat(limiter.allow(84)).isFalse(); + + clock.advance(Duration.ofNanos(100L)); // boundary resets both + assertThat(limiter.allow(42)).isTrue(); + assertThat(limiter.allow(84)).isTrue(); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("Supports Long keys") + void supportsLongKeys() { + TimeSource clock = new TimeSource(Instant.EPOCH); + RateLimiter limiter = new RateLimiter<>(2, Duration.ofNanos(50L), clock); + + assertThat(limiter.allow(1L)).isTrue(); + assertThat(limiter.allow(1L)).isTrue(); + assertThat(limiter.allow(1L)).isFalse(); + + clock.advance(Duration.ofNanos(1L)); + assertThat(limiter.allow(2L)).isTrue(); // independent key + assertThat(limiter.allow(2L)).isTrue(); + assertThat(limiter.allow(2L)).isFalse(); + + clock.advance(Duration.ofNanos(50L)); + assertThat(limiter.allow(1L)).isTrue(); + assertThat(limiter.allow(2L)).isTrue(); + } +} diff --git a/exercises/practice/rational-numbers/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/rational-numbers/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/rational-numbers/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/rational-numbers/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/rational-numbers/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/rational-numbers/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/rational-numbers/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/rational-numbers/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/rational-numbers/gradlew b/exercises/practice/rational-numbers/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/rational-numbers/gradlew +++ b/exercises/practice/rational-numbers/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/rational-numbers/gradlew.bat b/exercises/practice/rational-numbers/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/rational-numbers/gradlew.bat +++ b/exercises/practice/rational-numbers/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/rational-numbers/src/test/java/RationalTest.java b/exercises/practice/rational-numbers/src/test/java/RationalTest.java index 8a26c474a..91f8b3e49 100644 --- a/exercises/practice/rational-numbers/src/test/java/RationalTest.java +++ b/exercises/practice/rational-numbers/src/test/java/RationalTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -17,6 +18,7 @@ private void assertDoublesEqual(double x, double y) { // Tests @Test + @DisplayName("Add two positive rational numbers") public void testAddTwoPositiveRationalNumbers() { Rational expected = new Rational(7, 6); Rational actual = new Rational(1, 2).add(new Rational(2, 3)); @@ -25,6 +27,7 @@ public void testAddTwoPositiveRationalNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("Add a positive rational number and a negative rational number") public void testAddAPositiveRationalNumberAndANegativeRationalNumber() { Rational expected = new Rational(-1, 6); Rational actual = new Rational(1, 2).add(new Rational(-2, 3)); @@ -33,6 +36,7 @@ public void testAddAPositiveRationalNumberAndANegativeRationalNumber() { @Disabled("Remove to run test") @Test + @DisplayName("Add two negative rational numbers") public void testAddTwoNegativeRationalNumbers() { Rational expected = new Rational(-7, 6); Rational actual = new Rational(-1, 2).add(new Rational(-2, 3)); @@ -41,6 +45,7 @@ public void testAddTwoNegativeRationalNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("Add a rational number to its additive inverse") public void testAddARationalNumberToItsAdditiveInverse() { Rational expected = new Rational(0, 1); Rational actual = new Rational(1, 2).add(new Rational(-1, 2)); @@ -49,6 +54,7 @@ public void testAddARationalNumberToItsAdditiveInverse() { @Disabled("Remove to run test") @Test + @DisplayName("Subtract two positive rational numbers") public void testSubtractTwoPositiveRationalNumbers() { Rational expected = new Rational(-1, 6); Rational actual = new Rational(1, 2).subtract(new Rational(2, 3)); @@ -57,6 +63,7 @@ public void testSubtractTwoPositiveRationalNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("Subtract a positive rational number and a negative rational number") public void testSubtractAPositiveRationalNumberAndANegativeRationalNumber() { Rational expected = new Rational(7, 6); Rational actual = new Rational(1, 2).subtract(new Rational(-2, 3)); @@ -65,6 +72,7 @@ public void testSubtractAPositiveRationalNumberAndANegativeRationalNumber() { @Disabled("Remove to run test") @Test + @DisplayName("Subtract two negative rational numbers") public void testSubtractTwoNegativeRationalNumbers() { Rational expected = new Rational(1, 6); Rational actual = new Rational(-1, 2).subtract(new Rational(-2, 3)); @@ -73,6 +81,7 @@ public void testSubtractTwoNegativeRationalNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("Subtract a rational number from itself") public void testSubtractARationalNumberFromItself() { Rational expected = new Rational(0, 1); Rational actual = new Rational(1, 2).subtract(new Rational(1, 2)); @@ -81,6 +90,7 @@ public void testSubtractARationalNumberFromItself() { @Disabled("Remove to run test") @Test + @DisplayName("Multiply two positive rational numbers") public void testMultiplyTwoPositiveRationalNumbers() { Rational expected = new Rational(1, 3); Rational actual = new Rational(1, 2).multiply(new Rational(2, 3)); @@ -89,6 +99,7 @@ public void testMultiplyTwoPositiveRationalNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("Multiply a negative rational number by a positive rational number") public void testMultiplyANegativeRationalNumberByAPositiveRationalNumber() { Rational expected = new Rational(-1, 3); Rational actual = new Rational(-1, 2).multiply(new Rational(2, 3)); @@ -97,6 +108,7 @@ public void testMultiplyANegativeRationalNumberByAPositiveRationalNumber() { @Disabled("Remove to run test") @Test + @DisplayName("Multiply two negative rational numbers") public void testMultiplyTwoNegativeRationalNumbers() { Rational expected = new Rational(1, 3); Rational actual = new Rational(-1, 2).multiply(new Rational(-2, 3)); @@ -105,6 +117,7 @@ public void testMultiplyTwoNegativeRationalNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("Multiply a rational number by its reciprocal") public void testMultiplyARationalNumberByItsReciprocal() { Rational expected = new Rational(1, 1); Rational actual = new Rational(1, 2).multiply(new Rational(2, 1)); @@ -113,6 +126,7 @@ public void testMultiplyARationalNumberByItsReciprocal() { @Disabled("Remove to run test") @Test + @DisplayName("Multiply a rational number by 1") public void testMultiplyARationalNumberByOne() { Rational expected = new Rational(1, 2); Rational actual = new Rational(1, 2).multiply(new Rational(1, 1)); @@ -121,6 +135,7 @@ public void testMultiplyARationalNumberByOne() { @Disabled("Remove to run test") @Test + @DisplayName("Multiply a rational number by 0") public void testMultiplyARationalNumberByZero() { Rational expected = new Rational(0, 1); Rational actual = new Rational(1, 2).multiply(new Rational(0, 1)); @@ -129,6 +144,7 @@ public void testMultiplyARationalNumberByZero() { @Disabled("Remove to run test") @Test + @DisplayName("Divide two positive rational numbers") public void testDivideTwoPositiveRationalNumbers() { Rational expected = new Rational(3, 4); Rational actual = new Rational(1, 2).divide(new Rational(2, 3)); @@ -137,6 +153,7 @@ public void testDivideTwoPositiveRationalNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("Divide a positive rational number by a negative rational number") public void testDivideAPositiveRationalNumberByANegativeRationalNumber() { Rational expected = new Rational(-3, 4); Rational actual = new Rational(1, 2).divide(new Rational(-2, 3)); @@ -145,6 +162,7 @@ public void testDivideAPositiveRationalNumberByANegativeRationalNumber() { @Disabled("Remove to run test") @Test + @DisplayName("Divide two negative rational numbers") public void testDivideTwoNegativeRationalNumbers() { Rational expected = new Rational(3, 4); Rational actual = new Rational(-1, 2).divide(new Rational(-2, 3)); @@ -153,6 +171,7 @@ public void testDivideTwoNegativeRationalNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("Divide a rational number by 1") public void testDivideARationalNumberByOne() { Rational expected = new Rational(1, 2); Rational actual = new Rational(1, 2).divide(new Rational(1, 1)); @@ -161,6 +180,7 @@ public void testDivideARationalNumberByOne() { @Disabled("Remove to run test") @Test + @DisplayName("Absolute value of a positive rational number") public void testAbsoluteValueOfAPositiveRationalNumber() { Rational expected = new Rational(1, 2); Rational actual = new Rational(1, 2).abs(); @@ -169,6 +189,7 @@ public void testAbsoluteValueOfAPositiveRationalNumber() { @Disabled("Remove to run test") @Test + @DisplayName("Absolute value of a positive rational number with negative numerator and denominator") public void testAbsoluteValueOfAPositiveRationalNumberWithNegativeNumeratorAndDenominator() { Rational expected = new Rational(1, 2); Rational actual = new Rational(-1, -2).abs(); @@ -177,6 +198,7 @@ public void testAbsoluteValueOfAPositiveRationalNumberWithNegativeNumeratorAndDe @Disabled("Remove to run test") @Test + @DisplayName("Absolute value of a negative rational number") public void testAbsoluteValueOfANegativeRationalNumber() { Rational expected = new Rational(1, 2); Rational actual = new Rational(-1, 2).abs(); @@ -185,6 +207,7 @@ public void testAbsoluteValueOfANegativeRationalNumber() { @Disabled("Remove to run test") @Test + @DisplayName("\"Absolute value of a negative rational number with negative denominator") public void testAbsoluteValueOfANegativeRationalNumberWithNegativeDenominator() { Rational expected = new Rational(1, 2); Rational actual = new Rational(1, -2).abs(); @@ -193,6 +216,7 @@ public void testAbsoluteValueOfANegativeRationalNumberWithNegativeDenominator() @Disabled("Remove to run test") @Test + @DisplayName("Absolute value of zero") public void testAbsoluteValueOfZero() { Rational expected = new Rational(0, 1); Rational actual = new Rational(0, 1).abs(); @@ -201,6 +225,7 @@ public void testAbsoluteValueOfZero() { @Disabled("Remove to run test") @Test + @DisplayName("Absolute value of a rational number is reduced to lowest terms") public void testAbsoluteValueOfARationalNumberIsReducedToLowestTerms() { Rational expected = new Rational(1, 2); Rational actual = new Rational(2, 4).abs(); @@ -209,6 +234,7 @@ public void testAbsoluteValueOfARationalNumberIsReducedToLowestTerms() { @Disabled("Remove to run test") @Test + @DisplayName("Raise a positive rational number to a positive integer power") public void testRaiseAPositiveRationalNumberToAPositiveIntegerPower() { Rational expected = new Rational(1, 8); Rational actual = new Rational(1, 2).pow(3); @@ -217,6 +243,7 @@ public void testRaiseAPositiveRationalNumberToAPositiveIntegerPower() { @Disabled("Remove to run test") @Test + @DisplayName("Raise a negative rational number to a positive integer power") public void testRaiseANegativeRationalNumberToAPositiveIntegerPower() { Rational expected = new Rational(-1, 8); Rational actual = new Rational(-1, 2).pow(3); @@ -225,6 +252,7 @@ public void testRaiseANegativeRationalNumberToAPositiveIntegerPower() { @Disabled("Remove to run test") @Test + @DisplayName("Raise a positive rational number to a negative integer power") public void testRaiseAPositiveRationalNumberToANegativeIntegerPower() { Rational expected = new Rational(25, 9); Rational actual = new Rational(3, 5).pow(-2); @@ -233,6 +261,7 @@ public void testRaiseAPositiveRationalNumberToANegativeIntegerPower() { @Disabled("Remove to run test") @Test + @DisplayName("\"Raise a negative rational number to an even negative integer power") public void testRaiseANegativeRationalNumberToAnEvenNegativeIntegerPower() { Rational expected = new Rational(25, 9); Rational actual = new Rational(-3, 5).pow(-2); @@ -241,6 +270,7 @@ public void testRaiseANegativeRationalNumberToAnEvenNegativeIntegerPower() { @Disabled("Remove to run test") @Test + @DisplayName("Raise a negative rational number to an odd negative integer power") public void testRaiseANegativeRationalNumberToAnOddNegativeIntegerPower() { Rational expected = new Rational(-125, 27); Rational actual = new Rational(-3, 5).pow(-3); @@ -249,6 +279,7 @@ public void testRaiseANegativeRationalNumberToAnOddNegativeIntegerPower() { @Disabled("Remove to run test") @Test + @DisplayName("Raise zero to an integer power") public void testRaiseZeroToAnIntegerPower() { Rational expected = new Rational(0, 1); Rational actual = new Rational(0, 1).pow(5); @@ -257,6 +288,7 @@ public void testRaiseZeroToAnIntegerPower() { @Disabled("Remove to run test") @Test + @DisplayName("Raise one to an integer power") public void testRaiseOneToAnIntegerPower() { Rational expected = new Rational(1, 1); Rational actual = new Rational(1, 1).pow(4); @@ -265,6 +297,7 @@ public void testRaiseOneToAnIntegerPower() { @Disabled("Remove to run test") @Test + @DisplayName("Raise a positive rational number to the power of zero") public void testRaiseAPositiveRationalNumberToThePowerOfZero() { Rational expected = new Rational(1, 1); Rational actual = new Rational(-1, 2).pow(0); @@ -273,6 +306,7 @@ public void testRaiseAPositiveRationalNumberToThePowerOfZero() { @Disabled("Remove to run test") @Test + @DisplayName("Raise a real number to a positive rational number") public void testRaiseARealNumberToAPositiveRationalNumber() { double expected = 16.0; double actual = new Rational(4, 3).exp(8.0); @@ -281,6 +315,7 @@ public void testRaiseARealNumberToAPositiveRationalNumber() { @Disabled("Remove to run test") @Test + @DisplayName("Raise a real number to a negative rational number") public void testRaiseARealNumberToANegativeRationalNumber() { double expected = 1.0 / 3; double actual = new Rational(-1, 2).exp(9); @@ -289,6 +324,7 @@ public void testRaiseARealNumberToANegativeRationalNumber() { @Disabled("Remove to run test") @Test + @DisplayName("Reduce a positive rational number to lowest terms") public void testReduceAPositiveRationalNumberToLowestTerms() { Rational expected = new Rational(1, 2); Rational actual = new Rational(2, 4); @@ -297,6 +333,7 @@ public void testReduceAPositiveRationalNumberToLowestTerms() { @Disabled("Remove to run test") @Test + @DisplayName("Reduce places the minus sign on the numerator") public void testReducePlacesTheMinusSignOnTheNumerator() { Rational expected = new Rational(-3, 4); Rational actual = new Rational(3, -4); @@ -305,6 +342,7 @@ public void testReducePlacesTheMinusSignOnTheNumerator() { @Disabled("Remove to run test") @Test + @DisplayName("Reduce a negative rational number to lowest terms") public void testReduceANegativeRationalNumberToLowestTerms() { Rational expected = new Rational(-2, 3); Rational actual = new Rational(-4, 6); @@ -313,6 +351,7 @@ public void testReduceANegativeRationalNumberToLowestTerms() { @Disabled("Remove to run test") @Test + @DisplayName("Reduce a rational number with a negative denominator to lowest terms") public void testReduceARationalNumberWithANegativeDenominatorToLowestTerms() { Rational expected = new Rational(-1, 3); Rational actual = new Rational(3, -9); @@ -321,6 +360,7 @@ public void testReduceARationalNumberWithANegativeDenominatorToLowestTerms() { @Disabled("Remove to run test") @Test + @DisplayName("Reduce zero to lowest terms") public void testReduceZeroToLowestTerms() { Rational expected = new Rational(0, 1); Rational actual = new Rational(0, 6); @@ -329,6 +369,7 @@ public void testReduceZeroToLowestTerms() { @Disabled("Remove to run test") @Test + @DisplayName("Reduce an integer to lowest terms") public void testReduceAnIntegerToLowestTerms() { Rational expected = new Rational(-2, 1); Rational actual = new Rational(-14, 7); @@ -337,6 +378,7 @@ public void testReduceAnIntegerToLowestTerms() { @Disabled("Remove to run test") @Test + @DisplayName("Reduce one to lowest terms") public void testReduceOneToLowestTerms() { Rational expected = new Rational(1, 1); Rational actual = new Rational(13, 13); diff --git a/exercises/practice/react/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/react/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/react/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/react/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/react/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/react/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/react/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/react/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/react/gradlew b/exercises/practice/react/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/react/gradlew +++ b/exercises/practice/react/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/react/gradlew.bat b/exercises/practice/react/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/react/gradlew.bat +++ b/exercises/practice/react/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/react/src/test/java/ReactTest.java b/exercises/practice/react/src/test/java/ReactTest.java index fd2047353..e7c18a063 100644 --- a/exercises/practice/react/src/test/java/ReactTest.java +++ b/exercises/practice/react/src/test/java/ReactTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.ArrayList; @@ -10,6 +11,7 @@ public class ReactTest { @Test + @DisplayName("input cells have a value") public void testInputCellHasValue() { var input = React.inputCell(10); @@ -18,6 +20,7 @@ public void testInputCellHasValue() { @Disabled("Remove to run") @Test + @DisplayName("an input cell's value can be set") public void testInputCellValueCanBeSet() { var input = React.inputCell(4); input.setValue(20); @@ -27,6 +30,7 @@ public void testInputCellValueCanBeSet() { @Disabled("Remove to run") @Test + @DisplayName("compute cells calculate initial value") public void testComputeCellCalculateInitialValue() { var input = React.inputCell(1); var output = React.computeCell(list -> list.get(0) + 1, List.of(input)); @@ -36,6 +40,7 @@ public void testComputeCellCalculateInitialValue() { @Disabled("Remove to run") @Test + @DisplayName("compute cells take inputs in the right order") public void testComputeCellsInTheRightOrder() { var first = React.inputCell(1); var second = React.inputCell(2); @@ -46,6 +51,7 @@ public void testComputeCellsInTheRightOrder() { @Disabled("Remove to run") @Test + @DisplayName("compute cells update value when dependencies are changed") public void testComputeCellsUpdateValueWhenDependenciesAreChanged() { var input = React.inputCell(1); var output = React.computeCell(list -> list.get(0) + 1, List.of(input)); @@ -56,6 +62,7 @@ public void testComputeCellsUpdateValueWhenDependenciesAreChanged() { @Disabled("Remove to run") @Test + @DisplayName("compute cells can depend on other compute cells") public void testComputeCellsCanDependOnOtherComputeCells() { var input = React.inputCell(1); var timesTwo = React.computeCell(list -> list.get(0) * 2, List.of(input)); @@ -70,6 +77,7 @@ public void testComputeCellsCanDependOnOtherComputeCells() { @Disabled("Remove to run") @Test + @DisplayName("compute cells fire callbacks") public void testComputeCellsFireCallbacks() { var input = React.inputCell(1); var output = React.computeCell(list -> list.get(0) + 1, List.of(input)); @@ -83,6 +91,7 @@ public void testComputeCellsFireCallbacks() { @Disabled("Remove to run") @Test + @DisplayName("callback cells only fire on change") public void testCallbacksOnlyFireOnChange() { var input = React.inputCell(1); var output = React.computeCell(list -> list.get(0) < 3 ? 111 : 222, List.of(input)); @@ -99,6 +108,7 @@ public void testCallbacksOnlyFireOnChange() { @Disabled("Remove to run") @Test + @DisplayName("callbacks do not report already reported values") public void testCallbacksDoNotReportAlreadyReportedValues() { var input = React.inputCell(1); var output = React.computeCell(list -> list.get(0) + 1, List.of(input)); @@ -116,6 +126,7 @@ public void testCallbacksDoNotReportAlreadyReportedValues() { @Disabled("Remove to run") @Test + @DisplayName("callbacks can fire from multiple cells") public void testCallbacksCanFireFromMultipleCells() { var input = React.inputCell(1); var plusOne = React.computeCell(list -> list.get(0) + 1, List.of(input)); @@ -134,6 +145,7 @@ public void testCallbacksCanFireFromMultipleCells() { @Disabled("Remove to run") @Test + @DisplayName("callbacks can be added and removed") public void testCallbacksCanBeAddedAndRemoved() { var input = React.inputCell(11); var output = React.computeCell(list -> list.get(0) + 1, List.of(input)); @@ -166,6 +178,7 @@ public void testCallbacksCanBeAddedAndRemoved() { @Disabled("Remove to run") @Test + @DisplayName("removing a callback multiple times doesn't interfere with other callbacks") public void testRemovingACallbackMultipleTimesDoesntInterfereWithOtherCallbacks() { var input = React.inputCell(1); var output = React.computeCell(list -> list.get(0) + 1, List.of(input)); @@ -189,6 +202,7 @@ public void testRemovingACallbackMultipleTimesDoesntInterfereWithOtherCallbacks( @Disabled("Remove to run") @Test + @DisplayName("callbacks should only be called once even if multiple dependencies change") public void testCallbacksShouldOnlyBeCalledOnceEvenIfMultipleDependenciesChange() { var input = React.inputCell(1); var plusOne = React.computeCell(list -> list.get(0) + 1, List.of(input)); @@ -205,6 +219,7 @@ public void testCallbacksShouldOnlyBeCalledOnceEvenIfMultipleDependenciesChange( @Disabled("Remove to run") @Test + @DisplayName("callbacks should not be called if dependencies change but output value doesn't change") public void testCallbacksShouldNotBeCalledIfDependenciesChangeButOutputValueDoesntChange() { var input = React.inputCell(1); var plusOne = React.computeCell(list -> list.get(0) + 1, List.of(input)); diff --git a/exercises/practice/rectangles/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/rectangles/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/rectangles/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/rectangles/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/rectangles/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/rectangles/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/rectangles/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/rectangles/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/rectangles/gradlew b/exercises/practice/rectangles/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/rectangles/gradlew +++ b/exercises/practice/rectangles/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/rectangles/gradlew.bat b/exercises/practice/rectangles/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/rectangles/gradlew.bat +++ b/exercises/practice/rectangles/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/rectangles/src/test/java/RectangleCounterTest.java b/exercises/practice/rectangles/src/test/java/RectangleCounterTest.java index 816c2b7aa..c1f665729 100644 --- a/exercises/practice/rectangles/src/test/java/RectangleCounterTest.java +++ b/exercises/practice/rectangles/src/test/java/RectangleCounterTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -14,6 +15,7 @@ public void setUp() { } @Test + @DisplayName("no rows") public void testInputWithNoRowsContainsNoRectangles() { String[] inputGrid = new String[]{}; @@ -22,6 +24,7 @@ public void testInputWithNoRowsContainsNoRectangles() { @Disabled("Remove to run test") @Test + @DisplayName("no columns") public void testInputWithNoColumnsContainsNoRectangles() { String[] inputGrid = new String[]{""}; @@ -30,6 +33,7 @@ public void testInputWithNoColumnsContainsNoRectangles() { @Disabled("Remove to run test") @Test + @DisplayName("no rectangles") public void testNonTrivialInputWithNoRectangles() { String[] inputGrid = new String[]{" "}; @@ -38,6 +42,7 @@ public void testNonTrivialInputWithNoRectangles() { @Disabled("Remove to run test") @Test + @DisplayName("one rectangle") public void testInputWithOneRectangle() { String[] inputGrid = new String[]{ "+-+", @@ -50,6 +55,7 @@ public void testInputWithOneRectangle() { @Disabled("Remove to run test") @Test + @DisplayName("two rectangles without shared parts") public void testInputWithTwoRectanglesWithoutSharedEdges() { String[] inputGrid = new String[]{ " +-+", @@ -64,6 +70,7 @@ public void testInputWithTwoRectanglesWithoutSharedEdges() { @Disabled("Remove to run test") @Test + @DisplayName("five rectangles with shared parts") public void testInputWithFiveRectanglesWithSharedEdges() { String[] inputGrid = new String[]{ " +-+", @@ -78,6 +85,7 @@ public void testInputWithFiveRectanglesWithSharedEdges() { @Disabled("Remove to run test") @Test + @DisplayName("rectangle of height 1 is counted") public void testThatRectangleOfHeightOneIsCounted() { String[] inputGrid = new String[]{ "+--+", @@ -89,6 +97,7 @@ public void testThatRectangleOfHeightOneIsCounted() { @Disabled("Remove to run test") @Test + @DisplayName("rectangle of width 1 is counted") public void testThatRectangleOfWidthOneIsCounted() { String[] inputGrid = new String[]{ "++", @@ -101,6 +110,7 @@ public void testThatRectangleOfWidthOneIsCounted() { @Disabled("Remove to run test") @Test + @DisplayName("1x1 square is counted") public void testThatOneByOneSquareIsCounted() { String[] inputGrid = new String[]{ "++", @@ -112,6 +122,7 @@ public void testThatOneByOneSquareIsCounted() { @Disabled("Remove to run test") @Test + @DisplayName("only complete rectangles are counted") public void testThatIncompleteRectanglesAreNotCounted() { String[] inputGrid = new String[]{ " +-+", @@ -126,6 +137,7 @@ public void testThatIncompleteRectanglesAreNotCounted() { @Disabled("Remove to run test") @Test + @DisplayName("rectangles can be of different sizes") public void testThatRectanglesOfDifferentSizesAreAllCounted() { String[] inputGrid = new String[]{ "+------+----+", @@ -140,6 +152,7 @@ public void testThatRectanglesOfDifferentSizesAreAllCounted() { @Disabled("Remove to run test") @Test + @DisplayName("corner is required for a rectangle to be complete") public void testThatIntersectionsWithoutCornerCharacterDoNotCountAsRectangleCorners() { String[] inputGrid = new String[]{ "+------+----+", @@ -154,6 +167,7 @@ public void testThatIntersectionsWithoutCornerCharacterDoNotCountAsRectangleCorn @Disabled("Remove to run test") @Test + @DisplayName("large input with many rectangles") public void testLargeInputWithManyRectangles() { String[] inputGrid = new String[]{ "+---+--+----+", @@ -171,6 +185,7 @@ public void testLargeInputWithManyRectangles() { @Disabled("Remove to run test") @Test + @DisplayName("rectangles must have four sides") public void testRectanglesMustHaveFourSides() { String[] inputGrid = new String[]{ "+-+ +-+", diff --git a/exercises/practice/relative-distance/.docs/instructions.md b/exercises/practice/relative-distance/.docs/instructions.md new file mode 100644 index 000000000..9046aee7c --- /dev/null +++ b/exercises/practice/relative-distance/.docs/instructions.md @@ -0,0 +1,39 @@ +# Instructions + +Your task is to determine the degree of separation between two individuals in a family tree. +This is similar to the pop culture idea that every Hollywood actor is [within six degrees of Kevin Bacon][six-bacons]. + +- You will be given an input, with all parent names and their children. +- Each name is unique, a child _can_ have one or two parents. +- The degree of separation is defined as the shortest number of connections from one person to another. +- If two individuals are not connected, return a value that represents "no known relationship." + Please see the test cases for the actual implementation. + +## Example + +Given the following family tree: + +```text + ┌──────────┐ ┌──────────┐ ┌───────────┐ + │ Helena │ │ Erdős ├─────┤ Shusaku │ + └───┬───┬──┘ └─────┬────┘ └────┬──────┘ + ┌───┘ └───────┐ └───────┬───────┘ +┌─────┴────┐ ┌────┴───┐ ┌─────┴────┐ +│ Isla ├─────┤ Tariq │ │ Kevin │ +└────┬─────┘ └────┬───┘ └──────────┘ + │ │ +┌────┴────┐ ┌────┴───┐ +│ Uma │ │ Morphy │ +└─────────┘ └────────┘ +``` + +The degree of separation between Tariq and Uma is 2 (Tariq → Isla → Uma). +There's no known relationship between Isla and Kevin, as there is no connection in the given data. +The degree of separation between Uma and Isla is 1. + +~~~~exercism/note +Isla and Tariq are siblings and have a separation of 1. +Similarly, this implementation would report a separation of 2 from you to your father's brother. +~~~~ + +[six-bacons]: https://en.m.wikipedia.org/wiki/Six_Degrees_of_Kevin_Bacon diff --git a/exercises/practice/relative-distance/.docs/introduction.md b/exercises/practice/relative-distance/.docs/introduction.md new file mode 100644 index 000000000..34073b40a --- /dev/null +++ b/exercises/practice/relative-distance/.docs/introduction.md @@ -0,0 +1,12 @@ +# Introduction + +You've been hired to develop **Noble Knots**, the hottest new dating app for nobility! +With centuries of royal intermarriage, things have gotten… _complicated_. +To avoid any _oops-we're-twins_ situations, your job is to build a system that checks how closely two people are related. + +Noble Knots is inspired by Iceland's "[Islendinga-App][islendiga-app]," which is backed up by a database that traces all known family connections between Icelanders from the time of the settlement of Iceland. +Your algorithm will determine the **degree of separation** between two individuals in the royal family tree. + +Will your app help crown a perfect match? + +[islendiga-app]: https://web.archive.org/web/20250816223614/http://www.islendingaapp.is/information-in-english/ diff --git a/exercises/practice/relative-distance/.meta/config.json b/exercises/practice/relative-distance/.meta/config.json new file mode 100644 index 000000000..c6b2cc422 --- /dev/null +++ b/exercises/practice/relative-distance/.meta/config.json @@ -0,0 +1,22 @@ +{ + "authors": [ + "BNAndras" + ], + "files": { + "solution": [ + "src/main/java/RelativeDistance.java" + ], + "test": [ + "src/test/java/RelativeDistanceTest.java" + ], + "example": [ + ".meta/src/reference/java/RelativeDistance.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Given a family tree, calculate the degree of separation.", + "source": "vaeng", + "source_url": "https://github.com/exercism/problem-specifications/pull/2537" +} diff --git a/exercises/practice/relative-distance/.meta/src/reference/java/RelativeDistance.java b/exercises/practice/relative-distance/.meta/src/reference/java/RelativeDistance.java new file mode 100644 index 000000000..3d170879b --- /dev/null +++ b/exercises/practice/relative-distance/.meta/src/reference/java/RelativeDistance.java @@ -0,0 +1,68 @@ +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Queue; + +class RelativeDistance { + + private final Map> graph; + + RelativeDistance(Map> familyTree) { + final HashMap> connections = new HashMap<>(); + + for (Map.Entry> entry : familyTree.entrySet()) { + String parent = entry.getKey(); + List children = entry.getValue(); + + connections.putIfAbsent(parent, new HashSet<>()); + + for (String child : children) { + connections.putIfAbsent(child, new HashSet<>()); + + connections.get(parent).add(child); + connections.get(child).add(parent); + + for (String sibling : children) { + if (!sibling.equals(child)) { + connections.get(child).add(sibling); + } + } + } + } + + graph = connections; + } + + int degreeOfSeparation(String personA, String personB) { + if (!graph.containsKey(personA) || !graph.containsKey(personB)) { + return -1; + } + + Queue queue = new LinkedList<>(); + Map distances = new HashMap<>() { + { + put(personA, 0); + } + }; + queue.add(personA); + + while (!queue.isEmpty()) { + String current = queue.poll(); + int currentDistance = distances.get(current); + + for (String relative : graph.get(current)) { + if (!distances.containsKey(relative)) { + if (relative.equals(personB)) { + return currentDistance + 1; + } + distances.put(relative, currentDistance + 1); + queue.add(relative); + } + } + } + + return -1; + } +} diff --git a/exercises/practice/relative-distance/.meta/tests.toml b/exercises/practice/relative-distance/.meta/tests.toml new file mode 100644 index 000000000..66c91ba09 --- /dev/null +++ b/exercises/practice/relative-distance/.meta/tests.toml @@ -0,0 +1,31 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[4a1ded74-5d32-47fb-8ae5-321f51d06b5b] +description = "Direct parent-child relation" + +[30d17269-83e9-4f82-a0d7-8ef9656d8dce] +description = "Sibling relationship" + +[8dffa27d-a8ab-496d-80b3-2f21c77648b5] +description = "Two degrees of separation, grandchild" + +[34e56ec1-d528-4a42-908e-020a4606ee60] +description = "Unrelated individuals" + +[93ffe989-bad2-48c4-878f-3acb1ce2611b] +description = "Complex graph, cousins" + +[2cc2e76b-013a-433c-9486-1dbe29bf06e5] +description = "Complex graph, no shortcut, far removed nephew" + +[46c9fbcb-e464-455f-a718-049ea3c7400a] +description = "Complex graph, some shortcuts, cross-down and cross-up, cousins several times removed, with unrelated family tree" diff --git a/exercises/practice/relative-distance/build.gradle b/exercises/practice/relative-distance/build.gradle new file mode 100644 index 000000000..d28f35dee --- /dev/null +++ b/exercises/practice/relative-distance/build.gradle @@ -0,0 +1,25 @@ +plugins { + id "java" +} + +repositories { + mavenCentral() +} + +dependencies { + testImplementation platform("org.junit:junit-bom:5.10.0") + testImplementation "org.junit.jupiter:junit-jupiter" + testImplementation "org.assertj:assertj-core:3.25.1" + + testRuntimeOnly "org.junit.platform:junit-platform-launcher" +} + +test { + useJUnitPlatform() + + testLogging { + exceptionFormat = "full" + showStandardStreams = true + events = ["passed", "failed", "skipped"] + } +} diff --git a/exercises/practice/relative-distance/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/relative-distance/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..f8e1ee312 Binary files /dev/null and b/exercises/practice/relative-distance/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/relative-distance/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/relative-distance/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..4d97ea344 --- /dev/null +++ b/exercises/practice/relative-distance/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/exercises/practice/relative-distance/gradlew b/exercises/practice/relative-distance/gradlew new file mode 100755 index 000000000..adff685a0 --- /dev/null +++ b/exercises/practice/relative-distance/gradlew @@ -0,0 +1,248 @@ +#!/bin/sh + +# +# Copyright © 2015 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/exercises/practice/relative-distance/gradlew.bat b/exercises/practice/relative-distance/gradlew.bat new file mode 100644 index 000000000..c4bdd3ab8 --- /dev/null +++ b/exercises/practice/relative-distance/gradlew.bat @@ -0,0 +1,93 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/exercises/practice/relative-distance/src/main/java/RelativeDistance.java b/exercises/practice/relative-distance/src/main/java/RelativeDistance.java new file mode 100644 index 000000000..6b74ce091 --- /dev/null +++ b/exercises/practice/relative-distance/src/main/java/RelativeDistance.java @@ -0,0 +1,13 @@ +import java.util.List; +import java.util.Map; + +class RelativeDistance { + + RelativeDistance(Map> familyTree) { + throw new UnsupportedOperationException("Delete this statement and write your own implementation."); + } + + int degreeOfSeparation(String personA, String personB) { + throw new UnsupportedOperationException("Delete this statement and write your own implementation."); + } +} diff --git a/exercises/practice/relative-distance/src/test/java/RelativeDistanceTest.java b/exercises/practice/relative-distance/src/test/java/RelativeDistanceTest.java new file mode 100644 index 000000000..b10a9459f --- /dev/null +++ b/exercises/practice/relative-distance/src/test/java/RelativeDistanceTest.java @@ -0,0 +1,267 @@ +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + + +public class RelativeDistanceTest { + + @Test + @DisplayName("Direct parent-child relation") + public void testDirectParentChildRelation() { + Map> familyTree = new HashMap<>() { + { + put("Vera", List.of("Tomoko")); + put("Tomoko", List.of("Aditi")); + } + }; + + RelativeDistance rd = new RelativeDistance(familyTree); + assertThat(rd.degreeOfSeparation("Vera", "Tomoko")).isEqualTo(1); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("Sibling relationship") + public void testSiblingRelationship() { + Map> familyTree = new HashMap<>() { + { + put("Dalia", List.of("Olga", "Yassin")); + } + }; + + RelativeDistance rd = new RelativeDistance(familyTree); + assertThat(rd.degreeOfSeparation("Olga", "Yassin")).isEqualTo(1); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("Two degrees of separation, grandchild") + public void testTwoDegreesOfSeparationGrandchild() { + Map> familyTree = new HashMap<>() { + { + put("Khadija", List.of("Mateo")); + put("Mateo", List.of("Rami")); + } + }; + + RelativeDistance rd = new RelativeDistance(familyTree); + assertThat(rd.degreeOfSeparation("Khadija", "Rami")).isEqualTo(2); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("Unrelated individuals") + public void testUnrelatedIndividuals() { + Map> familyTree = new HashMap<>() { + { + put("Priya", List.of("Rami")); + put("Kaito", List.of("Elif")); + } + }; + + RelativeDistance rd = new RelativeDistance(familyTree); + assertThat(rd.degreeOfSeparation("Priya", "Kaito")).isEqualTo(-1); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("Complex graph, cousins") + public void testComplexGraphCousins() { + Map> familyTree = new HashMap<>() { + { + put("Aiko", List.of("Bao", "Carlos")); + put("Bao", List.of("Dalia", "Elias")); + put("Carlos", List.of("Fatima", "Gustavo")); + put("Dalia", List.of("Hassan", "Isla")); + put("Elias", List.of("Javier")); + put("Fatima", List.of("Khadija", "Liam")); + put("Gustavo", List.of("Mina")); + put("Hassan", List.of("Noah", "Olga")); + put("Isla", List.of("Pedro")); + put("Javier", List.of("Quynh", "Ravi")); + put("Khadija", List.of("Sofia")); + put("Liam", List.of("Tariq", "Uma")); + put("Mina", List.of("Viktor", "Wang")); + put("Noah", List.of("Xiomara")); + put("Olga", List.of("Yuki")); + put("Pedro", List.of("Zane", "Aditi")); + put("Quynh", List.of("Boris")); + put("Ravi", List.of("Celine")); + put("Sofia", List.of("Diego", "Elif")); + put("Tariq", List.of("Farah")); + put("Uma", List.of("Giorgio")); + put("Viktor", List.of("Hana", "Ian")); + put("Wang", List.of("Jing")); + put("Xiomara", List.of("Kaito")); + put("Yuki", List.of("Leila")); + put("Zane", List.of("Mateo")); + put("Aditi", List.of("Nia")); + put("Boris", List.of("Oscar")); + put("Celine", List.of("Priya")); + put("Diego", List.of("Qi")); + put("Elif", List.of("Rami")); + put("Farah", List.of("Sven")); + put("Giorgio", List.of("Tomoko")); + put("Hana", List.of("Umar")); + put("Ian", List.of("Vera")); + put("Jing", List.of("Wyatt")); + put("Kaito", List.of("Xia")); + put("Leila", List.of("Yassin")); + put("Mateo", List.of("Zara")); + put("Nia", List.of("Antonio")); + put("Oscar", List.of("Bianca")); + put("Priya", List.of("Cai")); + put("Qi", List.of("Dimitri")); + put("Rami", List.of("Ewa")); + put("Sven", List.of("Fabio")); + put("Tomoko", List.of("Gabriela")); + put("Umar", List.of("Helena")); + put("Vera", List.of("Igor")); + put("Wyatt", List.of("Jun")); + put("Xia", List.of("Kim")); + put("Yassin", List.of("Lucia")); + put("Zara", List.of("Mohammed")); + } + }; + + RelativeDistance rd = new RelativeDistance(familyTree); + assertThat(rd.degreeOfSeparation("Dimitri", "Fabio")).isEqualTo(9); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("Complex graph, no shortcut, far removed nephew") + public void testComplexGraphNoShortcutFarRemovedNephew() { + Map> familyTree = new HashMap<>() { + { + put("Aiko", List.of("Bao", "Carlos")); + put("Bao", List.of("Dalia", "Elias")); + put("Carlos", List.of("Fatima", "Gustavo")); + put("Dalia", List.of("Hassan", "Isla")); + put("Elias", List.of("Javier")); + put("Fatima", List.of("Khadija", "Liam")); + put("Gustavo", List.of("Mina")); + put("Hassan", List.of("Noah", "Olga")); + put("Isla", List.of("Pedro")); + put("Javier", List.of("Quynh", "Ravi")); + put("Khadija", List.of("Sofia")); + put("Liam", List.of("Tariq", "Uma")); + put("Mina", List.of("Viktor", "Wang")); + put("Noah", List.of("Xiomara")); + put("Olga", List.of("Yuki")); + put("Pedro", List.of("Zane", "Aditi")); + put("Quynh", List.of("Boris")); + put("Ravi", List.of("Celine")); + put("Sofia", List.of("Diego", "Elif")); + put("Tariq", List.of("Farah")); + put("Uma", List.of("Giorgio")); + put("Viktor", List.of("Hana", "Ian")); + put("Wang", List.of("Jing")); + put("Xiomara", List.of("Kaito")); + put("Yuki", List.of("Leila")); + put("Zane", List.of("Mateo")); + put("Aditi", List.of("Nia")); + put("Boris", List.of("Oscar")); + put("Celine", List.of("Priya")); + put("Diego", List.of("Qi")); + put("Elif", List.of("Rami")); + put("Farah", List.of("Sven")); + put("Giorgio", List.of("Tomoko")); + put("Hana", List.of("Umar")); + put("Ian", List.of("Vera")); + put("Jing", List.of("Wyatt")); + put("Kaito", List.of("Xia")); + put("Leila", List.of("Yassin")); + put("Mateo", List.of("Zara")); + put("Nia", List.of("Antonio")); + put("Oscar", List.of("Bianca")); + put("Priya", List.of("Cai")); + put("Qi", List.of("Dimitri")); + put("Rami", List.of("Ewa")); + put("Sven", List.of("Fabio")); + put("Tomoko", List.of("Gabriela")); + put("Umar", List.of("Helena")); + put("Vera", List.of("Igor")); + put("Wyatt", List.of("Jun")); + put("Xia", List.of("Kim")); + put("Yassin", List.of("Lucia")); + put("Zara", List.of("Mohammed")); + } + }; + RelativeDistance rd = new RelativeDistance(familyTree); + assertThat(rd.degreeOfSeparation("Lucia", "Jun")).isEqualTo(14); + } + + @Disabled("Remove to run test") + @Test + @DisplayName( + "Complex graph, some shortcuts, cross-down and cross-up, " + + "cousins several times removed, with unrelated family tree" + ) + public void testComplexGraphSomeShortcutsCrossDownAndCrossUpCousinsSeveralTimesRemovedWithUnrelatedFamilyTree() { + Map> familyTree = new HashMap<>() { + { + put("Aiko", List.of("Bao", "Carlos")); + put("Bao", List.of("Dalia")); + put("Carlos", List.of("Fatima", "Gustavo")); + put("Dalia", List.of("Hassan", "Isla")); + put("Fatima", List.of("Khadija", "Liam")); + put("Gustavo", List.of("Mina")); + put("Hassan", List.of("Noah", "Olga")); + put("Isla", List.of("Pedro")); + put("Javier", List.of("Quynh", "Ravi")); + put("Khadija", List.of("Sofia")); + put("Liam", List.of("Tariq", "Uma")); + put("Mina", List.of("Viktor", "Wang")); + put("Noah", List.of("Xiomara")); + put("Olga", List.of("Yuki")); + put("Pedro", List.of("Zane", "Aditi")); + put("Quynh", List.of("Boris")); + put("Ravi", List.of("Celine")); + put("Sofia", List.of("Diego", "Elif")); + put("Tariq", List.of("Farah")); + put("Uma", List.of("Giorgio")); + put("Viktor", List.of("Hana", "Ian")); + put("Wang", List.of("Jing")); + put("Xiomara", List.of("Kaito")); + put("Yuki", List.of("Leila")); + put("Zane", List.of("Mateo")); + put("Aditi", List.of("Nia")); + put("Boris", List.of("Oscar")); + put("Celine", List.of("Priya")); + put("Diego", List.of("Qi")); + put("Elif", List.of("Rami")); + put("Farah", List.of("Sven")); + put("Giorgio", List.of("Tomoko")); + put("Hana", List.of("Umar")); + put("Ian", List.of("Vera")); + put("Jing", List.of("Wyatt")); + put("Kaito", List.of("Xia")); + put("Leila", List.of("Yassin")); + put("Mateo", List.of("Zara")); + put("Nia", List.of("Antonio")); + put("Oscar", List.of("Bianca")); + put("Priya", List.of("Cai")); + put("Qi", List.of("Dimitri")); + put("Rami", List.of("Ewa")); + put("Sven", List.of("Fabio")); + put("Tomoko", List.of("Gabriela")); + put("Umar", List.of("Helena")); + put("Vera", List.of("Igor")); + put("Wyatt", List.of("Jun")); + put("Xia", List.of("Kim")); + put("Yassin", List.of("Lucia")); + put("Zara", List.of("Mohammed")); + } + }; + RelativeDistance rd = new RelativeDistance(familyTree); + assertThat(rd.degreeOfSeparation("Wyatt", "Xia")).isEqualTo(12); + } +} diff --git a/exercises/practice/resistor-color-duo/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/resistor-color-duo/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/resistor-color-duo/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/resistor-color-duo/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/resistor-color-duo/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/resistor-color-duo/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/resistor-color-duo/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/resistor-color-duo/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/resistor-color-duo/gradlew b/exercises/practice/resistor-color-duo/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/resistor-color-duo/gradlew +++ b/exercises/practice/resistor-color-duo/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/resistor-color-duo/gradlew.bat b/exercises/practice/resistor-color-duo/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/resistor-color-duo/gradlew.bat +++ b/exercises/practice/resistor-color-duo/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/resistor-color-duo/src/test/java/ResistorColorDuoTest.java b/exercises/practice/resistor-color-duo/src/test/java/ResistorColorDuoTest.java index ef5fec6bb..6e8c5d0d4 100644 --- a/exercises/practice/resistor-color-duo/src/test/java/ResistorColorDuoTest.java +++ b/exercises/practice/resistor-color-duo/src/test/java/ResistorColorDuoTest.java @@ -1,6 +1,7 @@ import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -13,6 +14,7 @@ public void setup() { } @Test + @DisplayName("Brown and black") public void testBrownAndBlack() { assertThat( resistorColorDuo.value(new String[]{"brown", "black"}) @@ -21,6 +23,7 @@ public void testBrownAndBlack() { @Disabled("Remove to run test") @Test + @DisplayName("Blue and grey") public void testBlueAndGrey() { assertThat( resistorColorDuo.value(new String[]{ "blue", "grey" }) @@ -29,6 +32,7 @@ public void testBlueAndGrey() { @Disabled("Remove to run test") @Test + @DisplayName("Yellow and violet") public void testYellowAndViolet() { assertThat( resistorColorDuo.value(new String[]{ "yellow", "violet" }) @@ -37,6 +41,7 @@ public void testYellowAndViolet() { @Disabled("Remove to run test") @Test + @DisplayName("Orange and orange") public void testOrangeAndOrange() { assertThat( resistorColorDuo.value(new String[]{ "orange", "orange" }) @@ -45,6 +50,7 @@ public void testOrangeAndOrange() { @Disabled("Remove to run test") @Test + @DisplayName("White and red") public void testWhiteAndRed() { assertThat( resistorColorDuo.value(new String[]{ "white", "red" }) @@ -53,6 +59,7 @@ public void testWhiteAndRed() { @Disabled("Remove to run test") @Test + @DisplayName("Black and brown, one-digit") public void testBlackAndBrownOneDigit() { assertThat( resistorColorDuo.value(new String[]{ "black", "brown" }) @@ -61,6 +68,7 @@ public void testBlackAndBrownOneDigit() { @Disabled("Remove to run test") @Test + @DisplayName("Ignore additional colors") public void testIgnoreAdditionalColors() { assertThat( resistorColorDuo.value(new String[]{ "green", "brown", "orange" }) diff --git a/exercises/practice/resistor-color-trio/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/resistor-color-trio/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/resistor-color-trio/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/resistor-color-trio/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/resistor-color-trio/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/resistor-color-trio/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/resistor-color-trio/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/resistor-color-trio/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/resistor-color-trio/gradlew b/exercises/practice/resistor-color-trio/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/resistor-color-trio/gradlew +++ b/exercises/practice/resistor-color-trio/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/resistor-color-trio/gradlew.bat b/exercises/practice/resistor-color-trio/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/resistor-color-trio/gradlew.bat +++ b/exercises/practice/resistor-color-trio/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/resistor-color-trio/src/test/java/ResistorColorTrioTest.java b/exercises/practice/resistor-color-trio/src/test/java/ResistorColorTrioTest.java index 6d966eb33..3c682c3be 100644 --- a/exercises/practice/resistor-color-trio/src/test/java/ResistorColorTrioTest.java +++ b/exercises/practice/resistor-color-trio/src/test/java/ResistorColorTrioTest.java @@ -1,6 +1,7 @@ import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -13,6 +14,7 @@ public void setup() { } @Test + @DisplayName("Orange and orange and black") public void testOrangeAndOrangeAndBlack() { assertThat( resistorColorTrio.label(new String[]{"orange", "orange", "black"}) @@ -21,6 +23,7 @@ public void testOrangeAndOrangeAndBlack() { @Disabled("Remove to run test") @Test + @DisplayName("Blue and grey and brown") public void testBlueAndGreyAndBrown() { assertThat( resistorColorTrio.label(new String[]{"blue", "grey", "brown"}) @@ -29,6 +32,7 @@ public void testBlueAndGreyAndBrown() { @Disabled("Remove to run test") @Test + @DisplayName("Red and black and red") public void testRedAndBlackAndRed() { assertThat( resistorColorTrio.label(new String[]{"red", "black", "red"}) @@ -37,6 +41,7 @@ public void testRedAndBlackAndRed() { @Disabled("Remove to run test") @Test + @DisplayName("Green and brown and orange") public void testGreenAndBrownAndOrange() { assertThat( resistorColorTrio.label(new String[]{"green", "brown", "orange"}) @@ -45,6 +50,7 @@ public void testGreenAndBrownAndOrange() { @Disabled("Remove to run test") @Test + @DisplayName("Yellow and violet and yellow") public void testYellowAndVioletAndYellow() { assertThat( resistorColorTrio.label(new String[]{"yellow", "violet", "yellow"}) @@ -53,6 +59,7 @@ public void testYellowAndVioletAndYellow() { @Disabled("Remove to run test") @Test + @DisplayName("Blue and violet and blue") public void testBlueAndVioletAndBlue() { assertThat( resistorColorTrio.label(new String[]{"blue", "violet", "blue"}) @@ -61,6 +68,7 @@ public void testBlueAndVioletAndBlue() { @Disabled("Remove to run test") @Test + @DisplayName("Minimum possible value") public void testBlackAndBlackAndBlack() { assertThat( resistorColorTrio.label(new String[]{"black", "black", "black"}) @@ -69,6 +77,7 @@ public void testBlackAndBlackAndBlack() { @Disabled("Remove to run test") @Test + @DisplayName("Maximum possible value") public void testWhiteAndWhiteAndWhite() { assertThat( resistorColorTrio.label(new String[]{"white", "white", "white"}) @@ -77,6 +86,7 @@ public void testWhiteAndWhiteAndWhite() { @Disabled("Remove to run test") @Test + @DisplayName("First two colors make an invalid octal number") public void testFirstTwoColorsMakeAnInvalidOctalNumber() { assertThat( resistorColorTrio.label(new String[]{"black", "grey", "black"}) @@ -85,6 +95,7 @@ public void testFirstTwoColorsMakeAnInvalidOctalNumber() { @Disabled("Remove to run test") @Test + @DisplayName("Ignore extra colors") public void testIgnoreExtraColors() { assertThat( resistorColorTrio.label(new String[]{"blue", "green", "yellow", "orange"}) diff --git a/exercises/practice/resistor-color/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/resistor-color/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/resistor-color/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/resistor-color/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/resistor-color/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/resistor-color/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/resistor-color/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/resistor-color/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/resistor-color/gradlew b/exercises/practice/resistor-color/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/resistor-color/gradlew +++ b/exercises/practice/resistor-color/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/resistor-color/gradlew.bat b/exercises/practice/resistor-color/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/resistor-color/gradlew.bat +++ b/exercises/practice/resistor-color/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/resistor-color/src/test/java/ResistorColorTest.java b/exercises/practice/resistor-color/src/test/java/ResistorColorTest.java index fa7426b5b..9eb218d05 100644 --- a/exercises/practice/resistor-color/src/test/java/ResistorColorTest.java +++ b/exercises/practice/resistor-color/src/test/java/ResistorColorTest.java @@ -1,6 +1,7 @@ import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; public class ResistorColorTest { @@ -13,24 +14,28 @@ public void setup() { } @Test + @DisplayName("Black") public void testBlackColorCode() { assertThat(resistorColor.colorCode("black")).isEqualTo(0); } @Disabled("Remove to run test") @Test + @DisplayName("white") public void testWhiteColorCode() { assertThat(resistorColor.colorCode("white")).isEqualTo(9); } @Disabled("Remove to run test") @Test + @DisplayName("Orange") public void testOrangeColorCode() { assertThat(resistorColor.colorCode("orange")).isEqualTo(3); } @Disabled("Remove to run test") @Test + @DisplayName("Colors") public void testColors() { assertThat(resistorColor.colors()).containsExactly( "black", "brown", "red", "orange", "yellow", "green", "blue", "violet", "grey", "white" diff --git a/exercises/practice/rest-api/build.gradle b/exercises/practice/rest-api/build.gradle index 7b2a81d33..b5866449e 100644 --- a/exercises/practice/rest-api/build.gradle +++ b/exercises/practice/rest-api/build.gradle @@ -12,6 +12,8 @@ dependencies { testImplementation platform("org.junit:junit-bom:5.10.0") testImplementation "org.junit.jupiter:junit-jupiter" testImplementation "org.assertj:assertj-core:3.25.1" + + testRuntimeOnly "org.junit.platform:junit-platform-launcher" } test { diff --git a/exercises/practice/rest-api/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/rest-api/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/rest-api/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/rest-api/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/rest-api/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/rest-api/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/rest-api/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/rest-api/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/rest-api/gradlew b/exercises/practice/rest-api/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/rest-api/gradlew +++ b/exercises/practice/rest-api/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/rest-api/gradlew.bat b/exercises/practice/rest-api/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/rest-api/gradlew.bat +++ b/exercises/practice/rest-api/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/rest-api/src/test/java/RestApiTest.java b/exercises/practice/rest-api/src/test/java/RestApiTest.java index d03f15717..e17d0a9a6 100644 --- a/exercises/practice/rest-api/src/test/java/RestApiTest.java +++ b/exercises/practice/rest-api/src/test/java/RestApiTest.java @@ -1,6 +1,7 @@ import org.json.JSONArray; import org.json.JSONObject; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -8,6 +9,7 @@ public class RestApiTest { @Test + @DisplayName("no users") public void noUsers() { String expected = new JSONObject().put("users", new JSONArray()).toString(); @@ -18,6 +20,7 @@ public void noUsers() { @Disabled("Remove to run test") @Test + @DisplayName("add user") public void addUser() { String expected = new JSONObject() .put("name", "Adam") @@ -33,6 +36,7 @@ public void addUser() { @Disabled("Remove to run test") @Test + @DisplayName("get single user") public void getSingleUser() { String expected = new JSONObject() .put( @@ -56,6 +60,7 @@ public void getSingleUser() { } @Test + @DisplayName("both users have 0 balance") public void bothUsersHave0Balance() { String expected = new JSONObject() @@ -94,6 +99,7 @@ public void bothUsersHave0Balance() { @Disabled("Remove to run test") @Test + @DisplayName("borrower has negative balance") public void borrowerHasNegativeBalance() { String expected = new JSONObject() @@ -135,6 +141,7 @@ public void borrowerHasNegativeBalance() { @Disabled("Remove to run test") @Test + @DisplayName("lender has negative balance") public void lenderHasNegativeBalance() { String expected = new JSONObject() @@ -178,6 +185,7 @@ public void lenderHasNegativeBalance() { @Disabled("Remove to run test") @Test + @DisplayName("lender owes borrower") public void lenderOwesBorrower() { String expected = new JSONObject() @@ -216,6 +224,7 @@ public void lenderOwesBorrower() { @Disabled("Remove to run test") @Test + @DisplayName("lender owes borrower less than new loan") public void lenderOwesBorrowerLessThanNewLoan() { String expected = new JSONObject() @@ -254,6 +263,7 @@ public void lenderOwesBorrowerLessThanNewLoan() { @Disabled("Remove to run test") @Test + @DisplayName("lender owes borrower same as new loan") public void lenderOwesBorrowerSameAsNewLoan() { String expected = new JSONObject() diff --git a/exercises/practice/reverse-string/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/reverse-string/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/reverse-string/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/reverse-string/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/reverse-string/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/reverse-string/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/reverse-string/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/reverse-string/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/reverse-string/gradlew b/exercises/practice/reverse-string/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/reverse-string/gradlew +++ b/exercises/practice/reverse-string/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/reverse-string/gradlew.bat b/exercises/practice/reverse-string/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/reverse-string/gradlew.bat +++ b/exercises/practice/reverse-string/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/reverse-string/src/test/java/ReverseStringTest.java b/exercises/practice/reverse-string/src/test/java/ReverseStringTest.java index 1c7a72c74..64475609c 100644 --- a/exercises/practice/reverse-string/src/test/java/ReverseStringTest.java +++ b/exercises/practice/reverse-string/src/test/java/ReverseStringTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -6,36 +7,42 @@ public class ReverseStringTest { @Test + @DisplayName("an empty string") public void testAnEmptyString() { assertThat(new ReverseString().reverse("")).isEqualTo(""); } @Disabled("Remove to run test") @Test + @DisplayName("a word") public void testAWord() { assertThat(new ReverseString().reverse("robot")).isEqualTo("tobor"); } @Disabled("Remove to run test") @Test + @DisplayName("a capitalized word") public void testACapitalizedWord() { assertThat(new ReverseString().reverse("Ramen")).isEqualTo("nemaR"); } @Disabled("Remove to run test") @Test + @DisplayName("a sentence with punctuation") public void testASentenceWithPunctuation() { assertThat(new ReverseString().reverse("I'm hungry!")).isEqualTo("!yrgnuh m'I"); } @Disabled("Remove to run test") @Test + @DisplayName("a palindrome") public void testAPalindrome() { assertThat(new ReverseString().reverse("racecar")).isEqualTo("racecar"); } @Disabled("Remove to run test") @Test + @DisplayName("an even-sized word") public void testAnEvenSizedWord() { assertThat(new ReverseString().reverse("drawer")).isEqualTo("reward"); } diff --git a/exercises/practice/rna-transcription/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/rna-transcription/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/rna-transcription/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/rna-transcription/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/rna-transcription/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/rna-transcription/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/rna-transcription/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/rna-transcription/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/rna-transcription/gradlew b/exercises/practice/rna-transcription/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/rna-transcription/gradlew +++ b/exercises/practice/rna-transcription/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/rna-transcription/gradlew.bat b/exercises/practice/rna-transcription/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/rna-transcription/gradlew.bat +++ b/exercises/practice/rna-transcription/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/rna-transcription/src/test/java/RnaTranscriptionTest.java b/exercises/practice/rna-transcription/src/test/java/RnaTranscriptionTest.java index 7de6deaf8..7b1cc753a 100644 --- a/exercises/practice/rna-transcription/src/test/java/RnaTranscriptionTest.java +++ b/exercises/practice/rna-transcription/src/test/java/RnaTranscriptionTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -14,36 +15,42 @@ public void setUp() { } @Test + @DisplayName("Empty RNA sequence") public void testEmptyRnaSequence() { assertThat(rnaTranscription.transcribe("")).isEmpty(); } @Disabled("Remove to run test") @Test + @DisplayName("RNA complement of cytosine is guanine") public void testRnaTranscriptionOfCytosineIsGuanine() { assertThat(rnaTranscription.transcribe("C")).isEqualTo("G"); } @Disabled("Remove to run test") @Test + @DisplayName("RNA complement of guanine is cytosine") public void testRnaTranscriptionOfGuanineIsCytosine() { assertThat(rnaTranscription.transcribe("G")).isEqualTo("C"); } @Disabled("Remove to run test") @Test + @DisplayName("RNA complement of thymine is adenine") public void testRnaTranscriptionOfThymineIsAdenine() { assertThat(rnaTranscription.transcribe("T")).isEqualTo("A"); } @Disabled("Remove to run test") @Test + @DisplayName("RNA complement of adenine is uracil") public void testRnaTranscriptionOfAdenineIsUracil() { assertThat(rnaTranscription.transcribe("A")).isEqualTo("U"); } @Disabled("Remove to run test") @Test + @DisplayName("RNA complement") public void testRnaTranscription() { assertThat(rnaTranscription.transcribe("ACGTGGTCTTAA")).isEqualTo("UGCACCAGAAUU"); } diff --git a/exercises/practice/robot-name/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/robot-name/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/robot-name/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/robot-name/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/robot-name/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/robot-name/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/robot-name/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/robot-name/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/robot-name/gradlew b/exercises/practice/robot-name/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/robot-name/gradlew +++ b/exercises/practice/robot-name/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/robot-name/gradlew.bat b/exercises/practice/robot-name/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/robot-name/gradlew.bat +++ b/exercises/practice/robot-name/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/robot-name/src/test/java/RobotTest.java b/exercises/practice/robot-name/src/test/java/RobotTest.java index 6c19ae877..542d4a586 100644 --- a/exercises/practice/robot-name/src/test/java/RobotTest.java +++ b/exercises/practice/robot-name/src/test/java/RobotTest.java @@ -1,11 +1,12 @@ -import static org.assertj.core.api.Assertions.assertThat; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; import java.util.HashSet; import java.util.Set; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; public class RobotTest { @@ -18,24 +19,28 @@ public void setUp() { } @Test + @DisplayName("Robot has a valid name") public void hasName() { assertIsValidName(robot.getName()); } @Test @Disabled("Remove to run test") + @DisplayName("Same robot returns the same name on repeated calls") public void sameRobotsHaveSameNames() { assertThat(robot.getName()).isEqualTo(robot.getName()); } @Disabled("Remove to run test") @Test + @DisplayName("Different robots have different names") public void differentRobotsHaveDifferentNames() { assertThat(robot.getName()).isNotEqualTo(new Robot().getName()); } @Disabled("Remove to run test") @Test + @DisplayName("Resetting a robot assigns a new valid name") public void resetName() { final String name = robot.getName(); robot.reset(); @@ -46,6 +51,7 @@ public void resetName() { @Disabled("Remove to run test") @Test + @DisplayName("Robot names are unique") public void robotNamesAreUnique() { Set robotNames = new HashSet<>(); int sampleSize = 5000; diff --git a/exercises/practice/robot-simulator/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/robot-simulator/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/robot-simulator/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/robot-simulator/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/robot-simulator/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/robot-simulator/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/robot-simulator/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/robot-simulator/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/robot-simulator/gradlew b/exercises/practice/robot-simulator/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/robot-simulator/gradlew +++ b/exercises/practice/robot-simulator/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/robot-simulator/gradlew.bat b/exercises/practice/robot-simulator/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/robot-simulator/gradlew.bat +++ b/exercises/practice/robot-simulator/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/robot-simulator/src/test/java/RobotTest.java b/exercises/practice/robot-simulator/src/test/java/RobotTest.java index 27deb9ce4..5c8edbc0c 100644 --- a/exercises/practice/robot-simulator/src/test/java/RobotTest.java +++ b/exercises/practice/robot-simulator/src/test/java/RobotTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -8,6 +9,7 @@ public class RobotTest { /* Create robot */ @Test + @DisplayName("at origin facing north") public void atOriginFacingNorth() { Orientation initialOrientation = Orientation.NORTH; GridPosition initialGridPosition = new GridPosition(0, 0); @@ -19,6 +21,7 @@ public void atOriginFacingNorth() { @Disabled("Remove to run test") @Test + @DisplayName("at negative position facing south") public void atNegativePositionFacingSouth() { GridPosition initialGridPosition = new GridPosition(-1, -1); Orientation initialOrientation = Orientation.SOUTH; @@ -32,6 +35,7 @@ public void atNegativePositionFacingSouth() { @Disabled("Remove to run test") @Test + @DisplayName("changes north to east") public void changesNorthToEast() { GridPosition initialGridPosition = new GridPosition(0, 0); Robot robot = new Robot(initialGridPosition, Orientation.NORTH); @@ -45,6 +49,7 @@ public void changesNorthToEast() { @Disabled("Remove to run test") @Test + @DisplayName("changes east to south") public void changesEastToSouth() { GridPosition initialGridPosition = new GridPosition(0, 0); Robot robot = new Robot(initialGridPosition, Orientation.EAST); @@ -58,6 +63,7 @@ public void changesEastToSouth() { @Disabled("Remove to run test") @Test + @DisplayName("changes south to west") public void changesSouthToWest() { GridPosition initialGridPosition = new GridPosition(0, 0); Robot robot = new Robot(initialGridPosition, Orientation.SOUTH); @@ -71,6 +77,7 @@ public void changesSouthToWest() { @Disabled("Remove to run test") @Test + @DisplayName("changes west to north") public void changesWestToNorth() { GridPosition initialGridPosition = new GridPosition(0, 0); Robot robot = new Robot(initialGridPosition, Orientation.WEST); @@ -86,6 +93,7 @@ public void changesWestToNorth() { @Disabled("Remove to run test") @Test + @DisplayName("changes north to west") public void changesNorthToWest() { GridPosition initialGridPosition = new GridPosition(0, 0); Robot robot = new Robot(initialGridPosition, Orientation.NORTH); @@ -99,6 +107,7 @@ public void changesNorthToWest() { @Disabled("Remove to run test") @Test + @DisplayName("changes west to south") public void changesWestToSouth() { GridPosition initialGridPosition = new GridPosition(0, 0); Robot robot = new Robot(initialGridPosition, Orientation.WEST); @@ -112,6 +121,7 @@ public void changesWestToSouth() { @Disabled("Remove to run test") @Test + @DisplayName("changes south to east") public void changesSouthToEast() { GridPosition initialGridPosition = new GridPosition(0, 0); Robot robot = new Robot(initialGridPosition, Orientation.SOUTH); @@ -125,6 +135,7 @@ public void changesSouthToEast() { @Disabled("Remove to run test") @Test + @DisplayName("changes east to north") public void changesEastToNorth() { GridPosition initialGridPosition = new GridPosition(0, 0); Robot robot = new Robot(initialGridPosition, Orientation.EAST); @@ -140,6 +151,7 @@ public void changesEastToNorth() { @Disabled("Remove to run test") @Test + @DisplayName("facing north increments Y") public void facingNorthIncrementsY() { Orientation initialOrientation = Orientation.NORTH; Robot robot = new Robot(new GridPosition(0, 0), initialOrientation); @@ -153,6 +165,7 @@ public void facingNorthIncrementsY() { @Disabled("Remove to run test") @Test + @DisplayName("facing south decrements Y") public void facingSouthDecrementsY() { Orientation initialOrientation = Orientation.SOUTH; Robot robot = new Robot(new GridPosition(0, 0), initialOrientation); @@ -166,6 +179,7 @@ public void facingSouthDecrementsY() { @Disabled("Remove to run test") @Test + @DisplayName("facing east increments X") public void facingEastIncrementsX() { Orientation initialOrientation = Orientation.EAST; Robot robot = new Robot(new GridPosition(0, 0), initialOrientation); @@ -179,6 +193,7 @@ public void facingEastIncrementsX() { @Disabled("Remove to run test") @Test + @DisplayName("facing west decrements X") public void facingWestDecrementsX() { Orientation initialOrientation = Orientation.WEST; Robot robot = new Robot(new GridPosition(0, 0), initialOrientation); @@ -194,6 +209,7 @@ public void facingWestDecrementsX() { @Disabled("Remove to run test") @Test + @DisplayName("moving east and north from README") public void movingEastAndNorthFromReadme() { Robot robot = new Robot(new GridPosition(7, 3), Orientation.NORTH); @@ -209,6 +225,7 @@ public void movingEastAndNorthFromReadme() { @Disabled("Remove to run test") @Test + @DisplayName("moving west and north") public void movingWestAndNorth() { Robot robot = new Robot(new GridPosition(0, 0), Orientation.NORTH); @@ -223,6 +240,7 @@ public void movingWestAndNorth() { @Disabled("Remove to run test") @Test + @DisplayName("moving west and south") public void movingWestAndSouth() { Robot robot = new Robot(new GridPosition(2, -7), Orientation.EAST); @@ -237,6 +255,7 @@ public void movingWestAndSouth() { @Disabled("Remove to run test") @Test + @DisplayName("moving east and north") public void movingEastAndNorth() { Robot robot = new Robot(new GridPosition(8, 4), Orientation.SOUTH); diff --git a/exercises/practice/roman-numerals/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/roman-numerals/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/roman-numerals/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/roman-numerals/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/roman-numerals/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/roman-numerals/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/roman-numerals/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/roman-numerals/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/roman-numerals/gradlew b/exercises/practice/roman-numerals/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/roman-numerals/gradlew +++ b/exercises/practice/roman-numerals/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/roman-numerals/gradlew.bat b/exercises/practice/roman-numerals/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/roman-numerals/gradlew.bat +++ b/exercises/practice/roman-numerals/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/roman-numerals/src/test/java/RomanNumeralsTest.java b/exercises/practice/roman-numerals/src/test/java/RomanNumeralsTest.java index 5d02ddc6f..8b7c21da8 100644 --- a/exercises/practice/roman-numerals/src/test/java/RomanNumeralsTest.java +++ b/exercises/practice/roman-numerals/src/test/java/RomanNumeralsTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -8,6 +9,7 @@ public class RomanNumeralsTest { private RomanNumerals romanNumerals; @Test + @DisplayName("1 is I") public void test1ToRomanNumberI() { romanNumerals = new RomanNumerals(1); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("I"); @@ -15,6 +17,7 @@ public void test1ToRomanNumberI() { @Disabled("Remove to run test") @Test + @DisplayName("2 is II") public void test2ToRomanNumberII() { romanNumerals = new RomanNumerals(2); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("II"); @@ -22,6 +25,7 @@ public void test2ToRomanNumberII() { @Disabled("Remove to run test") @Test + @DisplayName("3 is III") public void test3ToRomanNumberIII() { romanNumerals = new RomanNumerals(3); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("III"); @@ -29,6 +33,7 @@ public void test3ToRomanNumberIII() { @Disabled("Remove to run test") @Test + @DisplayName("4 is IV") public void test4ToRomanNumberIV() { romanNumerals = new RomanNumerals(4); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("IV"); @@ -36,6 +41,7 @@ public void test4ToRomanNumberIV() { @Disabled("Remove to run test") @Test + @DisplayName("5 is V") public void test5ToRomanNumberV() { romanNumerals = new RomanNumerals(5); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("V"); @@ -43,6 +49,7 @@ public void test5ToRomanNumberV() { @Disabled("Remove to run test") @Test + @DisplayName("6 is VI") public void test6ToRomanNumberVI() { romanNumerals = new RomanNumerals(6); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("VI"); @@ -50,6 +57,7 @@ public void test6ToRomanNumberVI() { @Disabled("Remove to run test") @Test + @DisplayName("9 is IX") public void test9ToRomanNumberIX() { romanNumerals = new RomanNumerals(9); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("IX"); @@ -57,6 +65,7 @@ public void test9ToRomanNumberIX() { @Disabled("Remove to run test") @Test + @DisplayName("16 is XVI") public void test16ToRomanNumberXVI() { romanNumerals = new RomanNumerals(16); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("XVI"); @@ -64,6 +73,7 @@ public void test16ToRomanNumberXVI() { @Disabled("Remove to run test") @Test + @DisplayName("27 is XXVII") public void test27ToRomanNumberXXVII() { romanNumerals = new RomanNumerals(27); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("XXVII"); @@ -71,6 +81,7 @@ public void test27ToRomanNumberXXVII() { @Disabled("Remove to run test") @Test + @DisplayName("48 is XLVIII") public void test48ToRomanNumberXLVIII() { romanNumerals = new RomanNumerals(48); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("XLVIII"); @@ -78,6 +89,7 @@ public void test48ToRomanNumberXLVIII() { @Disabled("Remove to run test") @Test + @DisplayName("49 is XLIX") public void test49ToRomanNumberXLIX() { romanNumerals = new RomanNumerals(49); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("XLIX"); @@ -85,6 +97,7 @@ public void test49ToRomanNumberXLIX() { @Disabled("Remove to run test") @Test + @DisplayName("59 is LIX") public void test59ToRomanNumberLIX() { romanNumerals = new RomanNumerals(59); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("LIX"); @@ -92,6 +105,7 @@ public void test59ToRomanNumberLIX() { @Disabled("Remove to run test") @Test + @DisplayName("66 is LXVI") public void test66ToRomanNumberLXVI() { romanNumerals = new RomanNumerals(66); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("LXVI"); @@ -99,6 +113,7 @@ public void test66ToRomanNumberLXVI() { @Disabled("Remove to run test") @Test + @DisplayName("93 is XCIII") public void test93ToRomanNumberXCIII() { romanNumerals = new RomanNumerals(93); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("XCIII"); @@ -106,6 +121,7 @@ public void test93ToRomanNumberXCIII() { @Disabled("Remove to run test") @Test + @DisplayName("141 is CXLI") public void test141ToRomanNumberCXLI() { romanNumerals = new RomanNumerals(141); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("CXLI"); @@ -113,6 +129,7 @@ public void test141ToRomanNumberCXLI() { @Disabled("Remove to run test") @Test + @DisplayName("163 is CLXIII") public void test163ToRomanNumberCLXIII() { romanNumerals = new RomanNumerals(163); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("CLXIII"); @@ -120,6 +137,7 @@ public void test163ToRomanNumberCLXIII() { @Disabled("Remove to run test") @Test + @DisplayName("166 is CLXVI") public void test166ToRomanNumberCLXVI() { romanNumerals = new RomanNumerals(166); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("CLXVI"); @@ -127,6 +145,7 @@ public void test166ToRomanNumberCLXVI() { @Disabled("Remove to run test") @Test + @DisplayName("402 is CDII") public void test402ToRomanNumberCDII() { romanNumerals = new RomanNumerals(402); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("CDII"); @@ -134,6 +153,7 @@ public void test402ToRomanNumberCDII() { @Disabled("Remove to run test") @Test + @DisplayName("575 is DLXXV") public void test575ToRomanNumberDLXXV() { romanNumerals = new RomanNumerals(575); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("DLXXV"); @@ -141,6 +161,7 @@ public void test575ToRomanNumberDLXXV() { @Disabled("Remove to run test") @Test + @DisplayName("666 is DCLXVI") public void test666ToRomanNumberDCLXVI() { romanNumerals = new RomanNumerals(666); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("DCLXVI"); @@ -148,6 +169,7 @@ public void test666ToRomanNumberDCLXVI() { @Disabled("Remove to run test") @Test + @DisplayName("911 is CMXI") public void test911ToRomanNumberCMXI() { romanNumerals = new RomanNumerals(911); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("CMXI"); @@ -155,6 +177,7 @@ public void test911ToRomanNumberCMXI() { @Disabled("Remove to run test") @Test + @DisplayName("1024 is MXXIV") public void test1024ToRomanNumberMXXIV() { romanNumerals = new RomanNumerals(1024); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("MXXIV"); @@ -162,6 +185,7 @@ public void test1024ToRomanNumberMXXIV() { @Disabled("Remove to run test") @Test + @DisplayName("1666 is MDCLXVI") public void test1666ToRomanNumberMDCLXVI() { romanNumerals = new RomanNumerals(1666); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("MDCLXVI"); @@ -169,6 +193,7 @@ public void test1666ToRomanNumberMDCLXVI() { @Disabled("Remove to run test") @Test + @DisplayName("3000 is MMM") public void test3000ToRomanNumberMMM() { romanNumerals = new RomanNumerals(3000); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("MMM"); @@ -176,6 +201,7 @@ public void test3000ToRomanNumberMMM() { @Disabled("Remove to run test") @Test + @DisplayName("3001 is MMMI") public void test3001ToRomanNumberMMMI() { romanNumerals = new RomanNumerals(3001); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("MMMI"); @@ -183,6 +209,7 @@ public void test3001ToRomanNumberMMMI() { @Disabled("Remove to run test") @Test + @DisplayName("3888 is MMMDCCCLXXXVIII") public void test3888ToRomanNumberMMMDCCCLXXXVIII() { romanNumerals = new RomanNumerals(3888); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("MMMDCCCLXXXVIII"); @@ -190,6 +217,7 @@ public void test3888ToRomanNumberMMMDCCCLXXXVIII() { @Disabled("Remove to run test") @Test + @DisplayName("3999 is MMMCMXCIX") public void test3999ToRomanNumberMMMCMXCIX() { romanNumerals = new RomanNumerals(3999); assertThat(romanNumerals.getRomanNumeral()).isEqualTo("MMMCMXCIX"); diff --git a/exercises/practice/rotational-cipher/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/rotational-cipher/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/rotational-cipher/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/rotational-cipher/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/rotational-cipher/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/rotational-cipher/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/rotational-cipher/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/rotational-cipher/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/rotational-cipher/gradlew b/exercises/practice/rotational-cipher/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/rotational-cipher/gradlew +++ b/exercises/practice/rotational-cipher/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/rotational-cipher/gradlew.bat b/exercises/practice/rotational-cipher/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/rotational-cipher/gradlew.bat +++ b/exercises/practice/rotational-cipher/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/rotational-cipher/src/test/java/RotationalCipherTest.java b/exercises/practice/rotational-cipher/src/test/java/RotationalCipherTest.java index cd18aa56e..be75833ab 100644 --- a/exercises/practice/rotational-cipher/src/test/java/RotationalCipherTest.java +++ b/exercises/practice/rotational-cipher/src/test/java/RotationalCipherTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -8,6 +9,7 @@ public class RotationalCipherTest { private RotationalCipher rotationalCipher; @Test + @DisplayName("rotate a by 0, same output as input") public void rotateSingleCharacterBy0() { rotationalCipher = new RotationalCipher(0); assertThat(rotationalCipher.rotate("a")).isEqualTo("a"); @@ -15,6 +17,7 @@ public void rotateSingleCharacterBy0() { @Disabled("Remove to run test") @Test + @DisplayName("rotate a by 1") public void rotateSingleCharacterBy1() { rotationalCipher = new RotationalCipher(1); assertThat(rotationalCipher.rotate("a")).isEqualTo("b"); @@ -22,6 +25,7 @@ public void rotateSingleCharacterBy1() { @Disabled("Remove to run test") @Test + @DisplayName("rotate a by 26, same output as input") public void rotateSingleCharacterBy26() { rotationalCipher = new RotationalCipher(26); assertThat(rotationalCipher.rotate("a")).isEqualTo("a"); @@ -29,6 +33,7 @@ public void rotateSingleCharacterBy26() { @Disabled("Remove to run test") @Test + @DisplayName("rotate m by 13") public void rotateSingleCharacterBy13() { rotationalCipher = new RotationalCipher(13); assertThat(rotationalCipher.rotate("m")).isEqualTo("z"); @@ -36,6 +41,7 @@ public void rotateSingleCharacterBy13() { @Disabled("Remove to run test") @Test + @DisplayName("rotate n by 13 with wrap around alphabet") public void rotateSingleCharacterWithWrapAround() { rotationalCipher = new RotationalCipher(13); assertThat(rotationalCipher.rotate("n")).isEqualTo("a"); @@ -43,6 +49,7 @@ public void rotateSingleCharacterWithWrapAround() { @Disabled("Remove to run test") @Test + @DisplayName("rotate capital letters") public void rotateCapitalLetters() { rotationalCipher = new RotationalCipher(5); assertThat(rotationalCipher.rotate("OMG")).isEqualTo("TRL"); @@ -50,6 +57,7 @@ public void rotateCapitalLetters() { @Disabled("Remove to run test") @Test + @DisplayName("rotate spaces") public void rotateSpaces() { rotationalCipher = new RotationalCipher(5); assertThat(rotationalCipher.rotate("O M G")).isEqualTo("T R L"); @@ -57,6 +65,7 @@ public void rotateSpaces() { @Disabled("Remove to run test") @Test + @DisplayName("rotate numbers") public void rotateNumbers() { rotationalCipher = new RotationalCipher(4); assertThat(rotationalCipher.rotate("Testing 1 2 3 testing")).isEqualTo("Xiwxmrk 1 2 3 xiwxmrk"); @@ -64,6 +73,7 @@ public void rotateNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("rotate punctuation") public void rotatePunctuation() { rotationalCipher = new RotationalCipher(21); assertThat(rotationalCipher.rotate("Let's eat, Grandma!")).isEqualTo("Gzo'n zvo, Bmviyhv!"); @@ -71,6 +81,7 @@ public void rotatePunctuation() { @Disabled("Remove to run test") @Test + @DisplayName("rotate all letters") public void rotateAllLetters() { rotationalCipher = new RotationalCipher(13); assertThat(rotationalCipher.rotate("Gur dhvpx oebja sbk whzcf bire gur ynml qbt.")) diff --git a/exercises/practice/run-length-encoding/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/run-length-encoding/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/run-length-encoding/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/run-length-encoding/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/run-length-encoding/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/run-length-encoding/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/run-length-encoding/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/run-length-encoding/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/run-length-encoding/gradlew b/exercises/practice/run-length-encoding/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/run-length-encoding/gradlew +++ b/exercises/practice/run-length-encoding/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/run-length-encoding/gradlew.bat b/exercises/practice/run-length-encoding/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/run-length-encoding/gradlew.bat +++ b/exercises/practice/run-length-encoding/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/run-length-encoding/src/test/java/RunLengthEncodingTest.java b/exercises/practice/run-length-encoding/src/test/java/RunLengthEncodingTest.java index 6923ccdbd..47373f2e2 100644 --- a/exercises/practice/run-length-encoding/src/test/java/RunLengthEncodingTest.java +++ b/exercises/practice/run-length-encoding/src/test/java/RunLengthEncodingTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -13,24 +14,28 @@ public void setUp() { } @Test + @DisplayName("empty string") public void encodeEmpty() { assertThat(runLengthEncoding.encode("")).isEmpty(); } @Disabled("Remove to run test") @Test + @DisplayName("single characters only are encoded without count") public void encodeWithOnlySingleValues() { assertThat(runLengthEncoding.encode("XYZ")).isEqualTo("XYZ"); } @Disabled("Remove to run test") @Test + @DisplayName("string with no single characters") public void encodeWithNoSingleValues() { assertThat(runLengthEncoding.encode("AABBBCCCC")).isEqualTo("2A3B4C"); } @Disabled("Remove to run test") @Test + @DisplayName("single characters mixed with repeated characters") public void encodeWithMixedValues() { assertThat(runLengthEncoding.encode( "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB")) @@ -39,6 +44,7 @@ public void encodeWithMixedValues() { @Disabled("Remove to run test") @Test + @DisplayName("multiple whitespace mixed in string") public void encodeWithWhitespaceValues() { assertThat(runLengthEncoding.encode(" hsqq qww ")) .isEqualTo("2 hs2q q2w2 "); @@ -46,30 +52,35 @@ public void encodeWithWhitespaceValues() { @Disabled("Remove to run test") @Test + @DisplayName("lowercase characters") public void encodeWithLowercaseValues() { assertThat(runLengthEncoding.encode("aabbbcccc")).isEqualTo("2a3b4c"); } @Disabled("Remove to run test") @Test + @DisplayName("empty string") public void decodeEmpty() { assertThat(runLengthEncoding.decode("")).isEmpty(); } @Disabled("Remove to run test") @Test + @DisplayName("single characters only") public void decodeWithOnlySingleValues() { assertThat(runLengthEncoding.decode("XYZ")).isEqualTo("XYZ"); } @Disabled("Remove to run test") @Test + @DisplayName("string with no single characters") public void decodeWithNoSingleValues() { assertThat(runLengthEncoding.decode("2A3B4C")).isEqualTo("AABBBCCCC"); } @Disabled("Remove to run test") @Test + @DisplayName("single characters with repeated characters") public void decodeWithMixedValues() { assertThat(runLengthEncoding.decode("12WB12W3B24WB")) .isEqualTo("WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB"); @@ -77,18 +88,21 @@ public void decodeWithMixedValues() { @Disabled("Remove to run test") @Test + @DisplayName("multiple whitespace mixed in string") public void decodeWithWhitespaceValues() { assertThat(runLengthEncoding.decode("2 hs2q q2w2 ")).isEqualTo(" hsqq qww "); } @Disabled("Remove to run test") @Test + @DisplayName("lowercase string") public void decodeWithLowercaseValues() { assertThat(runLengthEncoding.decode("2a3b4c")).isEqualTo("aabbbcccc"); } @Disabled("Remove to run test") @Test + @DisplayName("encode followed by decode gives original string") public void encodeThenDecode() { String inOut = "zzz ZZ zZ"; String encoded = runLengthEncoding.encode(inOut); diff --git a/exercises/practice/saddle-points/.docs/instructions.md b/exercises/practice/saddle-points/.docs/instructions.md index c585568b4..f69cdab95 100644 --- a/exercises/practice/saddle-points/.docs/instructions.md +++ b/exercises/practice/saddle-points/.docs/instructions.md @@ -13,11 +13,12 @@ Or it might have one, or even several. Here is a grid that has exactly one candidate tree. ```text - 1 2 3 4 - |----------- -1 | 9 8 7 8 -2 | 5 3 2 4 <--- potential tree house at row 2, column 1, for tree with height 5 -3 | 6 6 7 1 + ↓ + 1 2 3 4 + |----------- + 1 | 9 8 7 8 +→ 2 |[5] 3 2 4 + 3 | 6 6 7 1 ``` - Row 2 has values 5, 3, 2, and 4. The largest value is 5. diff --git a/exercises/practice/saddle-points/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/saddle-points/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/saddle-points/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/saddle-points/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/saddle-points/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/saddle-points/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/saddle-points/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/saddle-points/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/saddle-points/gradlew b/exercises/practice/saddle-points/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/saddle-points/gradlew +++ b/exercises/practice/saddle-points/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/saddle-points/gradlew.bat b/exercises/practice/saddle-points/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/saddle-points/gradlew.bat +++ b/exercises/practice/saddle-points/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/saddle-points/src/test/java/MatrixTest.java b/exercises/practice/saddle-points/src/test/java/MatrixTest.java index 6bcb5afcb..56b5087fc 100644 --- a/exercises/practice/saddle-points/src/test/java/MatrixTest.java +++ b/exercises/practice/saddle-points/src/test/java/MatrixTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.ArrayList; @@ -12,6 +13,7 @@ public class MatrixTest { @Test + @DisplayName("Can identify single saddle point") public void testCanIdentifySingleSaddlePoint() { Matrix matrix = new Matrix(Arrays.asList( Arrays.asList(9, 8, 7), @@ -26,6 +28,7 @@ public void testCanIdentifySingleSaddlePoint() { @Disabled("Remove to run test") @Test + @DisplayName("Can identify that empty matrix has no saddle points") public void testCanIdentifyThatEmptyMatrixHasNoSaddlePoints() { Matrix matrix = new Matrix(new ArrayList<>()); @@ -36,6 +39,7 @@ public void testCanIdentifyThatEmptyMatrixHasNoSaddlePoints() { @Disabled("Remove to run test") @Test + @DisplayName("Can identify lack of saddle points when there are none") public void testCanIdentifyLackOfSaddlePointsWhenThereAreNone() { Matrix matrix = new Matrix(Arrays.asList( Arrays.asList(1, 2, 3), @@ -50,6 +54,7 @@ public void testCanIdentifyLackOfSaddlePointsWhenThereAreNone() { @Disabled("Remove to run test") @Test + @DisplayName("Can identify multiple saddle points in a column") public void testCanIdentifyMultipleSaddlePointsInAColumn() { Matrix matrix = new Matrix(Arrays.asList( Arrays.asList(4, 5, 4), @@ -68,6 +73,7 @@ public void testCanIdentifyMultipleSaddlePointsInAColumn() { @Disabled("Remove to run test") @Test + @DisplayName("Can identify multiple saddle points in a Row") public void testCanIdentifyMultipleSaddlePointsInARow() { Matrix matrix = new Matrix(Arrays.asList( Arrays.asList(6, 7, 8), @@ -86,6 +92,7 @@ public void testCanIdentifyMultipleSaddlePointsInARow() { @Disabled("Remove to run test") @Test + @DisplayName("Can identify saddle point in bottom right corner") public void testCanIdentifySaddlePointInBottomRightCorner() { Matrix matrix = new Matrix(Arrays.asList( Arrays.asList(8, 7, 9), @@ -100,6 +107,7 @@ public void testCanIdentifySaddlePointInBottomRightCorner() { @Disabled("Remove to run test") @Test + @DisplayName("Can identify saddle points in a non square matrix") public void testCanIdentifySaddlePointsInANonSquareMatrix() { Matrix matrix = new Matrix(Arrays.asList( Arrays.asList(3, 1, 3), @@ -116,6 +124,7 @@ public void testCanIdentifySaddlePointsInANonSquareMatrix() { @Disabled("Remove to run test") @Test + @DisplayName("Can identify that saddle points in a single column matrix are those with the minimum value") public void testCanIdentifyThatSaddlePointsInASingleColumnMatrixAreThoseWithMinimumValue() { Matrix matrix = new Matrix(Arrays.asList( Collections.singletonList(2), @@ -134,6 +143,7 @@ public void testCanIdentifyThatSaddlePointsInASingleColumnMatrixAreThoseWithMini @Disabled("Remove to run test") @Test + @DisplayName("Can identify that saddle points in a single row matrix are those with the maximum value") public void testCanIdentifyThatSaddlePointsInASingleRowMatrixAreThoseWithMaximumValue() { Matrix matrix = new Matrix(Arrays.asList( Arrays.asList(2, 5, 3, 5) diff --git a/exercises/practice/satellite/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/satellite/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/satellite/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/satellite/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/satellite/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/satellite/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/satellite/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/satellite/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/satellite/gradlew b/exercises/practice/satellite/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/satellite/gradlew +++ b/exercises/practice/satellite/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/satellite/gradlew.bat b/exercises/practice/satellite/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/satellite/gradlew.bat +++ b/exercises/practice/satellite/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/satellite/src/test/java/SatelliteTest.java b/exercises/practice/satellite/src/test/java/SatelliteTest.java index 52bd9e97c..7b3c62d93 100644 --- a/exercises/practice/satellite/src/test/java/SatelliteTest.java +++ b/exercises/practice/satellite/src/test/java/SatelliteTest.java @@ -3,12 +3,14 @@ import java.util.List; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; public class SatelliteTest { Satellite satellite = new Satellite(); @Test + @DisplayName("Empty tree") public void emptyTree() { List preorder = List.of(); List inorder = List.of(); @@ -22,6 +24,7 @@ public void emptyTree() { @Disabled("Remove to run test") @Test + @DisplayName("Tree with one item") public void treeWithOneItem() { List preorder = List.of('a'); List inorder = List.of('a'); @@ -35,6 +38,7 @@ public void treeWithOneItem() { @Disabled("Remove to run test") @Test + @DisplayName("Tree with many items") public void treeWithManyItems() { List preorder = List.of('a', 'i', 'x', 'f', 'r'); List inorder = List.of('i', 'a', 'f', 'x', 'r'); @@ -48,6 +52,7 @@ public void treeWithManyItems() { @Disabled("Remove to run test") @Test + @DisplayName("Reject traversals of different length") public void rejectTraversalsOfDifferentLengths() { List preorder = List.of('a', 'b'); List inorder = List.of('b', 'a', 'r'); @@ -60,6 +65,7 @@ public void rejectTraversalsOfDifferentLengths() { @Disabled("Remove to run test") @Test + @DisplayName("Reject inconsistent traversals of same length") public void rejectInconsistentTraversalsOfSameLength() { List preorder = List.of('x', 'y', 'z'); List inorder = List.of('a', 'b', 'c'); @@ -71,6 +77,7 @@ public void rejectInconsistentTraversalsOfSameLength() { @Disabled("Remove to run test") @Test + @DisplayName("Reject traversals with repeated items") public void rejectTraversalsWithRepeatedItems() { List preorder = List.of('a', 'b', 'a'); List inorder = List.of('b', 'a', 'a'); diff --git a/exercises/practice/say/.docs/instructions.md b/exercises/practice/say/.docs/instructions.md index ad3d34778..3251c519a 100644 --- a/exercises/practice/say/.docs/instructions.md +++ b/exercises/practice/say/.docs/instructions.md @@ -1,48 +1,12 @@ # Instructions -Given a number from 0 to 999,999,999,999, spell out that number in English. +Given a number, your task is to express it in English words exactly as your friend should say it out loud. +Yaʻqūb expects to use numbers from 0 up to 999,999,999,999. -## Step 1 +Examples: -Handle the basic case of 0 through 99. - -If the input to the program is `22`, then the output should be `'twenty-two'`. - -Your program should complain loudly if given a number outside the blessed range. - -Some good test cases for this program are: - -- 0 -- 14 -- 50 -- 98 -- -1 -- 100 - -### Extension - -If you're on a Mac, shell out to Mac OS X's `say` program to talk out loud. -If you're on Linux or Windows, eSpeakNG may be available with the command `espeak`. - -## Step 2 - -Implement breaking a number up into chunks of thousands. - -So `1234567890` should yield a list like 1, 234, 567, and 890, while the far simpler `1000` should yield just 1 and 0. - -## Step 3 - -Now handle inserting the appropriate scale word between those chunks. - -So `1234567890` should yield `'1 billion 234 million 567 thousand 890'` - -The program must also report any values that are out of range. -It's fine to stop at "trillion". - -## Step 4 - -Put it all together to get nothing but plain English. - -`12345` should give `twelve thousand three hundred forty-five`. - -The program must also report any values that are out of range. +- 0 → zero +- 1 → one +- 12 → twelve +- 123 → one hundred twenty-three +- 1,234 → one thousand two hundred thirty-four diff --git a/exercises/practice/say/.docs/introduction.md b/exercises/practice/say/.docs/introduction.md new file mode 100644 index 000000000..abd22851e --- /dev/null +++ b/exercises/practice/say/.docs/introduction.md @@ -0,0 +1,6 @@ +# Introduction + +Your friend Yaʻqūb works the counter at the busiest deli in town, slicing, weighing, and wrapping orders for a never-ending line of hungry customers. +To keep things moving, each customer takes a numbered ticket when they arrive. + +When it’s time to call the next person, Yaʻqūb reads their number out loud, always in full English words to make sure everyone hears it clearly. diff --git a/exercises/practice/say/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/say/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/say/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/say/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/say/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/say/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/say/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/say/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/say/gradlew b/exercises/practice/say/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/say/gradlew +++ b/exercises/practice/say/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/say/gradlew.bat b/exercises/practice/say/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/say/gradlew.bat +++ b/exercises/practice/say/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/say/src/test/java/SayTest.java b/exercises/practice/say/src/test/java/SayTest.java index 9e7090d53..2a999c517 100644 --- a/exercises/practice/say/src/test/java/SayTest.java +++ b/exercises/practice/say/src/test/java/SayTest.java @@ -1,5 +1,6 @@ -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.*; @@ -8,102 +9,119 @@ public class SayTest { private Say say = new Say(); @Test + @DisplayName("zero") public void zero() { assertThat(say.say(0)).isEqualTo("zero"); } @Disabled("Remove to run test") @Test + @DisplayName("one") public void one() { assertThat(say.say(1)).isEqualTo("one"); } @Disabled("Remove to run test") @Test + @DisplayName("fourteen") public void fourteen() { assertThat(say.say(14)).isEqualTo("fourteen"); } @Disabled("Remove to run test") @Test + @DisplayName("twenty") public void twenty() { assertThat(say.say(20)).isEqualTo("twenty"); } @Disabled("Remove to run test") @Test + @DisplayName("twenty-two") public void twentyTwo() { assertThat(say.say(22)).isEqualTo("twenty-two"); } @Disabled("Remove to run test") @Test + @DisplayName("thirty") public void thirty() { assertThat(say.say(30)).isEqualTo("thirty"); } @Disabled("Remove to run test") @Test + @DisplayName("ninety-nine") public void ninetyNine() { assertThat(say.say(99)).isEqualTo("ninety-nine"); } @Disabled("Remove to run test") @Test + @DisplayName("one hundred") public void oneHundred() { assertThat(say.say(100)).isEqualTo("one hundred"); } @Disabled("Remove to run test") @Test + @DisplayName("one hundred twenty-three") public void oneHundredTwentyThree() { assertThat(say.say(123)).isEqualTo("one hundred twenty-three"); } @Disabled("Remove to run test") @Test + @DisplayName("two hundred") public void twoHundred() { assertThat(say.say(200)).isEqualTo("two hundred"); } @Disabled("Remove to run test") @Test + @DisplayName("nine hundred ninety-nine") public void nineHundredNinetyNine() { assertThat(say.say(999)).isEqualTo("nine hundred ninety-nine"); } @Disabled("Remove to run test") @Test + @DisplayName("one thousand") public void oneThousand() { assertThat(say.say(1_000)).isEqualTo("one thousand"); } @Disabled("Remove to run test") @Test + @DisplayName("one thousand two hundred thirty-four") public void oneThousandTwoHundredThirtyFour() { assertThat(say.say(1_234)).isEqualTo("one thousand two hundred thirty-four"); } @Disabled("Remove to run test") @Test + @DisplayName("one million") public void oneMillion() { assertThat(say.say(1_000_000)).isEqualTo("one million"); } @Disabled("Remove to run test") @Test + @DisplayName("one million two thousand three hundred forty-five") public void oneMillionTwoThousandThreeHundredFortyFive() { assertThat(say.say(1_002_345)).isEqualTo("one million two thousand three hundred forty-five"); } @Disabled("Remove to run test") @Test + @DisplayName("one billion") public void oneBillion() { assertThat(say.say(1_000_000_000)).isEqualTo("one billion"); } @Disabled("Remove to run test") @Test + @DisplayName("a big number") public void nineHundredEightySevenBillionSixHundredFiftyFourThreeHundredTwentyOneThousandOneHundredTwentyThree() { assertThat(say.say(987_654_321_123L)) .isEqualTo("nine hundred eighty-seven billion six hundred fifty-four million" + @@ -112,6 +130,7 @@ public void nineHundredEightySevenBillionSixHundredFiftyFourThreeHundredTwentyOn @Disabled("Remove to run test") @Test + @DisplayName("numbers below zero are out of range") public void illegalNegativeNumber() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> say.say(-1)); @@ -119,6 +138,7 @@ public void illegalNegativeNumber() { @Disabled("Remove to run test") @Test + @DisplayName("numbers above 999,999,999,999 are out of range") public void illegalTooBigNumber() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> say.say(1_000_000_000_000L)); diff --git a/exercises/practice/scrabble-score/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/scrabble-score/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/scrabble-score/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/scrabble-score/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/scrabble-score/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/scrabble-score/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/scrabble-score/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/scrabble-score/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/scrabble-score/gradlew b/exercises/practice/scrabble-score/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/scrabble-score/gradlew +++ b/exercises/practice/scrabble-score/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/scrabble-score/gradlew.bat b/exercises/practice/scrabble-score/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/scrabble-score/gradlew.bat +++ b/exercises/practice/scrabble-score/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/scrabble-score/src/test/java/ScrabbleScoreTest.java b/exercises/practice/scrabble-score/src/test/java/ScrabbleScoreTest.java index 1be75ea9b..9fc05c0f5 100644 --- a/exercises/practice/scrabble-score/src/test/java/ScrabbleScoreTest.java +++ b/exercises/practice/scrabble-score/src/test/java/ScrabbleScoreTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -6,6 +7,7 @@ public class ScrabbleScoreTest { @Test + @DisplayName("lowercase letter") public void testALowerCaseLetter() { Scrabble scrabble = new Scrabble("a"); assertThat(scrabble.getScore()).isEqualTo(1); @@ -13,6 +15,7 @@ public void testALowerCaseLetter() { @Disabled("Remove to run test") @Test + @DisplayName("uppercase letter") public void testAUpperCaseLetter() { Scrabble scrabble = new Scrabble("A"); assertThat(scrabble.getScore()).isEqualTo(1); @@ -20,6 +23,7 @@ public void testAUpperCaseLetter() { @Disabled("Remove to run test") @Test + @DisplayName("valuable letter") public void testAValuableLetter() { Scrabble scrabble = new Scrabble("f"); assertThat(scrabble.getScore()).isEqualTo(4); @@ -27,6 +31,7 @@ public void testAValuableLetter() { @Disabled("Remove to run test") @Test + @DisplayName("short word") public void testAShortWord() { Scrabble scrabble = new Scrabble("at"); assertThat(scrabble.getScore()).isEqualTo(2); @@ -34,6 +39,7 @@ public void testAShortWord() { @Disabled("Remove to run test") @Test + @DisplayName("short, valuable word") public void testAShortValuableWord() { Scrabble scrabble = new Scrabble("zoo"); assertThat(scrabble.getScore()).isEqualTo(12); @@ -41,6 +47,7 @@ public void testAShortValuableWord() { @Disabled("Remove to run test") @Test + @DisplayName("medium word") public void testAMediumWord() { Scrabble scrabble = new Scrabble("street"); assertThat(scrabble.getScore()).isEqualTo(6); @@ -48,6 +55,7 @@ public void testAMediumWord() { @Disabled("Remove to run test") @Test + @DisplayName("medium, valuable word") public void testAMediumValuableWord() { Scrabble scrabble = new Scrabble("quirky"); assertThat(scrabble.getScore()).isEqualTo(22); @@ -55,6 +63,7 @@ public void testAMediumValuableWord() { @Disabled("Remove to run test") @Test + @DisplayName("long, mixed-case word") public void testALongMixCaseWord() { Scrabble scrabble = new Scrabble("OxyphenButazone"); assertThat(scrabble.getScore()).isEqualTo(41); @@ -62,6 +71,7 @@ public void testALongMixCaseWord() { @Disabled("Remove to run test") @Test + @DisplayName("english-like word") public void testAEnglishLikeWord() { Scrabble scrabble = new Scrabble("pinata"); assertThat(scrabble.getScore()).isEqualTo(8); @@ -69,6 +79,7 @@ public void testAEnglishLikeWord() { @Disabled("Remove to run test") @Test + @DisplayName("empty input") public void testAnEmptyInput() { Scrabble scrabble = new Scrabble(""); assertThat(scrabble.getScore()).isEqualTo(0); @@ -76,6 +87,7 @@ public void testAnEmptyInput() { @Disabled("Remove to run test") @Test + @DisplayName("entire alphabet available") public void testEntireAlphabetAvailable() { Scrabble scrabble = new Scrabble("abcdefghijklmnopqrstuvwxyz"); assertThat(scrabble.getScore()).isEqualTo(87); diff --git a/exercises/practice/secret-handshake/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/secret-handshake/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/secret-handshake/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/secret-handshake/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/secret-handshake/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/secret-handshake/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/secret-handshake/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/secret-handshake/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/secret-handshake/gradlew b/exercises/practice/secret-handshake/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/secret-handshake/gradlew +++ b/exercises/practice/secret-handshake/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/secret-handshake/gradlew.bat b/exercises/practice/secret-handshake/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/secret-handshake/gradlew.bat +++ b/exercises/practice/secret-handshake/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/secret-handshake/src/test/java/HandshakeCalculatorTest.java b/exercises/practice/secret-handshake/src/test/java/HandshakeCalculatorTest.java index 286bff45b..a1cc3ce32 100644 --- a/exercises/practice/secret-handshake/src/test/java/HandshakeCalculatorTest.java +++ b/exercises/practice/secret-handshake/src/test/java/HandshakeCalculatorTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -8,30 +9,35 @@ public class HandshakeCalculatorTest { private final HandshakeCalculator handshakeCalculator = new HandshakeCalculator(); @Test + @DisplayName("wink for 1") public void testThatInput1YieldsAWink() { assertThat(handshakeCalculator.calculateHandshake(1)).containsExactly(Signal.WINK); } @Disabled("Remove to run test") @Test + @DisplayName("double blink for 10") public void testThatInput2YieldsADoubleBlink() { assertThat(handshakeCalculator.calculateHandshake(2)).containsExactly(Signal.DOUBLE_BLINK); } @Disabled("Remove to run test") @Test + @DisplayName("close your eyes for 100") public void testThatInput4YieldsACloseYourEyes() { assertThat(handshakeCalculator.calculateHandshake(4)).containsExactly(Signal.CLOSE_YOUR_EYES); } @Disabled("Remove to run test") @Test + @DisplayName("jump for 1000") public void testThatInput8YieldsAJump() { assertThat(handshakeCalculator.calculateHandshake(8)).containsExactly(Signal.JUMP); } @Disabled("Remove to run test") @Test + @DisplayName("combine two actions") public void testAnInputThatYieldsTwoActions() { assertThat(handshakeCalculator.calculateHandshake(3)) .containsExactly(Signal.WINK, Signal.DOUBLE_BLINK); @@ -39,6 +45,7 @@ public void testAnInputThatYieldsTwoActions() { @Disabled("Remove to run test") @Test + @DisplayName("reverse two actions") public void testAnInputThatYieldsTwoReversedActions() { assertThat(handshakeCalculator.calculateHandshake(19)) .containsExactly(Signal.DOUBLE_BLINK, Signal.WINK); @@ -46,18 +53,21 @@ public void testAnInputThatYieldsTwoReversedActions() { @Disabled("Remove to run test") @Test + @DisplayName("reversing one action gives the same action") public void testReversingASingleActionYieldsTheSameAction() { assertThat(handshakeCalculator.calculateHandshake(24)).containsExactly(Signal.JUMP); } @Disabled("Remove to run test") @Test + @DisplayName("reversing no actions still gives no actions") public void testReversingNoActionsYieldsNoActions() { assertThat(handshakeCalculator.calculateHandshake(16)).isEmpty(); } @Disabled("Remove to run test") @Test + @DisplayName("all possible actions") public void testInputThatYieldsAllActions() { assertThat(handshakeCalculator.calculateHandshake(15)) .containsExactly(Signal.WINK, Signal.DOUBLE_BLINK, Signal.CLOSE_YOUR_EYES, Signal.JUMP); @@ -65,6 +75,7 @@ public void testInputThatYieldsAllActions() { @Disabled("Remove to run test") @Test + @DisplayName("reverse all possible actions") public void testInputThatYieldsAllActionsReversed() { assertThat(handshakeCalculator.calculateHandshake(31)) .containsExactly(Signal.JUMP, Signal.CLOSE_YOUR_EYES, Signal.DOUBLE_BLINK, Signal.WINK); @@ -72,12 +83,18 @@ public void testInputThatYieldsAllActionsReversed() { @Disabled("Remove to run test") @Test + @DisplayName("do nothing for zero") public void testThatInput0YieldsNoActions() { assertThat(handshakeCalculator.calculateHandshake(0)).isEmpty(); } + /* The following tests diverge from the canonical test data to test numbers with binary representation with + * more than five digits are correctly handled. For more details, check out issue #1965 here: + * (https://github.com/exercism/java/issues/1965). + */ @Disabled("Remove to run test") @Test + @DisplayName("handles input with more than five bits with reversal") public void testThatHandlesMoreThanFiveBinaryPlacesWithReversal() { assertThat(handshakeCalculator.calculateHandshake(51)) .containsExactly(Signal.DOUBLE_BLINK, Signal.WINK); @@ -85,6 +102,7 @@ public void testThatHandlesMoreThanFiveBinaryPlacesWithReversal() { @Disabled("Remove to run test") @Test + @DisplayName("handles input with more than five bits without reversal") public void testThatHandlesMoreThanFiveBinaryPlacesWithoutReversal() { assertThat(handshakeCalculator.calculateHandshake(35)) .containsExactly(Signal.WINK, Signal.DOUBLE_BLINK); @@ -92,6 +110,7 @@ public void testThatHandlesMoreThanFiveBinaryPlacesWithoutReversal() { @Disabled("Remove to run test") @Test + @DisplayName("all actions for input with more than five bits") public void testInputThatYieldsAllActionsFromMoreThanFiveBinaryPlaces() { assertThat(handshakeCalculator.calculateHandshake(111)) .containsExactly(Signal.WINK, Signal.DOUBLE_BLINK, Signal.CLOSE_YOUR_EYES, Signal.JUMP); diff --git a/exercises/practice/series/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/series/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/series/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/series/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/series/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/series/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/series/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/series/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/series/gradlew b/exercises/practice/series/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/series/gradlew +++ b/exercises/practice/series/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/series/gradlew.bat b/exercises/practice/series/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/series/gradlew.bat +++ b/exercises/practice/series/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/series/src/test/java/SeriesTest.java b/exercises/practice/series/src/test/java/SeriesTest.java index 2009d437b..726e9fd24 100644 --- a/exercises/practice/series/src/test/java/SeriesTest.java +++ b/exercises/practice/series/src/test/java/SeriesTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.Arrays; @@ -11,6 +12,7 @@ public class SeriesTest { @Test + @DisplayName("slices of one from one") public void slicesOfOneFromOne() { Series series = new Series("1"); List expected = Collections.singletonList("1"); @@ -20,6 +22,7 @@ public void slicesOfOneFromOne() { @Disabled("Remove to run test") @Test + @DisplayName("slices of one from two") public void slicesOfOneFromTwo() { Series series = new Series("12"); List expected = Arrays.asList("1", "2"); @@ -29,6 +32,7 @@ public void slicesOfOneFromTwo() { @Disabled("Remove to run test") @Test + @DisplayName("slices of two") public void slicesOfTwo() { Series series = new Series("35"); List expected = Collections.singletonList("35"); @@ -38,6 +42,7 @@ public void slicesOfTwo() { @Disabled("Remove to run test") @Test + @DisplayName("slices of two overlap") public void slicesOfTwoOverlap() { Series series = new Series("9142"); List expected = Arrays.asList("91", "14", "42"); @@ -47,6 +52,7 @@ public void slicesOfTwoOverlap() { @Disabled("Remove to run test") @Test + @DisplayName("slices can include duplicates") public void slicesIncludeDuplicates() { Series series = new Series("777777"); List expected = Arrays.asList( @@ -61,6 +67,7 @@ public void slicesIncludeDuplicates() { @Disabled("Remove to run test") @Test + @DisplayName("slices of a long series") public void slicesOfLongSeries() { Series series = new Series("918493904243"); List expected = Arrays.asList( @@ -79,6 +86,7 @@ public void slicesOfLongSeries() { @Disabled("Remove to run test") @Test + @DisplayName("slice length is too large") public void sliceLengthIsToolarge() { Series series = new Series("12345"); @@ -89,6 +97,7 @@ public void sliceLengthIsToolarge() { @Disabled("Remove to run test") @Test + @DisplayName("slice length is way too large") public void sliceLengthIsWayToolarge() { Series series = new Series("12345"); @@ -99,6 +108,7 @@ public void sliceLengthIsWayToolarge() { @Disabled("Remove to run test") @Test + @DisplayName("slice length cannot be zero") public void sliceLengthZero() { Series series = new Series("12345"); @@ -109,6 +119,7 @@ public void sliceLengthZero() { @Disabled("Remove to run test") @Test + @DisplayName("slice length cannot be negative") public void sliceLengthNegative() { Series series = new Series("123"); @@ -119,6 +130,7 @@ public void sliceLengthNegative() { @Disabled("Remove to run test") @Test + @DisplayName("empty series is invalid") public void emptySeries() { assertThatExceptionOfType(IllegalArgumentException.class) diff --git a/exercises/practice/sgf-parsing/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/sgf-parsing/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/sgf-parsing/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/sgf-parsing/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/sgf-parsing/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/sgf-parsing/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/sgf-parsing/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/sgf-parsing/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/sgf-parsing/gradlew b/exercises/practice/sgf-parsing/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/sgf-parsing/gradlew +++ b/exercises/practice/sgf-parsing/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/sgf-parsing/gradlew.bat b/exercises/practice/sgf-parsing/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/sgf-parsing/gradlew.bat +++ b/exercises/practice/sgf-parsing/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/sgf-parsing/src/test/java/SgfParsingTest.java b/exercises/practice/sgf-parsing/src/test/java/SgfParsingTest.java index 6e15ca04b..afd458506 100644 --- a/exercises/practice/sgf-parsing/src/test/java/SgfParsingTest.java +++ b/exercises/practice/sgf-parsing/src/test/java/SgfParsingTest.java @@ -5,11 +5,13 @@ import java.util.Map; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; public class SgfParsingTest { @Test + @DisplayName("empty input") public void emptyInput() { String input = ""; assertThatExceptionOfType(SgfParsingException.class).as("tree missing") @@ -18,6 +20,7 @@ public void emptyInput() { @Test @Disabled("Remove to run test") + @DisplayName("tree with no nodes") public void treeWithNoNodes() { String input = "()"; assertThatExceptionOfType(SgfParsingException.class) @@ -27,6 +30,7 @@ public void treeWithNoNodes() { @Test @Disabled("Remove to run test") + @DisplayName("node without tree") public void nodeWithoutTree() { String input = ";"; assertThatExceptionOfType(SgfParsingException.class).as("tree missing") @@ -35,6 +39,7 @@ public void nodeWithoutTree() { @Test @Disabled("Remove to run test") + @DisplayName("node without properties") public void nodeWithoutProperties() throws SgfParsingException { String input = "(;)"; SgfNode expected = new SgfNode(); @@ -44,6 +49,7 @@ public void nodeWithoutProperties() throws SgfParsingException { @Test @Disabled("Remove to run test") + @DisplayName("single node tree") public void singleNodeTree() throws SgfParsingException { String input = "(;A[B])"; SgfNode expected = new SgfNode(Map.of("A", List.of("B"))); @@ -53,6 +59,7 @@ public void singleNodeTree() throws SgfParsingException { @Test @Disabled("Remove to run test") + @DisplayName("multiple properties") public void multipleProperties() throws SgfParsingException { String input = "(;A[b]C[d])"; SgfNode expected = new SgfNode(Map.of("A", List.of("b"), @@ -63,6 +70,7 @@ public void multipleProperties() throws SgfParsingException { @Test @Disabled("Remove to run test") + @DisplayName("properties without delimiter") public void propertiesWithoutDelimiter() { String input = "(;A)"; assertThatExceptionOfType(SgfParsingException.class).as("properties without delimiter") @@ -71,6 +79,7 @@ public void propertiesWithoutDelimiter() { @Test @Disabled("Remove to run test") + @DisplayName("all lowercase property") public void allLowercaseProperty() { String input = "(;a[b])"; assertThatExceptionOfType(SgfParsingException.class).as("property must be in uppercase") @@ -79,6 +88,7 @@ public void allLowercaseProperty() { @Test @Disabled("Remove to run test") + @DisplayName("upper and lowercase property") public void upperAndLowercaseProperty() { String input = "(;Aa[b])"; assertThatExceptionOfType(SgfParsingException.class).as("property must be in uppercase") @@ -87,6 +97,7 @@ public void upperAndLowercaseProperty() { @Test @Disabled("Remove to run test") + @DisplayName("two nodes") public void twoNodes() throws SgfParsingException { String input = "(;A[B];B[C])"; SgfNode expected = new SgfNode(Map.of("A", List.of("B")), @@ -99,6 +110,7 @@ public void twoNodes() throws SgfParsingException { @Test @Disabled("Remove to run test") + @DisplayName("two child trees") public void twoChildTrees() throws SgfParsingException { String input = "(;A[B](;B[C])(;C[D]))"; SgfNode expected = new SgfNode(Map.of("A", List.of("B")), @@ -112,6 +124,7 @@ public void twoChildTrees() throws SgfParsingException { @Test @Disabled("Remove to run test") + @DisplayName("multiple property values") public void multiplePropertyValues() throws SgfParsingException { String input = "(;A[b][c][d])"; SgfNode expected = new SgfNode(Map.of("A", List.of("b", "c", "d"))); @@ -121,6 +134,7 @@ public void multiplePropertyValues() throws SgfParsingException { @Test @Disabled("Remove to run test") + @DisplayName("within property values, whitespace characters such as tab are converted to spaces") public void withinPropertyValueWhitespace() throws SgfParsingException { String input = "(;A[hello\t\tworld])"; SgfNode expected = new SgfNode(Map.of("A", List.of("hello world"))); @@ -130,6 +144,7 @@ public void withinPropertyValueWhitespace() throws SgfParsingException { @Test @Disabled("Remove to run test") + @DisplayName("within property values, newlines remain as newlines") public void withinPropertyValueNewline() throws SgfParsingException { String input = "(;A[hello\n\nworld])"; SgfNode expected = new SgfNode(Map.of("A", List.of("hello\n\nworld"))); @@ -139,6 +154,7 @@ public void withinPropertyValueNewline() throws SgfParsingException { @Test @Disabled("Remove to run test") + @DisplayName("escaped closing bracket within property value becomes just a closing bracket") public void escapedClosingBracket() throws SgfParsingException { String input = "(;A[\\]])"; SgfNode expected = new SgfNode(Map.of("A", List.of("]"))); @@ -148,6 +164,7 @@ public void escapedClosingBracket() throws SgfParsingException { @Test @Disabled("Remove to run test") + @DisplayName("escaped backslash in property value becomes just a backslash") public void escapedBacklash() throws SgfParsingException { String input = "(;A[\\\\])"; SgfNode expected = new SgfNode(Map.of("A", List.of("\\"))); @@ -157,6 +174,7 @@ public void escapedBacklash() throws SgfParsingException { @Test @Disabled("Remove to run test") + @DisplayName("opening bracket within property value doesn't need to be escaped") public void openingBracketNeedNotToBeEscaped() throws SgfParsingException { String input = "(;A[x[y\\]z][foo]B[bar];C[baz])"; SgfNode expected = new SgfNode(Map.of("A", List.of("x[y]z", "foo"), @@ -170,6 +188,7 @@ public void openingBracketNeedNotToBeEscaped() throws SgfParsingException { @Test @Disabled("Remove to run test") + @DisplayName("semicolon in property value doesn't need to be escaped") public void semicolonNeedNotToBeEscaped() throws SgfParsingException { String input = "(;A[a;b][foo]B[bar];C[baz])"; SgfNode expected = new SgfNode(Map.of("A", List.of("a;b", "foo"), @@ -183,6 +202,7 @@ public void semicolonNeedNotToBeEscaped() throws SgfParsingException { @Test @Disabled("Remove to run test") + @DisplayName("parentheses in property value don't need to be escaped") public void paranthesesNeedNotToBeEscaped() throws SgfParsingException { String input = "(;A[x(y)z][foo]B[bar];C[baz])"; SgfNode expected = new SgfNode(Map.of("A", List.of("x(y)z", "foo"), @@ -196,6 +216,7 @@ public void paranthesesNeedNotToBeEscaped() throws SgfParsingException { @Test @Disabled("Remove to run test") + @DisplayName("escaped tab in property value is converted to space") public void escapedTab() throws SgfParsingException { String input = "(;A[hello\\\tworld])"; SgfNode expected = new SgfNode(Map.of("A", List.of("hello world"))); @@ -205,6 +226,7 @@ public void escapedTab() throws SgfParsingException { @Test @Disabled("Remove to run test") + @DisplayName("escaped newline in property value is converted to nothing at all") public void escapedNewline() throws SgfParsingException { String input = "(;A[hello\\\nworld])"; SgfNode expected = new SgfNode(Map.of("A", List.of("helloworld"))); @@ -215,6 +237,7 @@ public void escapedNewline() throws SgfParsingException { @Test @Disabled("Remove to run test") + @DisplayName("escaped t and n in property value are just letters, not whitespace") public void escapedTAndN() throws SgfParsingException { String input = "(;A[\\t = t and \\n = n])"; SgfNode expected = new SgfNode(Map.of("A", List.of("t = t and n = n"))); @@ -225,6 +248,7 @@ public void escapedTAndN() throws SgfParsingException { @Test @Disabled("Remove to run test") + @DisplayName("mixing various kinds of whitespace and escaped characters in property value") public void mixOfEscapedCharactersAndWhitespaces() throws SgfParsingException { String input = "(;A[\\]b\nc\\\nd\t\te\\\\ \\\n\\]])"; SgfNode expected = new SgfNode(Map.of("A", List.of("]b\ncd e\\ ]"))); diff --git a/exercises/practice/sieve/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/sieve/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/sieve/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/sieve/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/sieve/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/sieve/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/sieve/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/sieve/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/sieve/gradlew b/exercises/practice/sieve/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/sieve/gradlew +++ b/exercises/practice/sieve/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/sieve/gradlew.bat b/exercises/practice/sieve/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/sieve/gradlew.bat +++ b/exercises/practice/sieve/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/sieve/src/test/java/SieveTest.java b/exercises/practice/sieve/src/test/java/SieveTest.java index b213ac0f7..529329323 100644 --- a/exercises/practice/sieve/src/test/java/SieveTest.java +++ b/exercises/practice/sieve/src/test/java/SieveTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.Arrays; @@ -10,6 +11,7 @@ public class SieveTest { @Test + @DisplayName("no primes under two") public void noPrimesUnder2() { Sieve sieve = new Sieve(1); List expectedOutput = Collections.emptyList(); @@ -19,6 +21,7 @@ public void noPrimesUnder2() { @Disabled("Remove to run test") @Test + @DisplayName("find first prime") public void findFirstPrime() { Sieve sieve = new Sieve(2); List expectedOutput = Collections.singletonList(2); @@ -28,6 +31,7 @@ public void findFirstPrime() { @Disabled("Remove to run test") @Test + @DisplayName("find primes up to 10") public void findPrimesUpTo10() { Sieve sieve = new Sieve(10); List expectedOutput = Arrays.asList(2, 3, 5, 7); @@ -37,6 +41,7 @@ public void findPrimesUpTo10() { @Disabled("Remove to run test") @Test + @DisplayName("limit is prime") public void limitIsPrime() { Sieve sieve = new Sieve(13); List expectedOutput = Arrays.asList(2, 3, 5, 7, 11, 13); @@ -46,6 +51,7 @@ public void limitIsPrime() { @Disabled("Remove to run test") @Test + @DisplayName("find primes up to 1000") public void findPrimesUpTo1000() { Sieve sieve = new Sieve(1000); List expectedOutput = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, diff --git a/exercises/practice/simple-cipher/.docs/instructions.md b/exercises/practice/simple-cipher/.docs/instructions.md index 337857442..afd0b57da 100644 --- a/exercises/practice/simple-cipher/.docs/instructions.md +++ b/exercises/practice/simple-cipher/.docs/instructions.md @@ -1,66 +1,40 @@ # Instructions -Implement a simple shift cipher like Caesar and a more secure substitution cipher. +Create an implementation of the [Vigenère cipher][wiki]. +The Vigenère cipher is a simple substitution cipher. -## Step 1 +## Cipher terminology -"If he had anything confidential to say, he wrote it in cipher, that is, by so changing the order of the letters of the alphabet, that not a word could be made out. -If anyone wishes to decipher these, and get at their meaning, he must substitute the fourth letter of the alphabet, namely D, for A, and so with the others." -—Suetonius, Life of Julius Caesar +A cipher is an algorithm used to encrypt, or encode, a string. +The unencrypted string is called the _plaintext_ and the encrypted string is called the _ciphertext_. +Converting plaintext to ciphertext is called _encoding_ while the reverse is called _decoding_. -Ciphers are very straight-forward algorithms that allow us to render text less readable while still allowing easy deciphering. -They are vulnerable to many forms of cryptanalysis, but Caesar was lucky that his enemies were not cryptanalysts. +In a _substitution cipher_, each plaintext letter is replaced with a ciphertext letter which is computed with the help of a _key_. +(Note, it is possible for replacement letter to be the same as the original letter.) -The Caesar cipher was used for some messages from Julius Caesar that were sent afield. -Now Caesar knew that the cipher wasn't very good, but he had one ally in that respect: almost nobody could read well. -So even being a couple letters off was sufficient so that people couldn't recognize the few words that they did know. +## Encoding details -Your task is to create a simple shift cipher like the Caesar cipher. -This image is a great example of the Caesar cipher: +In this cipher, the key is a series of lowercase letters, such as `"abcd"`. +Each letter of the plaintext is _shifted_ or _rotated_ by a distance based on a corresponding letter in the key. +An `"a"` in the key means a shift of 0 (that is, no shift). +A `"b"` in the key means a shift of 1. +A `"c"` in the key means a shift of 2, and so on. -![Caesar cipher][img-caesar-cipher] +The first letter of the plaintext uses the first letter of the key, the second letter of the plaintext uses the second letter of the key and so on. +If you run out of letters in the key before you run out of letters in the plaintext, start over from the start of the key again. -For example: +If the key only contains one letter, such as `"dddddd"`, then all letters of the plaintext are shifted by the same amount (three in this example), which would make this the same as a rotational cipher or shift cipher (sometimes called a Caesar cipher). +For example, the plaintext `"iamapandabear"` would become `"ldpdsdqgdehdu"`. -Giving "iamapandabear" as input to the encode function returns the cipher "ldpdsdqgdehdu". -Obscure enough to keep our message secret in transit. +If the key only contains the letter `"a"` (one or more times), the shift distance is zero and the ciphertext is the same as the plaintext. -When "ldpdsdqgdehdu" is put into the decode function it would return the original "iamapandabear" letting your friend read your original message. +Usually the key is more complicated than that, though! +If the key is `"abcd"` then letters of the plaintext would be shifted by a distance of 0, 1, 2, and 3. +If the plaintext is `"hello"`, we need 5 shifts so the key would wrap around, giving shift distances of 0, 1, 2, 3, and 0. +Applying those shifts to the letters of `"hello"` we get `"hfnoo"`. -## Step 2 +## Random keys -Shift ciphers quickly cease to be useful when the opposition commander figures them out. -So instead, let's try using a substitution cipher. -Try amending the code to allow us to specify a key and use that for the shift distance. +If no key is provided, generate a key which consists of at least 100 random lowercase letters from the Latin alphabet. -Here's an example: - -Given the key "aaaaaaaaaaaaaaaaaa", encoding the string "iamapandabear" -would return the original "iamapandabear". - -Given the key "ddddddddddddddddd", encoding our string "iamapandabear" -would return the obscured "ldpdsdqgdehdu" - -In the example above, we've set a = 0 for the key value. -So when the plaintext is added to the key, we end up with the same message coming out. -So "aaaa" is not an ideal key. -But if we set the key to "dddd", we would get the same thing as the Caesar cipher. - -## Step 3 - -The weakest link in any cipher is the human being. -Let's make your substitution cipher a little more fault tolerant by providing a source of randomness and ensuring that the key contains only lowercase letters. - -If someone doesn't submit a key at all, generate a truly random key of at least 100 lowercase characters in length. - -## Extensions - -Shift ciphers work by making the text slightly odd, but are vulnerable to frequency analysis. -Substitution ciphers help that, but are still very vulnerable when the key is short or if spaces are preserved. -Later on you'll see one solution to this problem in the exercise "crypto-square". - -If you want to go farther in this field, the questions begin to be about how we can exchange keys in a secure way. -Take a look at [Diffie-Hellman on Wikipedia][dh] for one of the first implementations of this scheme. - -[img-caesar-cipher]: https://upload.wikimedia.org/wikipedia/commons/thumb/4/4a/Caesar_cipher_left_shift_of_3.svg/320px-Caesar_cipher_left_shift_of_3.svg.png -[dh]: https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange +[wiki]: https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher diff --git a/exercises/practice/simple-cipher/.meta/config.json b/exercises/practice/simple-cipher/.meta/config.json index 6f7ac09b1..de6b37f39 100644 --- a/exercises/practice/simple-cipher/.meta/config.json +++ b/exercises/practice/simple-cipher/.meta/config.json @@ -34,7 +34,7 @@ "build.gradle" ] }, - "blurb": "Implement a simple shift cipher like Caesar and a more secure substitution cipher.", + "blurb": "Implement the Vigenère cipher, a simple substitution cipher.", "source": "Substitution Cipher at Wikipedia", "source_url": "https://en.wikipedia.org/wiki/Substitution_cipher" } diff --git a/exercises/practice/simple-cipher/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/simple-cipher/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/simple-cipher/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/simple-cipher/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/simple-cipher/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/simple-cipher/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/simple-cipher/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/simple-cipher/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/simple-cipher/gradlew b/exercises/practice/simple-cipher/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/simple-cipher/gradlew +++ b/exercises/practice/simple-cipher/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/simple-cipher/gradlew.bat b/exercises/practice/simple-cipher/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/simple-cipher/gradlew.bat +++ b/exercises/practice/simple-cipher/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/simple-cipher/src/test/java/SimpleCipherTest.java b/exercises/practice/simple-cipher/src/test/java/SimpleCipherTest.java index 1aadc854f..af7adbe4b 100644 --- a/exercises/practice/simple-cipher/src/test/java/SimpleCipherTest.java +++ b/exercises/practice/simple-cipher/src/test/java/SimpleCipherTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -18,6 +19,7 @@ public void setup() { * problem with shift ciphers, some characters will always output the key verbatim. */ @Test + @DisplayName("Can encode") public void randomKeyCipherCanEncode() { String plainText = "aaaaaaaaaa"; String cipherText = randomKeyCipher.getKey().substring(0, 10); @@ -26,6 +28,7 @@ public void randomKeyCipherCanEncode() { @Disabled("Remove to run test") @Test + @DisplayName("Can decode") public void randomKeyCipherCanDecode() { String cipherText = "aaaaaaaaaa"; assertThat(randomKeyCipher.decode(randomKeyCipher.getKey().substring(0, 10))) @@ -34,6 +37,10 @@ public void randomKeyCipherCanDecode() { @Disabled("Remove to run test") @Test + @DisplayName( + "Is reversible. I.e., if you apply decode in a encoded result, " + + "you must see the same plaintext encode parameter as a result of the decode method" + ) public void randomKeyCipherIsReversible() { String plainText = "abcdefghij"; assertThat(randomKeyCipher.decode(randomKeyCipher.encode(plainText))).isEqualTo(plainText); @@ -41,12 +48,14 @@ public void randomKeyCipherIsReversible() { @Disabled("Remove to run test") @Test + @DisplayName("Key is made only of lowercase letters") public void randomKeyCipherKeyIsLowercaseLetters() { assertThat(randomKeyCipher.getKey()).matches("^[a-z]+$"); } @Disabled("Remove to run test") @Test + @DisplayName("Can encode") public void substitutionCipherCanEncode() { String plainText = "aaaaaaaaaa"; String cipherText = "abcdefghij"; @@ -55,6 +64,7 @@ public void substitutionCipherCanEncode() { @Disabled("Remove to run test") @Test + @DisplayName("Can decode") public void substitutionCipherCanDecode() { String plainText = "abcdefghij"; String cipherText = "aaaaaaaaaa"; @@ -63,6 +73,10 @@ public void substitutionCipherCanDecode() { @Disabled("Remove to run test") @Test + @DisplayName( + "Is reversible. I.e., if you apply decode in a encoded result, " + + "you must see the same plaintext encode parameter as a result of the decode method" + ) public void substitutionCipherIsReversibleGivenKey() { String plainText = "abcdefghij"; assertThat(substitutionCipher.decode(substitutionCipher.encode(plainText))).isEqualTo(plainText); @@ -70,6 +84,7 @@ public void substitutionCipherIsReversibleGivenKey() { @Disabled("Remove to run test") @Test + @DisplayName("Can double shift encode") public void substitutionCipherCanDoubleShiftEncode() { String plainText = "iamapandabear"; String cipherText = "qayaeaagaciai"; @@ -78,6 +93,7 @@ public void substitutionCipherCanDoubleShiftEncode() { @Disabled("Remove to run test") @Test + @DisplayName("Can wrap on encode") public void substitutionCipherCanWrapEncode() { String plainText = "zzzzzzzzzz"; String cipherText = "zabcdefghi"; @@ -86,6 +102,7 @@ public void substitutionCipherCanWrapEncode() { @Disabled("Remove to run test") @Test + @DisplayName("Can wrap on decode") public void substitutionCipherCanWrapDecode() { String plainText = "zabcdefghi"; String cipherText = "zzzzzzzzzz"; @@ -94,6 +111,7 @@ public void substitutionCipherCanWrapDecode() { @Disabled("Remove to run test") @Test + @DisplayName("Can decode messages longer than the key") public void substitutionCipherMessageLongerThanKey() { String plainText = "iamapandabear"; String key = "abc"; diff --git a/exercises/practice/simple-linked-list/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/simple-linked-list/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/simple-linked-list/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/simple-linked-list/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/simple-linked-list/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/simple-linked-list/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/simple-linked-list/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/simple-linked-list/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/simple-linked-list/gradlew b/exercises/practice/simple-linked-list/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/simple-linked-list/gradlew +++ b/exercises/practice/simple-linked-list/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/simple-linked-list/gradlew.bat b/exercises/practice/simple-linked-list/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/simple-linked-list/gradlew.bat +++ b/exercises/practice/simple-linked-list/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/simple-linked-list/src/test/java/SimpleLinkedListTest.java b/exercises/practice/simple-linked-list/src/test/java/SimpleLinkedListTest.java index 76e219ff8..109d3b3a7 100644 --- a/exercises/practice/simple-linked-list/src/test/java/SimpleLinkedListTest.java +++ b/exercises/practice/simple-linked-list/src/test/java/SimpleLinkedListTest.java @@ -1,14 +1,16 @@ -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; - import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.NoSuchElementException; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + public class SimpleLinkedListTest { @Test + @DisplayName("A new list is empty") public void aNewListIsEmpty() { SimpleLinkedList list = new SimpleLinkedList<>(); assertThat(list.size()).isEqualTo(0); @@ -16,6 +18,7 @@ public void aNewListIsEmpty() { @Disabled("Remove to run test") @Test + @DisplayName("Create list from array") public void canCreateFromArray() { Character[] values = new Character[]{'1', '2', '3'}; SimpleLinkedList list = new SimpleLinkedList(values); @@ -24,6 +27,7 @@ public void canCreateFromArray() { @Disabled("Remove to run test") @Test + @DisplayName("Popping an empty list throws NoSuchElementException") public void popOnEmptyListWillThrow() { SimpleLinkedList list = new SimpleLinkedList(); @@ -32,6 +36,7 @@ public void popOnEmptyListWillThrow() { @Disabled("Remove to run test") @Test + @DisplayName("Pop returns last added element (LIFO)") public void popReturnsLastAddedElement() { SimpleLinkedList list = new SimpleLinkedList(); list.push(9); @@ -44,6 +49,7 @@ public void popReturnsLastAddedElement() { @Disabled("Remove to run test") @Test + @DisplayName("Reverse reverses the list order") public void reverseReversesList() { SimpleLinkedList list = new SimpleLinkedList(); list.push("9"); @@ -61,6 +67,7 @@ public void reverseReversesList() { @Disabled("Remove to run test") @Test + @DisplayName("Can return list as an array") public void canReturnListAsArray() { SimpleLinkedList list = new SimpleLinkedList(); list.push('9'); @@ -74,6 +81,7 @@ public void canReturnListAsArray() { @Disabled("Remove to run test") @Test + @DisplayName("Can return empty list as an empty array") public void canReturnEmptyListAsEmptyArray() { SimpleLinkedList list = new SimpleLinkedList(); Object[] expected = {}; diff --git a/exercises/practice/space-age/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/space-age/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/space-age/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/space-age/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/space-age/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/space-age/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/space-age/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/space-age/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/space-age/gradlew b/exercises/practice/space-age/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/space-age/gradlew +++ b/exercises/practice/space-age/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/space-age/gradlew.bat b/exercises/practice/space-age/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/space-age/gradlew.bat +++ b/exercises/practice/space-age/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/space-age/src/test/java/SpaceAgeTest.java b/exercises/practice/space-age/src/test/java/SpaceAgeTest.java index 4b2a9d43a..248d6938e 100644 --- a/exercises/practice/space-age/src/test/java/SpaceAgeTest.java +++ b/exercises/practice/space-age/src/test/java/SpaceAgeTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -9,6 +10,7 @@ public class SpaceAgeTest { private static final double MAXIMUM_DELTA = 1E-02; @Test + @DisplayName("age on Earth") public void ageOnEarth() { SpaceAge age = new SpaceAge(1000000000); @@ -17,6 +19,7 @@ public void ageOnEarth() { @Disabled("Remove to run test") @Test + @DisplayName("age on Mercury") public void ageOnMercury() { SpaceAge age = new SpaceAge(2134835688); @@ -25,6 +28,7 @@ public void ageOnMercury() { @Disabled("Remove to run test") @Test + @DisplayName("age on Venus") public void ageOnVenus() { SpaceAge age = new SpaceAge(189839836); @@ -33,6 +37,7 @@ public void ageOnVenus() { @Disabled("Remove to run test") @Test + @DisplayName("age on Mars") public void ageOnMars() { SpaceAge age = new SpaceAge(2129871239L); @@ -41,6 +46,7 @@ public void ageOnMars() { @Disabled("Remove to run test") @Test + @DisplayName("age on Jupiter") public void ageOnJupiter() { SpaceAge age = new SpaceAge(901876382); @@ -49,6 +55,7 @@ public void ageOnJupiter() { @Disabled("Remove to run test") @Test + @DisplayName("age on Saturn") public void ageOnSaturn() { SpaceAge age = new SpaceAge(2000000000L); @@ -57,6 +64,7 @@ public void ageOnSaturn() { @Disabled("Remove to run test") @Test + @DisplayName("age on Uranus") public void ageOnUranus() { SpaceAge age = new SpaceAge(1210123456L); @@ -65,6 +73,7 @@ public void ageOnUranus() { @Disabled("Remove to run test") @Test + @DisplayName("age on Neptune") public void ageOnNeptune() { SpaceAge age = new SpaceAge(1821023456L); diff --git a/exercises/practice/spiral-matrix/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/spiral-matrix/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/spiral-matrix/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/spiral-matrix/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/spiral-matrix/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/spiral-matrix/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/spiral-matrix/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/spiral-matrix/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/spiral-matrix/gradlew b/exercises/practice/spiral-matrix/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/spiral-matrix/gradlew +++ b/exercises/practice/spiral-matrix/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/spiral-matrix/gradlew.bat b/exercises/practice/spiral-matrix/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/spiral-matrix/gradlew.bat +++ b/exercises/practice/spiral-matrix/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/spiral-matrix/src/test/java/SpiralMatrixBuilderTest.java b/exercises/practice/spiral-matrix/src/test/java/SpiralMatrixBuilderTest.java index ee9a971f9..215afdc10 100644 --- a/exercises/practice/spiral-matrix/src/test/java/SpiralMatrixBuilderTest.java +++ b/exercises/practice/spiral-matrix/src/test/java/SpiralMatrixBuilderTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -14,12 +15,14 @@ public void setUp() { } @Test + @DisplayName("empty spiral") public void testEmptySpiral() { assertThat(spiralMatrixBuilder.buildMatrixOfSize(0)).isEmpty(); } @Disabled("Remove to run test") @Test + @DisplayName("trivial spiral") public void testTrivialSpiral() { int[][] expected = { {1} @@ -30,6 +33,7 @@ public void testTrivialSpiral() { @Disabled("Remove to run test") @Test + @DisplayName("spiral of size 2") public void testSpiralOfSize2() { int[][] expected = { {1, 2}, @@ -41,6 +45,7 @@ public void testSpiralOfSize2() { @Disabled("Remove to run test") @Test + @DisplayName("spiral of size 3") public void testSpiralOfSize3() { int[][] expected = { {1, 2, 3}, @@ -53,6 +58,7 @@ public void testSpiralOfSize3() { @Disabled("Remove to run test") @Test + @DisplayName("spiral of size 4") public void testSpiralOfSize4() { int[][] expected = { { 1, 2, 3, 4}, @@ -66,6 +72,7 @@ public void testSpiralOfSize4() { @Disabled("Remove to run test") @Test + @DisplayName("spiral of size 5") public void testSpiralOfSize5() { int[][] expected = { { 1, 2, 3, 4, 5}, diff --git a/exercises/practice/split-second-stopwatch/.docs/instructions.md b/exercises/practice/split-second-stopwatch/.docs/instructions.md new file mode 100644 index 000000000..30bdc988d --- /dev/null +++ b/exercises/practice/split-second-stopwatch/.docs/instructions.md @@ -0,0 +1,22 @@ +# Instructions + +Your task is to build a stopwatch to keep precise track of lap times. + +The stopwatch uses four commands (start, stop, lap, and reset) to keep track of: + +1. The current lap's tracked time +2. Previously recorded lap times + +What commands can be used depends on which state the stopwatch is in: + +1. Ready: initial state +2. Running: tracking time +3. Stopped: not tracking time + +| Command | Begin state | End state | Effect | +| ------- | ----------- | --------- | -------------------------------------------------------- | +| Start | Ready | Running | Start tracking time | +| Start | Stopped | Running | Resume tracking time | +| Stop | Running | Stopped | Stop tracking time | +| Lap | Running | Running | Add current lap to previous laps, then reset current lap | +| Reset | Stopped | Ready | Reset current lap and clear previous laps | diff --git a/exercises/practice/split-second-stopwatch/.docs/introduction.md b/exercises/practice/split-second-stopwatch/.docs/introduction.md new file mode 100644 index 000000000..a84322477 --- /dev/null +++ b/exercises/practice/split-second-stopwatch/.docs/introduction.md @@ -0,0 +1,6 @@ +# Introduction + +You've always run for the thrill of it — no schedules, no timers, just the sound of your feet on the pavement. +But now that you've joined a competitive running crew, things are getting serious. +Training sessions are timed to the second, and every split second counts. +To keep pace, you've picked up the _Split-Second Stopwatch_ — a sleek, high-tech gadget that's about to become your new best friend. diff --git a/exercises/practice/split-second-stopwatch/.meta/config.json b/exercises/practice/split-second-stopwatch/.meta/config.json new file mode 100644 index 000000000..6fb187621 --- /dev/null +++ b/exercises/practice/split-second-stopwatch/.meta/config.json @@ -0,0 +1,22 @@ +{ + "authors": [ + "EmmanuelBerkowicz" + ], + "files": { + "solution": [ + "src/main/java/SplitSecondStopwatch.java" + ], + "test": [ + "src/test/java/SplitSecondStopwatchTest.java" + ], + "example": [ + ".meta/src/reference/java/SplitSecondStopwatch.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Keep track of time through a digital stopwatch.", + "source": "Erik Schierboom", + "source_url": "https://github.com/exercism/problem-specifications/pull/2547" +} diff --git a/exercises/practice/split-second-stopwatch/.meta/src/reference/java/SplitSecondStopwatch.java b/exercises/practice/split-second-stopwatch/.meta/src/reference/java/SplitSecondStopwatch.java new file mode 100644 index 000000000..c00a58cea --- /dev/null +++ b/exercises/practice/split-second-stopwatch/.meta/src/reference/java/SplitSecondStopwatch.java @@ -0,0 +1,125 @@ +import java.util.ArrayList; +import java.util.List; + +public class SplitSecondStopwatch { + + /** + * A split-second stopwatch that tracks elapsed time with lap functionality. + * Supports start, stop, reset, and lap operations with precise time tracking. + * Times are formatted in HH:MM:SS format with two-digit precision. + * + * @see + * Problem Specifications + * + */ + + private enum State { READY, RUNNING, STOPPED } + + private State state; + private long totalCompletedLaps; // Total time from completed laps + private long currentLapStart; // When current lap started + private long accumulated; // Accumulated time for current lap when stopped + private List previousLaps; + private long mockTime; + + public SplitSecondStopwatch() { + this.state = State.READY; + this.totalCompletedLaps = 0; + this.currentLapStart = 0; + this.accumulated = 0; + this.previousLaps = new ArrayList<>(); + this.mockTime = 0; + } + + public void start() { + if (state == State.RUNNING) { + throw new IllegalStateException("cannot start an already running stopwatch"); + } + + currentLapStart = mockTime; + state = State.RUNNING; + } + + public void stop() { + if (state != State.RUNNING) { + throw new IllegalStateException("cannot stop a stopwatch that is not running"); + } + + accumulated += mockTime - currentLapStart; + state = State.STOPPED; + } + + public void reset() { + if (state != State.STOPPED) { + throw new IllegalStateException("cannot reset a stopwatch that is not stopped"); + } + + state = State.READY; + totalCompletedLaps = 0; + currentLapStart = 0; + accumulated = 0; + previousLaps.clear(); + } + + public void lap() { + if (state != State.RUNNING) { + throw new IllegalStateException("cannot lap a stopwatch that is not running"); + } + + long currentLapTime = getCurrentLapTime(); + totalCompletedLaps += currentLapTime; + previousLaps.add(formatTime(currentLapTime)); + + // Reset current lap and restart + accumulated = 0; + currentLapStart = mockTime; + } + + public String state() { + return state.name().toLowerCase(); + } + + public String currentLap() { + return formatTime(getCurrentLapTime()); + } + + public String total() { + return formatTime(totalCompletedLaps + getCurrentLapTime()); + } + + public List previousLaps() { + return new ArrayList<>(previousLaps); + } + + public void advanceTime(String timeString) { + String[] parts = timeString.split(":"); + long hours = Long.parseLong(parts[0]); + long minutes = Long.parseLong(parts[1]); + long seconds = Long.parseLong(parts[2]); + + long milliseconds = (hours * 3600 + minutes * 60 + seconds) * 1000; + mockTime += milliseconds; + } + + private long getCurrentLapTime() { + switch (state) { + case READY: + return 0; + case RUNNING: + return accumulated + (mockTime - currentLapStart); + case STOPPED: + return accumulated; + default: + throw new IllegalStateException("Invalid state"); + } + } + + private String formatTime(long milliseconds) { + long totalSeconds = milliseconds / 1000; + long hours = totalSeconds / 3600; + long minutes = (totalSeconds % 3600) / 60; + long seconds = totalSeconds % 60; + + return String.format("%02d:%02d:%02d", hours, minutes, seconds); + } +} diff --git a/exercises/practice/split-second-stopwatch/.meta/tests.toml b/exercises/practice/split-second-stopwatch/.meta/tests.toml new file mode 100644 index 000000000..323cb7ae8 --- /dev/null +++ b/exercises/practice/split-second-stopwatch/.meta/tests.toml @@ -0,0 +1,97 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[ddb238ea-99d4-4eaa-a81d-3c917a525a23] +description = "new stopwatch starts in ready state" + +[b19635d4-08ad-4ac3-b87f-aca10e844071] +description = "new stopwatch's current lap has no elapsed time" + +[492eb532-268d-43ea-8a19-2a032067d335] +description = "new stopwatch's total has no elapsed time" + +[8a892c1e-9ef7-4690-894e-e155a1fe4484] +description = "new stopwatch does not have previous laps" + +[5b2705b6-a584-4042-ba3a-4ab8d0ab0281] +description = "start from ready state changes state to running" + +[748235ce-1109-440b-9898-0a431ea179b6] +description = "start does not change previous laps" + +[491487b1-593d-423e-a075-aa78d449ff1f] +description = "start initiates time tracking for current lap" + +[a0a7ba2c-8db6-412c-b1b6-cb890e9b72ed] +description = "start initiates time tracking for total" + +[7f558a17-ef6d-4a5b-803a-f313af7c41d3] +description = "start cannot be called from running state" + +[32466eef-b2be-4d60-a927-e24fce52dab9] +description = "stop from running state changes state to stopped" + +[621eac4c-8f43-4d99-919c-4cad776d93df] +description = "stop pauses time tracking for current lap" + +[465bcc82-7643-41f2-97ff-5e817cef8db4] +description = "stop pauses time tracking for total" + +[b1ba7454-d627-41ee-a078-891b2ed266fc] +description = "stop cannot be called from ready state" + +[5c041078-0898-44dc-9d5b-8ebb5352626c] +description = "stop cannot be called from stopped state" + +[3f32171d-8fbf-46b6-bc2b-0810e1ec53b7] +description = "start from stopped state changes state to running" + +[626997cb-78d5-4fe8-b501-29fdef804799] +description = "start from stopped state resumes time tracking for current lap" + +[58487c53-ab26-471c-a171-807ef6363319] +description = "start from stopped state resumes time tracking for total" + +[091966e3-ed25-4397-908b-8bb0330118f8] +description = "lap adds current lap to previous laps" + +[1aa4c5ee-a7d5-4d59-9679-419deef3c88f] +description = "lap resets current lap and resumes time tracking" + +[4b46b92e-1b3f-46f6-97d2-0082caf56e80] +description = "lap continues time tracking for total" + +[ea75d36e-63eb-4f34-97ce-8c70e620bdba] +description = "lap cannot be called from ready state" + +[63731154-a23a-412d-a13f-c562f208eb1e] +description = "lap cannot be called from stopped state" + +[e585ee15-3b3f-4785-976b-dd96e7cc978b] +description = "stop does not change previous laps" + +[fc3645e2-86cf-4d11-97c6-489f031103f6] +description = "reset from stopped state changes state to ready" + +[20fbfbf7-68ad-4310-975a-f5f132886c4e] +description = "reset resets current lap" + +[00a8f7bb-dd5c-43e5-8705-3ef124007662] +description = "reset clears previous laps" + +[76cea936-6214-4e95-b6d1-4d4edcf90499] +description = "reset cannot be called from ready state" + +[ba4d8e69-f200-4721-b59e-90d8cf615153] +description = "reset cannot be called from running state" + +[0b01751a-cb57-493f-bb86-409de6e84306] +description = "supports very long laps" diff --git a/exercises/practice/split-second-stopwatch/build.gradle b/exercises/practice/split-second-stopwatch/build.gradle new file mode 100644 index 000000000..d28f35dee --- /dev/null +++ b/exercises/practice/split-second-stopwatch/build.gradle @@ -0,0 +1,25 @@ +plugins { + id "java" +} + +repositories { + mavenCentral() +} + +dependencies { + testImplementation platform("org.junit:junit-bom:5.10.0") + testImplementation "org.junit.jupiter:junit-jupiter" + testImplementation "org.assertj:assertj-core:3.25.1" + + testRuntimeOnly "org.junit.platform:junit-platform-launcher" +} + +test { + useJUnitPlatform() + + testLogging { + exceptionFormat = "full" + showStandardStreams = true + events = ["passed", "failed", "skipped"] + } +} diff --git a/exercises/practice/split-second-stopwatch/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/split-second-stopwatch/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..f8e1ee312 Binary files /dev/null and b/exercises/practice/split-second-stopwatch/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/split-second-stopwatch/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/split-second-stopwatch/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..4d97ea344 --- /dev/null +++ b/exercises/practice/split-second-stopwatch/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/exercises/practice/split-second-stopwatch/gradlew b/exercises/practice/split-second-stopwatch/gradlew new file mode 100755 index 000000000..adff685a0 --- /dev/null +++ b/exercises/practice/split-second-stopwatch/gradlew @@ -0,0 +1,248 @@ +#!/bin/sh + +# +# Copyright © 2015 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/exercises/practice/split-second-stopwatch/gradlew.bat b/exercises/practice/split-second-stopwatch/gradlew.bat new file mode 100644 index 000000000..c4bdd3ab8 --- /dev/null +++ b/exercises/practice/split-second-stopwatch/gradlew.bat @@ -0,0 +1,93 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/exercises/practice/split-second-stopwatch/src/main/java/SplitSecondStopwatch.java b/exercises/practice/split-second-stopwatch/src/main/java/SplitSecondStopwatch.java new file mode 100644 index 000000000..36847004c --- /dev/null +++ b/exercises/practice/split-second-stopwatch/src/main/java/SplitSecondStopwatch.java @@ -0,0 +1,37 @@ +public class SplitSecondStopwatch { + public void start() { + throw new UnsupportedOperationException("Please implement the SplitSecondStopwatch.start method."); + } + + public void stop() { + throw new UnsupportedOperationException("Please implement the SplitSecondStopwatch.stop method."); + } + + public void reset() { + throw new UnsupportedOperationException("Please implement the SplitSecondStopwatch.reset method."); + } + + public void lap() { + throw new UnsupportedOperationException("Please implement the SplitSecondStopwatch.lap method."); + } + + public String state() { + throw new UnsupportedOperationException("Please implement the SplitSecondStopwatch.state method."); + } + + public String currentLap() { + throw new UnsupportedOperationException("Please implement the SplitSecondStopwatch.currentLap method."); + } + + public String total() { + throw new UnsupportedOperationException("Please implement the SplitSecondStopwatch.total method."); + } + + public java.util.List previousLaps() { + throw new UnsupportedOperationException("Please implement the SplitSecondStopwatch.previousLaps method."); + } + + public void advanceTime(String timeString) { + throw new UnsupportedOperationException("Please implement the SplitSecondStopwatch.advanceTime method."); + } +} \ No newline at end of file diff --git a/exercises/practice/split-second-stopwatch/src/test/java/SplitSecondStopwatchTest.java b/exercises/practice/split-second-stopwatch/src/test/java/SplitSecondStopwatchTest.java new file mode 100644 index 000000000..1f54a9907 --- /dev/null +++ b/exercises/practice/split-second-stopwatch/src/test/java/SplitSecondStopwatchTest.java @@ -0,0 +1,339 @@ +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +public class SplitSecondStopwatchTest { + @Test + @DisplayName("new stopwatch starts in ready state") + public void newStopwatchStartsInReadyState() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + assertThat(stopwatch.state()).isEqualTo("ready"); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("new stopwatch's current lap has no elapsed time") + public void newStopwatchCurrentLapHasNoElapsedTime() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + assertThat(stopwatch.currentLap()).isEqualTo("00:00:00"); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("new stopwatch's total has no elapsed time") + public void newStopwatchTotalHasNoElapsedTime() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + assertThat(stopwatch.total()).isEqualTo("00:00:00"); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("new stopwatch does not have previous laps") + public void newStopwatchDoesNotHavePreviousLaps() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + assertThat(stopwatch.previousLaps()).isEmpty(); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("start from ready state changes state to running") + public void startFromReadyStateChangesStateToRunning() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + stopwatch.start(); + assertThat(stopwatch.state()).isEqualTo("running"); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("start does not change previous laps") + public void startDoesNotChangePreviousLaps() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + stopwatch.start(); + assertThat(stopwatch.previousLaps()).isEmpty(); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("start initiates time tracking for current lap") + public void startInitiatesTimeTrackingForCurrentLap() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + stopwatch.start(); + stopwatch.advanceTime("00:00:05"); + assertThat(stopwatch.currentLap()).isEqualTo("00:00:05"); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("start initiates time tracking for total") + public void startInitiatesTimeTrackingForTotal() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + stopwatch.start(); + stopwatch.advanceTime("00:00:23"); + assertThat(stopwatch.total()).isEqualTo("00:00:23"); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("start cannot be called from running state") + public void startCannotBeCalledFromRunningState() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + stopwatch.start(); + assertThatExceptionOfType(IllegalStateException.class) + .isThrownBy(stopwatch::start) + .withMessage("cannot start an already running stopwatch"); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("stop from running state changes state to stopped") + public void stopFromRunningStateChangesStateToStopped() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + stopwatch.start(); + stopwatch.stop(); + assertThat(stopwatch.state()).isEqualTo("stopped"); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("stop pauses time tracking for current lap") + public void stopPausesTimeTrackingForCurrentLap() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + stopwatch.start(); + stopwatch.advanceTime("00:00:05"); + stopwatch.stop(); + stopwatch.advanceTime("00:00:08"); + assertThat(stopwatch.currentLap()).isEqualTo("00:00:05"); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("stop pauses time tracking for total") + public void stopPausesTimeTrackingForTotal() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + stopwatch.start(); + stopwatch.advanceTime("00:00:13"); + stopwatch.stop(); + stopwatch.advanceTime("00:00:44"); + assertThat(stopwatch.total()).isEqualTo("00:00:13"); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("stop cannot be called from ready state") + public void stopCannotBeCalledFromReadyState() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + assertThatExceptionOfType(IllegalStateException.class) + .isThrownBy(stopwatch::stop) + .withMessage("cannot stop a stopwatch that is not running"); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("stop cannot be called from stopped state") + public void stopCannotBeCalledFromStoppedState() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + stopwatch.start(); + stopwatch.stop(); + assertThatExceptionOfType(IllegalStateException.class) + .isThrownBy(stopwatch::stop) + .withMessage("cannot stop a stopwatch that is not running"); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("start from stopped state changes state to running") + public void startFromStoppedStateChangesStateToRunning() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + stopwatch.start(); + stopwatch.stop(); + stopwatch.start(); + assertThat(stopwatch.state()).isEqualTo("running"); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("start from stopped state resumes time tracking for current lap") + public void startFromStoppedStateResumesTimeTrackingForCurrentLap() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + stopwatch.start(); + stopwatch.advanceTime("00:01:20"); + stopwatch.stop(); + stopwatch.advanceTime("00:00:20"); + stopwatch.start(); + stopwatch.advanceTime("00:00:08"); + assertThat(stopwatch.currentLap()).isEqualTo("00:01:28"); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("start from stopped state resumes time tracking for total") + public void startFromStoppedStateResumesTimeTrackingForTotal() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + stopwatch.start(); + stopwatch.advanceTime("00:00:23"); + stopwatch.stop(); + stopwatch.advanceTime("00:00:44"); + stopwatch.start(); + stopwatch.advanceTime("00:00:09"); + assertThat(stopwatch.total()).isEqualTo("00:00:32"); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("lap adds current lap to previous laps") + public void lapAddsCurrentLapToPreviousLaps() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + stopwatch.start(); + stopwatch.advanceTime("00:01:38"); + stopwatch.lap(); + assertThat(stopwatch.previousLaps()).containsExactly("00:01:38"); + stopwatch.advanceTime("00:00:44"); + stopwatch.lap(); + assertThat(stopwatch.previousLaps()).containsExactly("00:01:38", "00:00:44"); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("lap resets current lap and resumes time tracking") + public void lapResetsCurrentLapAndResumesTimeTracking() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + stopwatch.start(); + stopwatch.advanceTime("00:08:22"); + stopwatch.lap(); + assertThat(stopwatch.currentLap()).isEqualTo("00:00:00"); + stopwatch.advanceTime("00:00:15"); + assertThat(stopwatch.currentLap()).isEqualTo("00:00:15"); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("lap continues time tracking for total") + public void lapContinuesTimeTrackingForTotal() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + stopwatch.start(); + stopwatch.advanceTime("00:00:22"); + stopwatch.lap(); + stopwatch.advanceTime("00:00:33"); + assertThat(stopwatch.total()).isEqualTo("00:00:55"); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("lap cannot be called from ready state") + public void lapCannotBeCalledFromReadyState() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + assertThatExceptionOfType(IllegalStateException.class) + .isThrownBy(stopwatch::lap) + .withMessage("cannot lap a stopwatch that is not running"); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("lap cannot be called from stopped state") + public void lapCannotBeCalledFromStoppedState() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + stopwatch.start(); + stopwatch.stop(); + assertThatExceptionOfType(IllegalStateException.class) + .isThrownBy(stopwatch::lap) + .withMessage("cannot lap a stopwatch that is not running"); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("stop does not change previous laps") + public void stopDoesNotChangePreviousLaps() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + stopwatch.start(); + stopwatch.advanceTime("00:11:22"); + stopwatch.lap(); + assertThat(stopwatch.previousLaps()).containsExactly("00:11:22"); + stopwatch.stop(); + assertThat(stopwatch.previousLaps()).containsExactly("00:11:22"); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("reset from stopped state changes state to ready") + public void resetFromStoppedStateChangesStateToReady() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + stopwatch.start(); + stopwatch.stop(); + stopwatch.reset(); + assertThat(stopwatch.state()).isEqualTo("ready"); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("reset resets current lap") + public void resetResetsCurrentLap() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + stopwatch.start(); + stopwatch.advanceTime("00:00:10"); + stopwatch.stop(); + stopwatch.reset(); + assertThat(stopwatch.currentLap()).isEqualTo("00:00:00"); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("reset clears previous laps") + public void resetClearsPreviousLaps() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + stopwatch.start(); + stopwatch.advanceTime("00:00:10"); + stopwatch.lap(); + stopwatch.advanceTime("00:00:20"); + stopwatch.lap(); + assertThat(stopwatch.previousLaps()).containsExactly("00:00:10", "00:00:20"); + stopwatch.stop(); + stopwatch.reset(); + assertThat(stopwatch.previousLaps()).isEmpty(); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("reset cannot be called from ready state") + public void resetCannotBeCalledFromReadyState() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + assertThatExceptionOfType(IllegalStateException.class) + .isThrownBy(stopwatch::reset) + .withMessage("cannot reset a stopwatch that is not stopped"); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("reset cannot be called from running state") + public void resetCannotBeCalledFromRunningState() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + stopwatch.start(); + assertThatExceptionOfType(IllegalStateException.class) + .isThrownBy(stopwatch::reset) + .withMessage("cannot reset a stopwatch that is not stopped"); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("supports very long laps") + public void supportsVeryLongLaps() { + SplitSecondStopwatch stopwatch = new SplitSecondStopwatch(); + stopwatch.start(); + stopwatch.advanceTime("01:23:45"); + assertThat(stopwatch.currentLap()).isEqualTo("01:23:45"); + stopwatch.lap(); + assertThat(stopwatch.previousLaps()).containsExactly("01:23:45"); + stopwatch.advanceTime("04:01:40"); + assertThat(stopwatch.currentLap()).isEqualTo("04:01:40"); + assertThat(stopwatch.total()).isEqualTo("05:25:25"); + stopwatch.lap(); + assertThat(stopwatch.previousLaps()).containsExactly("01:23:45", "04:01:40"); + stopwatch.advanceTime("08:43:05"); + assertThat(stopwatch.currentLap()).isEqualTo("08:43:05"); + assertThat(stopwatch.total()).isEqualTo("14:08:30"); + stopwatch.lap(); + assertThat(stopwatch.previousLaps()).containsExactly("01:23:45", "04:01:40", "08:43:05"); + } +} diff --git a/exercises/practice/square-root/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/square-root/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/square-root/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/square-root/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/square-root/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/square-root/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/square-root/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/square-root/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/square-root/gradlew b/exercises/practice/square-root/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/square-root/gradlew +++ b/exercises/practice/square-root/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/square-root/gradlew.bat b/exercises/practice/square-root/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/square-root/gradlew.bat +++ b/exercises/practice/square-root/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/state-of-tic-tac-toe/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/state-of-tic-tac-toe/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/state-of-tic-tac-toe/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/state-of-tic-tac-toe/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/state-of-tic-tac-toe/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/state-of-tic-tac-toe/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/state-of-tic-tac-toe/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/state-of-tic-tac-toe/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/state-of-tic-tac-toe/gradlew b/exercises/practice/state-of-tic-tac-toe/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/state-of-tic-tac-toe/gradlew +++ b/exercises/practice/state-of-tic-tac-toe/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/state-of-tic-tac-toe/gradlew.bat b/exercises/practice/state-of-tic-tac-toe/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/state-of-tic-tac-toe/gradlew.bat +++ b/exercises/practice/state-of-tic-tac-toe/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/state-of-tic-tac-toe/src/test/java/StateOfTicTacToeTest.java b/exercises/practice/state-of-tic-tac-toe/src/test/java/StateOfTicTacToeTest.java index e5352ae50..d264db005 100644 --- a/exercises/practice/state-of-tic-tac-toe/src/test/java/StateOfTicTacToeTest.java +++ b/exercises/practice/state-of-tic-tac-toe/src/test/java/StateOfTicTacToeTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -14,6 +15,7 @@ public void setup() { } @Test + @DisplayName("Finished game where X won via left column victory") public void testFinishedGameWhereXWonViaLeftColumnVictory() { assertThat( @@ -23,6 +25,7 @@ public void testFinishedGameWhereXWonViaLeftColumnVictory() { @Disabled("Remove to run test") @Test + @DisplayName("Finished game where X won via middle column victory") public void testFinishedGameWhereXWonViaMiddleColumnVictory() { assertThat( @@ -32,6 +35,7 @@ public void testFinishedGameWhereXWonViaMiddleColumnVictory() { @Disabled("Remove to run test") @Test + @DisplayName("Finished game where X won via right column victory") public void testFinishedGameWhereXWonViaRightColumnVictory() { assertThat( @@ -41,6 +45,7 @@ public void testFinishedGameWhereXWonViaRightColumnVictory() { @Disabled("Remove to run test") @Test + @DisplayName("Finished game where O won via left column victory") public void testFinishedGameWhereOWonViaLeftColumnVictory() { assertThat( @@ -50,6 +55,7 @@ public void testFinishedGameWhereOWonViaLeftColumnVictory() { @Disabled("Remove to run test") @Test + @DisplayName("Finished game where O won via middle column victory") public void testFinishedGameWhereOWonViaMiddleColumnVictory() { assertThat( @@ -59,6 +65,7 @@ public void testFinishedGameWhereOWonViaMiddleColumnVictory() { @Disabled("Remove to run test") @Test + @DisplayName("Finished game where O won via right column victory") public void testFinishedGameWhereOWonViaRightColumnVictory() { assertThat( @@ -68,6 +75,7 @@ public void testFinishedGameWhereOWonViaRightColumnVictory() { @Disabled("Remove to run test") @Test + @DisplayName("Finished game where X won via top row victory") public void testFinishedGameWhereXWonViaTopRowVictory() { assertThat( @@ -77,6 +85,7 @@ public void testFinishedGameWhereXWonViaTopRowVictory() { @Disabled("Remove to run test") @Test + @DisplayName("Finished game where X won via middle row victory") public void testFinishedGameWhereXWonViaMiddleRowVictory() { assertThat( @@ -86,6 +95,7 @@ public void testFinishedGameWhereXWonViaMiddleRowVictory() { @Disabled("Remove to run test") @Test + @DisplayName("Finished game where X won via middle row victory") public void testFinishedGameWhereXWonViaBottomRowVictory() { assertThat( @@ -95,6 +105,7 @@ public void testFinishedGameWhereXWonViaBottomRowVictory() { @Disabled("Remove to run test") @Test + @DisplayName("Finished game where O won via top row victory") public void testFinishedGameWhereOWonViaTopRowVictory() { assertThat( @@ -104,6 +115,7 @@ public void testFinishedGameWhereOWonViaTopRowVictory() { @Disabled("Remove to run test") @Test + @DisplayName("Finished game where O won via middle row victory") public void testFinishedGameWhereOWonViaMiddleRowVictory() { assertThat( @@ -113,6 +125,7 @@ public void testFinishedGameWhereOWonViaMiddleRowVictory() { @Disabled("Remove to run test") @Test + @DisplayName("Finished game where O won via bottom row victory") public void testFinishedGameWhereOWonViaBottomRowVictory() { assertThat( @@ -122,6 +135,7 @@ public void testFinishedGameWhereOWonViaBottomRowVictory() { @Disabled("Remove to run test") @Test + @DisplayName("Finished game where X won via falling diagonal victory") public void testFinishedGameWhereXWonViaFallingDiagonalVictory() { assertThat( @@ -131,6 +145,7 @@ public void testFinishedGameWhereXWonViaFallingDiagonalVictory() { @Disabled("Remove to run test") @Test + @DisplayName("Finished game where X won via rising diagonal victory") public void testFinishedGameWhereXWonViaRisingDiagonalVictory() { assertThat( @@ -140,6 +155,7 @@ public void testFinishedGameWhereXWonViaRisingDiagonalVictory() { @Disabled("Remove to run test") @Test + @DisplayName("Finished game where O won via falling diagonal victory") public void testFinishedGameWhereOWonViaFallingDiagonalVictory() { assertThat( @@ -149,6 +165,7 @@ public void testFinishedGameWhereOWonViaFallingDiagonalVictory() { @Disabled("Remove to run test") @Test + @DisplayName("Finished game where O won via rising diagonal victory") public void testFinishedGameWhereOWonViaRisingDiagonalVictory() { assertThat( @@ -158,6 +175,7 @@ public void testFinishedGameWhereOWonViaRisingDiagonalVictory() { @Disabled("Remove to run test") @Test + @DisplayName("Finished game where X won via a row and a column victory") public void testFinishedGameWhereXWonViaARowAndAColumnVictory() { assertThat( @@ -167,6 +185,7 @@ public void testFinishedGameWhereXWonViaARowAndAColumnVictory() { @Disabled("Remove to run test") @Test + @DisplayName("Finished game where X won via two diagonal victories") public void testFinishedGameWhereXWonViaTwoDiagonalVictories() { assertThat( @@ -176,6 +195,7 @@ public void testFinishedGameWhereXWonViaTwoDiagonalVictories() { @Disabled("Remove to run test") @Test + @DisplayName("Drawn games") public void testDraw() { assertThat( @@ -185,6 +205,7 @@ public void testDraw() { @Disabled("Remove to run test") @Test + @DisplayName("Another draw") public void testAnotherDraw() { assertThat( @@ -194,6 +215,7 @@ public void testAnotherDraw() { @Disabled("Remove to run test") @Test + @DisplayName("Ongoing game: one move in") public void testOngoingGameOneMoveIn() { assertThat( @@ -203,6 +225,7 @@ public void testOngoingGameOneMoveIn() { @Disabled("Remove to run test") @Test + @DisplayName("Ongoing game: two moves in") public void testOngoingGameTwoMovesIn() { assertThat( @@ -212,6 +235,7 @@ public void testOngoingGameTwoMovesIn() { @Disabled("Remove to run test") @Test + @DisplayName("Ongoing game: five moves in") public void testOngoingGameFiveMovesIn() { assertThat( @@ -221,6 +245,7 @@ public void testOngoingGameFiveMovesIn() { @Disabled("Remove to run test") @Test + @DisplayName("Invalid board: X went twice") public void testInvalidBoardXWentTwice() { assertThatExceptionOfType(IllegalArgumentException.class) @@ -230,6 +255,7 @@ public void testInvalidBoardXWentTwice() { @Disabled("Remove to run test") @Test + @DisplayName("Invalid board: O started") public void testInvalidBoardOStarted() { assertThatExceptionOfType(IllegalArgumentException.class) @@ -239,6 +265,7 @@ public void testInvalidBoardOStarted() { @Disabled("Remove to run test") @Test + @DisplayName("Invalid board") public void testInvalidBoard() { assertThatExceptionOfType(IllegalArgumentException.class) @@ -248,6 +275,7 @@ public void testInvalidBoard() { @Disabled("Remove to run test") @Test + @DisplayName("Invalid board: players kept playing after a win") public void testInvalidBoardPlayersKeptPlayingAfterAWin() { assertThatExceptionOfType(IllegalArgumentException.class) diff --git a/exercises/practice/sublist/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/sublist/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/sublist/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/sublist/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/sublist/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/sublist/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/sublist/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/sublist/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/sublist/gradlew b/exercises/practice/sublist/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/sublist/gradlew +++ b/exercises/practice/sublist/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/sublist/gradlew.bat b/exercises/practice/sublist/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/sublist/gradlew.bat +++ b/exercises/practice/sublist/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/sublist/src/test/java/RelationshipComputerTest.java b/exercises/practice/sublist/src/test/java/RelationshipComputerTest.java index e9e4adc62..bcb2d6f8d 100644 --- a/exercises/practice/sublist/src/test/java/RelationshipComputerTest.java +++ b/exercises/practice/sublist/src/test/java/RelationshipComputerTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.List; @@ -10,6 +11,7 @@ public class RelationshipComputerTest { @Test + @DisplayName("empty lists") public void testThatTwoEmptyListsAreConsideredEqual() { Relationship relationship = new RelationshipComputer<>().computeRelationship( emptyList(), @@ -20,6 +22,7 @@ public void testThatTwoEmptyListsAreConsideredEqual() { @Disabled("Remove to run test") @Test + @DisplayName("empty list within non empty list") public void testEmptyListIsSublistOfNonEmptyList() { Relationship relationship = new RelationshipComputer<>().computeRelationship( emptyList(), @@ -30,6 +33,7 @@ public void testEmptyListIsSublistOfNonEmptyList() { @Disabled("Remove to run test") @Test + @DisplayName("non empty list contains empty list") public void testNonEmptyListIsSuperlistOfEmptyList() { Relationship relationship = new RelationshipComputer<>().computeRelationship( asList('1', '2', '3'), @@ -40,6 +44,7 @@ public void testNonEmptyListIsSuperlistOfEmptyList() { @Disabled("Remove to run test") @Test + @DisplayName("list equals itself") public void testListIsEqualToItself() { List anyList = asList("1", "2", "3"); @@ -52,6 +57,7 @@ public void testListIsEqualToItself() { @Disabled("Remove to run test") @Test + @DisplayName("different lists") public void testDifferentListsOfTheSameLengthAreUnequal() { Relationship relationship = new RelationshipComputer<>().computeRelationship( asList(1, 2, 3), @@ -62,6 +68,7 @@ public void testDifferentListsOfTheSameLengthAreUnequal() { @Disabled("Remove to run test") @Test + @DisplayName("false start") public void testSublistCheckDoesNotAbortAfterFalseStart() { Relationship relationship = new RelationshipComputer<>().computeRelationship( asList('1', '2', '5'), @@ -72,6 +79,7 @@ public void testSublistCheckDoesNotAbortAfterFalseStart() { @Disabled("Remove to run test") @Test + @DisplayName("consecutive") public void testSublistCheckHandlesExtraneousRepeatsOfFirstEntry() { Relationship relationship = new RelationshipComputer<>().computeRelationship( asList("1", "1", "2"), @@ -82,6 +90,7 @@ public void testSublistCheckHandlesExtraneousRepeatsOfFirstEntry() { @Disabled("Remove to run test") @Test + @DisplayName("sublist at start") public void testSublistAtStart() { Relationship relationship = new RelationshipComputer<>().computeRelationship( asList(0, 1, 2), @@ -92,6 +101,7 @@ public void testSublistAtStart() { @Disabled("Remove to run test") @Test + @DisplayName("sublist in middle") public void testSublistInMiddle() { Relationship relationship = new RelationshipComputer<>().computeRelationship( asList('2', '3', '4'), @@ -102,6 +112,7 @@ public void testSublistInMiddle() { @Disabled("Remove to run test") @Test + @DisplayName("sublist at end") public void testSublistAtEnd() { Relationship relationship = new RelationshipComputer<>().computeRelationship( asList("3", "4", "5"), @@ -112,6 +123,7 @@ public void testSublistAtEnd() { @Disabled("Remove to run test") @Test + @DisplayName("at start of superlist") public void testAtStartOfSuperlist() { Relationship relationship = new RelationshipComputer<>().computeRelationship( asList(0, 1, 2, 3, 4, 5), @@ -122,6 +134,7 @@ public void testAtStartOfSuperlist() { @Disabled("Remove to run test") @Test + @DisplayName("in middle of superlist") public void testInMiddleOfSuperlist() { Relationship relationship = new RelationshipComputer<>().computeRelationship( asList('0', '1', '2', '3', '4', '5'), @@ -132,6 +145,7 @@ public void testInMiddleOfSuperlist() { @Disabled("Remove to run test") @Test + @DisplayName("at end of superlist") public void testAtEndOfSuperlist() { Relationship relationship = new RelationshipComputer<>().computeRelationship( asList("0", "1", "2", "3", "4", "5"), @@ -142,6 +156,7 @@ public void testAtEndOfSuperlist() { @Disabled("Remove to run test") @Test + @DisplayName("first list missing element from second list") public void testFirstListMissingElementFromSecondList() { Relationship relationship = new RelationshipComputer<>().computeRelationship( asList(1, 3), @@ -152,6 +167,7 @@ public void testFirstListMissingElementFromSecondList() { @Disabled("Remove to run test") @Test + @DisplayName("second list missing element from first list") public void testSecondListMissingElementFromFirstList() { Relationship relationship = new RelationshipComputer<>().computeRelationship( asList('1', '2', '3'), @@ -162,30 +178,33 @@ public void testSecondListMissingElementFromFirstList() { @Disabled("Remove to run test") @Test - public void testThatListOrderingIsAccountedFor() { + @DisplayName("first list missing additional digits from second list") + public void testFirstListMissingAdditionalDigitsFromSecondList() { Relationship relationship = new RelationshipComputer<>().computeRelationship( - asList("1", "2", "3"), - asList("3", "2", "1")); + asList(1, 2), + asList(1, 22)); assertThat(relationship).isEqualTo(Relationship.UNEQUAL); } @Disabled("Remove to run test") @Test - public void testThatListsWithSameDigitsButDifferentNumbersAreUnequal() { + @DisplayName("order matters to a list") + public void testThatListOrderingIsAccountedFor() { Relationship relationship = new RelationshipComputer<>().computeRelationship( - asList(1, 0, 1), - asList(10, 1)); + asList("1", "2", "3"), + asList("3", "2", "1")); assertThat(relationship).isEqualTo(Relationship.UNEQUAL); } @Disabled("Remove to run test") @Test - public void testFirstListMissingAdditionalDigitsFromSecondList() { + @DisplayName("same digits but different numbers") + public void testThatListsWithSameDigitsButDifferentNumbersAreUnequal() { Relationship relationship = new RelationshipComputer<>().computeRelationship( - asList(1, 2), - asList(1, 22)); + asList(1, 0, 1), + asList(10, 1)); assertThat(relationship).isEqualTo(Relationship.UNEQUAL); } diff --git a/exercises/practice/sum-of-multiples/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/sum-of-multiples/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/sum-of-multiples/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/sum-of-multiples/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/sum-of-multiples/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/sum-of-multiples/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/sum-of-multiples/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/sum-of-multiples/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/sum-of-multiples/gradlew b/exercises/practice/sum-of-multiples/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/sum-of-multiples/gradlew +++ b/exercises/practice/sum-of-multiples/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/sum-of-multiples/gradlew.bat b/exercises/practice/sum-of-multiples/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/sum-of-multiples/gradlew.bat +++ b/exercises/practice/sum-of-multiples/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/sum-of-multiples/src/test/java/SumOfMultiplesTest.java b/exercises/practice/sum-of-multiples/src/test/java/SumOfMultiplesTest.java index c7f7ddfbc..b2736d8bd 100644 --- a/exercises/practice/sum-of-multiples/src/test/java/SumOfMultiplesTest.java +++ b/exercises/practice/sum-of-multiples/src/test/java/SumOfMultiplesTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -6,6 +7,7 @@ public class SumOfMultiplesTest { @Test + @DisplayName("no multiples within limit") public void testNoMultiplesWithinLimit() { int[] set = { @@ -19,6 +21,7 @@ public void testNoMultiplesWithinLimit() { @Disabled("Remove to run test") @Test + @DisplayName("one factor has multiples within limit") public void testOneFactorHasMultiplesWithinLimit() { int[] set = { @@ -32,6 +35,7 @@ public void testOneFactorHasMultiplesWithinLimit() { @Disabled("Remove to run test") @Test + @DisplayName("more than one multiple within limit") public void testMoreThanOneMultipleWithinLimit() { int[] set = { @@ -44,6 +48,7 @@ public void testMoreThanOneMultipleWithinLimit() { @Disabled("Remove to run test") @Test + @DisplayName("more than one factor with multiples within limit") public void testMoreThanOneFactorWithMultiplesWithinLimit() { int[] set = { @@ -57,6 +62,7 @@ public void testMoreThanOneFactorWithMultiplesWithinLimit() { @Disabled("Remove to run test") @Test + @DisplayName("each multiple is only counted once") public void testEachMultipleIsOnlyCountedOnce() { int[] set = { @@ -70,6 +76,7 @@ public void testEachMultipleIsOnlyCountedOnce() { @Disabled("Remove to run test") @Test + @DisplayName("a much larger limit") public void testAMuchLargerLimit() { int[] set = { @@ -83,6 +90,7 @@ public void testAMuchLargerLimit() { @Disabled("Remove to run test") @Test + @DisplayName("three factors") public void testThreeFactors() { int[] set = { @@ -97,6 +105,7 @@ public void testThreeFactors() { @Disabled("Remove to run test") @Test + @DisplayName("factors not relatively prime") public void testFactorsNotRelativelyPrime() { int[] set = { @@ -110,6 +119,7 @@ public void testFactorsNotRelativelyPrime() { @Disabled("Remove to run test") @Test + @DisplayName("some pairs of factors relatively prime and some not") public void testSomePairsOfFactorsRelativelyPrimeAndSomeNot() { int[] set = { @@ -124,6 +134,7 @@ public void testSomePairsOfFactorsRelativelyPrimeAndSomeNot() { @Disabled("Remove to run test") @Test + @DisplayName("one factor is a multiple of another") public void testOneFactorIsAMultipleOfAnother() { int[] set = { @@ -137,6 +148,7 @@ public void testOneFactorIsAMultipleOfAnother() { @Disabled("Remove to run test") @Test + @DisplayName("much larger factors") public void testMuchLargerFactors() { int[] set = { @@ -150,6 +162,7 @@ public void testMuchLargerFactors() { @Disabled("Remove to run test") @Test + @DisplayName("all numbers are multiples of 1") public void testAllNumbersAreMultiplesOf1() { int[] set = { @@ -162,6 +175,7 @@ public void testAllNumbersAreMultiplesOf1() { @Disabled("Remove to run test") @Test + @DisplayName("no factors means an empty sum") public void testNoFactorsMeanAnEmptySum() { int[] set = {}; @@ -172,6 +186,7 @@ public void testNoFactorsMeanAnEmptySum() { @Disabled("Remove to run test") @Test + @DisplayName("the only multiple of 0 is 0") public void testSumOfMultiplesOfZeroIsZero() { int[] set = { @@ -184,6 +199,7 @@ public void testSumOfMultiplesOfZeroIsZero() { @Disabled("Remove to run test") @Test + @DisplayName("the factor 0 does not affect the sum of multiples of other factors") public void testFactorZeroDoesNotAffectTheSumOfMultiplesOfOtherFactors() { int[] set = { @@ -197,6 +213,7 @@ public void testFactorZeroDoesNotAffectTheSumOfMultiplesOfOtherFactors() { @Disabled("Remove to run test") @Test + @DisplayName("solutions using include-exclude must extend to cardinality greater than 3") public void testSolutionsUsingIncludeExcludeMustExtendToCardinalityGreater3() { int[] set = { diff --git a/exercises/practice/swift-scheduling/.docs/instructions.md b/exercises/practice/swift-scheduling/.docs/instructions.md new file mode 100644 index 000000000..6423a1066 --- /dev/null +++ b/exercises/practice/swift-scheduling/.docs/instructions.md @@ -0,0 +1,50 @@ +# Instructions + +Your task is to convert delivery date descriptions to _actual_ delivery dates, based on when the meeting started. + +There are two types of delivery date descriptions: + +1. Fixed: a predefined set of words. +2. Variable: words that have a variable component, but follow a predefined set of patterns. + +## Fixed delivery date descriptions + +There are three fixed delivery date descriptions: + +- `"NOW"` +- `"ASAP"` (As Soon As Possible) +- `"EOW"` (End Of Week) + +The following table shows how to translate them: + +| Description | Meeting start | Delivery date | +| ----------- | ----------------------------- | ----------------------------------- | +| `"NOW"` | - | Two hours after the meeting started | +| `"ASAP"` | Before 13:00 | Today at 17:00 | +| `"ASAP"` | After or at 13:00 | Tomorrow at 13:00 | +| `"EOW"` | Monday, Tuesday, or Wednesday | Friday at 17:00 | +| `"EOW"` | Thursday or Friday | Sunday at 20:00 | + +## Variable delivery date descriptions + +There are two variable delivery date description patterns: + +- `"M"` (N-th month) +- `"Q"` (N-th quarter) + +| Description | Meeting start | Delivery date | +| ----------- | ------------------------- | --------------------------------------------------------- | +| `"M"` | Before N-th month | At 8:00 on the _first_ workday of this year's N-th month | +| `"M"` | After or in N-th month | At 8:00 on the _first_ workday of next year's N-th month | +| `"Q"` | Before or in N-th quarter | At 8:00 on the _last_ workday of this year's N-th quarter | +| `"Q"` | After N-th quarter | At 8:00 on the _last_ workday of next year's N-th quarter | + +~~~~exercism/note +A workday is a Monday, Tuesday, Wednesday, Thursday, or Friday. + +A year has four quarters, each with three months: +1. January/February/March +2. April/May/June +3. July/August/September +4. October/November/December. +~~~~ diff --git a/exercises/practice/swift-scheduling/.docs/introduction.md b/exercises/practice/swift-scheduling/.docs/introduction.md new file mode 100644 index 000000000..2322f813f --- /dev/null +++ b/exercises/practice/swift-scheduling/.docs/introduction.md @@ -0,0 +1,6 @@ +# Introduction + +This week, it is your turn to take notes in the department's planning meeting. +In this meeting, your boss will set delivery dates for all open work items. +Annoyingly, instead of specifying the _actual_ delivery dates, your boss will only _describe them_ in an abbreviated format. +As many of your colleagues won't be familiar with this corporate lingo, you'll need to convert these delivery date descriptions to actual delivery dates. diff --git a/exercises/practice/swift-scheduling/.meta/config.json b/exercises/practice/swift-scheduling/.meta/config.json new file mode 100644 index 000000000..2c2db5875 --- /dev/null +++ b/exercises/practice/swift-scheduling/.meta/config.json @@ -0,0 +1,22 @@ +{ + "authors": [ + "zamora-carlos" + ], + "files": { + "solution": [ + "src/main/java/SwiftScheduling.java" + ], + "test": [ + "src/test/java/SwiftSchedulingTest.java" + ], + "example": [ + ".meta/src/reference/java/SwiftScheduling.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "blurb": "Convert delivery date descriptions to actual delivery dates.", + "source": "Erik Schierboom", + "source_url": "https://github.com/exercism/problem-specifications/pull/2536" +} diff --git a/exercises/practice/swift-scheduling/.meta/src/reference/java/SwiftScheduling.java b/exercises/practice/swift-scheduling/.meta/src/reference/java/SwiftScheduling.java new file mode 100644 index 000000000..8bff6e3d3 --- /dev/null +++ b/exercises/practice/swift-scheduling/.meta/src/reference/java/SwiftScheduling.java @@ -0,0 +1,97 @@ +import java.time.DayOfWeek; +import java.time.LocalDateTime; + +import static java.time.DayOfWeek.*; + +public class SwiftScheduling { + public static LocalDateTime convertToDeliveryDate(LocalDateTime meetingStart, String description) { + if ("NOW".equals(description)) { + return meetingStart.plusHours(2); + } + + if ("ASAP".equals(description)) { + LocalDateTime sameDayAt1pm = toStartOfDay(meetingStart).withHour(13); + + if (meetingStart.isBefore(sameDayAt1pm)) { + return toStartOfDay(meetingStart).withHour(17); + } else { + return toStartOfDay(meetingStart).plusDays(1).withHour(13); + } + } + + if ("EOW".equals(description)) { + DayOfWeek day = meetingStart.getDayOfWeek(); + LocalDateTime deliveryDate = toStartOfDay(meetingStart); + + if (day == MONDAY || day == TUESDAY || day == WEDNESDAY) { + deliveryDate = deliveryDate.withHour(17); + while (deliveryDate.getDayOfWeek() != FRIDAY) { + deliveryDate = deliveryDate.plusDays(1); + } + } else if (day == THURSDAY || day == FRIDAY) { + deliveryDate = deliveryDate.withHour(20); + while (deliveryDate.getDayOfWeek() != SUNDAY) { + deliveryDate = deliveryDate.plusDays(1); + } + } else { + throw new IllegalArgumentException("Invalid day of week"); + } + + return deliveryDate; + } + + if (description.matches("\\d+M")) { + int month = Integer.parseInt(description.substring(0, description.length() - 1)); + LocalDateTime targetMonth = toStartOfDay(meetingStart) + .withMonth(month) + .withDayOfMonth(1); + + if (!meetingStart.isBefore(targetMonth)) { + targetMonth = targetMonth.plusYears(1); + } + + LocalDateTime deliveryDate = targetMonth.withHour(8); + while (isWeekend(deliveryDate)) { + deliveryDate = deliveryDate.plusDays(1); + } + + return deliveryDate; + } + + if (description.matches("Q\\d")) { + int quarter = Integer.parseInt(description.substring(1)); + LocalDateTime lastDayOfQuarter = getLastDayOfQuarter(meetingStart, quarter); + + if (!meetingStart.isBefore(lastDayOfQuarter.plusDays(1))) { + lastDayOfQuarter = lastDayOfQuarter.plusYears(1); + } + + LocalDateTime deliveryDate = lastDayOfQuarter.withHour(8); + while (isWeekend(deliveryDate)) { + deliveryDate = deliveryDate.minusDays(1); + } + + return deliveryDate; + } + + throw new IllegalArgumentException("Invalid description"); + } + + private static LocalDateTime toStartOfDay(LocalDateTime dateTime) { + return dateTime.toLocalDate().atStartOfDay(); + } + + private static LocalDateTime getLastDayOfQuarter(LocalDateTime dateTime, int quarter) { + int lastMonthOfQuarter = quarter * 3; + return toStartOfDay(dateTime) + .withMonth(lastMonthOfQuarter) + .withDayOfMonth(1) + .plusMonths(1) + .minusDays(1); + } + + private static boolean isWeekend(LocalDateTime date) { + DayOfWeek dayOfWeek = date.getDayOfWeek(); + return dayOfWeek == SATURDAY || dayOfWeek == SUNDAY; + } +} diff --git a/exercises/practice/swift-scheduling/.meta/tests.toml b/exercises/practice/swift-scheduling/.meta/tests.toml new file mode 100644 index 000000000..7cc3e4158 --- /dev/null +++ b/exercises/practice/swift-scheduling/.meta/tests.toml @@ -0,0 +1,58 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[1d0e6e72-f370-408c-bc64-5dafa9c6da73] +description = "NOW translates to two hours later" + +[93325e7b-677d-4d96-b017-2582af879dc2] +description = "ASAP before one in the afternoon translates to today at five in the afternoon" + +[cb4252a3-c4c1-41f6-8b8c-e7269733cef8] +description = "ASAP at one in the afternoon translates to tomorrow at one in the afternoon" + +[6fddc1ea-2fe9-4c60-81f7-9220d2f45537] +description = "ASAP after one in the afternoon translates to tomorrow at one in the afternoon" + +[25f46bf9-6d2a-4e95-8edd-f62dd6bc8a6e] +description = "EOW on Monday translates to Friday at five in the afternoon" + +[0b375df5-d198-489e-acee-fd538a768616] +description = "EOW on Tuesday translates to Friday at five in the afternoon" + +[4afbb881-0b5c-46be-94e1-992cdc2a8ca4] +description = "EOW on Wednesday translates to Friday at five in the afternoon" + +[e1341c2b-5e1b-4702-a95c-a01e8e96e510] +description = "EOW on Thursday translates to Sunday at eight in the evening" + +[bbffccf7-97f7-4244-888d-bdd64348fa2e] +description = "EOW on Friday translates to Sunday at eight in the evening" + +[d651fcf4-290e-407c-8107-36b9076f39b2] +description = "EOW translates to leap day" + +[439bf09f-3a0e-44e7-bad5-b7b6d0c4505a] +description = "2M before the second month of this year translates to the first workday of the second month of this year" + +[86d82e83-c481-4fb4-9264-625de7521340] +description = "11M in the eleventh month translates to the first workday of the eleventh month of next year" + +[0d0b8f6a-1915-46f5-a630-1ff06af9da08] +description = "4M in the ninth month translates to the first workday of the fourth month of next year" + +[06d401e3-8461-438f-afae-8d26aa0289e0] +description = "Q1 in the first quarter translates to the last workday of the first quarter of this year" + +[eebd5f32-b16d-4ecd-91a0-584b0364b7ed] +description = "Q4 in the second quarter translates to the last workday of the fourth quarter of this year" + +[c920886c-44ad-4d34-a156-dc4176186581] +description = "Q3 in the fourth quarter translates to the last workday of the third quarter of next year" diff --git a/exercises/practice/swift-scheduling/build.gradle b/exercises/practice/swift-scheduling/build.gradle new file mode 100644 index 000000000..dd3862eb9 --- /dev/null +++ b/exercises/practice/swift-scheduling/build.gradle @@ -0,0 +1,25 @@ +plugins { + id "java" +} + +repositories { + mavenCentral() +} + +dependencies { + testImplementation platform("org.junit:junit-bom:5.10.0") + testImplementation "org.junit.jupiter:junit-jupiter" + testImplementation "org.assertj:assertj-core:3.25.1" + + testRuntimeOnly "org.junit.platform:junit-platform-launcher" +} + +test { + useJUnitPlatform() + + testLogging { + exceptionFormat = "full" + showStandardStreams = true + events = ["passed", "failed", "skipped"] + } +} diff --git a/exercises/practice/swift-scheduling/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/swift-scheduling/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..f8e1ee312 Binary files /dev/null and b/exercises/practice/swift-scheduling/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/swift-scheduling/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/swift-scheduling/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..4d97ea344 --- /dev/null +++ b/exercises/practice/swift-scheduling/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/exercises/practice/swift-scheduling/gradlew b/exercises/practice/swift-scheduling/gradlew new file mode 100755 index 000000000..adff685a0 --- /dev/null +++ b/exercises/practice/swift-scheduling/gradlew @@ -0,0 +1,248 @@ +#!/bin/sh + +# +# Copyright © 2015 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/exercises/practice/swift-scheduling/gradlew.bat b/exercises/practice/swift-scheduling/gradlew.bat new file mode 100644 index 000000000..c4bdd3ab8 --- /dev/null +++ b/exercises/practice/swift-scheduling/gradlew.bat @@ -0,0 +1,93 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/exercises/practice/swift-scheduling/src/main/java/SwiftScheduling.java b/exercises/practice/swift-scheduling/src/main/java/SwiftScheduling.java new file mode 100644 index 000000000..e5b85bec9 --- /dev/null +++ b/exercises/practice/swift-scheduling/src/main/java/SwiftScheduling.java @@ -0,0 +1,7 @@ +import java.time.LocalDateTime; + +public class SwiftScheduling { + public static LocalDateTime convertToDeliveryDate(LocalDateTime meetingStart, String description) { + throw new UnsupportedOperationException("Delete this statement and write your own implementation."); + } +} diff --git a/exercises/practice/swift-scheduling/src/test/java/SwiftSchedulingTest.java b/exercises/practice/swift-scheduling/src/test/java/SwiftSchedulingTest.java new file mode 100644 index 000000000..ffde7b7a0 --- /dev/null +++ b/exercises/practice/swift-scheduling/src/test/java/SwiftSchedulingTest.java @@ -0,0 +1,202 @@ +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.time.LocalDateTime; + +import static org.assertj.core.api.Assertions.assertThat; + +class SwiftSchedulingTest { + @Test + @DisplayName("NOW translates to two hours later") + void testNowAtNineAm() { + LocalDateTime meetingStart = LocalDateTime.parse("2012-02-13T09:00:00"); + LocalDateTime expected = LocalDateTime.parse("2012-02-13T11:00:00"); + + LocalDateTime actual = SwiftScheduling.convertToDeliveryDate(meetingStart, "NOW"); + + assertThat(actual).isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("ASAP before one in the afternoon translates to today at five in the afternoon") + void testAsapBeforeOnePm() { + LocalDateTime meetingStart = LocalDateTime.parse("1999-06-03T09:45:00"); + LocalDateTime expected = LocalDateTime.parse("1999-06-03T17:00:00"); + + LocalDateTime actual = SwiftScheduling.convertToDeliveryDate(meetingStart, "ASAP"); + + assertThat(actual).isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("ASAP at one in the afternoon translates to tomorrow at one in the afternoon") + void testAsapAtOnePm() { + LocalDateTime meetingStart = LocalDateTime.parse("2008-12-21T13:00:00"); + LocalDateTime expected = LocalDateTime.parse("2008-12-22T13:00:00"); + + LocalDateTime actual = SwiftScheduling.convertToDeliveryDate(meetingStart, "ASAP"); + + assertThat(actual).isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("ASAP after one in the afternoon translates to tomorrow at one in the afternoon") + void testAsapAfterOnePm() { + LocalDateTime meetingStart = LocalDateTime.parse("2008-12-21T14:50:00"); + LocalDateTime expected = LocalDateTime.parse("2008-12-22T13:00:00"); + + LocalDateTime actual = SwiftScheduling.convertToDeliveryDate(meetingStart, "ASAP"); + + assertThat(actual).isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("EOW on Monday translates to Friday at five in the afternoon") + void testEowOnMonday() { + LocalDateTime meetingStart = LocalDateTime.parse("2025-02-03T16:00:00"); + LocalDateTime expected = LocalDateTime.parse("2025-02-07T17:00:00"); + + LocalDateTime actual = SwiftScheduling.convertToDeliveryDate(meetingStart, "EOW"); + + assertThat(actual).isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("EOW on Tuesday translates to Friday at five in the afternoon") + void testEowOnTuesday() { + LocalDateTime meetingStart = LocalDateTime.parse("1997-04-29T10:50:00"); + LocalDateTime expected = LocalDateTime.parse("1997-05-02T17:00:00"); + + LocalDateTime actual = SwiftScheduling.convertToDeliveryDate(meetingStart, "EOW"); + + assertThat(actual).isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("EOW on Wednesday translates to Friday at five in the afternoon") + void testEowOnWednesday() { + LocalDateTime meetingStart = LocalDateTime.parse("2005-09-14T11:00:00"); + LocalDateTime expected = LocalDateTime.parse("2005-09-16T17:00:00"); + + LocalDateTime actual = SwiftScheduling.convertToDeliveryDate(meetingStart, "EOW"); + + assertThat(actual).isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("EOW on Thursday translates to Sunday at eight in the evening") + void testEowOnThursday() { + LocalDateTime meetingStart = LocalDateTime.parse("2011-05-19T08:30:00"); + LocalDateTime expected = LocalDateTime.parse("2011-05-22T20:00:00"); + + LocalDateTime actual = SwiftScheduling.convertToDeliveryDate(meetingStart, "EOW"); + + assertThat(actual).isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("EOW on Friday translates to Sunday at eight in the evening") + void testEowOnFriday() { + LocalDateTime meetingStart = LocalDateTime.parse("2022-08-05T14:00:00"); + LocalDateTime expected = LocalDateTime.parse("2022-08-07T20:00:00"); + + LocalDateTime actual = SwiftScheduling.convertToDeliveryDate(meetingStart, "EOW"); + + assertThat(actual).isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("EOW translates to leap day") + void testEowDuringLeapYear() { + LocalDateTime meetingStart = LocalDateTime.parse("2008-02-25T10:30:00"); + LocalDateTime expected = LocalDateTime.parse("2008-02-29T17:00:00"); + + LocalDateTime actual = SwiftScheduling.convertToDeliveryDate(meetingStart, "EOW"); + + assertThat(actual).isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName( + "2M before the second month of this year translates to the first workday of the second month of this year" + ) + void test2MInJanuary() { + LocalDateTime meetingStart = LocalDateTime.parse("2007-01-02T14:15:00"); + LocalDateTime expected = LocalDateTime.parse("2007-02-01T08:00:00"); + + LocalDateTime actual = SwiftScheduling.convertToDeliveryDate(meetingStart, "2M"); + + assertThat(actual).isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("11M in the eleventh month translates to the first workday of the eleventh month of next year") + void test11MInNovember() { + LocalDateTime meetingStart = LocalDateTime.parse("2013-11-21T15:30:00"); + LocalDateTime expected = LocalDateTime.parse("2014-11-03T08:00:00"); + + LocalDateTime actual = SwiftScheduling.convertToDeliveryDate(meetingStart, "11M"); + + assertThat(actual).isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("4M in the ninth month translates to the first workday of the fourth month of next year") + void test4MInNovember() { + LocalDateTime meetingStart = LocalDateTime.parse("2019-11-18T15:15:00"); + LocalDateTime expected = LocalDateTime.parse("2020-04-01T08:00:00"); + + LocalDateTime actual = SwiftScheduling.convertToDeliveryDate(meetingStart, "4M"); + + assertThat(actual).isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("Q1 in the first quarter translates to the last workday of the first quarter of this year") + void testQ1InQ1() { + LocalDateTime meetingStart = LocalDateTime.parse("2003-01-01T10:45:00"); + LocalDateTime expected = LocalDateTime.parse("2003-03-31T08:00:00"); + + LocalDateTime actual = SwiftScheduling.convertToDeliveryDate(meetingStart, "Q1"); + + assertThat(actual).isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("Q4 in the second quarter translates to the last workday of the fourth quarter of this year") + void testQ4InQ2() { + LocalDateTime meetingStart = LocalDateTime.parse("2001-04-09T09:00:00"); + LocalDateTime expected = LocalDateTime.parse("2001-12-31T08:00:00"); + + LocalDateTime actual = SwiftScheduling.convertToDeliveryDate(meetingStart, "Q4"); + + assertThat(actual).isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("Q3 in the fourth quarter translates to the last workday of the third quarter of next year") + void testQ3InQ4() { + LocalDateTime meetingStart = LocalDateTime.parse("2022-10-06T11:00:00"); + LocalDateTime expected = LocalDateTime.parse("2023-09-29T08:00:00"); + + LocalDateTime actual = SwiftScheduling.convertToDeliveryDate(meetingStart, "Q3"); + + assertThat(actual).isEqualTo(expected); + } +} diff --git a/exercises/practice/tournament/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/tournament/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/tournament/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/tournament/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/tournament/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/tournament/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/tournament/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/tournament/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/tournament/gradlew b/exercises/practice/tournament/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/tournament/gradlew +++ b/exercises/practice/tournament/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/tournament/gradlew.bat b/exercises/practice/tournament/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/tournament/gradlew.bat +++ b/exercises/practice/tournament/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/tournament/src/test/java/TournamentTest.java b/exercises/practice/tournament/src/test/java/TournamentTest.java index aa34a8d05..94accd8fb 100644 --- a/exercises/practice/tournament/src/test/java/TournamentTest.java +++ b/exercises/practice/tournament/src/test/java/TournamentTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -14,6 +15,7 @@ public void setUp() { } @Test + @DisplayName("just the header if no input") public void justTheHeaderIfNoInput() { assertThat(tournament.printTable()) .isEqualTo("Team | MP | W | D | L | P\n"); @@ -21,6 +23,7 @@ public void justTheHeaderIfNoInput() { @Disabled("Remove to run test") @Test + @DisplayName("a win is three points, a loss is zero points") public void aWinIsThreePointsALossIsZeroPoints() { tournament.applyResults("Allegoric Alaskans;Blithering Badgers;win"); assertThat(tournament.printTable()) @@ -32,6 +35,7 @@ public void aWinIsThreePointsALossIsZeroPoints() { @Disabled("Remove to run test") @Test + @DisplayName("a win can also be expressed as a loss") public void aWinCanAlsoBeExpressedAsALoss() { tournament.applyResults("Blithering Badgers;Allegoric Alaskans;loss"); assertThat(tournament.printTable()) @@ -43,6 +47,7 @@ public void aWinCanAlsoBeExpressedAsALoss() { @Disabled("Remove to run test") @Test + @DisplayName("a different team can win") public void aDifferentTeamCanWin() { tournament.applyResults("Blithering Badgers;Allegoric Alaskans;win"); assertThat(tournament.printTable()) @@ -54,6 +59,7 @@ public void aDifferentTeamCanWin() { @Disabled("Remove to run test") @Test + @DisplayName("a draw is one point each") public void aDrawIsOnePointEach() { tournament.applyResults("Allegoric Alaskans;Blithering Badgers;draw"); assertThat(tournament.printTable()) @@ -65,6 +71,7 @@ public void aDrawIsOnePointEach() { @Disabled("Remove to run test") @Test + @DisplayName("There can be more than one match") public void thereCanBeMoreThanOneMatch() { tournament.applyResults( "Allegoric Alaskans;Blithering Badgers;win\n" + @@ -78,6 +85,7 @@ public void thereCanBeMoreThanOneMatch() { @Disabled("Remove to run test") @Test + @DisplayName("There can be more than one winner") public void thereCanBeMoreThanOneWinner() { tournament.applyResults( "Allegoric Alaskans;Blithering Badgers;loss\n" + @@ -91,6 +99,7 @@ public void thereCanBeMoreThanOneWinner() { @Disabled("Remove to run test") @Test + @DisplayName("There can be more than two teams") public void thereCanBeMoreThanTwoTeams() { tournament.applyResults( "Allegoric Alaskans;Blithering Badgers;win\n" + @@ -106,6 +115,7 @@ public void thereCanBeMoreThanTwoTeams() { @Disabled("Remove to run test") @Test + @DisplayName("typical input") public void typicalInput() { tournament.applyResults( "Allegoric Alaskans;Blithering Badgers;win\n" + @@ -125,6 +135,7 @@ public void typicalInput() { @Disabled("Remove to run test") @Test + @DisplayName("incomplete competition (not all pairs have played)") public void incompleteCompetition() { tournament.applyResults( "Allegoric Alaskans;Blithering Badgers;loss\n" + @@ -142,6 +153,7 @@ public void incompleteCompetition() { @Disabled("Remove to run test") @Test + @DisplayName("ties broken alphabetically") public void tiesBrokenAlphabetically() { tournament.applyResults( "Courageous Californians;Devastating Donkeys;win\n" + @@ -161,6 +173,7 @@ public void tiesBrokenAlphabetically() { @Disabled("Remove to run test") @Test + @DisplayName("ensure points sorted numerically") public void pointsSortedNumerically() { tournament.applyResults( "Devastating Donkeys;Blithering Badgers;win\n" + diff --git a/exercises/practice/transpose/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/transpose/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/transpose/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/transpose/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/transpose/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/transpose/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/transpose/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/transpose/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/transpose/gradlew b/exercises/practice/transpose/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/transpose/gradlew +++ b/exercises/practice/transpose/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/transpose/gradlew.bat b/exercises/practice/transpose/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/transpose/gradlew.bat +++ b/exercises/practice/transpose/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/transpose/src/test/java/TransposeTest.java b/exercises/practice/transpose/src/test/java/TransposeTest.java index ad8f95f29..8a4b18686 100644 --- a/exercises/practice/transpose/src/test/java/TransposeTest.java +++ b/exercises/practice/transpose/src/test/java/TransposeTest.java @@ -1,6 +1,7 @@ import static org.assertj.core.api.Assertions.assertThat; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.BeforeEach; @@ -13,12 +14,14 @@ public void setup() { } @Test + @DisplayName("empty string") public void emptyString() { assertThat(transpose.transpose("")).isEqualTo(""); } @Disabled("Remove to run test") @Test + @DisplayName("two characters in a row") public void twoCharactersInARow() { assertThat(transpose.transpose("A1")) .isEqualTo( @@ -28,6 +31,7 @@ public void twoCharactersInARow() { @Disabled("Remove to run test") @Test + @DisplayName("two characters in a column") public void twoCharactersInAColumn() { assertThat( transpose.transpose( @@ -38,6 +42,7 @@ public void twoCharactersInAColumn() { @Disabled("Remove to run test") @Test + @DisplayName("simple") public void simple() { assertThat( transpose.transpose( @@ -51,6 +56,7 @@ public void simple() { @Disabled("Remove to run test") @Test + @DisplayName("single line") public void singleLine() { assertThat(transpose.transpose("Single line.")) .isEqualTo( @@ -70,6 +76,7 @@ public void singleLine() { @Disabled("Remove to run test") @Test + @DisplayName("first line longer than second line") public void firstLineLongerThanSecondLine() { assertThat( transpose.transpose( @@ -96,6 +103,7 @@ public void firstLineLongerThanSecondLine() { @Disabled("Remove to run test") @Test + @DisplayName("second line longer than first line") public void secondLineLongerThanFirstLine() { assertThat( transpose.transpose( @@ -122,6 +130,7 @@ public void secondLineLongerThanFirstLine() { @Disabled("Remove to run test") @Test + @DisplayName("mixed line length") public void mixedLineLength() { assertThat( transpose.transpose( @@ -151,6 +160,7 @@ public void mixedLineLength() { @Disabled("Remove to run test") @Test + @DisplayName("square") public void square() { assertThat( transpose.transpose( @@ -169,6 +179,7 @@ public void square() { @Disabled("Remove to run test") @Test + @DisplayName("rectangle") public void rectangle() { assertThat( transpose.transpose( @@ -189,6 +200,7 @@ public void rectangle() { @Disabled("Remove to run test") @Test + @DisplayName("triangle") public void triangle() { assertThat( transpose.transpose( @@ -209,6 +221,7 @@ public void triangle() { @Disabled("Remove to run test") @Test + @DisplayName("jagged triangle") public void jaggedTriangle() { assertThat( transpose.transpose( diff --git a/exercises/practice/tree-building/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/tree-building/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/tree-building/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/tree-building/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/tree-building/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/tree-building/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/tree-building/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/tree-building/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/tree-building/gradlew b/exercises/practice/tree-building/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/tree-building/gradlew +++ b/exercises/practice/tree-building/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/tree-building/gradlew.bat b/exercises/practice/tree-building/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/tree-building/gradlew.bat +++ b/exercises/practice/tree-building/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/tree-building/src/test/java/BuildTreeTest.java b/exercises/practice/tree-building/src/test/java/BuildTreeTest.java index c34bb3cc9..e11bc2990 100644 --- a/exercises/practice/tree-building/src/test/java/BuildTreeTest.java +++ b/exercises/practice/tree-building/src/test/java/BuildTreeTest.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.ArrayList; @@ -9,6 +10,7 @@ public class BuildTreeTest { @Test + @DisplayName("Empty list") public void testEmptyList() throws InvalidRecordsException { ArrayList records = new ArrayList<>(); @@ -18,6 +20,7 @@ public void testEmptyList() throws InvalidRecordsException { @Disabled("Remove to run test") @Test + @DisplayName("Single record") public void testOneRecord() throws InvalidRecordsException { ArrayList records = new ArrayList<>(); Record record = new Record(0, 0); @@ -30,6 +33,7 @@ public void testOneRecord() throws InvalidRecordsException { @Disabled("Remove to run test") @Test + @DisplayName("Three records in order") public void testThreeRecordsInOrder() throws InvalidRecordsException { ArrayList records = new ArrayList<>(); records.add(new Record(0, 0)); @@ -48,6 +52,7 @@ public void testThreeRecordsInOrder() throws InvalidRecordsException { @Disabled("Remove to run test") @Test + @DisplayName("Three records in reverse order") public void testThreeRecordsInReverseOrder() throws InvalidRecordsException { ArrayList records = new ArrayList<>(); records.add(new Record(2, 0)); @@ -66,6 +71,7 @@ public void testThreeRecordsInReverseOrder() throws InvalidRecordsException { @Disabled("Remove to run test") @Test + @DisplayName("More than two children") public void testRecordsWithMoreThanTwoChildren() throws InvalidRecordsException { ArrayList records = new ArrayList<>(); records.add(new Record(0, 0)); @@ -83,11 +89,11 @@ public void testRecordsWithMoreThanTwoChildren() throws InvalidRecordsException assertThat(root.getChildren().get(0).getNodeId()).isEqualTo(1); assertThat(root.getChildren().get(1).getNodeId()).isEqualTo(2); assertThat(root.getChildren().get(2).getNodeId()).isEqualTo(3); - } @Disabled("Remove to run test") @Test + @DisplayName("Binary tree") public void testBinaryTree() throws InvalidRecordsException { ArrayList records = new ArrayList<>(); records.add(new Record(6, 2)); @@ -119,6 +125,7 @@ public void testBinaryTree() throws InvalidRecordsException { @Disabled("Remove to run test") @Test + @DisplayName("Unbalanced tree") public void testUnbalancedTree() throws InvalidRecordsException { ArrayList records = new ArrayList<>(); records.add(new Record(0, 0)); @@ -149,6 +156,7 @@ public void testUnbalancedTree() throws InvalidRecordsException { @Disabled("Remove to run test") @Test + @DisplayName("Root has parent") public void testRootNodeHasParent() { ArrayList records = new ArrayList<>(); records.add(new Record(0, 1)); @@ -163,6 +171,7 @@ public void testRootNodeHasParent() { @Disabled("Remove to run test") @Test + @DisplayName("No root node") public void testNoRootNode() { ArrayList records = new ArrayList<>(); records.add(new Record(1, 0)); @@ -177,6 +186,7 @@ public void testNoRootNode() { @Disabled("Remove to run test") @Test + @DisplayName("Non continuous records") public void testNonContinuousRecords() { ArrayList records = new ArrayList<>(); records.add(new Record(2, 0)); @@ -193,6 +203,7 @@ public void testNonContinuousRecords() { @Disabled("Remove to run test") @Test + @DisplayName("Cycle indirectly") public void testCycleIndirectly() { ArrayList records = new ArrayList<>(); records.add(new Record(5, 2)); diff --git a/exercises/practice/triangle/.docs/instructions.md b/exercises/practice/triangle/.docs/instructions.md index ac3900872..e9b053dcd 100644 --- a/exercises/practice/triangle/.docs/instructions.md +++ b/exercises/practice/triangle/.docs/instructions.md @@ -13,6 +13,12 @@ A _scalene_ triangle has all sides of different lengths. For a shape to be a triangle at all, all sides have to be of length > 0, and the sum of the lengths of any two sides must be greater than or equal to the length of the third side. +~~~~exercism/note +_Degenerate triangles_ are triangles where the sum of the length of two sides is **equal** to the length of the third side, e.g. `1, 1, 2`. +We opted to not include tests for degenerate triangles in this exercise. +You may handle those situations if you wish to do so, or safely ignore them. +~~~~ + In equations: Let `a`, `b`, and `c` be sides of the triangle. diff --git a/exercises/practice/triangle/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/triangle/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/triangle/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/triangle/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/triangle/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/triangle/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/triangle/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/triangle/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/triangle/gradlew b/exercises/practice/triangle/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/triangle/gradlew +++ b/exercises/practice/triangle/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/triangle/gradlew.bat b/exercises/practice/triangle/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/triangle/gradlew.bat +++ b/exercises/practice/triangle/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/triangle/src/test/java/TriangleTest.java b/exercises/practice/triangle/src/test/java/TriangleTest.java index bd6ad663a..e7dc8f630 100644 --- a/exercises/practice/triangle/src/test/java/TriangleTest.java +++ b/exercises/practice/triangle/src/test/java/TriangleTest.java @@ -3,10 +3,12 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; public class TriangleTest { @Test + @DisplayName("equilateral triangle") public void equilateralTrianglesHaveEqualSides() throws TriangleException { Triangle triangle = new Triangle(2, 2, 2); @@ -15,6 +17,7 @@ public void equilateralTrianglesHaveEqualSides() throws TriangleException { @Disabled("Remove to run test") @Test + @DisplayName("any side is unequal") public void trianglesWithOneUnequalSideAreNotEquilateral() throws TriangleException { Triangle triangle = new Triangle(2, 3, 2); @@ -23,6 +26,7 @@ public void trianglesWithOneUnequalSideAreNotEquilateral() throws TriangleExcept @Disabled("Remove to run test") @Test + @DisplayName("no sides are equal") public void trianglesWithNoEqualSidesAreNotEquilateral() throws TriangleException { Triangle triangle = new Triangle(5, 4, 6); @@ -31,12 +35,14 @@ public void trianglesWithNoEqualSidesAreNotEquilateral() throws TriangleExceptio @Disabled("Remove to run test") @Test + @DisplayName("all zero sides is not a triangle") public void trianglesWithNoSizeAreIllegal() { assertThatExceptionOfType(TriangleException.class).isThrownBy(() -> new Triangle(0, 0, 0)); } @Disabled("Remove to run test") @Test + @DisplayName("sides may be floats") public void verySmallTrianglesCanBeEquilateral() throws TriangleException { Triangle triangle = new Triangle(0.5, 0.5, 0.5); @@ -45,6 +51,7 @@ public void verySmallTrianglesCanBeEquilateral() throws TriangleException { @Disabled("Remove to run test") @Test + @DisplayName("last two sides are equal") public void isoscelesTrianglesHaveLastTwoSidesEqual() throws TriangleException { Triangle triangle = new Triangle(3, 4, 4); @@ -53,6 +60,7 @@ public void isoscelesTrianglesHaveLastTwoSidesEqual() throws TriangleException { @Disabled("Remove to run test") @Test + @DisplayName("first two sides are equal") public void isoscelesTrianglesHaveTwoFirstSidesEqual() throws TriangleException { Triangle triangle = new Triangle(4, 4, 3); @@ -61,6 +69,7 @@ public void isoscelesTrianglesHaveTwoFirstSidesEqual() throws TriangleException @Disabled("Remove to run test") @Test + @DisplayName("first and last sides are equal") public void isoscelesTrianglesHaveFirstAndLastSidesEqual() throws TriangleException { Triangle triangle = new Triangle(4, 3, 4); @@ -69,6 +78,7 @@ public void isoscelesTrianglesHaveFirstAndLastSidesEqual() throws TriangleExcept @Disabled("Remove to run test") @Test + @DisplayName("equilateral triangles are also isosceles") public void equilateralTrianglesAreAlsoIsosceles() throws TriangleException { Triangle triangle = new Triangle(4, 4, 4); @@ -77,6 +87,7 @@ public void equilateralTrianglesAreAlsoIsosceles() throws TriangleException { @Disabled("Remove to run test") @Test + @DisplayName("no sides are equal") public void noSidesAreEqualCantBeIsoceles() throws TriangleException { Triangle triangle = new Triangle(2, 3, 4); @@ -85,24 +96,28 @@ public void noSidesAreEqualCantBeIsoceles() throws TriangleException { @Disabled("Remove to run test") @Test + @DisplayName("first triangle inequality violation") public void firstTriangleInequalityViolation() { assertThatExceptionOfType(TriangleException.class).isThrownBy(() -> new Triangle(1, 1, 3)); } @Disabled("Remove to run test") @Test + @DisplayName("second triangle inequality violation") public void secondTriangleInequalityViolation() { assertThatExceptionOfType(TriangleException.class).isThrownBy(() -> new Triangle(1, 3, 1)); } @Disabled("Remove to run test") @Test + @DisplayName("third triangle inequality violation") public void thirdTriangleInequalityViolation() { assertThatExceptionOfType(TriangleException.class).isThrownBy(() -> new Triangle(3, 1, 1)); } @Disabled("Remove to run test") @Test + @DisplayName("sides may be floats") public void verySmallTrianglesCanBeIsosceles() throws TriangleException { Triangle triangle = new Triangle(0.5, 0.4, 0.5); @@ -111,6 +126,7 @@ public void verySmallTrianglesCanBeIsosceles() throws TriangleException { @Disabled("Remove to run test") @Test + @DisplayName("no sides are equal") public void scaleneTrianglesHaveNoEqualSides() throws TriangleException { Triangle triangle = new Triangle(5, 4, 6); @@ -119,6 +135,7 @@ public void scaleneTrianglesHaveNoEqualSides() throws TriangleException { @Disabled("Remove to run test") @Test + @DisplayName("all sides are equal") public void allSidesEqualAreNotScalene() throws TriangleException { Triangle triangle = new Triangle(4, 4, 4); @@ -127,6 +144,7 @@ public void allSidesEqualAreNotScalene() throws TriangleException { @Disabled("Remove to run test") @Test + @DisplayName("first and second sides are equal") public void twoSidesEqualAreNotScalene() throws TriangleException { Triangle triangle = new Triangle(4, 4, 3); @@ -135,6 +153,7 @@ public void twoSidesEqualAreNotScalene() throws TriangleException { @Disabled("Remove to run test") @Test + @DisplayName("first and third sides are equal") public void firstAndThirdSidesAreEqualAreNotScalene() throws TriangleException { Triangle triangle = new Triangle(3, 4, 3); @@ -143,6 +162,7 @@ public void firstAndThirdSidesAreEqualAreNotScalene() throws TriangleException { @Disabled("Remove to run test") @Test + @DisplayName("second and third sides are equal") public void secondAndThirdSidesAreEqualAreNotScalene() throws TriangleException { Triangle triangle = new Triangle(4, 3, 3); @@ -151,12 +171,14 @@ public void secondAndThirdSidesAreEqualAreNotScalene() throws TriangleException @Disabled("Remove to run test") @Test + @DisplayName("may not violate triangle inequality") public void mayNotViolateTriangleInequality() { assertThatExceptionOfType(TriangleException.class).isThrownBy(() -> new Triangle(7, 3, 2)); } @Disabled("Remove to run test") @Test + @DisplayName("sides may be floats") public void verySmallTrianglesCanBeScalene() throws TriangleException { Triangle triangle = new Triangle(0.5, 0.4, 0.6); diff --git a/exercises/practice/twelve-days/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/twelve-days/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/twelve-days/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/twelve-days/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/twelve-days/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/twelve-days/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/twelve-days/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/twelve-days/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/twelve-days/gradlew b/exercises/practice/twelve-days/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/twelve-days/gradlew +++ b/exercises/practice/twelve-days/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/twelve-days/gradlew.bat b/exercises/practice/twelve-days/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/twelve-days/gradlew.bat +++ b/exercises/practice/twelve-days/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/twelve-days/src/test/java/TwelveDaysTest.java b/exercises/practice/twelve-days/src/test/java/TwelveDaysTest.java index d046235eb..a6827ee51 100644 --- a/exercises/practice/twelve-days/src/test/java/TwelveDaysTest.java +++ b/exercises/practice/twelve-days/src/test/java/TwelveDaysTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -13,6 +14,7 @@ public void setup() { } @Test + @DisplayName("first day a partridge in a pear tree") public void testVerseOne() { String expectedVerseOne = "On the first day of Christmas my true love gave to me: " + "a Partridge in a Pear Tree.\n"; @@ -21,6 +23,7 @@ public void testVerseOne() { @Disabled("Remove to run test") @Test + @DisplayName("second day two turtle doves") public void testVerseTwo() { String expectedVerseTwo = "On the second day of Christmas my true love gave to me: two Turtle Doves, " + "and a Partridge in a Pear Tree.\n"; @@ -29,6 +32,7 @@ public void testVerseTwo() { @Disabled("Remove to run test") @Test + @DisplayName("third day three french hens") public void testVerseThree() { String expectedVerseThree = "On the third day of Christmas my true love gave to me: three French Hens, " + "two Turtle Doves, and a Partridge in a Pear Tree.\n"; @@ -37,6 +41,7 @@ public void testVerseThree() { @Disabled("Remove to run test") @Test + @DisplayName("fourth day four calling birds") public void testVerseFour() { String expectedVerseFour = "On the fourth day of Christmas my true love gave to me: four Calling Birds, " + "three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n"; @@ -45,6 +50,7 @@ public void testVerseFour() { @Disabled("Remove to run test") @Test + @DisplayName("fifth day five gold rings") public void testVerseFive() { String expectedVerseFive = "On the fifth day of Christmas my true love gave to me: five Gold Rings, " + "four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n"; @@ -53,6 +59,7 @@ public void testVerseFive() { @Disabled("Remove to run test") @Test + @DisplayName("sixth day six geese-a-laying") public void testVerseSix() { String expectedVerseSix = "On the sixth day of Christmas my true love gave to me: six Geese-a-Laying, " + "five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, " + @@ -62,6 +69,7 @@ public void testVerseSix() { @Disabled("Remove to run test") @Test + @DisplayName("seventh day seven swans-a-swimming") public void testVerseSeven() { String expectedVerseSeven = "On the seventh day of Christmas my true love gave to me: " + "seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, " + @@ -71,6 +79,7 @@ public void testVerseSeven() { @Disabled("Remove to run test") @Test + @DisplayName("eighth day eight maids-a-milking") public void testVerseEight() { String expectedVerseEight = "On the eighth day of Christmas my true love gave to me: eight Maids-a-Milking," + " seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, " + @@ -80,6 +89,7 @@ public void testVerseEight() { @Disabled("Remove to run test") @Test + @DisplayName("ninth day nine ladies dancing") public void testVerseNine() { String expectedVerseNine = "On the ninth day of Christmas my true love gave to me: nine Ladies Dancing, " + "eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, " + @@ -89,6 +99,7 @@ public void testVerseNine() { @Disabled("Remove to run test") @Test + @DisplayName("tenth day ten lords-a-leaping") public void testVerseTen() { String expectedVerseTen = "On the tenth day of Christmas my true love gave to me: ten Lords-a-Leaping, " + "nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, " + @@ -99,6 +110,7 @@ public void testVerseTen() { @Disabled("Remove to run test") @Test + @DisplayName("eleventh day eleven pipers piping") public void testVerseEleven() { String expectedVerseEleven = "On the eleventh day of Christmas my true love gave to me: " + "eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, " + @@ -109,6 +121,7 @@ public void testVerseEleven() { @Disabled("Remove to run test") @Test + @DisplayName("twelfth day twelve drummers drumming") public void testVerseTwelve() { String expectedVerseTwelve = "On the twelfth day of Christmas my true love gave to me: " + "twelve Drummers Drumming, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, " + @@ -119,6 +132,7 @@ public void testVerseTwelve() { @Disabled("Remove to run test") @Test + @DisplayName("recites first three verses of the song") public void testFirstThreeVerses() { String expectedVersesOneToThree = "On the first day of Christmas my true love gave to me: " + "a Partridge in a Pear Tree.\n\n" + @@ -131,6 +145,7 @@ public void testFirstThreeVerses() { @Disabled("Remove to run test") @Test + @DisplayName("recites three verses from the middle of the song") public void testFourthToSixthVerses() { String expectedVersesFourToSix = "On the fourth day of Christmas my true love gave to me: " + "four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n\n" + @@ -143,6 +158,7 @@ public void testFourthToSixthVerses() { @Disabled("Remove to run test") @Test + @DisplayName("recites the whole song") public void testSingWholeSong() { String expectedSong = "On the first day of Christmas my true love gave to me: a Partridge in a Pear Tree.\n" + "\n" + diff --git a/exercises/practice/two-bucket/.meta/config.json b/exercises/practice/two-bucket/.meta/config.json index 4f45ff4a4..57c7007b7 100644 --- a/exercises/practice/two-bucket/.meta/config.json +++ b/exercises/practice/two-bucket/.meta/config.json @@ -14,7 +14,8 @@ "muzimuzhi", "sjwarner-bp", "SleeplessByte", - "sshine" + "sshine", + "Xinri" ], "files": { "solution": [ diff --git a/exercises/practice/two-bucket/.meta/tests.toml b/exercises/practice/two-bucket/.meta/tests.toml index d6ff02f53..a3fe533ec 100644 --- a/exercises/practice/two-bucket/.meta/tests.toml +++ b/exercises/practice/two-bucket/.meta/tests.toml @@ -27,6 +27,12 @@ description = "Measure one step using bucket one of size 1 and bucket two of siz [eb329c63-5540-4735-b30b-97f7f4df0f84] description = "Measure using bucket one of size 2 and bucket two of size 3 - start with bucket one and end with bucket two" +[58d70152-bf2b-46bb-ad54-be58ebe94c03] +description = "Measure using bucket one much bigger than bucket two" + +[9dbe6499-caa5-4a58-b5ce-c988d71b8981] +description = "Measure using bucket one much smaller than bucket two" + [449be72d-b10a-4f4b-a959-ca741e333b72] description = "Not possible to reach the goal" diff --git a/exercises/practice/two-bucket/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/two-bucket/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/two-bucket/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/two-bucket/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/two-bucket/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/two-bucket/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/two-bucket/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/two-bucket/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/two-bucket/gradlew b/exercises/practice/two-bucket/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/two-bucket/gradlew +++ b/exercises/practice/two-bucket/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/two-bucket/gradlew.bat b/exercises/practice/two-bucket/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/two-bucket/gradlew.bat +++ b/exercises/practice/two-bucket/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/two-bucket/src/main/java/TwoBucket.java b/exercises/practice/two-bucket/src/main/java/TwoBucket.java index 5cd0e4d87..1bc771a94 100644 --- a/exercises/practice/two-bucket/src/main/java/TwoBucket.java +++ b/exercises/practice/two-bucket/src/main/java/TwoBucket.java @@ -1,11 +1,11 @@ class TwoBucket { TwoBucket(int bucketOneCap, int bucketTwoCap, int desiredLiters, String startBucket) { - throw new UnsupportedOperationException("Please implement the TwoBucket(int, int, int, String) constructor."); + throw new UnsupportedOperationException("Delete this statement and write your own implementation."); } Result getResult() { - throw new UnsupportedOperationException("Please implement the TwoBucket(int, int, int, String) constructor."); + throw new UnsupportedOperationException("Delete this statement and write your own implementation."); } } diff --git a/exercises/practice/two-bucket/src/test/java/TwoBucketTest.java b/exercises/practice/two-bucket/src/test/java/TwoBucketTest.java index 3564951ab..80d39f0ac 100644 --- a/exercises/practice/two-bucket/src/test/java/TwoBucketTest.java +++ b/exercises/practice/two-bucket/src/test/java/TwoBucketTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -7,6 +8,7 @@ public class TwoBucketTest { @Test + @DisplayName("Measure using bucket one of size 3 and bucket two of size 5 - start with bucket one") public void testBucketOneSizeThreeBucketTwoSizeFiveStartWithOne() { Result bucketResult = new TwoBucket(3, 5, 1, "one").getResult(); @@ -19,6 +21,7 @@ public void testBucketOneSizeThreeBucketTwoSizeFiveStartWithOne() { @Disabled("Remove to run test") @Test + @DisplayName("Measure using bucket one of size 3 and bucket two of size 5 - start with bucket two") public void testBucketOneSizeThreeBucketTwoSizeFiveStartWithTwo() { Result bucketResult = new TwoBucket(3, 5, 1, "two").getResult(); @@ -31,6 +34,7 @@ public void testBucketOneSizeThreeBucketTwoSizeFiveStartWithTwo() { @Disabled("Remove to run test") @Test + @DisplayName("Measure using bucket one of size 7 and bucket two of size 11 - start with bucket one") public void testBucketOneSizeSevenBucketTwoSizeElevenStartWithOne() { Result bucketResult = new TwoBucket(7, 11, 2, "one").getResult(); @@ -43,6 +47,7 @@ public void testBucketOneSizeSevenBucketTwoSizeElevenStartWithOne() { @Disabled("Remove to run test") @Test + @DisplayName("Measure using bucket one of size 7 and bucket two of size 11 - start with bucket two") public void testBucketOneSizeSevenBucketTwoSizeElevenStartWithTwo() { Result bucketResult = new TwoBucket(7, 11, 2, "two").getResult(); @@ -55,6 +60,7 @@ public void testBucketOneSizeSevenBucketTwoSizeElevenStartWithTwo() { @Disabled("Remove to run test") @Test + @DisplayName("Measure one step using bucket one of size 1 and bucket two of size 3 - start with bucket two") public void testBucketOneSizeOneBucketTwoSizeThreeStartWithTwo() { Result bucketResult = new TwoBucket(1, 3, 3, "two").getResult(); @@ -67,6 +73,10 @@ public void testBucketOneSizeOneBucketTwoSizeThreeStartWithTwo() { @Disabled("Remove to run test") @Test + @DisplayName( + "Measure using bucket one of size 2 and bucket two of size 3 - " + + "start with bucket one and end with bucket two" + ) public void testBucketOneSizeTwoBucketTwoSizeThreeStartWithOne() { Result bucketResult = new TwoBucket(2, 3, 3, "one").getResult(); @@ -79,8 +89,35 @@ public void testBucketOneSizeTwoBucketTwoSizeThreeStartWithOne() { @Disabled("Remove to run test") @Test + @DisplayName("Measure using bucket one much bigger than bucket two") + public void testBucketOneMuchBiggerThanBucketTwo() { + + Result bucketResult = new TwoBucket(5, 1, 2, "one").getResult(); + + assertThat(bucketResult.getTotalMoves()).isEqualTo(6); + assertThat(bucketResult.getFinalBucket()).isEqualTo("one"); + assertThat(bucketResult.getOtherBucket()).isEqualTo(1); + + } + + @Disabled("Remove to run test") + @Test + @DisplayName("Measure using bucket one much smaller than bucket two") + public void testBucketOneMuchSmallerThanBucketTwo() { + + Result bucketResult = new TwoBucket(3, 15, 9, "one").getResult(); + + assertThat(bucketResult.getTotalMoves()).isEqualTo(6); + assertThat(bucketResult.getFinalBucket()).isEqualTo("two"); + assertThat(bucketResult.getOtherBucket()).isEqualTo(0); + + } + + @Disabled("Remove to run test") + @Test + @DisplayName("Not possible to reach the goal") public void testReachingGoalIsImpossible() { - + assertThatExceptionOfType(UnreachableGoalException.class) .isThrownBy(() -> new TwoBucket(6, 15, 5, "one").getResult()); @@ -88,6 +125,7 @@ public void testReachingGoalIsImpossible() { @Disabled("Remove to run test") @Test + @DisplayName("With the same buckets but a different goal, then it is possible") public void testBucketOneSizeSixBucketTwoSizeFifteenStartWithOne() { Result bucketResult = new TwoBucket(6, 15, 9, "one").getResult(); @@ -96,10 +134,11 @@ public void testBucketOneSizeSixBucketTwoSizeFifteenStartWithOne() { assertThat(bucketResult.getFinalBucket()).isEqualTo("two"); assertThat(bucketResult.getOtherBucket()).isEqualTo(0); - } + } @Disabled("Remove to run test") @Test + @DisplayName("Goal larger than both buckets is impossible") public void testGoalLargerThanBothBucketsIsImpossible() { assertThatExceptionOfType(UnreachableGoalException.class) diff --git a/exercises/practice/two-fer/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/two-fer/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/two-fer/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/two-fer/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/two-fer/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/two-fer/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/two-fer/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/two-fer/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/two-fer/gradlew b/exercises/practice/two-fer/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/two-fer/gradlew +++ b/exercises/practice/two-fer/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/two-fer/gradlew.bat b/exercises/practice/two-fer/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/two-fer/gradlew.bat +++ b/exercises/practice/two-fer/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/two-fer/src/test/java/TwoferTest.java b/exercises/practice/two-fer/src/test/java/TwoferTest.java index 67dd68646..3993057d6 100644 --- a/exercises/practice/two-fer/src/test/java/TwoferTest.java +++ b/exercises/practice/two-fer/src/test/java/TwoferTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -14,6 +15,7 @@ public void setup() { } @Test + @DisplayName("no name given") public void noNameGiven() { assertThat(twofer.twofer(null)) .isEqualTo("One for you, one for me."); @@ -21,6 +23,7 @@ public void noNameGiven() { @Disabled("Remove to run test") @Test + @DisplayName("a name given") public void aNameGiven() { assertThat(twofer.twofer("Alice")) .isEqualTo("One for Alice, one for me."); @@ -28,6 +31,7 @@ public void aNameGiven() { @Disabled("Remove to run test") @Test + @DisplayName("another name given") public void anotherNameGiven() { assertThat(twofer.twofer("Bob")) .isEqualTo("One for Bob, one for me."); diff --git a/exercises/practice/variable-length-quantity/.meta/config.json b/exercises/practice/variable-length-quantity/.meta/config.json index 1949d7e7b..331713ee2 100644 --- a/exercises/practice/variable-length-quantity/.meta/config.json +++ b/exercises/practice/variable-length-quantity/.meta/config.json @@ -12,7 +12,8 @@ "muzimuzhi", "SleeplessByte", "sshine", - "vpondala" + "vpondala", + "Xinri" ], "files": { "solution": [ diff --git a/exercises/practice/variable-length-quantity/.meta/tests.toml b/exercises/practice/variable-length-quantity/.meta/tests.toml index 923fa0c1a..53be789a3 100644 --- a/exercises/practice/variable-length-quantity/.meta/tests.toml +++ b/exercises/practice/variable-length-quantity/.meta/tests.toml @@ -1,81 +1,103 @@ -# 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. +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. [35c9db2e-f781-4c52-b73b-8e76427defd0] -description = "zero" +description = "Encode a series of integers, producing a series of bytes. -> zero" [be44d299-a151-4604-a10e-d4b867f41540] -description = "arbitrary single byte" +description = "Encode a series of integers, producing a series of bytes. -> arbitrary single byte" + +[890bc344-cb80-45af-b316-6806a6971e81] +description = "Encode a series of integers, producing a series of bytes. -> asymmetric single byte" [ea399615-d274-4af6-bbef-a1c23c9e1346] -description = "largest single byte" +description = "Encode a series of integers, producing a series of bytes. -> largest single byte" [77b07086-bd3f-4882-8476-8dcafee79b1c] -description = "smallest double byte" +description = "Encode a series of integers, producing a series of bytes. -> smallest double byte" [63955a49-2690-4e22-a556-0040648d6b2d] -description = "arbitrary double byte" +description = "Encode a series of integers, producing a series of bytes. -> arbitrary double byte" + +[4977d113-251b-4d10-a3ad-2f5a7756bb58] +description = "Encode a series of integers, producing a series of bytes. -> asymmetric double byte" [29da7031-0067-43d3-83a7-4f14b29ed97a] -description = "largest double byte" +description = "Encode a series of integers, producing a series of bytes. -> largest double byte" [3345d2e3-79a9-4999-869e-d4856e3a8e01] -description = "smallest triple byte" +description = "Encode a series of integers, producing a series of bytes. -> smallest triple byte" [5df0bc2d-2a57-4300-a653-a75ee4bd0bee] -description = "arbitrary triple byte" +description = "Encode a series of integers, producing a series of bytes. -> arbitrary triple byte" + +[6731045f-1e00-4192-b5ae-98b22e17e9f7] +description = "Encode a series of integers, producing a series of bytes. -> asymmetric triple byte" [f51d8539-312d-4db1-945c-250222c6aa22] -description = "largest triple byte" +description = "Encode a series of integers, producing a series of bytes. -> largest triple byte" [da78228b-544f-47b7-8bfe-d16b35bbe570] -description = "smallest quadruple byte" +description = "Encode a series of integers, producing a series of bytes. -> smallest quadruple byte" [11ed3469-a933-46f1-996f-2231e05d7bb6] -description = "arbitrary quadruple byte" +description = "Encode a series of integers, producing a series of bytes. -> arbitrary quadruple byte" + +[b45ef770-cbba-48c2-bd3c-c6362679516e] +description = "Encode a series of integers, producing a series of bytes. -> asymmetric quadruple byte" [d5f3f3c3-e0f1-4e7f-aad0-18a44f223d1c] -description = "largest quadruple byte" +description = "Encode a series of integers, producing a series of bytes. -> largest quadruple byte" [91a18b33-24e7-4bfb-bbca-eca78ff4fc47] -description = "smallest quintuple byte" +description = "Encode a series of integers, producing a series of bytes. -> smallest quintuple byte" [5f34ff12-2952-4669-95fe-2d11b693d331] -description = "arbitrary quintuple byte" +description = "Encode a series of integers, producing a series of bytes. -> arbitrary quintuple byte" + +[9be46731-7cd5-415c-b960-48061cbc1154] +description = "Encode a series of integers, producing a series of bytes. -> asymmetric quintuple byte" [7489694b-88c3-4078-9864-6fe802411009] -description = "maximum 32-bit integer input" +description = "Encode a series of integers, producing a series of bytes. -> maximum 32-bit integer input" [f9b91821-cada-4a73-9421-3c81d6ff3661] -description = "two single-byte values" +description = "Encode a series of integers, producing a series of bytes. -> two single-byte values" [68694449-25d2-4974-ba75-fa7bb36db212] -description = "two multi-byte values" +description = "Encode a series of integers, producing a series of bytes. -> two multi-byte values" [51a06b5c-de1b-4487-9a50-9db1b8930d85] -description = "many multi-byte values" +description = "Encode a series of integers, producing a series of bytes. -> many multi-byte values" [baa73993-4514-4915-bac0-f7f585e0e59a] -description = "one byte" +description = "Decode a series of bytes, producing a series of integers. -> one byte" [72e94369-29f9-46f2-8c95-6c5b7a595aee] -description = "two bytes" +description = "Decode a series of bytes, producing a series of integers. -> two bytes" [df5a44c4-56f7-464e-a997-1db5f63ce691] -description = "three bytes" +description = "Decode a series of bytes, producing a series of integers. -> three bytes" [1bb58684-f2dc-450a-8406-1f3452aa1947] -description = "four bytes" +description = "Decode a series of bytes, producing a series of integers. -> four bytes" [cecd5233-49f1-4dd1-a41a-9840a40f09cd] -description = "maximum 32-bit integer" +description = "Decode a series of bytes, producing a series of integers. -> maximum 32-bit integer" [e7d74ba3-8b8e-4bcb-858d-d08302e15695] -description = "incomplete sequence causes error" +description = "Decode a series of bytes, producing a series of integers. -> incomplete sequence causes error" [aa378291-9043-4724-bc53-aca1b4a3fcb6] -description = "incomplete sequence causes error, even if value is zero" +description = "Decode a series of bytes, producing a series of integers. -> incomplete sequence causes error, even if value is zero" [a91e6f5a-c64a-48e3-8a75-ce1a81e0ebee] -description = "multiple values" +description = "Decode a series of bytes, producing a series of integers. -> multiple values" diff --git a/exercises/practice/variable-length-quantity/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/variable-length-quantity/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/variable-length-quantity/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/variable-length-quantity/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/variable-length-quantity/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/variable-length-quantity/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/variable-length-quantity/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/variable-length-quantity/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/variable-length-quantity/gradlew b/exercises/practice/variable-length-quantity/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/variable-length-quantity/gradlew +++ b/exercises/practice/variable-length-quantity/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/variable-length-quantity/gradlew.bat b/exercises/practice/variable-length-quantity/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/variable-length-quantity/gradlew.bat +++ b/exercises/practice/variable-length-quantity/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/variable-length-quantity/src/test/java/VariableLengthQuantityTest.java b/exercises/practice/variable-length-quantity/src/test/java/VariableLengthQuantityTest.java index 5b25441e7..5e3059937 100644 --- a/exercises/practice/variable-length-quantity/src/test/java/VariableLengthQuantityTest.java +++ b/exercises/practice/variable-length-quantity/src/test/java/VariableLengthQuantityTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.Arrays; @@ -13,6 +14,7 @@ public class VariableLengthQuantityTest { new VariableLengthQuantity(); @Test + @DisplayName("zero") public void testZero() { List expected = Arrays.asList("0x0"); List numbers = Arrays.asList(0x0L); @@ -22,6 +24,7 @@ public void testZero() { @Disabled("Remove to run test") @Test + @DisplayName("arbitrary single byte") public void testArbitrarySingleByte() { List expected = Arrays.asList("0x40"); List numbers = Arrays.asList(0x40L); @@ -31,6 +34,17 @@ public void testArbitrarySingleByte() { @Disabled("Remove to run test") @Test + @DisplayName("asymmetric single byte") + public void testAsymmetricSingleByte() { + List expected = Arrays.asList("0x53"); + List numbers = Arrays.asList(0x53L); + + assertThat(variableLengthQuantity.encode(numbers)).isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("largest single byte") public void testLargestSingleByte() { List expected = Arrays.asList("0x7f"); List numbers = Arrays.asList(0x7fL); @@ -40,6 +54,7 @@ public void testLargestSingleByte() { @Disabled("Remove to run test") @Test + @DisplayName("smallest double byte") public void testSmallestDoubleByte() { List expected = Arrays.asList("0x81", "0x0"); List numbers = Arrays.asList(0x80L); @@ -49,6 +64,7 @@ public void testSmallestDoubleByte() { @Disabled("Remove to run test") @Test + @DisplayName("arbitrary double byte") public void testArbitraryDoubleByte() { List expected = Arrays.asList("0xc0", "0x0"); List numbers = Arrays.asList(0x2000L); @@ -58,6 +74,17 @@ public void testArbitraryDoubleByte() { @Disabled("Remove to run test") @Test + @DisplayName("asymmetric double byte") + public void testAsymmetricDoubleByte() { + List expected = Arrays.asList("0x81", "0x2d"); + List numbers = Arrays.asList(0xadL); + + assertThat(variableLengthQuantity.encode(numbers)).isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("largest double byte") public void testLargestDoubleByte() { List expected = Arrays.asList("0xff", "0x7f"); List numbers = Arrays.asList(0x3fffL); @@ -67,6 +94,7 @@ public void testLargestDoubleByte() { @Disabled("Remove to run test") @Test + @DisplayName("smallest triple byte") public void testSmallestTripleByte() { List expected = Arrays.asList("0x81", "0x80", "0x0"); List numbers = Arrays.asList(0x4000L); @@ -76,6 +104,7 @@ public void testSmallestTripleByte() { @Disabled("Remove to run test") @Test + @DisplayName("arbitrary triple byte") public void testArbitraryTripleByte() { List expected = Arrays.asList("0xc0", "0x80", "0x0"); List numbers = Arrays.asList(0x100000L); @@ -85,6 +114,17 @@ public void testArbitraryTripleByte() { @Disabled("Remove to run test") @Test + @DisplayName("asymmetric triple byte") + public void testAsymmetricTripleByte() { + List expected = Arrays.asList("0x87", "0xab", "0x1c"); + List numbers = Arrays.asList(0x1d59cL); + + assertThat(variableLengthQuantity.encode(numbers)).isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("largest triple byte") public void testLargestTripleByte() { List expected = Arrays.asList("0xff", "0xff", "0x7f"); List numbers = Arrays.asList(0x1fffffL); @@ -94,6 +134,7 @@ public void testLargestTripleByte() { @Disabled("Remove to run test") @Test + @DisplayName("smallest quadruple byte") public void testSmallestQuadrupleByte() { List expected = Arrays.asList("0x81", "0x80", "0x80", "0x0"); List numbers = Arrays.asList(0x200000L); @@ -103,6 +144,7 @@ public void testSmallestQuadrupleByte() { @Disabled("Remove to run test") @Test + @DisplayName("arbitrary quadruple byte") public void testArbitraryQuadrupleByte() { List expected = Arrays.asList("0xc0", "0x80", "0x80", "0x0"); List numbers = Arrays.asList(0x8000000L); @@ -112,6 +154,17 @@ public void testArbitraryQuadrupleByte() { @Disabled("Remove to run test") @Test + @DisplayName("asymmetric quadruple byte") + public void testAsymmetricQuadrupleByte() { + List expected = Arrays.asList("0x81", "0xd5", "0xee", "0x4"); + List numbers = Arrays.asList(0x357704L); + + assertThat(variableLengthQuantity.encode(numbers)).isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("largest quadruple byte") public void testLargestQuadrupleByte() { List expected = Arrays.asList("0xff", "0xff", "0xff", "0x7f"); List numbers = Arrays.asList(0xfffffffL); @@ -121,6 +174,7 @@ public void testLargestQuadrupleByte() { @Disabled("Remove to run test") @Test + @DisplayName("smallest quintuple byte") public void testSmallestQuintupleByte() { List expected = Arrays.asList("0x81", "0x80", "0x80", "0x80", "0x0"); List numbers = Arrays.asList(0x10000000L); @@ -130,6 +184,7 @@ public void testSmallestQuintupleByte() { @Disabled("Remove to run test") @Test + @DisplayName("arbitrary quintuple byte") public void testArbitraryQuintupleByte() { List expected = Arrays.asList("0x8f", "0xf8", "0x80", "0x80", "0x0"); List numbers = Arrays.asList(0xff000000L); @@ -139,6 +194,17 @@ public void testArbitraryQuintupleByte() { @Disabled("Remove to run test") @Test + @DisplayName("asymmetric quintuple byte") + public void testAsymmetricQuintupleByte() { + List expected = Arrays.asList("0x88", "0xb3", "0x95", "0xc2", "0x5"); + List numbers = Arrays.asList(0x86656105L); + + assertThat(variableLengthQuantity.encode(numbers)).isEqualTo(expected); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("maximum 32-bit integer input") public void testMaximum32BitIntegerInput() { List expected = Arrays.asList("0x8f", "0xff", "0xff", "0xff", "0x7f"); List numbers = Arrays.asList(0xffffffffL); @@ -148,6 +214,7 @@ public void testMaximum32BitIntegerInput() { @Disabled("Remove to run test") @Test + @DisplayName("two single-byte values") public void testTwoSingleByteValues() { List expected = Arrays.asList("0x40", "0x7f"); List numbers = Arrays.asList(0x40L, 0x7fL); @@ -157,6 +224,7 @@ public void testTwoSingleByteValues() { @Disabled("Remove to run test") @Test + @DisplayName("two multi-byte values") public void testTwoMultiByteValues() { List expected = Arrays.asList("0x81", "0x80", "0x0", "0xc8", "0xe8", "0x56"); List numbers = Arrays.asList(0x4000L, 0x123456L); @@ -166,6 +234,7 @@ public void testTwoMultiByteValues() { @Disabled("Remove to run test") @Test + @DisplayName("many multi-byte values") public void testManyMultiByteValues() { List expected = Arrays.asList("0xc0", "0x0", "0xc8", "0xe8", "0x56", "0xff", "0xff", "0xff", @@ -179,6 +248,7 @@ public void testManyMultiByteValues() { @Disabled("Remove to run test") @Test + @DisplayName("one byte") public void testDecodeOneByte() { List expected = Arrays.asList("0x7f"); List bytes = Arrays.asList(0x7fL); @@ -188,6 +258,7 @@ public void testDecodeOneByte() { @Disabled("Remove to run test") @Test + @DisplayName("two bytes") public void testDecodeTwoBytes() { List expected = Arrays.asList("0x2000"); List bytes = Arrays.asList(0xc0L, 0x0L); @@ -197,6 +268,7 @@ public void testDecodeTwoBytes() { @Disabled("Remove to run test") @Test + @DisplayName("three bytes") public void testDecodeThreeBytes() { List expected = Arrays.asList("0x1fffff"); List bytes = Arrays.asList(0xffL, 0xffL, 0x7fL); @@ -206,6 +278,7 @@ public void testDecodeThreeBytes() { @Disabled("Remove to run test") @Test + @DisplayName("four bytes") public void testDecodeFourBytes() { List expected = Arrays.asList("0x200000"); List bytes = Arrays.asList(0x81L, 0x80L, 0x80L, 0x0L); @@ -215,6 +288,7 @@ public void testDecodeFourBytes() { @Disabled("Remove to run test") @Test + @DisplayName("maximum 32-bit integer") public void testDecodeMaximum32BitInteger() { List expected = Arrays.asList("0xffffffff"); List bytes = Arrays.asList(0x8fL, 0xffL, 0xffL, 0xffL, 0x7fL); @@ -224,6 +298,7 @@ public void testDecodeMaximum32BitInteger() { @Disabled("Remove to run test") @Test + @DisplayName("incomplete sequence causes error") public void testCannotDecodeIncompleteSequence() { List bytes = Arrays.asList(0xffL); @@ -234,6 +309,7 @@ public void testCannotDecodeIncompleteSequence() { @Disabled("Remove to run test") @Test + @DisplayName("incomplete sequence causes error, even if value is zero") public void testCannotDecodeIncompleteSequenceEvenIfValueIsZero() { List bytes = Arrays.asList(0x80L); @@ -244,6 +320,7 @@ public void testCannotDecodeIncompleteSequenceEvenIfValueIsZero() { @Disabled("Remove to run test") @Test + @DisplayName("multiple values") public void testDecodeMultipleBytes() { List expected = Arrays.asList("0x2000", "0x123456", "0xfffffff", "0x0", "0x3fff", diff --git a/exercises/practice/word-count/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/word-count/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/word-count/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/word-count/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/word-count/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/word-count/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/word-count/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/word-count/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/word-count/gradlew b/exercises/practice/word-count/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/word-count/gradlew +++ b/exercises/practice/word-count/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/word-count/gradlew.bat b/exercises/practice/word-count/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/word-count/gradlew.bat +++ b/exercises/practice/word-count/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/word-count/src/test/java/WordCountTest.java b/exercises/practice/word-count/src/test/java/WordCountTest.java index bd5f70fdb..0c2cd4e01 100644 --- a/exercises/practice/word-count/src/test/java/WordCountTest.java +++ b/exercises/practice/word-count/src/test/java/WordCountTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.HashMap; @@ -21,6 +22,7 @@ public void setup() { @Test + @DisplayName("count one word") public void countOneWord() { expectedWordCount.put("word", 1); @@ -30,6 +32,7 @@ public void countOneWord() { @Disabled("Remove to run test") @Test + @DisplayName("count one of each word") public void countOneOfEachWord() { expectedWordCount.put("one", 1); expectedWordCount.put("of", 1); @@ -41,6 +44,7 @@ public void countOneOfEachWord() { @Disabled("Remove to run test") @Test + @DisplayName("multiple occurrences of a word") public void multipleOccurrencesOfAWord() { expectedWordCount.put("one", 1); expectedWordCount.put("fish", 4); @@ -54,6 +58,7 @@ public void multipleOccurrencesOfAWord() { @Disabled("Remove to run test") @Test + @DisplayName("handles cramped lists") public void handlesCrampedLists() { expectedWordCount.put("one", 1); expectedWordCount.put("two", 1); @@ -65,6 +70,7 @@ public void handlesCrampedLists() { @Disabled("Remove to run test") @Test + @DisplayName("handles expanded lists") public void handlesExpandedLists() { expectedWordCount.put("one", 1); expectedWordCount.put("two", 1); @@ -76,6 +82,7 @@ public void handlesExpandedLists() { @Disabled("Remove to run test") @Test + @DisplayName("ignore punctuation") public void ignorePunctuation() { expectedWordCount.put("car", 1); expectedWordCount.put("carpet", 1); @@ -90,6 +97,7 @@ public void ignorePunctuation() { @Disabled("Remove to run test") @Test + @DisplayName("include numbers") public void includeNumbers() { expectedWordCount.put("testing", 2); expectedWordCount.put("1", 1); @@ -101,6 +109,7 @@ public void includeNumbers() { @Disabled("Remove to run test") @Test + @DisplayName("normalize case") public void normalizeCase() { expectedWordCount.put("go", 3); expectedWordCount.put("stop", 2); @@ -111,6 +120,7 @@ public void normalizeCase() { @Disabled("Remove to run test") @Test + @DisplayName("with apostrophes") public void withApostrophes() { expectedWordCount.put("first", 1); expectedWordCount.put("don't", 2); @@ -127,36 +137,39 @@ public void withApostrophes() { @Disabled("Remove to run test") @Test - public void substringsFromTheBeginning() { + @DisplayName("with quotations") + public void withQuotations() { expectedWordCount.put("joe", 1); expectedWordCount.put("can't", 1); expectedWordCount.put("tell", 1); expectedWordCount.put("between", 1); - expectedWordCount.put("app", 1); - expectedWordCount.put("apple", 1); + expectedWordCount.put("large", 2); expectedWordCount.put("and", 1); - expectedWordCount.put("a", 1); - actualWordCount = wordCount.phrase("Joe can't tell between app, apple and a."); + actualWordCount = wordCount.phrase("Joe can't tell between 'large' and large."); assertThat(actualWordCount).isEqualTo(expectedWordCount); } @Disabled("Remove to run test") @Test - public void withQuotations() { + @DisplayName("substrings from the beginning") + public void substringsFromTheBeginning() { expectedWordCount.put("joe", 1); expectedWordCount.put("can't", 1); expectedWordCount.put("tell", 1); expectedWordCount.put("between", 1); - expectedWordCount.put("large", 2); + expectedWordCount.put("app", 1); + expectedWordCount.put("apple", 1); expectedWordCount.put("and", 1); + expectedWordCount.put("a", 1); - actualWordCount = wordCount.phrase("Joe can't tell between 'large' and large."); + actualWordCount = wordCount.phrase("Joe can't tell between app, apple and a."); assertThat(actualWordCount).isEqualTo(expectedWordCount); } @Disabled("Remove to run test") @Test + @DisplayName("multiple spaces not detected as a word") public void multipleSpacesNotDetectedAsAWord() { expectedWordCount.put("multiple", 1); expectedWordCount.put("whitespaces", 1); @@ -167,6 +180,7 @@ public void multipleSpacesNotDetectedAsAWord() { @Disabled("Remove to run test") @Test + @DisplayName("alternating word separators not detected as a word") public void alternatingWordSeperatorsNotDetectedAsAWord() { expectedWordCount.put("one", 1); expectedWordCount.put("two", 1); @@ -178,6 +192,7 @@ public void alternatingWordSeperatorsNotDetectedAsAWord() { @Disabled("Remove to run test") @Test + @DisplayName("quotation for word with apostrophe") public void quotationForWordWithApostrophe() { expectedWordCount.put("can", 1); expectedWordCount.put("can't", 2); diff --git a/exercises/practice/word-search/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/word-search/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/word-search/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/word-search/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/word-search/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/word-search/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/word-search/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/word-search/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/word-search/gradlew b/exercises/practice/word-search/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/word-search/gradlew +++ b/exercises/practice/word-search/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/word-search/gradlew.bat b/exercises/practice/word-search/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/word-search/gradlew.bat +++ b/exercises/practice/word-search/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/word-search/src/test/java/WordSearcherTest.java b/exercises/practice/word-search/src/test/java/WordSearcherTest.java index 8460366c5..3a7d9291e 100644 --- a/exercises/practice/word-search/src/test/java/WordSearcherTest.java +++ b/exercises/practice/word-search/src/test/java/WordSearcherTest.java @@ -1,5 +1,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.HashMap; @@ -19,6 +20,7 @@ public void setUp() { } @Test + @DisplayName("Should accept an initial game grid and a target search word") public void testAcceptsInitialGridAndTargetWord() { Map> expectedLocations = new HashMap<>(); expectedLocations.put("clojure", Optional.empty()); @@ -37,6 +39,7 @@ public void testAcceptsInitialGridAndTargetWord() { @Disabled("Remove to run test") @Test + @DisplayName("Should locate one word written left to right") public void testLocatesOneWordWrittenLeftToRight() { Map> expectedLocations = new HashMap<>(); expectedLocations.put("clojure", Optional.of(new WordLocation(new Pair(1, 1), new Pair(7, 1)))); @@ -55,6 +58,7 @@ public void testLocatesOneWordWrittenLeftToRight() { @Disabled("Remove to run test") @Test + @DisplayName("Should locate the same word written left to right in a different position") public void testShouldLocateTheSameWordLeftToRightInDifferentPosition() { Map> expectedLocations = new HashMap<>(); expectedLocations.put("clojure", Optional.of(new WordLocation(new Pair(3, 1), new Pair(9, 1)))); @@ -73,6 +77,7 @@ public void testShouldLocateTheSameWordLeftToRightInDifferentPosition() { @Disabled("Remove to run test") @Test + @DisplayName("Should locate a different left to right word") public void testShouldLocateADifferentLeftToRightWord() { Map> expectedLocations = new HashMap<>(); expectedLocations.put("coffee", Optional.of(new WordLocation(new Pair(1, 1), new Pair(6, 1)))); @@ -91,6 +96,7 @@ public void testShouldLocateADifferentLeftToRightWord() { @Disabled("Remove to run test") @Test + @DisplayName("Should locate that different left to right word in a different position") public void testShouldLocateThatDifferentLeftToRightWordInADifferentPosition() { Map> expectedLocations = new HashMap<>(); expectedLocations.put("coffee", Optional.of(new WordLocation(new Pair(2, 1), new Pair(7, 1)))); @@ -109,6 +115,7 @@ public void testShouldLocateThatDifferentLeftToRightWordInADifferentPosition() { @Disabled("Remove to run test") @Test + @DisplayName("Should locate a left to right word in two line grid") public void testShouldLocateLeftToRightWordInTwoLineGrid() { Map> expectedLocations = new HashMap<>(); expectedLocations.put("clojure", Optional.of(new WordLocation(new Pair(2, 2), new Pair(8, 2)))); @@ -128,6 +135,7 @@ public void testShouldLocateLeftToRightWordInTwoLineGrid() { @Disabled("Remove to run test") @Test + @DisplayName("Should locate a left to right word in three line grid") public void testShouldLocateLeftToRightWordInThreeLineGrid() { Map> expectedLocations = new HashMap<>(); expectedLocations.put("clojure", Optional.of(new WordLocation(new Pair(1, 3), new Pair(7, 3)))); @@ -148,6 +156,7 @@ public void testShouldLocateLeftToRightWordInThreeLineGrid() { @Disabled("Remove to run test") @Test + @DisplayName("Should locate a left to right word in ten line grid") public void testLocatesWordWrittenLeftToRightInTenLineGrid() { Map> expectedLocations = new HashMap<>(); expectedLocations.put("clojure", Optional.of(new WordLocation(new Pair(1, 10), new Pair(7, 10)))); @@ -175,6 +184,7 @@ public void testLocatesWordWrittenLeftToRightInTenLineGrid() { @Disabled("Remove to run test") @Test + @DisplayName("Should locate that left to right word in a different position in a ten line grid") public void testLocatesSameWordWrittenLeftToRightInDifferentTenLineGrid() { Map> expectedLocations = new HashMap<>(); expectedLocations.put("clojure", Optional.of(new WordLocation(new Pair(1, 9), new Pair(7, 9)))); @@ -202,6 +212,7 @@ public void testLocatesSameWordWrittenLeftToRightInDifferentTenLineGrid() { @Disabled("Remove to run test") @Test + @DisplayName("Should locate a different left to right word in a ten line grid") public void testLocatesDifferentWordWrittenLeftToRightInTenLineGrid() { Map> expectedLocations = new HashMap<>(); expectedLocations.put("fortran", Optional.of(new WordLocation(new Pair(1, 7), new Pair(7, 7)))); @@ -229,6 +240,7 @@ public void testLocatesDifferentWordWrittenLeftToRightInTenLineGrid() { @Disabled("Remove to run test") @Test + @DisplayName("Should locate multiple words") public void testShouldLocateMultipleWords() { Map> expectedLocations = new HashMap<>(); expectedLocations.put("fortran", Optional.of(new WordLocation(new Pair(1, 7), new Pair(7, 7)))); @@ -257,6 +269,7 @@ public void testShouldLocateMultipleWords() { @Disabled("Remove to run test") @Test + @DisplayName("Should locate a single word written right to left") public void testShouldLocateASingleWordRightToLeft() { Map> expectedLocations = new HashMap<>(); expectedLocations.put("elixir", Optional.of(new WordLocation(new Pair(6, 1), new Pair(1, 1)))); @@ -275,6 +288,7 @@ public void testShouldLocateASingleWordRightToLeft() { @Disabled("Remove to run test") @Test + @DisplayName("Should locate multiple words written in different horizontal directions") public void testShouldLocateMultipleWordsWrittenInDifferentHorizontalDirections() { Map> expectedLocations = new HashMap<>(); expectedLocations.put("elixir", Optional.of(new WordLocation(new Pair(6, 5), new Pair(1, 5)))); @@ -303,6 +317,7 @@ public void testShouldLocateMultipleWordsWrittenInDifferentHorizontalDirections( @Disabled("Remove to run test") @Test + @DisplayName("Should locate words written top to bottom") public void testLocatesWordsWrittenTopToBottom() { Map> expectedLocations = new HashMap<>(); expectedLocations.put("clojure", Optional.of(new WordLocation(new Pair(1, 10), new Pair(7, 10)))); @@ -332,6 +347,7 @@ public void testLocatesWordsWrittenTopToBottom() { @Disabled("Remove to run test") @Test + @DisplayName("Should locate words written bottom to top") public void testLocatesWordsWrittenBottomToTop() { Map> expectedLocations = new HashMap<>(); expectedLocations.put("clojure", Optional.of(new WordLocation(new Pair(1, 10), new Pair(7, 10)))); @@ -360,6 +376,7 @@ public void testLocatesWordsWrittenBottomToTop() { @Disabled("Remove to run test") @Test + @DisplayName("Should locate words written top left to bottom right") public void testLocatesWordsWrittenTopLeftToBottomRight() { Map> expectedLocations = new HashMap<>(); expectedLocations.put("clojure", Optional.of(new WordLocation(new Pair(1, 10), new Pair(7, 10)))); @@ -389,6 +406,7 @@ public void testLocatesWordsWrittenTopLeftToBottomRight() { @Disabled("Remove to run test") @Test + @DisplayName("Should locate words written bottom right to top left") public void testLocatesWordsWrittenBottomRightToTopLeft() { Map> expectedLocations = new HashMap<>(); expectedLocations.put("clojure", Optional.of(new WordLocation(new Pair(1, 10), new Pair(7, 10)))); @@ -419,6 +437,7 @@ public void testLocatesWordsWrittenBottomRightToTopLeft() { @Disabled("Remove to run test") @Test + @DisplayName("Should locate words written bottom left to top right") public void testLocatesWordsWrittenBottomLeftToTopRight() { Map> expectedLocations = new HashMap<>(); expectedLocations.put("clojure", Optional.of(new WordLocation(new Pair(1, 10), new Pair(7, 10)))); @@ -450,6 +469,7 @@ public void testLocatesWordsWrittenBottomLeftToTopRight() { @Disabled("Remove to run test") @Test + @DisplayName("Should locate words written top right to bottom left") public void testLocatesWordsWrittenTopRightToBottomLeft() { Map> expectedLocations = new HashMap<>(); expectedLocations.put("clojure", Optional.of(new WordLocation(new Pair(1, 10), new Pair(7, 10)))); @@ -482,6 +502,7 @@ public void testLocatesWordsWrittenTopRightToBottomLeft() { @Disabled("Remove to run test") @Test + @DisplayName("Should fail to locate a word that is not in the puzzle") public void testFailsToLocateAWordsThatIsNotInThePuzzle() { Map> expectedLocations = new HashMap<>(); expectedLocations.put("clojure", Optional.of(new WordLocation(new Pair(1, 10), new Pair(7, 10)))); @@ -515,6 +536,7 @@ public void testFailsToLocateAWordsThatIsNotInThePuzzle() { @Disabled("Remove to run test") @Test + @DisplayName("Should fail to locate words that are not on horizontal, vertical, or diagonal lines") public void testFailToLocateWordsThatAreNotOnHorizontalVerticalOrDiagonalLines() { Map> expectedLocations = new HashMap<>(); expectedLocations.put("aef", Optional.empty()); @@ -535,6 +557,7 @@ public void testFailToLocateWordsThatAreNotOnHorizontalVerticalOrDiagonalLines() @Disabled("Remove to run test") @Test + @DisplayName("Should not concatenate different lines to find a horizontal word") public void testNotConcatenateDifferentLinesToFindAHorizontalWord() { Map> expectedLocations = new HashMap<>(); expectedLocations.put("elixir", Optional.empty()); @@ -552,6 +575,7 @@ public void testNotConcatenateDifferentLinesToFindAHorizontalWord() { @Disabled("Remove to run test") @Test + @DisplayName("Should not wrap around horizontally to find a word") public void testNotWrapAroundHorizontallyToFindAWord() { Map> expectedLocations = new HashMap<>(); expectedLocations.put("lisp", Optional.empty()); @@ -570,6 +594,7 @@ public void testNotWrapAroundHorizontallyToFindAWord() { @Disabled("Remove to run test") @Test + @DisplayName("Should not wrap around vertically to find a word") public void testNotWrapAroundVerticallyToFindAWord() { Map> expectedLocations = new HashMap<>(); expectedLocations.put("rust", Optional.empty()); diff --git a/exercises/practice/wordy/.meta/config.json b/exercises/practice/wordy/.meta/config.json index 2e6e383fd..78f4c3f91 100644 --- a/exercises/practice/wordy/.meta/config.json +++ b/exercises/practice/wordy/.meta/config.json @@ -21,6 +21,7 @@ "vasouv", "vivshaw", "vpondala", + "Xinri", "Zaldrick" ], "files": { diff --git a/exercises/practice/wordy/.meta/tests.toml b/exercises/practice/wordy/.meta/tests.toml index 912d57600..a0a83ed0b 100644 --- a/exercises/practice/wordy/.meta/tests.toml +++ b/exercises/practice/wordy/.meta/tests.toml @@ -1,13 +1,32 @@ -# 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. +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. [88bf4b28-0de3-4883-93c7-db1b14aa806e] description = "just a number" +[18983214-1dfc-4ebd-ac77-c110dde699ce] +description = "just a zero" + +[607c08ee-2241-4288-916d-dae5455c87e6] +description = "just a negative number" + [bb8c655c-cf42-4dfc-90e0-152fcfd8d4e0] description = "addition" +[bb9f2082-171c-46ad-ad4e-c3f72087c1b5] +description = "addition with a left hand zero" + +[6fa05f17-405a-4742-80ae-5d1a8edb0d5d] +description = "addition with a right hand zero" + [79e49e06-c5ae-40aa-a352-7a3a01f70015] description = "more addition" diff --git a/exercises/practice/wordy/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/wordy/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/wordy/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/wordy/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/wordy/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/wordy/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/wordy/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/wordy/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/wordy/gradlew b/exercises/practice/wordy/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/wordy/gradlew +++ b/exercises/practice/wordy/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/wordy/gradlew.bat b/exercises/practice/wordy/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/wordy/gradlew.bat +++ b/exercises/practice/wordy/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/wordy/src/test/java/WordProblemSolverTest.java b/exercises/practice/wordy/src/test/java/WordProblemSolverTest.java index 70f0a1c30..79c4a1d41 100644 --- a/exercises/practice/wordy/src/test/java/WordProblemSolverTest.java +++ b/exercises/practice/wordy/src/test/java/WordProblemSolverTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -9,129 +10,175 @@ public class WordProblemSolverTest { WordProblemSolver solver = new WordProblemSolver(); @Test + @DisplayName("just a number") public void testJustANumber() { assertThat(solver.solve("What is 5?")).isEqualTo(5); } + @Test + @DisplayName("just a zero") + public void testJustAZero() { + assertThat(solver.solve("What is 0?")).isEqualTo(0); + } + + @Test + @DisplayName("just a negative number") + public void testJustANegativeNumber() { + assertThat(solver.solve("What is -123?")).isEqualTo(-123); + } + @Disabled("Remove to run test") @Test + @DisplayName("addition") public void testSingleAddition1() { assertThat(solver.solve("What is 1 plus 1?")).isEqualTo(2); } @Disabled("Remove to run test") @Test + @DisplayName("addition with a left hand zero") + public void testAdditionWithALeftHandZero() { + assertThat(solver.solve("What is 0 plus 2?")).isEqualTo(2); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("addition with a right hand zero") + public void testAdditionWithARightHandZero() { + assertThat(solver.solve("What is 3 plus 0?")).isEqualTo(3); + } + + @Disabled("Remove to run test") + @Test + @DisplayName("more addition") public void testSingleAddition2() { assertThat(solver.solve("What is 53 plus 2?")).isEqualTo(55); } @Disabled("Remove to run test") @Test + @DisplayName("addition with negative numbers") public void testSingleAdditionWithNegativeNumbers() { assertThat(solver.solve("What is -1 plus -10?")).isEqualTo(-11); } @Disabled("Remove to run test") @Test + @DisplayName("large addition") public void testSingleAdditionOfLargeNumbers() { assertThat(solver.solve("What is 123 plus 45678?")).isEqualTo(45801); } @Disabled("Remove to run test") @Test + @DisplayName("subtraction") public void testSingleSubtraction() { assertThat(solver.solve("What is 4 minus -12?")).isEqualTo(16); } @Disabled("Remove to run test") @Test + @DisplayName("multiplication") public void testSingleMultiplication() { assertThat(solver.solve("What is -3 multiplied by 25?")).isEqualTo(-75); } @Disabled("Remove to run test") @Test + @DisplayName("division") public void testSingleDivision() { assertThat(solver.solve("What is 33 divided by -3?")).isEqualTo(-11); } @Disabled("Remove to run test") @Test + @DisplayName("multiple additions") public void testMultipleAdditions() { assertThat(solver.solve("What is 1 plus 1 plus 1?")).isEqualTo(3); } @Disabled("Remove to run test") @Test + @DisplayName("addition and subtraction") public void testAdditionThenSubtraction() { assertThat(solver.solve("What is 1 plus 5 minus -2?")).isEqualTo(8); } @Disabled("Remove to run test") @Test + @DisplayName("multiple subtraction") public void testMultipleSubtractions() { assertThat(solver.solve("What is 20 minus 4 minus 13?")).isEqualTo(3); } @Disabled("Remove to run test") @Test + @DisplayName("subtraction then addition") public void testSubtractionThenAddition() { assertThat(solver.solve("What is 17 minus 6 plus 3?")).isEqualTo(14); } @Disabled("Remove to run test") @Test + @DisplayName("multiple multiplication") public void testMultipleMultiplications() { assertThat(solver.solve("What is 2 multiplied by -2 multiplied by 3?")).isEqualTo(-12); } @Disabled("Remove to run test") @Test + @DisplayName("addition and multiplication") public void testAdditionThenMultiplication() { assertThat(solver.solve("What is -3 plus 7 multiplied by -2?")).isEqualTo(-8); } @Disabled("Remove to run test") @Test + @DisplayName("multiple division") public void testMultipleDivisions() { assertThat(solver.solve("What is -12 divided by 2 divided by -3?")).isEqualTo(2); } @Disabled("Remove to run test") @Test + @DisplayName("unknown operation") public void testUnknownOperation() { assertThatExceptionOfType(IllegalArgumentException.class) - .isThrownBy(() -> solver.solve("What is 52 cubed?")) - .withMessage("I'm sorry, I don't understand the question!"); + .isThrownBy(() -> solver.solve("What is 52 cubed?")) + .withMessage("I'm sorry, I don't understand the question!"); } @Disabled("Remove to run test") @Test + @DisplayName("Non math question") public void testNonMathQuestion() { // See https://en.wikipedia.org/wiki/President_of_the_United_States if you really need to know! assertThatExceptionOfType(IllegalArgumentException.class) - .isThrownBy(() -> solver.solve("Who is the President of the United States?")) - .withMessage("I'm sorry, I don't understand the question!"); + .isThrownBy(() -> solver.solve("Who is the President of the United States?")) + .withMessage("I'm sorry, I don't understand the question!"); } @Disabled("Remove to run test") @Test + @DisplayName("reject problem missing an operand") public void testMissingAnOperand() { assertThatExceptionOfType(IllegalArgumentException.class) - .isThrownBy(() -> solver.solve("What is 1 plus?")) - .withMessage("I'm sorry, I don't understand the question!"); + .isThrownBy(() -> solver.solve("What is 1 plus?")) + .withMessage("I'm sorry, I don't understand the question!"); } @Disabled("Remove to run test") @Test + @DisplayName("reject problem with no operands or operator") public void testNoOperandsOrOperators() { assertThatExceptionOfType(IllegalArgumentException.class) - .isThrownBy(() -> solver.solve("What is?")) - .withMessage("I'm sorry, I don't understand the question!"); + .isThrownBy(() -> solver.solve("What is?")) + .withMessage("I'm sorry, I don't understand the question!"); } @Disabled("Remove to run test") @Test + @DisplayName("reject two operations in a row") public void testTwoOperationsInARow() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> solver.solve("What is 1 plus plus 2?")) @@ -140,6 +187,7 @@ public void testTwoOperationsInARow() { @Disabled("Remove to run test") @Test + @DisplayName("reject two numbers in a row") public void testTwoNumbersAfterOperation() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> solver.solve("What is 1 plus 2 1?")) @@ -148,6 +196,7 @@ public void testTwoNumbersAfterOperation() { @Disabled("Remove to run test") @Test + @DisplayName("reject postfix notation") public void testPostfixNotation() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> solver.solve("What is 1 2 plus?")) @@ -156,6 +205,7 @@ public void testPostfixNotation() { @Disabled("Remove to run test") @Test + @DisplayName("reject prefix notation") public void testPrefixNotation() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> solver.solve("What is plus 1 2?")) diff --git a/exercises/practice/yacht/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/yacht/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/yacht/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/yacht/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/yacht/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/yacht/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/yacht/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/yacht/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/yacht/gradlew b/exercises/practice/yacht/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/yacht/gradlew +++ b/exercises/practice/yacht/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/yacht/gradlew.bat b/exercises/practice/yacht/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/yacht/gradlew.bat +++ b/exercises/practice/yacht/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/yacht/src/test/java/YachtTest.java b/exercises/practice/yacht/src/test/java/YachtTest.java index b2792817b..2a5e873e6 100644 --- a/exercises/practice/yacht/src/test/java/YachtTest.java +++ b/exercises/practice/yacht/src/test/java/YachtTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -6,6 +7,7 @@ public class YachtTest { @Test + @DisplayName("Yacht") public void yacht() { Yacht yacht = new Yacht(new int[]{ 5, 5, 5, 5, 5 }, YachtCategory.YACHT); assertThat(yacht.score()).isEqualTo(50); @@ -13,6 +15,7 @@ public void yacht() { @Disabled("Remove to run test") @Test + @DisplayName("Not Yacht") public void notYacht() { Yacht yacht = new Yacht(new int[]{ 1, 3, 3, 2, 5 }, YachtCategory.YACHT); assertThat(yacht.score()).isEqualTo(0); @@ -20,6 +23,7 @@ public void notYacht() { @Disabled("Remove to run test") @Test + @DisplayName("Ones") public void ones() { Yacht yacht = new Yacht(new int[]{ 1, 1, 1, 3, 5 }, YachtCategory.ONES); assertThat(yacht.score()).isEqualTo(3); @@ -27,6 +31,7 @@ public void ones() { @Disabled("Remove to run test") @Test + @DisplayName("Ones, out of order") public void onesOutOfOrder() { Yacht yacht = new Yacht(new int[]{ 3, 1, 1, 5, 1 }, YachtCategory.ONES); assertThat(yacht.score()).isEqualTo(3); @@ -34,6 +39,7 @@ public void onesOutOfOrder() { @Disabled("Remove to run test") @Test + @DisplayName("No ones") public void noOnes() { Yacht yacht = new Yacht(new int[]{ 4, 3, 6, 5, 5 }, YachtCategory.ONES); assertThat(yacht.score()).isEqualTo(0); @@ -41,6 +47,7 @@ public void noOnes() { @Disabled("Remove to run test") @Test + @DisplayName("Twos") public void twos() { Yacht yacht = new Yacht(new int[]{ 2, 3, 4, 5, 6 }, YachtCategory.TWOS); assertThat(yacht.score()).isEqualTo(2); @@ -48,6 +55,7 @@ public void twos() { @Disabled("Remove to run test") @Test + @DisplayName("Fours") public void fours() { Yacht yacht = new Yacht(new int[]{ 1, 4, 1, 4, 1 }, YachtCategory.FOURS); assertThat(yacht.score()).isEqualTo(8); @@ -55,6 +63,7 @@ public void fours() { @Disabled("Remove to run test") @Test + @DisplayName("Yacht counted as threes") public void yachtCountedAsThrees() { Yacht yacht = new Yacht(new int[]{ 3, 3, 3, 3, 3 }, YachtCategory.THREES); assertThat(yacht.score()).isEqualTo(15); @@ -62,6 +71,7 @@ public void yachtCountedAsThrees() { @Disabled("Remove to run test") @Test + @DisplayName("Yacht of 3s counted as fives") public void yachtOfThreesCountedAsFives() { Yacht yacht = new Yacht(new int[]{ 3, 3, 3, 3, 3 }, YachtCategory.FIVES); assertThat(yacht.score()).isEqualTo(0); @@ -69,6 +79,7 @@ public void yachtOfThreesCountedAsFives() { @Disabled("Remove to run test") @Test + @DisplayName("Fives") public void fives() { Yacht yacht = new Yacht(new int[]{ 1, 5, 3, 5, 3 }, YachtCategory.FIVES); assertThat(yacht.score()).isEqualTo(10); @@ -76,6 +87,7 @@ public void fives() { @Disabled("Remove to run test") @Test + @DisplayName("Sixes") public void sixes() { Yacht yacht = new Yacht(new int[]{ 2, 3, 4, 5, 6 }, YachtCategory.SIXES); assertThat(yacht.score()).isEqualTo(6); @@ -83,6 +95,7 @@ public void sixes() { @Disabled("Remove to run test") @Test + @DisplayName("Full house two small, three big") public void fullHouseTwoSmallThreeBig() { Yacht yacht = new Yacht(new int[]{ 2, 2, 4, 4, 4 }, YachtCategory.FULL_HOUSE); assertThat(yacht.score()).isEqualTo(16); @@ -90,6 +103,7 @@ public void fullHouseTwoSmallThreeBig() { @Disabled("Remove to run test") @Test + @DisplayName("Full house three small, two big") public void fullHouseThreeSmallTwoBig() { Yacht yacht = new Yacht(new int[]{ 5, 3, 3, 5, 3 }, YachtCategory.FULL_HOUSE); assertThat(yacht.score()).isEqualTo(19); @@ -97,6 +111,7 @@ public void fullHouseThreeSmallTwoBig() { @Disabled("Remove to run test") @Test + @DisplayName("Two pair is not a full house") public void twoPairIsNotAFullHouse() { Yacht yacht = new Yacht(new int[]{ 2, 2, 4, 4, 5 }, YachtCategory.FULL_HOUSE); assertThat(yacht.score()).isEqualTo(0); @@ -104,6 +119,7 @@ public void twoPairIsNotAFullHouse() { @Disabled("Remove to run test") @Test + @DisplayName("Four of a kind is not a full house") public void fourOfAKindIsNotAFullHouse() { Yacht yacht = new Yacht(new int[]{ 1, 4, 4, 4, 4 }, YachtCategory.FULL_HOUSE); assertThat(yacht.score()).isEqualTo(0); @@ -111,6 +127,7 @@ public void fourOfAKindIsNotAFullHouse() { @Disabled("Remove to run test") @Test + @DisplayName("Yacht is not a full house") public void yachtIsNotAFullHouse() { Yacht yacht = new Yacht(new int[]{ 2, 2, 2, 2, 2 }, YachtCategory.FULL_HOUSE); assertThat(yacht.score()).isEqualTo(0); @@ -118,6 +135,7 @@ public void yachtIsNotAFullHouse() { @Disabled("Remove to run test") @Test + @DisplayName("Four of a Kind") public void fourOfAKind() { Yacht yacht = new Yacht(new int[]{ 6, 6, 4, 6, 6 }, YachtCategory.FOUR_OF_A_KIND); assertThat(yacht.score()).isEqualTo(24); @@ -125,6 +143,7 @@ public void fourOfAKind() { @Disabled("Remove to run test") @Test + @DisplayName("Yacht can be scored as Four of a Kind") public void yachtCanBeScoredAsFourOfAKind() { Yacht yacht = new Yacht(new int[]{ 3, 3, 3, 3, 3 }, YachtCategory.FOUR_OF_A_KIND); assertThat(yacht.score()).isEqualTo(12); @@ -132,6 +151,7 @@ public void yachtCanBeScoredAsFourOfAKind() { @Disabled("Remove to run test") @Test + @DisplayName("Full house is not Four of a Kind") public void fullHouseIsNotFourOfAKind() { Yacht yacht = new Yacht(new int[]{ 3, 3, 3, 5, 5 }, YachtCategory.FOUR_OF_A_KIND); assertThat(yacht.score()).isEqualTo(0); @@ -139,6 +159,7 @@ public void fullHouseIsNotFourOfAKind() { @Disabled("Remove to run test") @Test + @DisplayName("Little Straight") public void littleStraight() { Yacht yacht = new Yacht(new int[]{ 3, 5, 4, 1, 2 }, YachtCategory.LITTLE_STRAIGHT); assertThat(yacht.score()).isEqualTo(30); @@ -146,6 +167,7 @@ public void littleStraight() { @Disabled("Remove to run test") @Test + @DisplayName("Little Straight as Big Straight") public void littleStraightAsBigStraight() { Yacht yacht = new Yacht(new int[]{ 1, 2, 3, 4, 5 }, YachtCategory.BIG_STRAIGHT); assertThat(yacht.score()).isEqualTo(0); @@ -153,6 +175,7 @@ public void littleStraightAsBigStraight() { @Disabled("Remove to run test") @Test + @DisplayName("Four in order but not a little straight") public void fourInOrderButNotALittleStraight() { Yacht yacht = new Yacht(new int[]{ 1, 1, 2, 3, 4 }, YachtCategory.LITTLE_STRAIGHT); assertThat(yacht.score()).isEqualTo(0); @@ -160,6 +183,7 @@ public void fourInOrderButNotALittleStraight() { @Disabled("Remove to run test") @Test + @DisplayName("No pairs but not a little straight") public void noPairsButNotALittleStraight() { Yacht yacht = new Yacht(new int[]{ 1, 2, 3, 4, 6 }, YachtCategory.LITTLE_STRAIGHT); assertThat(yacht.score()).isEqualTo(0); @@ -167,6 +191,7 @@ public void noPairsButNotALittleStraight() { @Disabled("Remove to run test") @Test + @DisplayName("Minimum is 1, maximum is 5, but not a little straight") public void minimumIs1MaximumIs5ButNotALittleStraight() { Yacht yacht = new Yacht(new int[]{ 1, 1, 3, 4, 5 }, YachtCategory.LITTLE_STRAIGHT); assertThat(yacht.score()).isEqualTo(0); @@ -174,6 +199,7 @@ public void minimumIs1MaximumIs5ButNotALittleStraight() { @Disabled("Remove to run test") @Test + @DisplayName("Big Straight") public void bigStraight() { Yacht yacht = new Yacht(new int[]{ 4, 6, 2, 5, 3 }, YachtCategory.BIG_STRAIGHT); assertThat(yacht.score()).isEqualTo(30); @@ -181,6 +207,7 @@ public void bigStraight() { @Disabled("Remove to run test") @Test + @DisplayName("Big Straight as little straight") public void bigStraightAsLittleStraight() { Yacht yacht = new Yacht(new int[]{ 6, 5, 4, 3, 2 }, YachtCategory.LITTLE_STRAIGHT); assertThat(yacht.score()).isEqualTo(0); @@ -188,6 +215,7 @@ public void bigStraightAsLittleStraight() { @Disabled("Remove to run test") @Test + @DisplayName("No pairs but not a big straight") public void noPairsButNotABigStraight() { Yacht yacht = new Yacht(new int[]{ 6, 5, 4, 3, 1 }, YachtCategory.BIG_STRAIGHT); assertThat(yacht.score()).isEqualTo(0); @@ -195,6 +223,7 @@ public void noPairsButNotABigStraight() { @Disabled("Remove to run test") @Test + @DisplayName("Choice") public void choice() { Yacht yacht = new Yacht(new int[]{ 3, 3, 5, 6, 6 }, YachtCategory.CHOICE); assertThat(yacht.score()).isEqualTo(23); @@ -202,6 +231,7 @@ public void choice() { @Disabled("Remove to run test") @Test + @DisplayName("Yacht as choice") public void yachtAsChoice() { Yacht yacht = new Yacht(new int[]{ 2, 2, 2, 2, 2 }, YachtCategory.CHOICE); assertThat(yacht.score()).isEqualTo(10); diff --git a/exercises/practice/zebra-puzzle/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/zebra-puzzle/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/zebra-puzzle/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/zebra-puzzle/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/zebra-puzzle/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/zebra-puzzle/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/zebra-puzzle/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/zebra-puzzle/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/zebra-puzzle/gradlew b/exercises/practice/zebra-puzzle/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/zebra-puzzle/gradlew +++ b/exercises/practice/zebra-puzzle/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/zebra-puzzle/gradlew.bat b/exercises/practice/zebra-puzzle/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/zebra-puzzle/gradlew.bat +++ b/exercises/practice/zebra-puzzle/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/zebra-puzzle/src/test/java/ZebraPuzzleTest.java b/exercises/practice/zebra-puzzle/src/test/java/ZebraPuzzleTest.java index 911ebae5c..b0bb118fe 100644 --- a/exercises/practice/zebra-puzzle/src/test/java/ZebraPuzzleTest.java +++ b/exercises/practice/zebra-puzzle/src/test/java/ZebraPuzzleTest.java @@ -1,4 +1,5 @@ import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -6,6 +7,7 @@ public class ZebraPuzzleTest { @Test + @DisplayName("resident who drinks water") public void residentWhoDrinksWater() { ZebraPuzzle zebraPuzzle = new ZebraPuzzle(); assertThat(zebraPuzzle.getWaterDrinker()).isEqualTo("Norwegian"); @@ -13,6 +15,7 @@ public void residentWhoDrinksWater() { @Disabled("Remove to run test") @Test + @DisplayName("resident who owns zebra") public void residentWhoOwnsZebra() { ZebraPuzzle zebraPuzzle = new ZebraPuzzle(); assertThat(zebraPuzzle.getZebraOwner()).isEqualTo("Japanese"); diff --git a/exercises/practice/zipper/gradle/wrapper/gradle-wrapper.jar b/exercises/practice/zipper/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/exercises/practice/zipper/gradle/wrapper/gradle-wrapper.jar and b/exercises/practice/zipper/gradle/wrapper/gradle-wrapper.jar differ diff --git a/exercises/practice/zipper/gradle/wrapper/gradle-wrapper.properties b/exercises/practice/zipper/gradle/wrapper/gradle-wrapper.properties index 2deab89d5..4d97ea344 100644 --- a/exercises/practice/zipper/gradle/wrapper/gradle-wrapper.properties +++ b/exercises/practice/zipper/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/exercises/practice/zipper/gradlew b/exercises/practice/zipper/gradlew index 1aa94a426..adff685a0 100755 --- a/exercises/practice/zipper/gradlew +++ b/exercises/practice/zipper/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/exercises/practice/zipper/gradlew.bat b/exercises/practice/zipper/gradlew.bat index 25da30dbd..c4bdd3ab8 100644 --- a/exercises/practice/zipper/gradlew.bat +++ b/exercises/practice/zipper/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/exercises/practice/zipper/src/test/java/ZipperTest.java b/exercises/practice/zipper/src/test/java/ZipperTest.java index 842ca8be2..d8797814f 100644 --- a/exercises/practice/zipper/src/test/java/ZipperTest.java +++ b/exercises/practice/zipper/src/test/java/ZipperTest.java @@ -1,6 +1,7 @@ +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.BeforeEach; import static org.assertj.core.api.Assertions.assertThat; @@ -21,12 +22,14 @@ public void setup() { } @Test + @DisplayName("data is retained") public void testToTree() { assertThat(zipper.toTree()).isEqualTo(binaryTree); } @Disabled("Remove to run test") @Test + @DisplayName("left, right and value") public void testLeftRightAndValue() { zipper = binaryTree.getRoot(); assertThat(zipper.left.right.getValue()).isEqualTo(3); @@ -34,6 +37,7 @@ public void testLeftRightAndValue() { @Disabled("Remove to run test") @Test + @DisplayName("dead end") public void testDeadEnd() { zipper = binaryTree.getRoot(); assertThat(zipper.left.left).isNull(); @@ -41,6 +45,7 @@ public void testDeadEnd() { @Disabled("Remove to run test") @Test + @DisplayName("tree from deep focus") public void testToTreeFromDeepFocus() { zipper = binaryTree.getRoot(); assertThat(zipper.left.right.toTree()).isEqualTo(binaryTree); @@ -48,6 +53,7 @@ public void testToTreeFromDeepFocus() { @Disabled("Remove to run test") @Test + @DisplayName("traversing up from top") public void testTraversingUpFromTop() { zipper = binaryTree.getRoot(); assertThat(zipper.up).isNull(); @@ -55,6 +61,7 @@ public void testTraversingUpFromTop() { @Disabled("Remove to run test") @Test + @DisplayName("left, right, and up") public void testLeftRightAndUp() { zipper = binaryTree.getRoot(); assertThat(zipper.left.up.right.up.left.right.getValue()).isEqualTo(3); @@ -62,6 +69,7 @@ public void testLeftRightAndUp() { @Disabled("Remove to run test") @Test + @DisplayName("test ability to descend multiple levels and return") public void testAbilityToReturnAfterMultipleLevelDescend() { zipper = binaryTree.getRoot(); assertThat(zipper.left.right.up.up.getValue()).isEqualTo(1); @@ -69,6 +77,7 @@ public void testAbilityToReturnAfterMultipleLevelDescend() { @Disabled("Remove to run test") @Test + @DisplayName("set_value") public void testSetValue() { zipper = binaryTree.getRoot(); zipper = zipper.left; @@ -91,6 +100,7 @@ public void testSetValue() { @Disabled("Remove to run test") @Test + @DisplayName("set_value after traversing up") public void testSetValueAfterTraversingUp() { zipper = binaryTree.getRoot(); zipper = zipper.left.right.up; @@ -113,6 +123,7 @@ public void testSetValueAfterTraversingUp() { @Disabled("Remove to run test") @Test + @DisplayName("set_left with leaf") public void testSetLeftWithLeaf() { zipper = binaryTree.getRoot(); zipper = zipper.left; @@ -138,6 +149,7 @@ public void testSetLeftWithLeaf() { @Disabled("Remove to run test") @Test + @DisplayName("set_right with null") public void testSetRightWithNull() { zipper = binaryTree.getRoot(); zipper = zipper.left; @@ -151,6 +163,7 @@ public void testSetRightWithNull() { @Disabled("Remove to run test") @Test + @DisplayName("set_right with subtree") public void testSetRightWithSubtree() { BinaryTree subtree = new BinaryTree(6); subtree.getRoot().setLeft(new Zipper(7)); @@ -181,6 +194,7 @@ public void testSetRightWithSubtree() { @Disabled("Remove to run test") @Test + @DisplayName("set_value on deep focus") public void testSetValueOnDeepFocus() { zipper = binaryTree.getRoot(); zipper = zipper.left.right; @@ -203,6 +217,7 @@ public void testSetValueOnDeepFocus() { @Disabled("Remove to run test") @Test + @DisplayName("different paths to same zipper") public void differentPathToSameZipper() { Zipper zipper1 = binaryTree.getRoot().left.up.right; Zipper zipper2 = binaryTree.getRoot().right; diff --git a/exercises/settings.gradle b/exercises/settings.gradle index 2ff1e9a14..6bf710357 100644 --- a/exercises/settings.gradle +++ b/exercises/settings.gradle @@ -40,6 +40,7 @@ include 'practice:bank-account' // include 'practice:binary' // deprecated include 'practice:binary-search' include 'practice:binary-search-tree' +include 'practice:baffling-birthdays' include 'practice:bob' include 'practice:book-store' include 'practice:bottle-song' @@ -62,6 +63,7 @@ include 'practice:dot-dsl' include 'practice:error-handling' include 'practice:etl' include 'practice:flatten-array' +include 'practice:flower-field' include 'practice:food-chain' include 'practice:forth' include 'practice:game-of-life' @@ -76,6 +78,7 @@ include 'practice:hangman' include 'practice:hello-world' include 'practice:high-scores' include 'practice:house' +include 'practice:intergalactic-transmission' include 'practice:isbn-verifier' include 'practice:isogram' include 'practice:killer-sudoku-helper' @@ -93,7 +96,7 @@ include 'practice:matrix' include 'practice:mazy-mice' include 'practice:meetup' include 'practice:micro-blog' -include 'practice:minesweeper' +// include 'practice:minesweeper' // deprecated include 'practice:nth-prime' include 'practice:nucleotide-count' include 'practice:ocr-numbers' @@ -104,6 +107,7 @@ include 'practice:parallel-letter-frequency' include 'practice:pascals-triangle' include 'practice:perfect-numbers' include 'practice:phone-number' +include 'practice:piecing-it-together' include 'practice:pig-latin' include 'practice:poker' include 'practice:eliuds-eggs' @@ -114,10 +118,12 @@ include 'practice:proverb' include 'practice:pythagorean-triplet' include 'practice:queen-attack' include 'practice:rail-fence-cipher' +include 'practice:rate-limiter' include 'practice:raindrops' include 'practice:rational-numbers' include 'practice:react' include 'practice:rectangles' +include 'practice:relative-distance' include 'practice:resistor-color' include 'practice:resistor-color-duo' include 'practice:resistor-color-trio' @@ -141,11 +147,13 @@ include 'practice:simple-linked-list' include 'practice:sgf-parsing' include 'practice:space-age' include 'practice:spiral-matrix' +include 'practice:split-second-stopwatch' include 'practice:square-root' include 'practice:state-of-tic-tac-toe' // include 'practice:strain' // deprecated include 'practice:sublist' include 'practice:sum-of-multiples' +include 'practice:swift-scheduling' include 'practice:tournament' include 'practice:transpose' include 'practice:tree-building' diff --git a/reference/contributing-to-practice-exercises.md b/reference/contributing-to-practice-exercises.md index 327c68635..e5fbb2c78 100644 --- a/reference/contributing-to-practice-exercises.md +++ b/reference/contributing-to-practice-exercises.md @@ -1,25 +1,34 @@ # Contributing to Practice Exercises -## Adding a new Practice Exercise +There are two types of practice exercises in the Java track. + +- The most common are come from the [problem specifications repository][problem-specifications]. + The repository contains data that is common for all implementations, such as the introduction, instructions and the test cases. -The easiest way to add a new exercise to the Java track is to port an exercise from another track. -That means that you take an exercise that has already been implemented in another language, and you implement it in this track. +- The others _do_ not have data in the problem specification and are specific to the Java track. -To add a completely new exercise you need to open a pull request to the [problem specifications repository][problem-specifications]. -Any completely new exercise needs to be added and accepted there before it can be added to the Java track. +If you are looking to add a completely new exercise that is not from the [problem specifications repository][problem-specifications], please open a discussion in the forums in the [Java][forum-java] category for Java specific exercises or the [Building Exercism][forum-building-exercism] category for adding to the [problem specifications repository][problem-specifications]. -Before porting an exercise to the Java track, please review the [practice exercise guide][docs-building-exercises-practice]. +If the exercise is already in the problem specifications, please check that no one else has claimed the issue or pull request. +An issue can be "claimed" by asking (in a comment on the issue) if you can work on it. -Please make sure no one else has a pull request open to implement your chosen exercise before you start. +## Adding a new Practice Exercise -It might also be a good idea to open a Pull Request to make it clear to others that you are working on this exercise. -This can just be a Pull Request with an empty commit that states which new exercise you're working on. -[Mark the Pull Request as Draft][github-draft-pr] to let the maintainers know that it's not ready for review yet. +Before adding an exercise to the Java track, please review the [practice exercise guide][docs-building-exercises-practice]. + +The easiest way to get started is to use [configlet][docs-configlet] to provide some of the scaffolding. + +```sh +configlet create --practice-exercise +``` + +This will create the necessary entries in `config.json`, create the directory and pulls the exercise's document files from the problem specifications repository. The Java specific details you need to know about adding an exercise are: -- Please add an entry to the `exercises` array in `config.json`. - You can find details about what should be in that entry [here][docs-building-config-json]. +- Please check the entry added by configlet to the `exercises` array in `config.json`. + The entries are sorted by difficulty, then name. + You can find details about what should be in that entry at the [Exercism docs][docs-building-config-json]. You can also look at other entries in `config.json` as examples and try to mimic them. - Please add an entry for your exercise to `settings.gradle`. @@ -30,11 +39,12 @@ The Java specific details you need to know about adding an exercise are: In the `resources/exercise-template` you will find a template to get you started. See [The Problem Submodules](../CONTRIBUTING.md#the-problem-submodules) section for details on how each exercise submodule is structured. -- Use the configlet to [generate documentation and metadata files][docs-building-configlet-sync-new-exercise] for the new exercise. +- Please copy and add the Gradle files and directories from the `resources/exercise-template` directory. + This should allow you to run Gradle from the exercise's directory. - Make sure you've followed the [track policies](../POLICIES.md), especially the ones for exercise added/updated. -Hopefully that should be enough information to help you port an exercise to the Java track. +Hopefully that should be enough information to help you add a practice exercise to the Java track. Feel free to open an issue or post in the [Building Exercism][forum-building-exercism] category of the [Exercism forum][forum] if you have any questions, and we'll try and answer as soon as we can. ## Updating the documentation for an exercise @@ -48,8 +58,8 @@ bin/configlet sync --docs --metadata --update --exercise ## Updating the tests for an exercise -The tests for practice exercises are based on the canonical data in [problem specification][problem-specifications]. -Each practice exercise should contain a `.meta/tests.toml` file containing the test cases that were implemented for that exercise. +For exercises from the [problem specification][problem-specifications], the tests are based on the canonical data. +The practice exercise should contain a `.meta/tests.toml` file containing the test cases that were implemented for that exercise. In case the canonical data for an exercise changes, this file can be updated by running the configlet from the root of this repository: @@ -60,10 +70,12 @@ bin/configlet sync --tests --update --exercise Note that this only updates the `.meta/tests.toml` file. Any tests that were added or updated should be implemented in the exercise's unit tests! +Syncing is _not_ required for Java specific exercises. + [docs-building-config-json]: https://exercism.org/docs/building/tracks/config-json -[docs-building-configlet-sync-new-exercise]: https://exercism.org/docs/building/configlet/sync#h-using-sync-when-adding-a-new-exercise-to-a-track [docs-building-exercises-practice]: https://exercism.org/docs/building/tracks/practice-exercises +[docs-configlet]: https://exercism.org/docs/building/configlet [forum]: https://forum.exercism.org/ [forum-building-exercism]: https://forum.exercism.org/c/exercism/building-exercism/125 -[github-draft-pr]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/changing-the-stage-of-a-pull-request +[forum-java]: https://forum.exercism.org/c/programming/java/91 [problem-specifications]: https://github.com/exercism/problem-specifications/tree/main/exercises diff --git a/resources/exercise-template/gradle/wrapper/gradle-wrapper.jar b/resources/exercise-template/gradle/wrapper/gradle-wrapper.jar index e6441136f..f8e1ee312 100644 Binary files a/resources/exercise-template/gradle/wrapper/gradle-wrapper.jar and b/resources/exercise-template/gradle/wrapper/gradle-wrapper.jar differ diff --git a/resources/exercise-template/gradle/wrapper/gradle-wrapper.properties b/resources/exercise-template/gradle/wrapper/gradle-wrapper.properties index b82aa23a4..23449a2b5 100644 --- a/resources/exercise-template/gradle/wrapper/gradle-wrapper.properties +++ b/resources/exercise-template/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/resources/exercise-template/gradlew b/resources/exercise-template/gradlew index 1aa94a426..adff685a0 100755 --- a/resources/exercise-template/gradlew +++ b/resources/exercise-template/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/resources/exercise-template/gradlew.bat b/resources/exercise-template/gradlew.bat index 93e3f59f1..c4bdd3ab8 100644 --- a/resources/exercise-template/gradlew.bat +++ b/resources/exercise-template/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -43,11 +45,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,22 +59,21 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell