diff --git a/.github/scripts/assignments_test.py b/.github/scripts/assignments_test.py deleted file mode 100644 index f4822adc..00000000 --- a/.github/scripts/assignments_test.py +++ /dev/null @@ -1,63 +0,0 @@ -import os, re, sys -from shutil import copyfile -from xml.dom import minidom - -def get_directories(basedir): - return [os.path.join(basedir, dir) for dir in os.listdir(basedir) \ - if os.path.isdir(os.path.join(basedir, dir)) \ - and not dir.startswith('.')] - -home_dir = '/home/runner/work/andy/andy/assignments' -andy_jar = '/home/runner/work/andy/andy.jar' - -expected_andy_version = 'v' + minidom.parse('pom.xml').getElementsByTagName('andy.version')[0].firstChild.data - -dir = os.path.join(os.getcwd(), 'work') -os.makedirs(dir, exist_ok = True) - -pipeline_failed = False -for category_dir in get_directories(home_dir): - for assignment_dir in get_directories(category_dir): - os.chdir(assignment_dir) - - # Remove the contents of the output folder. - os.system(f'rm -r {dir}/*') - - # Copy the files to the correct folder. - source = os.listdir(os.path.join(assignment_dir, 'src/main/java/delft'))[0] - copyfile(f'{assignment_dir}/src/main/java/delft/{source}', os.path.join(dir, 'Library.java')) - solution = os.listdir(os.path.join(assignment_dir, 'solution'))[0] - copyfile(f'{assignment_dir}/solution/{solution}', os.path.join(dir, 'Solution.java')) - copyfile(f'{assignment_dir}/config/Configuration.java', os.path.join(dir, 'Configuration.java')) - # Copy resources - os.system('find . -type f | ' + - 'grep -i -v "^\./src/" | grep -i -v "\./config/Configuration.java" | ' + - 'grep -i -v "^\./pom.xml$" | grep -i -v "^\./solution/" | grep -i -v "^\./README.md$" | ' + - 'xargs -i cp --parents {} ' + f'{dir}/') - - # Run Andy and collect the results. - os.chdir(dir) - os.system(f'java -ea -cp {andy_jar} -XX:+TieredCompilation -XX:TieredStopAtLevel=1 nl.tudelft.cse1110.andy.AndyLauncher "FULL_WITH_HINTS"') - - with open(f'{dir}/stdout.txt') as file: - # Get the score from the `stdout.txt` file. - file_content = file.read() - re_score = re.search('Final grade: [0-9]+', file_content) - score = int(re_score.group().split()[2]) if re_score else -1 - re_andy_version = re.search('Andy v.+', file_content) - andy_version = re_andy_version.group() if re_andy_version else "Unknown Andy version" - - # Print the score for the assignment. - print(f'{andy_version} | {assignment_dir.split("/")[-2]}/{assignment_dir.split("/")[-1]}: {score}/100') - - # Update the `pipeline_failed` variable. - if score != 100: - print(file_content) - pipeline_failed = True - - if expected_andy_version not in andy_version: - print(f'Error: Unexpected Andy version {andy_version}, expected {expected_andy_version}') - pipeline_failed = True - -if pipeline_failed: - sys.exit('Some assignments do not have 100/100.') diff --git a/.github/scripts/assignments_test_docker.py b/.github/scripts/assignments_test_docker.py index 8a7c3bde..336080d3 100644 --- a/.github/scripts/assignments_test_docker.py +++ b/.github/scripts/assignments_test_docker.py @@ -5,8 +5,9 @@ def get_directories(basedir): if os.path.isdir(os.path.join(basedir, dir)) \ and not dir.startswith('.')] -home_dir = '/home/runner/work/andy/andy/assignments' -docker_dir = '/home/runner/work/andy/andy/weblab-docker' +repo_name = os.environ['REPO_NAME'] +home_dir = f'/home/runner/work/{repo_name}/{repo_name}/assignments' +docker_dir = f'/home/runner/work/{repo_name}/{repo_name}/weblab-docker' test_dir = docker_dir + '/tests/github-ci' output_dir = docker_dir + '/testresults' diff --git a/.github/workflows/assignments_test_docker.yml b/.github/workflows/assignments_test_docker.yml index b132073d..0bab7db6 100644 --- a/.github/workflows/assignments_test_docker.yml +++ b/.github/workflows/assignments_test_docker.yml @@ -1,5 +1,10 @@ name: assignments_test_docker -on: [push, workflow_dispatch] +on: [push, pull_request, workflow_dispatch] +env: + # PR: github.sha is the SHA of the PR, not commit, we can't check this out + GHA_SHA: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + # PR: github.repository is the repository the PR is made in, not the fork + GHA_REPO: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} jobs: run_assignments_docker: runs-on: ubuntu-latest @@ -21,12 +26,14 @@ jobs: - name: Build Docker image working-directory: ./weblab-docker env: - BUILD_ARGS: "--build-arg ANDY_BRANCH=${{ github.sha }}" + BUILD_ARGS: "--build-arg ANDY_BRANCH=${{ env.GHA_SHA }} --build-arg ANDY_REPO=${{ env.GHA_REPO }}" run: | make - name: Run the reference solutions of all assignments and verify the scores are 100/100 env: - COMMIT_HASH: ${{ github.sha }} + # github.repository contains owner, we don't want that + REPO_NAME: ${{ github.event.repository.name }} + COMMIT_HASH: ${{ env.GHA_SHA }} run: | python ./.github/scripts/assignments_test_docker.py diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 68f1488c..73a72cb9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -88,7 +88,9 @@ jobs: path: ~/.m2 key: ${{ matrix.job.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ matrix.job.os }}-m2 - + + - name: Run Checkstyle + run: mvn checkstyle:check + - name: Run Weblab runner tests run: mvn test -pl weblab-runner -DexcludedGroups=selenium - diff --git a/.mvn/jvm.config b/.mvn/jvm.config new file mode 100644 index 00000000..32599cef --- /dev/null +++ b/.mvn/jvm.config @@ -0,0 +1,10 @@ +--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED +--add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED +--add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED diff --git a/README.md b/README.md index bb8029be..47e2aaae 100644 --- a/README.md +++ b/README.md @@ -300,6 +300,8 @@ Andy provides different checks for JUnit, Mockito, and JQWik tests: - `LoopInTestMethods`: checks whether there is a loop in a test method. - `UseOfStringLiterals`: checks whether there is a string literal in a test method. - `MethodCalledInTestMethod`: checks whether a method was invoked in a test method. + - `ClassUsedInSolution`: checks whether a class was used anywhere in the test suite. + - `MethodCalledAnywhere`: checks whether a method was invoked in any scope. - Mockito: - `MockClass`: Checks whether a class was mocked in the test suite. diff --git a/andy-aws-lambda/src/main/java/nl/tudelft/cse1110/andy/aws/AndyOnAWSLambda.java b/andy-aws-lambda/src/main/java/nl/tudelft/cse1110/andy/aws/AndyOnAWSLambda.java index 96109961..2d1a8341 100644 --- a/andy-aws-lambda/src/main/java/nl/tudelft/cse1110/andy/aws/AndyOnAWSLambda.java +++ b/andy-aws-lambda/src/main/java/nl/tudelft/cse1110/andy/aws/AndyOnAWSLambda.java @@ -6,6 +6,9 @@ import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; import com.google.gson.Gson; import nl.tudelft.cse1110.andy.Andy; +import nl.tudelft.cse1110.andy.config.DirectoryConfiguration; +import nl.tudelft.cse1110.andy.execution.Context.ContextBuilder; +import nl.tudelft.cse1110.andy.execution.Context.ContextDirector; import nl.tudelft.cse1110.andy.execution.mode.Action; import nl.tudelft.cse1110.andy.result.Result; import nl.tudelft.cse1110.andy.utils.FilesUtils; @@ -16,7 +19,6 @@ import java.nio.file.Path; import java.util.Arrays; -import static nl.tudelft.cse1110.andy.execution.Context.build; import static nl.tudelft.cse1110.andy.utils.FilesUtils.*; public class AndyOnAWSLambda implements RequestHandler { @@ -30,11 +32,12 @@ public AWSResult run(AWSInput input) { writeToFile(workDir, "Configuration.java", input.getConfiguration()); writeToFile(workDir, "Solution.java", input.getSolution()); - nl.tudelft.cse1110.andy.execution.Context ctx = build( + ContextDirector director = new ContextDirector(new ContextBuilder()); + nl.tudelft.cse1110.andy.execution.Context.Context ctx = director.constructWithLibraries( Action.valueOf(input.getAction()), - workDir.toString(), - outputDir.toString(), - Arrays.asList(myself())); + new DirectoryConfiguration(workDir.toString(), outputDir.toString()), + Arrays.asList(myself()) + ); Result result = new Andy().run(ctx); diff --git a/andy-checkstyle-checker.xml b/andy-checkstyle-checker.xml new file mode 100644 index 00000000..a8ac184f --- /dev/null +++ b/andy-checkstyle-checker.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/andy-maven-plugin/src/main/java/io/github/cse1110/andy/AndyMojo.java b/andy-maven-plugin/src/main/java/io/github/cse1110/andy/AndyMojo.java index 2aacf04e..f51067c1 100644 --- a/andy-maven-plugin/src/main/java/io/github/cse1110/andy/AndyMojo.java +++ b/andy-maven-plugin/src/main/java/io/github/cse1110/andy/AndyMojo.java @@ -2,7 +2,10 @@ import com.google.common.io.Files; import nl.tudelft.cse1110.andy.Andy; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.config.DirectoryConfiguration; +import nl.tudelft.cse1110.andy.execution.Context.Context; +import nl.tudelft.cse1110.andy.execution.Context.ContextBuilder; +import nl.tudelft.cse1110.andy.execution.Context.ContextDirector; import nl.tudelft.cse1110.andy.execution.mode.Action; import nl.tudelft.cse1110.andy.result.Result; import nl.tudelft.cse1110.andy.writer.standard.StandardResultWriter; @@ -72,11 +75,12 @@ public void execute() { Timer workingIndicator = this.startWorkingIndicationTimer(); /* Run Andy! */ - Context ctx = Context.build( + ContextDirector director = new ContextDirector(new ContextBuilder()); + Context ctx = director.constructWithLibraries( action(), - workDir.getAbsolutePath(), - outputDir.getAbsolutePath(), - compileClasspathElements); + new DirectoryConfiguration(workDir.getAbsolutePath(), outputDir.getAbsolutePath()), + compileClasspathElements + ); Result result = new Andy().run(ctx); diff --git a/andy/pom.xml b/andy/pom.xml index 3c848774..747ce821 100644 --- a/andy/pom.xml +++ b/andy/pom.xml @@ -46,14 +46,6 @@ - - - com.github.mauricioaniche - codesheriff - 0.3 - test - - org.slf4j slf4j-reload4j diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/Andy.java b/andy/src/main/java/nl/tudelft/cse1110/andy/Andy.java index 7ac4ec8d..515841bc 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/Andy.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/Andy.java @@ -1,6 +1,6 @@ package nl.tudelft.cse1110.andy; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.execution.ExecutionFlow; import nl.tudelft.cse1110.andy.result.Result; diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/AndyLauncher.java b/andy/src/main/java/nl/tudelft/cse1110/andy/AndyLauncher.java index 30677cbe..daf075c5 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/AndyLauncher.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/AndyLauncher.java @@ -1,6 +1,9 @@ package nl.tudelft.cse1110.andy; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.config.DirectoryConfiguration; +import nl.tudelft.cse1110.andy.execution.Context.Context; +import nl.tudelft.cse1110.andy.execution.Context.ContextBuilder; +import nl.tudelft.cse1110.andy.execution.Context.ContextDirector; import nl.tudelft.cse1110.andy.execution.mode.Action; import nl.tudelft.cse1110.andy.result.Result; import nl.tudelft.cse1110.andy.writer.standard.StandardResultWriter; @@ -16,7 +19,9 @@ public static void main(String[] args) { Action action = getAction(args[0]); String inputDir = args[1]; String outputDir = args[2]; - Context ctx = Context.build(action, inputDir, outputDir); + + ContextDirector director = new ContextDirector(new ContextBuilder()); + Context ctx = director.constructBase(action, new DirectoryConfiguration(inputDir, outputDir)); StandardResultWriter writer = new StandardResultWriter(); try { diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/codechecker/checks/ClassUsedInSolution.java b/andy/src/main/java/nl/tudelft/cse1110/andy/codechecker/checks/ClassUsedInSolution.java new file mode 100644 index 00000000..87a31865 --- /dev/null +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/codechecker/checks/ClassUsedInSolution.java @@ -0,0 +1,62 @@ +package nl.tudelft.cse1110.andy.codechecker.checks; + +import org.eclipse.jdt.core.dom.*; + +/** + * Checks whether a class is used - instantiated or one of its methods called. + * Parameter: + * - the name of the method + * Output: + * - true if the class was used. + * + */ +public class ClassUsedInSolution extends WithinTestMethod { + + private final String classToBeUsed; + private boolean classWasUsed = false; + + public ClassUsedInSolution(String classToBeUsed) { + this.classToBeUsed = classToBeUsed; + } + + /** + * Checks for class instance creations to + * check if the instantiated class if one of the classes + * we are looking for + */ + @Override + public boolean visit(ClassInstanceCreation cic) { + String className = cic.getType().toString(); + if (classToBeUsed.equals(className)) + classWasUsed = true; + + return super.visit(cic); + } + + /** + * Checks for method invocation to check if a static + * method of the said class is called. Uses Expression + */ + @Override + public boolean visit(MethodInvocation mi) { + Expression expression = mi.getExpression(); + if (expression != null) { + if (expression.toString().equals(classToBeUsed)) + classWasUsed = true; + + + } + + return super.visit(mi); + } + + + @Override + public boolean result() { + return classWasUsed; + } + + public String toString() { + return classToBeUsed + " class is used"; + } +} diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/codechecker/checks/JQWikProvideAnnotations.java b/andy/src/main/java/nl/tudelft/cse1110/andy/codechecker/checks/JQWikProvideAnnotations.java index 43ba4f41..1f8ec802 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/codechecker/checks/JQWikProvideAnnotations.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/codechecker/checks/JQWikProvideAnnotations.java @@ -1,5 +1,6 @@ package nl.tudelft.cse1110.andy.codechecker.checks; +import com.google.common.collect.ImmutableSet; import org.eclipse.jdt.core.dom.MarkerAnnotation; import org.eclipse.jdt.core.dom.Name; import org.eclipse.jdt.core.dom.NormalAnnotation; @@ -11,15 +12,15 @@ public class JQWikProvideAnnotations extends Check { - private boolean provideAnnotationIdentified = false; + private static Set JQWIK_PROVIDE_ANNOTATIONS = new HashSet<>(ImmutableSet.of( + "IntRange", + "Positive", + "Negative" - private static Set JQWIK_PROVIDE_ANNOTATIONS = new HashSet<>() {{ - add("IntRange"); - add("Positive"); - add("Negative"); + // TODO: add all annotations here + )); - // TODO: add all annotations here - }}; + private boolean provideAnnotationIdentified = false; @Override public boolean visit(MarkerAnnotation node) { diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/codechecker/checks/MethodCalledAnywhere.java b/andy/src/main/java/nl/tudelft/cse1110/andy/codechecker/checks/MethodCalledAnywhere.java new file mode 100644 index 00000000..0859d45c --- /dev/null +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/codechecker/checks/MethodCalledAnywhere.java @@ -0,0 +1,33 @@ +package nl.tudelft.cse1110.andy.codechecker.checks; + +import org.eclipse.jdt.core.dom.MethodInvocation; + +public class MethodCalledAnywhere extends Check { + private final String methodToBeCalled; + private boolean methodWasCalled = false; + + public MethodCalledAnywhere(String methodToBeCalled) { + this.methodToBeCalled = methodToBeCalled; + } + + @Override + public boolean visit(MethodInvocation mi) { + + String methodName = mi.getName().toString(); + + if (methodToBeCalled.equals(methodName)) + methodWasCalled = true; + + return super.visit(mi); + } + + + @Override + public boolean result() { + return methodWasCalled; + } + + public String toString() { + return methodToBeCalled + " method is called"; + } +} \ No newline at end of file diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/codechecker/checks/TestMethodsHaveAssertions.java b/andy/src/main/java/nl/tudelft/cse1110/andy/codechecker/checks/TestMethodsHaveAssertions.java index 06db6b41..fd3846d6 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/codechecker/checks/TestMethodsHaveAssertions.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/codechecker/checks/TestMethodsHaveAssertions.java @@ -1,5 +1,6 @@ package nl.tudelft.cse1110.andy.codechecker.checks; +import com.google.common.collect.ImmutableSet; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.MethodInvocation; @@ -22,40 +23,40 @@ */ public class TestMethodsHaveAssertions extends WithinTestMethod { - private boolean containsATestWithoutAssertion = false; - private boolean currentMethodContainsAssertion = false; - /** * This is, for now, a non-exhaustive list. */ - private static Set ASSERT_METHODS = new HashSet<>() {{ + private static Set ASSERT_METHODS = new HashSet<>(ImmutableSet.of( // junit - add("assertEquals"); - add("assertNotEquals"); - add("assertTrue"); - add("assertFalse"); - add("assertThrows"); - add("assertNull"); - add("assertArrayEquals"); - add("assertDoesNotThrow"); - add("assertIterableEquals"); - add("assertLinesMatch"); - add("assertNotNull"); - add("assertNotSame"); - add("assertSame"); + "assertEquals", + "assertNotEquals", + "assertTrue", + "assertFalse", + "assertThrows", + "assertNull", + "assertArrayEquals", + "assertDoesNotThrow", + "assertIterableEquals", + "assertLinesMatch", + "assertNotNull", + "assertNotSame", + "assertSame", // assertj - add("assertThat"); - add("assertThatThrownBy"); - add("assertThatExceptionOfType"); - add("assertThatCode"); - add("assertThatIllegalArgumentException"); - add("assertThatIllegalStateException"); - add("assertThatIOException"); - add("assertThatNullPointerException"); - add("assertThatObject"); - - }}; + "assertThat", + "assertThatThrownBy", + "assertThatExceptionOfType", + "assertThatCode", + "assertThatIllegalArgumentException", + "assertThatIllegalStateException", + "assertThatIOException", + "assertThatNullPointerException", + "assertThatObject" + + )); + + private boolean containsATestWithoutAssertion = false; + private boolean currentMethodContainsAssertion = false; @Override public boolean visit(MethodDeclaration md) { diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/codechecker/checks/UseOfStringLiterals.java b/andy/src/main/java/nl/tudelft/cse1110/andy/codechecker/checks/UseOfStringLiterals.java index 03ed41dd..72bcd1ab 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/codechecker/checks/UseOfStringLiterals.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/codechecker/checks/UseOfStringLiterals.java @@ -1,5 +1,6 @@ package nl.tudelft.cse1110.andy.codechecker.checks; +import com.google.common.collect.ImmutableSet; import org.eclipse.jdt.core.dom.StringLiteral; import java.util.HashSet; @@ -20,16 +21,12 @@ public class UseOfStringLiterals extends WithinAnnotatedMethod { * in JUnit tests and in JQWik methods */ public static Set TEST_ANNOTATIONS = - new HashSet<>() {{ - add("Test"); // junit - add("ParameterizedTest"); // junit - add("Property"); // jqwik - add("Provide"); // jqwik - }}; - - protected Set annotations() { - return TEST_ANNOTATIONS; - } + new HashSet<>(ImmutableSet.of( + "Test", // junit + "ParameterizedTest", // junit + "Property", // jqwik + "Provide" // jqwik + )); private boolean literalFound = false; private int length; @@ -38,6 +35,10 @@ public UseOfStringLiterals(int length) { this.length = length; } + protected Set annotations() { + return TEST_ANNOTATIONS; + } + public boolean visit(StringLiteral node) { if(isInTheAnnotatedMethod() && node.getLiteralValue().length()>=length) literalFound = true; diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/codechecker/checks/WithinAfterEach.java b/andy/src/main/java/nl/tudelft/cse1110/andy/codechecker/checks/WithinAfterEach.java index 88e613a7..c4a0393d 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/codechecker/checks/WithinAfterEach.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/codechecker/checks/WithinAfterEach.java @@ -1,13 +1,15 @@ package nl.tudelft.cse1110.andy.codechecker.checks; +import com.google.common.collect.ImmutableSet; + import java.util.HashSet; import java.util.Set; public abstract class WithinAfterEach extends WithinAnnotatedMethod { - public static Set AFTEREACH_ANNOTATION = new HashSet<>() {{ - add("AfterEach"); - }}; + public static Set AFTEREACH_ANNOTATION = new HashSet<>(ImmutableSet.of( + "AfterEach" + )); protected Set annotations() { return AFTEREACH_ANNOTATION; diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/codechecker/checks/WithinTestMethod.java b/andy/src/main/java/nl/tudelft/cse1110/andy/codechecker/checks/WithinTestMethod.java index 5a48d4d9..643569f3 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/codechecker/checks/WithinTestMethod.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/codechecker/checks/WithinTestMethod.java @@ -1,16 +1,18 @@ package nl.tudelft.cse1110.andy.codechecker.checks; +import com.google.common.collect.ImmutableSet; + import java.util.HashSet; import java.util.Set; public abstract class WithinTestMethod extends WithinAnnotatedMethod { public static Set TEST_ANNOTATIONS = - new HashSet<>() {{ - add("Test"); // junit - add("ParameterizedTest"); // junit - add("Property"); // jqwik - }}; + new HashSet<>(ImmutableSet.of( + "Test", // junit + "ParameterizedTest", // junit + "Property" // jqwik + )); protected Set annotations() { return TEST_ANNOTATIONS; diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/config/DefaultRunConfiguration.java b/andy/src/main/java/nl/tudelft/cse1110/andy/config/DefaultRunConfiguration.java index 8db45a8d..7f0c8807 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/config/DefaultRunConfiguration.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/config/DefaultRunConfiguration.java @@ -1,5 +1,7 @@ package nl.tudelft.cse1110.andy.config; +import com.google.common.collect.ImmutableMap; + import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -15,12 +17,12 @@ public DefaultRunConfiguration(List classesUnderTest) { @Override public Map weights() { - return new HashMap<>() {{ - put("coverage", 0.25f); - put("mutation", 0.25f); - put("meta", 0.25f); - put("codechecks", 0.25f); - }}; + return new HashMap<>(ImmutableMap.of( + "coverage", 0.25f, + "mutation", 0.25f, + "meta", 0.25f, + "codechecks", 0.25f + )); } @Override diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/config/MetaTest.java b/andy/src/main/java/nl/tudelft/cse1110/andy/config/MetaTest.java index 2b771131..3c12a0ac 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/config/MetaTest.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/config/MetaTest.java @@ -1,6 +1,6 @@ package nl.tudelft.cse1110.andy.config; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.execution.externalprocess.ExternalProcess; import nl.tudelft.cse1110.andy.execution.metatest.AbstractMetaTestFactory; diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/config/SecureExamRunConfiguration.java b/andy/src/main/java/nl/tudelft/cse1110/andy/config/SecureExamRunConfiguration.java index c1cbb514..75af9acc 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/config/SecureExamRunConfiguration.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/config/SecureExamRunConfiguration.java @@ -1,5 +1,6 @@ package nl.tudelft.cse1110.andy.config; +import com.google.common.collect.ImmutableMap; import nl.tudelft.cse1110.andy.execution.externalprocess.ExternalProcess; import nl.tudelft.cse1110.andy.execution.mode.Mode; @@ -16,10 +17,6 @@ public class SecureExamRunConfiguration extends RunConfiguration { private final int numberOfMutationsToConsider; private final ExternalProcess externalProcess; - public Mode mode() { - return Mode.EXAM; - } - public SecureExamRunConfiguration(RunConfiguration runConfigurationToClone) { this.classesUnderTest = runConfigurationToClone.classesUnderTest(); this.listOfMutants = runConfigurationToClone.listOfMutants(); @@ -28,14 +25,18 @@ public SecureExamRunConfiguration(RunConfiguration runConfigurationToClone) { this.successMessage = runConfigurationToClone.successMessage(); } + public Mode mode() { + return Mode.EXAM; + } + @Override public Map weights() { - return new HashMap<>() {{ - put("coverage", 0.25f); - put("mutation", 0.25f); - put("meta", 0.25f); - put("codechecks", 0.25f); - }}; + return new HashMap<>(ImmutableMap.of( + "coverage", 0.25f, + "mutation", 0.25f, + "meta", 0.25f, + "codechecks", 0.25f + )); } @Override diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/Context.java b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/Context/Context.java similarity index 69% rename from andy/src/main/java/nl/tudelft/cse1110/andy/execution/Context.java rename to andy/src/main/java/nl/tudelft/cse1110/andy/execution/Context/Context.java index dcdc0f5b..4c3e4c18 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/Context.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/Context/Context.java @@ -1,7 +1,8 @@ -package nl.tudelft.cse1110.andy.execution; +package nl.tudelft.cse1110.andy.execution.Context; import nl.tudelft.cse1110.andy.config.DirectoryConfiguration; import nl.tudelft.cse1110.andy.config.RunConfiguration; +import nl.tudelft.cse1110.andy.execution.ExecutionFlow; import nl.tudelft.cse1110.andy.execution.externalprocess.EmptyExternalProcess; import nl.tudelft.cse1110.andy.execution.mode.Action; import nl.tudelft.cse1110.andy.execution.mode.ModeActionSelector; @@ -14,7 +15,7 @@ public class Context { private final ClassLoader cleanClassloader; - private DirectoryConfiguration directoryConfiguration = null; + private final DirectoryConfiguration directoryConfiguration; private RunConfiguration runConfiguration; private List fullClassNames; private ExecutionFlow flow; @@ -22,40 +23,66 @@ public class Context { private ModeActionSelector modeActionSelector; private ExternalProcess externalProcess; private ClassLoader classloaderWithStudentsCode; - private List librariesToBeIncludedInCompilation; + private final List librariesToBeIncludedInCompilation; private IRuntime jacocoRuntime; private RuntimeData jacocoData; - private Context(ClassLoader cleanClassloader, Action action, DirectoryConfiguration directoryConfiguration, List librariesToBeIncludedInCompilation) { + public Context(ClassLoader cleanClassloader, DirectoryConfiguration directoryConfiguration, + RunConfiguration runConfiguration, List fullClassNames, ExecutionFlow flow, + Action action, ModeActionSelector modeActionSelector, ExternalProcess externalProcess, + ClassLoader classloaderWithStudentsCode, List librariesToBeIncludedInCompilation, + IRuntime jacocoRuntime, RuntimeData jacocoData) { this.cleanClassloader = cleanClassloader; - this.action = action; this.directoryConfiguration = directoryConfiguration; + this.runConfiguration = runConfiguration; + this.fullClassNames = fullClassNames; + this.flow = flow; + this.action = action; + this.modeActionSelector = modeActionSelector; + this.externalProcess = externalProcess; + this.classloaderWithStudentsCode = classloaderWithStudentsCode; this.librariesToBeIncludedInCompilation = librariesToBeIncludedInCompilation; - this.externalProcess = new EmptyExternalProcess(); + this.jacocoRuntime = jacocoRuntime; + this.jacocoData = jacocoData; } - public static Context build(Action action, String workDir, String outputDir, List librariesToBeIncludedInCompilation) { - Context ctx = new Context( - Thread.currentThread().getContextClassLoader(), - action, - new DirectoryConfiguration(workDir, outputDir), - librariesToBeIncludedInCompilation); + public void setFlow(ExecutionFlow flow) {this.flow = flow;} - return ctx; + public void setRunConfiguration(RunConfiguration runConfiguration) { + this.runConfiguration = runConfiguration; } - public static Context build(Action action, String workDir, String outputDir) { - return build(action, workDir, outputDir, null); + + public void setNewClassNames(List fullClassNames) { + this.fullClassNames = fullClassNames; } - public static Context build(ClassLoader cleanClassloader, Action action) { - return new Context(cleanClassloader, action, null, null); + public void setModeSelector(ModeActionSelector modeActionSelector) { + this.modeActionSelector = modeActionSelector; } - public static Context build(Action action) { - return build(Thread.currentThread().getContextClassLoader(), action); + public void setExternalProcess(ExternalProcess externalProcess) { + this.externalProcess = externalProcess; } - public void setFlow(ExecutionFlow flow) {this.flow = flow;} + public void killExternalProcess() { + // Retrieve error messages before killing process + externalProcess.extractErrorMessages(); + + externalProcess.kill(); + } + + public void setClassloaderWithStudentsCode(ClassLoader classloaderWithStudentsCode) { + this.classloaderWithStudentsCode = classloaderWithStudentsCode; + } + + public void setJacocoObjects(IRuntime runtime, RuntimeData data) { + jacocoRuntime = runtime; + jacocoData = data; + } + + public boolean hasJacocoRuntime() { + return jacocoRuntime != null && jacocoData != null; + } public ExecutionFlow getFlow() { return flow; @@ -69,22 +96,10 @@ public RunConfiguration getRunConfiguration() { return runConfiguration; } - public void setDirectoryConfiguration(DirectoryConfiguration directoryConfiguration) { - this.directoryConfiguration = directoryConfiguration; - } - - public void setRunConfiguration(RunConfiguration runConfiguration) { - this.runConfiguration = runConfiguration; - } - public ClassLoader getCleanClassloader() { return cleanClassloader; } - public void setNewClassNames(List fullClassNames) { - this.fullClassNames = fullClassNames; - } - public List getNewClassNames() { return fullClassNames; } @@ -93,10 +108,6 @@ public Action getAction() { return action; } - public void setModeSelector(ModeActionSelector modeActionSelector) { - this.modeActionSelector = modeActionSelector; - } - public ModeActionSelector getModeActionSelector() { return modeActionSelector; } @@ -105,29 +116,10 @@ public ExternalProcess getExternalProcess() { return externalProcess; } - public void setExternalProcess(ExternalProcess externalProcess) { - this.externalProcess = externalProcess; - } - - public void killExternalProcess() { - // Retrieve error messages before killing process - externalProcess.extractErrorMessages(); - - externalProcess.kill(); - } - - public void setClassloaderWithStudentsCode(ClassLoader classloaderWithStudentsCode) { - this.classloaderWithStudentsCode = classloaderWithStudentsCode; - } - public ClassLoader getClassloaderWithStudentsCode() { return classloaderWithStudentsCode; } - public void setLibrariesToBeIncludedInCompilation(List librariesToBeIncludedInCompilation) { - this.librariesToBeIncludedInCompilation = librariesToBeIncludedInCompilation; - } - public List getLibrariesToBeIncludedInCompilation() { return librariesToBeIncludedInCompilation; } @@ -136,15 +128,6 @@ public boolean hasLibrariesToBeIncluded() { return librariesToBeIncludedInCompilation!=null && !librariesToBeIncludedInCompilation.isEmpty(); } - public void setJacocoObjects(IRuntime runtime, RuntimeData data) { - jacocoRuntime = runtime; - jacocoData = data; - } - - public boolean hasJacocoRuntime() { - return jacocoRuntime != null && jacocoData != null; - } - public IRuntime getJacocoRuntime() { return jacocoRuntime; } diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/Context/ContextBuilder.java b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/Context/ContextBuilder.java new file mode 100644 index 00000000..368d87cb --- /dev/null +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/Context/ContextBuilder.java @@ -0,0 +1,61 @@ +package nl.tudelft.cse1110.andy.execution.Context; + +import nl.tudelft.cse1110.andy.config.DirectoryConfiguration; +import nl.tudelft.cse1110.andy.config.RunConfiguration; +import nl.tudelft.cse1110.andy.execution.ExecutionFlow; +import nl.tudelft.cse1110.andy.execution.externalprocess.ExternalProcess; +import nl.tudelft.cse1110.andy.execution.mode.Action; +import nl.tudelft.cse1110.andy.execution.mode.ModeActionSelector; +import org.jacoco.core.runtime.IRuntime; +import org.jacoco.core.runtime.RuntimeData; + +import java.util.List; + +public class ContextBuilder { + private ClassLoader cleanClassloader; + private DirectoryConfiguration directoryConfiguration; + private RunConfiguration runConfiguration; + private List fullClassNames; + private ExecutionFlow flow; + private Action action; + private ModeActionSelector modeActionSelector; + private ExternalProcess externalProcess; + private ClassLoader classloaderWithStudentsCode; + private List librariesToBeIncludedInCompilation; + private IRuntime jacocoRuntime; + private RuntimeData jacocoData; + + public void setCleanClassloader(ClassLoader cleanClassloader) { + this.cleanClassloader = cleanClassloader; + } + + public void setDirectoryConfiguration(DirectoryConfiguration directoryConfiguration) { + this.directoryConfiguration = directoryConfiguration; + } + + public void setRunConfiguration(RunConfiguration runConfiguration) { + this.runConfiguration = runConfiguration; + } + + public void setFlow(ExecutionFlow flow) { + this.flow = flow; + } + + public void setAction(Action action) { + this.action = action; + } + + public void setExternalProcess(ExternalProcess externalProcess) { + this.externalProcess = externalProcess; + } + + public void setLibrariesToBeIncludedInCompilation(List librariesToBeIncludedInCompilation) { + this.librariesToBeIncludedInCompilation = librariesToBeIncludedInCompilation; + } + + public Context buildContext() { + return new Context(cleanClassloader, directoryConfiguration, runConfiguration, fullClassNames, flow, + action, modeActionSelector, externalProcess, classloaderWithStudentsCode, + librariesToBeIncludedInCompilation, jacocoRuntime, jacocoData); + } +} diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/Context/ContextDirector.java b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/Context/ContextDirector.java new file mode 100644 index 00000000..4bc3f798 --- /dev/null +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/Context/ContextDirector.java @@ -0,0 +1,58 @@ +package nl.tudelft.cse1110.andy.execution.Context; + +import nl.tudelft.cse1110.andy.config.DirectoryConfiguration; +import nl.tudelft.cse1110.andy.execution.externalprocess.EmptyExternalProcess; +import nl.tudelft.cse1110.andy.execution.mode.Action; + +import java.util.List; + +public class ContextDirector { + private ContextBuilder contextBuilder; + + public ContextDirector(ContextBuilder contextBuilder) { + this.contextBuilder = contextBuilder; + } + + public Context constructBase(Action action, DirectoryConfiguration directoryConfiguration) { + this.setBase(action, directoryConfiguration); + + Context ctx = contextBuilder.buildContext(); + + // reset builder + contextBuilder = new ContextBuilder(); + return ctx; + } + + public Context constructWithLibraries(Action action, DirectoryConfiguration directoryConfiguration, + List librariesToBeIncludedInCompilation) { + this.setBase(action, directoryConfiguration); + contextBuilder.setLibrariesToBeIncludedInCompilation(librariesToBeIncludedInCompilation); + + Context ctx = contextBuilder.buildContext(); + + // reset builder + contextBuilder = new ContextBuilder(); + return ctx; + } + + public Context constructWithLibrariesAndClassLoader(ClassLoader cleanClassloader, Action action, + DirectoryConfiguration directoryConfiguration, + List librariesToBeIncludedInCompilation) { + this.setBase(action, directoryConfiguration); + contextBuilder.setCleanClassloader(cleanClassloader); + contextBuilder.setLibrariesToBeIncludedInCompilation(librariesToBeIncludedInCompilation); + + Context ctx = contextBuilder.buildContext(); + + // reset builder + contextBuilder = new ContextBuilder(); + return ctx; + } + + private void setBase(Action action, DirectoryConfiguration directoryConfiguration) { + contextBuilder.setCleanClassloader(Thread.currentThread().getContextClassLoader()); + contextBuilder.setAction(action); + contextBuilder.setDirectoryConfiguration(directoryConfiguration); + contextBuilder.setExternalProcess(new EmptyExternalProcess()); + } +} diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/ExecutionFlow.java b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/ExecutionFlow.java index 69f61637..78658ccd 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/ExecutionFlow.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/ExecutionFlow.java @@ -1,5 +1,6 @@ package nl.tudelft.cse1110.andy.execution; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.execution.step.*; import nl.tudelft.cse1110.andy.grade.GradeCalculator; import nl.tudelft.cse1110.andy.result.Result; diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/ExecutionStep.java b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/ExecutionStep.java index 6e166a16..7ee4f01a 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/ExecutionStep.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/ExecutionStep.java @@ -1,5 +1,6 @@ package nl.tudelft.cse1110.andy.execution; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.result.ResultBuilder; public interface ExecutionStep { diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/metatest/AbstractMetaTest.java b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/metatest/AbstractMetaTest.java index cdec08dd..a8333b2f 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/metatest/AbstractMetaTest.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/metatest/AbstractMetaTest.java @@ -3,7 +3,7 @@ import nl.tudelft.cse1110.andy.config.DirectoryConfiguration; import nl.tudelft.cse1110.andy.config.MetaTest; import nl.tudelft.cse1110.andy.config.RunConfiguration; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; public abstract class AbstractMetaTest implements MetaTest { diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/metatest/externalprocess/ExternalProcessMetaTest.java b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/metatest/externalprocess/ExternalProcessMetaTest.java index e6d3a951..a3891093 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/metatest/externalprocess/ExternalProcessMetaTest.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/metatest/externalprocess/ExternalProcessMetaTest.java @@ -1,12 +1,10 @@ package nl.tudelft.cse1110.andy.execution.metatest.externalprocess; -import nl.tudelft.cse1110.andy.config.DefaultRunConfiguration; import nl.tudelft.cse1110.andy.config.DirectoryConfiguration; import nl.tudelft.cse1110.andy.config.RunConfiguration; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.execution.externalprocess.ExternalProcess; import nl.tudelft.cse1110.andy.execution.metatest.AbstractMetaTest; -import nl.tudelft.cse1110.andy.execution.mode.Action; import nl.tudelft.cse1110.andy.execution.step.RunJUnitTestsStep; import nl.tudelft.cse1110.andy.result.ResultBuilder; @@ -34,9 +32,6 @@ public boolean execute(Context ctx, DirectoryConfiguration dirCfg, RunConfigurat /* Start the meta external process */ this.startExternalProcess(); - /* Run the test suite using our existing JUnit runner */ - Context jUnitContext = Context.build(Action.META_TEST); - jUnitContext.setRunConfiguration(new DefaultRunConfiguration(ctx.getRunConfiguration().classesUnderTest())); ResultBuilder metaResultBuilder = new ResultBuilder(null, null); RunJUnitTestsStep jUnitStep = new RunJUnitTestsStep(); diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/metatest/library/LibraryMetaTest.java b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/metatest/library/LibraryMetaTest.java index ad6841e2..8a1900ef 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/metatest/library/LibraryMetaTest.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/metatest/library/LibraryMetaTest.java @@ -2,16 +2,15 @@ import nl.tudelft.cse1110.andy.config.DirectoryConfiguration; import nl.tudelft.cse1110.andy.config.RunConfiguration; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; +import nl.tudelft.cse1110.andy.execution.Context.ContextBuilder; +import nl.tudelft.cse1110.andy.execution.Context.ContextDirector; import nl.tudelft.cse1110.andy.execution.ExecutionFlow; import nl.tudelft.cse1110.andy.execution.metatest.AbstractMetaTest; import nl.tudelft.cse1110.andy.execution.metatest.library.evaluators.MetaEvaluator; import nl.tudelft.cse1110.andy.execution.mode.Action; -import nl.tudelft.cse1110.andy.grade.GradeCalculator; import nl.tudelft.cse1110.andy.result.Result; -import nl.tudelft.cse1110.andy.result.ResultBuilder; import nl.tudelft.cse1110.andy.utils.FilesUtils; -import nl.tudelft.cse1110.andy.writer.EmptyWriter; import java.io.File; import java.io.IOException; @@ -94,9 +93,13 @@ private Result runMetaTest(Context ctx, DirectoryConfiguration dirCfg, File meta dirCfg.getOutputDir() ); - Context metaCtx = Context.build(ctx.getCleanClassloader(), Action.META_TEST); - metaCtx.setDirectoryConfiguration(metaDirCfg); - metaCtx.setLibrariesToBeIncludedInCompilation(ctx.getLibrariesToBeIncludedInCompilation()); + ContextDirector director = new ContextDirector(new ContextBuilder()); + Context metaCtx = director.constructWithLibrariesAndClassLoader( + ctx.getCleanClassloader(), + Action.META_TEST, + metaDirCfg, + ctx.getLibrariesToBeIncludedInCompilation() + ); ExecutionFlow flow = ExecutionFlow.build(metaCtx); Result metaResult = flow.run(); diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/mode/ModeActionSelector.java b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/mode/ModeActionSelector.java index 914c1b9a..c2532c47 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/mode/ModeActionSelector.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/mode/ModeActionSelector.java @@ -45,9 +45,10 @@ public List getSteps() { case GRADING -> { return getGradingMode(); } + default -> { + return Collections.emptyList(); + } } - - return Collections.emptyList(); } public boolean shouldShowFullHints() { diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/CollectCoverageInformationStep.java b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/CollectCoverageInformationStep.java index d88f5633..e227aced 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/CollectCoverageInformationStep.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/CollectCoverageInformationStep.java @@ -2,7 +2,7 @@ import nl.tudelft.cse1110.andy.config.DirectoryConfiguration; import nl.tudelft.cse1110.andy.config.RunConfiguration; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.execution.ExecutionStep; import nl.tudelft.cse1110.andy.result.ResultBuilder; import nl.tudelft.cse1110.andy.utils.ClassUtils; @@ -34,19 +34,16 @@ public class CollectCoverageInformationStep implements ExecutionStep { @Override public void execute(Context ctx, ResultBuilder result) { - // Skip step if disabled if (ctx.getRunConfiguration().skipJacoco()) { return; } - if(!ctx.hasJacocoRuntime()) { throw new RuntimeException("Failed when getting coverage information!"); } DirectoryConfiguration dirCfg = ctx.getDirectoryConfiguration(); RunConfiguration runCfg = ctx.getRunConfiguration(); - RuntimeData data = ctx.getJacocoData(); IRuntime runtime = ctx.getJacocoRuntime(); @@ -141,4 +138,9 @@ private void generateReport(DirectoryConfiguration dirCfg, String testClass, public boolean equals(Object other) { return other instanceof CollectCoverageInformationStep; } + + @Override + public int hashCode() { + return super.hashCode(); + } } diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/CompilationStep.java b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/CompilationStep.java index 75219da4..71ad04b5 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/CompilationStep.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/CompilationStep.java @@ -1,7 +1,7 @@ package nl.tudelft.cse1110.andy.execution.step; import nl.tudelft.cse1110.andy.config.DirectoryConfiguration; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.execution.ExecutionStep; import nl.tudelft.cse1110.andy.result.ResultBuilder; import nl.tudelft.cse1110.andy.utils.FilesUtils; @@ -49,20 +49,18 @@ public void execute(Context ctx, ResultBuilder result) { * So, all the libraries available (JUnit, etc) will be reused here */ Collection listOfFiles = FilesUtils.getAllJavaFiles(dirCfg.getWorkingDir()); - - Iterable sources = - manager.getJavaFileObjectsFromFiles(listOfFiles); + Iterable sources = manager.getJavaFileObjectsFromFiles(listOfFiles); ClassNameScanner scanner = new ClassNameScanner(); ClassNameProcessor processor = new ClassNameProcessor(scanner); - List options = ctx.hasLibrariesToBeIncluded() ? Arrays.asList(new String[] { "-cp", asClassPath(ctx.getLibrariesToBeIncludedInCompilation()) }) : null; + List options = ctx.hasLibrariesToBeIncluded() ? Arrays.asList( + new String[] { "-cp", asClassPath(ctx.getLibrariesToBeIncludedInCompilation()) }) : null; JavaCompiler.CompilationTask task = compiler.getTask(null, manager, diagnostics, options, null, sources); task.setProcessors(Arrays.asList(processor)); /* - * Compiles. The .class files will be saved in the same directory - * as the java files. + * Compiles. The .class files will be saved in the same directory as the java files. */ try { boolean compilationResult = task.call(); @@ -121,4 +119,8 @@ public boolean equals(Object other) { return other instanceof CompilationStep; } + @Override + public int hashCode() { + return super.hashCode(); + } } \ No newline at end of file diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/ExamModeSecurityGuardStep.java b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/ExamModeSecurityGuardStep.java index 1043c873..9fa64f85 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/ExamModeSecurityGuardStep.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/ExamModeSecurityGuardStep.java @@ -2,7 +2,7 @@ import nl.tudelft.cse1110.andy.config.SecureExamRunConfiguration; import nl.tudelft.cse1110.andy.config.RunConfiguration; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.execution.ExecutionStep; import nl.tudelft.cse1110.andy.execution.mode.Mode; import nl.tudelft.cse1110.andy.result.ResultBuilder; diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/GetRunConfigurationStep.java b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/GetRunConfigurationStep.java index 9d9e6de3..e44fae15 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/GetRunConfigurationStep.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/GetRunConfigurationStep.java @@ -2,12 +2,8 @@ import nl.tudelft.cse1110.andy.config.DefaultRunConfiguration; import nl.tudelft.cse1110.andy.config.RunConfiguration; -import nl.tudelft.cse1110.andy.execution.Context; -import nl.tudelft.cse1110.andy.execution.ExecutionFlow; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.execution.ExecutionStep; -import nl.tudelft.cse1110.andy.execution.mode.Action; -import nl.tudelft.cse1110.andy.execution.mode.Mode; -import nl.tudelft.cse1110.andy.execution.mode.ModeActionSelector; import nl.tudelft.cse1110.andy.result.ResultBuilder; import java.util.NoSuchElementException; @@ -39,4 +35,9 @@ public void execute(Context ctx, ResultBuilder result) { public boolean equals(Object other) { return other instanceof GetRunConfigurationStep; } + + @Override + public int hashCode() { + return super.hashCode(); + } } diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/InjectModeActionStepsStep.java b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/InjectModeActionStepsStep.java index dfb95577..cf90c058 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/InjectModeActionStepsStep.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/InjectModeActionStepsStep.java @@ -1,7 +1,7 @@ package nl.tudelft.cse1110.andy.execution.step; import nl.tudelft.cse1110.andy.config.RunConfiguration; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.execution.ExecutionFlow; import nl.tudelft.cse1110.andy.execution.ExecutionStep; import nl.tudelft.cse1110.andy.execution.mode.Action; diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/InstrumentCodeForCoverageStep.java b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/InstrumentCodeForCoverageStep.java index fcfe0419..b986e40b 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/InstrumentCodeForCoverageStep.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/InstrumentCodeForCoverageStep.java @@ -1,39 +1,20 @@ package nl.tudelft.cse1110.andy.execution.step; import nl.tudelft.cse1110.andy.config.DirectoryConfiguration; -import nl.tudelft.cse1110.andy.config.RunConfiguration; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.execution.ExecutionStep; import nl.tudelft.cse1110.andy.result.ResultBuilder; -import nl.tudelft.cse1110.andy.utils.ClassUtils; -import nl.tudelft.cse1110.andy.utils.FilesUtils; import nl.tudelft.cse1110.andy.utils.FromBytesClassLoader; -import org.jacoco.core.analysis.Analyzer; -import org.jacoco.core.analysis.CoverageBuilder; -import org.jacoco.core.analysis.IClassCoverage; -import org.jacoco.core.data.ExecutionDataStore; -import org.jacoco.core.data.SessionInfoStore; import org.jacoco.core.instr.Instrumenter; import org.jacoco.core.runtime.IRuntime; import org.jacoco.core.runtime.LoggerRuntime; import org.jacoco.core.runtime.RuntimeData; -import org.jacoco.report.DirectorySourceFileLocator; -import org.jacoco.report.FileMultiReportOutput; -import org.jacoco.report.IReportVisitor; -import org.jacoco.report.html.HTMLFormatter; -import org.junit.platform.launcher.Launcher; -import org.junit.platform.launcher.LauncherDiscoveryRequest; -import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder; -import org.junit.platform.launcher.core.LauncherFactory; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; -import java.util.Collection; -import static nl.tudelft.cse1110.andy.utils.ClassUtils.clazzNameAsPath; -import static nl.tudelft.cse1110.andy.utils.FilesUtils.concatenateDirectories; import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass; public class InstrumentCodeForCoverageStep implements ExecutionStep { @@ -102,4 +83,9 @@ private void instrumentAllInDirectory(Instrumenter instr, File directory, FromBy public boolean equals(Object other) { return other instanceof InstrumentCodeForCoverageStep; } + + @Override + public int hashCode() { + return super.hashCode(); + } } diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/KillExternalProcessStep.java b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/KillExternalProcessStep.java index f7ff0858..ec484eb2 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/KillExternalProcessStep.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/KillExternalProcessStep.java @@ -1,6 +1,6 @@ package nl.tudelft.cse1110.andy.execution.step; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.execution.ExecutionStep; import nl.tudelft.cse1110.andy.result.ResultBuilder; @@ -15,4 +15,9 @@ public void execute(Context ctx, ResultBuilder result) { public boolean equals(Object other) { return other instanceof KillExternalProcessStep; } + + @Override + public int hashCode() { + return super.hashCode(); + } } diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/OrganizeSourceCodeStep.java b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/OrganizeSourceCodeStep.java index 99f7ebbc..7e7244b1 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/OrganizeSourceCodeStep.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/OrganizeSourceCodeStep.java @@ -1,10 +1,9 @@ package nl.tudelft.cse1110.andy.execution.step; import nl.tudelft.cse1110.andy.config.DirectoryConfiguration; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.execution.ExecutionStep; import nl.tudelft.cse1110.andy.result.ResultBuilder; -import org.apache.commons.io.FileUtils; import java.io.File; import java.nio.file.Files; @@ -41,4 +40,9 @@ public void execute(Context ctx, ResultBuilder result) { public boolean equals(Object other) { return other instanceof OrganizeSourceCodeStep; } + + @Override + public int hashCode() { + return super.hashCode(); + } } diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/ReplaceClassloaderStep.java b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/ReplaceClassloaderStep.java index a1b57d7d..e427cf10 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/ReplaceClassloaderStep.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/ReplaceClassloaderStep.java @@ -1,6 +1,6 @@ package nl.tudelft.cse1110.andy.execution.step; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.config.DirectoryConfiguration; import nl.tudelft.cse1110.andy.execution.ExecutionStep; import nl.tudelft.cse1110.andy.result.ResultBuilder; @@ -53,4 +53,9 @@ private URL toURL(Path path) { public boolean equals(Object other) { return other instanceof ReplaceClassloaderStep; } + + @Override + public int hashCode() { + return super.hashCode(); + } } diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/RunCodeChecksStep.java b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/RunCodeChecksStep.java index ffeb4fc3..cad3b9a5 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/RunCodeChecksStep.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/RunCodeChecksStep.java @@ -3,7 +3,7 @@ import nl.tudelft.cse1110.andy.codechecker.engine.CheckScript; import nl.tudelft.cse1110.andy.config.DirectoryConfiguration; import nl.tudelft.cse1110.andy.config.RunConfiguration; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.execution.ExecutionStep; import nl.tudelft.cse1110.andy.result.ResultBuilder; @@ -31,4 +31,9 @@ public void execute(Context ctx, ResultBuilder result) { public boolean equals(Object other) { return other instanceof RunCodeChecksStep; } + + @Override + public int hashCode() { + return super.hashCode(); + } } diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/RunExternalProcessStep.java b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/RunExternalProcessStep.java index 68a662c3..6eb7febc 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/RunExternalProcessStep.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/RunExternalProcessStep.java @@ -1,7 +1,7 @@ package nl.tudelft.cse1110.andy.execution.step; import nl.tudelft.cse1110.andy.config.RunConfiguration; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.execution.ExecutionStep; import nl.tudelft.cse1110.andy.result.ResultBuilder; import nl.tudelft.cse1110.andy.execution.externalprocess.ExternalProcess; @@ -30,4 +30,9 @@ public void execute(Context ctx, ResultBuilder result) { public boolean equals(Object other) { return other instanceof RunExternalProcessStep; } + + @Override + public int hashCode() { + return super.hashCode(); + } } diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/RunJUnitTestsStep.java b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/RunJUnitTestsStep.java index 6f1e29bf..c206581d 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/RunJUnitTestsStep.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/RunJUnitTestsStep.java @@ -1,6 +1,6 @@ package nl.tudelft.cse1110.andy.execution.step; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.execution.ExecutionStep; import nl.tudelft.cse1110.andy.result.ResultBuilder; import nl.tudelft.cse1110.andy.utils.ClassUtils; @@ -17,7 +17,6 @@ import java.io.ByteArrayOutputStream; import java.io.PrintStream; -import java.util.List; import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass; @@ -68,6 +67,11 @@ public boolean equals(Object other) { return other instanceof RunJUnitTestsStep; } + @Override + public int hashCode() { + return super.hashCode(); + } + public static class AdditionalReportJUnitListener implements TestExecutionListener { private ResultBuilder result; diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/RunMetaTestsStep.java b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/RunMetaTestsStep.java index 32873786..654abff8 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/RunMetaTestsStep.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/RunMetaTestsStep.java @@ -3,7 +3,7 @@ import nl.tudelft.cse1110.andy.config.DirectoryConfiguration; import nl.tudelft.cse1110.andy.config.MetaTest; import nl.tudelft.cse1110.andy.config.RunConfiguration; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.execution.ExecutionStep; import nl.tudelft.cse1110.andy.result.MetaTestResult; import nl.tudelft.cse1110.andy.result.ResultBuilder; @@ -54,4 +54,9 @@ public void execute(Context ctx, ResultBuilder result) { public boolean equals(Object other) { return other instanceof RunMetaTestsStep; } + + @Override + public int hashCode() { + return super.hashCode(); + } } diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/RunPenaltyCodeChecksStep.java b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/RunPenaltyCodeChecksStep.java index 4558c73c..1a89c17e 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/RunPenaltyCodeChecksStep.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/RunPenaltyCodeChecksStep.java @@ -3,7 +3,7 @@ import nl.tudelft.cse1110.andy.codechecker.engine.CheckScript; import nl.tudelft.cse1110.andy.config.DirectoryConfiguration; import nl.tudelft.cse1110.andy.config.RunConfiguration; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.execution.ExecutionStep; import nl.tudelft.cse1110.andy.result.ResultBuilder; @@ -31,4 +31,9 @@ public void execute(Context ctx, ResultBuilder result) { public boolean equals(Object other) { return other instanceof RunPenaltyCodeChecksStep; } + + @Override + public int hashCode() { + return super.hashCode(); + } } diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/RunPitestStep.java b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/RunPitestStep.java index aa969633..06c542bb 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/RunPitestStep.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/RunPitestStep.java @@ -1,6 +1,6 @@ package nl.tudelft.cse1110.andy.execution.step; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.config.DirectoryConfiguration; import nl.tudelft.cse1110.andy.config.RunConfiguration; import nl.tudelft.cse1110.andy.execution.ExecutionStep; @@ -141,4 +141,9 @@ private PrintStream silencePitest() { public boolean equals(Object other) { return other instanceof RunPitestStep; } + + @Override + public int hashCode() { + return super.hashCode(); + } } diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/SourceCodeSecurityCheckStep.java b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/SourceCodeSecurityCheckStep.java index a98edb5e..12d69595 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/SourceCodeSecurityCheckStep.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/execution/step/SourceCodeSecurityCheckStep.java @@ -1,7 +1,7 @@ package nl.tudelft.cse1110.andy.execution.step; import nl.tudelft.cse1110.andy.config.DirectoryConfiguration; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.execution.ExecutionStep; import nl.tudelft.cse1110.andy.result.ResultBuilder; import nl.tudelft.cse1110.andy.utils.FilesUtils; @@ -102,4 +102,9 @@ private boolean checkForKeywords(String code, ResultBuilder result) { public boolean equals(Object other) { return other instanceof SourceCodeSecurityCheckStep; } + + @Override + public int hashCode() { + return super.hashCode(); + } } diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/result/CodeChecksResult.java b/andy/src/main/java/nl/tudelft/cse1110/andy/result/CodeChecksResult.java index db09e7de..a7ce44d1 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/result/CodeChecksResult.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/result/CodeChecksResult.java @@ -35,7 +35,7 @@ public int getTotalNumberOfChecks() { } public int getTotalNumberOfChecks(boolean includeWeight) { - return checkResults.stream().mapToInt(c -> (includeWeight ? c.getWeight() : 1)).sum(); + return checkResults.stream().mapToInt(c -> includeWeight ? c.getWeight() : 1).sum(); } public List getCheckResults() { diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/result/ResultBuilder.java b/andy/src/main/java/nl/tudelft/cse1110/andy/result/ResultBuilder.java index ee1825b8..86ebe84c 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/result/ResultBuilder.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/result/ResultBuilder.java @@ -2,7 +2,7 @@ import nl.tudelft.cse1110.andy.codechecker.engine.CheckScript; import nl.tudelft.cse1110.andy.codechecker.engine.CheckType; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.execution.ExecutionStep; import nl.tudelft.cse1110.andy.execution.externalprocess.ExternalProcess; import nl.tudelft.cse1110.andy.grade.GradeCalculator; @@ -207,6 +207,7 @@ public void logJacoco(Collection coverages) { totalCoveredBranches, totalBranches, coverageLineByLine); } + @SuppressWarnings("checkstyle:methodLength") private CoverageLineByLine getCoverageLineByLine(Collection coverages) { List fullyCoveredLines = new ArrayList<>(); List partiallyCoveredLines = new ArrayList<>(); diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/utils/FilesUtils.java b/andy/src/main/java/nl/tudelft/cse1110/andy/utils/FilesUtils.java index 7a7425f8..e8d24eb9 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/utils/FilesUtils.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/utils/FilesUtils.java @@ -81,6 +81,7 @@ public static String findSolution(String workdir) throws FileNotFoundException { .orElseThrow(() -> new FileNotFoundException("Solution file does not exist.")); } + @SuppressWarnings("checkstyle:UnnecessaryParenthesesCheck") public static String findLibrary(String workdir) throws FileNotFoundException { return getAllJavaFiles(workdir) .stream().filter(x -> x.getAbsolutePath().endsWith("Library.java") diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/writer/EmptyWriter.java b/andy/src/main/java/nl/tudelft/cse1110/andy/writer/EmptyWriter.java index 7044ad29..d6ef834f 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/writer/EmptyWriter.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/writer/EmptyWriter.java @@ -1,6 +1,6 @@ package nl.tudelft.cse1110.andy.writer; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.result.Result; public class EmptyWriter implements ResultWriter { diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/writer/ResultWriter.java b/andy/src/main/java/nl/tudelft/cse1110/andy/writer/ResultWriter.java index 7f356155..b0d15972 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/writer/ResultWriter.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/writer/ResultWriter.java @@ -1,6 +1,6 @@ package nl.tudelft.cse1110.andy.writer; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.result.Result; public interface ResultWriter { diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/writer/standard/CodeSnippetGenerator.java b/andy/src/main/java/nl/tudelft/cse1110/andy/writer/standard/CodeSnippetGenerator.java index 583822aa..29585193 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/writer/standard/CodeSnippetGenerator.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/writer/standard/CodeSnippetGenerator.java @@ -1,6 +1,6 @@ package nl.tudelft.cse1110.andy.writer.standard; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.utils.CodeSnippetUtils; import java.io.FileNotFoundException; diff --git a/andy/src/main/java/nl/tudelft/cse1110/andy/writer/standard/StandardResultWriter.java b/andy/src/main/java/nl/tudelft/cse1110/andy/writer/standard/StandardResultWriter.java index 72cf9544..81165442 100644 --- a/andy/src/main/java/nl/tudelft/cse1110/andy/writer/standard/StandardResultWriter.java +++ b/andy/src/main/java/nl/tudelft/cse1110/andy/writer/standard/StandardResultWriter.java @@ -1,6 +1,6 @@ package nl.tudelft.cse1110.andy.writer.standard; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.execution.mode.Action; import nl.tudelft.cse1110.andy.execution.mode.Mode; import nl.tudelft.cse1110.andy.execution.mode.ModeActionSelector; diff --git a/andy/src/main/resources/congrats/0list.txt b/andy/src/main/resources/congrats/0list.txt index 9156ab71..5f9f3350 100644 --- a/andy/src/main/resources/congrats/0list.txt +++ b/andy/src/main/resources/congrats/0list.txt @@ -22,4 +22,5 @@ rickroll.txt smiley.txt smilingcat.txt sun.txt +shrek.txt winniethepooh.txt diff --git a/andy/src/main/resources/congrats/shrek.txt b/andy/src/main/resources/congrats/shrek.txt new file mode 100644 index 00000000..68de6f0c --- /dev/null +++ b/andy/src/main/resources/congrats/shrek.txt @@ -0,0 +1,16 @@ +⢀⡴⠑⡄⠀⠀⠀⠀⠀⠀⠀⣀⣀⣤⣤⣤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠸⡇⠀⠿⡀⠀⠀⠀⣀⡴⢿⣿⣿⣿⣿⣿⣿⣿⣷⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠑⢄⣠⠾⠁⣀⣄⡈⠙⣿⣿⣿⣿⣿⣿⣿⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⢀⡀⠁⠀⠀⠈⠙⠛⠂⠈⣿⣿⣿⣿⣿⠿⡿⢿⣆⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⢀⡾⣁⣀⠀⠴⠂⠙⣗⡀⠀⢻⣿⣿⠭⢤⣴⣦⣤⣹⠀⠀⠀⢀⢴⣶⣆ +⠀⠀⢀⣾⣿⣿⣿⣷⣮⣽⣾⣿⣥⣴⣿⣿⡿⢂⠔⢚⡿⢿⣿⣦⣴⣾⠁⠸⣼⡿ +⠀⢀⡞⠁⠙⠻⠿⠟⠉⠀⠛⢹⣿⣿⣿⣿⣿⣌⢤⣼⣿⣾⣿⡟⠉⠀⠀⠀⠀⠀ +⠀⣾⣷⣶⠇⠀⠀⣤⣄⣀⡀⠈⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀ +⠀⠉⠈⠉⠀⠀⢦⡈⢻⣿⣿⣿⣶⣶⣶⣶⣤⣽⡹⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠉⠲⣽⡻⢿⣿⣿⣿⣿⣿⣿⣷⣜⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣷⣶⣮⣭⣽⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⣀⣀⣈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠻⠿⠿⠿⠿⠛⠉ + Super Congrats! \ No newline at end of file diff --git a/andy/src/test/java/codequality/CodeSheriffTest.java b/andy/src/test/java/codequality/CodeSheriffTest.java deleted file mode 100644 index 38bda85e..00000000 --- a/andy/src/test/java/codequality/CodeSheriffTest.java +++ /dev/null @@ -1,35 +0,0 @@ -package codequality; - -import com.github.mauricioaniche.codesheriff.dsl.CodeSheriff; -import com.github.mauricioaniche.codesheriff.junit.CodeSheriffJUnit5; - -public class CodeSheriffTest extends CodeSheriffJUnit5 { - - CodeSheriff complexity() { - CodeSheriff sheriff = new CodeSheriff(); - - sheriff.thatEnsures() - .methods() - .inClassesOfPackage("nl.tudelft.cse1110.andy") - .have() - .complexity(m -> m <= 10); - - return sheriff; - } - - CodeSheriff loc() { - CodeSheriff sheriff = new CodeSheriff(); - - sheriff.thatEnsures() - .methods() - .inClassesOfPackage("nl.tudelft.cse1110.andy") - .withExceptionOfMethod("visit/1") - .withExceptionOfMethod("execute/2") // the Step methods are a bit long now, we gotta refactor them - .withExceptionOfMethod("getCoverageLineByLine/1") // it's long but extracting makes it harder to understand - .have() - .linesOfCode(m -> m <= 25); - - return sheriff; - } - -} diff --git a/andy/src/test/java/integration/GenericFailureTest.java b/andy/src/test/java/integration/GenericFailureTest.java index 6458128e..3efa5013 100644 --- a/andy/src/test/java/integration/GenericFailureTest.java +++ b/andy/src/test/java/integration/GenericFailureTest.java @@ -1,6 +1,6 @@ package integration; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.execution.ExecutionFlow; import nl.tudelft.cse1110.andy.execution.ExecutionStep; import nl.tudelft.cse1110.andy.execution.mode.Action; diff --git a/andy/src/test/java/integration/GenericFailureWithStandardResultWriterTest.java b/andy/src/test/java/integration/GenericFailureWithStandardResultWriterTest.java index 4d112480..e4d2124a 100644 --- a/andy/src/test/java/integration/GenericFailureWithStandardResultWriterTest.java +++ b/andy/src/test/java/integration/GenericFailureWithStandardResultWriterTest.java @@ -1,7 +1,7 @@ package integration; import nl.tudelft.cse1110.andy.config.DirectoryConfiguration; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.execution.ExecutionStep; import nl.tudelft.cse1110.andy.execution.mode.Action; import nl.tudelft.cse1110.andy.execution.step.*; diff --git a/andy/src/test/java/integration/IntegrationTestBase.java b/andy/src/test/java/integration/IntegrationTestBase.java index 27cfb6aa..64ad5c79 100644 --- a/andy/src/test/java/integration/IntegrationTestBase.java +++ b/andy/src/test/java/integration/IntegrationTestBase.java @@ -1,9 +1,11 @@ package integration; import com.google.common.io.Files; -import nl.tudelft.cse1110.andy.execution.Context; -import nl.tudelft.cse1110.andy.execution.ExecutionFlow; -import nl.tudelft.cse1110.andy.execution.ExecutionStep; +import nl.tudelft.cse1110.andy.config.DirectoryConfiguration; +import nl.tudelft.cse1110.andy.execution.*; +import nl.tudelft.cse1110.andy.execution.Context.Context; +import nl.tudelft.cse1110.andy.execution.Context.ContextBuilder; +import nl.tudelft.cse1110.andy.execution.Context.ContextDirector; import nl.tudelft.cse1110.andy.execution.mode.Action; import nl.tudelft.cse1110.andy.result.Result; import nl.tudelft.cse1110.andy.utils.FilesUtils; @@ -41,7 +43,12 @@ public Result run(Action action, copyFiles(libraryFile, solutionFile); - this.ctx = Context.build(action, workDir.toString(), reportDir.toString()); + ContextDirector director = new ContextDirector(new ContextBuilder()); + this.ctx = director.constructBase( + action, + new DirectoryConfiguration(workDir.toString(), reportDir.toString()) + ); + ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); try { diff --git a/andy/src/test/java/integration/JUnitTestsTest.java b/andy/src/test/java/integration/JUnitTestsTest.java index 3e07e86e..641f4283 100644 --- a/andy/src/test/java/integration/JUnitTestsTest.java +++ b/andy/src/test/java/integration/JUnitTestsTest.java @@ -1,7 +1,7 @@ package integration; import nl.tudelft.cse1110.andy.config.DirectoryConfiguration; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.execution.mode.Action; import nl.tudelft.cse1110.andy.result.Result; import nl.tudelft.cse1110.andy.result.UnitTestsResult; diff --git a/andy/src/test/java/integration/JacocoTest.java b/andy/src/test/java/integration/JacocoTest.java index 039295fb..399cad44 100644 --- a/andy/src/test/java/integration/JacocoTest.java +++ b/andy/src/test/java/integration/JacocoTest.java @@ -65,7 +65,7 @@ void nestedClassesInLibrary() { assertThat(result.getCoverage().getCoveredBranches()).isEqualTo(14); } - @ParameterizedTest + @ParameterizedTest(name = "[{index}] coveredAndUncoveredLines") @MethodSource("coveredLinesGenerator") void coveredAndUncoveredLines(String library, String solution, List coveredLines, List partiallyCovered, List notCovered) { Result result = run(Action.TESTS, library, solution); diff --git a/andy/src/test/java/unit/codechecker/checks/ClassUsedInSolutionTest.java b/andy/src/test/java/unit/codechecker/checks/ClassUsedInSolutionTest.java new file mode 100644 index 00000000..a6edd064 --- /dev/null +++ b/andy/src/test/java/unit/codechecker/checks/ClassUsedInSolutionTest.java @@ -0,0 +1,27 @@ +package unit.codechecker.checks; + +import nl.tudelft.cse1110.andy.codechecker.checks.Check; +import nl.tudelft.cse1110.andy.codechecker.checks.ClassUsedInSolution; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ClassUsedInSolutionTest extends ChecksBaseTest { + + @ParameterizedTest + @CsvSource(value={ + "SomeStaticClass, true", + "SomeClass, true", + "SomeUselessClass, true", + "Math, true", + "CreatedOutside, true", + "NeverSeenClass, false" + }) + void classUsesInTestMethod(String className, boolean expectation) { + Check check = new ClassUsedInSolution(className); + run("ClassUsed.java", check); + assertThat(check.result()).isEqualTo(expectation); + } +} + diff --git a/andy/src/test/java/unit/codechecker/checks/MethodCalledAnywhereTest.java b/andy/src/test/java/unit/codechecker/checks/MethodCalledAnywhereTest.java new file mode 100644 index 00000000..dd940628 --- /dev/null +++ b/andy/src/test/java/unit/codechecker/checks/MethodCalledAnywhereTest.java @@ -0,0 +1,35 @@ +package unit.codechecker.checks; + +import nl.tudelft.cse1110.andy.codechecker.checks.Check; +import nl.tudelft.cse1110.andy.codechecker.checks.MethodCalledAnywhere; +import nl.tudelft.cse1110.andy.codechecker.checks.MethodCalledInTestMethod; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import static org.assertj.core.api.Assertions.assertThat; + +public class MethodCalledAnywhereTest extends ChecksBaseTest { + + @ParameterizedTest + @CsvSource(value={ + "update, true", + "save, true", + "persist, true", + "retrieve, true", + "ceil, false", + }) + void methodInvocationsInTestMethod(String methodName, boolean expectation) { + Check check = new MethodCalledAnywhere(methodName); + run("MethodCalled.java", check); + assertThat(check.result()).isEqualTo(expectation); + } + + @Test + void shouldIgnoreAnonymousClasses() { // was breaking in midterm 2021 + Check check = new MethodCalledInTestMethod("getPoints"); + run("StackOverflowTestWithAnonymousClass.java", check); + assertThat(check.result()).isTrue(); + } + +} diff --git a/andy/src/test/java/unit/codechecker/engine/AndCheckTest.java b/andy/src/test/java/unit/codechecker/engine/AndCheckTest.java index cc9a2778..7199e78e 100644 --- a/andy/src/test/java/unit/codechecker/engine/AndCheckTest.java +++ b/andy/src/test/java/unit/codechecker/engine/AndCheckTest.java @@ -52,6 +52,7 @@ void runCheckRunsAllChecks() { verify(check2).runCheck(unit); } + @SuppressWarnings("SelfEquals") @Test void testSameObjectEquals() { diff --git a/andy/src/test/java/unit/execution/Context/ContextDirectorTest.java b/andy/src/test/java/unit/execution/Context/ContextDirectorTest.java new file mode 100644 index 00000000..04475a4d --- /dev/null +++ b/andy/src/test/java/unit/execution/Context/ContextDirectorTest.java @@ -0,0 +1,95 @@ +package unit.execution.Context; + +import nl.tudelft.cse1110.andy.config.DirectoryConfiguration; +import nl.tudelft.cse1110.andy.execution.Context.Context; +import nl.tudelft.cse1110.andy.execution.Context.ContextBuilder; +import nl.tudelft.cse1110.andy.execution.Context.ContextDirector; +import nl.tudelft.cse1110.andy.execution.mode.Action; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class ContextDirectorTest { + + private static ClassLoader classLoader; + private static DirectoryConfiguration directoryConfiguration; + private static Action action; + private static List librariesToBeIncludedInCompilation; + + @BeforeAll + public static void initializeParameters() { + classLoader = Thread.currentThread().getContextClassLoader(); + directoryConfiguration = new DirectoryConfiguration("working", "reports"); + action = Action.META_TEST; + librariesToBeIncludedInCompilation = List.of("library1", "library2"); + } + + @Test + void constructBase() { + ContextBuilder builder = new ContextBuilder(); + ContextDirector director = new ContextDirector(builder); + Context context = director.constructBase(action, directoryConfiguration); + + boolean hasBaseContextProperties = isBaseContext(context); + boolean restIsNull = restIsNull(context); + + assertThat(hasBaseContextProperties).isTrue(); + assertThat(context.getLibrariesToBeIncludedInCompilation()).isNull(); + assertThat(restIsNull).isTrue(); + } + + @Test + void constructWithLibraries() { + ContextBuilder builder = new ContextBuilder(); + ContextDirector director = new ContextDirector(builder); + Context context = director.constructWithLibraries(action, directoryConfiguration, + librariesToBeIncludedInCompilation); + + boolean hasBaseContextProperties = isBaseContext(context); + boolean restIsNull = restIsNull(context); + + assertThat(hasBaseContextProperties).isTrue(); + assertThat(context.getLibrariesToBeIncludedInCompilation()).isEqualTo(librariesToBeIncludedInCompilation); + assertThat(restIsNull).isTrue(); + + } + + + @Test + void constructWithLibrariesAndClassLoader() { + ContextBuilder builder = new ContextBuilder(); + ContextDirector director = new ContextDirector(builder); + Context context = director.constructWithLibraries(action, directoryConfiguration, + librariesToBeIncludedInCompilation); + + boolean hasBaseContextProperties = isBaseContext(context); + boolean restIsNull = restIsNull(context); + + assertThat(hasBaseContextProperties).isTrue(); + assertThat(context.getCleanClassloader()).isEqualTo(classLoader); + assertThat(context.getLibrariesToBeIncludedInCompilation()).isEqualTo(librariesToBeIncludedInCompilation); + assertThat(restIsNull).isTrue(); + + } + + private static boolean isBaseContext(Context context) { + return context != null + && context.getAction().equals(action) + && context.getDirectoryConfiguration().getWorkingDir().equals(directoryConfiguration.getWorkingDir()) + && context.getDirectoryConfiguration().getOutputDir().equals(directoryConfiguration.getOutputDir()) + && context.getCleanClassloader() != null + && context.getExternalProcess() != null; + } + + private static boolean restIsNull(Context context) { + return context.getFlow() == null + && context.getRunConfiguration() == null + && context.getNewClassNames() == null + && context.getClassloaderWithStudentsCode() == null + && context.getJacocoData() == null + && context.getJacocoRuntime() == null; + } +} \ No newline at end of file diff --git a/andy/src/test/java/unit/execution/metatest/LibraryMetaTestTest.java b/andy/src/test/java/unit/execution/metatest/LibraryMetaTestTest.java index 931d8ad1..55e243b4 100644 --- a/andy/src/test/java/unit/execution/metatest/LibraryMetaTestTest.java +++ b/andy/src/test/java/unit/execution/metatest/LibraryMetaTestTest.java @@ -14,7 +14,7 @@ public class LibraryMetaTestTest { - @ParameterizedTest + @ParameterizedTest(name = "[{index}] insertInLine") @MethodSource("insertInLineGenerator") void insertInLine(String oldCode, int lineToInsert, String contentToAdd, String expectedResult) { LibraryMetaTest metaTest = (LibraryMetaTest) MetaTest.insertAt("some meta test", lineToInsert, contentToAdd); @@ -66,7 +66,7 @@ static Stream insertInLineGenerator() { ); } - @ParameterizedTest + @ParameterizedTest(name = "[{index}] withLineReplacement") @MethodSource("withLineReplacementGenerator") void withLineReplacement(String oldCode, int start, int end, String replacement, String expectedResult) { LibraryMetaTest metaTest = (LibraryMetaTest) MetaTest.withLineReplacement("some meta test", start,end, replacement); @@ -112,7 +112,7 @@ static Stream withLineReplacementGenerator() { ); } - @ParameterizedTest + @ParameterizedTest(name = "[{index}] withStringReplacement") @MethodSource("withStringReplacementGenerator") void withStringReplacement(String oldCode, String old, String replacement, String expectedResult) { LibraryMetaTest metaTest = (LibraryMetaTest) MetaTest.withStringReplacement("some meta test", old, replacement); diff --git a/andy/src/test/java/unit/utils/CodeSnippetUtilsTest.java b/andy/src/test/java/unit/utils/CodeSnippetUtilsTest.java index de85b645..81ff9f3f 100644 --- a/andy/src/test/java/unit/utils/CodeSnippetUtilsTest.java +++ b/andy/src/test/java/unit/utils/CodeSnippetUtilsTest.java @@ -12,7 +12,7 @@ public class CodeSnippetUtilsTest { - @ParameterizedTest + @ParameterizedTest(name = "[{index}] generateCodeSnippetSimple") @MethodSource("generator") void generateCodeSnippetSimple(List lines, int lineNumber, String expected) { String actual = CodeSnippetUtils.generateCodeSnippet(lines, lineNumber); diff --git a/andy/src/test/java/unit/writer/standard/StandardResultWriterTest.java b/andy/src/test/java/unit/writer/standard/StandardResultWriterTest.java index c9a34ff5..60d50647 100644 --- a/andy/src/test/java/unit/writer/standard/StandardResultWriterTest.java +++ b/andy/src/test/java/unit/writer/standard/StandardResultWriterTest.java @@ -1,7 +1,7 @@ package unit.writer.standard; import nl.tudelft.cse1110.andy.config.DirectoryConfiguration; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.execution.mode.Action; import nl.tudelft.cse1110.andy.execution.mode.Mode; import nl.tudelft.cse1110.andy.execution.mode.ModeActionSelector; diff --git a/andy/src/test/resources/codechecker/fixtures/ClassUsed.java b/andy/src/test/resources/codechecker/fixtures/ClassUsed.java new file mode 100644 index 00000000..c89a4c1f --- /dev/null +++ b/andy/src/test/resources/codechecker/fixtures/ClassUsed.java @@ -0,0 +1,80 @@ +package delft; + +import org.junit.jupiter.api.Test; + +public class ClassUsed { + /** + * Test for statically used classes + */ + @Test + void t1() { + int result = SomeStaticClass.retrieveStatically(); + assertThat(result).isEqualTo(9); + } + + /** + * Standard test + */ + @Test + void t2() { + SomeClass someClass = new SomeClass("someField"); + String result = someClass.retrieve(); + assertThat(result).isEqualTo("someField"); + } + + /** + * Test for checking a class that is just instantiated + */ + @Test + void t3() { + SomeUselessClass us = new SomeUselessClass(9); + } + + //Create a class outside of a method + CreatedOutside co = new CreatedOutside(2); + + /** + * Test for checking if a class declared outside of a test + * is recognized as used. + */ + @Test + void t4() { + co.getSomeInt(); + } + + // Example of a call to a method that is not a test + void t5() { + int rand = Math.random(); + } + + class SomeStaticClass{ + public static int retrieveStatically(){ + return 9; + } + } + + class SomeClass { + private String someField; + + public SomeRepo(String someField) { + this.someField = someField; + } + + public String retrieve(){ + return this.someField; + } + } + + class SomeUselessClass { + int uselessInt; + public SomeUselessClass(int uselessInt){ + this.uselessInt=uselessInt; + } + + int getUselessInt(){ + return this.uselessInt; + } + } + } + + diff --git a/assignments/sql-testing/employees/src/main/java/delft/Employees.java b/assignments/sql-testing/employees/src/main/java/delft/Employees.java index 01e7fb4d..2b58fcf1 100644 --- a/assignments/sql-testing/employees/src/main/java/delft/Employees.java +++ b/assignments/sql-testing/employees/src/main/java/delft/Employees.java @@ -163,6 +163,11 @@ public boolean equals(Object o) { location.equals(restaurant.location); } + @Override + public int hashCode() { + return Objects.hash(id, name, cuisine, rating, location); + } + @Override public String toString() { return "Restaurant{" + diff --git a/assignments/sql-testing/recipes/src/main/java/delft/Recipes.java b/assignments/sql-testing/recipes/src/main/java/delft/Recipes.java index f1bb19d8..73299117 100644 --- a/assignments/sql-testing/recipes/src/main/java/delft/Recipes.java +++ b/assignments/sql-testing/recipes/src/main/java/delft/Recipes.java @@ -42,6 +42,11 @@ public boolean equals(Object o) { name.equals(recipe.name); } + @Override + public int hashCode() { + return Objects.hash(id, name, prepTime, vegan, dessert, price); + } + @Override public String toString() { return "Recipe{" + diff --git a/assignments/sql-testing/restaurant/src/main/java/delft/Restaurant.java b/assignments/sql-testing/restaurant/src/main/java/delft/Restaurant.java index dec8d032..45f7800c 100644 --- a/assignments/sql-testing/restaurant/src/main/java/delft/Restaurant.java +++ b/assignments/sql-testing/restaurant/src/main/java/delft/Restaurant.java @@ -148,6 +148,11 @@ public boolean equals(Object o) { name.equals(recipe.name); } + @Override + public int hashCode() { + return Objects.hash(name, prepTime, vegan, desert, price, id); + } + @Override public String toString() { return "Recipe{" + @@ -257,6 +262,11 @@ public boolean equals(Object o) { location.equals(restaurant.location); } + @Override + public int hashCode() { + return Objects.hash(id, name, cuisine, rating, location); + } + @Override public String toString() { return "Restaurant{" + diff --git a/assignments/stubs-fakes-and-mocks/editTripCapacity/config/Configuration.java b/assignments/stubs-fakes-and-mocks/editTripCapacity/config/Configuration.java index 3bdf64d1..be5dfb48 100644 --- a/assignments/stubs-fakes-and-mocks/editTripCapacity/config/Configuration.java +++ b/assignments/stubs-fakes-and-mocks/editTripCapacity/config/Configuration.java @@ -79,7 +79,7 @@ public List metaTests() { MetaTest.withStringReplacement("does not check update", "tRepository.update(trip, capacity);", ""), - MetaTest.withLineReplacement("does not check invalid tripId", 150, 158, + MetaTest.withLineReplacement("does not check invalid tripId", 156, 164, """ try { Trip trip = tRepository.getTripById(id); @@ -90,7 +90,7 @@ public List metaTests() { throw new RuntimeException("killed the mutant"); } """), - MetaTest.withLineReplacement("does not check capacity", 150, 158, + MetaTest.withLineReplacement("does not check capacity", 156, 164, """ try { Trip trip = tRepository.getTripById(id); diff --git a/assignments/stubs-fakes-and-mocks/editTripCapacity/src/main/java/delft/SoftWhere.java b/assignments/stubs-fakes-and-mocks/editTripCapacity/src/main/java/delft/SoftWhere.java index 1ef506bf..95212a7c 100644 --- a/assignments/stubs-fakes-and-mocks/editTripCapacity/src/main/java/delft/SoftWhere.java +++ b/assignments/stubs-fakes-and-mocks/editTripCapacity/src/main/java/delft/SoftWhere.java @@ -2,6 +2,7 @@ import java.time.LocalDate; import java.util.List; +import java.util.Objects; class ElementNotFoundException extends RuntimeException { } @@ -104,6 +105,11 @@ public boolean equals(Object o) { return false; return people != null ? people.equals(that.people) : that.people == null; } + + @Override + public int hashCode() { + return Objects.hash(code, trip, people); + } } interface ReservationRepository { diff --git a/assignments/stubs-fakes-and-mocks/gradeEmailService/config/Configuration.java b/assignments/stubs-fakes-and-mocks/gradeEmailService/config/Configuration.java index 387e6e82..fc74aa2f 100644 --- a/assignments/stubs-fakes-and-mocks/gradeEmailService/config/Configuration.java +++ b/assignments/stubs-fakes-and-mocks/gradeEmailService/config/Configuration.java @@ -52,37 +52,37 @@ public List metaTests() { return List.of( MetaTest.withLineReplacement( "does not check whether email is null", - 174, 181, + 182, 189, "emails.add(new GradeEmail(address, course, grades.get(student)));" ), MetaTest.withLineReplacement( "does not add non-sendable email errors", - 187, 190, + 195, 198, "" ), MetaTest.withLineReplacement( "does not include student number in error string", - 179, 179, + 187, 187, "\"\"" ), MetaTest.withLineReplacement( "does not add no matching email errors", - 177, 180, + 185, 188, "" ), MetaTest.withLineReplacement( "does not include email in error string", - 189, 189, + 197, 197, "e.getAddresses().stream().map(a -> \"\").collect(Collectors.toList())" ), MetaTest.withLineReplacement( "only executes loop once", - 181, 181, + 189, 189, "} break;" ), MetaTest.withLineReplacement( "zero iterations in the loop", - 165, 165, + 173, 173, "if(studentNumbers.isEmpty()) throw new RuntimeException();" ), MetaTest.withStringReplacement( diff --git a/assignments/stubs-fakes-and-mocks/gradeEmailService/src/main/java/delft/GradeEmailService.java b/assignments/stubs-fakes-and-mocks/gradeEmailService/src/main/java/delft/GradeEmailService.java index 9e8bfde8..3dd2d82a 100644 --- a/assignments/stubs-fakes-and-mocks/gradeEmailService/src/main/java/delft/GradeEmailService.java +++ b/assignments/stubs-fakes-and-mocks/gradeEmailService/src/main/java/delft/GradeEmailService.java @@ -32,6 +32,10 @@ public boolean equals(Object o) { return Objects.equals(domain, that.domain); } + @Override + public int hashCode() { + return Objects.hash(username, company, domain); + } } class GradeEmail { @@ -74,6 +78,10 @@ public boolean equals(Object o) { return Objects.equals(course, that.course); } + @Override + public int hashCode() { + return Objects.hash(recipient, course, grade); + } } class CouldNotSendAllEmailsException extends RuntimeException { diff --git a/assignments/stubs-fakes-and-mocks/invoiceFilter/config/Configuration.java b/assignments/stubs-fakes-and-mocks/invoiceFilter/config/Configuration.java index 73be3db5..910b7af4 100644 --- a/assignments/stubs-fakes-and-mocks/invoiceFilter/config/Configuration.java +++ b/assignments/stubs-fakes-and-mocks/invoiceFilter/config/Configuration.java @@ -52,7 +52,7 @@ public List metaTests() { MetaTest.withStringReplacement("change boundary", "return issuedInvoices.all().stream().filter(invoice -> invoice.getValue() < 100).collect(toList());", "return issuedInvoices.all().stream().filter(invoice -> invoice.getValue() <= 100).collect(toList());" ), - MetaTest.insertAt("at least two invoices used", 16, + MetaTest.insertAt("at least two invoices used", 17, """ if (issuedInvoices.all().size() >= 2) { throw new RuntimeException("killed the mutant"); diff --git a/assignments/stubs-fakes-and-mocks/invoiceFilter/src/main/java/delft/InvoiceFilter.java b/assignments/stubs-fakes-and-mocks/invoiceFilter/src/main/java/delft/InvoiceFilter.java index 3474bb9d..07296457 100644 --- a/assignments/stubs-fakes-and-mocks/invoiceFilter/src/main/java/delft/InvoiceFilter.java +++ b/assignments/stubs-fakes-and-mocks/invoiceFilter/src/main/java/delft/InvoiceFilter.java @@ -3,6 +3,7 @@ import static java.util.stream.Collectors.toList; import java.util.List; +import java.util.Objects; class InvoiceFilter { @@ -45,4 +46,9 @@ public boolean equals(Object o) { } return false; } + + @Override + public int hashCode() { + return Objects.hash(value); + } } diff --git a/assignments/stubs-fakes-and-mocks/makeReservation/config/Configuration.java b/assignments/stubs-fakes-and-mocks/makeReservation/config/Configuration.java index 96a8a6a9..468adab4 100644 --- a/assignments/stubs-fakes-and-mocks/makeReservation/config/Configuration.java +++ b/assignments/stubs-fakes-and-mocks/makeReservation/config/Configuration.java @@ -81,7 +81,7 @@ public List metaTests() { MetaTest.withStringReplacement("does not check save", "rRepository.save(new Reservation(trip, people));", ""), - MetaTest.withLineReplacement("does not check invalid trip Id", 150, 158, + MetaTest.withLineReplacement("does not check invalid trip Id", 156, 164, """ try { Trip trip = tRepository.getTripById(tripId); @@ -92,7 +92,7 @@ public List metaTests() { throw new RuntimeException("killed the mutant"); } """), - MetaTest.withLineReplacement("does not check capacity", 150, 158, + MetaTest.withLineReplacement("does not check capacity", 156, 164, """ try { Trip trip = tRepository.getTripById(tripId); diff --git a/assignments/stubs-fakes-and-mocks/makeReservation/src/main/java/delft/SoftWhere.java b/assignments/stubs-fakes-and-mocks/makeReservation/src/main/java/delft/SoftWhere.java index 5ad55774..7461c94b 100644 --- a/assignments/stubs-fakes-and-mocks/makeReservation/src/main/java/delft/SoftWhere.java +++ b/assignments/stubs-fakes-and-mocks/makeReservation/src/main/java/delft/SoftWhere.java @@ -2,6 +2,7 @@ import java.time.LocalDate; import java.util.List; +import java.util.Objects; class ElementNotFoundException extends RuntimeException { } @@ -104,6 +105,11 @@ public boolean equals(Object o) { return false; return people != null ? people.equals(that.people) : that.people == null; } + + @Override + public int hashCode() { + return Objects.hash(code, trip, people); + } } interface ReservationRepository { diff --git a/pom.xml b/pom.xml index df04918d..a75b69a5 100644 --- a/pom.xml +++ b/pom.xml @@ -48,6 +48,18 @@ 17 17 + + + -XDcompilePolicy=simple + -Xplugin:ErrorProne + + + + com.google.errorprone + error_prone_core + 2.20.0 + + @@ -73,6 +85,57 @@ + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.3.0 + + andy-checkstyle-checker.xml + false + + + + validate + validate + + check + + + + + + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.3.0 + + andy-checkstyle-checker.xml + + + + + checkstyle + + + + + + + org.apache.maven.plugins + maven-project-info-reports-plugin + 3.4.5 + + false + + + + + + \ No newline at end of file diff --git a/weblab-docker/Dockerfile b/weblab-docker/Dockerfile index d9e2576f..5ab8e05e 100644 --- a/weblab-docker/Dockerfile +++ b/weblab-docker/Dockerfile @@ -1,4 +1,4 @@ -FROM maven:3.6.3-openjdk-17-slim +FROM maven:3-amazoncorretto-17-debian WORKDIR /home/ @@ -17,20 +17,21 @@ RUN apt update \ SHELL ["/bin/bash", "-c"] ARG ANDY_DIR=/home/andy/ +ARG ANDY_REPO=SERG-Delft/andy ARG ANDY_BRANCH=main # Prevent Docker from using an old version of the branch from cache -ADD "https://api.github.com/repos/SERG-Delft/andy/commits/${ANDY_BRANCH}?per_page=1" latest_commit +ADD "https://api.github.com/repos/${ANDY_REPO}/commits/${ANDY_BRANCH}?per_page=1" latest_commit # Copy the full repo to the docker image -RUN git clone -n https://github.com/SERG-Delft/andy.git +RUN git clone -n https://github.com/${ANDY_REPO}.git andy # Checkout the current branch WORKDIR ${ANDY_DIR} RUN git checkout ${ANDY_BRANCH} # Compile and install all dependencies -RUN mvn package -pl weblab-runner -am -Djar.finalName=andy -DskipTests +RUN mvn package -pl weblab-runner -am -DskipTests ARG GNAME=student ARG GID=1000 @@ -45,7 +46,7 @@ COPY --chown=${UNAME} user_code/ ${UHOME} WORKDIR ${UHOME} # Move the compiled classes -RUN mv /home/andy/weblab-runner/target/andy.jar /home/andy.jar +RUN mv /home/andy/weblab-runner/target/weblab-runner-1.0.jar /home/andy.jar # Clean up RUN rm -rf /home/andy/ diff --git a/weblab-runner/src/main/java/nl/tudelft/cse1110/andy/AndyOnWebLab.java b/weblab-runner/src/main/java/nl/tudelft/cse1110/andy/AndyOnWebLab.java index e7613c5f..25a9886c 100644 --- a/weblab-runner/src/main/java/nl/tudelft/cse1110/andy/AndyOnWebLab.java +++ b/weblab-runner/src/main/java/nl/tudelft/cse1110/andy/AndyOnWebLab.java @@ -1,6 +1,9 @@ package nl.tudelft.cse1110.andy; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.config.DirectoryConfiguration; +import nl.tudelft.cse1110.andy.execution.Context.Context; +import nl.tudelft.cse1110.andy.execution.Context.ContextBuilder; +import nl.tudelft.cse1110.andy.execution.Context.ContextDirector; import nl.tudelft.cse1110.andy.execution.mode.Action; import nl.tudelft.cse1110.andy.result.Result; import nl.tudelft.cse1110.andy.writer.weblab.WebLabResultWriter; @@ -29,7 +32,12 @@ public static void main(String[] args) { private static void runAndy(String action, String workDir, String outputDir) { WebLabResultWriter writer = new WebLabResultWriter(); - Context ctx = Context.build(getAction(action), workDir, outputDir); + + ContextDirector director = new ContextDirector(new ContextBuilder()); + Context ctx = director.constructBase( + getAction(action), + new DirectoryConfiguration(workDir, outputDir) + ); try { Result result = new Andy().run(ctx); diff --git a/weblab-runner/src/main/java/nl/tudelft/cse1110/andy/writer/weblab/WebLabResultWriter.java b/weblab-runner/src/main/java/nl/tudelft/cse1110/andy/writer/weblab/WebLabResultWriter.java index 0c853056..047fce61 100644 --- a/weblab-runner/src/main/java/nl/tudelft/cse1110/andy/writer/weblab/WebLabResultWriter.java +++ b/weblab-runner/src/main/java/nl/tudelft/cse1110/andy/writer/weblab/WebLabResultWriter.java @@ -1,7 +1,7 @@ package nl.tudelft.cse1110.andy.writer.weblab; import com.google.gson.Gson; -import nl.tudelft.cse1110.andy.execution.Context; +import nl.tudelft.cse1110.andy.execution.Context.Context; import nl.tudelft.cse1110.andy.result.CompilationErrorInfo; import nl.tudelft.cse1110.andy.result.Result; import nl.tudelft.cse1110.andy.utils.FilesUtils;