Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add analyzer for Lasagna
Browse files Browse the repository at this point in the history
sanderploegsma committed Jan 21, 2024
1 parent 65325ac commit d33e6b4
Showing 21 changed files with 344 additions and 8 deletions.
8 changes: 4 additions & 4 deletions bin/run-tests.sh
Original file line number Diff line number Diff line change
@@ -14,15 +14,15 @@
exit_code=0

# Iterate over all test directories
for test_dir in tests/*; do
test_dir_name=$(basename "${test_dir}")
for test_dir in $(find tests -name expected_analysis.json | rev | cut -d '/' -f 2- | rev); do
test_dir_path=$(realpath "${test_dir}")
test_slug=$(echo "${test_dir}" | awk -F/ '{ print $2 }')

bin/run.sh "${test_dir_name}" "${test_dir_path}/" "${test_dir_path}/"
bin/run.sh "${test_slug}" "${test_dir_path}/" "${test_dir_path}/"

for file in analysis.json tags.json; do
expected_file="expected_${file}"
echo "${test_dir_name}: comparing ${file} to ${expected_file}"
echo "${test_dir}: comparing ${file} to ${expected_file}"

if ! diff "${test_dir_path}/${file}" "${test_dir_path}/${expected_file}"; then
exit_code=1
10 changes: 6 additions & 4 deletions src/main/java/analyzer/AnalyzerRoot.java
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
import analyzer.comments.FeedbackRequest;
import analyzer.exercises.GlobalAnalyzer;
import analyzer.exercises.hamming.HammingAnalyzer;
import analyzer.exercises.lasagna.LasagnaAnalyzer;
import analyzer.exercises.twofer.TwoferAnalyzer;
import com.github.javaparser.ast.CompilationUnit;

@@ -18,23 +19,24 @@ public static Analysis analyze(String slug, List<CompilationUnit> compilationUni
analyzer.analyze(compilationUnits, analysis);
}

if (!analysis.getComments().isEmpty()) {
if (analysis.getComments().stream().anyMatch(x -> x.getType() != CommentType.CELEBRATORY)) {
analysis.addComment(new FeedbackRequest());
}

return analysis;
}

private static List<Analyzer> createAnalyzers(String slug) {
var analyzers = new ArrayList<Analyzer>();

analyzers.add(new GlobalAnalyzer());

switch (slug) {
case "hamming" -> analyzers.add(new HammingAnalyzer());
case "lasagna" -> analyzers.add(new LasagnaAnalyzer());
case "two-fer" -> analyzers.add(new TwoferAnalyzer());
}

analyzers.add(new GlobalAnalyzer());

return List.copyOf(analyzers);
}
}
32 changes: 32 additions & 0 deletions src/main/java/analyzer/comments/OptimalSolution.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package analyzer.comments;

import analyzer.Comment;
import analyzer.CommentType;

import java.util.Map;

/**
* @see <a href="https://github.com/exercism/website-copy/blob/main/analyzer-comments/java/general/optimal_solution.md">Markdown Template</a>
*/
public class OptimalSolution extends Comment {
private final String exerciseName;

public OptimalSolution(String exerciseName) {
this.exerciseName = exerciseName;
}

@Override
public String getKey() {
return "java.general.optimal_solution";
}

@Override
public Map<String, String> getParameters() {
return Map.of("exerciseName", this.exerciseName);
}

@Override
public CommentType getType() {
return CommentType.CELEBRATORY;
}
}
49 changes: 49 additions & 0 deletions src/main/java/analyzer/exercises/lasagna/LasagnaAnalyzer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package analyzer.exercises.lasagna;

import analyzer.Analysis;
import analyzer.Analyzer;
import analyzer.comments.OptimalSolution;
import com.github.javaparser.ast.CompilationUnit;
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;

public class LasagnaAnalyzer extends VoidVisitorAdapter<Analysis> implements Analyzer {
private static final String EXERCISE_NAME = "Lasagna";
private static final String EXPECTED_MINUTES_IN_OVEN = "expectedMinutesInOven";
private static final String REMAINING_MINUTES_IN_OVEN = "remainingMinutesInOven";
private static final String PREPARATION_TIME_IN_MINUTES = "preparationTimeInMinutes";
private static final String TOTAL_TIME_IN_MINUTES = "totalTimeInMinutes";

@Override
public void analyze(List<CompilationUnit> compilationUnits, Analysis analysis) {
for (CompilationUnit compilationUnit : compilationUnits) {
compilationUnit.accept(this, analysis);
}

if (analysis.getComments().isEmpty()) {
analysis.addComment(new OptimalSolution(EXERCISE_NAME));
}
}

@Override
public void visit(MethodDeclaration node, Analysis analysis) {
if (node.getNameAsString().equals(REMAINING_MINUTES_IN_OVEN)
&& doesNotCallMethod(node, EXPECTED_MINUTES_IN_OVEN)) {
analysis.addComment(new ReuseCode(REMAINING_MINUTES_IN_OVEN, EXPECTED_MINUTES_IN_OVEN));
}

if (node.getNameAsString().equals(TOTAL_TIME_IN_MINUTES)
&& doesNotCallMethod(node, PREPARATION_TIME_IN_MINUTES)) {
analysis.addComment(new ReuseCode(TOTAL_TIME_IN_MINUTES, PREPARATION_TIME_IN_MINUTES));
}

super.visit(node, analysis);
}

private static boolean doesNotCallMethod(MethodDeclaration node, String otherMethodName) {
return node.findAll(MethodCallExpr.class, x -> x.getNameAsString().contains(otherMethodName)).isEmpty();
}
}
34 changes: 34 additions & 0 deletions src/main/java/analyzer/exercises/lasagna/ReuseCode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package analyzer.exercises.lasagna;

import analyzer.Comment;
import analyzer.CommentType;

import java.util.Map;

class ReuseCode extends Comment {
private final String callingMethod;
private final String methodToCall;

ReuseCode(String callingMethod, String methodToCall) {
this.callingMethod = callingMethod;
this.methodToCall = methodToCall;
}

@Override
public String getKey() {
return "java.lasagna.reuse_code";
}

@Override
public Map<String, String> getParameters() {
return Map.of(
"callingMethod", this.callingMethod,
"methodToCall", this.methodToCall
);
}

@Override
public CommentType getType() {
return CommentType.ACTIONABLE;
}
}
23 changes: 23 additions & 0 deletions tests/lasagna/optimal-solution/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"authors": [
"mirkoperillo"
],
"files": {
"solution": [
"src/main/java/Lasagna.java"
],
"test": [
"src/test/java/LasagnaTest.java"
],
"exemplar": [
".meta/src/reference/java/Lasagna.java"
],
"invalidator": [
"build.gradle"
]
},
"forked_from": [
"csharp/lucians-luscious-lasagna"
],
"blurb": "Learn about the basics of Java by following a lasagna recipe."
}
5 changes: 5 additions & 0 deletions tests/lasagna/optimal-solution/expected_analysis.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{"comments": [{
"comment": "java.general.optimal_solution",
"type": "celebratory",
"params": {"exerciseName": "Lasagna"}
}]}
1 change: 1 addition & 0 deletions tests/lasagna/optimal-solution/expected_tags.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
17 changes: 17 additions & 0 deletions tests/lasagna/optimal-solution/src/main/java/Lasagna.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
public class Lasagna {
public int expectedMinutesInOven() {
return 40;
}

public int remainingMinutesInOven(int actualMinutesInOven) {
return expectedMinutesInOven() - actualMinutesInOven;
}

public int preparationTimeInMinutes(int numberOfLayers) {
return numberOfLayers * 2;
}

public int totalTimeInMinutes(int numberOfLayers, int actualMinutesInOven) {
return preparationTimeInMinutes(numberOfLayers) + actualMinutesInOven;
}
}
23 changes: 23 additions & 0 deletions tests/lasagna/reuse-code/both-methods/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"authors": [
"mirkoperillo"
],
"files": {
"solution": [
"src/main/java/Lasagna.java"
],
"test": [
"src/test/java/LasagnaTest.java"
],
"exemplar": [
".meta/src/reference/java/Lasagna.java"
],
"invalidator": [
"build.gradle"
]
},
"forked_from": [
"csharp/lucians-luscious-lasagna"
],
"blurb": "Learn about the basics of Java by following a lasagna recipe."
}
22 changes: 22 additions & 0 deletions tests/lasagna/reuse-code/both-methods/expected_analysis.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{"comments": [
{
"comment": "java.lasagna.reuse_code",
"type": "actionable",
"params": {
"callingMethod": "remainingMinutesInOven",
"methodToCall": "expectedMinutesInOven"
}
},
{
"comment": "java.lasagna.reuse_code",
"type": "actionable",
"params": {
"callingMethod": "totalTimeInMinutes",
"methodToCall": "preparationTimeInMinutes"
}
},
{
"comment": "java.general.feedback_request",
"type": "informative"
}
]}
1 change: 1 addition & 0 deletions tests/lasagna/reuse-code/both-methods/expected_tags.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
17 changes: 17 additions & 0 deletions tests/lasagna/reuse-code/both-methods/src/main/java/Lasagna.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
public class Lasagna {
public int expectedMinutesInOven() {
return 40;
}

public int remainingMinutesInOven(int actualMinutesInOven) {
return 40 - actualMinutesInOven;
}

public int preparationTimeInMinutes(int numberOfLayers) {
return numberOfLayers * 2;
}

public int totalTimeInMinutes(int numberOfLayers, int actualMinutesInOven) {
return 2 * numberOfLayers + actualMinutesInOven;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"authors": [
"mirkoperillo"
],
"files": {
"solution": [
"src/main/java/Lasagna.java"
],
"test": [
"src/test/java/LasagnaTest.java"
],
"exemplar": [
".meta/src/reference/java/Lasagna.java"
],
"invalidator": [
"build.gradle"
]
},
"forked_from": [
"csharp/lucians-luscious-lasagna"
],
"blurb": "Learn about the basics of Java by following a lasagna recipe."
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{"comments": [
{
"comment": "java.lasagna.reuse_code",
"type": "actionable",
"params": {
"callingMethod": "remainingMinutesInOven",
"methodToCall": "expectedMinutesInOven"
}
},
{
"comment": "java.general.feedback_request",
"type": "informative"
}
]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
public class Lasagna {
public int expectedMinutesInOven() {
return 40;
}

public int remainingMinutesInOven(int actualMinutesInOven) {
return 40 - actualMinutesInOven;
}

public int preparationTimeInMinutes(int numberOfLayers) {
return numberOfLayers * 2;
}

public int totalTimeInMinutes(int numberOfLayers, int actualMinutesInOven) {
return preparationTimeInMinutes(numberOfLayers) + actualMinutesInOven;
}
}
23 changes: 23 additions & 0 deletions tests/lasagna/reuse-code/total-time-in-minutes/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"authors": [
"mirkoperillo"
],
"files": {
"solution": [
"src/main/java/Lasagna.java"
],
"test": [
"src/test/java/LasagnaTest.java"
],
"exemplar": [
".meta/src/reference/java/Lasagna.java"
],
"invalidator": [
"build.gradle"
]
},
"forked_from": [
"csharp/lucians-luscious-lasagna"
],
"blurb": "Learn about the basics of Java by following a lasagna recipe."
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{"comments": [
{
"comment": "java.lasagna.reuse_code",
"type": "actionable",
"params": {
"callingMethod": "totalTimeInMinutes",
"methodToCall": "preparationTimeInMinutes"
}
},
{
"comment": "java.general.feedback_request",
"type": "informative"
}
]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
public class Lasagna {
public int expectedMinutesInOven() {
return 40;
}

public int remainingMinutesInOven(int actualMinutesInOven) {
return expectedMinutesInOven() - actualMinutesInOven;
}

public int preparationTimeInMinutes(int numberOfLayers) {
return numberOfLayers * 2;
}

public int totalTimeInMinutes(int numberOfLayers, int actualMinutesInOven) {
return 2 * numberOfLayers + actualMinutesInOven;
}
}

0 comments on commit d33e6b4

Please sign in to comment.