diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 7b7ae6aa..fabc9b27 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -16,7 +16,7 @@ jobs: - name: Checkout uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - name: Set up JDK - uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 + uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b with: java-version: "21" distribution: "temurin" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4fd70aaa..531efe52 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,14 +15,14 @@ jobs: steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - name: Set up JDK - uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 + uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b with: java-version: "21" distribution: "temurin" - name: Test with Gradle run: ./gradlew --no-daemon --continue test - name: Upload test coverage - uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b + uses: coverallsapp/github-action@cfd0633edbd2411b532b808ba7a8b5e04f76d2c8 smoke_tests: name: Smoke tests @@ -32,12 +32,12 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 + uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 with: install: true - name: Build Docker image and store in cache - uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 + uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 with: context: . push: false diff --git a/bin/run.sh b/bin/run.sh index f691e6bb..f486cbe6 100755 --- a/bin/run.sh +++ b/bin/run.sh @@ -1,3 +1,3 @@ #!/usr/bin/env sh -java -jar /opt/analyzer/java-analyzer.jar "$@" +java -jar /opt/analyzer/java-analyzer.jar "$@" \ No newline at end of file diff --git a/build.gradle b/build.gradle index 6e123262..a02ed456 100644 --- a/build.gradle +++ b/build.gradle @@ -15,13 +15,13 @@ repositories { } dependencies { - implementation "com.google.code.gson:gson:2.12.1" + implementation "com.google.code.gson:gson:2.11.0" implementation "com.github.javaparser:javaparser-core:3.26.3" testImplementation platform("org.junit:junit-bom:5.11.4") testImplementation "org.junit.jupiter:junit-jupiter" testImplementation "org.assertj:assertj-core:3.27.0" - testImplementation "com.approvaltests:approvaltests:24.15.0" + testImplementation "com.approvaltests:approvaltests:24.7.0" } shadowJar { diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index d64cd491..a4b76b95 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b82aa23a..9355b415 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/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-8.10-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 1aa94a42..f5feea6d 100755 --- a/gradlew +++ b/gradlew @@ -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,8 @@ 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 +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/gradlew.bat b/gradlew.bat index 25da30db..9d21a218 100644 --- a/gradlew.bat +++ b/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 ########################################################################## diff --git a/src/main/java/analyzer/AnalyzerRoot.java b/src/main/java/analyzer/AnalyzerRoot.java index 6e249ec3..b7cb7a2f 100644 --- a/src/main/java/analyzer/AnalyzerRoot.java +++ b/src/main/java/analyzer/AnalyzerRoot.java @@ -12,6 +12,7 @@ import analyzer.exercises.secrets.SecretsAnalyzer; import analyzer.exercises.twofer.TwoferAnalyzer; import analyzer.exercises.wizardsandwarriors.WizardsAndWarriorsAnalyzer; +import analyzer.exercises.wizardsandwarriors2.WizardsAndWarriors2Analyzer; import java.util.ArrayList; import java.util.List; @@ -33,7 +34,6 @@ private AnalyzerRoot() { */ public static Output analyze(Solution solution) { var outputBuilder = new OutputBuilder(); - for (Analyzer analyzer : createAnalyzers(solution.getSlug())) { analyzer.analyze(solution, outputBuilder); } @@ -49,7 +49,6 @@ private static List createAnalyzers(String slug) { var analyzers = new ArrayList(); analyzers.add(new GlobalAnalyzer()); - switch (slug) { case "annalyns-infiltration" -> analyzers.add(new AnnalynsInfiltrationAnalyzer()); case "hamming" -> analyzers.add(new HammingAnalyzer()); @@ -61,6 +60,7 @@ private static List createAnalyzers(String slug) { case "secrets" -> analyzers.add(new SecretsAnalyzer()); case "two-fer" -> analyzers.add(new TwoferAnalyzer()); case "wizards-and-warriors" -> analyzers.add(new WizardsAndWarriorsAnalyzer()); + case "wizards-and-warriors-2" -> analyzers.add(new WizardsAndWarriors2Analyzer()); } return List.copyOf(analyzers); diff --git a/src/main/java/analyzer/exercises/wizardsandwarriors2/UseMethodOverloading.java b/src/main/java/analyzer/exercises/wizardsandwarriors2/UseMethodOverloading.java new file mode 100644 index 00000000..7d9aefa1 --- /dev/null +++ b/src/main/java/analyzer/exercises/wizardsandwarriors2/UseMethodOverloading.java @@ -0,0 +1,20 @@ +package analyzer.exercises.wizardsandwarriors2; + +import analyzer.Comment; + +/** + * @author: chiarazarrella + */ +public class UseMethodOverloading extends Comment{ + + @Override + public String getKey() { + return "java.wizards-and-warriors-2.use_method_overloading"; + } + + @Override + public Type getType() { + return Type.ACTIONABLE; + } +} + diff --git a/src/main/java/analyzer/exercises/wizardsandwarriors2/WizardsAndWarriors2Analyzer.java b/src/main/java/analyzer/exercises/wizardsandwarriors2/WizardsAndWarriors2Analyzer.java new file mode 100644 index 00000000..8eaed9e2 --- /dev/null +++ b/src/main/java/analyzer/exercises/wizardsandwarriors2/WizardsAndWarriors2Analyzer.java @@ -0,0 +1,85 @@ +package analyzer.exercises.wizardsandwarriors2; + +import analyzer.Analyzer; +import analyzer.OutputCollector; +import analyzer.Solution; +import analyzer.comments.ExemplarSolution; +import analyzer.comments.PreferStringConcatenation; +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.expr.MethodCallExpr; +import com.github.javaparser.ast.visitor.VoidVisitorAdapter; + +import java.util.List; + +/** + * The {@link WizardsAndWarriors2Analyzer} is the analyzer implementation for the {@code wizards-and-warriors-2} practice exercise. + * + * @see The wizards-and-warriors exercise on the Java track + */ +public class WizardsAndWarriors2Analyzer extends VoidVisitorAdapter implements Analyzer { + + private static final String EXERCISE_NAME = "Wizards and Warriors 2"; + private static final String GAME_MASTER = "GameMaster"; + private static final String DESCRIBE = "describe"; + private static final String FORMAT = "format"; + + @Override + public void analyze(Solution solution, OutputCollector output) { + + for (var compilationUnit : solution.getCompilationUnits()) { + compilationUnit.getClassByName(GAME_MASTER).ifPresent(c -> c.accept(this, output)); + } + + if (output.getComments().isEmpty()) { + output.addComment(new ExemplarSolution(EXERCISE_NAME)); + } + } + + @Override + public void visit(MethodDeclaration node, OutputCollector output) { + + if(!node.getNameAsString().equals(DESCRIBE)) { + return; + } + + if(node.getParameters().size() > 1 && !useOverload(node)) { + + output.addComment(new UseMethodOverloading()); + + } + + if(useStringFormat(node)) { + + output.addComment(new PreferStringConcatenation()); + + } + + + super.visit(node, output); + } + + private static boolean useOverload(MethodDeclaration node) { + + int paramCount = node.getParameters().size(); + + List describeCalls = node.findAll(MethodCallExpr.class).stream() + .filter(m -> m.getNameAsString().equals(DESCRIBE)) + .toList(); + + if (paramCount == 2) { + return describeCalls.size() == 1 || describeCalls.size() == 3; + } + + if (paramCount == 3) { + return describeCalls.size() == 3; + } + + return false; + } + + private static boolean useStringFormat(MethodDeclaration node) { + return node.findAll(MethodCallExpr.class).stream() + .anyMatch(m -> m.getNameAsString().contains(FORMAT)); + } + +} diff --git a/src/test/java/analyzer/AnalyzerIntegrationTest.java b/src/test/java/analyzer/AnalyzerIntegrationTest.java index 26315c72..8b732f84 100644 --- a/src/test/java/analyzer/AnalyzerIntegrationTest.java +++ b/src/test/java/analyzer/AnalyzerIntegrationTest.java @@ -205,4 +205,20 @@ void salarycalculator(String scenario) throws IOException { Approvals.verify(serialize(output.analysis()), Approvals.NAMES.withParameters(scenario)); } + + @ParameterizedTest + @ValueSource(strings = { + "ExemplarSolution", + "NotUseMethodOverloading", + "PartialUseOfMethodOverloading", + "UseStringFormat", + "UseStringFormatAndNotUseMethodOverloading", + }) + void wizardsandwarriors2(String scenario) throws IOException { + var path = Path.of("wizards-and-warriors-2", scenario + ".java"); + var solution = new SolutionFromFiles("wizards-and-warriors-2", SCENARIOS.resolve(path)); + var output = AnalyzerRoot.analyze(solution); + + Approvals.verify(serialize(output.analysis()), Approvals.NAMES.withParameters(scenario)); + } } diff --git a/src/test/resources/analyzer/AnalyzerIntegrationTest.wizardsandwarriors2.ExemplarSolution.approved.txt b/src/test/resources/analyzer/AnalyzerIntegrationTest.wizardsandwarriors2.ExemplarSolution.approved.txt new file mode 100644 index 00000000..a9ee72ff --- /dev/null +++ b/src/test/resources/analyzer/AnalyzerIntegrationTest.wizardsandwarriors2.ExemplarSolution.approved.txt @@ -0,0 +1,11 @@ +{ + "comments": [ + { + "comment": "java.general.exemplar", + "params": { + "exerciseName": "Wizards and Warriors 2" + }, + "type": "celebratory" + } + ] +} \ No newline at end of file diff --git a/src/test/resources/analyzer/AnalyzerIntegrationTest.wizardsandwarriors2.NotUseMethodOverloading.approved.txt b/src/test/resources/analyzer/AnalyzerIntegrationTest.wizardsandwarriors2.NotUseMethodOverloading.approved.txt new file mode 100644 index 00000000..96757c7d --- /dev/null +++ b/src/test/resources/analyzer/AnalyzerIntegrationTest.wizardsandwarriors2.NotUseMethodOverloading.approved.txt @@ -0,0 +1,14 @@ +{ + "comments": [ + { + "comment": "java.wizards-and-warriors-2.use_method_overloading", + "params": {}, + "type": "actionable" + }, + { + "comment": "java.general.feedback_request", + "params": {}, + "type": "informative" + } + ] +} \ No newline at end of file diff --git a/src/test/resources/analyzer/AnalyzerIntegrationTest.wizardsandwarriors2.PartialUseOfMethodOverloading.approved.txt b/src/test/resources/analyzer/AnalyzerIntegrationTest.wizardsandwarriors2.PartialUseOfMethodOverloading.approved.txt new file mode 100644 index 00000000..96757c7d --- /dev/null +++ b/src/test/resources/analyzer/AnalyzerIntegrationTest.wizardsandwarriors2.PartialUseOfMethodOverloading.approved.txt @@ -0,0 +1,14 @@ +{ + "comments": [ + { + "comment": "java.wizards-and-warriors-2.use_method_overloading", + "params": {}, + "type": "actionable" + }, + { + "comment": "java.general.feedback_request", + "params": {}, + "type": "informative" + } + ] +} \ No newline at end of file diff --git a/src/test/resources/analyzer/AnalyzerIntegrationTest.wizardsandwarriors2.UseStringFormat.approved.txt b/src/test/resources/analyzer/AnalyzerIntegrationTest.wizardsandwarriors2.UseStringFormat.approved.txt new file mode 100644 index 00000000..b01ad7f7 --- /dev/null +++ b/src/test/resources/analyzer/AnalyzerIntegrationTest.wizardsandwarriors2.UseStringFormat.approved.txt @@ -0,0 +1,14 @@ +{ + "comments": [ + { + "comment": "java.general.prefer_string_concatenation", + "params": {}, + "type": "informative" + }, + { + "comment": "java.general.feedback_request", + "params": {}, + "type": "informative" + } + ] +} \ No newline at end of file diff --git a/src/test/resources/analyzer/AnalyzerIntegrationTest.wizardsandwarriors2.UseStringFormatAndNotUseMethodOverloading.approved.txt b/src/test/resources/analyzer/AnalyzerIntegrationTest.wizardsandwarriors2.UseStringFormatAndNotUseMethodOverloading.approved.txt new file mode 100644 index 00000000..25d682cc --- /dev/null +++ b/src/test/resources/analyzer/AnalyzerIntegrationTest.wizardsandwarriors2.UseStringFormatAndNotUseMethodOverloading.approved.txt @@ -0,0 +1,19 @@ +{ + "comments": [ + { + "comment": "java.wizards-and-warriors-2.use_method_overloading", + "params": {}, + "type": "actionable" + }, + { + "comment": "java.general.prefer_string_concatenation", + "params": {}, + "type": "informative" + }, + { + "comment": "java.general.feedback_request", + "params": {}, + "type": "informative" + } + ] +} \ No newline at end of file diff --git a/src/test/resources/scenarios/wizards-and-warriors-2/ExemplarSolution.java b/src/test/resources/scenarios/wizards-and-warriors-2/ExemplarSolution.java new file mode 100644 index 00000000..e5b69038 --- /dev/null +++ b/src/test/resources/scenarios/wizards-and-warriors-2/ExemplarSolution.java @@ -0,0 +1,25 @@ +public class GameMaster { + + public String describe(Character character) { + return "You're a level " + character.getLevel() + " " + character.getCharacterClass() + " with " + character.getHitPoints() + " hit points."; + } + + public String describe(Destination destination) { + return "You've arrived at " + destination.getName() + ", which has " + destination.getInhabitants() + " inhabitants."; + } + + public String describe(TravelMethod travelMethod) { + if (travelMethod == TravelMethod.WALKING) { + return "You're traveling to your destination by walking."; + } + return "You're traveling to your destination on horseback."; + } + + public String describe(Character character, Destination destination, TravelMethod travelMethod) { + return describe(character) + " " + describe(travelMethod) + " " + describe(destination); + } + + public String describe(Character character, Destination destination) { + return describe(character, destination, TravelMethod.WALKING); + } + } \ No newline at end of file diff --git a/src/test/resources/scenarios/wizards-and-warriors-2/NotUseMethodOverloading.java b/src/test/resources/scenarios/wizards-and-warriors-2/NotUseMethodOverloading.java new file mode 100644 index 00000000..97c00b5b --- /dev/null +++ b/src/test/resources/scenarios/wizards-and-warriors-2/NotUseMethodOverloading.java @@ -0,0 +1,29 @@ +public class GameMaster { + + public String describe(Character character) { + return "You're a level " + character.getLevel() + " " + character.getCharacterClass() + " with " + character.getHitPoints() + " hit points."; + } + + public String describe(Destination destination) { + return "You've arrived at " + destination.getName() + ", which has " + destination.getInhabitants() + " inhabitants."; + } + + public String describe(TravelMethod travelMethod) { + if (travelMethod == TravelMethod.WALKING) { + return "You're traveling to your destination by walking."; + } + return "You're traveling to your destination on horseback."; + } + + public String describe(Character character, Destination destination, TravelMethod travelMethod) { + return "You're a level " + character.getLevel() + " " + character.getCharacterClass() + " with " + character.getHitPoints() + " hit points. " + + (travelMethod == TravelMethod.WALKING ? "You're traveling to your destination by walking. " : "You're traveling to your destination on horseback. ") + + "You've arrived at " + destination.getName() + ", which has " + destination.getInhabitants() + " inhabitants."; + } + + public String describe(Character character, Destination destination) { + return "You're a level " + character.getLevel() + " " + character.getCharacterClass() + " with " + character.getHitPoints() + " hit points. " + + "You're traveling to your destination by walking. " + + "You've arrived at " + destination.getName() + ", which has " + destination.getInhabitants() + " inhabitants."; + } +} \ No newline at end of file diff --git a/src/test/resources/scenarios/wizards-and-warriors-2/PartialUseOfMethodOverloading.java b/src/test/resources/scenarios/wizards-and-warriors-2/PartialUseOfMethodOverloading.java new file mode 100644 index 00000000..6e9efe84 --- /dev/null +++ b/src/test/resources/scenarios/wizards-and-warriors-2/PartialUseOfMethodOverloading.java @@ -0,0 +1,25 @@ +public class GameMaster { + + public String describe(Character character) { + return "You're a level " + character.getLevel() + " " + character.getCharacterClass() + " with " + character.getHitPoints() + " hit points."; + } + + public String describe(Destination destination) { + return "You've arrived at " + destination.getName() + ", which has " + destination.getInhabitants() + " inhabitants."; + } + + public String describe(TravelMethod travelMethod) { + if (travelMethod == TravelMethod.WALKING) { + return "You're traveling to your destination by walking."; + } + return "You're traveling to your destination on horseback."; + } + + public String describe(Character character, Destination destination, TravelMethod travelMethod) { + return describe(character) + " " + describe(travelMethod) + " " + describe(destination); + } + + public String describe(Character character, Destination destination) { + return describe(character) + " " + describe(destination) + " You're traveling to your destination by walking."; + } +} \ No newline at end of file diff --git a/src/test/resources/scenarios/wizards-and-warriors-2/UseStringFormat.java b/src/test/resources/scenarios/wizards-and-warriors-2/UseStringFormat.java new file mode 100644 index 00000000..e32fd7d4 --- /dev/null +++ b/src/test/resources/scenarios/wizards-and-warriors-2/UseStringFormat.java @@ -0,0 +1,28 @@ +public class GameMaster { + + public String describe(Character character) { + return "You're a level %d %s with %d hit points.".formatted(character.getLevel(), + character.getCharacterClass(), character.getHitPoints()); + } + + public String describe(Destination destination) { + return "You've arrived at %s, which has %d inhabitants.".formatted(destination.getName(), + destination.getInhabitants()); + } + + public String describe(TravelMethod travelMethod) { + if (travelMethod == TravelMethod.WALKING) { + return "You're traveling to your destination by walking."; + } + return "You're traveling to your destination on horseback."; + + } + + public String describe(Character character, Destination destination, TravelMethod travelMethod) { + return "%s %s %s".formatted(describe(character), describe(travelMethod), describe(destination)); + } + + public String describe(Character character, Destination destination) { + return describe(character, destination, TravelMethod.WALKING); + } +} diff --git a/src/test/resources/scenarios/wizards-and-warriors-2/UseStringFormatAndNotUseMethodOverloading.java b/src/test/resources/scenarios/wizards-and-warriors-2/UseStringFormatAndNotUseMethodOverloading.java new file mode 100644 index 00000000..f3fc84e3 --- /dev/null +++ b/src/test/resources/scenarios/wizards-and-warriors-2/UseStringFormatAndNotUseMethodOverloading.java @@ -0,0 +1,35 @@ +public class GameMaster { + + public String describe(Character character) { + return "You're a level %d %s with %d hit points.".formatted(character.getLevel(), + character.getCharacterClass(), character.getHitPoints()); + } + + public String describe(Destination destination) { + return "You've arrived at %s, which has %d inhabitants.".formatted(destination.getName(), + destination.getInhabitants()); + } + + public String describe(TravelMethod travelMethod) { + if (travelMethod == TravelMethod.WALKING) { + return "You're traveling to your destination by walking."; + } + return "You're traveling to your destination on horseback."; + + } + + public String describe(Character character, Destination destination, TravelMethod travelMethod) { + return "You're a level %d %s with %d hit points. ".formatted(character.getLevel(), + character.getCharacterClass(), character.getHitPoints()) + + (travelMethod == TravelMethod.WALKING ? "You're traveling to your destination by walking. " + : "You're traveling to your destination on horseback. ") + + "You've arrived at %s, which has %d inhabitants.".formatted(destination.getName(), + destination.getInhabitants()); + } + + public String describe(Character character, Destination destination) { + return "You're a level %d %s with %d hit points. You're traveling to your destination by walking. You've arrived at %s, which has %d inhabitants." + .formatted(character.getLevel(), character.getCharacterClass(), character.getHitPoints(), + destination.getName(), destination.getInhabitants()); + } +} diff --git a/tests/wizards-and-warriors-2/exemplar-solution/.meta/config.json b/tests/wizards-and-warriors-2/exemplar-solution/.meta/config.json new file mode 100644 index 00000000..decfa680 --- /dev/null +++ b/tests/wizards-and-warriors-2/exemplar-solution/.meta/config.json @@ -0,0 +1,32 @@ +{ + "authors": [ + "sougat818" + ], + "contributors": [ + "jagdish-15", + "sanderploegsma" + ], + "files": { + "solution": [ + "src/main/java/GameMaster.java" + ], + "test": [ + "src/test/java/GameMasterTest.java" + ], + "exemplar": [ + ".meta/src/reference/java/GameMaster.java" + ], + "editor": [ + "src/main/java/Character.java", + "src/main/java/Destination.java", + "src/main/java/TravelMethod.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "forked_from": [ + "csharp/wizards-and-warriors-2" + ], + "blurb": "Learn about method overloading by extending your favorite RPG." +} \ No newline at end of file diff --git a/tests/wizards-and-warriors-2/exemplar-solution/expected_analysis.json b/tests/wizards-and-warriors-2/exemplar-solution/expected_analysis.json new file mode 100644 index 00000000..a9b48769 --- /dev/null +++ b/tests/wizards-and-warriors-2/exemplar-solution/expected_analysis.json @@ -0,0 +1,11 @@ +{ + "comments": [ + { + "comment": "java.general.exemplar", + "params": { + "exerciseName": "Wizards and Warriors 2" + }, + "type": "celebratory" + } + ] +} \ No newline at end of file diff --git a/tests/wizards-and-warriors-2/exemplar-solution/expected_tags.json b/tests/wizards-and-warriors-2/exemplar-solution/expected_tags.json new file mode 100644 index 00000000..eb25b190 --- /dev/null +++ b/tests/wizards-and-warriors-2/exemplar-solution/expected_tags.json @@ -0,0 +1,3 @@ +{ + "tags": [] +} \ No newline at end of file diff --git a/tests/wizards-and-warriors-2/exemplar-solution/src/main/java/GameMaster.java b/tests/wizards-and-warriors-2/exemplar-solution/src/main/java/GameMaster.java new file mode 100644 index 00000000..8a513f51 --- /dev/null +++ b/tests/wizards-and-warriors-2/exemplar-solution/src/main/java/GameMaster.java @@ -0,0 +1,25 @@ +public class GameMaster { + + public String describe(Character character) { + return "You're a level " + character.getLevel() + " " + character.getCharacterClass() + " with " + character.getHitPoints() + " hit points."; + } + + public String describe(Destination destination) { + return "You've arrived at " + destination.getName() + ", which has " + destination.getInhabitants() + " inhabitants."; + } + + public String describe(TravelMethod travelMethod) { + if (travelMethod == TravelMethod.WALKING) { + return "You're traveling to your destination by walking."; + } + return "You're traveling to your destination on horseback."; + } + + public String describe(Character character, Destination destination, TravelMethod travelMethod) { + return describe(character) + " " + describe(travelMethod) + " " + describe(destination); + } + + public String describe(Character character, Destination destination) { + return describe(character, destination, TravelMethod.WALKING); + } +} \ No newline at end of file diff --git a/tests/wizards-and-warriors-2/not-use-method-overloading/.meta/config.json b/tests/wizards-and-warriors-2/not-use-method-overloading/.meta/config.json new file mode 100644 index 00000000..decfa680 --- /dev/null +++ b/tests/wizards-and-warriors-2/not-use-method-overloading/.meta/config.json @@ -0,0 +1,32 @@ +{ + "authors": [ + "sougat818" + ], + "contributors": [ + "jagdish-15", + "sanderploegsma" + ], + "files": { + "solution": [ + "src/main/java/GameMaster.java" + ], + "test": [ + "src/test/java/GameMasterTest.java" + ], + "exemplar": [ + ".meta/src/reference/java/GameMaster.java" + ], + "editor": [ + "src/main/java/Character.java", + "src/main/java/Destination.java", + "src/main/java/TravelMethod.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "forked_from": [ + "csharp/wizards-and-warriors-2" + ], + "blurb": "Learn about method overloading by extending your favorite RPG." +} \ No newline at end of file diff --git a/tests/wizards-and-warriors-2/not-use-method-overloading/expected_analysis.json b/tests/wizards-and-warriors-2/not-use-method-overloading/expected_analysis.json new file mode 100644 index 00000000..a2e52b42 --- /dev/null +++ b/tests/wizards-and-warriors-2/not-use-method-overloading/expected_analysis.json @@ -0,0 +1,14 @@ +{ + "comments": [ + { + "comment": "java.wizards-and-warriors-2.use_method_overloading", + "params": {}, + "type": "actionable" + }, + { + "comment": "java.general.feedback_request", + "params": {}, + "type": "informative" + } + ] +} \ No newline at end of file diff --git a/tests/wizards-and-warriors-2/not-use-method-overloading/expected_tags.json b/tests/wizards-and-warriors-2/not-use-method-overloading/expected_tags.json new file mode 100644 index 00000000..eb25b190 --- /dev/null +++ b/tests/wizards-and-warriors-2/not-use-method-overloading/expected_tags.json @@ -0,0 +1,3 @@ +{ + "tags": [] +} \ No newline at end of file diff --git a/tests/wizards-and-warriors-2/not-use-method-overloading/src/main/java/GameMaster.java b/tests/wizards-and-warriors-2/not-use-method-overloading/src/main/java/GameMaster.java new file mode 100644 index 00000000..97c00b5b --- /dev/null +++ b/tests/wizards-and-warriors-2/not-use-method-overloading/src/main/java/GameMaster.java @@ -0,0 +1,29 @@ +public class GameMaster { + + public String describe(Character character) { + return "You're a level " + character.getLevel() + " " + character.getCharacterClass() + " with " + character.getHitPoints() + " hit points."; + } + + public String describe(Destination destination) { + return "You've arrived at " + destination.getName() + ", which has " + destination.getInhabitants() + " inhabitants."; + } + + public String describe(TravelMethod travelMethod) { + if (travelMethod == TravelMethod.WALKING) { + return "You're traveling to your destination by walking."; + } + return "You're traveling to your destination on horseback."; + } + + public String describe(Character character, Destination destination, TravelMethod travelMethod) { + return "You're a level " + character.getLevel() + " " + character.getCharacterClass() + " with " + character.getHitPoints() + " hit points. " + + (travelMethod == TravelMethod.WALKING ? "You're traveling to your destination by walking. " : "You're traveling to your destination on horseback. ") + + "You've arrived at " + destination.getName() + ", which has " + destination.getInhabitants() + " inhabitants."; + } + + public String describe(Character character, Destination destination) { + return "You're a level " + character.getLevel() + " " + character.getCharacterClass() + " with " + character.getHitPoints() + " hit points. " + + "You're traveling to your destination by walking. " + + "You've arrived at " + destination.getName() + ", which has " + destination.getInhabitants() + " inhabitants."; + } +} \ No newline at end of file diff --git a/tests/wizards-and-warriors-2/use-string-format/.meta/config.json b/tests/wizards-and-warriors-2/use-string-format/.meta/config.json new file mode 100644 index 00000000..decfa680 --- /dev/null +++ b/tests/wizards-and-warriors-2/use-string-format/.meta/config.json @@ -0,0 +1,32 @@ +{ + "authors": [ + "sougat818" + ], + "contributors": [ + "jagdish-15", + "sanderploegsma" + ], + "files": { + "solution": [ + "src/main/java/GameMaster.java" + ], + "test": [ + "src/test/java/GameMasterTest.java" + ], + "exemplar": [ + ".meta/src/reference/java/GameMaster.java" + ], + "editor": [ + "src/main/java/Character.java", + "src/main/java/Destination.java", + "src/main/java/TravelMethod.java" + ], + "invalidator": [ + "build.gradle" + ] + }, + "forked_from": [ + "csharp/wizards-and-warriors-2" + ], + "blurb": "Learn about method overloading by extending your favorite RPG." +} \ No newline at end of file diff --git a/tests/wizards-and-warriors-2/use-string-format/expected_analysis.json b/tests/wizards-and-warriors-2/use-string-format/expected_analysis.json new file mode 100644 index 00000000..2b150682 --- /dev/null +++ b/tests/wizards-and-warriors-2/use-string-format/expected_analysis.json @@ -0,0 +1,14 @@ +{ + "comments": [ + { + "comment": "java.general.prefer_string_concatenation", + "params": {}, + "type": "informative" + }, + { + "comment": "java.general.feedback_request", + "params": {}, + "type": "informative" + } + ] +} \ No newline at end of file diff --git a/tests/wizards-and-warriors-2/use-string-format/expected_tags.json b/tests/wizards-and-warriors-2/use-string-format/expected_tags.json new file mode 100644 index 00000000..eb25b190 --- /dev/null +++ b/tests/wizards-and-warriors-2/use-string-format/expected_tags.json @@ -0,0 +1,3 @@ +{ + "tags": [] +} \ No newline at end of file diff --git a/tests/wizards-and-warriors-2/use-string-format/src/main/java/GameMaster.java b/tests/wizards-and-warriors-2/use-string-format/src/main/java/GameMaster.java new file mode 100644 index 00000000..e32fd7d4 --- /dev/null +++ b/tests/wizards-and-warriors-2/use-string-format/src/main/java/GameMaster.java @@ -0,0 +1,28 @@ +public class GameMaster { + + public String describe(Character character) { + return "You're a level %d %s with %d hit points.".formatted(character.getLevel(), + character.getCharacterClass(), character.getHitPoints()); + } + + public String describe(Destination destination) { + return "You've arrived at %s, which has %d inhabitants.".formatted(destination.getName(), + destination.getInhabitants()); + } + + public String describe(TravelMethod travelMethod) { + if (travelMethod == TravelMethod.WALKING) { + return "You're traveling to your destination by walking."; + } + return "You're traveling to your destination on horseback."; + + } + + public String describe(Character character, Destination destination, TravelMethod travelMethod) { + return "%s %s %s".formatted(describe(character), describe(travelMethod), describe(destination)); + } + + public String describe(Character character, Destination destination) { + return describe(character, destination, TravelMethod.WALKING); + } +}