From 2fc4919b9c90ec32d2ec8c8a1a0fcc9ce4ddb3de Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Sun, 23 Apr 2023 14:19:08 +0200 Subject: [PATCH 01/62] add maven_blackbox as project type --- .../de/tum/in/www1/artemis/domain/enumeration/ProjectType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/de/tum/in/www1/artemis/domain/enumeration/ProjectType.java b/src/main/java/de/tum/in/www1/artemis/domain/enumeration/ProjectType.java index f47cdc0545f4..c1b79b4dfc58 100644 --- a/src/main/java/de/tum/in/www1/artemis/domain/enumeration/ProjectType.java +++ b/src/main/java/de/tum/in/www1/artemis/domain/enumeration/ProjectType.java @@ -8,7 +8,7 @@ */ public enum ProjectType { - MAVEN_MAVEN, PLAIN_MAVEN, PLAIN, XCODE, FACT, GCC, PLAIN_GRADLE, GRADLE_GRADLE; + MAVEN_MAVEN, PLAIN_MAVEN, PLAIN, XCODE, FACT, GCC, PLAIN_GRADLE, GRADLE_GRADLE, MAVEN_BLACKBOX; public boolean isMaven() { return this == MAVEN_MAVEN || this == PLAIN_MAVEN; From 1bad098b6bf299495664d57ff1fcef12eaf702dd Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Sat, 6 May 2023 14:48:05 +0200 Subject: [PATCH 02/62] files --- .../ProgrammingLanguageConfiguration.java | 1 + .../ProgrammingExerciseRepositoryService.java | 20 +- src/main/resources/config/application.yml | 1 + .../java/maven_blackbox/exercise/pom.xml | 39 +++ .../src/${packageNameFolder}/Client.java | 32 +++ .../java/maven_blackbox/solution/pom.xml | 39 +++ .../src/${packageNameFolder}/BubbleSort.java | 26 ++ .../src/${packageNameFolder}/Client.java | 67 +++++ .../src/${packageNameFolder}/Context.java | 40 +++ .../src/${packageNameFolder}/MergeSort.java | 62 +++++ .../src/${packageNameFolder}/Policy.java | 30 +++ .../${packageNameFolder}/SortStrategy.java | 14 ++ .../${packageNameFolder}/input/Command.java | 13 + .../input/CommandParser.java | 70 ++++++ .../input/HelpMessageSupplier.java | 16 ++ .../input/InvalidCommandException.java | 20 ++ .../blackbox.projectTemplate/git.ignore.file | 198 +++++++++++++++ .../test/blackbox.projectTemplate/pom.xml | 229 ++++++++++++++++++ .../test/blackbox.projectTemplate/readme.md | 19 ++ 19 files changed, 932 insertions(+), 4 deletions(-) create mode 100644 src/main/resources/templates/java/maven_blackbox/exercise/pom.xml create mode 100644 src/main/resources/templates/java/maven_blackbox/exercise/src/${packageNameFolder}/Client.java create mode 100644 src/main/resources/templates/java/maven_blackbox/solution/pom.xml create mode 100755 src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/BubbleSort.java create mode 100644 src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java create mode 100755 src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java create mode 100755 src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/MergeSort.java create mode 100755 src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Policy.java create mode 100755 src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/SortStrategy.java create mode 100644 src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/Command.java create mode 100644 src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java create mode 100644 src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/HelpMessageSupplier.java create mode 100644 src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/InvalidCommandException.java create mode 100644 src/main/resources/templates/java/test/blackbox.projectTemplate/git.ignore.file create mode 100644 src/main/resources/templates/java/test/blackbox.projectTemplate/pom.xml create mode 100644 src/main/resources/templates/java/test/blackbox.projectTemplate/readme.md diff --git a/src/main/java/de/tum/in/www1/artemis/config/ProgrammingLanguageConfiguration.java b/src/main/java/de/tum/in/www1/artemis/config/ProgrammingLanguageConfiguration.java index dbf5c4cd88bf..9664eeb1970f 100644 --- a/src/main/java/de/tum/in/www1/artemis/config/ProgrammingLanguageConfiguration.java +++ b/src/main/java/de/tum/in/www1/artemis/config/ProgrammingLanguageConfiguration.java @@ -188,6 +188,7 @@ private ProjectType getConfiguredProjectType(final ProjectType actualProjectType case XCODE -> ProjectType.XCODE; case FACT -> ProjectType.FACT; case GCC -> ProjectType.GCC; + case MAVEN_BLACKBOX -> ProjectType.MAVEN_BLACKBOX; }; } diff --git a/src/main/java/de/tum/in/www1/artemis/service/programming/ProgrammingExerciseRepositoryService.java b/src/main/java/de/tum/in/www1/artemis/service/programming/ProgrammingExerciseRepositoryService.java index 5d383cd1c7b0..7892961da556 100644 --- a/src/main/java/de/tum/in/www1/artemis/service/programming/ProgrammingExerciseRepositoryService.java +++ b/src/main/java/de/tum/in/www1/artemis/service/programming/ProgrammingExerciseRepositoryService.java @@ -1,6 +1,7 @@ package de.tum.in.www1.artemis.service.programming; import static de.tum.in.www1.artemis.config.Constants.SETUP_COMMIT_MESSAGE; +import static de.tum.in.www1.artemis.domain.enumeration.ProjectType.isMavenProject; import java.io.FileNotFoundException; import java.io.IOException; @@ -295,11 +296,22 @@ private void setupJVMTestTemplateAndPush(final RepositoryResources resources, fi // Java both supports Gradle and Maven as a test template Path projectTemplatePath = templatePath; - if (projectType != null && projectType.isGradle()) { + /* + * if (projectType != null && projectType.isGradle()) { + * projectTemplatePath = projectTemplatePath.resolve("gradle"); + * } + * else { + * projectTemplatePath = projectTemplatePath.resolve("maven"); + * } + */ + if (isMavenProject(projectType)) { + projectTemplatePath = projectTemplatePath.resolve("maven"); + } + else if (projectType.isGradle()) { projectTemplatePath = projectTemplatePath.resolve("gradle"); } else { - projectTemplatePath = projectTemplatePath.resolve("maven"); + projectTemplatePath = projectTemplatePath.resolve("blackbox"); } projectTemplatePath = projectTemplatePath.resolve("projectTemplate"); @@ -452,7 +464,7 @@ private void setupTestTemplateSequentialTestRuns(final RepositoryResources resou sectionsMap.put("sequential", true); // maven configuration should be set for kotlin and older exercises where no project type has been introduced where no project type is defined - final boolean isMaven = ProjectType.isMavenProject(projectType); + final boolean isMaven = isMavenProject(projectType); final String projectFileName; if (isMaven) { @@ -524,7 +536,7 @@ private void setupBuildStage(final Path resourcePrefix, final Path templatePath, final Path packagePath = buildStagePath.toAbsolutePath().resolve(TEST_DIR).resolve(PACKAGE_NAME_FOLDER_PLACEHOLDER).toAbsolutePath(); // staging project files are only required for maven - final boolean isMaven = ProjectType.isMavenProject(projectType); + final boolean isMaven = isMavenProject(projectType); if (isMaven && stagePomXml.isPresent()) { Files.copy(stagePomXml.get().getInputStream(), buildStagePath.resolve(POM_XML)); } diff --git a/src/main/resources/config/application.yml b/src/main/resources/config/application.yml index ffdd255f3bef..4f667cb314fe 100644 --- a/src/main/resources/config/application.yml +++ b/src/main/resources/config/application.yml @@ -59,6 +59,7 @@ artemis: java: # possible overrides: maven, gradle default: "ls1tum/artemis-maven-template:java17-16" + maven_blackbox: "" kotlin: # possible overrides: maven, gradle default: "ls1tum/artemis-maven-template:java17-16" diff --git a/src/main/resources/templates/java/maven_blackbox/exercise/pom.xml b/src/main/resources/templates/java/maven_blackbox/exercise/pom.xml new file mode 100644 index 000000000000..adc393074c0d --- /dev/null +++ b/src/main/resources/templates/java/maven_blackbox/exercise/pom.xml @@ -0,0 +1,39 @@ + + 4.0.0 + ${packageName} + ${exerciseNamePomXml} + jar + 1.0 + ${exerciseNamePomXml} + + UTF-8 + + + + org.apache.commons + commons-lang3 + 3.12.0 + + + + ${project.basedir}/src + + + ${project.basedir}/resources + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.10.1 + + 17 + 17 + + + + + diff --git a/src/main/resources/templates/java/maven_blackbox/exercise/src/${packageNameFolder}/Client.java b/src/main/resources/templates/java/maven_blackbox/exercise/src/${packageNameFolder}/Client.java new file mode 100644 index 000000000000..2a46429dbc89 --- /dev/null +++ b/src/main/resources/templates/java/maven_blackbox/exercise/src/${packageNameFolder}/Client.java @@ -0,0 +1,32 @@ +package ${packageName}; + +import org.apache.commons.lang3.RandomUtils; + +import java.text.*; +import java.util.*; + +public final class Client { + + // TODO: Implement BubbleSort + // TODO: Implement MergeSort + + // TODO: Create a SortStrategy interface according to the UML class diagram + // TODO: Make the sorting algorithms implement this interface. + + // TODO: Create and implement a Context class according to the UML class diagram + // TODO: Create and implement a Policy class as described in the problem statement + + private Client() { + } + + /** + * Main method. + * Add code to demonstrate your implementation here. + * + * @param args command line arguments + */ + public static void main(String[] args) throws ParseException { + + } + } +} diff --git a/src/main/resources/templates/java/maven_blackbox/solution/pom.xml b/src/main/resources/templates/java/maven_blackbox/solution/pom.xml new file mode 100644 index 000000000000..cc9188f80be9 --- /dev/null +++ b/src/main/resources/templates/java/maven_blackbox/solution/pom.xml @@ -0,0 +1,39 @@ + + 4.0.0 + ${packageName} + ${exerciseNamePomXml}-Solution + jar + 1.0 + ${exerciseNamePomXml} Solution + + UTF-8 + + + + org.apache.commons + commons-lang3 + 3.12.0 + + + + ${project.basedir}/src + + + ${project.basedir}/resources + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.10.1 + + 17 + 17 + + + + + diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/BubbleSort.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/BubbleSort.java new file mode 100755 index 000000000000..f796c35e483f --- /dev/null +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/BubbleSort.java @@ -0,0 +1,26 @@ +package ${packageName}; + +import java.util.Date; +import java.util.List; + +public class BubbleSort implements SortStrategy { + + /** + * Sorts Dates with BubbleSort. + * + * @param input the List of Dates to be sorted. + */ + public void performSort(List input) { + + for (int i = input.size() - 1; i >= 0; i--) { + for (int j = 0; j < i; j++) { + if (input.get(j).compareTo(input.get(j + 1)) > 0) { + Date temp = input.get(j); + input.set(j, input.get(j + 1)); + input.set(j + 1, temp); + } + } + } + + } +} diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java new file mode 100644 index 000000000000..ff95c728e5f1 --- /dev/null +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java @@ -0,0 +1,67 @@ +import input.Command; +import input.CommandParser; +import input.HelpMessageSupplier; +import input.InvalidCommandException; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.function.Supplier; + +public class Client { + private static final String PROMPT = "sort> "; + private static final Context context = new Context(); + private static final Policy policy = new Policy(context); + private static final Supplier helpMessageSupplier = + new HelpMessageSupplier(); + + private Client() { + throw new IllegalCallerException("utility class"); + } + + public static void main(String[] args) throws IOException { + BufferedReader in + = new BufferedReader(new InputStreamReader(System.in)); + CommandRunResult commandRunResult = CommandRunResult.CONTINUE; + while (commandRunResult == CommandRunResult.CONTINUE) { + System.out.print(PROMPT); + try { + Command command = CommandParser.parseCommand(in.readLine()); + commandRunResult = runCommand(command); + } catch (InvalidCommandException invalidCommandException) { + System.out.println(invalidCommandException.getMessage()); + } + } + } + + private static CommandRunResult runCommand(final Command command) { + if (command instanceof Command.AddCommand addCommand) { + context.addValues(addCommand.values()); + } else if (command instanceof Command.SortCommand) { + policy.configure(); + context.sort(); + } else if (command instanceof Command.ClearCommand) { + context.clearValues(); + } else if (command instanceof Command.HelpCommand) { + System.out.println(helpMessageSupplier.get()); + } else if (command instanceof Command.PrintCommand) { + System.out.println(context.getDates()); + } + else if (command instanceof Command.QuitCommand) { + return CommandRunResult.QUIT; + } else { + // can never happen since all cases of the sealed interface are + // covered + // ToDo: refactor with Java 21 switch expression patterns when + // released to let the compiler check exhaustivity + throw new UnsupportedOperationException("Unknown command type."); + } + + return CommandRunResult.CONTINUE; + } + + private enum CommandRunResult { + CONTINUE, + QUIT + } +} diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java new file mode 100755 index 000000000000..54b0a7555195 --- /dev/null +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java @@ -0,0 +1,40 @@ +package ${packageName}; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +public class Context { + private SortStrategy sortAlgorithm; + + private final List dates = new ArrayList<>(); + + public List getDates() { + return dates; + } + + public void addValues(List values) { + this.dates.addAll(values); + } + + public void setSortAlgorithm(SortStrategy sa) { + sortAlgorithm = sa; + } + + public SortStrategy getSortAlgorithm() { + return sortAlgorithm; + } + + public void clearValues() { + this.dates.clear(); + } + + /** + * Runs the configured sort algorithm. + */ + public void sort() { + if (sortAlgorithm != null) { + sortAlgorithm.performSort(this.dates); + } + } +} diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/MergeSort.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/MergeSort.java new file mode 100755 index 000000000000..c8376d748b67 --- /dev/null +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/MergeSort.java @@ -0,0 +1,62 @@ +package ${packageName}; + +import java.util.Date; +import java.util.List; + +public class MergeSort implements SortStrategy { + + /** + * Wrapper method for the real MergeSort algorithm. + * + * @param input the List of double values to be sorted + */ + public void performSort(List input) { + mergesort(input, 0, input.size() - 1); + } + + /** + * Performs MergeSort. + */ + private void mergesort(List input, int low, int high) { + if (high - low < 1) { + return; + } + int mid = (low + high) / 2; + mergesort(input, low, mid); + mergesort(input, mid + 1, high); + merge(input, low, mid, high); + } + + /** + * Merges the Dates of the sub-lists. + */ + private void merge(List input, int low, int middle, int high) { + + Date[] temp = new Date[high - low + 1]; + int leftIndex = low; + int rightIndex = middle + 1; + int wholeIndex = 0; + while (leftIndex <= middle && rightIndex <= high) { + if (input.get(leftIndex).compareTo(input.get(rightIndex)) <= 0) { + temp[wholeIndex] = input.get(leftIndex++); + } + else { + temp[wholeIndex] = input.get(rightIndex++); + } + wholeIndex++; + } + if (leftIndex <= middle && rightIndex > high) { + while (leftIndex <= middle) { + temp[wholeIndex++] = input.get(leftIndex++); + } + } + else { + while (rightIndex <= high) { + temp[wholeIndex++] = input.get(rightIndex++); + } + } + for (wholeIndex = 0; wholeIndex < temp.length; wholeIndex++) { + input.set(wholeIndex + low, temp[wholeIndex]); + } + } +} diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Policy.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Policy.java new file mode 100755 index 000000000000..5f9aa6702975 --- /dev/null +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Policy.java @@ -0,0 +1,30 @@ +package ${packageName}; + +public class Policy { + + /** + * @oracleIgnore + */ + private static final int VALUES_SIZE_THRESHOLD = 10; + + private final Context context; + + public Policy(Context context) { + this.context = context; + } + + /** + * Chooses a strategy depending on the number of Dates. + */ + public void configure() { + if (this.context.getDates().size() > VALUES_SIZE_THRESHOLD) { + System.out.println("More than " + VALUES_SIZE_THRESHOLD + + " double values, choosing merge sort!"); + this.context.setSortAlgorithm(new MergeSort()); + } else { + System.out.println("Less or equal than " + VALUES_SIZE_THRESHOLD + + " double values, choosing quick sort!"); + this.context.setSortAlgorithm(new BubbleSort()); + } + } +} diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/SortStrategy.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/SortStrategy.java new file mode 100755 index 000000000000..71c01b5c1fe5 --- /dev/null +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/SortStrategy.java @@ -0,0 +1,14 @@ +package ${packageName}; + +import java.util.Date; +import java.util.List; + +public interface SortStrategy { + + /** + * Sorts a list of Dates. + * + * @param input The list of Dates to be sorted. + */ + void performSort(List input); +} diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/Command.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/Command.java new file mode 100644 index 000000000000..148faf36e304 --- /dev/null +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/Command.java @@ -0,0 +1,13 @@ +package ${packageName}.input; + +import java.util.Date; +import java.util.List; + +public sealed interface Command { + record AddCommand(List values) implements Command {} + record ClearCommand() implements Command {} + record HelpCommand() implements Command {} + record PrintCommand() implements Command {} + record QuitCommand() implements Command {} + record SortCommand() implements Command {} +} diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java new file mode 100644 index 000000000000..e661930948d7 --- /dev/null +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java @@ -0,0 +1,70 @@ +package ${packageName}.input; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; + +public class CommandParser { + private CommandParser() { + throw new IllegalCallerException("utility class"); + } + + public static Command parseCommand(final String inputLine) + throws InvalidCommandException { + final String[] args = inputLine.strip().split("\\s+"); + + if (args.length == 0) { + throw new InvalidCommandException( + "Expected a command. Use 'help' to show available commands." + ); + } + + final String commandVerb = args[0]; + return switch (commandVerb) { + case "add" -> parseAddCommand(args); + case "clear" -> new Command.ClearCommand(); + case "help" -> new Command.HelpCommand(); + case "print" -> new Command.PrintCommand(); + case "quit" -> new Command.QuitCommand(); + case "sort" -> new Command.SortCommand(); + default -> throw new InvalidCommandException( + "Unknown command. Use 'help' to show available commands." + ); + }; + } + + private static Command.AddCommand parseAddCommand(final String[] args) + throws InvalidCommandException { + if (args.length < 2) { + throw new UnsupportedOperationException( + "The 'add' command needs some values that can be added." + ); + } + + final List dates = new ArrayList<>(); + + for (int i = 1; i < args.length; ++i) { + final String arg = args[i]; + try { + final Date date = parseDateInput(arg); + dates.add(date); + } catch (ParseException e) { + throw new InvalidCommandException( + "Dates have to follow the format YYYY-MM-DD and must" + + " be valid." + ); + } + } + + return new Command.AddCommand(Collections.unmodifiableList(dates)); + } + + private static Date parseDateInput(String input) throws ParseException { + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + formatter.setLenient(false); + return formatter.parse(input); + } +} diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/HelpMessageSupplier.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/HelpMessageSupplier.java new file mode 100644 index 000000000000..77418b1018fb --- /dev/null +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/HelpMessageSupplier.java @@ -0,0 +1,16 @@ +package ${packageName}.input; + +import java.util.function.Supplier; + +public class HelpMessageSupplier implements Supplier { + @Override + public String get() { + return """ + add: adds the given Dates to the list (format: YYYY-MM-DD) + clear: empties the list + help: prints this text + print: prints the list + sort: sorts the list + quit: quits the program"""; + } +} diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/InvalidCommandException.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/InvalidCommandException.java new file mode 100644 index 000000000000..043f85fd7aca --- /dev/null +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/InvalidCommandException.java @@ -0,0 +1,20 @@ +package ${packageName}.input; + +import java.io.Serial; + +/** + * Error type to be used to signal that the user entered an invalid command. + */ +public class InvalidCommandException extends Exception { + @Serial + private static final long serialVersionUID = 1L; + + /** + * Builds a new exception that signals that an invalid command was entered. + * + * @param message A message that should be understandable for the user. + */ + public InvalidCommandException(final String message) { + super(message); + } +} diff --git a/src/main/resources/templates/java/test/blackbox.projectTemplate/git.ignore.file b/src/main/resources/templates/java/test/blackbox.projectTemplate/git.ignore.file new file mode 100644 index 000000000000..44c742ee253c --- /dev/null +++ b/src/main/resources/templates/java/test/blackbox.projectTemplate/git.ignore.file @@ -0,0 +1,198 @@ +assignment/ + +# Taken from https://github.com/github/gitignore + +### Java +# Compiled class file +*.class + +# Log file +*.log + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +### Eclipse +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# CDT- autotools +.autotools + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +# Annotation Processing +.apt_generated/ +.apt_generated_test/ + +### JetBrains +.idea + +# Gradle and Maven with auto-import +*.iml +*.ipr + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +### VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +# Local History for Visual Studio Code +.history/ + +# Built Visual Studio Code Extensions +*.vsix + +### Vim +# Swap +[._]*.s[a-v][a-z] +!*.svg # comment out if you don't need vector files +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim +Sessionx.vim + +# Temporary +.netrwhist +*~ +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ + +### MacOs +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### Windows +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +### Linux +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* diff --git a/src/main/resources/templates/java/test/blackbox.projectTemplate/pom.xml b/src/main/resources/templates/java/test/blackbox.projectTemplate/pom.xml new file mode 100644 index 000000000000..b6fc74356115 --- /dev/null +++ b/src/main/resources/templates/java/test/blackbox.projectTemplate/pom.xml @@ -0,0 +1,229 @@ + + 4.0.0 + ${packageName} + ${exerciseNamePomXml}-Tests + ${packaging} + 1.0 + ${exerciseName} Tests + + UTF-8 + -Dfile.encoding=UTF-8 + + ${project.basedir}/staticCodeAnalysisConfig + false + + + + + + de.tum.in.ase + artemis-java-test-sandbox + 1.11.3 + + + + ${project.basedir}${studentWorkingDirectory} + + ${project.basedir}/test + + + ${project.basedir}/test + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.10.1 + + 17 + 17 + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M9 + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.2.1 + + + enforce-no-student-code-in-trusted-packages + process-classes + + enforce + + + + + + + + ${project.build.outputDirectory}/ch/qos/logback/ + ${project.build.outputDirectory}/com/intellij/ + ${project.build.outputDirectory}/com/sun/ + ${project.build.outputDirectory}/de/tum/in/test/api/ + ${project.build.outputDirectory}/java/ + ${project.build.outputDirectory}/javax/ + ${project.build.outputDirectory}/jdk/ + ${project.build.outputDirectory}/net/jqwik/ + ${project.build.outputDirectory}/org/apache/ + ${project.build.outputDirectory}/org/assertj/ + ${project.build.outputDirectory}/org/eclipse/ + ${project.build.outputDirectory}/org/jacoco/ + ${project.build.outputDirectory}/org/json/ + ${project.build.outputDirectory}/org/junit/ + ${project.build.outputDirectory}/org/opentest4j/ + ${project.build.outputDirectory}/sun/ + ${project.build.outputDirectory}/org/gradle/ + ${project.build.outputDirectory}/worker/org/gradle/ + + ${project.build.outputDirectory}/com/squareup/ + ${project.build.outputDirectory}/com/teamscale/ + ${project.build.outputDirectory}/okhttp3/ + ${project.build.outputDirectory}/okio/ + ${project.build.outputDirectory}/retrofit2/ + ${project.build.outputDirectory}/shadow/ + + + + + + + + + com.github.spotbugs + spotbugs-maven-plugin + 4.7.3.0 + + + ${analyzeTests} + true + + ${scaConfigDirectory}/spotbugs-exclusions.xml + + + + Default + + Low + + + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.2.1 + + + com.puppycrawl.tools + checkstyle + 10.8.0 + + + + + ${analyzeTests} + + ${scaConfigDirectory}/checkstyle-configuration.xml + + false + + + + org.apache.maven.plugins + maven-pmd-plugin + 3.20.0 + + + net.sourceforge.pmd + pmd-core + 6.55.0 + + + net.sourceforge.pmd + pmd-java + 6.55.0 + + + + + ${analyzeTests} + + 5 + + + ${scaConfigDirectory}/pmd-configuration.xml + + + 60 + + true + + false + + + + + + + + + coverage + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M9 + + + okhttp3,com.teamscale,retrofit2,shadow,com.squareup,okio + + + + + com.teamscale + teamscale-surefire-provider + 29.1.2 + + + + + com.teamscale + teamscale-maven-plugin + 29.1.2 + + http://localhost + dummy + ${exerciseNamePomXml}-Tests + dummy + testwise + + *${packageName}* + + + + + + prepare-tia-unit-test + + + + + + + + + + diff --git a/src/main/resources/templates/java/test/blackbox.projectTemplate/readme.md b/src/main/resources/templates/java/test/blackbox.projectTemplate/readme.md new file mode 100644 index 000000000000..4dd021d52f19 --- /dev/null +++ b/src/main/resources/templates/java/test/blackbox.projectTemplate/readme.md @@ -0,0 +1,19 @@ +## Test Repository instructions + +#### Test tool & command +Tests will be run using the command maven clean test. + +#### Project structure +Make sure that the package structure of your test classes is equivalent to the package structure of your base and solution repository. +Otherwise during the test run maven will not be able to find the imported classes in your test files. + +#### Sequential test runs +If you have decided to use the sequential test runs feature for this exercise, read the following instructions: +We use the folder structure of the test repository to differentiate structural and behavior tests: +1. Structural test files must be placed in the folder "structural" +2. Behavior test files must be placed in the folder "behavior" + +Files in other folders will not be executed! + +#### Static Code Analysis +The pom.xml contains dependencies for the execution of static code analysis, if the option is active for this programming exercise. From 4e021f82cacac5c37cfd6ceb85cf7cefbaa8ccd3 Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Sun, 7 May 2023 14:29:26 +0200 Subject: [PATCH 03/62] more files --- .../src/${packageNameFolder}/Client.java | 19 +- .../${packageNameFolder}/input/Command.java | 2 +- .../input/CommandParser.java | 12 +- .../input/HelpMessageSupplier.java | 16 - .../{ => model}/BubbleSort.java | 2 +- .../{ => model}/Context.java | 4 +- .../{ => model}/MergeSort.java | 2 +- .../{ => model}/Policy.java | 2 +- .../{ => model}/SortStrategy.java | 2 +- .../${packageNameFolder}.tests/advanced.exp | 14 + .../${packageNameFolder}.tests/public.exp | 9 + .../${packageNameFolder}.tests/secret.exp | 11 + .../dejagnu/config/default.exp | 402 ++++++++++++++++++ .../dejagnu/testfiles/public/.gitkeep | 0 .../dejagnu/testfiles/secret/.gitkeep | 0 15 files changed, 462 insertions(+), 35 deletions(-) delete mode 100644 src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/HelpMessageSupplier.java rename src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/{ => model}/BubbleSort.java (95%) rename src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/{ => model}/Context.java (89%) rename src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/{ => model}/MergeSort.java (98%) rename src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/{ => model}/Policy.java (96%) rename src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/{ => model}/SortStrategy.java (88%) create mode 100644 src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/${packageNameFolder}.tests/advanced.exp create mode 100644 src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/${packageNameFolder}.tests/public.exp create mode 100644 src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/${packageNameFolder}.tests/secret.exp create mode 100644 src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/config/default.exp create mode 100644 src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/testfiles/public/.gitkeep create mode 100644 src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/testfiles/secret/.gitkeep diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java index ff95c728e5f1..1c1c341178c3 100644 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java @@ -1,19 +1,16 @@ -import input.Command; -import input.CommandParser; -import input.HelpMessageSupplier; -import input.InvalidCommandException; +import ${packageName}.input.Command; +import ${packageName}.input.CommandParser; +import ${packageName}.input.InvalidCommandException; +import ${packageName}.sorting.model.Context; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; -import java.util.function.Supplier; public class Client { private static final String PROMPT = "sort> "; private static final Context context = new Context(); - private static final Policy policy = new Policy(context); - private static final Supplier helpMessageSupplier = - new HelpMessageSupplier(); + // private static final Policy policy = new Policy(context); private Client() { throw new IllegalCallerException("utility class"); @@ -38,12 +35,12 @@ private static CommandRunResult runCommand(final Command command) { if (command instanceof Command.AddCommand addCommand) { context.addValues(addCommand.values()); } else if (command instanceof Command.SortCommand) { - policy.configure(); + // policy.configure(); context.sort(); } else if (command instanceof Command.ClearCommand) { context.clearValues(); - } else if (command instanceof Command.HelpCommand) { - System.out.println(helpMessageSupplier.get()); + } else if (command instanceof Command.HelpCommand helpCommand()) { + System.out.println(helpCommand.helpMessage()); } else if (command instanceof Command.PrintCommand) { System.out.println(context.getDates()); } diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/Command.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/Command.java index 148faf36e304..ccf0ca40cd8e 100644 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/Command.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/Command.java @@ -6,7 +6,7 @@ public sealed interface Command { record AddCommand(List values) implements Command {} record ClearCommand() implements Command {} - record HelpCommand() implements Command {} + record HelpCommand(String helpMessage) implements Command {} record PrintCommand() implements Command {} record QuitCommand() implements Command {} record SortCommand() implements Command {} diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java index e661930948d7..718fdedd722b 100644 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java @@ -8,6 +8,16 @@ import java.util.List; public class CommandParser { + + private static final String HELP_MESSAGE = + """ + add: adds the given Dates to the list (format: YYYY-MM-DD) + clear: empties the list + help: prints this text + print: prints the list + sort: sorts the list + quit: quits the program"""; + private CommandParser() { throw new IllegalCallerException("utility class"); } @@ -26,7 +36,7 @@ public static Command parseCommand(final String inputLine) return switch (commandVerb) { case "add" -> parseAddCommand(args); case "clear" -> new Command.ClearCommand(); - case "help" -> new Command.HelpCommand(); + case "help" -> new Command.HelpCommand(HELP_MESSAGE); case "print" -> new Command.PrintCommand(); case "quit" -> new Command.QuitCommand(); case "sort" -> new Command.SortCommand(); diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/HelpMessageSupplier.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/HelpMessageSupplier.java deleted file mode 100644 index 77418b1018fb..000000000000 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/HelpMessageSupplier.java +++ /dev/null @@ -1,16 +0,0 @@ -package ${packageName}.input; - -import java.util.function.Supplier; - -public class HelpMessageSupplier implements Supplier { - @Override - public String get() { - return """ - add: adds the given Dates to the list (format: YYYY-MM-DD) - clear: empties the list - help: prints this text - print: prints the list - sort: sorts the list - quit: quits the program"""; - } -} diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/BubbleSort.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/BubbleSort.java similarity index 95% rename from src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/BubbleSort.java rename to src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/BubbleSort.java index f796c35e483f..f363402df44f 100755 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/BubbleSort.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/BubbleSort.java @@ -1,4 +1,4 @@ -package ${packageName}; +package ${packageName}.model; import java.util.Date; import java.util.List; diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/Context.java similarity index 89% rename from src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java rename to src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/Context.java index 54b0a7555195..b09c69d77208 100755 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/Context.java @@ -1,11 +1,11 @@ -package ${packageName}; +package ${packageName}.model; import java.util.ArrayList; import java.util.Date; import java.util.List; public class Context { - private SortStrategy sortAlgorithm; + private SortStrategy sortAlgorithm = new MergeSort(); private final List dates = new ArrayList<>(); diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/MergeSort.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/MergeSort.java similarity index 98% rename from src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/MergeSort.java rename to src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/MergeSort.java index c8376d748b67..c641d8373d51 100755 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/MergeSort.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/MergeSort.java @@ -1,4 +1,4 @@ -package ${packageName}; +package ${packageName}.model; import java.util.Date; import java.util.List; diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Policy.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/Policy.java similarity index 96% rename from src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Policy.java rename to src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/Policy.java index 5f9aa6702975..08454c446b9d 100755 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Policy.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/Policy.java @@ -1,4 +1,4 @@ -package ${packageName}; +package ${packageName}.model; public class Policy { diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/SortStrategy.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/SortStrategy.java similarity index 88% rename from src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/SortStrategy.java rename to src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/SortStrategy.java index 71c01b5c1fe5..c1455f087096 100755 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/SortStrategy.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/SortStrategy.java @@ -1,4 +1,4 @@ -package ${packageName}; +package ${packageName}.model; import java.util.Date; import java.util.List; diff --git a/src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/${packageNameFolder}.tests/advanced.exp b/src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/${packageNameFolder}.tests/advanced.exp new file mode 100644 index 000000000000..488e4cd6b135 --- /dev/null +++ b/src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/${packageNameFolder}.tests/advanced.exp @@ -0,0 +1,14 @@ +# Sorting Testdata + +# Non-Public Tests +PROGRAM_test {add 2020-03-31} {} +PROGRAM_test {add 2020-03-30} {} +PROGRAM_test {add 2020-04-01} {} +PROGRAM_test {print} {[Tue Mar 31 00:00:00 CEST 2020, Mon Mar 30 00:00:00 CEST 2020, Wed Apr 01 00:00:00 CEST 2020]} +PROGRAM_test {sort} {} +PROGRAM_test {print} {[Mon Mar 30 00:00:00 CEST 2020, Tue Mar 31 00:00:00 CEST 2020, Wed Apr 01 00:00:00 CEST 2020]} + +PROGRAM_test {add 2020-01-31} {} +PROGRAM_test {print} {[Mon Mar 30 00:00:00 CEST 2020, Tue Mar 31 00:00:00 CEST 2020, Wed Apr 01 00:00:00 CEST 2020, Fri Jan 31 00:00:00 CET 2020]} +PROGRAM_test {sort} {} +PROGRAM_test {print} {[Fri Jan 31 00:00:00 CET 2020, Mon Mar 30 00:00:00 CEST 2020, Tue Mar 31 00:00:00 CEST 2020, Wed Apr 01 00:00:00 CEST 2020]} diff --git a/src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/${packageNameFolder}.tests/public.exp b/src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/${packageNameFolder}.tests/public.exp new file mode 100644 index 000000000000..6430298416dc --- /dev/null +++ b/src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/${packageNameFolder}.tests/public.exp @@ -0,0 +1,9 @@ +# Sorting Testdata + +# Secret Tests +PROGRAM_test {add 2020-03-31} {} +PROGRAM_test {add 2020-03-30} {} +PROGRAM_test {add 2020-04-01} {} +PROGRAM_test {print} {[Tue Mar 31 00:00:00 CEST 2020, Mon Mar 30 00:00:00 CEST 2020, Wed Apr 01 00:00:00 CEST 2020]} +PROGRAM_test {sort} {} +PROGRAM_test {print} {[Mon Mar 30 00:00:00 CEST 2020, Tue Mar 31 00:00:00 CEST 2020, Wed Apr 01 00:00:00 CEST 2020]} diff --git a/src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/${packageNameFolder}.tests/secret.exp b/src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/${packageNameFolder}.tests/secret.exp new file mode 100644 index 000000000000..f6b28589d9d1 --- /dev/null +++ b/src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/${packageNameFolder}.tests/secret.exp @@ -0,0 +1,11 @@ +# Sorting Testdata + +# Public Tests +PROGRAM_test {print} {} {[]} +PROGRAM_test {add 2020-03-31} {} +PROGRAM_test {add 2020-03-30} {} +PROGRAM_test {add 2020-04-01} {} +PROGRAM_test {print} {[Tue Mar 31 00:00:00 CEST 2020, Mon Mar 30 00:00:00 CEST 2020, Wed Apr 01 00:00:00 CEST 2020]} + +PROGRAM_test {clear} {[]} +PROGRAM_test {print} {} {[]} diff --git a/src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/config/default.exp b/src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/config/default.exp new file mode 100644 index 000000000000..795e2e36d658 --- /dev/null +++ b/src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/config/default.exp @@ -0,0 +1,402 @@ +# Set timeout, prompt, etc. +# Please adapt this. +set standard_timeout 15 +set startup_timeout 5 +set prompt "sort> " +set answer "" +set exit_cmd "quit" + +# Don't change this +set timeout $standard_timeout +# If we haven't read the right prompt in PROGRAM_start, it doesn't +# make sense to do any other test. +set prompt_error 0 + +# Load a program +proc PROGRAM_load { arg } { + # +} + +# Start program and wait for prompt +proc PROGRAM_start {} { + # it is impossible to use or in start :-( + global standard_timeout + global startup_timeout + global timeout + global prompt + global spawn_id + global prompt_error + + # Startup of the java engine needs to much time. + set timeout $startup_timeout + spawn "java" -cp CLASSPATH "MAIN_CLASS" + + # Check for prompt + expect { + "$prompt" { } + timeout { + set prompt_error 1 + send_user "\nFAIL: start " + send_user "(timeout with no prompt, expected \"$prompt\")\n"; + } + eof { + set prompt_error 1 + send_user "\nFAIL: start " + send_user "(no prompt, expected \"$prompt\")\n" + } + } + set timeout $standard_timeout +} + +# End program +proc PROGRAM_exit {} { + global exit_cmd + global prompt_error + + # Don't continue if we haven't read the right prompt + if $prompt_error { + return + } + + if [catch {send "$exit_cmd\n"}] { + send_user "\n" + fail "could not send text, is the program running?" + return + } + + expect "$exit_cmd\r\n" + + expect { + eof { pass "$exit_cmd" } + -re "." { + send_user "\n" + fail "$exit_cmd (expected end-of-output)" + } + } +} + +# Return version +proc PROGRAM_version {} { + return "unknown" +} + +# Functions to just enter data without expecting answers or errors. +# +# There are two variants: +# 1. ..._enter just expects the data to send +# 2. ..._enter_c has an additional argument: a comment that is printed +# on succes or failure. +# +proc PROGRAM_enter {expr} { + PROGRAM_enter_ "$expr" "" +} + +proc PROGRAM_enter_c {expr comment} { + PROGRAM_enter_ "$expr" "\[$comment\]" +} + +proc PROGRAM_enter_ {expr comment} { + global prompt + global prompt_error + + # Don't continue if we haven't read the right prompt + if $prompt_error { + return + } + + # Quote the command + regsub -all {[].$^()*+?|[]} $expr {\\&} cmd + + # Send expression and wait for echo + if [catch {send -- "$expr\n"}] { + fail "could not send text, is the program running? $comment" + return + } + + # Check result + expect { + -re "$expr\[\r\n\]+$prompt" { + pass "$expr $comment" + } + -re "\[:\].*\[\r\n\]+$prompt" { + fail "$expr (got answer, but none expected) $comment" + } + -re "\[!\].*\[\r\n\]+$prompt" { + send_user "\n" + fail "$expr (got error, but none expected) $comment" + } + -ex "$prompt" { + send_user "\n" + fail "$expr (expected nothing) $comment" + } + timeout { + send_user "\n" + fail "$expr (timeout with no prompt, expected \"$prompt\") $comment"; + expect "$prompt" + } + } +} + +# Own functions +proc PROGRAM_ignore {expr} { + PROGRAM_ignore_ "$expr" "" +} + +proc PROGRAM_ignore_c {expr comment} { + PROGRAM_ignore_ "$expr" "\[$comment\]" +} + +proc PROGRAM_ignore_ {expr comment} { + global prompt + global prompt_error + + # Don't continue if we haven't read the right prompt + if $prompt_error { + return + } + + # Send expression and wait for echo + if [catch {send -- "$expr\n"}] { + send_user "\n" + fail "could not send text, is the program running? $comment" + return + } + + # Check result + expect { + -ex "$prompt" { + pass "$expr" + } + timeout { + send_user "\n" + fail "$expr (timeout with no prompt, expected \"$prompt\") $comment"; + } + } +} + +# Own functions +proc PROGRAM_test {expr result} { + PROGRAM_test_ "$expr" "$result" "" +} + +proc PROGRAM_test_c {expr result comment} { + PROGRAM_test_ "$expr" "$result" "\[$comment\]" +} + +proc PROGRAM_test_ {expr result comment} { + global prompt + global answer + global prompt_error + + # Don't continue if we haven't read the right prompt + if $prompt_error { + return + } + + # Send expression and wait for echo + if [catch {send -- "$expr\n"}] { + send_user "\n" + fail "could not send text, is the program running? $comment" + return + } + + # Quote the expected result + regsub -all {[].$^()*+?|[]} $result {\\&} quoted + # Quote the command + regsub -all {[].$^()*+?|[]} $expr {\\&} cmd + + # Check result + expect { + -re "$cmd\[\r\n \]+$answer *$quoted\[ \r\n\]+$prompt" { + pass "$expr $comment" + } + -re "\[:\].*\[\r\n\]+$prompt" { + fail "$expr (got wrong answer, expected \"$result\") $comment" + } + -re "\[!\].*\[\r\n\]+$prompt" { + send_user "\n" + fail "$expr (got error, but expected \"$result\") $comment" + } + -ex "$prompt" { + send_user "\n" + fail "$expr (expected \"$result\") $comment" + } + timeout { + send_user "\n" + fail "$expr (timeout with no prompt, expected \"$prompt\") $comment"; + expect "$prompt" + } + } +} + +proc PROGRAM_alternative {expr result1 result2} { + global prompt + global answer + global prompt_error + + # Don't continue if we haven't read the right prompt + if $prompt_error { + return + } + + # Send expression and wait for echo + if [catch {send -- "$expr\n"}] { + send_user "\n" + fail "could not send text, is the program running?" + return + } + + # Quote the expected result + regsub -all {[].$^()*+?|[]} $result1 {\\&} quoted1 + regsub -all {[].$^()*+?|[]} $result2 {\\&} quoted2 + # Quote the command + regsub -all {[].$^()*+?|[]} $expr {\\&} cmd + + # Check result + expect { + -re "$cmd\[\r\n \]+$answer *$quoted1\[ \r\n\]+$prompt" { + pass "$expr" + } + -re "$cmd\[\r\n \]+$answer *$quoted2\[ \r\n\]+$prompt" { + pass "$expr" + } + -re "\[:\].*\[\r\n\]+$prompt" { + fail "$expr (got wrong answer, expected \"$result1\" or \"$result2\")" + } + -re "\[!\].*\[\r\n\]+$prompt" { + send_user "\n" + fail "$expr (got error, but expected \"$result1\" or \"$result2\")" + } + -ex "$prompt" { + send_user "\n" + fail "$expr (expected \"$result1\" or \"$result2\")" + } + timeout { + send_user "\n" + fail "$expr (timeout with no prompt, expected \"$prompt\")"; + expect "$prompt" + } + } +} + +proc PROGRAM_regexp {expr result} { + global prompt + global answer + global prompt_error + + # Don't continue if we haven't read the right prompt + if $prompt_error { + return + } + + # Send expression and wait for echo + if [catch {send -- "$expr\n"}] { + send_user "\n" + fail "could not send text, is the program running?" + return + } + + # Quote the command + regsub -all {[].$^()*+?|[]} $expr {\\&} cmd + set quoted $result + + # Check result + expect { + -re "$cmd\[\r\n \]+$answer *$quoted\[ \r\n\]+$prompt" { + pass "$expr" + } + -re "\[:\].*\[\r\n\]+$prompt" { + fail "$expr (got wrong answer, expected \"$quoted\")" + } + -re "\[!\].*\[\r\n\]+$prompt" { + send_user "\n" + fail "$expr (got error, but expected \"$quoted\")" + } + -ex "$prompt" { + send_user "\n" + fail "$expr (expected \"$quoted\")" + } + timeout { + send_user "\n" + fail "$expr (timeout with no prompt, expected \"$prompt\")"; + expect "$prompt" + } + } +} + +proc PROGRAM_error {expr} { + PROGRAM_error_ "$expr" "" +} + +proc PROGRAM_error_c {expr comment} { + PROGRAM_error_ "$expr" "\[$comment\]" +} + +proc PROGRAM_error_ {expr comment} { + global prompt + global prompt_error + + # Don't continue if we haven't read the right prompt + if $prompt_error { + return + } + + # Send expression and wait for echo + if [catch {send -- "$expr\n"}] { + send_user "\n" + fail "could not send text, is the program running?" + return + } + + # Quote the command + regsub -all {[].$^()*+?|[]} $expr {\\&} cmd + + # Check result + expect { + -re "$cmd\[\r\n\]+Error! .*\[\r\n\]+$prompt" { + pass "$expr" + } + -re "$prompt" { + send_user "\n" + fail "$expr (expected error message)" + } + timeout { + send_user "\n" + fail "$expr (timeout with no prompt, expected \"$prompt\") $comment"; + expect "$prompt" + } + } +} + +proc PROGRAM_write_testfile {path} { + set file_tail [file tail "$path"] + + if [catch {open "$path" "r"} f] { + fail "could not open test file $path" + + } else { + set source_file [open "$path" "r"] + + if [catch {open "tests/$file_tail" "w+"} fh] { + file mkdir "tests" + set fh [open "tests/$file_tail" "w+"] + + while {[gets $source_file line] != -1} { + puts $fh $line + } + close $fh + + } else { + set fh [open "tests/$file_tail" "w+"] + + while {[gets $source_file line] != -1} { + puts $fh $line + } + close $fh + } + } +} + + +# Now go and start the program... +PROGRAM_start diff --git a/src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/testfiles/public/.gitkeep b/src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/testfiles/public/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/testfiles/secret/.gitkeep b/src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/testfiles/secret/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 From e4a3a310770bd3c177cddebf0546c40efa2567a5 Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Tue, 16 May 2023 13:32:37 +0200 Subject: [PATCH 04/62] added DejaGnu ProjectType button --- .../JenkinsProgrammingLanguageFeatureService.java | 4 ++-- .../resources/templates/java/maven_blackbox/readme | 1 + .../webapp/app/entities/programming-exercise.model.ts | 1 + .../update/programming-exercise-update.component.ts | 3 +++ .../programming-exercise-language.component.html | 10 +++++++++- src/main/webapp/i18n/de/programmingExercise.json | 1 + src/main/webapp/i18n/en/programmingExercise.json | 1 + 7 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 src/main/resources/templates/java/maven_blackbox/readme diff --git a/src/main/java/de/tum/in/www1/artemis/service/connectors/jenkins/JenkinsProgrammingLanguageFeatureService.java b/src/main/java/de/tum/in/www1/artemis/service/connectors/jenkins/JenkinsProgrammingLanguageFeatureService.java index 925f53feb918..e56cc4881cbe 100644 --- a/src/main/java/de/tum/in/www1/artemis/service/connectors/jenkins/JenkinsProgrammingLanguageFeatureService.java +++ b/src/main/java/de/tum/in/www1/artemis/service/connectors/jenkins/JenkinsProgrammingLanguageFeatureService.java @@ -18,8 +18,8 @@ public class JenkinsProgrammingLanguageFeatureService extends ProgrammingLanguag public JenkinsProgrammingLanguageFeatureService() { // Must be extended once a new programming language is added programmingLanguageFeatures.put(EMPTY, new ProgrammingLanguageFeature(EMPTY, false, false, false, false, false, List.of(), false, true, true)); - programmingLanguageFeatures.put(JAVA, - new ProgrammingLanguageFeature(JAVA, true, true, true, true, false, List.of(PLAIN_GRADLE, GRADLE_GRADLE, PLAIN_MAVEN, MAVEN_MAVEN), true, true, true)); + programmingLanguageFeatures.put(JAVA, new ProgrammingLanguageFeature(JAVA, true, true, true, true, false, + List.of(PLAIN_GRADLE, GRADLE_GRADLE, PLAIN_MAVEN, MAVEN_MAVEN, MAVEN_BLACKBOX), true, true, true)); programmingLanguageFeatures.put(KOTLIN, new ProgrammingLanguageFeature(KOTLIN, true, false, true, true, false, List.of(), true, true, true)); programmingLanguageFeatures.put(PYTHON, new ProgrammingLanguageFeature(PYTHON, false, false, true, false, false, List.of(), false, true, true)); // Jenkins is not supporting XCODE at the moment diff --git a/src/main/resources/templates/java/maven_blackbox/readme b/src/main/resources/templates/java/maven_blackbox/readme new file mode 100644 index 000000000000..43bfabe9024a --- /dev/null +++ b/src/main/resources/templates/java/maven_blackbox/readme @@ -0,0 +1 @@ +empty for now. diff --git a/src/main/webapp/app/entities/programming-exercise.model.ts b/src/main/webapp/app/entities/programming-exercise.model.ts index bc25c1dd83af..13174db12cf9 100644 --- a/src/main/webapp/app/entities/programming-exercise.model.ts +++ b/src/main/webapp/app/entities/programming-exercise.model.ts @@ -26,6 +26,7 @@ export enum ProgrammingLanguage { export enum ProjectType { MAVEN_MAVEN = 'MAVEN_MAVEN', PLAIN_MAVEN = 'PLAIN_MAVEN', + MAVEN_BLACKBOX = 'MAVEN_BLACKBOX', PLAIN_GRADLE = 'PLAIN_GRADLE', GRADLE_GRADLE = 'GRADLE_GRADLE', PLAIN = 'PLAIN', diff --git a/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.ts b/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.ts index 2df2731c8e50..7d8eace6b89d 100644 --- a/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.ts +++ b/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.ts @@ -318,6 +318,9 @@ export class ProgrammingExerciseUpdateComponent implements OnInit { } else { this.programmingExercise.projectType = ProjectType.PLAIN_MAVEN; } + } else if (type === ProjectType.MAVEN_BLACKBOX) { + this.selectedProjectTypeValue = ProjectType.MAVEN_BLACKBOX; + this.programmingExercise.projectType = ProjectType.MAVEN_BLACKBOX; } else { this.selectedProjectTypeValue = ProjectType.PLAIN_GRADLE; if (this.withDependenciesValue) { diff --git a/src/main/webapp/app/exercises/programming/manage/update/update-components/programming-exercise-language.component.html b/src/main/webapp/app/exercises/programming/manage/update/update-components/programming-exercise-language.component.html index 1786bbf38485..5c94f80cd2b6 100644 --- a/src/main/webapp/app/exercises/programming/manage/update/update-components/programming-exercise-language.component.html +++ b/src/main/webapp/app/exercises/programming/manage/update/update-components/programming-exercise-language.component.html @@ -27,7 +27,15 @@ name="projectType" id="field_projectType" > -
+
Date: Tue, 16 May 2023 15:53:56 +0200 Subject: [PATCH 05/62] backend changes --- .../in/www1/artemis/service/FileService.java | 2 +- .../ProgrammingExerciseRepositoryService.java | 17 +++-- .../src/${packageNameFolder}/Client.java | 2 +- .../model/BubbleSort.java | 26 -------- .../${packageNameFolder}/model/Context.java | 40 ------------ .../${packageNameFolder}/model/MergeSort.java | 62 ------------------- .../${packageNameFolder}/model/Policy.java | 30 --------- .../model/SortStrategy.java | 14 ----- .../${packageNameFolder}.tests/advanced.exp | 0 .../${packageNameFolder}.tests/public.exp | 0 .../${packageNameFolder}.tests/secret.exp | 0 .../dejagnu/config/default.exp | 0 .../dejagnu/lib/${packageNameFile}.exp} | 0 .../dejagnu/testfiles/public}/.gitkeep | 0 .../dejagnu/testfiles/secret/.gitkeep | 0 .../projectTemplate}/git.ignore.file | 0 .../projectTemplate}/pom.xml | 0 .../projectTemplate}/readme.md | 0 18 files changed, 10 insertions(+), 183 deletions(-) delete mode 100755 src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/BubbleSort.java delete mode 100755 src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/Context.java delete mode 100755 src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/MergeSort.java delete mode 100755 src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/Policy.java delete mode 100755 src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/SortStrategy.java rename src/main/resources/templates/java/test/{blackbox.projectTemplate => blackbox/projectTemplate}/dejagnu/${packageNameFolder}.tests/advanced.exp (100%) rename src/main/resources/templates/java/test/{blackbox.projectTemplate => blackbox/projectTemplate}/dejagnu/${packageNameFolder}.tests/public.exp (100%) rename src/main/resources/templates/java/test/{blackbox.projectTemplate => blackbox/projectTemplate}/dejagnu/${packageNameFolder}.tests/secret.exp (100%) rename src/main/resources/templates/java/test/{blackbox.projectTemplate => blackbox/projectTemplate}/dejagnu/config/default.exp (100%) rename src/main/resources/templates/java/test/{blackbox.projectTemplate/dejagnu/testfiles/public/.gitkeep => blackbox/projectTemplate/dejagnu/lib/${packageNameFile}.exp} (100%) rename src/main/resources/templates/java/test/{blackbox.projectTemplate/dejagnu/testfiles/secret => blackbox/projectTemplate/dejagnu/testfiles/public}/.gitkeep (100%) create mode 100644 src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/testfiles/secret/.gitkeep rename src/main/resources/templates/java/test/{blackbox.projectTemplate => blackbox/projectTemplate}/git.ignore.file (100%) rename src/main/resources/templates/java/test/{blackbox.projectTemplate => blackbox/projectTemplate}/pom.xml (100%) rename src/main/resources/templates/java/test/{blackbox.projectTemplate => blackbox/projectTemplate}/readme.md (100%) diff --git a/src/main/java/de/tum/in/www1/artemis/service/FileService.java b/src/main/java/de/tum/in/www1/artemis/service/FileService.java index 75a01f81a21c..927225a6085e 100644 --- a/src/main/java/de/tum/in/www1/artemis/service/FileService.java +++ b/src/main/java/de/tum/in/www1/artemis/service/FileService.java @@ -96,7 +96,7 @@ public class FileService implements DisposableBean { /** * These directories get falsely marked as files and should be ignored during copying. */ - private static final List IGNORED_DIRECTORY_SUFFIXES = List.of(".xcassets", ".colorset", ".appiconset", ".xcworkspace", ".xcodeproj", ".swiftpm"); + private static final List IGNORED_DIRECTORY_SUFFIXES = List.of(".xcassets", ".colorset", ".appiconset", ".xcworkspace", ".xcodeproj", ".swiftpm", ".tests"); @Override public void destroy() { diff --git a/src/main/java/de/tum/in/www1/artemis/service/programming/ProgrammingExerciseRepositoryService.java b/src/main/java/de/tum/in/www1/artemis/service/programming/ProgrammingExerciseRepositoryService.java index 7892961da556..cf3b3732c598 100644 --- a/src/main/java/de/tum/in/www1/artemis/service/programming/ProgrammingExerciseRepositoryService.java +++ b/src/main/java/de/tum/in/www1/artemis/service/programming/ProgrammingExerciseRepositoryService.java @@ -296,14 +296,6 @@ private void setupJVMTestTemplateAndPush(final RepositoryResources resources, fi // Java both supports Gradle and Maven as a test template Path projectTemplatePath = templatePath; - /* - * if (projectType != null && projectType.isGradle()) { - * projectTemplatePath = projectTemplatePath.resolve("gradle"); - * } - * else { - * projectTemplatePath = projectTemplatePath.resolve("maven"); - * } - */ if (isMavenProject(projectType)) { projectTemplatePath = projectTemplatePath.resolve("maven"); } @@ -324,6 +316,11 @@ else if (projectType.isGradle()) { setupJVMTestTemplateProjectTypeResources(resources, programmingExercise, repoLocalPath); } + if (projectType == ProjectType.MAVEN_BLACKBOX) { + Path dejagnuLibFolderPath = repoLocalPath.resolve("dejagnu").resolve("lib"); + fileService.replaceVariablesInFileName(dejagnuLibFolderPath.toString(), PACKAGE_NAME_FILE_PLACEHOLDER, programmingExercise.getPackageName()); + } + final Map sectionsMap = new HashMap<>(); // Keep or delete static code analysis configuration in the build configuration file sectionsMap.put("static-code-analysis", Boolean.TRUE.equals(programmingExercise.isStaticCodeAnalysisEnabled())); @@ -387,7 +384,9 @@ private void setupTestTemplateRegularTestRuns(final RepositoryResources resource setupBuildToolProjectFile(repoLocalPath, projectType, sectionsMap); - fileService.copyResources(testFileResources, resources.prefix, packagePath, false); + if (programmingExercise.getProjectType() != ProjectType.MAVEN_BLACKBOX) { + fileService.copyResources(testFileResources, resources.prefix, packagePath, false); + } if (projectType != null) { overwriteProjectTypeSpecificFiles(resources, programmingExercise, packagePath); diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java index 1c1c341178c3..b7e54171bd08 100644 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java @@ -1,7 +1,7 @@ import ${packageName}.input.Command; import ${packageName}.input.CommandParser; import ${packageName}.input.InvalidCommandException; -import ${packageName}.sorting.model.Context; +import ${packageName}.Context; import java.io.BufferedReader; import java.io.IOException; diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/BubbleSort.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/BubbleSort.java deleted file mode 100755 index f363402df44f..000000000000 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/BubbleSort.java +++ /dev/null @@ -1,26 +0,0 @@ -package ${packageName}.model; - -import java.util.Date; -import java.util.List; - -public class BubbleSort implements SortStrategy { - - /** - * Sorts Dates with BubbleSort. - * - * @param input the List of Dates to be sorted. - */ - public void performSort(List input) { - - for (int i = input.size() - 1; i >= 0; i--) { - for (int j = 0; j < i; j++) { - if (input.get(j).compareTo(input.get(j + 1)) > 0) { - Date temp = input.get(j); - input.set(j, input.get(j + 1)); - input.set(j + 1, temp); - } - } - } - - } -} diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/Context.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/Context.java deleted file mode 100755 index b09c69d77208..000000000000 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/Context.java +++ /dev/null @@ -1,40 +0,0 @@ -package ${packageName}.model; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -public class Context { - private SortStrategy sortAlgorithm = new MergeSort(); - - private final List dates = new ArrayList<>(); - - public List getDates() { - return dates; - } - - public void addValues(List values) { - this.dates.addAll(values); - } - - public void setSortAlgorithm(SortStrategy sa) { - sortAlgorithm = sa; - } - - public SortStrategy getSortAlgorithm() { - return sortAlgorithm; - } - - public void clearValues() { - this.dates.clear(); - } - - /** - * Runs the configured sort algorithm. - */ - public void sort() { - if (sortAlgorithm != null) { - sortAlgorithm.performSort(this.dates); - } - } -} diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/MergeSort.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/MergeSort.java deleted file mode 100755 index c641d8373d51..000000000000 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/MergeSort.java +++ /dev/null @@ -1,62 +0,0 @@ -package ${packageName}.model; - -import java.util.Date; -import java.util.List; - -public class MergeSort implements SortStrategy { - - /** - * Wrapper method for the real MergeSort algorithm. - * - * @param input the List of double values to be sorted - */ - public void performSort(List input) { - mergesort(input, 0, input.size() - 1); - } - - /** - * Performs MergeSort. - */ - private void mergesort(List input, int low, int high) { - if (high - low < 1) { - return; - } - int mid = (low + high) / 2; - mergesort(input, low, mid); - mergesort(input, mid + 1, high); - merge(input, low, mid, high); - } - - /** - * Merges the Dates of the sub-lists. - */ - private void merge(List input, int low, int middle, int high) { - - Date[] temp = new Date[high - low + 1]; - int leftIndex = low; - int rightIndex = middle + 1; - int wholeIndex = 0; - while (leftIndex <= middle && rightIndex <= high) { - if (input.get(leftIndex).compareTo(input.get(rightIndex)) <= 0) { - temp[wholeIndex] = input.get(leftIndex++); - } - else { - temp[wholeIndex] = input.get(rightIndex++); - } - wholeIndex++; - } - if (leftIndex <= middle && rightIndex > high) { - while (leftIndex <= middle) { - temp[wholeIndex++] = input.get(leftIndex++); - } - } - else { - while (rightIndex <= high) { - temp[wholeIndex++] = input.get(rightIndex++); - } - } - for (wholeIndex = 0; wholeIndex < temp.length; wholeIndex++) { - input.set(wholeIndex + low, temp[wholeIndex]); - } - } -} diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/Policy.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/Policy.java deleted file mode 100755 index 08454c446b9d..000000000000 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/Policy.java +++ /dev/null @@ -1,30 +0,0 @@ -package ${packageName}.model; - -public class Policy { - - /** - * @oracleIgnore - */ - private static final int VALUES_SIZE_THRESHOLD = 10; - - private final Context context; - - public Policy(Context context) { - this.context = context; - } - - /** - * Chooses a strategy depending on the number of Dates. - */ - public void configure() { - if (this.context.getDates().size() > VALUES_SIZE_THRESHOLD) { - System.out.println("More than " + VALUES_SIZE_THRESHOLD - + " double values, choosing merge sort!"); - this.context.setSortAlgorithm(new MergeSort()); - } else { - System.out.println("Less or equal than " + VALUES_SIZE_THRESHOLD - + " double values, choosing quick sort!"); - this.context.setSortAlgorithm(new BubbleSort()); - } - } -} diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/SortStrategy.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/SortStrategy.java deleted file mode 100755 index c1455f087096..000000000000 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/model/SortStrategy.java +++ /dev/null @@ -1,14 +0,0 @@ -package ${packageName}.model; - -import java.util.Date; -import java.util.List; - -public interface SortStrategy { - - /** - * Sorts a list of Dates. - * - * @param input The list of Dates to be sorted. - */ - void performSort(List input); -} diff --git a/src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/${packageNameFolder}.tests/advanced.exp b/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/advanced.exp similarity index 100% rename from src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/${packageNameFolder}.tests/advanced.exp rename to src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/advanced.exp diff --git a/src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/${packageNameFolder}.tests/public.exp b/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/public.exp similarity index 100% rename from src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/${packageNameFolder}.tests/public.exp rename to src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/public.exp diff --git a/src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/${packageNameFolder}.tests/secret.exp b/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/secret.exp similarity index 100% rename from src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/${packageNameFolder}.tests/secret.exp rename to src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/secret.exp diff --git a/src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/config/default.exp b/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/config/default.exp similarity index 100% rename from src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/config/default.exp rename to src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/config/default.exp diff --git a/src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/testfiles/public/.gitkeep b/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/lib/${packageNameFile}.exp similarity index 100% rename from src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/testfiles/public/.gitkeep rename to src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/lib/${packageNameFile}.exp diff --git a/src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/testfiles/secret/.gitkeep b/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/testfiles/public/.gitkeep similarity index 100% rename from src/main/resources/templates/java/test/blackbox.projectTemplate/dejagnu/testfiles/secret/.gitkeep rename to src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/testfiles/public/.gitkeep diff --git a/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/testfiles/secret/.gitkeep b/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/testfiles/secret/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/main/resources/templates/java/test/blackbox.projectTemplate/git.ignore.file b/src/main/resources/templates/java/test/blackbox/projectTemplate/git.ignore.file similarity index 100% rename from src/main/resources/templates/java/test/blackbox.projectTemplate/git.ignore.file rename to src/main/resources/templates/java/test/blackbox/projectTemplate/git.ignore.file diff --git a/src/main/resources/templates/java/test/blackbox.projectTemplate/pom.xml b/src/main/resources/templates/java/test/blackbox/projectTemplate/pom.xml similarity index 100% rename from src/main/resources/templates/java/test/blackbox.projectTemplate/pom.xml rename to src/main/resources/templates/java/test/blackbox/projectTemplate/pom.xml diff --git a/src/main/resources/templates/java/test/blackbox.projectTemplate/readme.md b/src/main/resources/templates/java/test/blackbox/projectTemplate/readme.md similarity index 100% rename from src/main/resources/templates/java/test/blackbox.projectTemplate/readme.md rename to src/main/resources/templates/java/test/blackbox/projectTemplate/readme.md From 4639b5a4b04a91e7c9923ba65a9eaca06dfe0e5b Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Wed, 17 May 2023 14:09:43 +0200 Subject: [PATCH 06/62] adapted readme to the user input exercise format --- .../templates/java/maven_blackbox/readme | 107 +++++++++++++++++- 1 file changed, 106 insertions(+), 1 deletion(-) diff --git a/src/main/resources/templates/java/maven_blackbox/readme b/src/main/resources/templates/java/maven_blackbox/readme index 43bfabe9024a..4432f05e50ed 100644 --- a/src/main/resources/templates/java/maven_blackbox/readme +++ b/src/main/resources/templates/java/maven_blackbox/readme @@ -1 +1,106 @@ -empty for now. +# Sorting with the Strategy Pattern + +In this exercise, we want to implement sorting algorithms and control the program interactively via user input on the console. + +**Note:** This project is using `Maven`! You have to import the project as Maven project (not as Eclipse project) as otherwise, errors will occur and you won't be able to work on this exercise. + +### Part 0: User Input + +First, there has to be a way for the user to communicate with the program. +The `Client` class should handle the user input. The following commands need to be supported by your implementation: + +`add date1 date2 ...`: Adds at least one date, but should also support multiple dates. +`sort`: Sorts the previously entered dates. +`clear`: Clears the list of dates. +`help`: Prints a dialog to the console that briefly explains the supported commands. +`print`: Prints the current list of dates to the console. +`quit`: Terminates the program. + +Using a `BufferedReader` might be a good starting point. + + +### Part 1: Sorting + +We need to implement two sorting algorithms, in this case `MergeSort` and `BubbleSort`. + +**You have the following tasks:** + +1. [task][Implement Bubble Sort](testBubbleSort) +Implement the method `performSort(List)` in the class `BubbleSort`. Make sure to follow the Bubble Sort algorithm exactly. + +2. [task][Implement Merge Sort](testMergeSort) +Implement the method `performSort(List)` in the class `MergeSort`. Make sure to follow the Merge Sort algorithm exactly. + +### Part 2: Strategy Pattern + +We want the application to apply different algorithms for sorting a `List` of `Date` objects. +Use the strategy pattern to select the right sorting algorithm at runtime. + +**You have the following tasks:** + +1. [task][SortStrategy Interface](testClass[SortStrategy],testMethods[SortStrategy]) +Create a `SortStrategy` interface and adjust the sorting algorithms so that they implement this interface. + +2. [task][Context Class](testAttributes[Context],testMethods[Context]) +Create and implement a `Context` class following the below class diagram + +3. [task][Context Policy](testConstructors[Policy],testAttributes[Policy],testMethods[Policy]) +Create and implement a `Policy` class following the below class diagram with a simple configuration mechanism: + + 1. [task][Select MergeSort](testClass[MergeSort],testUseMergeSortForBigList) + Select `MergeSort` when the List has more than 10 dates. + + 2. [task][Select BubbleSort](testClass[BubbleSort],testUseBubbleSortForSmallList) + Select `BubbleSort` when the List has less or equal 10 dates. + +4. Complete the `Client` class which demonstrates switching between two strategies at runtime. + +@startuml + +class Client { +} + +class Policy { + +configure() +} + +class Context { + -dates: List + +sort() +} + +interface SortStrategy { + +performSort(List) +} + +class BubbleSort { + +performSort(List) +} + +class MergeSort { + +performSort(List) +} + +MergeSort -up-|> SortStrategy #testsColor(testClass[MergeSort]) +BubbleSort -up-|> SortStrategy #testsColor(testClass[BubbleSort]) +Policy -right-> Context #testsColor(testAttributes[Policy]): context +Context -right-> SortStrategy #testsColor(testAttributes[Context]): sortAlgorithm +Client .down.> Policy +Client .down.> Context + +hide empty fields +hide empty methods + +@enduml + + +### Part 3: Optional Challenges + +(These are not tested) + +1. Create a new class `QuickSort` that implements `SortStrategy` and implement the Quick Sort algorithm. + +2. Make the method `performSort(List)` generic, so that other objects can also be sorted by the same method. +**Hint:** Have a look at Java Generics and the interface `Comparable`. + +3. Think about a useful decision in `Policy` when to use the new `QuickSort` algorithm. From e45f84276cf1d336488af81ba66d33da6335a6f1 Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Wed, 17 May 2023 15:33:03 +0200 Subject: [PATCH 07/62] cosmetic improvements for the readme --- .../templates/java/maven_blackbox/readme | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/resources/templates/java/maven_blackbox/readme b/src/main/resources/templates/java/maven_blackbox/readme index 4432f05e50ed..34849b86620c 100644 --- a/src/main/resources/templates/java/maven_blackbox/readme +++ b/src/main/resources/templates/java/maven_blackbox/readme @@ -9,12 +9,18 @@ In this exercise, we want to implement sorting algorithms and control the progra First, there has to be a way for the user to communicate with the program. The `Client` class should handle the user input. The following commands need to be supported by your implementation: -`add date1 date2 ...`: Adds at least one date, but should also support multiple dates. -`sort`: Sorts the previously entered dates. -`clear`: Clears the list of dates. -`help`: Prints a dialog to the console that briefly explains the supported commands. -`print`: Prints the current list of dates to the console. -`quit`: Terminates the program. +`add date1 date2 ...` +Adds at least one date, but should also support multiple dates. +`sort` +Sorts the previously entered dates. +`clear` +Clears the list of dates. +`help` +Prints a dialog to the console that briefly explains the supported commands. +`print` +Prints the current list of dates to the console. +`quit` +Terminates the program. Using a `BufferedReader` might be a good starting point. From c4a1fb5f8826f5fc2166a7e2e2f79a7484c9147f Mon Sep 17 00:00:00 2001 From: Benedikt Fein Date: Wed, 17 May 2023 16:18:46 +0200 Subject: [PATCH 08/62] Suggestions from Code Review --- src/main/resources/config/application.yml | 2 +- .../exercise/src/${packageNameFolder}/Client.java | 1 - .../solution/src/${packageNameFolder}/Client.java | 2 ++ 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/resources/config/application.yml b/src/main/resources/config/application.yml index 869acfbc7074..62151c9cc398 100644 --- a/src/main/resources/config/application.yml +++ b/src/main/resources/config/application.yml @@ -59,7 +59,7 @@ artemis: java: # possible overrides: maven, gradle default: "ls1tum/artemis-maven-template:java17-16" - maven_blackbox: "" + maven_blackbox: "registry.git.fim.uni-passau.de/artemis/artemis-docker-images/dejagnu:20" kotlin: # possible overrides: maven, gradle default: "ls1tum/artemis-maven-template:java17-16" diff --git a/src/main/resources/templates/java/maven_blackbox/exercise/src/${packageNameFolder}/Client.java b/src/main/resources/templates/java/maven_blackbox/exercise/src/${packageNameFolder}/Client.java index 2a46429dbc89..965a341a0962 100644 --- a/src/main/resources/templates/java/maven_blackbox/exercise/src/${packageNameFolder}/Client.java +++ b/src/main/resources/templates/java/maven_blackbox/exercise/src/${packageNameFolder}/Client.java @@ -27,6 +27,5 @@ private Client() { */ public static void main(String[] args) throws ParseException { - } } } diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java index b7e54171bd08..399df976765c 100644 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java @@ -1,3 +1,5 @@ +package ${packageName}; + import ${packageName}.input.Command; import ${packageName}.input.CommandParser; import ${packageName}.input.InvalidCommandException; From f4099ca7c61045c3d89ec5ec830d8e4d1594e5a3 Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Wed, 17 May 2023 17:04:50 +0200 Subject: [PATCH 09/62] deactivate sequential test runs and testwise coverage for dejagnu project type --- .../manage/update/programming-exercise-update.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.html b/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.html index d50ab57c9b9c..99b5d2c0902d 100644 --- a/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.html +++ b/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.html @@ -83,10 +83,10 @@

Date: Wed, 17 May 2023 17:11:42 +0200 Subject: [PATCH 10/62] remove test repo instructions that no longer apply --- .../java/test/blackbox/projectTemplate/readme.md | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/main/resources/templates/java/test/blackbox/projectTemplate/readme.md b/src/main/resources/templates/java/test/blackbox/projectTemplate/readme.md index 4dd021d52f19..fec7ea136127 100644 --- a/src/main/resources/templates/java/test/blackbox/projectTemplate/readme.md +++ b/src/main/resources/templates/java/test/blackbox/projectTemplate/readme.md @@ -1,19 +1,8 @@ ## Test Repository instructions -#### Test tool & command -Tests will be run using the command maven clean test. - #### Project structure Make sure that the package structure of your test classes is equivalent to the package structure of your base and solution repository. Otherwise during the test run maven will not be able to find the imported classes in your test files. -#### Sequential test runs -If you have decided to use the sequential test runs feature for this exercise, read the following instructions: -We use the folder structure of the test repository to differentiate structural and behavior tests: -1. Structural test files must be placed in the folder "structural" -2. Behavior test files must be placed in the folder "behavior" - -Files in other folders will not be executed! - #### Static Code Analysis The pom.xml contains dependencies for the execution of static code analysis, if the option is active for this programming exercise. From 5f0556b9d3d958c6554ad469cf64a00ab17b408b Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Wed, 17 May 2023 17:20:31 +0200 Subject: [PATCH 11/62] remove unsupported dependencies in pom --- .../test/blackbox/projectTemplate/pom.xml | 79 ------------------- 1 file changed, 79 deletions(-) diff --git a/src/main/resources/templates/java/test/blackbox/projectTemplate/pom.xml b/src/main/resources/templates/java/test/blackbox/projectTemplate/pom.xml index b6fc74356115..30711c5550bb 100644 --- a/src/main/resources/templates/java/test/blackbox/projectTemplate/pom.xml +++ b/src/main/resources/templates/java/test/blackbox/projectTemplate/pom.xml @@ -14,24 +14,8 @@ false - - - - de.tum.in.ase - artemis-java-test-sandbox - 1.11.3 - - ${project.basedir}${studentWorkingDirectory} - - ${project.basedir}/test - - - ${project.basedir}/test - - - org.apache.maven.plugins @@ -42,11 +26,6 @@ 17 - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M9 - org.apache.maven.plugins maven-enforcer-plugin @@ -82,14 +61,6 @@ ${project.build.outputDirectory}/sun/ ${project.build.outputDirectory}/org/gradle/ ${project.build.outputDirectory}/worker/org/gradle/ - - ${project.build.outputDirectory}/com/squareup/ - ${project.build.outputDirectory}/com/teamscale/ - ${project.build.outputDirectory}/okhttp3/ - ${project.build.outputDirectory}/okio/ - ${project.build.outputDirectory}/retrofit2/ - ${project.build.outputDirectory}/shadow/ - @@ -176,54 +147,4 @@ - - - - coverage - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M9 - - - okhttp3,com.teamscale,retrofit2,shadow,com.squareup,okio - - - - - com.teamscale - teamscale-surefire-provider - 29.1.2 - - - - - com.teamscale - teamscale-maven-plugin - 29.1.2 - - http://localhost - dummy - ${exerciseNamePomXml}-Tests - dummy - testwise - - *${packageName}* - - - - - - prepare-tia-unit-test - - - - - - - - - From 140d4fef9f6623d2aed0f55d7368863adc4950ce Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Mon, 29 May 2023 20:55:53 +0200 Subject: [PATCH 12/62] files added and fixed --- .../src/${packageNameFolder}/Client.java | 2 - .../src/${packageNameFolder}/Client.java | 9 +- .../src/${packageNameFolder}/Context.java | 42 +++ .../dejagnu/config/default.exp | 177 ----------- .../blackbox/projectTemplate/pipeline.groovy | 281 ++++++++++++++++++ 5 files changed, 327 insertions(+), 184 deletions(-) create mode 100644 src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java create mode 100644 src/main/resources/templates/java/test/blackbox/projectTemplate/pipeline.groovy diff --git a/src/main/resources/templates/java/maven_blackbox/exercise/src/${packageNameFolder}/Client.java b/src/main/resources/templates/java/maven_blackbox/exercise/src/${packageNameFolder}/Client.java index 965a341a0962..97cc47af05dd 100644 --- a/src/main/resources/templates/java/maven_blackbox/exercise/src/${packageNameFolder}/Client.java +++ b/src/main/resources/templates/java/maven_blackbox/exercise/src/${packageNameFolder}/Client.java @@ -1,7 +1,5 @@ package ${packageName}; -import org.apache.commons.lang3.RandomUtils; - import java.text.*; import java.util.*; diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java index 399df976765c..ef9083b43a69 100644 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java @@ -35,18 +35,17 @@ public static void main(String[] args) throws IOException { private static CommandRunResult runCommand(final Command command) { if (command instanceof Command.AddCommand addCommand) { - context.addValues(addCommand.values()); + context.addDates(addCommand.values()); } else if (command instanceof Command.SortCommand) { // policy.configure(); context.sort(); } else if (command instanceof Command.ClearCommand) { - context.clearValues(); - } else if (command instanceof Command.HelpCommand helpCommand()) { + context.clearDates(); + } else if (command instanceof Command.HelpCommand helpCommand) { System.out.println(helpCommand.helpMessage()); } else if (command instanceof Command.PrintCommand) { System.out.println(context.getDates()); - } - else if (command instanceof Command.QuitCommand) { + } else if (command instanceof Command.QuitCommand) { return CommandRunResult.QUIT; } else { // can never happen since all cases of the sealed interface are diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java new file mode 100644 index 000000000000..2280bfdd553e --- /dev/null +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java @@ -0,0 +1,42 @@ +package ${packageName}; + +import java.util.*; + +public class Context { + private SortStrategy sortAlgorithm; + + private List dates; + + public List getDates() { + return dates; + } + + public void setDates(List dates) { + this.dates = dates; + } + + public void addDates(List dates) { + this.dates.addAll(dates); + } + + public void clearDates() { + this.dates = new ArrayList<>(); + } + + public void setSortAlgorithm(SortStrategy sa) { + sortAlgorithm = sa; + } + + public SortStrategy getSortAlgorithm() { + return sortAlgorithm; + } + + /** + * Runs the configured sort algorithm. + */ + public void sort() { + if (sortAlgorithm != null) { + sortAlgorithm.performSort(this.dates); + } + } +} diff --git a/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/config/default.exp b/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/config/default.exp index 795e2e36d658..264d5500143b 100644 --- a/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/config/default.exp +++ b/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/config/default.exp @@ -137,44 +137,6 @@ proc PROGRAM_enter_ {expr comment} { } } -# Own functions -proc PROGRAM_ignore {expr} { - PROGRAM_ignore_ "$expr" "" -} - -proc PROGRAM_ignore_c {expr comment} { - PROGRAM_ignore_ "$expr" "\[$comment\]" -} - -proc PROGRAM_ignore_ {expr comment} { - global prompt - global prompt_error - - # Don't continue if we haven't read the right prompt - if $prompt_error { - return - } - - # Send expression and wait for echo - if [catch {send -- "$expr\n"}] { - send_user "\n" - fail "could not send text, is the program running? $comment" - return - } - - # Check result - expect { - -ex "$prompt" { - pass "$expr" - } - timeout { - send_user "\n" - fail "$expr (timeout with no prompt, expected \"$prompt\") $comment"; - } - } -} - -# Own functions proc PROGRAM_test {expr result} { PROGRAM_test_ "$expr" "$result" "" } @@ -229,145 +191,6 @@ proc PROGRAM_test_ {expr result comment} { } } -proc PROGRAM_alternative {expr result1 result2} { - global prompt - global answer - global prompt_error - - # Don't continue if we haven't read the right prompt - if $prompt_error { - return - } - - # Send expression and wait for echo - if [catch {send -- "$expr\n"}] { - send_user "\n" - fail "could not send text, is the program running?" - return - } - - # Quote the expected result - regsub -all {[].$^()*+?|[]} $result1 {\\&} quoted1 - regsub -all {[].$^()*+?|[]} $result2 {\\&} quoted2 - # Quote the command - regsub -all {[].$^()*+?|[]} $expr {\\&} cmd - - # Check result - expect { - -re "$cmd\[\r\n \]+$answer *$quoted1\[ \r\n\]+$prompt" { - pass "$expr" - } - -re "$cmd\[\r\n \]+$answer *$quoted2\[ \r\n\]+$prompt" { - pass "$expr" - } - -re "\[:\].*\[\r\n\]+$prompt" { - fail "$expr (got wrong answer, expected \"$result1\" or \"$result2\")" - } - -re "\[!\].*\[\r\n\]+$prompt" { - send_user "\n" - fail "$expr (got error, but expected \"$result1\" or \"$result2\")" - } - -ex "$prompt" { - send_user "\n" - fail "$expr (expected \"$result1\" or \"$result2\")" - } - timeout { - send_user "\n" - fail "$expr (timeout with no prompt, expected \"$prompt\")"; - expect "$prompt" - } - } -} - -proc PROGRAM_regexp {expr result} { - global prompt - global answer - global prompt_error - - # Don't continue if we haven't read the right prompt - if $prompt_error { - return - } - - # Send expression and wait for echo - if [catch {send -- "$expr\n"}] { - send_user "\n" - fail "could not send text, is the program running?" - return - } - - # Quote the command - regsub -all {[].$^()*+?|[]} $expr {\\&} cmd - set quoted $result - - # Check result - expect { - -re "$cmd\[\r\n \]+$answer *$quoted\[ \r\n\]+$prompt" { - pass "$expr" - } - -re "\[:\].*\[\r\n\]+$prompt" { - fail "$expr (got wrong answer, expected \"$quoted\")" - } - -re "\[!\].*\[\r\n\]+$prompt" { - send_user "\n" - fail "$expr (got error, but expected \"$quoted\")" - } - -ex "$prompt" { - send_user "\n" - fail "$expr (expected \"$quoted\")" - } - timeout { - send_user "\n" - fail "$expr (timeout with no prompt, expected \"$prompt\")"; - expect "$prompt" - } - } -} - -proc PROGRAM_error {expr} { - PROGRAM_error_ "$expr" "" -} - -proc PROGRAM_error_c {expr comment} { - PROGRAM_error_ "$expr" "\[$comment\]" -} - -proc PROGRAM_error_ {expr comment} { - global prompt - global prompt_error - - # Don't continue if we haven't read the right prompt - if $prompt_error { - return - } - - # Send expression and wait for echo - if [catch {send -- "$expr\n"}] { - send_user "\n" - fail "could not send text, is the program running?" - return - } - - # Quote the command - regsub -all {[].$^()*+?|[]} $expr {\\&} cmd - - # Check result - expect { - -re "$cmd\[\r\n\]+Error! .*\[\r\n\]+$prompt" { - pass "$expr" - } - -re "$prompt" { - send_user "\n" - fail "$expr (expected error message)" - } - timeout { - send_user "\n" - fail "$expr (timeout with no prompt, expected \"$prompt\") $comment"; - expect "$prompt" - } - } -} - proc PROGRAM_write_testfile {path} { set file_tail [file tail "$path"] diff --git a/src/main/resources/templates/java/test/blackbox/projectTemplate/pipeline.groovy b/src/main/resources/templates/java/test/blackbox/projectTemplate/pipeline.groovy new file mode 100644 index 000000000000..f85b74c096ff --- /dev/null +++ b/src/main/resources/templates/java/test/blackbox/projectTemplate/pipeline.groovy @@ -0,0 +1,281 @@ +MAIN_CLASS = "notFound" // default value, will be replaced in Build stage +OUT_DIR = "target/surefire-reports" +mavenFlags = "-B" + +testfiles_base_path = "./dejagnu/testfiles" + +runDejagnuTests = fileExists("./dejagnu") +tool = getToolName() +hasSecretTestFiles = secretTestFilesFolderExists() + +dockerImage = "registry.git.fim.uni-passau.de/artemis/artemis-docker-images/dejagnu:20.0.1" +dockerFlags = "" +secretTestVolume = "prog2_${tool}-secret" +secret_volume_mount_path = "/secrets" +rebuildImage = true + +/** + * Main function called by Jenkins. + */ +void testRunner() { + setup() + removeSecretFiles() + build() + + // catchError-block: execute following steps even if the one inside the + // block fails, otherwise whole pipeline is aborted + catchError { + customCheckers() + } + catchError { + if (runDejagnuTests) { + dejagnuTests() + } + } + catchError { + staticCodeAnalysis() + } +} + +/** + * Runs special tasks before the actual tests can begin. + *

+ * E.g. container creation, setting docker flags. + */ +private void setup() { + // special jobs to run only for the solution repository + if ("${env.JOB_NAME}" ==~ /.+-SOLUTION$/) { + dockerFlags += " -v prog2_maven-cache:/maven_cache" + + if (runDejagnuTests) { + createSecretTestVolume() + } + } else { + dockerFlags += " -v prog2_maven-cache:/maven_cache:ro" + + // if not solution repo, disallow network access from containers + dockerFlags += " --network none" + mavenFlags += " --offline" + } +} + +/** + * Copies the files required only for the secret tests to the Docker volume. + */ +private void createSecretTestVolume() { + stage("Create Secret Test Volume") { + docker.image(dockerImage).inside("-v ${secretTestVolume}:${secret_volume_mount_path}") { c -> + sh """ + rm -rf ${secret_volume_mount_path}/* + cp dejagnu/${tool}.tests/secret.exp ${secret_volume_mount_path}/secret.exp + """ + + if (hasSecretTestFiles) { + sh("cp -vr ${testfiles_base_path}/secret ${secret_volume_mount_path}/secret") + } + } + } +} + +/** + * Builds the student code and tries to find a main method. + */ +private void build() { + stage('Build') { + docker.image(dockerImage).inside(dockerFlags) { c -> + sh "mvn ${mavenFlags} clean compile" + setMainClass() + } + } +} + +/** + * Runs the custom {@code pipeline-helper.jar} checkers. + */ +private void customCheckers() { + stage('Checkers') { + docker.image(dockerImage).inside(dockerFlags) { c -> + // all java files in the assignment folder should have maximal line length 80 + sh 'pipeline-helper -l 80 assignment/ java' + // checks that the file exists and is not empty for non gui programs + if (runDejagnuTests) { + sh 'pipeline-helper -e assignment/Tests.txt' + } + } + } +} + +/** + * Runs Dejagnu scripts. + */ +private void dejagnuTests() { + stage('Public+Advanced Tests') { + docker.image(dockerImage).inside(dockerFlags) { c -> + applyExpectScriptReplacements() + + runDejagnuTestStep("public", 60) + runDejagnuTestStep("advanced", 60) + } + } + + stage('Secret Tests') { + docker.image(dockerImage).inside(dockerFlags + " -v ${secretTestVolume}:${secret_volume_mount_path}:ro") { c -> + restoreSecretFiles() + applyExpectScriptReplacements() + runDejagnuTestStep("secret", 60) + } + } +} + +/** + * Runs a single Dejagnu test step. + * + * @param step The test step name. Runs the test file {@code step.exp}. + * @param timeoutSeconds A number of seconds after which Jenkins will kill the dejagnu process. + */ +private void runDejagnuTestStep(String step, int timeoutSeconds) { + catchError() { + timeout(time: timeoutSeconds, unit: 'SECONDS') { + sh """ + cd dejagnu || exit + rm ${tool}.log || true + runtest --tool ${tool} ${step}.exp || true + """ + } + } + sh("""pipeline-helper -o customFeedbacks -d "dejagnu[${step}]" dejagnu/${tool}.log""") +} + +/** + * Extracts the Dejagnu tool name from the folder names. + *

+ * E.g., for a folder {@code dejagnu/ggt.tests/} the tool name is {@code ggt}. + * + * @return The Dejagnu tool name. + */ +private String getToolName() { + // Java Files API gets blocked by Jenkins sandbox + + return sh( + script: """find dejagnu -name "*.tests" -type d -printf "%f" | cut --delimiter=. -f 1""", + returnStdout: true + ).trim() +} + +/** + * Extracts the name of the student’s Java class that contains the main method + * and stores it in {@code MAIN_CLASS}. + *

+ * Aborts the pipeline if no main class could be found. + */ +private void setMainClass() { + def main_checker_lines = sh( + script: "pipeline-helper -m assignment/", + returnStdout: true + ).tokenize('\n') + + // first line of output is class name with main method + // second one a status message that the checker ran successfully/failed + if (main_checker_lines.size() == 2) { + MAIN_CLASS = main_checker_lines.get(0) + } else { + // no main method found: let this stage fail, this aborts all further stages + error + } +} + +/** + * Replaces variables of the expect scripts with task specific values. + */ +private void applyExpectScriptReplacements() { + sh """ + sed -i "s#CLASSPATH#../target/classes#" dejagnu/config/default.exp + sed -i "s#MAIN_CLASS#${MAIN_CLASS}#" dejagnu/config/default.exp + + sed -i "s#TESTFILES_DIRECTORY#../${testfiles_base_path}#" dejagnu/${tool}.tests/*.exp + """ +} + +/** + * Removes all secret files from the working directory. + *

+ * Without the special Docker volume mounted then students can no longer access + * those files during the public tests. + */ +private void removeSecretFiles() { + secretExp = "dejagnu/${tool}.tests/secret.exp" + if (fileExists(secretExp)) { + sh("rm ${secretExp}") + } + + if (hasSecretTestFiles) { + sh("rm -rf ${testfiles_base_path}/secret/") + } +} + +/** + * Copies the secret files from the Docker volume back into the working directory. + */ +private void restoreSecretFiles() { + if (runDejagnuTests) { + sh("cp ${secret_volume_mount_path}/secret.exp dejagnu/${tool}.tests/secret.exp") + } + + if (hasSecretTestFiles) { + sh("cp -vr ${secret_volume_mount_path}/secret ${testfiles_base_path}/secret") + } +} + +/** + * Checks if a folder with secret Dejagnu test files exists. + * + * @return True, if such a folder exists. + */ +private boolean secretTestFilesFolderExists() { + return fileExists("${testfiles_base_path}/secret") +} + +/** + * Runs the static code analysis + */ +private void staticCodeAnalysis() { + stage("StaticCodeAnalysis") { + docker.image(dockerImage).inside(dockerFlags) { c -> + /* + sh """ + mvn -B spotbugs:spotbugs checkstyle:checkstyle pmd:pmd pmd:cpd + mkdir -p staticCodeAnalysisReports + cp target/spotbugsXml.xml staticCodeAnalysisReports + cp target/checkstyle-result.xml staticCodeAnalysisReports + cp target/pmd.xml staticCodeAnalysisReports + cp target/cpd.xml staticCodeAnalysisReports + """ + */ + + sh """ + mvn ${mavenFlags} checkstyle:checkstyle + mkdir -p staticCodeAnalysisReports + cp target/checkstyle-result.xml staticCodeAnalysisReports + """ + } + } +} + +/** + * Script of the post build tasks aggregating all JUnit files in $WORKSPACE/results. + * + * Called by Jenkins. + */ +void postBuildTasks() { + // we do not actually have any JUnit-XMLs => no action needed + /* + sh ''' + rm -rf results + mkdir results + cp target/surefire-reports/*.xml $WORKSPACE/results/ || true + sed -i 's/[^[:print:]\t]/�/g' $WORKSPACE/results/*.xml || true + ''' + */ +} + +return this From e54ce398e228f556c6f2a263ec76d246550ebc44 Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Mon, 29 May 2023 21:15:01 +0200 Subject: [PATCH 13/62] correctly annotated files --- .../dejagnu/${packageNameFolder}.tests/public.exp | 2 +- .../dejagnu/${packageNameFolder}.tests/secret.exp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/public.exp b/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/public.exp index 6430298416dc..403b6f710fce 100644 --- a/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/public.exp +++ b/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/public.exp @@ -1,6 +1,6 @@ # Sorting Testdata -# Secret Tests +# Public Tests PROGRAM_test {add 2020-03-31} {} PROGRAM_test {add 2020-03-30} {} PROGRAM_test {add 2020-04-01} {} diff --git a/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/secret.exp b/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/secret.exp index f6b28589d9d1..4e8d86d3b5a7 100644 --- a/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/secret.exp +++ b/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/secret.exp @@ -1,6 +1,6 @@ # Sorting Testdata -# Public Tests +# Secret Tests PROGRAM_test {print} {} {[]} PROGRAM_test {add 2020-03-31} {} PROGRAM_test {add 2020-03-30} {} From be51569eafe58144c4ec394642f6fb0a7b01bffb Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Wed, 31 May 2023 12:08:21 +0200 Subject: [PATCH 14/62] fix --- .../solution/src/${packageNameFolder}/Context.java | 2 +- .../dejagnu/${packageNameFolder}.tests/secret.exp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java index 2280bfdd553e..899a7f236c67 100644 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java @@ -5,7 +5,7 @@ public class Context { private SortStrategy sortAlgorithm; - private List dates; + private List dates = new ArrayList<>(); public List getDates() { return dates; diff --git a/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/secret.exp b/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/secret.exp index 4e8d86d3b5a7..d68674e8b410 100644 --- a/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/secret.exp +++ b/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/secret.exp @@ -1,11 +1,11 @@ # Sorting Testdata # Secret Tests -PROGRAM_test {print} {} {[]} +PROGRAM_test {print} {[]} PROGRAM_test {add 2020-03-31} {} PROGRAM_test {add 2020-03-30} {} PROGRAM_test {add 2020-04-01} {} PROGRAM_test {print} {[Tue Mar 31 00:00:00 CEST 2020, Mon Mar 30 00:00:00 CEST 2020, Wed Apr 01 00:00:00 CEST 2020]} -PROGRAM_test {clear} {[]} -PROGRAM_test {print} {} {[]} +PROGRAM_test {clear} {} +PROGRAM_test {print} {[]} From bbcfddfbada5145f0233306605ab9e34197a7308 Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Wed, 31 May 2023 12:29:56 +0200 Subject: [PATCH 15/62] standardized time zone --- .../solution/src/${packageNameFolder}/input/CommandParser.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java index 718fdedd722b..7ea052e9964e 100644 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java @@ -74,6 +74,7 @@ private static Command.AddCommand parseAddCommand(final String[] args) private static Date parseDateInput(String input) throws ParseException { SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + formatter.setTimeZone(TimeZone.getTimeZone("UTC")); formatter.setLenient(false); return formatter.parse(input); } From a9df1b323b7d103d434dbbe4c373d75bd5a87e1c Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Wed, 31 May 2023 12:33:28 +0200 Subject: [PATCH 16/62] added import --- .../solution/src/${packageNameFolder}/input/CommandParser.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java index 7ea052e9964e..ed59fb698e31 100644 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java @@ -6,6 +6,7 @@ import java.util.Collections; import java.util.Date; import java.util.List; +import java.util.TimeZone; public class CommandParser { From 493f12e9750e0c3b51e9736e96627807347d4a15 Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Wed, 31 May 2023 12:41:17 +0200 Subject: [PATCH 17/62] changed date format in the tests also --- .../dejagnu/${packageNameFolder}.tests/advanced.exp | 8 ++++---- .../dejagnu/${packageNameFolder}.tests/public.exp | 4 ++-- .../dejagnu/${packageNameFolder}.tests/secret.exp | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/advanced.exp b/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/advanced.exp index 488e4cd6b135..6b14d5100410 100644 --- a/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/advanced.exp +++ b/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/advanced.exp @@ -4,11 +4,11 @@ PROGRAM_test {add 2020-03-31} {} PROGRAM_test {add 2020-03-30} {} PROGRAM_test {add 2020-04-01} {} -PROGRAM_test {print} {[Tue Mar 31 00:00:00 CEST 2020, Mon Mar 30 00:00:00 CEST 2020, Wed Apr 01 00:00:00 CEST 2020]} +PROGRAM_test {print} {[Tue Mar 31 00:00:00 UTC 2020, Mon Mar 30 00:00:00 UTC 2020, Wed Apr 01 00:00:00 UTC 2020]} PROGRAM_test {sort} {} -PROGRAM_test {print} {[Mon Mar 30 00:00:00 CEST 2020, Tue Mar 31 00:00:00 CEST 2020, Wed Apr 01 00:00:00 CEST 2020]} +PROGRAM_test {print} {[Mon Mar 30 00:00:00 UTC 2020, Tue Mar 31 00:00:00 UTC 2020, Wed Apr 01 00:00:00 UTC 2020]} PROGRAM_test {add 2020-01-31} {} -PROGRAM_test {print} {[Mon Mar 30 00:00:00 CEST 2020, Tue Mar 31 00:00:00 CEST 2020, Wed Apr 01 00:00:00 CEST 2020, Fri Jan 31 00:00:00 CET 2020]} +PROGRAM_test {print} {[Mon Mar 30 00:00:00 UTC 2020, Tue Mar 31 00:00:00 UTC 2020, Wed Apr 01 00:00:00 UTC 2020, Fri Jan 31 00:00:00 UTC 2020]} PROGRAM_test {sort} {} -PROGRAM_test {print} {[Fri Jan 31 00:00:00 CET 2020, Mon Mar 30 00:00:00 CEST 2020, Tue Mar 31 00:00:00 CEST 2020, Wed Apr 01 00:00:00 CEST 2020]} +PROGRAM_test {print} {[Fri Jan 31 00:00:00 CET 2020, Mon Mar 30 00:00:00 UTC 2020, Tue Mar 31 00:00:00 UTC 2020, Wed Apr 01 00:00:00 UTC 2020]} diff --git a/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/public.exp b/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/public.exp index 403b6f710fce..169e0e8863af 100644 --- a/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/public.exp +++ b/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/public.exp @@ -4,6 +4,6 @@ PROGRAM_test {add 2020-03-31} {} PROGRAM_test {add 2020-03-30} {} PROGRAM_test {add 2020-04-01} {} -PROGRAM_test {print} {[Tue Mar 31 00:00:00 CEST 2020, Mon Mar 30 00:00:00 CEST 2020, Wed Apr 01 00:00:00 CEST 2020]} +PROGRAM_test {print} {[Tue Mar 31 00:00:00 UTC 2020, Mon Mar 30 00:00:00 UTC 2020, Wed Apr 01 00:00:00 UTC 2020]} PROGRAM_test {sort} {} -PROGRAM_test {print} {[Mon Mar 30 00:00:00 CEST 2020, Tue Mar 31 00:00:00 CEST 2020, Wed Apr 01 00:00:00 CEST 2020]} +PROGRAM_test {print} {[Mon Mar 30 00:00:00 UTC 2020, Tue Mar 31 00:00:00 UTC 2020, Wed Apr 01 00:00:00 UTC 2020]} diff --git a/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/secret.exp b/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/secret.exp index d68674e8b410..fa9bdc551612 100644 --- a/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/secret.exp +++ b/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/secret.exp @@ -5,7 +5,7 @@ PROGRAM_test {print} {[]} PROGRAM_test {add 2020-03-31} {} PROGRAM_test {add 2020-03-30} {} PROGRAM_test {add 2020-04-01} {} -PROGRAM_test {print} {[Tue Mar 31 00:00:00 CEST 2020, Mon Mar 30 00:00:00 CEST 2020, Wed Apr 01 00:00:00 CEST 2020]} +PROGRAM_test {print} {[Tue Mar 31 00:00:00 UTC 2020, Mon Mar 30 00:00:00 UTC 2020, Wed Apr 01 00:00:00 UTC 2020]} PROGRAM_test {clear} {} PROGRAM_test {print} {[]} From 4d7e721c2fb10283fb07bc1a4c6e4070c9549b8d Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Wed, 31 May 2023 12:49:39 +0200 Subject: [PATCH 18/62] initialized sorting algorithm in the context class --- .../solution/src/${packageNameFolder}/Context.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java index 899a7f236c67..8bf55254a6f6 100644 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java @@ -3,7 +3,7 @@ import java.util.*; public class Context { - private SortStrategy sortAlgorithm; + private SortStrategy sortAlgorithm = new MergeSort(); private List dates = new ArrayList<>(); From 6fad054eda048fa469683732d43921f3d04153b3 Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Wed, 31 May 2023 12:56:03 +0200 Subject: [PATCH 19/62] timezone oversight --- .../dejagnu/${packageNameFolder}.tests/advanced.exp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/advanced.exp b/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/advanced.exp index 6b14d5100410..6e551fda09fe 100644 --- a/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/advanced.exp +++ b/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/advanced.exp @@ -11,4 +11,4 @@ PROGRAM_test {print} {[Mon Mar 30 00:00:00 UTC 2020, Tue Mar 31 00:00:00 UTC 202 PROGRAM_test {add 2020-01-31} {} PROGRAM_test {print} {[Mon Mar 30 00:00:00 UTC 2020, Tue Mar 31 00:00:00 UTC 2020, Wed Apr 01 00:00:00 UTC 2020, Fri Jan 31 00:00:00 UTC 2020]} PROGRAM_test {sort} {} -PROGRAM_test {print} {[Fri Jan 31 00:00:00 CET 2020, Mon Mar 30 00:00:00 UTC 2020, Tue Mar 31 00:00:00 UTC 2020, Wed Apr 01 00:00:00 UTC 2020]} +PROGRAM_test {print} {[Fri Jan 31 00:00:00 UTC 2020, Mon Mar 30 00:00:00 UTC 2020, Tue Mar 31 00:00:00 UTC 2020, Wed Apr 01 00:00:00 UTC 2020]} From d0e00a6ce7100e338f1cb2974cc368fcb2ceb634 Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Wed, 31 May 2023 13:11:21 +0200 Subject: [PATCH 20/62] no more complaining from the static code analysis --- .../solution/src/${packageNameFolder}/Client.java | 2 +- .../solution/src/${packageNameFolder}/Context.java | 4 ++-- .../src/${packageNameFolder}/input/CommandParser.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java index ef9083b43a69..8f86b69d3347 100644 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java @@ -9,7 +9,7 @@ import java.io.IOException; import java.io.InputStreamReader; -public class Client { +public final class Client { private static final String PROMPT = "sort> "; private static final Context context = new Context(); // private static final Policy policy = new Policy(context); diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java index 8bf55254a6f6..684fe8733657 100644 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java @@ -15,8 +15,8 @@ public void setDates(List dates) { this.dates = dates; } - public void addDates(List dates) { - this.dates.addAll(dates); + public void addDates(List datesToAdd) { + this.dates.addAll(datesToAdd); } public void clearDates() { diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java index ed59fb698e31..a107e4aad4be 100644 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java @@ -8,7 +8,7 @@ import java.util.List; import java.util.TimeZone; -public class CommandParser { +public final class CommandParser { private static final String HELP_MESSAGE = """ From ed07c8105088ea163e378ed90380d4c71490c267 Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Wed, 31 May 2023 13:16:44 +0200 Subject: [PATCH 21/62] added Tests.txt --- .../resources/templates/java/maven_blackbox/exercise/Tests.txt | 0 .../resources/templates/java/maven_blackbox/solution/Tests.txt | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/main/resources/templates/java/maven_blackbox/exercise/Tests.txt create mode 100644 src/main/resources/templates/java/maven_blackbox/solution/Tests.txt diff --git a/src/main/resources/templates/java/maven_blackbox/exercise/Tests.txt b/src/main/resources/templates/java/maven_blackbox/exercise/Tests.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/main/resources/templates/java/maven_blackbox/solution/Tests.txt b/src/main/resources/templates/java/maven_blackbox/solution/Tests.txt new file mode 100644 index 000000000000..e69de29bb2d1 From b505bb3209dc7a48d52867a710879a059a93164a Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Sun, 4 Jun 2023 17:34:23 +0200 Subject: [PATCH 22/62] content for tests.txt and policy class with character limit --- .../java/maven_blackbox/solution/Tests.txt | 35 +++++++++++++++++++ .../src/${packageNameFolder}/Policy.java | 30 ++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Policy.java diff --git a/src/main/resources/templates/java/maven_blackbox/solution/Tests.txt b/src/main/resources/templates/java/maven_blackbox/solution/Tests.txt index e69de29bb2d1..50eb3340d94e 100644 --- a/src/main/resources/templates/java/maven_blackbox/solution/Tests.txt +++ b/src/main/resources/templates/java/maven_blackbox/solution/Tests.txt @@ -0,0 +1,35 @@ +sort> help +add: adds the given Dates to the list (format: YYYY-MM-DD) +clear: empties the list +help: prints this text +print: prints the list +sort: sorts the list +quit: quits the program +sort> +Unknown command. Use 'help' to show available commands. +sort> help +add: adds the given Dates to the list (format: YYYY-MM-DD) +clear: empties the list +help: prints this text +print: prints the list +sort: sorts the list +quit: quits the program +sort> 2015-04-01 +Unknown command. Use 'help' to show available commands. +sort> add 2015-04-01 +sort> print +[Wed Apr 01 02:00:00 CEST 2015] +sort> add 2016-04-01 +sort> add 2014-04-01 +sort> add 2015-05-01 2015-04-30 +sort> prinr +Unknown command. Use 'help' to show available commands. +sort> print +[Wed Apr 01 02:00:00 CEST 2015, Fri Apr 01 02:00:00 CEST 2016, Tue Apr 01 02:00:00 CEST 2014, Fri May 01 02:00:00 CEST 2015, Thu Apr 30 02:00:00 CEST 2015] +sort> sort +sort> print +[Tue Apr 01 02:00:00 CEST 2014, Wed Apr 01 02:00:00 CEST 2015, Thu Apr 30 02:00:00 CEST 2015, Fri May 01 02:00:00 CEST 2015, Fri Apr 01 02:00:00 CEST 2016] +sort> clear +sort> print +[] +sort> quit diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Policy.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Policy.java new file mode 100644 index 000000000000..4f050e6540e7 --- /dev/null +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Policy.java @@ -0,0 +1,30 @@ +package ${packageName}; + +public class Policy { + + /** + * @oracleIgnore + */ + private static final int DATES_SIZE_THRESHOLD = 10; + + private Context context; + + public Policy(Context context) { + this.context = context; + } + + /** + * Chooses a strategy depending on the number of date objects. + */ + public void configure() { + if (this.context.getDates().size() > DATES_SIZE_THRESHOLD) { + System.out.println("More than " + DATES_SIZE_THRESHOLD + + " dates, choosing merge sort!"); + this.context.setSortAlgorithm(new MergeSort()); + } else { + System.out.println("Less or equal than " + DATES_SIZE_THRESHOLD + + " dates. choosing quick sort!"); + this.context.setSortAlgorithm(new BubbleSort()); + } + } +} From be8f76de409153b61e9815309b1eb1755eeb207c Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Sun, 4 Jun 2023 21:08:06 +0200 Subject: [PATCH 23/62] respect 80 line character limit in policy class --- .../src/${packageNameFolder}/Policy.java | 30 ------------------- .../src/${packageNameFolder}/Policy.java | 6 ++-- 2 files changed, 4 insertions(+), 32 deletions(-) delete mode 100644 src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Policy.java diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Policy.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Policy.java deleted file mode 100644 index 4f050e6540e7..000000000000 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Policy.java +++ /dev/null @@ -1,30 +0,0 @@ -package ${packageName}; - -public class Policy { - - /** - * @oracleIgnore - */ - private static final int DATES_SIZE_THRESHOLD = 10; - - private Context context; - - public Policy(Context context) { - this.context = context; - } - - /** - * Chooses a strategy depending on the number of date objects. - */ - public void configure() { - if (this.context.getDates().size() > DATES_SIZE_THRESHOLD) { - System.out.println("More than " + DATES_SIZE_THRESHOLD - + " dates, choosing merge sort!"); - this.context.setSortAlgorithm(new MergeSort()); - } else { - System.out.println("Less or equal than " + DATES_SIZE_THRESHOLD - + " dates. choosing quick sort!"); - this.context.setSortAlgorithm(new BubbleSort()); - } - } -} diff --git a/src/main/resources/templates/java/solution/src/${packageNameFolder}/Policy.java b/src/main/resources/templates/java/solution/src/${packageNameFolder}/Policy.java index 81fecaa43e06..4f050e6540e7 100755 --- a/src/main/resources/templates/java/solution/src/${packageNameFolder}/Policy.java +++ b/src/main/resources/templates/java/solution/src/${packageNameFolder}/Policy.java @@ -18,10 +18,12 @@ public Policy(Context context) { */ public void configure() { if (this.context.getDates().size() > DATES_SIZE_THRESHOLD) { - System.out.println("More than " + DATES_SIZE_THRESHOLD + " dates, choosing merge sort!"); + System.out.println("More than " + DATES_SIZE_THRESHOLD + + " dates, choosing merge sort!"); this.context.setSortAlgorithm(new MergeSort()); } else { - System.out.println("Less or equal than " + DATES_SIZE_THRESHOLD + " dates. choosing quick sort!"); + System.out.println("Less or equal than " + DATES_SIZE_THRESHOLD + + " dates. choosing quick sort!"); this.context.setSortAlgorithm(new BubbleSort()); } } From 1c7501126bb46b7467176a52df29af5f72441639 Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Sun, 4 Jun 2023 21:22:36 +0200 Subject: [PATCH 24/62] new docker image --- .../java/test/blackbox/projectTemplate/pipeline.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/templates/java/test/blackbox/projectTemplate/pipeline.groovy b/src/main/resources/templates/java/test/blackbox/projectTemplate/pipeline.groovy index f85b74c096ff..942cb27a141a 100644 --- a/src/main/resources/templates/java/test/blackbox/projectTemplate/pipeline.groovy +++ b/src/main/resources/templates/java/test/blackbox/projectTemplate/pipeline.groovy @@ -8,7 +8,7 @@ runDejagnuTests = fileExists("./dejagnu") tool = getToolName() hasSecretTestFiles = secretTestFilesFolderExists() -dockerImage = "registry.git.fim.uni-passau.de/artemis/artemis-docker-images/dejagnu:20.0.1" +dockerImage = "ghcr.io/uni-passau-artemis/artemis-dejagnu:20" dockerFlags = "" secretTestVolume = "prog2_${tool}-secret" secret_volume_mount_path = "/secrets" From 54cccabfff5cae218755f8aa597d483921f741d6 Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Tue, 6 Jun 2023 14:21:34 +0200 Subject: [PATCH 25/62] updated readme once again --- .../templates/java/maven_blackbox/readme | 68 ++++++++++++------- 1 file changed, 45 insertions(+), 23 deletions(-) diff --git a/src/main/resources/templates/java/maven_blackbox/readme b/src/main/resources/templates/java/maven_blackbox/readme index 34849b86620c..f3699aaa36f4 100644 --- a/src/main/resources/templates/java/maven_blackbox/readme +++ b/src/main/resources/templates/java/maven_blackbox/readme @@ -4,59 +4,65 @@ In this exercise, we want to implement sorting algorithms and control the progra **Note:** This project is using `Maven`! You have to import the project as Maven project (not as Eclipse project) as otherwise, errors will occur and you won't be able to work on this exercise. -### Part 0: User Input +### Part 1: User Input First, there has to be a way for the user to communicate with the program. The `Client` class should handle the user input. The following commands need to be supported by your implementation: -`add date1 date2 ...` -Adds at least one date, but should also support multiple dates. -`sort` -Sorts the previously entered dates. -`clear` -Clears the list of dates. -`help` -Prints a dialog to the console that briefly explains the supported commands. -`print` -Prints the current list of dates to the console. -`quit` -Terminates the program. +`add date1 date2 ...`
+Adds at least one date, but should also support multiple dates.
+ +`sort`
+Sorts the previously entered dates.
+ +`clear`
+Clears the list of dates.
+ +`help`
+Prints a dialog to the console that briefly explains the supported commands.
+ +`print`
+Prints the current list of dates to the console.
+ +`quit`
+Terminates the program.
Using a `BufferedReader` might be a good starting point. -### Part 1: Sorting + +### Part 2: Sorting We need to implement two sorting algorithms, in this case `MergeSort` and `BubbleSort`. **You have the following tasks:** -1. [task][Implement Bubble Sort](testBubbleSort) +1. **Implement Bubble Sort**
Implement the method `performSort(List)` in the class `BubbleSort`. Make sure to follow the Bubble Sort algorithm exactly. -2. [task][Implement Merge Sort](testMergeSort) +2. **Implement Merge Sort**
Implement the method `performSort(List)` in the class `MergeSort`. Make sure to follow the Merge Sort algorithm exactly. -### Part 2: Strategy Pattern +### Part 3: Strategy Pattern We want the application to apply different algorithms for sorting a `List` of `Date` objects. Use the strategy pattern to select the right sorting algorithm at runtime. **You have the following tasks:** -1. [task][SortStrategy Interface](testClass[SortStrategy],testMethods[SortStrategy]) +1. **SortStrategy Interface**
Create a `SortStrategy` interface and adjust the sorting algorithms so that they implement this interface. -2. [task][Context Class](testAttributes[Context],testMethods[Context]) +2. **Context Class**
Create and implement a `Context` class following the below class diagram -3. [task][Context Policy](testConstructors[Policy],testAttributes[Policy],testMethods[Policy]) +3. **Context Policy**
Create and implement a `Policy` class following the below class diagram with a simple configuration mechanism: - 1. [task][Select MergeSort](testClass[MergeSort],testUseMergeSortForBigList) + 1. **Select MergeSort**
Select `MergeSort` when the List has more than 10 dates. - 2. [task][Select BubbleSort](testClass[BubbleSort],testUseBubbleSortForSmallList) + 2. **Select BubbleSort**
Select `BubbleSort` when the List has less or equal 10 dates. 4. Complete the `Client` class which demonstrates switching between two strategies at runtime. @@ -99,8 +105,24 @@ hide empty methods @enduml +### Part 4: Tests + +This section shows you, which tests are passed by your implementation. + +1. [task][Main Methode existiert](MainMethodChecker) + +2. [task][Alle Zeilen <= 80 Zeichen lang](LineLengthChecker) + +3. [task][Tests.txt existiert und nicht leer](FileExistsChecker) + +4. [task][Öffentliche Tests](dejagnu[public]) + +5. [task][Erweiterte Tests](dejagnu[advanced]) + +6. [task][Geheime Tests](dejagnu[secret]) + -### Part 3: Optional Challenges +### Part 4: Optional Challenges (These are not tested) From a6cced341727fb989fbe2ecf8355d63b0103bd38 Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Tue, 6 Jun 2023 14:23:33 +0200 Subject: [PATCH 26/62] make prefix more general --- .../java/test/blackbox/projectTemplate/pipeline.groovy | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/templates/java/test/blackbox/projectTemplate/pipeline.groovy b/src/main/resources/templates/java/test/blackbox/projectTemplate/pipeline.groovy index 942cb27a141a..eff235cf4ce2 100644 --- a/src/main/resources/templates/java/test/blackbox/projectTemplate/pipeline.groovy +++ b/src/main/resources/templates/java/test/blackbox/projectTemplate/pipeline.groovy @@ -10,7 +10,7 @@ hasSecretTestFiles = secretTestFilesFolderExists() dockerImage = "ghcr.io/uni-passau-artemis/artemis-dejagnu:20" dockerFlags = "" -secretTestVolume = "prog2_${tool}-secret" +secretTestVolume = "artemis_blackbox_${tool}-secret" secret_volume_mount_path = "/secrets" rebuildImage = true @@ -45,13 +45,13 @@ void testRunner() { private void setup() { // special jobs to run only for the solution repository if ("${env.JOB_NAME}" ==~ /.+-SOLUTION$/) { - dockerFlags += " -v prog2_maven-cache:/maven_cache" + dockerFlags += " -v artemis_blackbox_maven-cache:/maven_cache" if (runDejagnuTests) { createSecretTestVolume() } } else { - dockerFlags += " -v prog2_maven-cache:/maven_cache:ro" + dockerFlags += " -v artemis_blackbox_maven-cache:/maven_cache:ro" // if not solution repo, disallow network access from containers dockerFlags += " --network none" From b4d839ec7df3166778e33300fd60fc799c59e331 Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Tue, 6 Jun 2023 14:38:44 +0200 Subject: [PATCH 27/62] remove comma --- src/main/resources/templates/java/maven_blackbox/readme | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/templates/java/maven_blackbox/readme b/src/main/resources/templates/java/maven_blackbox/readme index f3699aaa36f4..1e8500b1b931 100644 --- a/src/main/resources/templates/java/maven_blackbox/readme +++ b/src/main/resources/templates/java/maven_blackbox/readme @@ -107,7 +107,7 @@ hide empty methods ### Part 4: Tests -This section shows you, which tests are passed by your implementation. +This section shows you which tests are passed by your implementation. 1. [task][Main Methode existiert](MainMethodChecker) From e47b76467887f1c417b87e4349a93d13c0c1c5af Mon Sep 17 00:00:00 2001 From: Benedikt Fein Date: Tue, 6 Jun 2023 15:20:08 +0200 Subject: [PATCH 28/62] Suggestions from Code Review. --- src/main/resources/config/application.yml | 2 +- .../java/maven_blackbox/exercise/pom.xml | 4 +- .../src/${packageNameFolder}/Client.java | 25 +---------- .../templates/java/maven_blackbox/readme | 12 ++--- .../java/maven_blackbox/solution/pom.xml | 4 +- .../src/${packageNameFolder}/Client.java | 1 - .../src/${packageNameFolder}/Context.java | 2 +- .../input/CommandParser.java | 4 +- .../test/blackbox/projectTemplate/pom.xml | 44 +------------------ ...ogramming-exercise-language.component.html | 2 +- 10 files changed, 19 insertions(+), 81 deletions(-) diff --git a/src/main/resources/config/application.yml b/src/main/resources/config/application.yml index d4395e4f60f4..745d795ef25f 100644 --- a/src/main/resources/config/application.yml +++ b/src/main/resources/config/application.yml @@ -63,7 +63,7 @@ artemis: java: # possible overrides: maven, gradle default: "ls1tum/artemis-maven-template:java17-16" - maven_blackbox: "registry.git.fim.uni-passau.de/artemis/artemis-docker-images/dejagnu:20" + maven_blackbox: "ghcr.io/uni-passau-artemis/artemis-dejagnu:20" kotlin: # possible overrides: maven, gradle default: "ls1tum/artemis-maven-template:java17-16" diff --git a/src/main/resources/templates/java/maven_blackbox/exercise/pom.xml b/src/main/resources/templates/java/maven_blackbox/exercise/pom.xml index adc393074c0d..c79c2d78d254 100644 --- a/src/main/resources/templates/java/maven_blackbox/exercise/pom.xml +++ b/src/main/resources/templates/java/maven_blackbox/exercise/pom.xml @@ -30,8 +30,8 @@ maven-compiler-plugin 3.10.1 - 17 - 17 + 20 + 20 diff --git a/src/main/resources/templates/java/maven_blackbox/exercise/src/${packageNameFolder}/Client.java b/src/main/resources/templates/java/maven_blackbox/exercise/src/${packageNameFolder}/Client.java index 97cc47af05dd..7e1ad95b3c41 100644 --- a/src/main/resources/templates/java/maven_blackbox/exercise/src/${packageNameFolder}/Client.java +++ b/src/main/resources/templates/java/maven_blackbox/exercise/src/${packageNameFolder}/Client.java @@ -3,27 +3,6 @@ import java.text.*; import java.util.*; -public final class Client { - - // TODO: Implement BubbleSort - // TODO: Implement MergeSort - - // TODO: Create a SortStrategy interface according to the UML class diagram - // TODO: Make the sorting algorithms implement this interface. - - // TODO: Create and implement a Context class according to the UML class diagram - // TODO: Create and implement a Policy class as described in the problem statement - - private Client() { - } - - /** - * Main method. - * Add code to demonstrate your implementation here. - * - * @param args command line arguments - */ - public static void main(String[] args) throws ParseException { - - } +public class Client { + // TODO: Create and implement interactive command line handling } diff --git a/src/main/resources/templates/java/maven_blackbox/readme b/src/main/resources/templates/java/maven_blackbox/readme index 1e8500b1b931..088bfe08acf8 100644 --- a/src/main/resources/templates/java/maven_blackbox/readme +++ b/src/main/resources/templates/java/maven_blackbox/readme @@ -109,17 +109,17 @@ hide empty methods This section shows you which tests are passed by your implementation. -1. [task][Main Methode existiert](MainMethodChecker) +1. [task][Main method exists](MainMethodChecker) -2. [task][Alle Zeilen <= 80 Zeichen lang](LineLengthChecker) +2. [task][All lines have <= 80 characters](LineLengthChecker) -3. [task][Tests.txt existiert und nicht leer](FileExistsChecker) +3. [task][Tests.txt exists and is not empty](FileExistsChecker) -4. [task][Öffentliche Tests](dejagnu[public]) +4. [task][Public Tests](dejagnu[public]) -5. [task][Erweiterte Tests](dejagnu[advanced]) +5. [task][Advanced Tests](dejagnu[advanced]) -6. [task][Geheime Tests](dejagnu[secret]) +6. [task][Secret Tests](dejagnu[secret]) ### Part 4: Optional Challenges diff --git a/src/main/resources/templates/java/maven_blackbox/solution/pom.xml b/src/main/resources/templates/java/maven_blackbox/solution/pom.xml index cc9188f80be9..7359834a81cd 100644 --- a/src/main/resources/templates/java/maven_blackbox/solution/pom.xml +++ b/src/main/resources/templates/java/maven_blackbox/solution/pom.xml @@ -30,8 +30,8 @@ maven-compiler-plugin 3.10.1 - 17 - 17 + 20 + 20 diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java index 8f86b69d3347..2afe6c52240e 100644 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java @@ -3,7 +3,6 @@ import ${packageName}.input.Command; import ${packageName}.input.CommandParser; import ${packageName}.input.InvalidCommandException; -import ${packageName}.Context; import java.io.BufferedReader; import java.io.IOException; diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java index 684fe8733657..9c635ee7a7ec 100644 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java @@ -3,7 +3,7 @@ import java.util.*; public class Context { - private SortStrategy sortAlgorithm = new MergeSort(); + private SortStrategy sortAlgorithm = new MergeSort(); private List dates = new ArrayList<>(); diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java index a107e4aad4be..5fb8f11dbb71 100644 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java @@ -73,8 +73,8 @@ private static Command.AddCommand parseAddCommand(final String[] args) return new Command.AddCommand(Collections.unmodifiableList(dates)); } - private static Date parseDateInput(String input) throws ParseException { - SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + private static Date parseDateInput(final String input) throws ParseException { + final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); formatter.setTimeZone(TimeZone.getTimeZone("UTC")); formatter.setLenient(false); return formatter.parse(input); diff --git a/src/main/resources/templates/java/test/blackbox/projectTemplate/pom.xml b/src/main/resources/templates/java/test/blackbox/projectTemplate/pom.xml index 30711c5550bb..2b04779323a1 100644 --- a/src/main/resources/templates/java/test/blackbox/projectTemplate/pom.xml +++ b/src/main/resources/templates/java/test/blackbox/projectTemplate/pom.xml @@ -22,48 +22,8 @@ maven-compiler-plugin 3.10.1 - 17 - 17 - - - - org.apache.maven.plugins - maven-enforcer-plugin - 3.2.1 - - - enforce-no-student-code-in-trusted-packages - process-classes - - enforce - - - - - - - - ${project.build.outputDirectory}/ch/qos/logback/ - ${project.build.outputDirectory}/com/intellij/ - ${project.build.outputDirectory}/com/sun/ - ${project.build.outputDirectory}/de/tum/in/test/api/ - ${project.build.outputDirectory}/java/ - ${project.build.outputDirectory}/javax/ - ${project.build.outputDirectory}/jdk/ - ${project.build.outputDirectory}/net/jqwik/ - ${project.build.outputDirectory}/org/apache/ - ${project.build.outputDirectory}/org/assertj/ - ${project.build.outputDirectory}/org/eclipse/ - ${project.build.outputDirectory}/org/jacoco/ - ${project.build.outputDirectory}/org/json/ - ${project.build.outputDirectory}/org/junit/ - ${project.build.outputDirectory}/org/opentest4j/ - ${project.build.outputDirectory}/sun/ - ${project.build.outputDirectory}/org/gradle/ - ${project.build.outputDirectory}/worker/org/gradle/ - - - + 20 + 20 diff --git a/src/main/webapp/app/exercises/programming/manage/update/update-components/programming-exercise-language.component.html b/src/main/webapp/app/exercises/programming/manage/update/update-components/programming-exercise-language.component.html index c42088765d46..349ed00821ba 100644 --- a/src/main/webapp/app/exercises/programming/manage/update/update-components/programming-exercise-language.component.html +++ b/src/main/webapp/app/exercises/programming/manage/update/update-components/programming-exercise-language.component.html @@ -34,7 +34,7 @@ !isImportFromFile && !programmingExercise.id && programmingExercise.programmingLanguage === ProgrammingLanguage.JAVA && - programmingExercise.projectType != ProjectType.MAVEN_BLACKBOX + programmingExercise.projectType !== ProjectType.MAVEN_BLACKBOX " > Date: Tue, 6 Jun 2023 16:35:23 +0200 Subject: [PATCH 29/62] static code analysis fixes --- .../src/${packageNameFolder}/Client.java | 9 ++++- .../src/${packageNameFolder}/Context.java | 8 ++++ .../${packageNameFolder}/input/Command.java | 40 ++++++++++++++++--- .../input/CommandParser.java | 15 ++++++- 4 files changed, 62 insertions(+), 10 deletions(-) diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java index 2afe6c52240e..0192309c4452 100644 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java @@ -10,13 +10,18 @@ public final class Client { private static final String PROMPT = "sort> "; - private static final Context context = new Context(); - // private static final Policy policy = new Policy(context); + private final Context context = new Context(); + // private final Policy policy = new Policy(context); private Client() { throw new IllegalCallerException("utility class"); } + /** + * The entrypoint of the program. + * + * @param args command line arguments + */ public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java index 9c635ee7a7ec..a9e62818bb74 100644 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Context.java @@ -15,10 +15,18 @@ public void setDates(List dates) { this.dates = dates; } + /** + * Adds the given dates to the internal list of dates. + * + * @param datesToAdd The dates that are added. + */ public void addDates(List datesToAdd) { this.dates.addAll(datesToAdd); } + /** + * Removes all dates from the list of dates. + */ public void clearDates() { this.dates = new ArrayList<>(); } diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/Command.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/Command.java index ccf0ca40cd8e..7d1d98eb18f2 100644 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/Command.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/Command.java @@ -4,10 +4,38 @@ import java.util.List; public sealed interface Command { - record AddCommand(List values) implements Command {} - record ClearCommand() implements Command {} - record HelpCommand(String helpMessage) implements Command {} - record PrintCommand() implements Command {} - record QuitCommand() implements Command {} - record SortCommand() implements Command {} + /** + * Represents an add command. This ensures that only a list of dates can be + * added. + * + * @param dates The list of dates that is added to the list. + */ + record AddCommand(List dates) implements Command { } + + /** + * Represents a clear command. + */ + record ClearCommand() implements Command { } + + /** + * Reprents a help command. + * + * @param helpMessage The help message that is printed on the console. + */ + record HelpCommand(String helpMessage) implements Command { } + + /** + * Represents a print command. + */ + record PrintCommand() implements Command { } + + /** + * Represents a quit command. + */ + record QuitCommand() implements Command { } + + /** + * Represents a sort command. + */ + record SortCommand() implements Command { } } diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java index 5fb8f11dbb71..f2398c911c69 100644 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java @@ -23,6 +23,15 @@ private CommandParser() { throw new IllegalCallerException("utility class"); } + /** + * Parses a line that was entered via the console. The first word of the + * input determines the command, and possible arguments (if applicable) + * can be appended, separated by whitespaces. + * + * @param inputLine + * @return + * @throws InvalidCommandException + */ public static Command parseCommand(final String inputLine) throws InvalidCommandException { final String[] args = inputLine.strip().split("\\s+"); @@ -73,8 +82,10 @@ private static Command.AddCommand parseAddCommand(final String[] args) return new Command.AddCommand(Collections.unmodifiableList(dates)); } - private static Date parseDateInput(final String input) throws ParseException { - final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + private static Date parseDateInput(final String input) + throws ParseException { + final SimpleDateFormat formatter + = new SimpleDateFormat("yyyy-MM-dd"); formatter.setTimeZone(TimeZone.getTimeZone("UTC")); formatter.setLenient(false); return formatter.parse(input); From d193d1a5a9c3b90430678277f1370695e421f210 Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Tue, 6 Jun 2023 17:00:20 +0200 Subject: [PATCH 30/62] further improvements --- .../java/maven_blackbox/exercise/pom.xml | 7 ------- .../java/maven_blackbox/solution/pom.xml | 7 ------- .../src/${packageNameFolder}/Client.java | 16 ++++++++-------- .../input/CommandParser.java | 6 +++--- 4 files changed, 11 insertions(+), 25 deletions(-) diff --git a/src/main/resources/templates/java/maven_blackbox/exercise/pom.xml b/src/main/resources/templates/java/maven_blackbox/exercise/pom.xml index c79c2d78d254..4c061e00f8a0 100644 --- a/src/main/resources/templates/java/maven_blackbox/exercise/pom.xml +++ b/src/main/resources/templates/java/maven_blackbox/exercise/pom.xml @@ -10,13 +10,6 @@ UTF-8 - - - org.apache.commons - commons-lang3 - 3.12.0 - - ${project.basedir}/src diff --git a/src/main/resources/templates/java/maven_blackbox/solution/pom.xml b/src/main/resources/templates/java/maven_blackbox/solution/pom.xml index 7359834a81cd..51e3093b50cc 100644 --- a/src/main/resources/templates/java/maven_blackbox/solution/pom.xml +++ b/src/main/resources/templates/java/maven_blackbox/solution/pom.xml @@ -10,13 +10,6 @@ UTF-8 - - - org.apache.commons - commons-lang3 - 3.12.0 - - ${project.basedir}/src diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java index 0192309c4452..27c217a54e9a 100644 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/Client.java @@ -10,8 +10,8 @@ public final class Client { private static final String PROMPT = "sort> "; - private final Context context = new Context(); - // private final Policy policy = new Policy(context); + private static final Context CONTEXT = new Context(); + // private static final Policy POLICY = new Policy(context); private Client() { throw new IllegalCallerException("utility class"); @@ -20,7 +20,7 @@ private Client() { /** * The entrypoint of the program. * - * @param args command line arguments + * @param args The command line arguments. */ public static void main(String[] args) throws IOException { BufferedReader in @@ -39,16 +39,16 @@ public static void main(String[] args) throws IOException { private static CommandRunResult runCommand(final Command command) { if (command instanceof Command.AddCommand addCommand) { - context.addDates(addCommand.values()); + CONTEXT.addDates(addCommand.dates()); } else if (command instanceof Command.SortCommand) { - // policy.configure(); - context.sort(); + // POLICY.configure(); + CONTEXT.sort(); } else if (command instanceof Command.ClearCommand) { - context.clearDates(); + CONTEXT.clearDates(); } else if (command instanceof Command.HelpCommand helpCommand) { System.out.println(helpCommand.helpMessage()); } else if (command instanceof Command.PrintCommand) { - System.out.println(context.getDates()); + System.out.println(CONTEXT.getDates()); } else if (command instanceof Command.QuitCommand) { return CommandRunResult.QUIT; } else { diff --git a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java index f2398c911c69..fe706430d318 100644 --- a/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java +++ b/src/main/resources/templates/java/maven_blackbox/solution/src/${packageNameFolder}/input/CommandParser.java @@ -28,9 +28,9 @@ private CommandParser() { * input determines the command, and possible arguments (if applicable) * can be appended, separated by whitespaces. * - * @param inputLine - * @return - * @throws InvalidCommandException + * @param inputLine The console input. + * @return The corresponding command. + * @throws InvalidCommandException If the command could not be parsed. */ public static Command parseCommand(final String inputLine) throws InvalidCommandException { From b041464910f2526df008ae825f57d642ea3e2a0a Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Tue, 6 Jun 2023 17:10:52 +0200 Subject: [PATCH 31/62] improve front-end hack --- .../manage/update/programming-exercise-update.component.html | 4 ++-- .../manage/update/programming-exercise-update.component.ts | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.html b/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.html index 7b9f3cb86062..bf047ab26dbb 100644 --- a/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.html +++ b/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.html @@ -84,10 +84,10 @@

Date: Tue, 13 Jun 2023 09:47:09 +0200 Subject: [PATCH 32/62] fix dejagnu to testsuite folder for dejagnu 1.6.3 --- .../blackbox/projectTemplate/pipeline.groovy | 24 +++++++++---------- .../test/blackbox/projectTemplate/pom.xml | 2 +- .../${packageNameFolder}.tests/advanced.exp | 0 .../${packageNameFolder}.tests/public.exp | 0 .../${packageNameFolder}.tests/secret.exp | 0 .../{dejagnu => testsuite}/config/default.exp | 0 .../lib/${packageNameFile}.exp | 0 .../testfiles/public/.gitkeep | 0 .../testfiles/secret/.gitkeep | 0 9 files changed, 13 insertions(+), 13 deletions(-) rename src/main/resources/templates/java/test/blackbox/projectTemplate/{dejagnu => testsuite}/${packageNameFolder}.tests/advanced.exp (100%) rename src/main/resources/templates/java/test/blackbox/projectTemplate/{dejagnu => testsuite}/${packageNameFolder}.tests/public.exp (100%) rename src/main/resources/templates/java/test/blackbox/projectTemplate/{dejagnu => testsuite}/${packageNameFolder}.tests/secret.exp (100%) rename src/main/resources/templates/java/test/blackbox/projectTemplate/{dejagnu => testsuite}/config/default.exp (100%) rename src/main/resources/templates/java/test/blackbox/projectTemplate/{dejagnu => testsuite}/lib/${packageNameFile}.exp (100%) rename src/main/resources/templates/java/test/blackbox/projectTemplate/{dejagnu => testsuite}/testfiles/public/.gitkeep (100%) rename src/main/resources/templates/java/test/blackbox/projectTemplate/{dejagnu => testsuite}/testfiles/secret/.gitkeep (100%) diff --git a/src/main/resources/templates/java/test/blackbox/projectTemplate/pipeline.groovy b/src/main/resources/templates/java/test/blackbox/projectTemplate/pipeline.groovy index eff235cf4ce2..3ad4a11767b6 100644 --- a/src/main/resources/templates/java/test/blackbox/projectTemplate/pipeline.groovy +++ b/src/main/resources/templates/java/test/blackbox/projectTemplate/pipeline.groovy @@ -2,9 +2,9 @@ MAIN_CLASS = "notFound" // default value, will be replaced in Build stage OUT_DIR = "target/surefire-reports" mavenFlags = "-B" -testfiles_base_path = "./dejagnu/testfiles" +testfiles_base_path = "./testsuite/testfiles" -runDejagnuTests = fileExists("./dejagnu") +runDejagnuTests = fileExists("./testsuite") tool = getToolName() hasSecretTestFiles = secretTestFilesFolderExists() @@ -67,7 +67,7 @@ private void createSecretTestVolume() { docker.image(dockerImage).inside("-v ${secretTestVolume}:${secret_volume_mount_path}") { c -> sh """ rm -rf ${secret_volume_mount_path}/* - cp dejagnu/${tool}.tests/secret.exp ${secret_volume_mount_path}/secret.exp + cp testsuite/${tool}.tests/secret.exp ${secret_volume_mount_path}/secret.exp """ if (hasSecretTestFiles) { @@ -137,19 +137,19 @@ private void runDejagnuTestStep(String step, int timeoutSeconds) { catchError() { timeout(time: timeoutSeconds, unit: 'SECONDS') { sh """ - cd dejagnu || exit + cd testsuite || exit rm ${tool}.log || true runtest --tool ${tool} ${step}.exp || true """ } } - sh("""pipeline-helper -o customFeedbacks -d "dejagnu[${step}]" dejagnu/${tool}.log""") + sh("""pipeline-helper -o customFeedbacks -d "dejagnu[${step}]" testsuite/${tool}.log""") } /** * Extracts the Dejagnu tool name from the folder names. *

- * E.g., for a folder {@code dejagnu/ggt.tests/} the tool name is {@code ggt}. + * E.g., for a folder {@code testsuite/gcd.tests/} the tool name is {@code gcd}. * * @return The Dejagnu tool name. */ @@ -157,7 +157,7 @@ private String getToolName() { // Java Files API gets blocked by Jenkins sandbox return sh( - script: """find dejagnu -name "*.tests" -type d -printf "%f" | cut --delimiter=. -f 1""", + script: """find testsuite -name "*.tests" -type d -printf "%f" | cut --delimiter=. -f 1""", returnStdout: true ).trim() } @@ -189,10 +189,10 @@ private void setMainClass() { */ private void applyExpectScriptReplacements() { sh """ - sed -i "s#CLASSPATH#../target/classes#" dejagnu/config/default.exp - sed -i "s#MAIN_CLASS#${MAIN_CLASS}#" dejagnu/config/default.exp + sed -i "s#CLASSPATH#../target/classes#" testsuite/config/default.exp + sed -i "s#MAIN_CLASS#${MAIN_CLASS}#" testsuite/config/default.exp - sed -i "s#TESTFILES_DIRECTORY#../${testfiles_base_path}#" dejagnu/${tool}.tests/*.exp + sed -i "s#TESTFILES_DIRECTORY#../${testfiles_base_path}#" testsuite/${tool}.tests/*.exp """ } @@ -203,7 +203,7 @@ private void applyExpectScriptReplacements() { * those files during the public tests. */ private void removeSecretFiles() { - secretExp = "dejagnu/${tool}.tests/secret.exp" + secretExp = "testsuite/${tool}.tests/secret.exp" if (fileExists(secretExp)) { sh("rm ${secretExp}") } @@ -218,7 +218,7 @@ private void removeSecretFiles() { */ private void restoreSecretFiles() { if (runDejagnuTests) { - sh("cp ${secret_volume_mount_path}/secret.exp dejagnu/${tool}.tests/secret.exp") + sh("cp ${secret_volume_mount_path}/secret.exp testsuite/${tool}.tests/secret.exp") } if (hasSecretTestFiles) { diff --git a/src/main/resources/templates/java/test/blackbox/projectTemplate/pom.xml b/src/main/resources/templates/java/test/blackbox/projectTemplate/pom.xml index 2b04779323a1..8772556bd411 100644 --- a/src/main/resources/templates/java/test/blackbox/projectTemplate/pom.xml +++ b/src/main/resources/templates/java/test/blackbox/projectTemplate/pom.xml @@ -20,7 +20,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.10.1 + 3.11.0 20 20 diff --git a/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/advanced.exp b/src/main/resources/templates/java/test/blackbox/projectTemplate/testsuite/${packageNameFolder}.tests/advanced.exp similarity index 100% rename from src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/advanced.exp rename to src/main/resources/templates/java/test/blackbox/projectTemplate/testsuite/${packageNameFolder}.tests/advanced.exp diff --git a/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/public.exp b/src/main/resources/templates/java/test/blackbox/projectTemplate/testsuite/${packageNameFolder}.tests/public.exp similarity index 100% rename from src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/public.exp rename to src/main/resources/templates/java/test/blackbox/projectTemplate/testsuite/${packageNameFolder}.tests/public.exp diff --git a/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/secret.exp b/src/main/resources/templates/java/test/blackbox/projectTemplate/testsuite/${packageNameFolder}.tests/secret.exp similarity index 100% rename from src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/${packageNameFolder}.tests/secret.exp rename to src/main/resources/templates/java/test/blackbox/projectTemplate/testsuite/${packageNameFolder}.tests/secret.exp diff --git a/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/config/default.exp b/src/main/resources/templates/java/test/blackbox/projectTemplate/testsuite/config/default.exp similarity index 100% rename from src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/config/default.exp rename to src/main/resources/templates/java/test/blackbox/projectTemplate/testsuite/config/default.exp diff --git a/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/lib/${packageNameFile}.exp b/src/main/resources/templates/java/test/blackbox/projectTemplate/testsuite/lib/${packageNameFile}.exp similarity index 100% rename from src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/lib/${packageNameFile}.exp rename to src/main/resources/templates/java/test/blackbox/projectTemplate/testsuite/lib/${packageNameFile}.exp diff --git a/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/testfiles/public/.gitkeep b/src/main/resources/templates/java/test/blackbox/projectTemplate/testsuite/testfiles/public/.gitkeep similarity index 100% rename from src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/testfiles/public/.gitkeep rename to src/main/resources/templates/java/test/blackbox/projectTemplate/testsuite/testfiles/public/.gitkeep diff --git a/src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/testfiles/secret/.gitkeep b/src/main/resources/templates/java/test/blackbox/projectTemplate/testsuite/testfiles/secret/.gitkeep similarity index 100% rename from src/main/resources/templates/java/test/blackbox/projectTemplate/dejagnu/testfiles/secret/.gitkeep rename to src/main/resources/templates/java/test/blackbox/projectTemplate/testsuite/testfiles/secret/.gitkeep From dde809a8e80a9dfe4611da6f923ae6d7016b8b68 Mon Sep 17 00:00:00 2001 From: "Felix T.J. Dietrich" Date: Mon, 5 Jun 2023 19:42:39 +0200 Subject: [PATCH 33/62] Development: Add script to generate a code coverage table automatically (#6501) --- .github/PULL_REQUEST_TEMPLATE.md | 2 + .../generate_code_cov_table/.gitignore | 3 + .../generate_code_cov_table/README.md | 96 +++++++ .../generate_code_cov_table/env.example | 2 + .../generate_code_cov_table.py | 245 ++++++++++++++++++ .../generate_code_cov_table/requirements.txt | 6 + 6 files changed, 354 insertions(+) create mode 100644 supporting_scripts/generate_code_cov_table/.gitignore create mode 100644 supporting_scripts/generate_code_cov_table/README.md create mode 100644 supporting_scripts/generate_code_cov_table/env.example create mode 100644 supporting_scripts/generate_code_cov_table/generate_code_cov_table.py create mode 100644 supporting_scripts/generate_code_cov_table/requirements.txt diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index b8616041d7fb..809d3c455293 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -84,6 +84,8 @@ Prerequisites: + + diff --git a/src/main/resources/templates/java/test/blackbox/projectTemplate/readme.md b/src/main/resources/templates/java/test/blackbox/projectTemplate/readme.md index fec7ea136127..73823d184e3f 100644 --- a/src/main/resources/templates/java/test/blackbox/projectTemplate/readme.md +++ b/src/main/resources/templates/java/test/blackbox/projectTemplate/readme.md @@ -1,8 +1,14 @@ ## Test Repository instructions #### Project structure -Make sure that the package structure of your test classes is equivalent to the package structure of your base and solution repository. -Otherwise during the test run maven will not be able to find the imported classes in your test files. +The `testsuite` directory contains the test definitions used by DejaGnu. +`config/default.exp` contains the base setup shared by all tests. +The actual tests are split up into `public.exp`, `advanced.exp`, and `secret.exp`. + +In the `testfiles/` additional support files can be provided that can be loaded by the program under test. +The `secret/` directory can contain files that should only be readable during execution of the `secret` tests, but not during the other two. + +To make the `secret` tests actually secret (i.e. results not visible to the student), you need to configure the test visibility in the grading configuration of the exercise. #### Static Code Analysis The pom.xml contains dependencies for the execution of static code analysis, if the option is active for this programming exercise. diff --git a/src/main/resources/templates/java/test/blackbox/projectTemplate/testsuite/${packageNameFolder}.tests/advanced.exp b/src/main/resources/templates/java/test/blackbox/projectTemplate/testsuite/${packageNameFolder}.tests/advanced.exp index 6e551fda09fe..1c5783d4a861 100644 --- a/src/main/resources/templates/java/test/blackbox/projectTemplate/testsuite/${packageNameFolder}.tests/advanced.exp +++ b/src/main/resources/templates/java/test/blackbox/projectTemplate/testsuite/${packageNameFolder}.tests/advanced.exp @@ -1,6 +1,6 @@ # Sorting Testdata -# Non-Public Tests +# Tests for advanced functionality PROGRAM_test {add 2020-03-31} {} PROGRAM_test {add 2020-03-30} {} PROGRAM_test {add 2020-04-01} {} diff --git a/src/main/resources/templates/jenkins/java/blackbox/regularRuns/pipeline.groovy b/src/main/resources/templates/jenkins/java/blackbox/regularRuns/pipeline.groovy index 1ade500e0534..2775a6bc9540 100644 --- a/src/main/resources/templates/jenkins/java/blackbox/regularRuns/pipeline.groovy +++ b/src/main/resources/templates/jenkins/java/blackbox/regularRuns/pipeline.groovy @@ -8,11 +8,11 @@ runDejagnuTests = fileExists("./testsuite") tool = getToolName() hasSecretTestFiles = secretTestFilesFolderExists() -dockerImage = "ghcr.io/uni-passau-artemis/artemis-dejagnu:20" -dockerFlags = "" +dockerImage = "#dockerImage" +dockerFlags = "#dockerArgs" secretTestVolume = "artemis_blackbox_${tool}-secret" secret_volume_mount_path = "/secrets" -rebuildImage = true +isStaticCodeAnalysisEnabled = #isStaticCodeAnalysisEnabled /** * Main function called by Jenkins. @@ -239,6 +239,10 @@ private boolean secretTestFilesFolderExists() { * Runs the static code analysis */ private void staticCodeAnalysis() { + if (!isStaticCodeAnalysisEnabled) { + return + } + stage("StaticCodeAnalysis") { docker.image(dockerImage).inside(dockerFlags) { c -> /* From fa394e4c28c8a6dda09575ed67e1dc31f8472662 Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Mon, 10 Jul 2023 12:28:27 +0200 Subject: [PATCH 47/62] missing dollar sign escape --- .../templates/jenkins/java/blackbox/regularRuns/pipeline.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/templates/jenkins/java/blackbox/regularRuns/pipeline.groovy b/src/main/resources/templates/jenkins/java/blackbox/regularRuns/pipeline.groovy index 2775a6bc9540..146fd914e08d 100644 --- a/src/main/resources/templates/jenkins/java/blackbox/regularRuns/pipeline.groovy +++ b/src/main/resources/templates/jenkins/java/blackbox/regularRuns/pipeline.groovy @@ -157,7 +157,7 @@ private String getToolName() { // Java Files API gets blocked by Jenkins sandbox return sh( - script: """find testsuite -name "*.tests" -type d -printf "%f" | sed 's#.tests$##'""", + script: """find testsuite -name "*.tests" -type d -printf "%f" | sed 's#.tests\$##'""", returnStdout: true ).trim() } From 4dbbd8951f2847db2aacdc200ccb583851db95b2 Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Thu, 20 Jul 2023 16:24:51 +0200 Subject: [PATCH 48/62] regex for blackbox project type and pipeline groovy adjustments --- .../java/blackbox/regularRuns/pipeline.groovy | 38 ++++++------------- .../programming-exercise-update.component.ts | 34 +++++++++++++---- src/main/webapp/i18n/de/exercise.json | 3 +- src/main/webapp/i18n/en/exercise.json | 3 +- 4 files changed, 43 insertions(+), 35 deletions(-) diff --git a/src/main/resources/templates/jenkins/java/blackbox/regularRuns/pipeline.groovy b/src/main/resources/templates/jenkins/java/blackbox/regularRuns/pipeline.groovy index 146fd914e08d..5727c5168d44 100644 --- a/src/main/resources/templates/jenkins/java/blackbox/regularRuns/pipeline.groovy +++ b/src/main/resources/templates/jenkins/java/blackbox/regularRuns/pipeline.groovy @@ -10,7 +10,7 @@ hasSecretTestFiles = secretTestFilesFolderExists() dockerImage = "#dockerImage" dockerFlags = "#dockerArgs" -secretTestVolume = "artemis_blackbox_${tool}-secret" +// secretTestVolume = "artemis_blackbox_${tool}-secret" secret_volume_mount_path = "/secrets" isStaticCodeAnalysisEnabled = #isStaticCodeAnalysisEnabled @@ -19,7 +19,7 @@ isStaticCodeAnalysisEnabled = #isStaticCodeAnalysisEnabled */ void testRunner() { setup() - removeSecretFiles() + //removeSecretFiles() build() // catchError-block: execute following steps even if the one inside the @@ -47,9 +47,9 @@ private void setup() { if ("${env.JOB_NAME}" ==~ /.+-SOLUTION$/) { dockerFlags += " -v artemis_blackbox_maven-cache:/maven_cache" - if (runDejagnuTests) { - createSecretTestVolume() - } + //if (runDejagnuTests) { + // createSecretTestVolume() + //} } else { dockerFlags += " -v artemis_blackbox_maven-cache:/maven_cache:ro" @@ -109,6 +109,13 @@ private void customCheckers() { * Runs Dejagnu scripts. */ private void dejagnuTests() { + stage('Secret Tests') { + docker.image(dockerImage).inside(dockerFlags) { c -> + applyExpectScriptReplacements() + runDejagnuTestStep("secret", 60) + removeSecretFiles() + } + } stage('Public+Advanced Tests') { docker.image(dockerImage).inside(dockerFlags) { c -> applyExpectScriptReplacements() @@ -117,14 +124,6 @@ private void dejagnuTests() { runDejagnuTestStep("advanced", 60) } } - - stage('Secret Tests') { - docker.image(dockerImage).inside(dockerFlags + " -v ${secretTestVolume}:${secret_volume_mount_path}:ro") { c -> - restoreSecretFiles() - applyExpectScriptReplacements() - runDejagnuTestStep("secret", 60) - } - } } /** @@ -213,19 +212,6 @@ private void removeSecretFiles() { } } -/** - * Copies the secret files from the Docker volume back into the working directory. - */ -private void restoreSecretFiles() { - if (runDejagnuTests) { - sh("cp ${secret_volume_mount_path}/secret.exp testsuite/${tool}.tests/secret.exp") - } - - if (hasSecretTestFiles) { - sh("cp -vr ${secret_volume_mount_path}/secret ${testfiles_base_path}/secret") - } -} - /** * Checks if a folder with secret Dejagnu test files exists. * diff --git a/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.ts b/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.ts index 23755aadf571..2905f5c91007 100644 --- a/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.ts +++ b/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.ts @@ -83,6 +83,9 @@ export class ProgrammingExerciseUpdateComponent implements OnInit { // with the restriction to a-z,A-Z,_ as "Java letter" and 0-9 as digits due to JavaScript/Browser Unicode character class limitations packageNamePatternForJavaKotlin = '^(?!.*(?:\\.|^)(?:abstract|continue|for|new|switch|assert|default|if|package|synchronized|boolean|do|goto|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while|_|true|false|null)(?:\\.|$))[A-Z_a-z][0-9A-Z_a-z]*(?:\\.[A-Z_a-z][0-9A-Z_a-z]*)*$'; + // No dots allowed for the blackbox project type, because the folder naming works slightly different here. + packageNamePatternForJavaBlackbox = + '^(?!.*(?:\\.|^)(?:abstract|continue|for|new|switch|assert|default|if|package|synchronized|boolean|do|goto|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while|_|true|false|null)(?:\\.|$))[A-Z_a-z][0-9A-Z_a-z]*(?:[A-Z_a-z][0-9A-Z_a-z]*)*$'; // Swift package name Regex derived from (https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID412), // with the restriction to a-z,A-Z as "Swift letter" and 0-9 as digits where no separators are allowed appNamePatternForSwift = @@ -674,12 +677,13 @@ export class ProgrammingExerciseUpdateComponent implements OnInit { * Sets the regex pattern for the package name for the selected programming language. * * @param language to choose from + * @param useBlackboxPattern whether to allow points in the regex */ - setPackageNamePattern(language: ProgrammingLanguage) { + setPackageNamePattern(language: ProgrammingLanguage, useBlackboxPattern = false) { if (language === ProgrammingLanguage.SWIFT) { this.packageNamePattern = this.appNamePatternForSwift; } else { - this.packageNamePattern = this.packageNamePatternForJavaKotlin; + this.packageNamePattern = useBlackboxPattern ? this.packageNamePatternForJavaBlackbox : this.packageNamePatternForJavaKotlin; } } @@ -699,6 +703,8 @@ export class ProgrammingExerciseUpdateComponent implements OnInit { } } this.selectedProjectType = projectType; + const useBlackboxPattern = projectType === ProjectType.MAVEN_BLACKBOX; + this.setPackageNamePattern(this.programmingExercise.programmingLanguage!, useBlackboxPattern); return projectType; } @@ -911,12 +917,26 @@ export class ProgrammingExerciseUpdateComponent implements OnInit { }); } else { const patternMatchJavaKotlin: RegExpMatchArray | null = this.programmingExercise.packageName.match(this.packageNamePatternForJavaKotlin); + const patternMatchJavaBlackbox: RegExpMatchArray | null = this.programmingExercise.packageName.match(this.packageNamePatternForJavaBlackbox); const patternMatchSwift: RegExpMatchArray | null = this.programmingExercise.packageName.match(this.appNamePatternForSwift); - if (this.programmingExercise.programmingLanguage === ProgrammingLanguage.JAVA && (patternMatchJavaKotlin === null || patternMatchJavaKotlin.length === 0)) { - validationErrorReasons.push({ - translateKey: 'artemisApp.exercise.form.packageName.pattern.JAVA', - translateValues: {}, - }); + const projectTypeDependentPatternMatch: RegExpMatchArray | null = + this.programmingExercise.projectType === ProjectType.MAVEN_BLACKBOX ? patternMatchJavaBlackbox : patternMatchJavaKotlin; + + if ( + this.programmingExercise.programmingLanguage === ProgrammingLanguage.JAVA && + (projectTypeDependentPatternMatch === null || projectTypeDependentPatternMatch.length === 0) + ) { + if (this.programmingExercise.projectType === ProjectType.MAVEN_BLACKBOX) { + validationErrorReasons.push({ + translateKey: 'artemisApp.exercise.form.packageName.pattern.JAVA_BLACKBOX', + translateValues: {}, + }); + } else { + validationErrorReasons.push({ + translateKey: 'artemisApp.exercise.form.packageName.pattern.JAVA', + translateValues: {}, + }); + } } else if (this.programmingExercise.programmingLanguage === ProgrammingLanguage.KOTLIN && (patternMatchJavaKotlin === null || patternMatchJavaKotlin.length === 0)) { validationErrorReasons.push({ translateKey: 'artemisApp.exercise.form.packageName.pattern.KOTLIN', diff --git a/src/main/webapp/i18n/de/exercise.json b/src/main/webapp/i18n/de/exercise.json index 83f6fefaad10..266f0f68940b 100644 --- a/src/main/webapp/i18n/de/exercise.json +++ b/src/main/webapp/i18n/de/exercise.json @@ -218,7 +218,8 @@ "pattern": { "JAVA": "Der Package-Name muss aus einem oder mehreren gültigen Java-Bezeichnern bestehen, die mit '.' getrennt sind, z.B. \"net.java\"!", "KOTLIN": "Der Package-Name muss aus einem oder mehreren gültigen Kotlin-Bezeichnern bestehen, die mit '.' getrennt sind, z.B. \"net.kotlin\"!", - "SWIFT": "Der Package-Name muss aus einem oder mehreren gültigen Swift-Bezeichnern bestehen, die nicht voneinander separiert sind, z.B. \"SwiftEx\"!" + "SWIFT": "Der Package-Name muss aus einem oder mehreren gültigen Swift-Bezeichnern bestehen, die nicht voneinander separiert sind, z.B. \"SwiftEx\"!", + "JAVA_BLACKBOX": "Der Package-Name muss ein gültiger Java-Bezeicher sein. Punkte sind für den Blackbox Aufgabentyp nicht erlaubt." } }, "points": { diff --git a/src/main/webapp/i18n/en/exercise.json b/src/main/webapp/i18n/en/exercise.json index 280006927d68..0740f8c227bf 100644 --- a/src/main/webapp/i18n/en/exercise.json +++ b/src/main/webapp/i18n/en/exercise.json @@ -218,7 +218,8 @@ "pattern": { "JAVA": "The package name must consist of one or more valid Java identifiers separated by '.', e.g. \"net.java\"!", "KOTLIN": "The package name must consist of one or more valid Kotlin identifiers separated by '.', e.g. \"net.kotlin\"!", - "SWIFT": "The package name must consist of one or more valid Swift identifiers without any separator, e.g. \"SwiftEx\"!" + "SWIFT": "The package name must consist of one or more valid Swift identifiers without any separator, e.g. \"SwiftEx\"!", + "JAVA_BLACKBOX": "The package name must be a valid Java identifier. No dots allowed for the blackbox project type!" } }, "points": { From 0206ceef280cfab1cfba8bf5d9d5079e77df57c2 Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Thu, 20 Jul 2023 16:42:34 +0200 Subject: [PATCH 49/62] single quotes needed for dockerFlags --- .../java/blackbox/regularRuns/pipeline.groovy | 36 ++++--------------- 1 file changed, 6 insertions(+), 30 deletions(-) diff --git a/src/main/resources/templates/jenkins/java/blackbox/regularRuns/pipeline.groovy b/src/main/resources/templates/jenkins/java/blackbox/regularRuns/pipeline.groovy index 5727c5168d44..62ae215fc9ae 100644 --- a/src/main/resources/templates/jenkins/java/blackbox/regularRuns/pipeline.groovy +++ b/src/main/resources/templates/jenkins/java/blackbox/regularRuns/pipeline.groovy @@ -8,10 +8,8 @@ runDejagnuTests = fileExists("./testsuite") tool = getToolName() hasSecretTestFiles = secretTestFilesFolderExists() -dockerImage = "#dockerImage" -dockerFlags = "#dockerArgs" -// secretTestVolume = "artemis_blackbox_${tool}-secret" -secret_volume_mount_path = "/secrets" +dockerImage = '#dockerImage' +dockerFlags = '#dockerArgs' isStaticCodeAnalysisEnabled = #isStaticCodeAnalysisEnabled /** @@ -45,35 +43,13 @@ void testRunner() { private void setup() { // special jobs to run only for the solution repository if ("${env.JOB_NAME}" ==~ /.+-SOLUTION$/) { - dockerFlags += " -v artemis_blackbox_maven-cache:/maven_cache" - - //if (runDejagnuTests) { - // createSecretTestVolume() - //} + dockerFlags += ' -v artemis_blackbox_maven-cache:/maven_cache' } else { - dockerFlags += " -v artemis_blackbox_maven-cache:/maven_cache:ro" + dockerFlags += ' -v artemis_blackbox_maven-cache:/maven_cache:ro' // if not solution repo, disallow network access from containers - dockerFlags += " --network none" - mavenFlags += " --offline" - } -} - -/** - * Copies the files required only for the secret tests to the Docker volume. - */ -private void createSecretTestVolume() { - stage("Create Secret Test Volume") { - docker.image(dockerImage).inside("-v ${secretTestVolume}:${secret_volume_mount_path}") { c -> - sh """ - rm -rf ${secret_volume_mount_path}/* - cp testsuite/${tool}.tests/secret.exp ${secret_volume_mount_path}/secret.exp - """ - - if (hasSecretTestFiles) { - sh("cp -vr ${testfiles_base_path}/secret ${secret_volume_mount_path}/secret") - } - } + dockerFlags += ' --network none' + mavenFlags += ' --offline' } } From 8ec92e4cd20a70683f4f29fececfb37c6f6b0cfb Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Thu, 20 Jul 2023 17:15:35 +0200 Subject: [PATCH 50/62] make editor height dependent on viewport --- .../app/exercises/programming/manage/build-plan-editor.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/webapp/app/exercises/programming/manage/build-plan-editor.scss b/src/main/webapp/app/exercises/programming/manage/build-plan-editor.scss index 6e23eccc31ef..955da71ea06d 100644 --- a/src/main/webapp/app/exercises/programming/manage/build-plan-editor.scss +++ b/src/main/webapp/app/exercises/programming/manage/build-plan-editor.scss @@ -8,6 +8,7 @@ &__editor { flex: 1 1 auto; height: 500px; + max-height: 65vh; } } } From 4860cd34fd67cdf77d28444431d4fb584ae96edd Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Sun, 23 Jul 2023 17:30:36 +0200 Subject: [PATCH 51/62] remove viewport limit again --- .../app/exercises/programming/manage/build-plan-editor.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/webapp/app/exercises/programming/manage/build-plan-editor.scss b/src/main/webapp/app/exercises/programming/manage/build-plan-editor.scss index 955da71ea06d..6e23eccc31ef 100644 --- a/src/main/webapp/app/exercises/programming/manage/build-plan-editor.scss +++ b/src/main/webapp/app/exercises/programming/manage/build-plan-editor.scss @@ -8,7 +8,6 @@ &__editor { flex: 1 1 auto; height: 500px; - max-height: 65vh; } } } From ca9dc60bfbc0c7e91904b1f6ef2f5acd9e92cd25 Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Mon, 7 Aug 2023 17:10:07 +0200 Subject: [PATCH 52/62] remove redundant part of regex --- .../manage/update/programming-exercise-update.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.ts b/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.ts index bec407ec0e7e..4257cd19dc05 100644 --- a/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.ts +++ b/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.ts @@ -86,7 +86,7 @@ export class ProgrammingExerciseUpdateComponent implements OnInit { '^(?!.*(?:\\.|^)(?:abstract|continue|for|new|switch|assert|default|if|package|synchronized|boolean|do|goto|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while|_|true|false|null)(?:\\.|$))[A-Z_a-z][0-9A-Z_a-z]*(?:\\.[A-Z_a-z][0-9A-Z_a-z]*)*$'; // No dots allowed for the blackbox project type, because the folder naming works slightly different here. packageNamePatternForJavaBlackbox = - '^(?!.*(?:\\.|^)(?:abstract|continue|for|new|switch|assert|default|if|package|synchronized|boolean|do|goto|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while|_|true|false|null)(?:\\.|$))[A-Z_a-z][0-9A-Z_a-z]*(?:[A-Z_a-z][0-9A-Z_a-z]*)*$'; + '^(?!.*(?:\\.|^)(?:abstract|continue|for|new|switch|assert|default|if|package|synchronized|boolean|do|goto|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while|_|true|false|null)(?:\\.|$))[A-Z_a-z][0-9A-Z_a-z]*$'; // Swift package name Regex derived from (https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID412), // with the restriction to a-z,A-Z as "Swift letter" and 0-9 as digits where no separators are allowed appNamePatternForSwift = From 18c634a1c30ffba0413d06c83f484fefffef41b9 Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Mon, 7 Aug 2023 17:27:19 +0200 Subject: [PATCH 53/62] fixed feature availabilty based on selected project type --- .../java/blackbox/regularRuns/pipeline.groovy | 1 - .../programming-exercise-update.component.ts | 16 ++++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/main/resources/templates/jenkins/java/blackbox/regularRuns/pipeline.groovy b/src/main/resources/templates/jenkins/java/blackbox/regularRuns/pipeline.groovy index 62ae215fc9ae..1407c303d3d2 100644 --- a/src/main/resources/templates/jenkins/java/blackbox/regularRuns/pipeline.groovy +++ b/src/main/resources/templates/jenkins/java/blackbox/regularRuns/pipeline.groovy @@ -17,7 +17,6 @@ isStaticCodeAnalysisEnabled = #isStaticCodeAnalysisEnabled */ void testRunner() { setup() - //removeSecretFiles() build() // catchError-block: execute following steps even if the one inside the diff --git a/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.ts b/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.ts index 4257cd19dc05..b800e293b8b3 100644 --- a/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.ts +++ b/src/main/webapp/app/exercises/programming/manage/update/programming-exercise-update.component.ts @@ -317,20 +317,24 @@ export class ProgrammingExerciseUpdateComponent implements OnInit { // update the project types for java programming exercises according to whether dependencies should be included if (this.programmingExercise.programmingLanguage === ProgrammingLanguage.JAVA) { - if (type === ProjectType.PLAIN_MAVEN || type === ProjectType.MAVEN_MAVEN) { + if (type == ProjectType.MAVEN_BLACKBOX) { + this.selectedProjectTypeValue = ProjectType.MAVEN_BLACKBOX; + this.programmingExercise.projectType = ProjectType.MAVEN_BLACKBOX; + this.sequentialTestRunsAllowed = false; + this.testwiseCoverageAnalysisSupported = false; + } else if (type === ProjectType.PLAIN_MAVEN || type === ProjectType.MAVEN_MAVEN) { this.selectedProjectTypeValue = ProjectType.PLAIN_MAVEN; + this.sequentialTestRunsAllowed = true; + this.testwiseCoverageAnalysisSupported = true; if (this.withDependenciesValue) { this.programmingExercise.projectType = ProjectType.MAVEN_MAVEN; } else { this.programmingExercise.projectType = ProjectType.PLAIN_MAVEN; } - } else if (type === ProjectType.MAVEN_BLACKBOX) { - this.selectedProjectTypeValue = ProjectType.MAVEN_BLACKBOX; - this.programmingExercise.projectType = ProjectType.MAVEN_BLACKBOX; - this.sequentialTestRunsAllowed = false; - this.testwiseCoverageAnalysisSupported = false; } else { this.selectedProjectTypeValue = ProjectType.PLAIN_GRADLE; + this.sequentialTestRunsAllowed = true; + this.testwiseCoverageAnalysisSupported = true; if (this.withDependenciesValue) { this.programmingExercise.projectType = ProjectType.GRADLE_GRADLE; } else { From 5fb7ca054e662a1b5d776415a1d995ec417e6533 Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Mon, 7 Aug 2023 18:12:08 +0200 Subject: [PATCH 54/62] test fix --- .../programming-exercise-update.component.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/javascript/spec/component/programming-exercise/programming-exercise-update.component.spec.ts b/src/test/javascript/spec/component/programming-exercise/programming-exercise-update.component.spec.ts index aa5ef5b5f9d5..13cba215dc5b 100644 --- a/src/test/javascript/spec/component/programming-exercise/programming-exercise-update.component.spec.ts +++ b/src/test/javascript/spec/component/programming-exercise/programming-exercise-update.component.spec.ts @@ -816,7 +816,7 @@ describe('ProgrammingExercise Management Update Component', () => { })); it('should disable options for java dejagnu project type', fakeAsync(() => { - comp.selectedProjectType = ProjectType.MAVEN_MAVEN; + comp.selectedProjectType = ProjectType.MAVEN_BLACKBOX; expect(comp.sequentialTestRunsAllowed).toBeFalse(); expect(comp.testwiseCoverageAnalysisSupported).toBeFalse(); From e6dfcfd126ccee52c5b521ae744234bf5593239f Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Mon, 7 Aug 2023 18:35:55 +0200 Subject: [PATCH 55/62] extend test --- .../programming-exercise-update.component.spec.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/test/javascript/spec/component/programming-exercise/programming-exercise-update.component.spec.ts b/src/test/javascript/spec/component/programming-exercise/programming-exercise-update.component.spec.ts index 13cba215dc5b..2acc13557c7b 100644 --- a/src/test/javascript/spec/component/programming-exercise/programming-exercise-update.component.spec.ts +++ b/src/test/javascript/spec/component/programming-exercise/programming-exercise-update.component.spec.ts @@ -815,11 +815,22 @@ describe('ProgrammingExercise Management Update Component', () => { expect(comp.programmingExercise.testwiseCoverageEnabled).toBeFalse(); })); - it('should disable options for java dejagnu project type', fakeAsync(() => { + it('should disable options for java dejagnu project type and re-enable them after changing back to maven or gradle', fakeAsync(() => { comp.selectedProjectType = ProjectType.MAVEN_BLACKBOX; + expect(comp.sequentialTestRunsAllowed).toBeFalse(); + expect(comp.testwiseCoverageAnalysisSupported).toBeFalse(); + + comp.selectedProjectType = ProjectType.MAVEN_MAVEN; + expect(comp.sequentialTestRunsAllowed).toBeTrue(); + expect(comp.testwiseCoverageAnalysisSupported).toBeTrue(); + comp.selectedProjectType = ProjectType.MAVEN_BLACKBOX; expect(comp.sequentialTestRunsAllowed).toBeFalse(); expect(comp.testwiseCoverageAnalysisSupported).toBeFalse(); + + comp.selectedProjectType = ProjectType.GRADLE_GRADLE; + expect(comp.sequentialTestRunsAllowed).toBeTrue(); + expect(comp.testwiseCoverageAnalysisSupported).toBeTrue(); })); }); From 5574e55b672d940970dc0e684b3511522ac555d8 Mon Sep 17 00:00:00 2001 From: Christoph Knoedlseder Date: Wed, 9 Aug 2023 12:50:18 +0200 Subject: [PATCH 56/62] fix error message for invalid blackbox package names --- .../programming-exercise-language.component.html | 9 ++++++++- src/main/webapp/i18n/de/exercise.json | 2 +- src/main/webapp/i18n/en/exercise.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/main/webapp/app/exercises/programming/manage/update/update-components/programming-exercise-language.component.html b/src/main/webapp/app/exercises/programming/manage/update/update-components/programming-exercise-language.component.html index 71b87cb7df34..f2b3db74f9e4 100644 --- a/src/main/webapp/app/exercises/programming/manage/update/update-components/programming-exercise-language.component.html +++ b/src/main/webapp/app/exercises/programming/manage/update/update-components/programming-exercise-language.component.html @@ -77,7 +77,14 @@

-
+
+

diff --git a/src/main/webapp/i18n/de/exercise.json b/src/main/webapp/i18n/de/exercise.json index 1dc748c5038c..e432422763b2 100644 --- a/src/main/webapp/i18n/de/exercise.json +++ b/src/main/webapp/i18n/de/exercise.json @@ -220,7 +220,7 @@ "JAVA": "Der Package-Name muss aus einem oder mehreren gültigen Java-Bezeichnern bestehen, die mit '.' getrennt sind, z.B. \"net.java\"!", "KOTLIN": "Der Package-Name muss aus einem oder mehreren gültigen Kotlin-Bezeichnern bestehen, die mit '.' getrennt sind, z.B. \"net.kotlin\"!", "SWIFT": "Der Package-Name muss aus einem oder mehreren gültigen Swift-Bezeichnern bestehen, die nicht voneinander separiert sind, z.B. \"SwiftEx\"!", - "JAVA_BLACKBOX": "Der Package-Name muss ein gültiger Java-Bezeicher sein. Punkte sind für den Blackbox Aufgabentyp nicht erlaubt." + "JAVA_BLACKBOX": "Der Package-Name muss ein gültiger Java-Bezeicher sein. Zusätzlich sind Trennpunkte für den Blackbox Aufgabentyp nicht erlaubt." } }, "points": { diff --git a/src/main/webapp/i18n/en/exercise.json b/src/main/webapp/i18n/en/exercise.json index 4ff1cdbdb446..b2b2f9574006 100644 --- a/src/main/webapp/i18n/en/exercise.json +++ b/src/main/webapp/i18n/en/exercise.json @@ -220,7 +220,7 @@ "JAVA": "The package name must consist of one or more valid Java identifiers separated by '.', e.g. \"net.java\"!", "KOTLIN": "The package name must consist of one or more valid Kotlin identifiers separated by '.', e.g. \"net.kotlin\"!", "SWIFT": "The package name must consist of one or more valid Swift identifiers without any separator, e.g. \"SwiftEx\"!", - "JAVA_BLACKBOX": "The package name must be a valid Java identifier. No dots allowed for the blackbox project type!" + "JAVA_BLACKBOX": "The package name must be a valid Java identifier. In addition, no dots are allowed for the blackbox project type!" } }, "points": { From cea85dc753f7170678424f38786e17288d72ff25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Kn=C3=B6dlseder?= <53149143+chrisknedl@users.noreply.github.com> Date: Fri, 18 Aug 2023 10:57:37 +0200 Subject: [PATCH 57/62] Update src/main/resources/templates/java/maven_blackbox/exercise/src/${packageNameFolder}/Client.java Co-authored-by: Benedikt Fein --- .../maven_blackbox/exercise/src/${packageNameFolder}/Client.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/templates/java/maven_blackbox/exercise/src/${packageNameFolder}/Client.java b/src/main/resources/templates/java/maven_blackbox/exercise/src/${packageNameFolder}/Client.java index 2716dfe23d9b..94d3ca2167c4 100644 --- a/src/main/resources/templates/java/maven_blackbox/exercise/src/${packageNameFolder}/Client.java +++ b/src/main/resources/templates/java/maven_blackbox/exercise/src/${packageNameFolder}/Client.java @@ -1,4 +1,5 @@ package ${packageName}; + public class Client { // TODO: Create and implement interactive command line handling } From 4ca640e12d0958dded2ef4c0a503366ebd9c0f63 Mon Sep 17 00:00:00 2001 From: Benedikt Fein Date: Mon, 21 Aug 2023 10:05:01 +0200 Subject: [PATCH 58/62] fix formatting after merge --- src/main/webapp/404.html | 2 +- .../account/activate/activate.component.ts | 6 ++- .../finish/password-reset-finish.component.ts | 7 +++- .../password-strength-bar.component.ts | 5 ++- .../account/password/password.component.ts | 7 +++- .../account/register/register.component.ts | 7 +++- .../account/settings/settings.component.ts | 7 +++- .../app/admin/audits/audit-data.model.ts | 6 ++- .../webapp/app/admin/audits/audit.model.ts | 7 +++- .../app/admin/audits/audits.component.html | 2 +- .../app/admin/audits/audits.component.ts | 7 +++- .../app/admin/health/health.component.ts | 5 ++- src/main/webapp/app/admin/logs/log.model.ts | 5 ++- .../webapp/app/admin/logs/logs.component.html | 2 +- .../jvm-memory/jvm-memory.component.html | 8 ++-- .../jvm-threads/jvm-threads.component.html | 8 ++-- .../metrics-cache.component.html | 4 +- .../metrics-datasource.component.html | 42 +++++++++---------- .../metrics-endpoints-requests.component.html | 4 +- .../metrics-garbagecollector.component.html | 26 ++++++------ .../metrics-request.component.html | 4 +- .../metrics-system.component.html | 16 +++---- .../app/admin/metrics/metrics.component.ts | 5 ++- ...rganization-management-detail.component.ts | 7 +++- ...rganization-management-update.component.ts | 5 ++- .../organization-management.service.ts | 5 ++- ...otification-management-detail.component.ts | 6 ++- ...otification-management-update.component.ts | 7 +++- .../upcoming-exams-and-exercises.component.ts | 6 ++- .../user-management.component.html | 12 +++--- .../assessment-detail.component.ts | 5 ++- .../assessment-header.component.ts | 6 ++- .../assessment-locks.component.html | 2 +- .../complaints/complaint-response.service.ts | 5 ++- .../app/complaints/complaint.service.ts | 5 ++- .../complaints-for-tutor.component.html | 4 +- .../form/complaints-form.component.ts | 5 ++- .../list-of-complaints.component.html | 2 +- .../app/core/about-us/about-us.component.ts | 6 ++- .../webapp/app/core/auth/auth-jwt.service.ts | 12 +++++- .../interceptor/auth-expired.interceptor.ts | 7 +++- .../interceptor/errorhandler.interceptor.ts | 5 ++- .../data-export/data-export.component.html | 4 +- .../data-export/data-export.component.ts | 7 +++- .../app/core/legal/imprint.component.ts | 6 ++- .../sentry/deduplicate.sentry-integration.ts | 15 ++++--- .../core/theme/theme-switch.component.scss | 4 +- .../webapp/app/core/util/alert.service.ts | 7 +++- .../app/core/util/event-manager.service.ts | 5 ++- .../competency-form.component.html | 2 +- .../competency-form.component.ts | 7 +++- .../competency-rings.component.scss | 4 +- .../course/competencies/competency.service.ts | 6 ++- ...essment-dashboard-information.component.ts | 6 ++- .../assessment-dashboard/tutor-issue.ts | 8 +++- .../app/course/manage/course-admin.service.ts | 5 ++- .../course-lti-configuration.component.ts | 6 ++- ...it-course-lti-configuration.component.html | 4 +- ...edit-course-lti-configuration.component.ts | 6 ++- .../course-management-exercises.component.ts | 6 ++- .../course-management-statistics.component.ts | 5 ++- .../manage/course-update.component.html | 4 +- .../course-detail-line-chart.component.ts | 5 ++- .../manage/detail/course-detail.component.ts | 7 +++- .../course-management-card.component.html | 8 ++-- ...arism-cases-instructor-view.component.html | 2 +- ...giarism-cases-instructor-view.component.ts | 5 ++- .../plagiarism-case-verdict.component.html | 2 +- ...sm-case-student-detail-view.component.html | 2 +- ...rism-case-student-detail-view.component.ts | 6 ++- .../tutorial-group-session.service.ts | 5 ++- .../tutorial-group-detail.component.html | 2 +- .../tutorial-group-detail.component.ts | 5 ++- ...al-group-free-days-overview.component.html | 2 +- ...rial-group-free-days-overview.component.ts | 5 ++- .../tutorial-group-session-row.component.html | 6 +-- .../tutorial-group-session-row.component.ts | 6 ++- ...torial-group-sessions-table.component.html | 6 +-- ...tutorial-group-sessions-table.component.ts | 5 ++- ...group-utilization-indicator.component.html | 4 +- .../tutorial-group-row.component.html | 8 ++-- .../tutorial-groups-table.component.html | 2 +- .../tutorial-groups-table.component.ts | 5 ++- .../registered-students.component.html | 4 +- ...te-tutorial-group-free-period.component.ts | 6 ++- ...it-tutorial-group-free-period.component.ts | 6 ++- ...rial-group-free-period-form.component.html | 6 +-- ...oup-free-period-row-buttons.component.html | 2 +- ...group-free-period-row-buttons.component.ts | 5 ++- ...oup-free-periods-management.component.html | 4 +- ...torial-group-management-resolve.service.ts | 5 ++- ...create-tutorial-group-session.component.ts | 6 ++- .../edit-tutorial-group-session.component.ts | 6 ++- ...tutorial-group-session-form.component.html | 6 +-- .../cancellation-modal.component.html | 4 +- ...l-group-session-row-buttons.component.html | 6 +-- ...ial-group-session-row-buttons.component.ts | 5 ++- ...l-group-sessions-management.component.html | 2 +- ...l-groups-configuration-form.component.html | 2 +- .../create-tutorial-group.component.ts | 7 +++- .../schedule-form.component.html | 10 ++--- .../schedule-form/schedule-form.component.ts | 6 ++- .../tutorial-group-form.component.html | 10 ++--- .../tutorial-group-row-buttons.component.ts | 5 ++- ...-registration-import-dialog.component.html | 20 ++++----- src/main/webapp/app/entities/bonus.model.ts | 5 ++- ...scores-average-scores-graph.component.html | 2 +- .../exam-scores/exam-scores.component.html | 4 +- .../exam/manage/exam-management.service.ts | 7 +++- .../exam/manage/exam-status.component.html | 10 ++--- .../app/exam/manage/exam-status.component.ts | 5 ++- .../exam-checklist.component.ts | 5 ++- .../manage/exams/exam-detail.component.html | 2 +- .../exercise-group-update.component.ts | 7 +++- .../exercise-groups/exercise-group.service.ts | 5 ++- ...ogramming-exercise-group-cell.component.ts | 6 ++- .../student-exam-detail.component.html | 2 +- .../student-exams/student-exam.service.ts | 6 ++- ...students-upload-images-dialog.component.ts | 6 ++- .../create-test-run-modal.component.ts | 5 ++- .../exam-participation-cover.component.html | 8 ++-- .../exam-cover/exam-participation-cover.scss | 4 +- .../exam-navigation-bar.component.html | 4 +- .../exam-participation.component.ts | 5 ++- .../participate/exam-participation.service.ts | 6 ++- .../exam-exercise-overview-page.component.ts | 5 ++- ...file-upload-exam-submission.component.html | 2 +- .../programming-exam-submission.component.ts | 5 ++- .../quiz/quiz-exam-submission.component.ts | 5 ++- .../text/text-exam-submission.component.html | 4 +- .../exam-information.component.html | 12 +++--- .../exam-participation-summary.component.html | 4 +- .../programming-exam-summary.component.html | 2 +- .../quiz-exam-summary.component.ts | 5 ++- .../exam-points-summary.component.ts | 6 ++- ...oad-exercise-management-resolve.service.ts | 6 ++- .../manage/file-upload-exercise.service.ts | 5 ++- .../file-upload-submission.component.html | 2 +- .../file-upload-submission.service.ts | 5 ++- .../modeling-exercise-resolver.service.ts | 6 ++- .../manage/modeling-exercise.service.ts | 5 ++- .../modeling-submission.component.html | 2 +- .../modeling-submission.service.ts | 5 ++- .../shared/modeling-editor.component.ts | 7 +++- ...or-assessment-inline-feedback.component.ts | 6 ++- ...amming-assessment-manual-result.service.ts | 5 ++- ...code-hint-generation-overview.component.ts | 5 ++- .../solution-entry-details-modal.component.ts | 5 ++- .../code-hint-generation-step.component.ts | 6 ++- .../coverage-generation-step.component.ts | 5 ++- .../diff-generation-step.component.ts | 5 ++- ...ution-entry-generation-step.component.html | 2 +- .../git-diff-report-modal.component.ts | 5 ++- .../manage/build-plan-editor.component.ts | 6 ++- ...a-category-distribution-chart.component.ts | 23 +++++----- .../test-case-distribution-chart.component.ts | 15 ++++--- .../programming-exercise-task.service.ts | 6 ++- ...ercise-instruction-analysis.component.html | 4 +- .../task-count-warning.component.html | 2 +- ...mming-exercise-create-buttons.component.ts | 5 ++- ...programming-exercise-detail.component.html | 10 ++--- ...ramming-exercise-reset-button.directive.ts | 6 ++- .../programming-exercise-grading.service.ts | 20 +++++++-- ...gramming-exercise-participation.service.ts | 6 ++- .../services/programming-exercise.service.ts | 6 ++- ...amming-exercise-information.component.html | 2 +- ...ogramming-exercise-language.component.html | 4 +- ...de-editor-student-container.component.html | 4 +- ...-instructor-exercise-download.component.ts | 5 ++- ...cise-instructor-repo-download.component.ts | 5 ++- ...instructor-submission-state.component.html | 7 ++-- ...g-exercise-re-evaluate-button.component.ts | 5 ++- ...g-exercise-trigger-all-button.component.ts | 6 ++- ...-editor-confirm-refresh-modal.component.ts | 6 ++- .../code-editor-build-output.component.html | 2 +- .../code-editor-file-browser-delete.ts | 5 ++- .../code-editor/model/code-editor.model.ts | 16 +++++-- .../code-editor-conflict-state.service.ts | 5 ++- ...ditor-domain-dependent-endpoint.service.ts | 6 ++- .../service/code-editor-repository.service.ts | 21 ++++++++-- .../service/code-editor-submission.service.ts | 6 ++- ...rogramming-exercise-plant-uml.extension.ts | 5 ++- .../programming-exercise-task.extension.ts | 5 ++- .../programming-exercise-plant-uml.service.ts | 5 ++- ...rcise-instruction-step-wizard.component.ts | 5 ++- ...ise-instruction-task-status.component.html | 2 +- ...rcise-instruction-task-status.component.ts | 6 ++- ...rogramming-exercise-lifecycle.component.ts | 5 ++- ...e-test-schedule-date-picker.component.html | 4 +- .../apollon-diagram-create-form.component.ts | 7 +++- .../apollon-diagram.service.ts | 5 ++- ...multiple-choice-question-edit.component.ts | 6 ++- .../quiz-exercise-create-buttons.component.ts | 5 ++- .../manage/quiz-exercise-popup.service.ts | 6 ++- .../quiz/manage/quiz-exercise.component.html | 4 +- .../quiz/manage/quiz-exercise.service.ts | 5 ++- .../quiz-participation.component.html | 4 +- .../quiz-participation.component.scss | 4 +- .../participate/quiz-participation.service.ts | 5 ++- .../shared/fit-text/fit-text.directive.ts | 5 ++- .../drag-and-drop-question.component.ts | 5 ++- ...iz-scoring-info-student-modal.component.ts | 5 ++- .../short-answer-question.component.ts | 5 ++- ...ercise-assessment-dashboard.component.html | 6 +-- .../tutor/tutor-participation.service.ts | 5 ++- .../example-solution.component.ts | 6 ++- .../example-submission-assess-command.ts | 6 ++- .../example-submission.service.ts | 5 ++- ...-exercise-page-with-details.component.html | 8 ++-- .../manage/exercise-hint.component.ts | 7 +++- ...xercise-hint-student-dialog.component.html | 3 +- .../shared/code-hint-container.component.ts | 5 ++- .../shared/exercise-hint.service.ts | 5 ++- ...exercise-scores-export-button.component.ts | 5 ++- .../exercise-scores.component.html | 8 ++-- .../exercise-details.component.ts | 6 ++- .../external-submission.service.ts | 5 ++- .../shared/feedback/feedback.component.html | 8 ++-- .../feedback/long-feedback-text.service.ts | 5 ++- .../standalone-feedback.component.ts | 6 ++- .../import/exercise-import.component.ts | 6 ++- .../exercise-import-from-file.component.ts | 5 ++- .../exercise-create-buttons.component.ts | 5 ++- .../shared/manage/exercise-paging.service.ts | 5 ++- .../participation-submission.component.html | 2 +- .../participation/participation.service.ts | 6 ++- .../plagiarism-header.component.ts | 5 ++- .../plagiarism-run-details.component.html | 14 +++---- .../plagiarism-sidebar.component.html | 2 +- .../text-submission-viewer.component.ts | 5 ++- .../rating-list/rating-list.component.ts | 7 +++- .../shared/rating/rating.component.ts | 5 ++- .../exercises/shared/result/result.service.ts | 5 ++- .../result/updating-result.component.ts | 5 ++- .../exercise-statistics.component.ts | 6 ++- .../shared/submission/submission.service.ts | 6 ++- .../team-config-form-group.component.html | 4 +- .../team-submission-sync.component.ts | 6 ++- .../team-exercise-search.component.ts | 5 ++- .../team-participate-info-box.component.scss | 4 +- .../team-students-online-list.component.ts | 5 ++- .../team-participation-table.component.html | 4 +- .../team-participation-table.component.ts | 7 +++- .../team-delete-button.component.ts | 5 ++- .../team-update-dialog.component.html | 4 +- .../team-update-dialog.component.ts | 6 ++- .../exercises/shared/team/team.component.html | 2 +- .../app/exercises/shared/team/team.service.ts | 6 ++- .../teams-export-button.component.ts | 5 ++- .../teams-import-dialog.component.ts | 6 ++- .../teams-import-from-file-form.component.ts | 7 +++- .../text-assesment-analytics.service.ts | 7 +++- .../text-assessment-area.component.html | 4 +- .../text/assess/text-assessment.service.ts | 5 ++- .../cluster-statistics.component.ts | 5 ++- .../text-exercise-row-buttons.component.ts | 5 ++- .../text-exercise/text-exercise.route.ts | 6 ++- .../text-exercise/text-exercise.service.ts | 5 ++- .../participate/text-editor.component.html | 4 +- .../text-result/text-result-block.ts | 5 ++- .../text-result/text-result.component.ts | 5 ++- .../participate/text-submission.service.ts | 5 ++- .../manual-text-selection.component.ts | 5 ++- .../text/shared/text-select.directive.ts | 5 ++- .../feature-overview.component.ts | 5 ++- .../base-grading-system.component.ts | 2 +- .../grading-system/bonus/bonus.component.html | 6 +-- .../app/grading-system/bonus/bonus.service.ts | 5 ++- .../detailed-grading-system.component.html | 4 +- .../grading-key-overview.component.html | 4 +- .../interval-grading-system.component.html | 8 ++-- .../app/guided-tour/dot-navigation.scss | 8 +++- .../guided-tour/guided-tour.component.html | 2 +- .../app/guided-tour/guided-tour.component.ts | 6 ++- src/main/webapp/app/home/home.component.html | 4 +- .../home/saml2-login/saml2-login.component.ts | 6 ++- .../lecture-attachments.component.html | 2 +- .../app/lecture/lecture-import.component.ts | 7 +++- .../attachment-unit-form.component.html | 2 +- .../attachment-unit-form.component.ts | 5 ++- .../attachmentUnit.service.ts | 5 ++- .../create-attachment-unit.component.ts | 7 +++- .../create-online-unit.component.ts | 7 +++- .../create-text-unit.component.ts | 7 +++- .../create-video-unit.component.ts | 7 +++- .../edit-attachment-unit.component.ts | 7 +++- .../edit-online-unit.component.ts | 7 +++- .../edit-text-unit.component.ts | 7 +++- .../edit-video-unit.component.ts | 7 +++- .../exerciseUnit.service.ts | 5 ++- .../lectureUnit.service.ts | 5 ++- .../online-unit-form.component.ts | 5 ++- .../onlineUnit.service.ts | 5 ++- .../text-unit-form.component.ts | 6 ++- .../textUnit.service.ts | 5 ++- .../unit-creation-card.component.ts | 6 ++- .../videoUnit.service.ts | 5 ++- .../app/lecture/lecture-update.component.html | 2 +- .../webapp/app/lecture/lecture.component.html | 2 +- .../lecture-wizard-competencies.component.ts | 4 +- .../lti13-dynamic-registration.component.ts | 5 ++- .../lti/lti13-exercise-launch.component.ts | 5 ++- .../orion-tutor-assessment.component.ts | 6 ++- .../orion-programming-exercise.component.ts | 6 ++- ...rcise-details-student-actions.component.ts | 6 ++- .../app/overview/course-card.component.ts | 7 +++- .../course-conversations.component.ts | 7 +++- .../channel-form/channel-form.component.html | 4 +- .../channel-item/channel-item.component.html | 2 +- .../channels-overview-dialog.component.html | 2 +- ...conversation-add-users-form.component.html | 4 +- .../conversation-detail-dialog.component.html | 2 +- .../conversation-detail-dialog.component.ts | 5 ++- .../conversation-info.component.ts | 7 +++- .../conversation-members.component.ts | 7 +++- .../conversation-settings.component.ts | 7 +++- ...generic-confirmation-dialog.component.html | 8 ++-- ...update-text-property-dialog.component.html | 2 +- ...c-update-text-property-dialog.component.ts | 5 ++- .../group-chat-create-dialog.component.html | 2 +- .../group-chat-create-dialog.component.ts | 5 ++- .../conversation-header.component.html | 2 +- .../conversation-messages.component.html | 2 +- .../conversation-sidebar-entry.component.ts | 7 +++- .../conversation-sidebar-section.component.ts | 5 ++- .../course-discussion.component.html | 4 +- ...-exam-attempt-review-detail.component.html | 4 +- .../course-exam-detail.component.html | 6 +-- .../course-exercises.component.html | 8 ++-- .../course-lecture-details.component.html | 2 +- .../course-lecture-row.component.html | 2 +- .../course-lectures.component.html | 4 +- .../video-unit/video-unit.component.ts | 9 ++-- .../course-registration-detail.component.ts | 7 +++- .../course-prerequisites-modal.component.ts | 6 ++- .../course-registration.component.ts | 5 ++- .../course-statistics.component.html | 40 +++++++++--------- .../course-tutorial-group-card.component.html | 12 +++--- .../course-unenrollment-modal.component.ts | 7 +++- .../app/overview/courses.component.html | 10 ++--- .../course-exercise-details.component.html | 2 +- .../lti-initializer-modal.component.ts | 7 +++- .../problem-statement.component.ts | 6 ++- .../participation-websocket.service.ts | 5 ++- .../exercise-scores-chart.component.html | 2 +- .../additional-feedback.component.ts | 5 ++- .../app/shared/alert/alert-error.model.ts | 6 ++- .../auth/has-any-authority.directive.ts | 6 ++- .../app/shared/breakpoints/layout.service.ts | 5 ++- .../competency-selection.component.ts | 6 ++- .../start-practice-mode-button.component.ts | 6 ++- .../connection-warning.component.ts | 5 ++- .../consistency-check.component.ts | 6 ++- .../course-users-selector.component.ts | 5 ++- .../tutor-leaderboard.component.html | 2 +- .../tutor-leaderboard.component.ts | 5 ++- .../progress-bar/progress-bar.component.ts | 5 ++- .../data-table/data-table.component.html | 4 +- .../shared/data-table/data-table.component.ts | 5 ++- .../date-time-picker.component.html | 2 +- .../delete-dialog/delete-button.directive.ts | 7 +++- .../delete-dialog/delete-dialog.component.ts | 5 ++- .../delete-dialog/delete-dialog.service.ts | 5 ++- .../shared/export/export-modal.component.ts | 5 ++- .../extension-point.directive.ts | 5 ++- .../feature-toggle/feature-toggle.service.ts | 5 ++- .../shared/fireworks/fireworks.component.scss | 8 +++- .../shared/image/cacheable-image.service.ts | 5 ++- .../shared/image/secured-image.component.ts | 6 ++- .../app/shared/import/import-component.ts | 7 +++- .../shared/language/translate.directive.ts | 5 ++- .../layouts/navbar/active-menu.directive.ts | 6 ++- .../layouts/profiles/profile.service.ts | 6 ++- .../link-preview-container.component.ts | 5 ++- .../ace-editor/ace-editor.component.ts | 6 ++- .../markdown-editor.component.html | 8 ++-- .../markdown-editor.component.ts | 6 ++- .../metis/conversations/channel.service.ts | 6 ++- .../conversations/conversation.service.ts | 6 ++- .../metis/conversations/group-chat.service.ts | 6 ++- .../conversations/one-to-one-chat.service.ts | 5 ++- .../message-inline-input.component.ts | 7 +++- .../message-reply-inline-input.component.ts | 7 +++- .../app/shared/metis/post/post.component.ts | 5 ++- .../posting-content-part.component.html | 4 +- .../posting-content-part.components.ts | 5 ++- ...answer-post-create-edit-modal.component.ts | 6 ++- .../post-create-edit-modal.component.ts | 7 +++- .../post-tag-selector.component.ts | 5 ++- .../posting-create-edit-modal.directive.ts | 6 ++- .../metis/posting-create-edit.directive.ts | 6 ++- .../post-footer/post-footer.component.ts | 5 ++- .../answer-post-header.component.html | 4 +- .../post-header/post-header.component.html | 4 +- .../posting-markdown-editor.component.ts | 6 ++- .../post-reactions-bar.component.html | 4 +- .../notification-sidebar.component.html | 4 +- .../admin-system-notification.service.ts | 6 ++- .../system-notification.service.ts | 5 ++- .../shared/orion/orion-connector.service.ts | 5 ++- .../orion-outdated.component.ts | 5 ++- .../orion-version-validator.service.ts | 5 ++- ...rticipant-scores-distribution.component.ts | 5 ++- .../app/shared/pipes/artemis-time-ago.pipe.ts | 6 ++- .../shared/pipes/artemis-translate.pipe.ts | 5 ++- .../score-display.component.html | 2 +- ...tistics-average-score-graph.component.html | 2 +- ...tatistics-average-score-graph.component.ts | 2 +- .../statistics-graph.component.ts | 5 ++- .../table/table-editable-field.component.html | 2 +- .../textarea/textarea-counter.component.html | 2 +- .../users-import-dialog.component.ts | 4 +- .../user-settings/user-settings.directive.ts | 6 ++- .../user-settings/user-settings.service.ts | 5 ++- src/main/webapp/app/shared/util/utils.ts | 5 ++- .../virtual-scroll.component.ts | 5 ++- src/main/webapp/app/utils/navigation.utils.ts | 5 ++- src/main/webapp/content/scss/global.scss | 18 ++++++-- src/main/webapp/index.html | 2 +- ...rsation-add-users-dialog.component.spec.ts | 6 +-- ...tor-assessment-container.component.spec.ts | 2 +- .../mock-has-any-authority.directive.ts | 5 ++- .../mocks/service/mock-account.service.ts | 6 +-- .../mocks/service/mock-alert.service.ts | 2 +- .../deduplicate.sentry-integration.spec.ts | 6 +-- .../text-assessment-analytics.service.spec.ts | 2 +- src/test/k6/requests/quiz.js | 21 ++++++---- 427 files changed, 1755 insertions(+), 683 deletions(-) diff --git a/src/main/webapp/404.html b/src/main/webapp/404.html index 679b2bd8a6e8..f068a0d35c2d 100644 --- a/src/main/webapp/404.html +++ b/src/main/webapp/404.html @@ -1,4 +1,4 @@ - + diff --git a/src/main/webapp/app/account/activate/activate.component.ts b/src/main/webapp/app/account/activate/activate.component.ts index a4b076741839..4bb2af36f1c3 100644 --- a/src/main/webapp/app/account/activate/activate.component.ts +++ b/src/main/webapp/app/account/activate/activate.component.ts @@ -14,7 +14,11 @@ export class ActivateComponent implements OnInit { success = false; isRegistrationEnabled = false; - constructor(private activateService: ActivateService, private route: ActivatedRoute, private profileService: ProfileService) {} + constructor( + private activateService: ActivateService, + private route: ActivatedRoute, + private profileService: ProfileService, + ) {} /** * Checks if the user can be activated with ActivateService diff --git a/src/main/webapp/app/account/password-reset/finish/password-reset-finish.component.ts b/src/main/webapp/app/account/password-reset/finish/password-reset-finish.component.ts index 648322475106..c2220bf609c4 100644 --- a/src/main/webapp/app/account/password-reset/finish/password-reset-finish.component.ts +++ b/src/main/webapp/app/account/password-reset/finish/password-reset-finish.component.ts @@ -25,7 +25,12 @@ export class PasswordResetFinishComponent implements OnInit, AfterViewInit { passwordForm: FormGroup; - constructor(private passwordResetFinishService: PasswordResetFinishService, private route: ActivatedRoute, private profileService: ProfileService, private fb: FormBuilder) {} + constructor( + private passwordResetFinishService: PasswordResetFinishService, + private route: ActivatedRoute, + private profileService: ProfileService, + private fb: FormBuilder, + ) {} ngOnInit() { this.route.queryParams.subscribe((params) => { diff --git a/src/main/webapp/app/account/password/password-strength-bar.component.ts b/src/main/webapp/app/account/password/password-strength-bar.component.ts index bf1576618b02..f550256d2edf 100644 --- a/src/main/webapp/app/account/password/password-strength-bar.component.ts +++ b/src/main/webapp/app/account/password/password-strength-bar.component.ts @@ -17,7 +17,10 @@ import { Component, ElementRef, Input, Renderer2 } from '@angular/core'; export class PasswordStrengthBarComponent { colors = ['#F00', '#F90', '#FF0', '#9F0', '#0F0']; - constructor(private renderer: Renderer2, private elementRef: ElementRef) {} + constructor( + private renderer: Renderer2, + private elementRef: ElementRef, + ) {} measureStrength(p: string): number { let force = 0; diff --git a/src/main/webapp/app/account/password/password.component.ts b/src/main/webapp/app/account/password/password.component.ts index 8f214958c6d4..5bec957b70b9 100644 --- a/src/main/webapp/app/account/password/password.component.ts +++ b/src/main/webapp/app/account/password/password.component.ts @@ -22,7 +22,12 @@ export class PasswordComponent implements OnInit { passwordForm: FormGroup; passwordResetEnabled = false; - constructor(private passwordService: PasswordService, private accountService: AccountService, private profileService: ProfileService, private fb: FormBuilder) {} + constructor( + private passwordService: PasswordService, + private accountService: AccountService, + private profileService: ProfileService, + private fb: FormBuilder, + ) {} ngOnInit() { this.accountService.identity().then((user) => { diff --git a/src/main/webapp/app/account/register/register.component.ts b/src/main/webapp/app/account/register/register.component.ts index c09aedb6505e..aa784f8f3f67 100644 --- a/src/main/webapp/app/account/register/register.component.ts +++ b/src/main/webapp/app/account/register/register.component.ts @@ -36,7 +36,12 @@ export class RegisterComponent implements OnInit, AfterViewInit { allowedEmailPattern?: string; allowedEmailPatternReadable?: string; - constructor(private translateService: TranslateService, private registerService: RegisterService, private fb: FormBuilder, private profileService: ProfileService) {} + constructor( + private translateService: TranslateService, + private registerService: RegisterService, + private fb: FormBuilder, + private profileService: ProfileService, + ) {} ngAfterViewInit(): void { if (this.login) { diff --git a/src/main/webapp/app/account/settings/settings.component.ts b/src/main/webapp/app/account/settings/settings.component.ts index c0b3e3fa737d..b29f833a5144 100644 --- a/src/main/webapp/app/account/settings/settings.component.ts +++ b/src/main/webapp/app/account/settings/settings.component.ts @@ -18,7 +18,12 @@ export class SettingsComponent implements OnInit { settingsForm: FormGroup; isRegistrationEnabled = false; - constructor(private accountService: AccountService, private fb: FormBuilder, private translateService: TranslateService, private profileService: ProfileService) {} + constructor( + private accountService: AccountService, + private fb: FormBuilder, + private translateService: TranslateService, + private profileService: ProfileService, + ) {} ngOnInit() { this.profileService.getProfileInfo().subscribe((profileInfo) => { diff --git a/src/main/webapp/app/admin/audits/audit-data.model.ts b/src/main/webapp/app/admin/audits/audit-data.model.ts index 9503e0013f92..8293e7057c70 100644 --- a/src/main/webapp/app/admin/audits/audit-data.model.ts +++ b/src/main/webapp/app/admin/audits/audit-data.model.ts @@ -1,3 +1,7 @@ export class AuditData { - constructor(public remoteAddress: string, public sessionId: string, public message?: string) {} + constructor( + public remoteAddress: string, + public sessionId: string, + public message?: string, + ) {} } diff --git a/src/main/webapp/app/admin/audits/audit.model.ts b/src/main/webapp/app/admin/audits/audit.model.ts index 6497fb444e35..b3ef5559c0f3 100644 --- a/src/main/webapp/app/admin/audits/audit.model.ts +++ b/src/main/webapp/app/admin/audits/audit.model.ts @@ -1,5 +1,10 @@ import { AuditData } from './audit-data.model'; export class Audit { - constructor(public data: AuditData, public principal: string, public timestamp: string, public type: string) {} + constructor( + public data: AuditData, + public principal: string, + public timestamp: string, + public type: string, + ) {} } diff --git a/src/main/webapp/app/admin/audits/audits.component.html b/src/main/webapp/app/admin/audits/audits.component.html index 617d2daaaf91..e511fe542d25 100644 --- a/src/main/webapp/app/admin/audits/audits.component.html +++ b/src/main/webapp/app/admin/audits/audits.component.html @@ -41,7 +41,7 @@

Filter by date

- {{ audit.timestamp | artemisDate : 'long' : true }} + {{ audit.timestamp | artemisDate: 'long' : true }} {{ audit.principal }} diff --git a/src/main/webapp/app/admin/audits/audits.component.ts b/src/main/webapp/app/admin/audits/audits.component.ts index 4e8e7e358f9f..9b14209276c3 100644 --- a/src/main/webapp/app/admin/audits/audits.component.ts +++ b/src/main/webapp/app/admin/audits/audits.component.ts @@ -30,7 +30,12 @@ export class AuditsComponent implements OnInit { // Icon faSort = faSort; - constructor(private auditsService: AuditsService, private activatedRoute: ActivatedRoute, private datePipe: DatePipe, private router: Router) {} + constructor( + private auditsService: AuditsService, + private activatedRoute: ActivatedRoute, + private datePipe: DatePipe, + private router: Router, + ) {} ngOnInit(): void { this.toDate = this.today(); diff --git a/src/main/webapp/app/admin/health/health.component.ts b/src/main/webapp/app/admin/health/health.component.ts index 6d7c2ddfdff2..d07c215f787a 100644 --- a/src/main/webapp/app/admin/health/health.component.ts +++ b/src/main/webapp/app/admin/health/health.component.ts @@ -18,7 +18,10 @@ export class HealthComponent implements OnInit { faSync = faSync; faEye = faEye; - constructor(private modalService: NgbModal, private healthService: HealthService) {} + constructor( + private modalService: NgbModal, + private healthService: HealthService, + ) {} ngOnInit() { this.refresh(); diff --git a/src/main/webapp/app/admin/logs/log.model.ts b/src/main/webapp/app/admin/logs/log.model.ts index 53dc35f6cba3..650852ec2d7c 100644 --- a/src/main/webapp/app/admin/logs/log.model.ts +++ b/src/main/webapp/app/admin/logs/log.model.ts @@ -11,5 +11,8 @@ export interface LoggersResponse { } export class Log { - constructor(public name: string, public level: Level) {} + constructor( + public name: string, + public level: Level, + ) {} } diff --git a/src/main/webapp/app/admin/logs/logs.component.html b/src/main/webapp/app/admin/logs/logs.component.html index 479663580d15..580b0fb314f0 100644 --- a/src/main/webapp/app/admin/logs/logs.component.html +++ b/src/main/webapp/app/admin/logs/logs.component.html @@ -16,7 +16,7 @@

L - {{ logger.name | slice : 0 : 140 }} + {{ logger.name | slice: 0 : 140 }} diff --git a/src/main/webapp/app/admin/metrics/blocks/jvm-memory/jvm-memory.component.html b/src/main/webapp/app/admin/metrics/blocks/jvm-memory/jvm-memory.component.html index f8caef6f9033..7e2a026a84fa 100644 --- a/src/main/webapp/app/admin/metrics/blocks/jvm-memory/jvm-memory.component.html +++ b/src/main/webapp/app/admin/metrics/blocks/jvm-memory/jvm-memory.component.html @@ -4,19 +4,19 @@

Memory

{{ entry.key }} - ({{ entry.value.used / 1048576 | number : '1.0-0' }}M / {{ entry.value.max / 1048576 | number : '1.0-0' }}M) + ({{ entry.value.used / 1048576 | number: '1.0-0' }}M / {{ entry.value.max / 1048576 | number: '1.0-0' }}M) -
Committed : {{ entry.value.committed / 1048576 | number : '1.0-0' }}M
+
Committed : {{ entry.value.committed / 1048576 | number: '1.0-0' }}M
{{ entry.key }} {{ entry.value.used / 1048576 | number : '1.0-0' }}M{{ entry.key }} {{ entry.value.used / 1048576 | number: '1.0-0' }}M - {{ (entry.value.used * 100) / entry.value.max | number : '1.0-0' }}% + {{ (entry.value.used * 100) / entry.value.max | number: '1.0-0' }}%
diff --git a/src/main/webapp/app/admin/metrics/blocks/jvm-threads/jvm-threads.component.html b/src/main/webapp/app/admin/metrics/blocks/jvm-threads/jvm-threads.component.html index b1f32b14ee00..d900ea4ed407 100644 --- a/src/main/webapp/app/admin/metrics/blocks/jvm-threads/jvm-threads.component.html +++ b/src/main/webapp/app/admin/metrics/blocks/jvm-threads/jvm-threads.component.html @@ -3,25 +3,25 @@

Threads

Runnable {{ threadStats.threadDumpRunnable }} - {{ (threadStats.threadDumpRunnable * 100) / threadStats.threadDumpAll | number : '1.0-0' }}% + {{ (threadStats.threadDumpRunnable * 100) / threadStats.threadDumpAll | number: '1.0-0' }}% Timed Waiting ({{ threadStats.threadDumpTimedWaiting }}) - {{ (threadStats.threadDumpTimedWaiting * 100) / threadStats.threadDumpAll | number : '1.0-0' }}% + {{ (threadStats.threadDumpTimedWaiting * 100) / threadStats.threadDumpAll | number: '1.0-0' }}% Waiting ({{ threadStats.threadDumpWaiting }}) - {{ (threadStats.threadDumpWaiting * 100) / threadStats.threadDumpAll | number : '1.0-0' }}% + {{ (threadStats.threadDumpWaiting * 100) / threadStats.threadDumpAll | number: '1.0-0' }}% Blocked ({{ threadStats.threadDumpBlocked }}) - {{ (threadStats.threadDumpBlocked * 100) / threadStats.threadDumpAll | number : '1.0-0' }}% + {{ (threadStats.threadDumpBlocked * 100) / threadStats.threadDumpAll | number: '1.0-0' }}%
Total: {{ threadStats.threadDumpAll }}
diff --git a/src/main/webapp/app/admin/metrics/blocks/metrics-cache/metrics-cache.component.html b/src/main/webapp/app/admin/metrics/blocks/metrics-cache/metrics-cache.component.html index ec6aff40ccd9..135b00a71bec 100644 --- a/src/main/webapp/app/admin/metrics/blocks/metrics-cache/metrics-cache.component.html +++ b/src/main/webapp/app/admin/metrics/blocks/metrics-cache/metrics-cache.component.html @@ -25,10 +25,10 @@

Cache statistics

{{ entry.value['cache.removals'] }} {{ entry.value['cache.evictions'] }} - {{ filterNaN((100 * entry.value['cache.gets.hit']) / (entry.value['cache.gets.hit'] + entry.value['cache.gets.miss'])) | number : '1.0-4' }} + {{ filterNaN((100 * entry.value['cache.gets.hit']) / (entry.value['cache.gets.hit'] + entry.value['cache.gets.miss'])) | number: '1.0-4' }} - {{ filterNaN((100 * entry.value['cache.gets.miss']) / (entry.value['cache.gets.hit'] + entry.value['cache.gets.miss'])) | number : '1.0-4' }} + {{ filterNaN((100 * entry.value['cache.gets.miss']) / (entry.value['cache.gets.hit'] + entry.value['cache.gets.miss'])) | number: '1.0-4' }} diff --git a/src/main/webapp/app/admin/metrics/blocks/metrics-datasource/metrics-datasource.component.html b/src/main/webapp/app/admin/metrics/blocks/metrics-datasource/metrics-datasource.component.html index 28ab859b1893..8f7732a6a6ce 100644 --- a/src/main/webapp/app/admin/metrics/blocks/metrics-datasource/metrics-datasource.component.html +++ b/src/main/webapp/app/admin/metrics/blocks/metrics-datasource/metrics-datasource.component.html @@ -22,35 +22,35 @@

DataSource st Acquire {{ datasourceMetrics.acquire.count }} - {{ filterNaN(datasourceMetrics.acquire.mean) | number : '1.0-2' }} - {{ datasourceMetrics.acquire['0.0'] | number : '1.0-3' }} - {{ datasourceMetrics.acquire['0.5'] | number : '1.0-3' }} - {{ datasourceMetrics.acquire['0.75'] | number : '1.0-3' }} - {{ datasourceMetrics.acquire['0.95'] | number : '1.0-3' }} - {{ datasourceMetrics.acquire['0.99'] | number : '1.0-3' }} - {{ filterNaN(datasourceMetrics.acquire.max) | number : '1.0-2' }} + {{ filterNaN(datasourceMetrics.acquire.mean) | number: '1.0-2' }} + {{ datasourceMetrics.acquire['0.0'] | number: '1.0-3' }} + {{ datasourceMetrics.acquire['0.5'] | number: '1.0-3' }} + {{ datasourceMetrics.acquire['0.75'] | number: '1.0-3' }} + {{ datasourceMetrics.acquire['0.95'] | number: '1.0-3' }} + {{ datasourceMetrics.acquire['0.99'] | number: '1.0-3' }} + {{ filterNaN(datasourceMetrics.acquire.max) | number: '1.0-2' }} Creation {{ datasourceMetrics.creation.count }} - {{ filterNaN(datasourceMetrics.creation.mean) | number : '1.0-2' }} - {{ datasourceMetrics.creation['0.0'] | number : '1.0-3' }} - {{ datasourceMetrics.creation['0.5'] | number : '1.0-3' }} - {{ datasourceMetrics.creation['0.75'] | number : '1.0-3' }} - {{ datasourceMetrics.creation['0.95'] | number : '1.0-3' }} - {{ datasourceMetrics.creation['0.99'] | number : '1.0-3' }} - {{ filterNaN(datasourceMetrics.creation.max) | number : '1.0-2' }} + {{ filterNaN(datasourceMetrics.creation.mean) | number: '1.0-2' }} + {{ datasourceMetrics.creation['0.0'] | number: '1.0-3' }} + {{ datasourceMetrics.creation['0.5'] | number: '1.0-3' }} + {{ datasourceMetrics.creation['0.75'] | number: '1.0-3' }} + {{ datasourceMetrics.creation['0.95'] | number: '1.0-3' }} + {{ datasourceMetrics.creation['0.99'] | number: '1.0-3' }} + {{ filterNaN(datasourceMetrics.creation.max) | number: '1.0-2' }} Usage {{ datasourceMetrics.usage.count }} - {{ filterNaN(datasourceMetrics.usage.mean) | number : '1.0-2' }} - {{ datasourceMetrics.usage['0.0'] | number : '1.0-3' }} - {{ datasourceMetrics.usage['0.5'] | number : '1.0-3' }} - {{ datasourceMetrics.usage['0.75'] | number : '1.0-3' }} - {{ datasourceMetrics.usage['0.95'] | number : '1.0-3' }} - {{ datasourceMetrics.usage['0.99'] | number : '1.0-3' }} - {{ filterNaN(datasourceMetrics.usage.max) | number : '1.0-2' }} + {{ filterNaN(datasourceMetrics.usage.mean) | number: '1.0-2' }} + {{ datasourceMetrics.usage['0.0'] | number: '1.0-3' }} + {{ datasourceMetrics.usage['0.5'] | number: '1.0-3' }} + {{ datasourceMetrics.usage['0.75'] | number: '1.0-3' }} + {{ datasourceMetrics.usage['0.95'] | number: '1.0-3' }} + {{ datasourceMetrics.usage['0.99'] | number: '1.0-3' }} + {{ filterNaN(datasourceMetrics.usage.max) | number: '1.0-2' }} diff --git a/src/main/webapp/app/admin/metrics/blocks/metrics-endpoints-requests/metrics-endpoints-requests.component.html b/src/main/webapp/app/admin/metrics/blocks/metrics-endpoints-requests/metrics-endpoints-requests.component.html index e95c9650dded..f0207fae774d 100644 --- a/src/main/webapp/app/admin/metrics/blocks/metrics-endpoints-requests/metrics-endpoints-requests.component.html +++ b/src/main/webapp/app/admin/metrics/blocks/metrics-endpoints-requests/metrics-endpoints-requests.component.html @@ -17,8 +17,8 @@

Endpoints requests (time in millisecond)

{{ method.key }} {{ entry.key }} {{ method.value!.count }} - {{ method.value!.mean | number : '1.0-3' }} - {{ method.value!.max | number : '1.0-3' }} + {{ method.value!.mean | number: '1.0-3' }} + {{ method.value!.max | number: '1.0-3' }} diff --git a/src/main/webapp/app/admin/metrics/blocks/metrics-garbagecollector/metrics-garbagecollector.component.html b/src/main/webapp/app/admin/metrics/blocks/metrics-garbagecollector/metrics-garbagecollector.component.html index 04b3d4b84934..d7d43d8acf02 100644 --- a/src/main/webapp/app/admin/metrics/blocks/metrics-garbagecollector/metrics-garbagecollector.component.html +++ b/src/main/webapp/app/admin/metrics/blocks/metrics-garbagecollector/metrics-garbagecollector.component.html @@ -4,8 +4,8 @@

Garbage col
- GC Live Data Size/GC Max Data Size ({{ garbageCollectorMetrics['jvm.gc.live.data.size'] / 1048576 | number : '1.0-0' }}M / - {{ garbageCollectorMetrics['jvm.gc.max.data.size'] / 1048576 | number : '1.0-0' }}M) + GC Live Data Size/GC Max Data Size ({{ garbageCollectorMetrics['jvm.gc.live.data.size'] / 1048576 | number: '1.0-0' }}M / + {{ garbageCollectorMetrics['jvm.gc.max.data.size'] / 1048576 | number: '1.0-0' }}M) Garbage col [animated]="false" type="success" > - {{ (100 * garbageCollectorMetrics['jvm.gc.live.data.size']) / garbageCollectorMetrics['jvm.gc.max.data.size'] | number : '1.0-2' }}% + {{ (100 * garbageCollectorMetrics['jvm.gc.live.data.size']) / garbageCollectorMetrics['jvm.gc.max.data.size'] | number: '1.0-2' }}%
@@ -23,8 +23,8 @@

Garbage col
- GC Memory Promoted/GC Memory Allocated ({{ garbageCollectorMetrics['jvm.gc.memory.promoted'] / 1048576 | number : '1.0-0' }}M / - {{ garbageCollectorMetrics['jvm.gc.memory.allocated'] / 1048576 | number : '1.0-0' }}M) + GC Memory Promoted/GC Memory Allocated ({{ garbageCollectorMetrics['jvm.gc.memory.promoted'] / 1048576 | number: '1.0-0' }}M / + {{ garbageCollectorMetrics['jvm.gc.memory.allocated'] / 1048576 | number: '1.0-0' }}M) Garbage col [animated]="false" type="success" > - {{ (100 * garbageCollectorMetrics['jvm.gc.memory.promoted']) / garbageCollectorMetrics['jvm.gc.memory.allocated'] | number : '1.0-2' }}% + {{ (100 * garbageCollectorMetrics['jvm.gc.memory.promoted']) / garbageCollectorMetrics['jvm.gc.memory.allocated'] | number: '1.0-2' }}%
@@ -69,13 +69,13 @@

Garbage col jvm.gc.pause {{ garbageCollectorMetrics['jvm.gc.pause'].count }} - {{ garbageCollectorMetrics['jvm.gc.pause'].mean | number : '1.0-3' }} - {{ garbageCollectorMetrics['jvm.gc.pause']['0.0'] | number : '1.0-3' }} - {{ garbageCollectorMetrics['jvm.gc.pause']['0.5'] | number : '1.0-3' }} - {{ garbageCollectorMetrics['jvm.gc.pause']['0.75'] | number : '1.0-3' }} - {{ garbageCollectorMetrics['jvm.gc.pause']['0.95'] | number : '1.0-3' }} - {{ garbageCollectorMetrics['jvm.gc.pause']['0.99'] | number : '1.0-3' }} - {{ garbageCollectorMetrics['jvm.gc.pause'].max | number : '1.0-3' }} + {{ garbageCollectorMetrics['jvm.gc.pause'].mean | number: '1.0-3' }} + {{ garbageCollectorMetrics['jvm.gc.pause']['0.0'] | number: '1.0-3' }} + {{ garbageCollectorMetrics['jvm.gc.pause']['0.5'] | number: '1.0-3' }} + {{ garbageCollectorMetrics['jvm.gc.pause']['0.75'] | number: '1.0-3' }} + {{ garbageCollectorMetrics['jvm.gc.pause']['0.95'] | number: '1.0-3' }} + {{ garbageCollectorMetrics['jvm.gc.pause']['0.99'] | number: '1.0-3' }} + {{ garbageCollectorMetrics['jvm.gc.pause'].max | number: '1.0-3' }} diff --git a/src/main/webapp/app/admin/metrics/blocks/metrics-request/metrics-request.component.html b/src/main/webapp/app/admin/metrics/blocks/metrics-request/metrics-request.component.html index 94c9dada4636..187839755a09 100644 --- a/src/main/webapp/app/admin/metrics/blocks/metrics-request/metrics-request.component.html +++ b/src/main/webapp/app/admin/metrics/blocks/metrics-request/metrics-request.component.html @@ -18,9 +18,9 @@

HTTP requests (tim - {{ filterNaN(entry.value.mean) | number : '1.0-2' }} + {{ filterNaN(entry.value.mean) | number: '1.0-2' }} - {{ entry.value.max | number : '1.0-2' }} + {{ entry.value.max | number: '1.0-2' }} diff --git a/src/main/webapp/app/admin/metrics/blocks/metrics-system/metrics-system.component.html b/src/main/webapp/app/admin/metrics/blocks/metrics-system/metrics-system.component.html index 390dfcfb1fbf..76ada9a91abd 100644 --- a/src/main/webapp/app/admin/metrics/blocks/metrics-system/metrics-system.component.html +++ b/src/main/webapp/app/admin/metrics/blocks/metrics-system/metrics-system.component.html @@ -8,25 +8,25 @@

System

Start time
-
{{ systemMetrics['process.start.time'] | date : 'full' }}
+
{{ systemMetrics['process.start.time'] | date: 'full' }}
Process CPU usage
-
{{ 100 * systemMetrics['process.cpu.usage'] | number : '1.0-2' }} %
+
{{ 100 * systemMetrics['process.cpu.usage'] | number: '1.0-2' }} %
- {{ 100 * systemMetrics['process.cpu.usage'] | number : '1.0-2' }} % + {{ 100 * systemMetrics['process.cpu.usage'] | number: '1.0-2' }} %
System CPU usage
-
{{ 100 * systemMetrics['system.cpu.usage'] | number : '1.0-2' }} %
+
{{ 100 * systemMetrics['system.cpu.usage'] | number: '1.0-2' }} %
- {{ 100 * systemMetrics['system.cpu.usage'] | number : '1.0-2' }} % + {{ 100 * systemMetrics['system.cpu.usage'] | number: '1.0-2' }} %
@@ -36,16 +36,16 @@

System

System 1m Load average
-
{{ systemMetrics['system.load.average.1m'] | number : '1.0-2' }}
+
{{ systemMetrics['system.load.average.1m'] | number: '1.0-2' }}
Process files max
-
{{ systemMetrics['process.files.max'] | number : '1.0-0' }}
+
{{ systemMetrics['process.files.max'] | number: '1.0-0' }}
Process files open
-
{{ systemMetrics['process.files.open'] | number : '1.0-0' }}
+
{{ systemMetrics['process.files.open'] | number: '1.0-0' }}
diff --git a/src/main/webapp/app/admin/metrics/metrics.component.ts b/src/main/webapp/app/admin/metrics/metrics.component.ts index 3db48d56e3e3..8e22b0d9e210 100644 --- a/src/main/webapp/app/admin/metrics/metrics.component.ts +++ b/src/main/webapp/app/admin/metrics/metrics.component.ts @@ -18,7 +18,10 @@ export class MetricsComponent implements OnInit { // Icons faSync = faSync; - constructor(private metricsService: MetricsService, private changeDetector: ChangeDetectorRef) {} + constructor( + private metricsService: MetricsService, + private changeDetector: ChangeDetectorRef, + ) {} /** * Calls the refresh method on init diff --git a/src/main/webapp/app/admin/organization-management/organization-management-detail.component.ts b/src/main/webapp/app/admin/organization-management/organization-management-detail.component.ts index abd7275219ff..7cb1771d09e3 100644 --- a/src/main/webapp/app/admin/organization-management/organization-management-detail.component.ts +++ b/src/main/webapp/app/admin/organization-management/organization-management-detail.component.ts @@ -42,7 +42,12 @@ export class OrganizationManagementDetailComponent implements OnInit { // Icons faUserSlash = faUserSlash; - constructor(private organizationService: OrganizationManagementService, private userService: UserService, private alertService: AlertService, private route: ActivatedRoute) {} + constructor( + private organizationService: OrganizationManagementService, + private userService: UserService, + private alertService: AlertService, + private route: ActivatedRoute, + ) {} /** * Retrieve the organization from the organization management activated route data subscription diff --git a/src/main/webapp/app/admin/organization-management/organization-management-update.component.ts b/src/main/webapp/app/admin/organization-management/organization-management-update.component.ts index 1ce6a53c4183..4eace90dca4a 100644 --- a/src/main/webapp/app/admin/organization-management/organization-management-update.component.ts +++ b/src/main/webapp/app/admin/organization-management/organization-management-update.component.ts @@ -16,7 +16,10 @@ export class OrganizationManagementUpdateComponent implements OnInit { faSave = faSave; faBan = faBan; - constructor(private route: ActivatedRoute, private organizationService: OrganizationManagementService) {} + constructor( + private route: ActivatedRoute, + private organizationService: OrganizationManagementService, + ) {} /** * Enable subscriptions to retrieve the organization based on the activated route on init diff --git a/src/main/webapp/app/admin/organization-management/organization-management.service.ts b/src/main/webapp/app/admin/organization-management/organization-management.service.ts index de99b4343797..f488abe062b3 100644 --- a/src/main/webapp/app/admin/organization-management/organization-management.service.ts +++ b/src/main/webapp/app/admin/organization-management/organization-management.service.ts @@ -11,7 +11,10 @@ export class OrganizationManagementService { public resourceUrl = 'api/organizations'; public adminResourceUrl = 'api/admin/organizations'; - constructor(private http: HttpClient, private entityTitleService: EntityTitleService) {} + constructor( + private http: HttpClient, + private entityTitleService: EntityTitleService, + ) {} /** * Send GET request to retrieve all organizations diff --git a/src/main/webapp/app/admin/system-notification-management/system-notification-management-detail.component.ts b/src/main/webapp/app/admin/system-notification-management/system-notification-management-detail.component.ts index b2059ee7dee0..05c64dec18e7 100644 --- a/src/main/webapp/app/admin/system-notification-management/system-notification-management-detail.component.ts +++ b/src/main/webapp/app/admin/system-notification-management/system-notification-management-detail.component.ts @@ -13,7 +13,11 @@ export class SystemNotificationManagementDetailComponent implements OnInit { // Icons faWrench = faWrench; - constructor(private systemNotificationService: SystemNotificationService, private route: ActivatedRoute, private router: Router) {} + constructor( + private systemNotificationService: SystemNotificationService, + private route: ActivatedRoute, + private router: Router, + ) {} /** * Assigns the subscription to system notification service diff --git a/src/main/webapp/app/admin/system-notification-management/system-notification-management-update.component.ts b/src/main/webapp/app/admin/system-notification-management/system-notification-management-update.component.ts index 354525ada52d..75523020fa0d 100644 --- a/src/main/webapp/app/admin/system-notification-management/system-notification-management-update.component.ts +++ b/src/main/webapp/app/admin/system-notification-management/system-notification-management-update.component.ts @@ -26,7 +26,12 @@ export class SystemNotificationManagementUpdateComponent implements OnInit { faSave = faSave; faBan = faBan; - constructor(private userService: UserService, private systemNotificationService: AdminSystemNotificationService, private route: ActivatedRoute, private router: Router) {} + constructor( + private userService: UserService, + private systemNotificationService: AdminSystemNotificationService, + private route: ActivatedRoute, + private router: Router, + ) {} /** * Loads notification from route data diff --git a/src/main/webapp/app/admin/upcoming-exams-and-exercises/upcoming-exams-and-exercises.component.ts b/src/main/webapp/app/admin/upcoming-exams-and-exercises/upcoming-exams-and-exercises.component.ts index 62a0bf18af2d..bb8614435e1d 100644 --- a/src/main/webapp/app/admin/upcoming-exams-and-exercises/upcoming-exams-and-exercises.component.ts +++ b/src/main/webapp/app/admin/upcoming-exams-and-exercises/upcoming-exams-and-exercises.component.ts @@ -18,7 +18,11 @@ export class UpcomingExamsAndExercisesComponent implements OnInit { predicate: string; reverse: boolean; - constructor(private exerciseService: ExerciseService, private examManagementService: ExamManagementService, private sortService: SortService) {} + constructor( + private exerciseService: ExerciseService, + private examManagementService: ExamManagementService, + private sortService: SortService, + ) {} ngOnInit(): void { this.exerciseService.getUpcomingExercises().subscribe((res: ExerciseEntityArrayResponseType) => { diff --git a/src/main/webapp/app/admin/user-management/user-management.component.html b/src/main/webapp/app/admin/user-management/user-management.component.html index 005378bff6c8..c662bebe9762 100644 --- a/src/main/webapp/app/admin/user-management/user-management.component.html +++ b/src/main/webapp/app/admin/user-management/user-management.component.html @@ -54,7 +54,7 @@

> {{ - 'artemisApp.userManagement.filter.modal.open' | artemisTranslate : { num: filters.numberOfAppliedFilters } + 'artemisApp.userManagement.filter.modal.open' | artemisTranslate: { num: filters.numberOfAppliedFilters } }}

@@ -225,7 +225,7 @@
{{ 'artemisApp.userManagement.filter.origin.title' | artemisTra
-
{{ 'artemisApp.userManagement.filter.registrationNumber.title' | artemisTranslate : { num: this.filters.registrationNumberFilter.size } }}
+
{{ 'artemisApp.userManagement.filter.registrationNumber.title' | artemisTranslate: { num: this.filters.registrationNumberFilter.size } }}
@@ -354,7 +354,7 @@
{{ 'artemisApp.userManagement.filter.registrationNumber.title'
-
{{ 'artemisApp.userManagement.filter.status.title' | artemisTranslate : { num: this.filters.statusFilter.size } }}
+
{{ 'artemisApp.userManagement.filter.status.title' | artemisTranslate: { num: this.filters.statusFilter.size } }}
@@ -378,7 +378,7 @@
{{ 'artemisApp.userManagement.filter.status.title' | artemisTra
-
{{ 'artemisApp.userManagement.filter.course.title' | artemisTranslate : { num: this.filters.courseFilter.size } }}
+
{{ 'artemisApp.userManagement.filter.course.title' | artemisTranslate: { num: this.filters.courseFilter.size } }}
diff --git a/src/main/webapp/app/assessment/assessment-detail/assessment-detail.component.ts b/src/main/webapp/app/assessment/assessment-detail/assessment-detail.component.ts index 67b0f5db1874..4e2e02c5bfac 100644 --- a/src/main/webapp/app/assessment/assessment-detail/assessment-detail.component.ts +++ b/src/main/webapp/app/assessment/assessment-detail/assessment-detail.component.ts @@ -24,7 +24,10 @@ export class AssessmentDetailComponent { faExclamation = faExclamation; faExclamationTriangle = faExclamationTriangle; - constructor(private translateService: TranslateService, public structuredGradingCriterionService: StructuredGradingCriterionService) {} + constructor( + private translateService: TranslateService, + public structuredGradingCriterionService: StructuredGradingCriterionService, + ) {} /** * Emits assessment changes to parent component diff --git a/src/main/webapp/app/assessment/assessment-header/assessment-header.component.ts b/src/main/webapp/app/assessment/assessment-header/assessment-header.component.ts index 1566aa5da356..e8c076d27cf5 100644 --- a/src/main/webapp/app/assessment/assessment-header/assessment-header.component.ts +++ b/src/main/webapp/app/assessment/assessment-header/assessment-header.component.ts @@ -69,7 +69,11 @@ export class AssessmentHeaderComponent { this.highlightDifferencesChange.emit(this.highlightDifferences); } - constructor(public textAssessmentAnalytics: TextAssessmentAnalytics, protected route: ActivatedRoute, private translateService: TranslateService) { + constructor( + public textAssessmentAnalytics: TextAssessmentAnalytics, + protected route: ActivatedRoute, + private translateService: TranslateService, + ) { textAssessmentAnalytics.setComponentRoute(route); } diff --git a/src/main/webapp/app/assessment/assessment-locks/assessment-locks.component.html b/src/main/webapp/app/assessment/assessment-locks/assessment-locks.component.html index 959829d3ef96..dcd509b28749 100644 --- a/src/main/webapp/app/assessment/assessment-locks/assessment-locks.component.html +++ b/src/main/webapp/app/assessment/assessment-locks/assessment-locks.component.html @@ -33,7 +33,7 @@

> {{ submission.participation!.exercise!.title || '' }} - {{ submission.submissionDate | artemisDate : 'long-date' }} + {{ submission.submissionDate | artemisDate: 'long-date' }} {{ submission.participation!.submissions ? submission.participation!.submissions.length : 0 }} {{ submission.latestResult!.score }}% diff --git a/src/main/webapp/app/complaints/complaint-response.service.ts b/src/main/webapp/app/complaints/complaint-response.service.ts index 31832f76bafa..1617793ac53b 100644 --- a/src/main/webapp/app/complaints/complaint-response.service.ts +++ b/src/main/webapp/app/complaints/complaint-response.service.ts @@ -13,7 +13,10 @@ type EntityResponseType = HttpResponse; export class ComplaintResponseService { private resourceUrl = 'api/complaint-responses'; - constructor(private http: HttpClient, private accountService: AccountService) {} + constructor( + private http: HttpClient, + private accountService: AccountService, + ) {} /** * Checks if a complaint response is locked for the currently logged-in user diff --git a/src/main/webapp/app/complaints/complaint.service.ts b/src/main/webapp/app/complaints/complaint.service.ts index f131b3c7331a..ef9482373526 100644 --- a/src/main/webapp/app/complaints/complaint.service.ts +++ b/src/main/webapp/app/complaints/complaint.service.ts @@ -35,7 +35,10 @@ export class ComplaintService implements IComplaintService { private apiUrl = 'api'; private resourceUrl = this.apiUrl + '/complaints'; - constructor(private http: HttpClient, private complaintResponseService: ComplaintResponseService) {} + constructor( + private http: HttpClient, + private complaintResponseService: ComplaintResponseService, + ) {} /** * Checks if a complaint is locked for the currently logged-in user diff --git a/src/main/webapp/app/complaints/complaints-for-tutor/complaints-for-tutor.component.html b/src/main/webapp/app/complaints/complaints-for-tutor/complaints-for-tutor.component.html index 90d89060f5f1..284511c2e55f 100644 --- a/src/main/webapp/app/complaints/complaints-for-tutor/complaints-for-tutor.component.html +++ b/src/main/webapp/app/complaints/complaints-for-tutor/complaints-for-tutor.component.html @@ -19,12 +19,12 @@

- {{ 'artemisApp.locks.lockInformationYou' | artemisTranslate : { endDate: this.complaintResponse.lockEndDate | artemisDate } }} + {{ 'artemisApp.locks.lockInformationYou' | artemisTranslate: { endDate: this.complaintResponse.lockEndDate | artemisDate } }} {{ 'artemisApp.locks.lockInformation' - | artemisTranslate : { user: this.complaintResponse?.reviewer?.login, endDate: this.complaintResponse.lockEndDate | artemisDate } + | artemisTranslate: { user: this.complaintResponse?.reviewer?.login, endDate: this.complaintResponse.lockEndDate | artemisDate } }}
diff --git a/src/main/webapp/app/complaints/form/complaints-form.component.ts b/src/main/webapp/app/complaints/form/complaints-form.component.ts index c1aa310cb289..5e67c1170fda 100644 --- a/src/main/webapp/app/complaints/form/complaints-form.component.ts +++ b/src/main/webapp/app/complaints/form/complaints-form.component.ts @@ -29,7 +29,10 @@ export class ComplaintsFormComponent implements OnInit { readonly ComplaintType = ComplaintType; - constructor(private complaintService: ComplaintService, private alertService: AlertService) {} + constructor( + private complaintService: ComplaintService, + private alertService: AlertService, + ) {} ngOnInit(): void { this.course = getCourseFromExercise(this.exercise); diff --git a/src/main/webapp/app/complaints/list-of-complaints/list-of-complaints.component.html b/src/main/webapp/app/complaints/list-of-complaints/list-of-complaints.component.html index cd417eeeaa43..66cb3f7f63f9 100644 --- a/src/main/webapp/app/complaints/list-of-complaints/list-of-complaints.component.html +++ b/src/main/webapp/app/complaints/list-of-complaints/list-of-complaints.component.html @@ -140,7 +140,7 @@

>= - {{ complaintService.getResponseTimeInSeconds(complaint) | artemisDurationFromSeconds : true }} + {{ complaintService.getResponseTimeInSeconds(complaint) | artemisDurationFromSeconds: true }} { return this.http.post('api/public/authenticate', credentials); diff --git a/src/main/webapp/app/core/interceptor/auth-expired.interceptor.ts b/src/main/webapp/app/core/interceptor/auth-expired.interceptor.ts index 02373a57410a..560b79ecfce6 100644 --- a/src/main/webapp/app/core/interceptor/auth-expired.interceptor.ts +++ b/src/main/webapp/app/core/interceptor/auth-expired.interceptor.ts @@ -9,7 +9,12 @@ import { AccountService } from 'app/core/auth/account.service'; @Injectable() export class AuthExpiredInterceptor implements HttpInterceptor { - constructor(private loginService: LoginService, private stateStorageService: StateStorageService, private router: Router, private accountService: AccountService) {} + constructor( + private loginService: LoginService, + private stateStorageService: StateStorageService, + private router: Router, + private accountService: AccountService, + ) {} /** * Identifies and handles a given HTTP request. If the request's error status is 401, the current user will be logged out. diff --git a/src/main/webapp/app/core/interceptor/errorhandler.interceptor.ts b/src/main/webapp/app/core/interceptor/errorhandler.interceptor.ts index c24e87b7e4f8..6b3b3ce0b9c5 100644 --- a/src/main/webapp/app/core/interceptor/errorhandler.interceptor.ts +++ b/src/main/webapp/app/core/interceptor/errorhandler.interceptor.ts @@ -7,7 +7,10 @@ import { AccountService } from 'app/core/auth/account.service'; @Injectable() export class ErrorHandlerInterceptor implements HttpInterceptor { - constructor(private eventManager: EventManager, private accountService: AccountService) {} + constructor( + private eventManager: EventManager, + private accountService: AccountService, + ) {} /** * Identifies and handles a given HTTP request. If the request's error status is not 401 while the user is not diff --git a/src/main/webapp/app/core/legal/data-export/data-export.component.html b/src/main/webapp/app/core/legal/data-export/data-export.component.html index 37a9988a2ef4..53f97f393bee 100644 --- a/src/main/webapp/app/core/legal/data-export/data-export.component.html +++ b/src/main/webapp/app/core/legal/data-export/data-export.component.html @@ -36,11 +36,11 @@

{{ 'artemisApp.dataExport.lastRequestDate' | artemisTranslate }} - {{ dataExport?.createdDate | artemisDate : 'long-date' }} + {{ dataExport?.createdDate | artemisDate: 'long-date' }}

{{ 'artemisApp.dataExport.nextRequestDate' | artemisTranslate }} - {{ dataExport?.nextRequestDate | artemisDate : 'long-date' }} + {{ dataExport?.nextRequestDate | artemisDate: 'long-date' }}

{{ 'artemisApp.dataExport.isBeingCreated' | artemisTranslate }} diff --git a/src/main/webapp/app/core/legal/data-export/data-export.component.ts b/src/main/webapp/app/core/legal/data-export/data-export.component.ts index 27c116daf5c4..d5bd8dfca62f 100644 --- a/src/main/webapp/app/core/legal/data-export/data-export.component.ts +++ b/src/main/webapp/app/core/legal/data-export/data-export.component.ts @@ -34,7 +34,12 @@ export class DataExportComponent implements OnInit { state?: DataExportState; dataExport: DataExport = new DataExport(); - constructor(private dataExportService: DataExportService, private accountService: AccountService, private alertService: AlertService, private route: ActivatedRoute) {} + constructor( + private dataExportService: DataExportService, + private accountService: AccountService, + private alertService: AlertService, + private route: ActivatedRoute, + ) {} ngOnInit() { this.currentLogin = this.accountService.userIdentity?.login; diff --git a/src/main/webapp/app/core/legal/imprint.component.ts b/src/main/webapp/app/core/legal/imprint.component.ts index e98fb69f2609..e29ca5b34d35 100644 --- a/src/main/webapp/app/core/legal/imprint.component.ts +++ b/src/main/webapp/app/core/legal/imprint.component.ts @@ -13,7 +13,11 @@ export class ImprintComponent implements AfterViewInit, OnInit, OnDestroy { imprint: string; private languageChangeSubscription?: Subscription; - constructor(private route: ActivatedRoute, private legalDocumentService: LegalDocumentService, private languageHelper: JhiLanguageHelper) {} + constructor( + private route: ActivatedRoute, + private legalDocumentService: LegalDocumentService, + private languageHelper: JhiLanguageHelper, + ) {} /** * On init get the Imprint statement file from the Artemis server and set up a subscription to fetch the file again if the language was changed. diff --git a/src/main/webapp/app/core/sentry/deduplicate.sentry-integration.ts b/src/main/webapp/app/core/sentry/deduplicate.sentry-integration.ts index d841f0a36608..ad6d5418b946 100644 --- a/src/main/webapp/app/core/sentry/deduplicate.sentry-integration.ts +++ b/src/main/webapp/app/core/sentry/deduplicate.sentry-integration.ts @@ -21,12 +21,15 @@ export class ArtemisDeduplicate implements Integration { } else { // Add event to seen events and schedule removal in 5 minutes (throttle) this.observedEventHashes.push(eventHash); - setTimeout(() => { - const index = this.observedEventHashes.indexOf(eventHash); - if (index >= 0) { - this.observedEventHashes.splice(index, 1); - } - }, 5 * 60 * 1000); + setTimeout( + () => { + const index = this.observedEventHashes.indexOf(eventHash); + if (index >= 0) { + this.observedEventHashes.splice(index, 1); + } + }, + 5 * 60 * 1000, + ); } } catch (e) { console.error(e); diff --git a/src/main/webapp/app/core/theme/theme-switch.component.scss b/src/main/webapp/app/core/theme/theme-switch.component.scss index d0090ebef470..404f6b46be2e 100644 --- a/src/main/webapp/app/core/theme/theme-switch.component.scss +++ b/src/main/webapp/app/core/theme/theme-switch.component.scss @@ -44,7 +44,9 @@ $ease-out: cubic-bezier(0.9, 0, 0.1, 1); & > .sun-beams { stroke: var(--navbar-dark-color); stroke-width: 2px; - transition: transform 1s $ease-default, opacity 0.5s $ease-default; + transition: + transform 1s $ease-default, + opacity 0.5s $ease-default; } & > .sun { diff --git a/src/main/webapp/app/core/util/alert.service.ts b/src/main/webapp/app/core/util/alert.service.ts index a5f05c224a01..359a0af650d0 100644 --- a/src/main/webapp/app/core/util/alert.service.ts +++ b/src/main/webapp/app/core/util/alert.service.ts @@ -64,7 +64,12 @@ export class AlertService { readonly conflictErrorKeysToSkip: string[] = ['cannotRegisterInstructor']; - constructor(private sanitizer: DomSanitizer, private ngZone: NgZone, private translateService: TranslateService, private eventManager: EventManager) { + constructor( + private sanitizer: DomSanitizer, + private ngZone: NgZone, + private translateService: TranslateService, + private eventManager: EventManager, + ) { this.errorListener = eventManager.subscribe('artemisApp.error', (response: EventWithContent | string) => { const errorResponse = (response as EventWithContent).content; this.addErrorAlert(errorResponse.message, errorResponse.translationKey, errorResponse.translationParams); diff --git a/src/main/webapp/app/core/util/event-manager.service.ts b/src/main/webapp/app/core/util/event-manager.service.ts index 266c04580fac..248d6826ef9c 100644 --- a/src/main/webapp/app/core/util/event-manager.service.ts +++ b/src/main/webapp/app/core/util/event-manager.service.ts @@ -3,7 +3,10 @@ import { Observable, Observer, Subscription } from 'rxjs'; import { filter, share } from 'rxjs/operators'; export class EventWithContent { - constructor(public name: string, public content: T) {} + constructor( + public name: string, + public content: T, + ) {} } /** diff --git a/src/main/webapp/app/course/competencies/competency-form/competency-form.component.html b/src/main/webapp/app/course/competencies/competency-form/competency-form.component.html index e4a9d1c6853a..74b482c64df0 100644 --- a/src/main/webapp/app/course/competencies/competency-form/competency-form.component.html +++ b/src/main/webapp/app/course/competencies/competency-form/competency-form.component.html @@ -54,7 +54,7 @@ -

-
+
+
diff --git a/src/main/webapp/app/course/manage/course-lti-configuration/edit-course-lti-configuration.component.ts b/src/main/webapp/app/course/manage/course-lti-configuration/edit-course-lti-configuration.component.ts index 0aa9409a059a..31df8aafb220 100644 --- a/src/main/webapp/app/course/manage/course-lti-configuration/edit-course-lti-configuration.component.ts +++ b/src/main/webapp/app/course/manage/course-lti-configuration/edit-course-lti-configuration.component.ts @@ -24,7 +24,11 @@ export class EditCourseLtiConfigurationComponent implements OnInit { faBan = faBan; faSave = faSave; - constructor(private route: ActivatedRoute, private courseService: CourseManagementService, private router: Router) {} + constructor( + private route: ActivatedRoute, + private courseService: CourseManagementService, + private router: Router, + ) {} /** * Gets the configuration for the course encoded in the route and prepares the form diff --git a/src/main/webapp/app/course/manage/course-management-exercises.component.ts b/src/main/webapp/app/course/manage/course-management-exercises.component.ts index 6c1dce22dc09..d9d55cd355bc 100644 --- a/src/main/webapp/app/course/manage/course-management-exercises.component.ts +++ b/src/main/webapp/app/course/manage/course-management-exercises.component.ts @@ -40,7 +40,11 @@ export class CourseManagementExercisesComponent implements OnInit { @ContentChild('overrideProgrammingExerciseCard') overrideProgrammingExerciseCard: TemplateRef; @ContentChild('overrideNonProgrammingExerciseCard') overrideNonProgrammingExerciseCard: TemplateRef; - constructor(private courseService: CourseManagementService, private router: Router, private route: ActivatedRoute) {} + constructor( + private courseService: CourseManagementService, + private router: Router, + private route: ActivatedRoute, + ) {} /** * initializes course diff --git a/src/main/webapp/app/course/manage/course-management-statistics.component.ts b/src/main/webapp/app/course/manage/course-management-statistics.component.ts index 74f32d141db9..9ea73f967a03 100644 --- a/src/main/webapp/app/course/manage/course-management-statistics.component.ts +++ b/src/main/webapp/app/course/manage/course-management-statistics.component.ts @@ -51,7 +51,10 @@ export class CourseManagementStatisticsComponent implements OnInit { courseStatistics: CourseManagementStatisticsDTO; - constructor(private service: StatisticsService, private route: ActivatedRoute) {} + constructor( + private service: StatisticsService, + private route: ActivatedRoute, + ) {} ngOnInit() { this.paramSub = this.route.params.subscribe((params) => { diff --git a/src/main/webapp/app/course/manage/course-update.component.html b/src/main/webapp/app/course/manage/course-update.component.html index 30762f3ea4ff..0144c2cc9fc7 100644 --- a/src/main/webapp/app/course/manage/course-update.component.html +++ b/src/main/webapp/app/course/manage/course-update.component.html @@ -36,8 +36,8 @@

Short Name -
-
+
+
diff --git a/src/main/webapp/app/course/manage/detail/course-detail-line-chart.component.ts b/src/main/webapp/app/course/manage/detail/course-detail-line-chart.component.ts index 1ea2ae762720..980515a4544c 100644 --- a/src/main/webapp/app/course/manage/detail/course-detail-line-chart.component.ts +++ b/src/main/webapp/app/course/manage/detail/course-detail-line-chart.component.ts @@ -74,7 +74,10 @@ export class CourseDetailLineChartComponent extends ActiveStudentsChart implemen faArrowLeft = faArrowLeft; faArrowRight = faArrowRight; - constructor(private service: CourseManagementService, private translateService: TranslateService) { + constructor( + private service: CourseManagementService, + private translateService: TranslateService, + ) { super(); this.translateService.onLangChange.subscribe(() => { this.updateXAxisLabel(); diff --git a/src/main/webapp/app/course/manage/detail/course-detail.component.ts b/src/main/webapp/app/course/manage/detail/course-detail.component.ts index d7d9cd85e35e..56c3114f5763 100644 --- a/src/main/webapp/app/course/manage/detail/course-detail.component.ts +++ b/src/main/webapp/app/course/manage/detail/course-detail.component.ts @@ -47,7 +47,12 @@ export class CourseDetailComponent implements OnInit, OnDestroy { faChartBar = faChartBar; faClipboard = faClipboard; - constructor(private eventManager: EventManager, private courseManagementService: CourseManagementService, private route: ActivatedRoute, private alertService: AlertService) {} + constructor( + private eventManager: EventManager, + private courseManagementService: CourseManagementService, + private route: ActivatedRoute, + private alertService: AlertService, + ) {} /** * On init load the course information and subscribe to listen for changes in courses. diff --git a/src/main/webapp/app/course/manage/overview/course-management-card.component.html b/src/main/webapp/app/course/manage/overview/course-management-card.component.html index 577a52abb65b..f050f5d2ad9f 100644 --- a/src/main/webapp/app/course/manage/overview/course-management-card.component.html +++ b/src/main/webapp/app/course/manage/overview/course-management-card.component.html @@ -4,12 +4,12 @@
-
{{ course.startDate | artemisDate : 'long-date' }} - {{ course.endDate | artemisDate : 'long-date' }}
+
{{ course.startDate | artemisDate: 'long-date' }} - {{ course.endDate | artemisDate: 'long-date' }}
- Start Date: {{ course.startDate | artemisDate : 'long-date' }} + Start Date: {{ course.startDate | artemisDate: 'long-date' }}
- End Date: {{ course.endDate | artemisDate : 'long-date' }} + End Date: {{ course.endDate | artemisDate: 'long-date' }}
@@ -156,7 +156,7 @@

{{ course.title }} ({{
- {{ 'artemisApp.course.pastExercises' | artemisTranslate : { amount: pastExercises.length, total: pastExerciseCount } }} + {{ 'artemisApp.course.pastExercises' | artemisTranslate: { amount: pastExercises.length, total: pastExerciseCount } }}
- {{ 'artemisApp.plagiarism.plagiarismCases.appearsInComparisons' | artemisTranslate : { count: plagiarismCase.plagiarismSubmissions.length } }} + {{ 'artemisApp.plagiarism.plagiarismCases.appearsInComparisons' | artemisTranslate: { count: plagiarismCase.plagiarismSubmissions.length } }}
{{ 'artemisApp.plagiarism.plagiarismCases.notifiedAt' | artemisTranslate }} {{ plagiarismCase.post.creationDate | artemisDate }} diff --git a/src/main/webapp/app/course/plagiarism-cases/instructor-view/plagiarism-cases-instructor-view.component.ts b/src/main/webapp/app/course/plagiarism-cases/instructor-view/plagiarism-cases-instructor-view.component.ts index 72b1f6eb9d61..01c67a85b9d3 100644 --- a/src/main/webapp/app/course/plagiarism-cases/instructor-view/plagiarism-cases-instructor-view.component.ts +++ b/src/main/webapp/app/course/plagiarism-cases/instructor-view/plagiarism-cases-instructor-view.component.ts @@ -21,7 +21,10 @@ export class PlagiarismCasesInstructorViewComponent implements OnInit { documentationType = DocumentationType.PlagiarismChecks; - constructor(private plagiarismCasesService: PlagiarismCasesService, private route: ActivatedRoute) {} + constructor( + private plagiarismCasesService: PlagiarismCasesService, + private route: ActivatedRoute, + ) {} ngOnInit(): void { this.courseId = Number(this.route.snapshot.paramMap.get('courseId')); diff --git a/src/main/webapp/app/course/plagiarism-cases/shared/verdict/plagiarism-case-verdict.component.html b/src/main/webapp/app/course/plagiarism-cases/shared/verdict/plagiarism-case-verdict.component.html index f964e20a8f75..6c76e8c03b33 100644 --- a/src/main/webapp/app/course/plagiarism-cases/shared/verdict/plagiarism-case-verdict.component.html +++ b/src/main/webapp/app/course/plagiarism-cases/shared/verdict/plagiarism-case-verdict.component.html @@ -11,7 +11,7 @@
[class]="plagiarismCase.verdict == plagiarismVerdict.NO_PLAGIARISM ? 'bg-success' : 'bg-danger'" ngbTooltip="{{ 'artemisApp.plagiarism.plagiarismCases.verdict.description' - | artemisTranslate : { date: plagiarismCase.verdictDate | artemisDate, user: plagiarismCase.verdictBy?.name } + | artemisTranslate: { date: plagiarismCase.verdictDate | artemisDate, user: plagiarismCase.verdictBy?.name } }}" >
{{ 'artemisApp.plagiarism.plagiarismCases.verdict.verdict' | artemisTranslate }}: {{ verdictTranslationString | artemisTranslate }}
diff --git a/src/main/webapp/app/course/plagiarism-cases/student-view/detail-view/plagiarism-case-student-detail-view.component.html b/src/main/webapp/app/course/plagiarism-cases/student-view/detail-view/plagiarism-case-student-detail-view.component.html index 2a8acf7848af..91afbb76ebfc 100644 --- a/src/main/webapp/app/course/plagiarism-cases/student-view/detail-view/plagiarism-case-student-detail-view.component.html +++ b/src/main/webapp/app/course/plagiarism-cases/student-view/detail-view/plagiarism-case-student-detail-view.component.html @@ -51,7 +51,7 @@

{{ 'artemisApp.plagiarism.plagiarismCases.conversation' | artemisTranslate } *ngIf="posts[0].creationDate" [innerHTML]=" 'artemisApp.plagiarism.replyToAccusationDueDateNotification' - | artemisTranslate : { dueDate: posts[0].creationDate.add(7, 'day').format('DD.MM.YYYY') } + | artemisTranslate: { dueDate: posts[0].creationDate.add(7, 'day').format('DD.MM.YYYY') } " >

diff --git a/src/main/webapp/app/course/plagiarism-cases/student-view/detail-view/plagiarism-case-student-detail-view.component.ts b/src/main/webapp/app/course/plagiarism-cases/student-view/detail-view/plagiarism-case-student-detail-view.component.ts index 3764c8d712e1..2dd031974d54 100644 --- a/src/main/webapp/app/course/plagiarism-cases/student-view/detail-view/plagiarism-case-student-detail-view.component.ts +++ b/src/main/webapp/app/course/plagiarism-cases/student-view/detail-view/plagiarism-case-student-detail-view.component.ts @@ -39,7 +39,11 @@ export class PlagiarismCaseStudentDetailViewComponent implements OnInit, OnDestr affectedExerciseRouterLink: (string | number)[]; - constructor(protected metisService: MetisService, private plagiarismCasesService: PlagiarismCasesService, private activatedRoute: ActivatedRoute) {} + constructor( + protected metisService: MetisService, + private plagiarismCasesService: PlagiarismCasesService, + private activatedRoute: ActivatedRoute, + ) {} ngOnInit(): void { this.paramSubscription = combineLatest({ diff --git a/src/main/webapp/app/course/tutorial-groups/services/tutorial-group-session.service.ts b/src/main/webapp/app/course/tutorial-groups/services/tutorial-group-session.service.ts index c453dc0a7745..c990ff95078e 100644 --- a/src/main/webapp/app/course/tutorial-groups/services/tutorial-group-session.service.ts +++ b/src/main/webapp/app/course/tutorial-groups/services/tutorial-group-session.service.ts @@ -19,7 +19,10 @@ export class TutorialGroupSessionDTO { export class TutorialGroupSessionService { private resourceURL = 'api'; - constructor(private httpClient: HttpClient, private tutorialGroupFreePeriodService: TutorialGroupFreePeriodService) {} + constructor( + private httpClient: HttpClient, + private tutorialGroupFreePeriodService: TutorialGroupFreePeriodService, + ) {} getOneOfTutorialGroup(courseId: number, tutorialGroupId: number, sessionId: number) { return this.httpClient .get(`${this.resourceURL}/courses/${courseId}/tutorial-groups/${tutorialGroupId}/sessions/${sessionId}`, { observe: 'response' }) diff --git a/src/main/webapp/app/course/tutorial-groups/shared/tutorial-group-detail/tutorial-group-detail.component.html b/src/main/webapp/app/course/tutorial-groups/shared/tutorial-group-detail/tutorial-group-detail.component.html index e44c3c4be608..8c7ce6a94a91 100644 --- a/src/main/webapp/app/course/tutorial-groups/shared/tutorial-group-detail/tutorial-group-detail.component.html +++ b/src/main/webapp/app/course/tutorial-groups/shared/tutorial-group-detail/tutorial-group-detail.component.html @@ -166,7 +166,7 @@

{{ 'artemisApp.pages.tutorialGroupDetail.title' | artemisTranslate }}:

(tutorialGroup.tutorialGroupSchedule!.repetitionFrequency! === 1 ? 'artemisApp.entities.tutorialGroupSchedule.repetitionOneWeek' : 'artemisApp.entities.tutorialGroupSchedule.repetitionNWeeks' - ) | artemisTranslate : { n: tutorialGroup.tutorialGroupSchedule!.repetitionFrequency! } + ) | artemisTranslate: { n: tutorialGroup.tutorialGroupSchedule!.repetitionFrequency! } }} diff --git a/src/main/webapp/app/course/tutorial-groups/shared/tutorial-group-detail/tutorial-group-detail.component.ts b/src/main/webapp/app/course/tutorial-groups/shared/tutorial-group-detail/tutorial-group-detail.component.ts index e11fd84b8365..8a8044b08eba 100644 --- a/src/main/webapp/app/course/tutorial-groups/shared/tutorial-group-detail/tutorial-group-detail.component.ts +++ b/src/main/webapp/app/course/tutorial-groups/shared/tutorial-group-detail/tutorial-group-detail.component.ts @@ -40,7 +40,10 @@ export class TutorialGroupDetailComponent implements OnChanges { readonly isMessagingEnabled = isMessagingEnabled; - constructor(private artemisMarkdownService: ArtemisMarkdownService, private changeDetectorRef: ChangeDetectorRef) {} + constructor( + private artemisMarkdownService: ArtemisMarkdownService, + private changeDetectorRef: ChangeDetectorRef, + ) {} ngOnChanges(changes: SimpleChanges) { for (const propName in changes) { diff --git a/src/main/webapp/app/course/tutorial-groups/shared/tutorial-group-free-days-overview/tutorial-group-free-days-overview.component.html b/src/main/webapp/app/course/tutorial-groups/shared/tutorial-group-free-days-overview/tutorial-group-free-days-overview.component.html index d843b7dceb76..8020594f73f9 100644 --- a/src/main/webapp/app/course/tutorial-groups/shared/tutorial-group-free-days-overview/tutorial-group-free-days-overview.component.html +++ b/src/main/webapp/app/course/tutorial-groups/shared/tutorial-group-free-days-overview/tutorial-group-free-days-overview.component.html @@ -4,7 +4,7 @@
  • - {{ freeDay.start | artemisDate : 'long-date' : false : timeZone : true }} + {{ freeDay.start | artemisDate: 'long-date' : false : timeZone : true }}