diff --git a/cli/src/main/java/de/jplag/cli/CLI.java b/cli/src/main/java/de/jplag/cli/CLI.java index e67c445c9..2ffb821b9 100644 --- a/cli/src/main/java/de/jplag/cli/CLI.java +++ b/cli/src/main/java/de/jplag/cli/CLI.java @@ -1,7 +1,8 @@ package de.jplag.cli; -import static picocli.CommandLine.Model.UsageMessageSpec.SECTION_KEY_FOOTER; +import static picocli.CommandLine.Model.UsageMessageSpec.SECTION_KEY_DESCRIPTION_HEADING; import static picocli.CommandLine.Model.UsageMessageSpec.SECTION_KEY_OPTION_LIST; +import static picocli.CommandLine.Model.UsageMessageSpec.SECTION_KEY_SYNOPSIS; import java.io.File; import java.security.SecureRandom; @@ -50,12 +51,16 @@ public final class CLI { "More Abstract than Tree", "Students Nightmare", "No, changing variable names does not work", "The tech is out there!", "Developed by plagiarism experts."}; + private static final String OPTION_LIST_HEADING = "Parameter descriptions: "; + private final CommandLine commandLine; private final CliOptions options; private static final String IMPOSSIBLE_EXCEPTION = "This should not have happened." + " Please create an issue on github (https://github.com/jplag/JPlag/issues) with the entire output."; + private static final String DESCRIPTION_PATTERN = "%nJPlag - %s%n%s%n%n"; + /** * Main class for using JPlag via the CLI. * @param args are the CLI arguments that will be passed to JPlag. @@ -88,6 +93,8 @@ public CLI() { this.options = new CliOptions(); this.commandLine = new CommandLine(options); + this.commandLine.setHelpFactory(new HelpFactory()); + this.commandLine.getHelpSectionMap().put(SECTION_KEY_OPTION_LIST, help -> help.optionList().lines().map(it -> { if (it.startsWith(" -")) { return " " + it; @@ -98,7 +105,8 @@ public CLI() { buildSubcommands().forEach(commandLine::addSubcommand); - this.commandLine.getHelpSectionMap().put(SECTION_KEY_FOOTER, help -> generateDescription()); + this.commandLine.getHelpSectionMap().put(SECTION_KEY_SYNOPSIS, help -> help.synopsis(help.synopsisHeadingLength()) + generateDescription()); + this.commandLine.getHelpSectionMap().put(SECTION_KEY_DESCRIPTION_HEADING, help -> OPTION_LIST_HEADING); this.commandLine.setAllowSubcommandsAsOptionParameters(true); } @@ -228,7 +236,7 @@ private static MergingParameters getMergingParameters(CliOptions options) { private String generateDescription() { var randomDescription = DESCRIPTIONS[RANDOM.nextInt(DESCRIPTIONS.length)]; - return String.format("JPlag - %s%n%n%s", randomDescription, CREDITS); + return String.format(DESCRIPTION_PATTERN, randomDescription, CREDITS); } public String getResultFolder() { diff --git a/cli/src/main/java/de/jplag/cli/CustomHelp.java b/cli/src/main/java/de/jplag/cli/CustomHelp.java new file mode 100644 index 000000000..368f358ce --- /dev/null +++ b/cli/src/main/java/de/jplag/cli/CustomHelp.java @@ -0,0 +1,26 @@ +package de.jplag.cli; + +import picocli.CommandLine; + +/** + * Custom implementation for the help page, including the custom {@link ParamLabelRenderer} + */ +public class CustomHelp extends CommandLine.Help { + private final IParamLabelRenderer paramLabelRenderer; + + /** + * New instance + * @param command The {@link picocli.CommandLine.Model.CommandSpec} to build the help for + * @param colorScheme The {@link picocli.CommandLine.Help.ColorScheme} for the help page + */ + public CustomHelp(CommandLine.Model.CommandSpec command, ColorScheme colorScheme) { + super(command, colorScheme); + + this.paramLabelRenderer = new ParamLabelRenderer(super.parameterLabelRenderer()); + } + + @Override + public IParamLabelRenderer parameterLabelRenderer() { + return this.paramLabelRenderer; + } +} diff --git a/cli/src/main/java/de/jplag/cli/HelpFactory.java b/cli/src/main/java/de/jplag/cli/HelpFactory.java new file mode 100644 index 000000000..53aa208b7 --- /dev/null +++ b/cli/src/main/java/de/jplag/cli/HelpFactory.java @@ -0,0 +1,13 @@ +package de.jplag.cli; + +import picocli.CommandLine; + +/** + * Custom help factory, used to add the custom {@link ParamLabelRenderer}. + */ +public class HelpFactory implements CommandLine.IHelpFactory { + @Override + public CommandLine.Help create(CommandLine.Model.CommandSpec commandSpec, CommandLine.Help.ColorScheme colorScheme) { + return new CustomHelp(commandSpec, colorScheme); + } +} diff --git a/cli/src/main/java/de/jplag/cli/ParamLabelRenderer.java b/cli/src/main/java/de/jplag/cli/ParamLabelRenderer.java new file mode 100644 index 000000000..2d815af30 --- /dev/null +++ b/cli/src/main/java/de/jplag/cli/ParamLabelRenderer.java @@ -0,0 +1,44 @@ +package de.jplag.cli; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import picocli.CommandLine; + +/** + * Custom implementation of {@link picocli.CommandLine.Help.IParamLabelRenderer}, that show the available options for + * enums. For all other parameter types, the base renderer is called. + */ +public class ParamLabelRenderer implements CommandLine.Help.IParamLabelRenderer { + private final CommandLine.Help.IParamLabelRenderer base; + + private static final String PARAM_LABEL_PATTERN = "=<{%s}>"; + private static final String VALUE_SEPARATOR = ", "; + + /** + * New instance + * @param base The base renderer used for all non enum types + */ + public ParamLabelRenderer(CommandLine.Help.IParamLabelRenderer base) { + this.base = base; + } + + @Override + public CommandLine.Help.Ansi.Text renderParameterLabel(CommandLine.Model.ArgSpec argSpec, CommandLine.Help.Ansi ansi, + List styles) { + if (argSpec.type().isEnum()) { + @SuppressWarnings("unchecked") + Enum[] enumConstants = ((Class>) argSpec.type()).getEnumConstants(); + String enumValueNames = Arrays.stream(enumConstants).map(Enum::name).collect(Collectors.joining(VALUE_SEPARATOR)); + return CommandLine.Help.Ansi.AUTO.text(String.format(PARAM_LABEL_PATTERN, enumValueNames)); + } + + return base.renderParameterLabel(argSpec, ansi, styles); + } + + @Override + public String separator() { + return base.separator(); + } +} diff --git a/cli/src/main/java/de/jplag/cli/logger/CollectedLogger.java b/cli/src/main/java/de/jplag/cli/logger/CollectedLogger.java index e38e88d97..80d94a74a 100644 --- a/cli/src/main/java/de/jplag/cli/logger/CollectedLogger.java +++ b/cli/src/main/java/de/jplag/cli/logger/CollectedLogger.java @@ -138,6 +138,7 @@ private String renderLevel(int level) { }; } + @Override public boolean isTraceEnabled() { return isLevelEnabled(LOG_LEVEL_TRACE); } @@ -147,114 +148,142 @@ public void trace(String message) { log(LOG_LEVEL_TRACE, message, null); } + @Override public void trace(String format, Object param1) { formatAndLog(LOG_LEVEL_TRACE, format, param1, null); } + @Override public void trace(String format, Object param1, Object param2) { formatAndLog(LOG_LEVEL_TRACE, format, param1, param2); } + @Override public void trace(String format, Object... argArray) { formatAndLog(LOG_LEVEL_TRACE, format, argArray); } + @Override public void trace(String message, Throwable t) { log(LOG_LEVEL_TRACE, message, t); } + @Override public boolean isDebugEnabled() { return isLevelEnabled(LOG_LEVEL_DEBUG); } + @Override public void debug(String message) { log(LOG_LEVEL_DEBUG, message, null); } + @Override public void debug(String format, Object param1) { formatAndLog(LOG_LEVEL_DEBUG, format, param1, null); } + @Override public void debug(String format, Object param1, Object param2) { formatAndLog(LOG_LEVEL_DEBUG, format, param1, param2); } + @Override public void debug(String format, Object... argArray) { formatAndLog(LOG_LEVEL_DEBUG, format, argArray); } + @Override public void debug(String message, Throwable throwable) { log(LOG_LEVEL_DEBUG, message, throwable); } + @Override public boolean isInfoEnabled() { return isLevelEnabled(LOG_LEVEL_INFO); } + @Override public void info(String message) { log(LOG_LEVEL_INFO, message, null); } + @Override public void info(String format, Object arg) { formatAndLog(LOG_LEVEL_INFO, format, arg, null); } + @Override public void info(String format, Object arg1, Object arg2) { formatAndLog(LOG_LEVEL_INFO, format, arg1, arg2); } + @Override public void info(String format, Object... argArray) { formatAndLog(LOG_LEVEL_INFO, format, argArray); } + @Override public void info(String message, Throwable throwable) { log(LOG_LEVEL_INFO, message, throwable); } + @Override public boolean isWarnEnabled() { return isLevelEnabled(LOG_LEVEL_WARN); } + @Override public void warn(String message) { log(LOG_LEVEL_WARN, message, null); } + @Override public void warn(String format, Object arg) { formatAndLog(LOG_LEVEL_WARN, format, arg, null); } + @Override public void warn(String format, Object arg1, Object arg2) { formatAndLog(LOG_LEVEL_WARN, format, arg1, arg2); } + @Override public void warn(String format, Object... argArray) { formatAndLog(LOG_LEVEL_WARN, format, argArray); } + @Override public void warn(String message, Throwable throwable) { log(LOG_LEVEL_WARN, message, throwable); } + @Override public boolean isErrorEnabled() { return isLevelEnabled(LOG_LEVEL_ERROR); } + @Override public void error(String message) { log(LOG_LEVEL_ERROR, message, null); } + @Override public void error(String format, Object arg) { formatAndLog(LOG_LEVEL_ERROR, format, arg, null); } + @Override public void error(String format, Object arg1, Object arg2) { formatAndLog(LOG_LEVEL_ERROR, format, arg1, arg2); } + @Override public void error(String format, Object... argArray) { formatAndLog(LOG_LEVEL_ERROR, format, argArray); } + @Override public void error(String message, Throwable throwable) { log(LOG_LEVEL_ERROR, message, throwable); } diff --git a/cli/src/main/java/de/jplag/cli/logger/CollectedLoggerFactory.java b/cli/src/main/java/de/jplag/cli/logger/CollectedLoggerFactory.java index 1971e4da9..ffba004b9 100644 --- a/cli/src/main/java/de/jplag/cli/logger/CollectedLoggerFactory.java +++ b/cli/src/main/java/de/jplag/cli/logger/CollectedLoggerFactory.java @@ -23,6 +23,7 @@ public CollectedLoggerFactory() { /** * Return an appropriate {@link CollectedLogger} instance by name. */ + @Override public Logger getLogger(String name) { CollectedLogger simpleLogger = loggerMap.get(name); if (simpleLogger != null) { diff --git a/cli/src/test/java/de/jplag/cli/CustomHelpTests.java b/cli/src/test/java/de/jplag/cli/CustomHelpTests.java new file mode 100644 index 000000000..3abde7505 --- /dev/null +++ b/cli/src/test/java/de/jplag/cli/CustomHelpTests.java @@ -0,0 +1,32 @@ +package de.jplag.cli; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import picocli.CommandLine; + +/** + * Tests for the {@link CustomHelp} class + */ +class CustomHelpTests { + private CommandLine.Help help; + + /** + * Creates the help object + */ + @BeforeEach + void setup() { + CommandLine.Model.CommandSpec commandSpec = CommandLine.Model.CommandSpec.create(); + this.help = new HelpFactory().create(commandSpec, new CommandLine(commandSpec).getColorScheme()); + } + + /** + * Tests, that the custom help object returns the custom label renderer + */ + @Test + void testReturnsCustomRenderer() { + Assertions.assertTrue(this.help.parameterLabelRenderer() instanceof ParamLabelRenderer, + "The custom help object returned the wrong ParamLabelRenderer type."); + } +} diff --git a/cli/src/test/java/de/jplag/cli/ParamLabelRendererTest.java b/cli/src/test/java/de/jplag/cli/ParamLabelRendererTest.java new file mode 100644 index 000000000..f10a2d350 --- /dev/null +++ b/cli/src/test/java/de/jplag/cli/ParamLabelRendererTest.java @@ -0,0 +1,82 @@ +package de.jplag.cli; + +import java.util.List; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import picocli.CommandLine; + +/** + * Tests for the custom {@link ParamLabelRenderer} + */ +class ParamLabelRendererTest { + private CommandLine.Help.IParamLabelRenderer paramLabelRenderer; + private CommandLine.Help.IParamLabelRenderer baseLabelRenderer; + + private CommandLine.Help.Ansi ansi; + private List styles; + + private static final String expectedEnumLabel = "=<{FIRST, SECOND, THIRD}>"; + + /** + * Creates the parameterLabelRenderer, the base renderer and formatting information for picocli. + */ + @BeforeEach + void setup() { + CommandLine commandLine = new CommandLine(CommandLine.Model.CommandSpec.create()); + CommandLine.Help help = commandLine.getHelp(); + + this.baseLabelRenderer = help.parameterLabelRenderer(); + this.paramLabelRenderer = new ParamLabelRenderer(this.baseLabelRenderer); + + this.ansi = help.ansi(); + this.styles = help.colorScheme().optionStyles(); + } + + /** + * Tests if enums are rendered correctly. + */ + @Test + void testRenderEnum() { + CommandLine.Model.ArgSpec argument = CommandLine.Model.OptionSpec.builder("enum").type(TestEnum.class).build(); + + String label = this.paramLabelRenderer.renderParameterLabel(argument, this.ansi, this.styles).plainString(); + Assertions.assertEquals(expectedEnumLabel, label); + } + + /** + * Tests, that a bunch of parameter types produces the same label as the default renderer from picocli + * @param parameterType The type for the option + */ + @ParameterizedTest + @ValueSource(classes = {Integer.class, String.class, Boolean.class}) + void testRenderDifferentTypes(Class parameterType) { + CommandLine.Model.ArgSpec argument = CommandLine.Model.OptionSpec.builder("test").type(parameterType).build(); + + String baseLabel = this.baseLabelRenderer.renderParameterLabel(argument, this.ansi, this.styles).plainString(); + String customLabel = this.paramLabelRenderer.renderParameterLabel(argument, this.ansi, this.styles).plainString(); + Assertions.assertEquals(baseLabel, customLabel); + } + + /** + * Tests that both the custom and the base label renderer return the same separator + */ + @Test + void testSameSeparator() { + Assertions.assertEquals(this.baseLabelRenderer.separator(), this.paramLabelRenderer.separator()); + } + + /** + * Enum used as for testing the label + */ + @SuppressWarnings("unused") + enum TestEnum { + FIRST, + SECOND, + THIRD + } +} diff --git a/core/src/main/java/de/jplag/options/JPlagOptions.java b/core/src/main/java/de/jplag/options/JPlagOptions.java index 8da73ee4c..801ab95ef 100644 --- a/core/src/main/java/de/jplag/options/JPlagOptions.java +++ b/core/src/main/java/de/jplag/options/JPlagOptions.java @@ -306,11 +306,7 @@ private static File convertLegacyBaseCodeToFile(String baseCodeSubmissionName, F while (normalizedName.endsWith(File.separator)) { normalizedName = normalizedName.substring(0, normalizedName.length() - 1); } - if (normalizedName.isEmpty() || normalizedName.contains(File.separator)) { - throw new BasecodeException( - "The basecode directory name \"" + normalizedName + "\" cannot contain dots! Please migrate to the path-based API."); - } - if (normalizedName.contains(".")) { + if (normalizedName.isEmpty() || normalizedName.contains(File.separator) || normalizedName.contains(".")) { throw new BasecodeException( "The basecode directory name \"" + normalizedName + "\" cannot contain dots! Please migrate to the path-based API."); } diff --git a/core/src/test/java/de/jplag/BasicFunctionalityTest.java b/core/src/test/java/de/jplag/BasicFunctionalityTest.java index 4bf4bf347..f7e6df53d 100644 --- a/core/src/test/java/de/jplag/BasicFunctionalityTest.java +++ b/core/src/test/java/de/jplag/BasicFunctionalityTest.java @@ -71,16 +71,16 @@ void testPartialPlagiarism() throws ExitException { // Hard coded assertions on selected comparisons assertEquals(0.237, getSelectedPercent(result, "A", "B"), DELTA); assertEquals(0.996, getSelectedPercent(result, "A", "C"), DELTA); - assertEquals(0.751, getSelectedPercent(result, "A", "D"), DELTA); + assertEquals(0.760, getSelectedPercent(result, "A", "D"), DELTA); assertEquals(0.237, getSelectedPercent(result, "B", "C"), DELTA); assertEquals(0.283, getSelectedPercent(result, "B", "D"), DELTA); - assertEquals(0.751, getSelectedPercent(result, "C", "D"), DELTA); + assertEquals(0.760, getSelectedPercent(result, "C", "D"), DELTA); // More detailed assertions for the plagiarism in A-D var biggestMatch = getSelectedComparison(result, "A", "D"); - assertEquals(0.947, biggestMatch.get().maximalSimilarity(), DELTA); - assertEquals(0.622, biggestMatch.get().minimalSimilarity(), DELTA); - assertEquals(11, biggestMatch.get().matches().size()); + assertEquals(0.959, biggestMatch.get().maximalSimilarity(), DELTA); + assertEquals(0.630, biggestMatch.get().minimalSimilarity(), DELTA); + assertEquals(12, biggestMatch.get().matches().size()); } @Test diff --git a/core/src/test/java/de/jplag/LegacyBaseCodeTest.java b/core/src/test/java/de/jplag/LegacyBaseCodeTest.java index 9b5b5e40a..ca02ccff1 100644 --- a/core/src/test/java/de/jplag/LegacyBaseCodeTest.java +++ b/core/src/test/java/de/jplag/LegacyBaseCodeTest.java @@ -15,17 +15,20 @@ */ @Deprecated(since = "4.0.0", forRemoval = true) class LegacyBaseCodeTest extends BaseCodeTest { + @Override @Test void testBasecodeUserSubmissionComparison() throws ExitException { JPlagResult result = runJPlag("basecode", it -> it.withBaseCodeSubmissionName("base")); verifyResults(result); } + @Override @Test void testTinyBasecode() { assertThrows(BasecodeException.class, () -> runJPlag("TinyBasecode", it -> it.withBaseCodeSubmissionName("base"))); } + @Override @Test void testEmptySubmission() throws ExitException { JPlagResult result = runJPlag("emptysubmission", it -> it.withBaseCodeSubmissionName("base")); @@ -38,12 +41,14 @@ void testAutoTrimFileSeparators() throws ExitException { verifyResults(result); } + @Override @Test void testBasecodePathComparison() throws ExitException { JPlagResult result = runJPlag("basecode", it -> it.withBaseCodeSubmissionName(getBasePath("basecode-base"))); assertEquals(3, result.getNumberOfSubmissions()); // "basecode/base" is now a user submission. } + @Override @Test void testInvalidBasecode() { assertThrows(BasecodeException.class, () -> runJPlag("basecode", it -> it.withBaseCodeSubmissionName("WrongBasecode"))); @@ -57,6 +62,7 @@ void testBasecodeUserSubmissionWithDots() { /** * The simple duplicate contains obvious plagiarism. */ + @Override @Test void testSubdirectoryGlobalBasecode() throws ExitException { String basecode = getBasePath("SubdirectoryBase"); @@ -67,6 +73,7 @@ void testSubdirectoryGlobalBasecode() throws ExitException { /** * The simple duplicate contains obvious plagiarism. */ + @Override @Test void testSubdirectoryLocalBasecode() throws ExitException { JPlagResult result = runJPlag("SubdirectoryDuplicate", it -> it.withSubdirectoryName("src").withBaseCodeSubmissionName("Base")); diff --git a/core/src/test/java/de/jplag/NewJavaFeaturesTest.java b/core/src/test/java/de/jplag/NewJavaFeaturesTest.java index 4052455b3..15a2436fb 100644 --- a/core/src/test/java/de/jplag/NewJavaFeaturesTest.java +++ b/core/src/test/java/de/jplag/NewJavaFeaturesTest.java @@ -1,6 +1,7 @@ package de.jplag; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assumptions.assumeTrue; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -8,16 +9,25 @@ import de.jplag.exceptions.ExitException; public class NewJavaFeaturesTest extends TestBase { + private static final int EXPECTED_MATCHES = 6; // might change if you add files to the submissions private static final double EXPECTED_SIMILARITY = 0.96; // might change if you add files to the submissions + private static final String EXPECTED_JAVA_VERSION = "17"; // might change with newer JPlag versions private static final String EXCLUSION_FILE_NAME = "blacklist.txt"; private static final String ROOT_DIRECTORY = "NewJavaFeatures"; private static final String CHANGE_MESSAGE = "Number of %s changed! If intended, modify the test case!"; + private static final String VERSION_MISMATCH_MESSAGE = "Using Java version %s instead of %s may skew the results."; + private static final String VERSION_MATCH_MESSAGE = "Java version matches, but results deviate from expected values"; + private static final String JAVA_VERSION_KEY = "java.version"; @Test @DisplayName("test comparison of Java files with modern language features") public void testJavaFeatureDuplicates() throws ExitException { + // pre-condition + String actualJavaVersion = System.getProperty(JAVA_VERSION_KEY); + assumeTrue(actualJavaVersion.startsWith(EXPECTED_JAVA_VERSION), VERSION_MISMATCH_MESSAGE.formatted(actualJavaVersion, EXPECTED_JAVA_VERSION)); + JPlagResult result = runJPlagWithExclusionFile(ROOT_DIRECTORY, EXCLUSION_FILE_NAME); // Ensure test input did not change: @@ -29,8 +39,7 @@ public void testJavaFeatureDuplicates() throws ExitException { // Check similarity and number of matches: var comparison = result.getAllComparisons().get(0); - assertEquals(EXPECTED_SIMILARITY, comparison.similarity(), DELTA); - assertEquals(EXPECTED_MATCHES, comparison.matches().size()); + assertEquals(EXPECTED_SIMILARITY, comparison.similarity(), DELTA, VERSION_MATCH_MESSAGE); + assertEquals(EXPECTED_MATCHES, comparison.matches().size(), VERSION_MATCH_MESSAGE); } - } diff --git a/core/src/test/java/de/jplag/TestBase.java b/core/src/test/java/de/jplag/TestBase.java index e658cf1c6..a2b17132e 100644 --- a/core/src/test/java/de/jplag/TestBase.java +++ b/core/src/test/java/de/jplag/TestBase.java @@ -8,6 +8,7 @@ import java.util.function.Function; import java.util.stream.Collectors; +import de.jplag.clustering.ClusteringOptions; import de.jplag.exceptions.ExitException; import de.jplag.java.JavaLanguage; import de.jplag.options.JPlagOptions; @@ -105,7 +106,8 @@ protected JPlagOptions getOptions(List newPaths, Function newPaths, List oldPaths, Function customization) { var newFiles = newPaths.stream().map(File::new).collect(Collectors.toSet()); var oldFiles = oldPaths.stream().map(File::new).collect(Collectors.toSet()); - JPlagOptions options = new JPlagOptions(new JavaLanguage(), newFiles, oldFiles); + JPlagOptions options = new JPlagOptions(new JavaLanguage(), newFiles, oldFiles) + .withClusteringOptions(new ClusteringOptions().withEnabled(false)); return customization.apply(options); } diff --git a/coverage-report/pom.xml b/coverage-report/pom.xml index b385967b6..944dc83a8 100644 --- a/coverage-report/pom.xml +++ b/coverage-report/pom.xml @@ -24,18 +24,23 @@ endtoend-testing ${revision} + + de.jplag + language-api + ${revision} + de.jplag language-antlr-utils ${revision} - - de.jplag - language-api + language-testutils ${revision} + + de.jplag text diff --git a/endtoend-testing/src/test/resources/results/java/sortAlgo.json b/endtoend-testing/src/test/resources/results/java/sortAlgo.json index dc4679a87..70c8ebbbc 100644 --- a/endtoend-testing/src/test/resources/results/java/sortAlgo.json +++ b/endtoend-testing/src/test/resources/results/java/sortAlgo.json @@ -4,9 +4,9 @@ }, "tests" : { "SortAlgo-SortAlgo5" : { - "minimal_similarity" : 0.6046511627906976, - "maximum_similarity" : 0.6341463414634146, - "matched_token_number" : 26 + "minimal_similarity" : 0.6511627906976745, + "maximum_similarity" : 0.6829268292682927, + "matched_token_number" : 28 }, "SortAlgo-SortAlgo6" : { "minimal_similarity" : 0.6122448979591837, @@ -19,9 +19,9 @@ "matched_token_number" : 38 }, "SortAlgo3_5-SortAlgo3_6" : { - "minimal_similarity" : 0.6428571428571429, - "maximum_similarity" : 0.6428571428571429, - "matched_token_number" : 36 + "minimal_similarity" : 0.7142857142857143, + "maximum_similarity" : 0.7142857142857143, + "matched_token_number" : 40 }, "SortAlgo6-SortAlgo7" : { "minimal_similarity" : 0.44642857142857145, @@ -64,9 +64,9 @@ "matched_token_number" : 33 }, "SortAlgo1_3-SortAlgo5" : { - "minimal_similarity" : 0.3620689655172414, - "maximum_similarity" : 0.4883720930232558, - "matched_token_number" : 21 + "minimal_similarity" : 0.4482758620689655, + "maximum_similarity" : 0.6046511627906976, + "matched_token_number" : 26 }, "SortAlgo-SortAlgo4" : { "minimal_similarity" : 0.7906976744186046, @@ -79,9 +79,9 @@ "matched_token_number" : 30 }, "SortAlgo2-SortAlgo2_5" : { - "minimal_similarity" : 0.6046511627906976, - "maximum_similarity" : 0.6341463414634146, - "matched_token_number" : 26 + "minimal_similarity" : 0.6511627906976745, + "maximum_similarity" : 0.6829268292682927, + "matched_token_number" : 28 }, "SortAlgo1_2-SortAlgo2" : { "minimal_similarity" : 0.7454545454545455, @@ -94,9 +94,9 @@ "matched_token_number" : 34 }, "SortAlgo5-SortAlgo6" : { - "minimal_similarity" : 0.46938775510204084, - "maximum_similarity" : 0.5348837209302325, - "matched_token_number" : 23 + "minimal_similarity" : 0.5510204081632653, + "maximum_similarity" : 0.627906976744186, + "matched_token_number" : 27 }, "SortAlgo1_2-SortAlgo4" : { "minimal_similarity" : 0.7272727272727273, @@ -104,14 +104,14 @@ "matched_token_number" : 40 }, "SortAlgo5-SortAlgo7" : { - "minimal_similarity" : 0.3392857142857143, - "maximum_similarity" : 0.4418604651162791, - "matched_token_number" : 19 + "minimal_similarity" : 0.375, + "maximum_similarity" : 0.4883720930232558, + "matched_token_number" : 21 }, "SortAlgo1_2-SortAlgo5" : { - "minimal_similarity" : 0.4727272727272727, - "maximum_similarity" : 0.6046511627906976, - "matched_token_number" : 26 + "minimal_similarity" : 0.5636363636363636, + "maximum_similarity" : 0.7209302325581395, + "matched_token_number" : 31 }, "SortAlgo1_2-SortAlgo6" : { "minimal_similarity" : 0.5454545454545454, @@ -124,9 +124,9 @@ "matched_token_number" : 44 }, "SortAlgo1-SortAlgo2_5" : { - "minimal_similarity" : 0.6046511627906976, - "maximum_similarity" : 0.6341463414634146, - "matched_token_number" : 26 + "minimal_similarity" : 0.6511627906976745, + "maximum_similarity" : 0.6829268292682927, + "matched_token_number" : 28 }, "SortAlgo1_3-SortAlgo3_6" : { "minimal_similarity" : 0.7758620689655172, @@ -134,9 +134,9 @@ "matched_token_number" : 45 }, "SortAlgo4-SortAlgo5" : { - "minimal_similarity" : 0.5813953488372093, - "maximum_similarity" : 0.5813953488372093, - "matched_token_number" : 25 + "minimal_similarity" : 0.627906976744186, + "maximum_similarity" : 0.627906976744186, + "matched_token_number" : 27 }, "SortAlgo4-SortAlgo6" : { "minimal_similarity" : 0.5306122448979592, @@ -149,9 +149,9 @@ "matched_token_number" : 33 }, "SortAlgo1_4-SortAlgo3_5" : { - "minimal_similarity" : 0.35714285714285715, - "maximum_similarity" : 0.46511627906976744, - "matched_token_number" : 20 + "minimal_similarity" : 0.42857142857142855, + "maximum_similarity" : 0.5581395348837209, + "matched_token_number" : 24 }, "SortAlgo1_4-SortAlgo3_6" : { "minimal_similarity" : 0.5535714285714286, @@ -159,9 +159,9 @@ "matched_token_number" : 31 }, "SortAlgo1_5-SortAlgo3_6" : { - "minimal_similarity" : 0.39285714285714285, - "maximum_similarity" : 0.5116279069767442, - "matched_token_number" : 22 + "minimal_similarity" : 0.5, + "maximum_similarity" : 0.6511627906976745, + "matched_token_number" : 28 }, "SortAlgo1_5-SortAlgo3_5" : { "minimal_similarity" : 0.6607142857142857, @@ -169,9 +169,9 @@ "matched_token_number" : 37 }, "SortAlgo1_6-SortAlgo3_5" : { - "minimal_similarity" : 0.39285714285714285, - "maximum_similarity" : 0.5116279069767442, - "matched_token_number" : 22 + "minimal_similarity" : 0.4642857142857143, + "maximum_similarity" : 0.6046511627906976, + "matched_token_number" : 26 }, "SortAlgo-SortAlgo4d3" : { "minimal_similarity" : 0.8297872340425532, @@ -199,9 +199,9 @@ "matched_token_number" : 35 }, "SortAlgo3-SortAlgo3_5" : { - "minimal_similarity" : 0.6428571428571429, - "maximum_similarity" : 0.6666666666666666, - "matched_token_number" : 36 + "minimal_similarity" : 0.6785714285714286, + "maximum_similarity" : 0.7037037037037037, + "matched_token_number" : 38 }, "SortAlgo1_4-SortAlgo4" : { "minimal_similarity" : 0.9534883720930233, @@ -224,14 +224,14 @@ "matched_token_number" : 32 }, "SortAlgo1_4-SortAlgo5" : { - "minimal_similarity" : 0.5348837209302325, - "maximum_similarity" : 0.5348837209302325, - "matched_token_number" : 23 + "minimal_similarity" : 0.6046511627906976, + "maximum_similarity" : 0.6046511627906976, + "matched_token_number" : 26 }, "SortAlgo2-SortAlgo3_5" : { - "minimal_similarity" : 0.375, - "maximum_similarity" : 0.5121951219512195, - "matched_token_number" : 21 + "minimal_similarity" : 0.4107142857142857, + "maximum_similarity" : 0.5609756097560976, + "matched_token_number" : 23 }, "SortAlgo1_4-SortAlgo6" : { "minimal_similarity" : 0.6530612244897959, @@ -249,9 +249,9 @@ "matched_token_number" : 26 }, "SortAlgo1-SortAlgo3_5" : { - "minimal_similarity" : 0.375, - "maximum_similarity" : 0.5121951219512195, - "matched_token_number" : 21 + "minimal_similarity" : 0.4107142857142857, + "maximum_similarity" : 0.5609756097560976, + "matched_token_number" : 23 }, "SortAlgo-SortAlgo1_2" : { "minimal_similarity" : 0.7454545454545455, @@ -259,14 +259,14 @@ "matched_token_number" : 41 }, "SortAlgo1_3-SortAlgo3_5" : { - "minimal_similarity" : 0.5172413793103449, - "maximum_similarity" : 0.5357142857142857, - "matched_token_number" : 30 + "minimal_similarity" : 0.603448275862069, + "maximum_similarity" : 0.625, + "matched_token_number" : 35 }, "SortAlgo1_2-SortAlgo3_5" : { - "minimal_similarity" : 0.375, - "maximum_similarity" : 0.38181818181818183, - "matched_token_number" : 21 + "minimal_similarity" : 0.4642857142857143, + "maximum_similarity" : 0.4727272727272727, + "matched_token_number" : 26 }, "SortAlgo1_2-SortAlgo3_6" : { "minimal_similarity" : 0.5714285714285714, @@ -279,9 +279,9 @@ "matched_token_number" : 34 }, "SortAlgo-SortAlgo1_5" : { - "minimal_similarity" : 0.6046511627906976, - "maximum_similarity" : 0.6341463414634146, - "matched_token_number" : 26 + "minimal_similarity" : 0.6511627906976745, + "maximum_similarity" : 0.6829268292682927, + "matched_token_number" : 28 }, "SortAlgo-SortAlgo1_4" : { "minimal_similarity" : 0.8372093023255814, @@ -309,9 +309,9 @@ "matched_token_number" : 34 }, "SortAlgo4d2-SortAlgo5" : { - "minimal_similarity" : 0.4897959183673469, - "maximum_similarity" : 0.5581395348837209, - "matched_token_number" : 24 + "minimal_similarity" : 0.5306122448979592, + "maximum_similarity" : 0.6046511627906976, + "matched_token_number" : 26 }, "SortAlgo4d2-SortAlgo6" : { "minimal_similarity" : 0.6938775510204082, @@ -359,9 +359,9 @@ "matched_token_number" : 40 }, "SortAlgo1_6-SortAlgo2_5" : { - "minimal_similarity" : 0.627906976744186, - "maximum_similarity" : 0.627906976744186, - "matched_token_number" : 27 + "minimal_similarity" : 0.7209302325581395, + "maximum_similarity" : 0.7209302325581395, + "matched_token_number" : 31 }, "SortAlgo1_4-SortAlgo4d1" : { "minimal_similarity" : 0.7083333333333334, @@ -369,9 +369,9 @@ "matched_token_number" : 34 }, "SortAlgo1_5-SortAlgo4d3" : { - "minimal_similarity" : 0.5106382978723404, - "maximum_similarity" : 0.5581395348837209, - "matched_token_number" : 24 + "minimal_similarity" : 0.5531914893617021, + "maximum_similarity" : 0.6046511627906976, + "matched_token_number" : 26 }, "SortAlgo1_4-SortAlgo4d2" : { "minimal_similarity" : 0.6938775510204082, @@ -379,9 +379,9 @@ "matched_token_number" : 34 }, "SortAlgo1_5-SortAlgo4d2" : { - "minimal_similarity" : 0.4897959183673469, - "maximum_similarity" : 0.5581395348837209, - "matched_token_number" : 24 + "minimal_similarity" : 0.5306122448979592, + "maximum_similarity" : 0.6046511627906976, + "matched_token_number" : 26 }, "SortAlgo1_4-SortAlgo4d3" : { "minimal_similarity" : 0.723404255319149, @@ -389,9 +389,9 @@ "matched_token_number" : 34 }, "SortAlgo1_5-SortAlgo4d1" : { - "minimal_similarity" : 0.5, - "maximum_similarity" : 0.5581395348837209, - "matched_token_number" : 24 + "minimal_similarity" : 0.5416666666666666, + "maximum_similarity" : 0.6046511627906976, + "matched_token_number" : 26 }, "SortAlgo4d2-SortAlgo4d3" : { "minimal_similarity" : 0.9183673469387755, @@ -419,9 +419,9 @@ "matched_token_number" : 40 }, "SortAlgo2-SortAlgo5" : { - "minimal_similarity" : 0.6046511627906976, - "maximum_similarity" : 0.6341463414634146, - "matched_token_number" : 26 + "minimal_similarity" : 0.6511627906976745, + "maximum_similarity" : 0.6829268292682927, + "matched_token_number" : 28 }, "SortAlgo4d1-SortAlgo4d3" : { "minimal_similarity" : 0.9375, @@ -449,14 +449,14 @@ "matched_token_number" : 37 }, "SortAlgo3_6-SortAlgo5" : { - "minimal_similarity" : 0.39285714285714285, - "maximum_similarity" : 0.5116279069767442, - "matched_token_number" : 22 + "minimal_similarity" : 0.5, + "maximum_similarity" : 0.6511627906976745, + "matched_token_number" : 28 }, "SortAlgo2_5-SortAlgo3_6" : { - "minimal_similarity" : 0.39285714285714285, - "maximum_similarity" : 0.5116279069767442, - "matched_token_number" : 22 + "minimal_similarity" : 0.5, + "maximum_similarity" : 0.6511627906976745, + "matched_token_number" : 28 }, "SortAlgo3_6-SortAlgo7" : { "minimal_similarity" : 0.42857142857142855, @@ -474,14 +474,14 @@ "matched_token_number" : 36 }, "SortAlgo4d3-SortAlgo5" : { - "minimal_similarity" : 0.5106382978723404, - "maximum_similarity" : 0.5581395348837209, - "matched_token_number" : 24 + "minimal_similarity" : 0.5531914893617021, + "maximum_similarity" : 0.6046511627906976, + "matched_token_number" : 26 }, "SortAlgo1_4-SortAlgo2_5" : { - "minimal_similarity" : 0.5348837209302325, - "maximum_similarity" : 0.5348837209302325, - "matched_token_number" : 23 + "minimal_similarity" : 0.6046511627906976, + "maximum_similarity" : 0.6046511627906976, + "matched_token_number" : 26 }, "SortAlgo1-SortAlgo4" : { "minimal_similarity" : 0.7906976744186046, @@ -489,9 +489,9 @@ "matched_token_number" : 34 }, "SortAlgo1-SortAlgo5" : { - "minimal_similarity" : 0.6046511627906976, - "maximum_similarity" : 0.6341463414634146, - "matched_token_number" : 26 + "minimal_similarity" : 0.6511627906976745, + "maximum_similarity" : 0.6829268292682927, + "matched_token_number" : 28 }, "SortAlgo1-SortAlgo2" : { "minimal_similarity" : 1.0, @@ -509,9 +509,9 @@ "matched_token_number" : 33 }, "SortAlgo1_3-SortAlgo2_5" : { - "minimal_similarity" : 0.3620689655172414, - "maximum_similarity" : 0.4883720930232558, - "matched_token_number" : 21 + "minimal_similarity" : 0.4482758620689655, + "maximum_similarity" : 0.6046511627906976, + "matched_token_number" : 26 }, "SortAlgo1_6-SortAlgo2" : { "minimal_similarity" : 0.7906976744186046, @@ -529,9 +529,9 @@ "matched_token_number" : 38 }, "SortAlgo1_2-SortAlgo2_5" : { - "minimal_similarity" : 0.4727272727272727, - "maximum_similarity" : 0.6046511627906976, - "matched_token_number" : 26 + "minimal_similarity" : 0.5636363636363636, + "maximum_similarity" : 0.7209302325581395, + "matched_token_number" : 31 }, "SortAlgo1_6-SortAlgo6" : { "minimal_similarity" : 0.7959183673469388, @@ -539,14 +539,14 @@ "matched_token_number" : 39 }, "SortAlgo-SortAlgo2_5" : { - "minimal_similarity" : 0.6046511627906976, - "maximum_similarity" : 0.6341463414634146, - "matched_token_number" : 26 + "minimal_similarity" : 0.6511627906976745, + "maximum_similarity" : 0.6829268292682927, + "matched_token_number" : 28 }, "SortAlgo1_6-SortAlgo5" : { - "minimal_similarity" : 0.627906976744186, - "maximum_similarity" : 0.627906976744186, - "matched_token_number" : 27 + "minimal_similarity" : 0.7209302325581395, + "maximum_similarity" : 0.7209302325581395, + "matched_token_number" : 31 }, "SortAlgo1_6-SortAlgo4" : { "minimal_similarity" : 0.6976744186046512, @@ -559,19 +559,19 @@ "matched_token_number" : 29 }, "SortAlgo1_5-SortAlgo6" : { - "minimal_similarity" : 0.46938775510204084, - "maximum_similarity" : 0.5348837209302325, - "matched_token_number" : 23 + "minimal_similarity" : 0.5510204081632653, + "maximum_similarity" : 0.627906976744186, + "matched_token_number" : 27 }, "SortAlgo2_5-SortAlgo7" : { - "minimal_similarity" : 0.3392857142857143, - "maximum_similarity" : 0.4418604651162791, - "matched_token_number" : 19 + "minimal_similarity" : 0.375, + "maximum_similarity" : 0.4883720930232558, + "matched_token_number" : 21 }, "SortAlgo1_5-SortAlgo7" : { - "minimal_similarity" : 0.3392857142857143, - "maximum_similarity" : 0.4418604651162791, - "matched_token_number" : 19 + "minimal_similarity" : 0.375, + "maximum_similarity" : 0.4883720930232558, + "matched_token_number" : 21 }, "SortAlgo1-SortAlgo4d3" : { "minimal_similarity" : 0.8297872340425532, @@ -579,9 +579,9 @@ "matched_token_number" : 39 }, "SortAlgo1_5-SortAlgo4" : { - "minimal_similarity" : 0.5813953488372093, - "maximum_similarity" : 0.5813953488372093, - "matched_token_number" : 25 + "minimal_similarity" : 0.627906976744186, + "maximum_similarity" : 0.627906976744186, + "matched_token_number" : 27 }, "SortAlgo1_5-SortAlgo5" : { "minimal_similarity" : 1.0, @@ -598,25 +598,25 @@ "maximum_similarity" : 0.9512195121951219, "matched_token_number" : 39 }, - "SortAlgo1_5-SortAlgo2" : { - "minimal_similarity" : 0.6046511627906976, - "maximum_similarity" : 0.6341463414634146, - "matched_token_number" : 26 - }, "SortAlgo3_5-SortAlgo6" : { - "minimal_similarity" : 0.5714285714285714, - "maximum_similarity" : 0.6530612244897959, - "matched_token_number" : 32 + "minimal_similarity" : 0.6428571428571429, + "maximum_similarity" : 0.7346938775510204, + "matched_token_number" : 36 + }, + "SortAlgo1_5-SortAlgo2" : { + "minimal_similarity" : 0.6511627906976745, + "maximum_similarity" : 0.6829268292682927, + "matched_token_number" : 28 }, "SortAlgo1_5-SortAlgo3" : { - "minimal_similarity" : 0.3888888888888889, - "maximum_similarity" : 0.4883720930232558, - "matched_token_number" : 21 + "minimal_similarity" : 0.46296296296296297, + "maximum_similarity" : 0.5813953488372093, + "matched_token_number" : 25 }, "SortAlgo3_5-SortAlgo7" : { - "minimal_similarity" : 0.26785714285714285, - "maximum_similarity" : 0.26785714285714285, - "matched_token_number" : 15 + "minimal_similarity" : 0.30357142857142855, + "maximum_similarity" : 0.30357142857142855, + "matched_token_number" : 17 }, "SortAlgo3-SortAlgo4d1" : { "minimal_similarity" : 0.7407407407407407, @@ -649,9 +649,9 @@ "matched_token_number" : 39 }, "SortAlgo1_5-SortAlgo1_6" : { - "minimal_similarity" : 0.627906976744186, - "maximum_similarity" : 0.627906976744186, - "matched_token_number" : 27 + "minimal_similarity" : 0.7209302325581395, + "maximum_similarity" : 0.7209302325581395, + "matched_token_number" : 31 }, "SortAlgo4d1-SortAlgo7" : { "minimal_similarity" : 0.6428571428571429, @@ -694,19 +694,19 @@ "matched_token_number" : 28 }, "SortAlgo4d1-SortAlgo5" : { - "minimal_similarity" : 0.5, - "maximum_similarity" : 0.5581395348837209, - "matched_token_number" : 24 + "minimal_similarity" : 0.5416666666666666, + "maximum_similarity" : 0.6046511627906976, + "matched_token_number" : 26 }, "SortAlgo3_5-SortAlgo4d2" : { - "minimal_similarity" : 0.4107142857142857, - "maximum_similarity" : 0.46938775510204084, - "matched_token_number" : 23 + "minimal_similarity" : 0.44642857142857145, + "maximum_similarity" : 0.5102040816326531, + "matched_token_number" : 25 }, "SortAlgo3_5-SortAlgo4" : { - "minimal_similarity" : 0.30357142857142855, - "maximum_similarity" : 0.3953488372093023, - "matched_token_number" : 17 + "minimal_similarity" : 0.35714285714285715, + "maximum_similarity" : 0.46511627906976744, + "matched_token_number" : 20 }, "SortAlgo3_5-SortAlgo5" : { "minimal_similarity" : 0.6607142857142857, @@ -714,29 +714,29 @@ "matched_token_number" : 37 }, "SortAlgo3_5-SortAlgo4d3" : { - "minimal_similarity" : 0.4107142857142857, - "maximum_similarity" : 0.48936170212765956, - "matched_token_number" : 23 + "minimal_similarity" : 0.44642857142857145, + "maximum_similarity" : 0.5319148936170213, + "matched_token_number" : 25 }, "SortAlgo2_5-SortAlgo4" : { - "minimal_similarity" : 0.5813953488372093, + "minimal_similarity" : 0.627906976744186, + "maximum_similarity" : 0.627906976744186, + "matched_token_number" : 27 + }, + "SortAlgo2_5-SortAlgo3" : { + "minimal_similarity" : 0.46296296296296297, "maximum_similarity" : 0.5813953488372093, "matched_token_number" : 25 }, "SortAlgo3_5-SortAlgo4d1" : { - "minimal_similarity" : 0.4107142857142857, - "maximum_similarity" : 0.4791666666666667, - "matched_token_number" : 23 - }, - "SortAlgo2_5-SortAlgo3" : { - "minimal_similarity" : 0.3888888888888889, - "maximum_similarity" : 0.4883720930232558, - "matched_token_number" : 21 + "minimal_similarity" : 0.44642857142857145, + "maximum_similarity" : 0.5208333333333334, + "matched_token_number" : 25 }, "SortAlgo2_5-SortAlgo6" : { - "minimal_similarity" : 0.46938775510204084, - "maximum_similarity" : 0.5348837209302325, - "matched_token_number" : 23 + "minimal_similarity" : 0.5510204081632653, + "maximum_similarity" : 0.627906976744186, + "matched_token_number" : 27 }, "SortAlgo2_5-SortAlgo5" : { "minimal_similarity" : 1.0, @@ -759,44 +759,44 @@ "matched_token_number" : 34 }, "SortAlgo1-SortAlgo1_5" : { - "minimal_similarity" : 0.6046511627906976, - "maximum_similarity" : 0.6341463414634146, - "matched_token_number" : 26 + "minimal_similarity" : 0.6511627906976745, + "maximum_similarity" : 0.6829268292682927, + "matched_token_number" : 28 }, "SortAlgo1-SortAlgo1_4" : { "minimal_similarity" : 0.8372093023255814, "maximum_similarity" : 0.8780487804878049, "matched_token_number" : 36 }, + "SortAlgo2_5-SortAlgo4d1" : { + "minimal_similarity" : 0.5416666666666666, + "maximum_similarity" : 0.6046511627906976, + "matched_token_number" : 26 + }, "SortAlgo3-SortAlgo7" : { "minimal_similarity" : 0.5535714285714286, "maximum_similarity" : 0.5740740740740741, "matched_token_number" : 31 }, - "SortAlgo2_5-SortAlgo4d1" : { - "minimal_similarity" : 0.5, - "maximum_similarity" : 0.5581395348837209, - "matched_token_number" : 24 - }, "SortAlgo3-SortAlgo6" : { "minimal_similarity" : 0.7222222222222222, "maximum_similarity" : 0.7959183673469388, "matched_token_number" : 39 }, "SortAlgo2_5-SortAlgo4d2" : { - "minimal_similarity" : 0.4897959183673469, - "maximum_similarity" : 0.5581395348837209, - "matched_token_number" : 24 + "minimal_similarity" : 0.5306122448979592, + "maximum_similarity" : 0.6046511627906976, + "matched_token_number" : 26 }, "SortAlgo1_4-SortAlgo1_5" : { - "minimal_similarity" : 0.5348837209302325, - "maximum_similarity" : 0.5348837209302325, - "matched_token_number" : 23 + "minimal_similarity" : 0.6046511627906976, + "maximum_similarity" : 0.6046511627906976, + "matched_token_number" : 26 }, "SortAlgo3-SortAlgo5" : { - "minimal_similarity" : 0.3888888888888889, - "maximum_similarity" : 0.4883720930232558, - "matched_token_number" : 21 + "minimal_similarity" : 0.46296296296296297, + "maximum_similarity" : 0.5813953488372093, + "matched_token_number" : 25 }, "SortAlgo1_4-SortAlgo1_6" : { "minimal_similarity" : 0.7441860465116279, @@ -809,9 +809,9 @@ "matched_token_number" : 29 }, "SortAlgo1_3-SortAlgo1_5" : { - "minimal_similarity" : 0.3620689655172414, - "maximum_similarity" : 0.4883720930232558, - "matched_token_number" : 21 + "minimal_similarity" : 0.4482758620689655, + "maximum_similarity" : 0.6046511627906976, + "matched_token_number" : 26 }, "SortAlgo1_3-SortAlgo1_4" : { "minimal_similarity" : 0.5689655172413793, @@ -819,34 +819,34 @@ "matched_token_number" : 33 }, "SortAlgo2_5-SortAlgo4d3" : { - "minimal_similarity" : 0.5106382978723404, - "maximum_similarity" : 0.5581395348837209, - "matched_token_number" : 24 + "minimal_similarity" : 0.5531914893617021, + "maximum_similarity" : 0.6046511627906976, + "matched_token_number" : 26 }, "SortAlgo1_3-SortAlgo1_6" : { "minimal_similarity" : 0.5344827586206896, "maximum_similarity" : 0.7209302325581395, "matched_token_number" : 31 }, + "SortAlgo1_2-SortAlgo1_5" : { + "minimal_similarity" : 0.5636363636363636, + "maximum_similarity" : 0.7209302325581395, + "matched_token_number" : 31 + }, "SortAlgo-SortAlgo3_6" : { "minimal_similarity" : 0.4642857142857143, "maximum_similarity" : 0.6341463414634146, "matched_token_number" : 26 }, - "SortAlgo1_2-SortAlgo1_5" : { - "minimal_similarity" : 0.4727272727272727, - "maximum_similarity" : 0.6046511627906976, - "matched_token_number" : 26 - }, "SortAlgo1_2-SortAlgo1_6" : { "minimal_similarity" : 0.6181818181818182, "maximum_similarity" : 0.7906976744186046, "matched_token_number" : 34 }, "SortAlgo-SortAlgo3_5" : { - "minimal_similarity" : 0.375, - "maximum_similarity" : 0.5121951219512195, - "matched_token_number" : 21 + "minimal_similarity" : 0.4107142857142857, + "maximum_similarity" : 0.5609756097560976, + "matched_token_number" : 23 }, "SortAlgo1_2-SortAlgo1_3" : { "minimal_similarity" : 0.6206896551724138, @@ -865,9 +865,9 @@ }, "tests" : { "SortAlgo-SortAlgo5" : { - "minimal_similarity" : 0.2558139534883721, - "maximum_similarity" : 0.2682926829268293, - "matched_token_number" : 11 + "minimal_similarity" : 0.27906976744186046, + "maximum_similarity" : 0.2926829268292683, + "matched_token_number" : 12 }, "SortAlgo-SortAlgo6" : { "minimal_similarity" : 0.42857142857142855, @@ -880,9 +880,9 @@ "matched_token_number" : 38 }, "SortAlgo3_5-SortAlgo3_6" : { - "minimal_similarity" : 0.16071428571428573, - "maximum_similarity" : 0.16071428571428573, - "matched_token_number" : 9 + "minimal_similarity" : 0.17857142857142858, + "maximum_similarity" : 0.17857142857142858, + "matched_token_number" : 10 }, "SortAlgo6-SortAlgo7" : { "minimal_similarity" : 0.19642857142857142, @@ -940,9 +940,9 @@ "matched_token_number" : 22 }, "SortAlgo2-SortAlgo2_5" : { - "minimal_similarity" : 0.2558139534883721, - "maximum_similarity" : 0.2682926829268293, - "matched_token_number" : 11 + "minimal_similarity" : 0.27906976744186046, + "maximum_similarity" : 0.2926829268292683, + "matched_token_number" : 12 }, "SortAlgo1_2-SortAlgo2" : { "minimal_similarity" : 0.7454545454545455, @@ -965,15 +965,15 @@ "matched_token_number" : 27 }, "SortAlgo5-SortAlgo7" : { - "minimal_similarity" : 0.17857142857142858, - "maximum_similarity" : 0.23255813953488372, - "matched_token_number" : 10 - }, - "SortAlgo1_2-SortAlgo5" : { - "minimal_similarity" : 0.2, + "minimal_similarity" : 0.19642857142857142, "maximum_similarity" : 0.2558139534883721, "matched_token_number" : 11 }, + "SortAlgo1_2-SortAlgo5" : { + "minimal_similarity" : 0.21818181818181817, + "maximum_similarity" : 0.27906976744186046, + "matched_token_number" : 12 + }, "SortAlgo1_2-SortAlgo6" : { "minimal_similarity" : 0.38181818181818183, "maximum_similarity" : 0.42857142857142855, @@ -985,9 +985,9 @@ "matched_token_number" : 38 }, "SortAlgo1-SortAlgo2_5" : { - "minimal_similarity" : 0.2558139534883721, - "maximum_similarity" : 0.2682926829268293, - "matched_token_number" : 11 + "minimal_similarity" : 0.27906976744186046, + "maximum_similarity" : 0.2926829268292683, + "matched_token_number" : 12 }, "SortAlgo1_3-SortAlgo3_6" : { "minimal_similarity" : 0.3103448275862069, @@ -1060,9 +1060,9 @@ "matched_token_number" : 19 }, "SortAlgo3-SortAlgo3_5" : { - "minimal_similarity" : 0.16071428571428573, - "maximum_similarity" : 0.16666666666666666, - "matched_token_number" : 9 + "minimal_similarity" : 0.17857142857142858, + "maximum_similarity" : 0.18518518518518517, + "matched_token_number" : 10 }, "SortAlgo1_4-SortAlgo4" : { "minimal_similarity" : 0.7674418604651163, @@ -1085,9 +1085,9 @@ "matched_token_number" : 17 }, "SortAlgo1_4-SortAlgo5" : { - "minimal_similarity" : 0.23255813953488372, - "maximum_similarity" : 0.23255813953488372, - "matched_token_number" : 10 + "minimal_similarity" : 0.2558139534883721, + "maximum_similarity" : 0.2558139534883721, + "matched_token_number" : 11 }, "SortAlgo2-SortAlgo3_5" : { "minimal_similarity" : 0.0, @@ -1140,9 +1140,9 @@ "matched_token_number" : 25 }, "SortAlgo-SortAlgo1_5" : { - "minimal_similarity" : 0.2558139534883721, - "maximum_similarity" : 0.2682926829268293, - "matched_token_number" : 11 + "minimal_similarity" : 0.27906976744186046, + "maximum_similarity" : 0.2926829268292683, + "matched_token_number" : 12 }, "SortAlgo-SortAlgo1_4" : { "minimal_similarity" : 0.5348837209302325, @@ -1220,9 +1220,9 @@ "matched_token_number" : 29 }, "SortAlgo1_6-SortAlgo2_5" : { - "minimal_similarity" : 0.2558139534883721, - "maximum_similarity" : 0.2558139534883721, - "matched_token_number" : 11 + "minimal_similarity" : 0.27906976744186046, + "maximum_similarity" : 0.27906976744186046, + "matched_token_number" : 12 }, "SortAlgo1_4-SortAlgo4d1" : { "minimal_similarity" : 0.3541666666666667, @@ -1280,9 +1280,9 @@ "matched_token_number" : 29 }, "SortAlgo2-SortAlgo5" : { - "minimal_similarity" : 0.2558139534883721, - "maximum_similarity" : 0.2682926829268293, - "matched_token_number" : 11 + "minimal_similarity" : 0.27906976744186046, + "maximum_similarity" : 0.2926829268292683, + "matched_token_number" : 12 }, "SortAlgo4d1-SortAlgo4d3" : { "minimal_similarity" : 0.9375, @@ -1340,9 +1340,9 @@ "matched_token_number" : 0 }, "SortAlgo1_4-SortAlgo2_5" : { - "minimal_similarity" : 0.23255813953488372, - "maximum_similarity" : 0.23255813953488372, - "matched_token_number" : 10 + "minimal_similarity" : 0.2558139534883721, + "maximum_similarity" : 0.2558139534883721, + "matched_token_number" : 11 }, "SortAlgo1-SortAlgo4" : { "minimal_similarity" : 0.5581395348837209, @@ -1350,9 +1350,9 @@ "matched_token_number" : 24 }, "SortAlgo1-SortAlgo5" : { - "minimal_similarity" : 0.2558139534883721, - "maximum_similarity" : 0.2682926829268293, - "matched_token_number" : 11 + "minimal_similarity" : 0.27906976744186046, + "maximum_similarity" : 0.2926829268292683, + "matched_token_number" : 12 }, "SortAlgo1-SortAlgo2" : { "minimal_similarity" : 1.0, @@ -1390,9 +1390,9 @@ "matched_token_number" : 38 }, "SortAlgo1_2-SortAlgo2_5" : { - "minimal_similarity" : 0.2, - "maximum_similarity" : 0.2558139534883721, - "matched_token_number" : 11 + "minimal_similarity" : 0.21818181818181817, + "maximum_similarity" : 0.27906976744186046, + "matched_token_number" : 12 }, "SortAlgo1_6-SortAlgo6" : { "minimal_similarity" : 0.7959183673469388, @@ -1400,14 +1400,14 @@ "matched_token_number" : 39 }, "SortAlgo-SortAlgo2_5" : { - "minimal_similarity" : 0.2558139534883721, - "maximum_similarity" : 0.2682926829268293, - "matched_token_number" : 11 + "minimal_similarity" : 0.27906976744186046, + "maximum_similarity" : 0.2926829268292683, + "matched_token_number" : 12 }, "SortAlgo1_6-SortAlgo5" : { - "minimal_similarity" : 0.2558139534883721, - "maximum_similarity" : 0.2558139534883721, - "matched_token_number" : 11 + "minimal_similarity" : 0.27906976744186046, + "maximum_similarity" : 0.27906976744186046, + "matched_token_number" : 12 }, "SortAlgo1_6-SortAlgo4" : { "minimal_similarity" : 0.5581395348837209, @@ -1425,14 +1425,14 @@ "matched_token_number" : 0 }, "SortAlgo2_5-SortAlgo7" : { - "minimal_similarity" : 0.17857142857142858, - "maximum_similarity" : 0.23255813953488372, - "matched_token_number" : 10 + "minimal_similarity" : 0.19642857142857142, + "maximum_similarity" : 0.2558139534883721, + "matched_token_number" : 11 }, "SortAlgo1_5-SortAlgo7" : { - "minimal_similarity" : 0.17857142857142858, - "maximum_similarity" : 0.23255813953488372, - "matched_token_number" : 10 + "minimal_similarity" : 0.19642857142857142, + "maximum_similarity" : 0.2558139534883721, + "matched_token_number" : 11 }, "SortAlgo1-SortAlgo4d3" : { "minimal_similarity" : 0.6595744680851063, @@ -1460,14 +1460,14 @@ "matched_token_number" : 31 }, "SortAlgo1_5-SortAlgo2" : { - "minimal_similarity" : 0.2558139534883721, - "maximum_similarity" : 0.2682926829268293, - "matched_token_number" : 11 + "minimal_similarity" : 0.27906976744186046, + "maximum_similarity" : 0.2926829268292683, + "matched_token_number" : 12 }, "SortAlgo3_5-SortAlgo6" : { - "minimal_similarity" : 0.16071428571428573, - "maximum_similarity" : 0.1836734693877551, - "matched_token_number" : 9 + "minimal_similarity" : 0.17857142857142858, + "maximum_similarity" : 0.20408163265306123, + "matched_token_number" : 10 }, "SortAlgo3_5-SortAlgo7" : { "minimal_similarity" : 0.0, @@ -1510,9 +1510,9 @@ "matched_token_number" : 31 }, "SortAlgo1_5-SortAlgo1_6" : { - "minimal_similarity" : 0.2558139534883721, - "maximum_similarity" : 0.2558139534883721, - "matched_token_number" : 11 + "minimal_similarity" : 0.27906976744186046, + "maximum_similarity" : 0.27906976744186046, + "matched_token_number" : 12 }, "SortAlgo3_6-SortAlgo4d2" : { "minimal_similarity" : 0.30357142857142855, @@ -1584,12 +1584,12 @@ "maximum_similarity" : 0.2558139534883721, "matched_token_number" : 11 }, - "SortAlgo2_5-SortAlgo3" : { + "SortAlgo3_5-SortAlgo4d1" : { "minimal_similarity" : 0.0, "maximum_similarity" : 0.0, "matched_token_number" : 0 }, - "SortAlgo3_5-SortAlgo4d1" : { + "SortAlgo2_5-SortAlgo3" : { "minimal_similarity" : 0.0, "maximum_similarity" : 0.0, "matched_token_number" : 0 @@ -1620,9 +1620,9 @@ "matched_token_number" : 25 }, "SortAlgo1-SortAlgo1_5" : { - "minimal_similarity" : 0.2558139534883721, - "maximum_similarity" : 0.2682926829268293, - "matched_token_number" : 11 + "minimal_similarity" : 0.27906976744186046, + "maximum_similarity" : 0.2926829268292683, + "matched_token_number" : 12 }, "SortAlgo1-SortAlgo1_4" : { "minimal_similarity" : 0.5348837209302325, @@ -1650,9 +1650,9 @@ "matched_token_number" : 0 }, "SortAlgo1_4-SortAlgo1_5" : { - "minimal_similarity" : 0.23255813953488372, - "maximum_similarity" : 0.23255813953488372, - "matched_token_number" : 10 + "minimal_similarity" : 0.2558139534883721, + "maximum_similarity" : 0.2558139534883721, + "matched_token_number" : 11 }, "SortAlgo3-SortAlgo5" : { "minimal_similarity" : 0.0, @@ -1695,9 +1695,9 @@ "matched_token_number" : 19 }, "SortAlgo1_2-SortAlgo1_5" : { - "minimal_similarity" : 0.2, - "maximum_similarity" : 0.2558139534883721, - "matched_token_number" : 11 + "minimal_similarity" : 0.21818181818181817, + "maximum_similarity" : 0.27906976744186046, + "matched_token_number" : 12 }, "SortAlgo1_2-SortAlgo1_6" : { "minimal_similarity" : 0.45454545454545453, diff --git a/language-antlr-utils/src/main/java/de/jplag/antlr/AbstractAntlrLanguage.java b/language-antlr-utils/src/main/java/de/jplag/antlr/AbstractAntlrLanguage.java index 0c0b05a81..93f6ace30 100644 --- a/language-antlr-utils/src/main/java/de/jplag/antlr/AbstractAntlrLanguage.java +++ b/language-antlr-utils/src/main/java/de/jplag/antlr/AbstractAntlrLanguage.java @@ -10,9 +10,12 @@ /** * Base class for Antlr languages. Handle the parse function from {@link Language} + *

+ * You can either pass the parser to the super constructor, or implement the initializeParser method. That allows you to + * access class members, like language specific options. */ public abstract class AbstractAntlrLanguage implements Language { - private final AbstractAntlrParserAdapter parser; + private AbstractAntlrParserAdapter parser; /** * New instance @@ -22,8 +25,29 @@ protected AbstractAntlrLanguage(AbstractAntlrParserAdapter parser) { this.parser = parser; } + /** + * New instance, without pre initialized parser. If you use this constructor, you need to override the initializeParser + * method. + */ + protected AbstractAntlrLanguage() { + this.parser = null; + } + @Override public List parse(Set files) throws ParsingException { + if (this.parser == null) { + this.parser = this.initializeParser(); + } + return this.parser.parse(files); } + + /** + * Lazily creates the parser. Has to be implemented, if no parser is passed in the constructor. + * @return The newly initialized parser + */ + protected AbstractAntlrParserAdapter initializeParser() { + throw new UnsupportedOperationException( + String.format("The initializeParser method needs to be implemented for %s", this.getClass().getName())); + } } diff --git a/language-antlr-utils/src/main/java/de/jplag/antlr/AbstractAntlrListener.java b/language-antlr-utils/src/main/java/de/jplag/antlr/AbstractAntlrListener.java index b80fdde6a..b8a38cd28 100644 --- a/language-antlr-utils/src/main/java/de/jplag/antlr/AbstractAntlrListener.java +++ b/language-antlr-utils/src/main/java/de/jplag/antlr/AbstractAntlrListener.java @@ -25,7 +25,6 @@ public class AbstractAntlrListener implements ParseTreeListener { private final List> startMappings; private final List> endMappings; - private final List> rangeMappings; private final List terminalMapping; @@ -46,7 +45,6 @@ public AbstractAntlrListener(TokenCollector collector, File currentFile, boolean this.startMappings = new ArrayList<>(); this.endMappings = new ArrayList<>(); - this.rangeMappings = new ArrayList<>(); this.terminalMapping = new ArrayList<>(); @@ -78,8 +76,6 @@ public void visitErrorNode(ErrorNode errorNode) { @Override public void enterEveryRule(ParserRuleContext rule) { this.startMappings.stream().filter(mapping -> mapping.matches(rule)).forEach(mapping -> mapping.createToken(rule, variableRegistry)); - - this.rangeMappings.stream().filter(mapping -> mapping.matches(rule)).forEach(mapping -> mapping.createToken(rule, variableRegistry)); } @Override @@ -163,7 +159,7 @@ protected ContextTokenBuilder mapRange(Class @SuppressWarnings("unchecked") protected ContextTokenBuilder mapRange(Class antlrType, TokenType jplagType, Predicate condition) { ContextTokenBuilder builder = initTypeBuilder(antlrType, jplagType, condition, ContextTokenBuilderType.RANGE); - this.rangeMappings.add((ContextTokenBuilder) builder); + this.startMappings.add((ContextTokenBuilder) builder); return builder; } diff --git a/language-antlr-utils/src/main/java/de/jplag/antlr/TokenBuilder.java b/language-antlr-utils/src/main/java/de/jplag/antlr/TokenBuilder.java index 4dab47b9e..08e393ef7 100644 --- a/language-antlr-utils/src/main/java/de/jplag/antlr/TokenBuilder.java +++ b/language-antlr-utils/src/main/java/de/jplag/antlr/TokenBuilder.java @@ -111,7 +111,7 @@ void createToken(T antlrContent, VariableRegistry semantics) { int line = antlrToken.getLine(); int column = antlrToken.getCharPositionInLine() + 1; - int length = antlrToken.getText().length(); + int length = getLength(antlrContent); Token token; if (semantics != null) { diff --git a/language-antlr-utils/src/test/java/de/jplag/antlr/LanguageTest.java b/language-antlr-utils/src/test/java/de/jplag/antlr/LanguageTest.java new file mode 100644 index 000000000..81941ac8d --- /dev/null +++ b/language-antlr-utils/src/test/java/de/jplag/antlr/LanguageTest.java @@ -0,0 +1,66 @@ +package de.jplag.antlr; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.io.File; +import java.util.Set; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import de.jplag.ParsingException; +import de.jplag.antlr.testLanguage.TestLanguage; +import de.jplag.antlr.testLanguage.TestParserAdapter; + +/** + * Some tests for the abstract antlr language + */ +class LanguageTest { + @Test + void testExceptionForNoDefinedParser() { + LanguageWithoutParser lang = new LanguageWithoutParser(); + Set emptySet = Set.of(); + assertThrows(UnsupportedOperationException.class, () -> lang.parse(emptySet)); + } + + @Test + void testLanguageWithStaticParser() throws ParsingException { + TestLanguage lang = new TestLanguage(); + Assertions.assertEquals(0, lang.parse(Set.of()).size()); + } + + @Test + void testLanguageWithLazyParser() throws ParsingException { + LanguageWithLazyParser lang = new LanguageWithLazyParser(); + Assertions.assertEquals(0, lang.parse(Set.of()).size()); + } + + private static class LanguageWithoutParser extends AbstractAntlrLanguage { + @Override + public String[] suffixes() { + return new String[0]; + } + + @Override + public String getName() { + return null; + } + + @Override + public String getIdentifier() { + return null; + } + + @Override + public int minimumTokenMatch() { + return 0; + } + } + + private static class LanguageWithLazyParser extends LanguageWithoutParser { + @Override + protected AbstractAntlrParserAdapter initializeParser() { + return new TestParserAdapter(); + } + } +} diff --git a/language-antlr-utils/src/test/java/de/jplag/antlr/ParserTest.java b/language-antlr-utils/src/test/java/de/jplag/antlr/ParserTest.java index 60f48c214..e33277201 100644 --- a/language-antlr-utils/src/test/java/de/jplag/antlr/ParserTest.java +++ b/language-antlr-utils/src/test/java/de/jplag/antlr/ParserTest.java @@ -2,7 +2,7 @@ import static de.jplag.antlr.testLanguage.TestTokenType.*; -import de.jplag.antlr.testLanguage.TestLangauge; +import de.jplag.antlr.testLanguage.TestLanguage; import de.jplag.antlr.testLanguage.TestTokenType; import de.jplag.testutils.LanguageModuleTest; import de.jplag.testutils.datacollector.TestDataCollector; @@ -10,7 +10,7 @@ public class ParserTest extends LanguageModuleTest { public ParserTest() { - super(new TestLangauge(), TestTokenType.class); + super(new TestLanguage(), TestTokenType.class); } @Override diff --git a/language-antlr-utils/src/test/java/de/jplag/antlr/testLanguage/TestLangauge.java b/language-antlr-utils/src/test/java/de/jplag/antlr/testLanguage/TestLanguage.java similarity index 85% rename from language-antlr-utils/src/test/java/de/jplag/antlr/testLanguage/TestLangauge.java rename to language-antlr-utils/src/test/java/de/jplag/antlr/testLanguage/TestLanguage.java index fd56bd35f..63a5f0d07 100644 --- a/language-antlr-utils/src/test/java/de/jplag/antlr/testLanguage/TestLangauge.java +++ b/language-antlr-utils/src/test/java/de/jplag/antlr/testLanguage/TestLanguage.java @@ -2,11 +2,11 @@ import de.jplag.antlr.AbstractAntlrLanguage; -public class TestLangauge extends AbstractAntlrLanguage { +public class TestLanguage extends AbstractAntlrLanguage { /** * New instance */ - public TestLangauge() { + public TestLanguage() { super(new TestParserAdapter()); } diff --git a/language-api/src/main/java/de/jplag/SharedTokenType.java b/language-api/src/main/java/de/jplag/SharedTokenType.java index 5374114ec..6866f46a2 100644 --- a/language-api/src/main/java/de/jplag/SharedTokenType.java +++ b/language-api/src/main/java/de/jplag/SharedTokenType.java @@ -11,6 +11,7 @@ public enum SharedTokenType implements TokenType { private final String description; + @Override public String getDescription() { return description; } diff --git a/language-api/src/test/java/de/jplag/TokenPrinterTest.java b/language-api/src/test/java/de/jplag/TokenPrinterTest.java index 4cb1bda1d..11c9c33f3 100644 --- a/language-api/src/test/java/de/jplag/TokenPrinterTest.java +++ b/language-api/src/test/java/de/jplag/TokenPrinterTest.java @@ -103,6 +103,7 @@ private enum TestTokenType implements TokenType { private final String description; + @Override public String getDescription() { return description; } diff --git a/language-testutils/src/test/java/de/jplag/testutils/LanguageModuleTest.java b/language-testutils/src/test/java/de/jplag/testutils/LanguageModuleTest.java index 62b997c12..46133a743 100644 --- a/language-testutils/src/test/java/de/jplag/testutils/LanguageModuleTest.java +++ b/language-testutils/src/test/java/de/jplag/testutils/LanguageModuleTest.java @@ -1,22 +1,34 @@ package de.jplag.testutils; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertIterableEquals; +import static org.junit.jupiter.api.Assertions.assertLinesMatch; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; import java.io.File; import java.io.IOException; import java.nio.file.Path; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; -import de.jplag.*; +import de.jplag.Language; +import de.jplag.ParsingException; +import de.jplag.SharedTokenType; +import de.jplag.Token; +import de.jplag.TokenPrinter; +import de.jplag.TokenType; import de.jplag.testutils.datacollector.TestData; import de.jplag.testutils.datacollector.TestDataCollector; import de.jplag.testutils.datacollector.TestSourceIgnoredLinesCollector; @@ -71,6 +83,7 @@ public & TokenType> LanguageModuleTest(Language language, Cla */ @ParameterizedTest @MethodSource("sourceCoverageFiles") + @DisplayName("Test that every line leads to at least one token") final void testSourceCoverage(TestData data) throws ParsingException, IOException { List tokens = parseTokens(data); @@ -81,7 +94,7 @@ final void testSourceCoverage(TestData data) throws ParsingException, IOExceptio tokens.stream().map(Token::getLine).forEach(relevantLines::remove); - Assertions.assertTrue(relevantLines.isEmpty(), + assertTrue(relevantLines.isEmpty(), "Test test source " + data.describeTestSource() + " contained uncovered lines:" + System.lineSeparator() + relevantLines); } @@ -101,14 +114,14 @@ final List sourceCoverageFiles() { */ @ParameterizedTest @MethodSource("tokenCoverageFiles") + @DisplayName("Test that every token occurs at least once") final void testTokenCoverage(TestData data) throws ParsingException, IOException { - List foundTokens = extractTokenTypes(data); + List actualTokens = extractTokenTypes(data); List languageTokens = new ArrayList<>(this.languageTokens); - languageTokens.removeAll(foundTokens); + languageTokens.removeAll(actualTokens); - Assertions.assertTrue(languageTokens.isEmpty(), - "Some tokens were not found in " + data.describeTestSource() + System.lineSeparator() + languageTokens); + assertTrue(languageTokens.isEmpty(), "Some tokens were not found in " + data.describeTestSource() + System.lineSeparator() + languageTokens); } /** @@ -120,23 +133,25 @@ final List tokenCoverageFiles() { } /** - * Tests the configured test sources for contained tokens + * Tests the configured test sources for contained tokens. The tokens neither have to occur exclusively nor in the given + * order. * @param test The source to test * @throws ParsingException If the parser throws some error * @throws IOException If any IO Exception occurs */ @ParameterizedTest @MethodSource("testTokensContainedData") + @DisplayName("Test that the specified tokens at least occur") final void testTokensContained(TestDataCollector.TokenListTest test) throws ParsingException, IOException { - List foundTokens = extractTokenTypes(test.data()); - List requiredTokens = new ArrayList<>(test.tokens()); + List actualTokens = extractTokenTypes(test.data()); + List expectedTokens = new ArrayList<>(test.tokens()); - for (TokenType foundToken : foundTokens) { - requiredTokens.remove(foundToken); + for (TokenType foundToken : actualTokens) { + expectedTokens.remove(foundToken); } - Assertions.assertTrue(requiredTokens.isEmpty(), - "Some required tokens were not found in " + test.data().describeTestSource() + System.lineSeparator() + requiredTokens); + assertTrue(expectedTokens.isEmpty(), + "Some expected tokens were not found in " + test.data().describeTestSource() + System.lineSeparator() + expectedTokens); } /** @@ -155,15 +170,22 @@ final List testTokensContainedData() { */ @ParameterizedTest @MethodSource("testTokenSequenceData") + @DisplayName("Test if extracted token sequence matches") final void testTokenSequence(TestDataCollector.TokenListTest test) throws ParsingException, IOException { - List extracted = extractTokenTypes(test.data()); - List required = new ArrayList<>(test.tokens()); - if (required.get(required.size() - 1) != SharedTokenType.FILE_END) { - required.add(SharedTokenType.FILE_END); + List actual = extractTokenTypes(test.data()); + List expected = new ArrayList<>(test.tokens()); + if (expected.get(expected.size() - 1) != SharedTokenType.FILE_END) { + expected.add(SharedTokenType.FILE_END); } + assertTokensMatch(expected, actual, "Extracted token from " + test.data().describeTestSource() + " does not match expected sequence."); + assertIterableEquals(expected, actual); + } - Assertions.assertEquals(required, extracted, - "Extracted token from " + test.data().describeTestSource() + " does not match required sequence."); + /** + * Convenience method for using assertLinesMatch with token lists. + */ + private void assertTokensMatch(List expected, List actual, String message) { + assertLinesMatch(expected.stream().map(Object::toString), actual.stream().map(Object::toString), message); } /** @@ -182,12 +204,13 @@ final List testTokenSequenceData() { */ @ParameterizedTest @MethodSource("getAllTestData") + @DisplayName("Test that the tokens map to ascending line numbers") final void testMonotoneTokenOrder(TestData data) throws ParsingException, IOException { - List extracted = parseTokens(data); + List tokens = parseTokens(data); - for (int i = 0; i < extracted.size() - 2; i++) { - Token first = extracted.get(i); - Token second = extracted.get(i + 1); + for (int i = 0; i < tokens.size() - 2; i++) { + Token first = tokens.get(i); + Token second = tokens.get(i + 1); if (first.getLine() > second.getLine()) { fail(String.format("Invalid token order. Token %s has a higher line number (%s) than token %s (%s).", first.getType(), @@ -204,10 +227,11 @@ final void testMonotoneTokenOrder(TestData data) throws ParsingException, IOExce */ @ParameterizedTest @MethodSource("getAllTestData") + @DisplayName("Test that the last token is the file end token") final void testTokenSequencesEndsWithFileEnd(TestData data) throws ParsingException, IOException { - List extracted = parseTokens(data); + List tokens = parseTokens(data); - Assertions.assertEquals(SharedTokenType.FILE_END, extracted.get(extracted.size() - 1).getType(), + assertEquals(SharedTokenType.FILE_END, tokens.get(tokens.size() - 1).getType(), "Last token in " + data.describeTestSource() + " is not file end."); } diff --git a/language-testutils/src/test/java/de/jplag/testutils/datacollector/FileTestData.java b/language-testutils/src/test/java/de/jplag/testutils/datacollector/FileTestData.java index 7d9043bb9..f2facf796 100644 --- a/language-testutils/src/test/java/de/jplag/testutils/datacollector/FileTestData.java +++ b/language-testutils/src/test/java/de/jplag/testutils/datacollector/FileTestData.java @@ -33,7 +33,7 @@ public String[] getSourceLines() throws IOException { @Override public String describeTestSource() { - return "(File: " + this.file.getPath() + ")"; + return "(File: " + this.file.getName() + ")"; } @Override @@ -53,6 +53,6 @@ public int hashCode() { @Override public String toString() { - return this.file.getPath(); + return this.file.getName(); } } diff --git a/language-testutils/src/test/java/de/jplag/testutils/datacollector/TestDataCollector.java b/language-testutils/src/test/java/de/jplag/testutils/datacollector/TestDataCollector.java index b1abce180..c99a3741d 100644 --- a/language-testutils/src/test/java/de/jplag/testutils/datacollector/TestDataCollector.java +++ b/language-testutils/src/test/java/de/jplag/testutils/datacollector/TestDataCollector.java @@ -46,6 +46,18 @@ public TestDataContext testFile(String... fileNames) { return new TestDataContext(data); } + /** + * Adds all files matching a certain type. Returns a {@link TestDataContext}, that can be used to configure various + * tests on the given files. + * @param fileSuffix is the suffix of the files to be added. + * @return The {@link TestDataContext} + */ + public TestDataContext testAllOfType(String fileSuffix) { + Set data = Arrays.stream(testFileLocation.list()).filter(it -> it.endsWith(fileSuffix)) + .map(it -> new File(this.testFileLocation, it)).map(FileTestData::new).collect(Collectors.toSet()); + return new TestDataContext(data); + } + /** * Adds a list of source string to the test data. Returns a {@link TestDataContext}, that can be used to configure * various tests on the given files. @@ -98,6 +110,11 @@ public List getAllTestData() { * @param data The test data */ public record TokenListTest(List tokens, TestData data) { + + @Override + public String toString() { + return data.toString(); // readable test name + } } /** diff --git a/languages/cpp/src/main/java/de/jplag/cpp/CPPTokenType.java b/languages/cpp/src/main/java/de/jplag/cpp/CPPTokenType.java index 312155fa1..e8143b98f 100644 --- a/languages/cpp/src/main/java/de/jplag/cpp/CPPTokenType.java +++ b/languages/cpp/src/main/java/de/jplag/cpp/CPPTokenType.java @@ -66,6 +66,7 @@ public enum CPPTokenType implements TokenType { private final String description; + @Override public String getDescription() { return this.description; } diff --git a/languages/cpp/src/main/java/de/jplag/cpp/experimental/GCCSourceAnalysis.java b/languages/cpp/src/main/java/de/jplag/cpp/experimental/GCCSourceAnalysis.java index 4b9371ff3..52b7bdfcd 100644 --- a/languages/cpp/src/main/java/de/jplag/cpp/experimental/GCCSourceAnalysis.java +++ b/languages/cpp/src/main/java/de/jplag/cpp/experimental/GCCSourceAnalysis.java @@ -24,6 +24,7 @@ public GCCSourceAnalysis() { this.logger = LoggerFactory.getLogger(this.getClass()); } + @Override public boolean isTokenIgnored(de.jplag.cpp.Token token, File file) { String fileName = file.getName(); if (linesToDelete.containsKey(fileName)) { @@ -33,6 +34,7 @@ public boolean isTokenIgnored(de.jplag.cpp.Token token, File file) { return false; } + @Override public void findUnusedVariableLines(Set files) throws InterruptedException { linesToDelete = new HashMap<>(); diff --git a/languages/csharp/src/main/java/de/jplag/csharp/CSharpTokenType.java b/languages/csharp/src/main/java/de/jplag/csharp/CSharpTokenType.java index 30bf18499..f8d6a4347 100644 --- a/languages/csharp/src/main/java/de/jplag/csharp/CSharpTokenType.java +++ b/languages/csharp/src/main/java/de/jplag/csharp/CSharpTokenType.java @@ -71,6 +71,7 @@ public enum CSharpTokenType implements TokenType { private final String description; + @Override public String getDescription() { return this.description; } diff --git a/languages/emf-metamodel-dynamic/src/test/java/de/jplag/emf/dynamic/MinimalDynamicMetamodelTest.java b/languages/emf-metamodel-dynamic/src/test/java/de/jplag/emf/dynamic/MinimalDynamicMetamodelTest.java index b0ec9f44f..0911fd455 100644 --- a/languages/emf-metamodel-dynamic/src/test/java/de/jplag/emf/dynamic/MinimalDynamicMetamodelTest.java +++ b/languages/emf-metamodel-dynamic/src/test/java/de/jplag/emf/dynamic/MinimalDynamicMetamodelTest.java @@ -22,6 +22,7 @@ import de.jplag.Token; import de.jplag.TokenPrinter; import de.jplag.TokenType; +import de.jplag.emf.EmfLanguage; import de.jplag.testutils.FileUtil; import de.jplag.testutils.TokenUtils; @@ -48,7 +49,7 @@ void testBookstoreMetamodels() throws ParsingException { List testFiles = Arrays.stream(TEST_SUBJECTS).map(path -> new File(BASE_PATH.toFile(), path)).toList(); List result = language.parse(new HashSet<>(testFiles)); List tokenTypes = result.stream().map(Token::getType).toList(); - logger.debug(TokenPrinter.printTokens(result, baseDirectory, Optional.of(DynamicEmfLanguage.VIEW_FILE_SUFFIX))); + logger.debug(TokenPrinter.printTokens(result, baseDirectory, Optional.of(EmfLanguage.VIEW_FILE_SUFFIX))); logger.info("parsed token types: " + tokenTypes.stream().map(TokenType::getDescription).toList()); assertEquals(94, tokenTypes.size()); assertEquals(7, new HashSet<>(tokenTypes.stream().filter(DynamicMetamodelTokenType.class::isInstance).toList()).size()); @@ -64,6 +65,6 @@ void testBookstoreMetamodels() throws ParsingException { @AfterEach public void tearDown() { - FileUtil.clearFiles(new File(BASE_PATH.toString()), DynamicEmfLanguage.VIEW_FILE_SUFFIX); + FileUtil.clearFiles(new File(BASE_PATH.toString()), EmfLanguage.VIEW_FILE_SUFFIX); } } diff --git a/languages/emf-metamodel/src/main/java/de/jplag/emf/util/EmfaticModelView.java b/languages/emf-metamodel/src/main/java/de/jplag/emf/util/EmfaticModelView.java index 036359080..ec2b055dc 100644 --- a/languages/emf-metamodel/src/main/java/de/jplag/emf/util/EmfaticModelView.java +++ b/languages/emf-metamodel/src/main/java/de/jplag/emf/util/EmfaticModelView.java @@ -9,6 +9,8 @@ import org.eclipse.emf.ecore.EEnumLiteral; import org.eclipse.emf.ecore.ENamedElement; import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EOperation; +import org.eclipse.emf.ecore.EParameter; import org.eclipse.emf.ecore.ETypedElement; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.util.EcoreUtil.Copier; @@ -27,9 +29,11 @@ */ public final class EmfaticModelView extends AbstractModelView { // The following regular expressions match keywords of the Emfatic syntax: + private static final String PACKAGE_REGEX = "package\\s+\\S+;"; private static final String TYPE_KEYWORD_REGEX = "(package |class |datatype |enum )"; private static final String FEATURE_KEYWORD_REGEX = "(.*attr .*|op .*|.*ref .*|.*val .*).*"; private static final String TYPE_SUFFIX_REGEX = "(;| extends| \\{)"; + private static final String LINE_SUFFIX_REGEX = ";"; private static final char CLOSING_CHAR = '}'; private static final String ANYTHING_REGEX = ".*"; @@ -40,6 +44,7 @@ public final class EmfaticModelView extends AbstractModelView { private final Copier modelCopier; // Allows to trace between original and copied elements private int lastLineIndex; // last line given to a token + private final int rootPackageIndex; /** * Creates an Emfatic view for a metamodel. @@ -57,6 +62,7 @@ public EmfaticModelView(File file, Resource modelResource) throws ParsingExcepti Resource copiedResource = EMFUtil.copyModel(modelResource, modelCopier); replaceElementNamesWithHashes(copiedResource); hashedLines = generateEmfaticCode(new StringBuilder(), copiedResource); + rootPackageIndex = findIndexOfRootPackage(hashedLines); } /** @@ -108,6 +114,18 @@ private final List generateEmfaticCode(StringBuilder builder, Resource m return builder.toString().lines().toList(); } + /** + * Calculates the index of the root package declaration, as it has unique syntax in Emfatic. + */ + private final int findIndexOfRootPackage(List lines) { + for (int index = 0; index < lines.size(); index++) { + if (lines.get(index).matches(PACKAGE_REGEX)) { + return index; + } + } + return -1; + } + /** * Calculates the line index of a metamodel token from the emfatic code. If it cannot be found, the last index is used. */ @@ -135,7 +153,7 @@ private int calculateLineIndexOf(MetamodelToken token) { */ private int findEndIndexOf(int declarationIndex) { int indentation = indentationOf(lines.get(declarationIndex)); - if (declarationIndex > 1) { // exception for top level package + if (declarationIndex > rootPackageIndex) { // exception for top level package for (int i = declarationIndex + 1; i < lines.size(); i++) { String nextLine = lines.get(i); if (nextLine.length() > indentation && CLOSING_CHAR == nextLine.charAt(indentation)) { @@ -186,7 +204,8 @@ private int findLineIndexOf(ENamedElement element) { * Checks if a line (with leading whitespace removed) contains an element based on the elements hash. */ private boolean isDeclaration(ENamedElement element, String hash, String line) { - return isStructuralFeature(element, hash, line) || isEnumLiteral(element, hash, line) || isType(hash, line); + return isStructuralFeature(element, hash, line) || isTypedElement(element, hash, line) || isEnumLiteral(element, hash, line) + || isType(hash, line); } private boolean isType(String hash, String line) { @@ -197,8 +216,12 @@ private boolean isEnumLiteral(ENamedElement element, String hash, String line) { return element instanceof EEnumLiteral && line.matches(hash + ANYTHING_REGEX); } + private boolean isTypedElement(ENamedElement element, String hash, String line) { + return element instanceof EOperation && element instanceof EParameter && line.matches(FEATURE_KEYWORD_REGEX + hash + ANYTHING_REGEX); + } + private boolean isStructuralFeature(ENamedElement element, String hash, String line) { - return element instanceof ETypedElement && line.matches(FEATURE_KEYWORD_REGEX + hash + ANYTHING_REGEX); + return element instanceof ETypedElement && line.matches(FEATURE_KEYWORD_REGEX + hash + LINE_SUFFIX_REGEX); } } diff --git a/languages/emf-metamodel/src/test/java/de/jplag/emf/AbstractEmfTest.java b/languages/emf-metamodel/src/test/java/de/jplag/emf/AbstractEmfTest.java index c039b25fb..699ee2af7 100644 --- a/languages/emf-metamodel/src/test/java/de/jplag/emf/AbstractEmfTest.java +++ b/languages/emf-metamodel/src/test/java/de/jplag/emf/AbstractEmfTest.java @@ -23,7 +23,7 @@ */ public abstract class AbstractEmfTest { - protected static final Path BASE_PATH = Path.of("src", "test", "resources", "de", "jplag", "models"); + protected static final Path BASE_PATH = Path.of("src", "test", "resources", "de", "jplag", "emf"); protected static final String[] TEST_SUBJECTS = {"bookStore.ecore", // base metamodel "bookStoreExtended.ecore", // extended version of base metamodel diff --git a/languages/emf-metamodel/src/test/java/de/jplag/emf/EmfLanguageTest.java b/languages/emf-metamodel/src/test/java/de/jplag/emf/EmfLanguageTest.java new file mode 100644 index 000000000..d3ee82d25 --- /dev/null +++ b/languages/emf-metamodel/src/test/java/de/jplag/emf/EmfLanguageTest.java @@ -0,0 +1,42 @@ +package de.jplag.emf; + +import static de.jplag.emf.MetamodelTokenType.ATTRIBUTE; +import static de.jplag.emf.MetamodelTokenType.CLASS; +import static de.jplag.emf.MetamodelTokenType.CLASS_END; +import static de.jplag.emf.MetamodelTokenType.CONTAINMENT_MULT; +import static de.jplag.emf.MetamodelTokenType.PACKAGE; +import static de.jplag.emf.MetamodelTokenType.PACKAGE_END; + +import org.junit.jupiter.api.AfterEach; + +import de.jplag.testutils.FileUtil; +import de.jplag.testutils.LanguageModuleTest; +import de.jplag.testutils.datacollector.TestDataCollector; +import de.jplag.testutils.datacollector.TestSourceIgnoredLinesCollector; + +/** + * Basic EMF test that mainly serves the purpose of checking ascending line indices for the tokens with Emfatic views. + */ +public class EmfLanguageTest extends LanguageModuleTest { + + public EmfLanguageTest() { + super(new EmfLanguage(), MetamodelTokenType.class); + } + + @Override + protected void collectTestData(TestDataCollector collector) { + collector.testAllOfType(EmfLanguage.FILE_ENDING).testContainedTokens(PACKAGE, PACKAGE_END, CLASS, CLASS_END, ATTRIBUTE, CONTAINMENT_MULT); + + } + + @Override + protected void configureIgnoredLines(TestSourceIgnoredLinesCollector collector) { + // None, does not really apply for modeling artifacts. + } + + @AfterEach + protected void tearDown() { + FileUtil.clearFiles(getTestFileLocation(), EmfLanguage.VIEW_FILE_SUFFIX); // clean up the view files. + } + +} diff --git a/languages/emf-metamodel/src/test/resources/de/jplag/models/bookStore.ecore b/languages/emf-metamodel/src/test/resources/de/jplag/emf/bookStore.ecore similarity index 100% rename from languages/emf-metamodel/src/test/resources/de/jplag/models/bookStore.ecore rename to languages/emf-metamodel/src/test/resources/de/jplag/emf/bookStore.ecore diff --git a/languages/emf-metamodel/src/test/resources/de/jplag/models/bookStoreExtended.ecore b/languages/emf-metamodel/src/test/resources/de/jplag/emf/bookStoreExtended.ecore similarity index 100% rename from languages/emf-metamodel/src/test/resources/de/jplag/models/bookStoreExtended.ecore rename to languages/emf-metamodel/src/test/resources/de/jplag/emf/bookStoreExtended.ecore diff --git a/languages/emf-metamodel/src/test/resources/de/jplag/models/bookStoreExtendedRefactor.ecore b/languages/emf-metamodel/src/test/resources/de/jplag/emf/bookStoreExtendedRefactor.ecore similarity index 100% rename from languages/emf-metamodel/src/test/resources/de/jplag/models/bookStoreExtendedRefactor.ecore rename to languages/emf-metamodel/src/test/resources/de/jplag/emf/bookStoreExtendedRefactor.ecore diff --git a/languages/emf-metamodel/src/test/resources/de/jplag/models/bookStoreRenamed.ecore b/languages/emf-metamodel/src/test/resources/de/jplag/emf/bookStoreRenamed.ecore similarity index 100% rename from languages/emf-metamodel/src/test/resources/de/jplag/models/bookStoreRenamed.ecore rename to languages/emf-metamodel/src/test/resources/de/jplag/emf/bookStoreRenamed.ecore diff --git a/languages/golang/src/main/java/de/jplag/golang/GoTokenType.java b/languages/golang/src/main/java/de/jplag/golang/GoTokenType.java index b93ced02f..9cf73ee1a 100644 --- a/languages/golang/src/main/java/de/jplag/golang/GoTokenType.java +++ b/languages/golang/src/main/java/de/jplag/golang/GoTokenType.java @@ -92,6 +92,7 @@ public enum GoTokenType implements TokenType { private final String description; + @Override public String getDescription() { return this.description; } diff --git a/languages/java/src/main/java/de/jplag/java/JavaTokenType.java b/languages/java/src/main/java/de/jplag/java/JavaTokenType.java index cfad295ab..8e5ed5fe5 100644 --- a/languages/java/src/main/java/de/jplag/java/JavaTokenType.java +++ b/languages/java/src/main/java/de/jplag/java/JavaTokenType.java @@ -12,12 +12,8 @@ public enum JavaTokenType implements TokenType { J_VARDEF("VARDEF"), // check J_SYNC_BEGIN("SYNC{"), // check J_SYNC_END("}SYNC"), // check - J_DO_BEGIN("DO{"), // check - J_DO_END("}DO"), // check - J_WHILE_BEGIN("WHILE{"), // check - J_WHILE_END("}WHILE"), // check - J_FOR_BEGIN("FOR{"), // check - J_FOR_END("}FOR"), // check + J_LOOP_BEGIN("LOOP{"), // check + J_LOOP_END("}LOOP"), // check J_SWITCH_BEGIN("SWITCH{"), // check J_SWITCH_END("}SWITCH"), // check J_CASE("CASE"), // check @@ -80,6 +76,7 @@ public enum JavaTokenType implements TokenType { private final String description; + @Override public String getDescription() { return this.description; } diff --git a/languages/java/src/main/java/de/jplag/java/TokenGeneratingTreeScanner.java b/languages/java/src/main/java/de/jplag/java/TokenGeneratingTreeScanner.java index 6dfca328a..c026b975a 100644 --- a/languages/java/src/main/java/de/jplag/java/TokenGeneratingTreeScanner.java +++ b/languages/java/src/main/java/de/jplag/java/TokenGeneratingTreeScanner.java @@ -66,9 +66,9 @@ final class TokenGeneratingTreeScanner extends TreeScanner { private final SourcePositions positions; private final CompilationUnitTree ast; - private List parsingExceptions = new ArrayList<>(); + private final List parsingExceptions = new ArrayList<>(); - private VariableRegistry variableRegistry; + private final VariableRegistry variableRegistry; private static final Set IMMUTABLES = Set.of( // from https://medium.com/@bpnorlander/java-understanding-primitive-types-and-wrapper-objects-a6798fb2afe9 @@ -216,10 +216,10 @@ public Void visitSynchronized(SynchronizedTree node, Void unused) { @Override public Void visitDoWhileLoop(DoWhileLoopTree node, Void unused) { long start = positions.getStartPosition(ast, node); - long end = positions.getEndPosition(ast, node) - 1; - addToken(JavaTokenType.J_DO_BEGIN, start, 2, CodeSemantics.createLoopBegin()); + long end = positions.getEndPosition(ast, node.getStatement()) - 1; + addToken(JavaTokenType.J_LOOP_BEGIN, start, 2, CodeSemantics.createLoopBegin()); scan(node.getStatement(), null); - addToken(JavaTokenType.J_DO_END, end, 1, CodeSemantics.createLoopEnd()); + addToken(JavaTokenType.J_LOOP_END, end, 1, CodeSemantics.createLoopEnd()); scan(node.getCondition(), null); return null; } @@ -228,9 +228,9 @@ public Void visitDoWhileLoop(DoWhileLoopTree node, Void unused) { public Void visitWhileLoop(WhileLoopTree node, Void unused) { long start = positions.getStartPosition(ast, node); long end = positions.getEndPosition(ast, node) - 1; - addToken(JavaTokenType.J_WHILE_BEGIN, start, 5, CodeSemantics.createLoopBegin()); + addToken(JavaTokenType.J_LOOP_BEGIN, start, 5, CodeSemantics.createLoopBegin()); super.visitWhileLoop(node, null); - addToken(JavaTokenType.J_WHILE_END, end, 1, CodeSemantics.createLoopEnd()); + addToken(JavaTokenType.J_LOOP_END, end, 1, CodeSemantics.createLoopEnd()); return null; } @@ -239,9 +239,9 @@ public Void visitForLoop(ForLoopTree node, Void unused) { variableRegistry.enterLocalScope(); long start = positions.getStartPosition(ast, node); long end = positions.getEndPosition(ast, node) - 1; - addToken(JavaTokenType.J_FOR_BEGIN, start, 3, CodeSemantics.createLoopBegin()); + addToken(JavaTokenType.J_LOOP_BEGIN, start, 3, CodeSemantics.createLoopBegin()); super.visitForLoop(node, null); - addToken(JavaTokenType.J_FOR_END, end, 1, CodeSemantics.createLoopEnd()); + addToken(JavaTokenType.J_LOOP_END, end, 1, CodeSemantics.createLoopEnd()); variableRegistry.exitLocalScope(); return null; } @@ -251,9 +251,9 @@ public Void visitEnhancedForLoop(EnhancedForLoopTree node, Void unused) { variableRegistry.enterLocalScope(); long start = positions.getStartPosition(ast, node); long end = positions.getEndPosition(ast, node) - 1; - addToken(JavaTokenType.J_FOR_BEGIN, start, 3, CodeSemantics.createLoopBegin()); + addToken(JavaTokenType.J_LOOP_BEGIN, start, 3, CodeSemantics.createLoopBegin()); super.visitEnhancedForLoop(node, null); - addToken(JavaTokenType.J_FOR_END, end, 1, CodeSemantics.createLoopEnd()); + addToken(JavaTokenType.J_LOOP_END, end, 1, CodeSemantics.createLoopEnd()); variableRegistry.exitLocalScope(); return null; } @@ -292,7 +292,6 @@ public Void visitTry(TryTree node, Void unused) { scan(node.getResources(), null); scan(node.getBlock(), null); long end = positions.getEndPosition(ast, node); - addToken(JavaTokenType.J_TRY_END, end, 1, CodeSemantics.createControl()); scan(node.getCatches(), null); if (node.getFinallyBlock() != null) { start = positions.getStartPosition(ast, node.getFinallyBlock()); @@ -301,6 +300,7 @@ public Void visitTry(TryTree node, Void unused) { end = positions.getEndPosition(ast, node.getFinallyBlock()); addToken(JavaTokenType.J_FINALLY_END, end, 1, CodeSemantics.createControl()); } + addToken(JavaTokenType.J_TRY_END, end, 1, CodeSemantics.createControl()); return null; } @@ -372,7 +372,7 @@ public Void visitThrow(ThrowTree node, Void unused) { @Override public Void visitNewClass(NewClassTree node, Void unused) { long start = positions.getStartPosition(ast, node); - if (node.getTypeArguments().size() > 0) { + if (!node.getTypeArguments().isEmpty()) { addToken(JavaTokenType.J_GENERIC, start, 3 + node.getIdentifier().toString().length(), new CodeSemantics()); } addToken(JavaTokenType.J_NEWCLASS, start, 3, new CodeSemantics()); diff --git a/languages/java/src/test/java/de/jplag/java/AbstractJavaLanguageTest.java b/languages/java/src/test/java/de/jplag/java/AbstractJavaLanguageTest.java deleted file mode 100644 index 77a25c789..000000000 --- a/languages/java/src/test/java/de/jplag/java/AbstractJavaLanguageTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package de.jplag.java; - -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.io.File; -import java.nio.file.Path; -import java.util.List; -import java.util.Set; - -import org.junit.jupiter.api.BeforeEach; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import de.jplag.ParsingException; -import de.jplag.Token; -import de.jplag.TokenPrinter; -import de.jplag.TokenType; - -/** - * Basic test class for testing the Java language module. - */ -public abstract class AbstractJavaLanguageTest { - - private static final Path BASE_PATH = Path.of("src", "test", "resources", "java"); - private static final String LOG_MESSAGE = "Tokens of {}: {}"; - private final Logger logger = LoggerFactory.getLogger(JavaBlockTest.class); - private de.jplag.Language language; - protected File baseDirectory; - - /** - * Sets up the base directory and the language module. - */ - @BeforeEach - void setUp() { - language = new JavaLanguage(); - baseDirectory = BASE_PATH.toFile(); - assertTrue(baseDirectory.exists(), "Could not find base directory!"); - } - - /** - * Parses a java file in the {@link AbstractJavaLanguageTest#baseDirectory} and returns the list of token types. - * @param fileName is the name of the file to parse. - * @return the token types. - * @throws ParsingException if parsing fails. - */ - protected List parseJavaFile(String fileName) throws ParsingException { - List parsedTokens = language.parse(Set.of(new File(baseDirectory, fileName))); - List tokenTypes = parsedTokens.stream().map(Token::getType).toList(); - logger.info(LOG_MESSAGE, fileName, tokenTypes); - logger.info(TokenPrinter.printTokens(parsedTokens, BASE_PATH.toAbsolutePath().toFile())); - return tokenTypes; - } - -} \ No newline at end of file diff --git a/languages/java/src/test/java/de/jplag/java/JavaBlockTest.java b/languages/java/src/test/java/de/jplag/java/JavaBlockTest.java deleted file mode 100644 index 57f52c704..000000000 --- a/languages/java/src/test/java/de/jplag/java/JavaBlockTest.java +++ /dev/null @@ -1,33 +0,0 @@ -package de.jplag.java; - -import static org.junit.jupiter.api.Assertions.assertIterableEquals; - -import java.util.stream.Stream; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import de.jplag.ParsingException; - -/** - * Test cases regarding the extraction from implicit vs. explicit blocks in Java code. - */ -class JavaBlockTest extends AbstractJavaLanguageTest { - @ParameterizedTest - @MethodSource("provideClassPairs") - @DisplayName("Test pairs of classes with explicit vs. implicit blocks.") - void testJavaClassPair(String fileName1, String fileName2) throws ParsingException { - assertIterableEquals(parseJavaFile(fileName1), parseJavaFile(fileName2)); - } - - /** - * Argument source for the test case {@link testJavaClassPair(String, String)). - */ - private static Stream provideClassPairs() { - return Stream.of(Arguments.of("IfWithBraces.java", "IfWithoutBraces.java"), // just if conditions - Arguments.of("Verbose.java", "Compact.java")); // complex case with different blocks - } - -} diff --git a/languages/java/src/test/java/de/jplag/java/JavaIfElseTest.java b/languages/java/src/test/java/de/jplag/java/JavaIfElseTest.java deleted file mode 100644 index 62e8be0a5..000000000 --- a/languages/java/src/test/java/de/jplag/java/JavaIfElseTest.java +++ /dev/null @@ -1,39 +0,0 @@ - -package de.jplag.java; - -import static org.junit.jupiter.api.Assertions.assertIterableEquals; - -import java.util.stream.Stream; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import de.jplag.ParsingException; - -/** - * Test cases regarding the extraction from if and else conditions. - */ -class JavaIfElseTest extends AbstractJavaLanguageTest { - private static final String IF_ELSE_IF = "IfElseIf.java"; - private static final String IF_IF = "IfIf.java"; - private static final String IF_ELSE = "IfElse.java"; - - @ParameterizedTest - @MethodSource("provideClassPairs") - @DisplayName("Test difference between if-else, if-if and if-else-if.") - void testJavaClassPair(String fileName1, String fileName2) throws ParsingException { - assertIterableEquals(parseJavaFile(fileName1), parseJavaFile(fileName2)); - } - - /** - * Argument source for the test case {@link testJavaClassPair(String, String)). - */ - private static Stream provideClassPairs() { - return Stream.of(Arguments.of(IF_ELSE, IF_IF), // if instead of else - Arguments.of(IF_ELSE, IF_ELSE_IF),// add if to else - Arguments.of(IF_ELSE_IF, IF_IF)); // removal of else - } - -} diff --git a/languages/java/src/test/java/de/jplag/java/JavaLanguageTest.java b/languages/java/src/test/java/de/jplag/java/JavaLanguageTest.java new file mode 100644 index 000000000..51e36d7c2 --- /dev/null +++ b/languages/java/src/test/java/de/jplag/java/JavaLanguageTest.java @@ -0,0 +1,49 @@ +package de.jplag.java; + +import static de.jplag.java.JavaTokenType.*; + +import de.jplag.testutils.LanguageModuleTest; +import de.jplag.testutils.datacollector.TestDataCollector; +import de.jplag.testutils.datacollector.TestSourceIgnoredLinesCollector; + +public class JavaLanguageTest extends LanguageModuleTest { + public JavaLanguageTest() { + super(new JavaLanguage(), JavaTokenType.class); + } + + @Override + protected void collectTestData(TestDataCollector collector) { + // Test cases regarding the extraction from if and else conditions. + collector.testFile("IfElse.java", "IfIf.java", "IfElseIf.java").testSourceCoverage().testTokenSequence(J_IMPORT, J_CLASS_BEGIN, + J_METHOD_BEGIN, J_VARDEF, J_IF_BEGIN, J_THROW, J_NEWCLASS, J_IF_END, J_IF_BEGIN, J_APPLY, J_APPLY, J_IF_END, J_METHOD_END, + J_CLASS_END); + + // Test cases regarding the extraction from implicit vs. explicit blocks in Java code. + collector.testFile("IfWithBraces.java", "IfWithoutBraces.java").testSourceCoverage().testTokenSequence(J_PACKAGE, J_IMPORT, J_CLASS_BEGIN, + J_METHOD_BEGIN, J_VARDEF, J_IF_BEGIN, J_THROW, J_NEWCLASS, J_IF_END, J_IF_BEGIN, J_APPLY, J_APPLY, J_IF_END, J_IF_BEGIN, J_APPLY, + J_IF_END, J_METHOD_END, J_CLASS_END); + + collector.testFile("Verbose.java", "Compact.java").testSourceCoverage().testTokenSequence(J_PACKAGE, J_IMPORT, J_CLASS_BEGIN, J_METHOD_BEGIN, + J_VARDEF, J_VARDEF, J_IF_BEGIN, J_APPLY, J_RETURN, J_IF_END, J_VARDEF, J_LOOP_BEGIN, J_VARDEF, J_APPLY, J_ASSIGN, J_IF_BEGIN, J_APPLY, + J_APPLY, J_ASSIGN, J_IF_END, J_LOOP_END, J_IF_BEGIN, J_APPLY, J_ASSIGN, J_IF_END, J_IF_BEGIN, J_APPLY, J_APPLY, J_ASSIGN, J_IF_END, + J_RETURN, J_METHOD_END, J_CLASS_END); + + // Test difference between try block and try-with-resource block. + collector.testFile("Try.java", "TryWithResource.java").testSourceCoverage().testTokenSequence(J_PACKAGE, J_IMPORT, J_IMPORT, J_IMPORT, + J_CLASS_BEGIN, J_METHOD_BEGIN, J_VARDEF, J_APPLY, J_NEWCLASS, J_METHOD_END, J_METHOD_BEGIN, J_VARDEF, J_VARDEF, J_TRY_BEGIN, J_VARDEF, + J_ASSIGN, J_NEWCLASS, J_NEWCLASS, J_LOOP_BEGIN, J_APPLY, J_APPLY, J_APPLY, J_LOOP_END, J_CATCH_BEGIN, J_VARDEF, J_APPLY, J_CATCH_END, + J_FINALLY_BEGIN, J_IF_BEGIN, J_APPLY, J_IF_END, J_FINALLY_END, J_TRY_END, J_METHOD_END, J_CLASS_END); + + collector.testFile("CLI.java").testSourceCoverage().testContainedTokens(J_TRY_END, J_IMPORT, J_VARDEF, J_LOOP_BEGIN, J_ARRAY_INIT_BEGIN, + J_IF_BEGIN, J_CATCH_END, J_COND, J_ARRAY_INIT_END, J_METHOD_BEGIN, J_TRY_BEGIN, J_CLASS_END, J_RETURN, J_ASSIGN, J_METHOD_END, + J_IF_END, J_CLASS_BEGIN, J_NEWARRAY, J_PACKAGE, J_APPLY, J_LOOP_END, J_THROW, J_NEWCLASS, J_CATCH_BEGIN); + } + + @Override + protected void configureIgnoredLines(TestSourceIgnoredLinesCollector collector) { + collector.ignoreLinesByPrefix("//"); + collector.ignoreMultipleLines("/*", "*/"); + collector.ignoreLinesByPrefix("})"); + collector.ignoreByCondition(line -> line.contains("else") && !line.contains("if")); + } +} diff --git a/languages/java/src/test/java/de/jplag/java/JavaTryTest.java b/languages/java/src/test/java/de/jplag/java/JavaTryTest.java deleted file mode 100644 index c5ee683d9..000000000 --- a/languages/java/src/test/java/de/jplag/java/JavaTryTest.java +++ /dev/null @@ -1,20 +0,0 @@ - -package de.jplag.java; - -import static org.junit.jupiter.api.Assertions.assertIterableEquals; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import de.jplag.ParsingException; - -/** - * Test cases regarding the extraction from try vs. try with resource. - */ -class JavaTryTest extends AbstractJavaLanguageTest { - @Test - @DisplayName("Test difference between try block and try-with-resource block.") - void testJavaClassPair() throws ParsingException { - assertIterableEquals(parseJavaFile("Try.java"), parseJavaFile("TryWithResource.java")); - } -} diff --git a/languages/java/src/test/resources/de/jplag/java/CLI.java b/languages/java/src/test/resources/de/jplag/java/CLI.java new file mode 100644 index 000000000..a019fe54c --- /dev/null +++ b/languages/java/src/test/resources/de/jplag/java/CLI.java @@ -0,0 +1,220 @@ +package de.jplag.cli; + +import static picocli.CommandLine.Model.UsageMessageSpec.SECTION_KEY_FOOTER; +import static picocli.CommandLine.Model.UsageMessageSpec.SECTION_KEY_OPTION_LIST; + +import java.io.File; +import java.security.SecureRandom; +import java.util.HashSet; +import java.util.List; +import java.util.Random; +import java.util.Set; +import java.util.stream.Collectors; + +import org.slf4j.ILoggerFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import de.jplag.JPlag; +import de.jplag.JPlagResult; +import de.jplag.Language; +import de.jplag.cli.logger.CollectedLoggerFactory; +import de.jplag.clustering.ClusteringOptions; +import de.jplag.clustering.Preprocessing; +import de.jplag.exceptions.ExitException; +import de.jplag.options.JPlagOptions; +import de.jplag.options.LanguageOption; +import de.jplag.options.LanguageOptions; +import de.jplag.reporting.reportobject.ReportObjectFactory; + +import picocli.CommandLine; +import picocli.CommandLine.Model.CommandSpec; +import picocli.CommandLine.Model.OptionSpec; +import picocli.CommandLine.ParseResult; + +/** + * Command line interface class, allows using via command line. + * + * @see CLI#main(String[]) + */ +public final class CLI { + + private static final Logger logger = LoggerFactory.getLogger(CLI.class); + + private static final Random RANDOM = new SecureRandom(); + + private static final String CREDITS = "Created by IPD Tichy, Guido Malpohl, and others. JPlag logo designed by Sandro Koch. Currently maintained by Sebastian Hahner and Timur Saglam."; + + private static final String[] DESCRIPTIONS = {"Detecting Software Plagiarism", "Software-Archaeological Playground", "Since 1996", "Scientifically Published", "Maintained by SDQ", "RIP Structure and Table", "What else?", "You have been warned!", "Since Java 1.0", "More Abstract than Tree", "Students Nightmare", "No, changing variable names does not work", "The tech is out there!", "Developed by plagiarism experts."}; + + private final CommandLine commandLine; + private final CliOptions options; + + private static final String IMPOSSIBLE_EXCEPTION = "This should not have happened." + " Please create an issue on github (https://github.com/jplag/JPlag/issues) with the entire output."; + + /** + * Main class for using JPlag via the CLI. + * + * @param args are the CLI arguments that will be passed to JPlag. + */ + public static void main(String[] args) { + try { + logger.debug("Your version of JPlag is {}", JPlag.JPLAG_VERSION); + + CLI cli = new CLI(); + + ParseResult parseResult = cli.parseOptions(args); + + if (!parseResult.isUsageHelpRequested() && !(parseResult.subcommand() != null && parseResult.subcommand().isUsageHelpRequested())) { + JPlagOptions options = cli.buildOptionsFromArguments(parseResult); + JPlagResult result = JPlag.run(options); + ReportObjectFactory reportObjectFactory = new ReportObjectFactory(); + reportObjectFactory.createAndSaveReport(result, cli.getResultFolder()); + } + } catch (ExitException exception) { + logger.error(exception.getMessage()); // do not pass exception here to keep log clean + finalizeLogger(); + System.exit(1); + } + } + + /** + * Creates a new instance + */ + public CLI() { + this.options = new CliOptions(); + this.commandLine = new CommandLine(options); + + this.commandLine.getHelpSectionMap().put(SECTION_KEY_OPTION_LIST, help -> help.optionList().lines().map(it -> { + if (it.startsWith(" -")) { + return " " + it; + } else { + return it; + } + }).collect(Collectors.joining(System.lineSeparator()))); + + buildSubcommands().forEach(commandLine::addSubcommand); + + this.commandLine.getHelpSectionMap().put(SECTION_KEY_FOOTER, help -> generateDescription()); + this.commandLine.setAllowSubcommandsAsOptionParameters(true); + } + + private List buildSubcommands() { + return LanguageLoader.getAllAvailableLanguages().values().stream().map(language -> { + CommandSpec command = CommandSpec.create().name(language.getIdentifier()); + + for (LanguageOption option : language.getOptions().getOptionsAsList()) { + command.addOption(OptionSpec.builder(option.getNameAsUnixParameter()).type(option.getType().getJavaType()) + .description(option.getDescription()).build()); + } + command.mixinStandardHelpOptions(true); + command.addPositional( + CommandLine.Model.PositionalParamSpec.builder().type(List.class).auxiliaryTypes(File.class).hidden(true).required(false).build()); + + return command; + }).toList(); + } + + /** + * Parses the options from the given command line arguments. Also prints help pages when requested. + * + * @param args The command line arguments + * @return the parse result generated by picocli + */ + public ParseResult parseOptions(String... args) throws CliException { + try { + ParseResult result = commandLine.parseArgs(args); + if (result.isUsageHelpRequested() || (result.subcommand() != null && result.subcommand().isUsageHelpRequested())) { + commandLine.getExecutionStrategy().execute(result); + } + return result; + } catch (CommandLine.PicocliException e) { + throw new CliException("Error during parsing", e); + } + } + + private static void finalizeLogger() { + ILoggerFactory factory = LoggerFactory.getILoggerFactory(); + if (!(factory instanceof CollectedLoggerFactory collectedLoggerFactory)) { + return; + } + collectedLoggerFactory.finalizeInstances(); + } + + /** + * Builds an options instance from parsed options. + * + * @return the newly built options + */ + public JPlagOptions buildOptionsFromArguments(ParseResult parseResult) throws CliException { + Set submissionDirectories = new HashSet<>(List.of(this.options.rootDirectory)); + Set oldSubmissionDirectories = Set.of(this.options.oldDirectories); + List suffixes = List.of(this.options.advanced.suffixes); + submissionDirectories.addAll(List.of(this.options.newDirectories)); + + if (parseResult.subcommand() != null && parseResult.subcommand().hasMatchedPositional(0)) { + submissionDirectories.addAll(parseResult.subcommand().matchedPositional(0).getValue()); + } + + ClusteringOptions clusteringOptions = getClusteringOptions(this.options); + + JPlagOptions jPlagOptions = new JPlagOptions(loadLanguage(parseResult), this.options.minTokenMatch, submissionDirectories, oldSubmissionDirectories, null, this.options.advanced.subdirectory, suffixes, this.options.advanced.exclusionFileName, JPlagOptions.DEFAULT_SIMILARITY_METRIC, this.options.advanced.similarityThreshold, this.options.shownComparisons, clusteringOptions, this.options.advanced.debug); + + String baseCodePath = this.options.baseCode; + File baseCodeDirectory = baseCodePath == null ? null : new File(baseCodePath); + if (baseCodeDirectory == null || baseCodeDirectory.exists()) { + return jPlagOptions.withBaseCodeSubmissionDirectory(baseCodeDirectory); + } else { + logger.warn("Using legacy partial base code API. Please migrate to new full path base code API."); + return jPlagOptions.withBaseCodeSubmissionName(baseCodePath); + } + } + + private Language loadLanguage(ParseResult result) throws CliException { + if (result.subcommand() != null) { + ParseResult subcommandResult = result.subcommand(); + Language language = LanguageLoader.getLanguage(subcommandResult.commandSpec().name()) + .orElseThrow(() -> new CliException(IMPOSSIBLE_EXCEPTION)); + LanguageOptions languageOptions = language.getOptions(); + languageOptions.getOptionsAsList().forEach(option -> { + if (subcommandResult.hasMatchedOption(option.getNameAsUnixParameter())) { + option.setValue(subcommandResult.matchedOptionValue(option.getNameAsUnixParameter(), null)); + } + }); + return language; + } else { + return this.options.language; + } + } + + private static ClusteringOptions getClusteringOptions(CliOptions options) { + ClusteringOptions clusteringOptions = new ClusteringOptions().withEnabled(!options.clustering.disable).withAlgorithm(options.clustering.enabled.algorithm).withSimilarityMetric(options.clustering.enabled.metric).withSpectralKernelBandwidth(options.clusterSpectralBandwidth).withSpectralGaussianProcessVariance(options.clusterSpectralNoise).withSpectralMinRuns(options.clusterSpectralMinRuns).withSpectralMaxRuns(options.clusterSpectralMaxRuns).withSpectralMaxKMeansIterationPerRun(options.clusterSpectralKMeansIterations).withAgglomerativeThreshold(options.clusterAgglomerativeThreshold).withAgglomerativeInterClusterSimilarity(options.clusterAgglomerativeInterClusterSimilarity); + + if (options.clusterPreprocessingNone) { + clusteringOptions = clusteringOptions.withPreprocessor(Preprocessing.NONE); + } + + if (options.clusterPreprocessingCdf) { + clusteringOptions = clusteringOptions.withPreprocessor(Preprocessing.CUMULATIVE_DISTRIBUTION_FUNCTION); + } + + if (options.clusterPreprocessingPercentile != 0) { + clusteringOptions = clusteringOptions.withPreprocessor(Preprocessing.PERCENTILE).withPreprocessorPercentile(options.clusterPreprocessingPercentile); + } + + if (options.clusterPreprocessingThreshold != 0) { + clusteringOptions = clusteringOptions.withPreprocessor(Preprocessing.THRESHOLD).withPreprocessorThreshold(options.clusterPreprocessingThreshold); + } + + return clusteringOptions; + } + + private String generateDescription() { + var randomDescription = DESCRIPTIONS[RANDOM.nextInt(DESCRIPTIONS.length)]; + return String.format("JPlag - %s%n%n%s", randomDescription, CREDITS); + } + + public String getResultFolder() { + return this.options.resultFolder; + } +} diff --git a/languages/java/src/test/resources/java/Compact.java b/languages/java/src/test/resources/de/jplag/java/Compact.java similarity index 100% rename from languages/java/src/test/resources/java/Compact.java rename to languages/java/src/test/resources/de/jplag/java/Compact.java diff --git a/languages/java/src/test/resources/java/IfElse.java b/languages/java/src/test/resources/de/jplag/java/IfElse.java similarity index 100% rename from languages/java/src/test/resources/java/IfElse.java rename to languages/java/src/test/resources/de/jplag/java/IfElse.java diff --git a/languages/java/src/test/resources/java/IfElseIf.java b/languages/java/src/test/resources/de/jplag/java/IfElseIf.java similarity index 100% rename from languages/java/src/test/resources/java/IfElseIf.java rename to languages/java/src/test/resources/de/jplag/java/IfElseIf.java diff --git a/languages/java/src/test/resources/java/IfIf.java b/languages/java/src/test/resources/de/jplag/java/IfIf.java similarity index 100% rename from languages/java/src/test/resources/java/IfIf.java rename to languages/java/src/test/resources/de/jplag/java/IfIf.java diff --git a/languages/java/src/test/resources/java/IfWithBraces.java b/languages/java/src/test/resources/de/jplag/java/IfWithBraces.java similarity index 100% rename from languages/java/src/test/resources/java/IfWithBraces.java rename to languages/java/src/test/resources/de/jplag/java/IfWithBraces.java diff --git a/languages/java/src/test/resources/java/IfWithoutBraces.java b/languages/java/src/test/resources/de/jplag/java/IfWithoutBraces.java similarity index 100% rename from languages/java/src/test/resources/java/IfWithoutBraces.java rename to languages/java/src/test/resources/de/jplag/java/IfWithoutBraces.java diff --git a/languages/java/src/test/resources/java/Try.java b/languages/java/src/test/resources/de/jplag/java/Try.java similarity index 100% rename from languages/java/src/test/resources/java/Try.java rename to languages/java/src/test/resources/de/jplag/java/Try.java diff --git a/languages/java/src/test/resources/java/TryWithResource.java b/languages/java/src/test/resources/de/jplag/java/TryWithResource.java similarity index 100% rename from languages/java/src/test/resources/java/TryWithResource.java rename to languages/java/src/test/resources/de/jplag/java/TryWithResource.java diff --git a/languages/java/src/test/resources/java/Verbose.java b/languages/java/src/test/resources/de/jplag/java/Verbose.java similarity index 100% rename from languages/java/src/test/resources/java/Verbose.java rename to languages/java/src/test/resources/de/jplag/java/Verbose.java diff --git a/languages/kotlin/src/main/java/de/jplag/kotlin/KotlinTokenType.java b/languages/kotlin/src/main/java/de/jplag/kotlin/KotlinTokenType.java index 421dd5888..318b2b17a 100644 --- a/languages/kotlin/src/main/java/de/jplag/kotlin/KotlinTokenType.java +++ b/languages/kotlin/src/main/java/de/jplag/kotlin/KotlinTokenType.java @@ -76,6 +76,7 @@ public enum KotlinTokenType implements TokenType { private final String description; + @Override public String getDescription() { return description; } diff --git a/languages/python-3/src/main/java/de/jplag/python3/Python3TokenType.java b/languages/python-3/src/main/java/de/jplag/python3/Python3TokenType.java index a692031be..e4a684c9b 100644 --- a/languages/python-3/src/main/java/de/jplag/python3/Python3TokenType.java +++ b/languages/python-3/src/main/java/de/jplag/python3/Python3TokenType.java @@ -36,6 +36,7 @@ public enum Python3TokenType implements TokenType { private final String description; + @Override public String getDescription() { return this.description; } diff --git a/languages/rlang/src/main/java/de/jplag/rlang/RTokenType.java b/languages/rlang/src/main/java/de/jplag/rlang/RTokenType.java index a70a08607..3a58935fb 100644 --- a/languages/rlang/src/main/java/de/jplag/rlang/RTokenType.java +++ b/languages/rlang/src/main/java/de/jplag/rlang/RTokenType.java @@ -35,6 +35,7 @@ public enum RTokenType implements TokenType { private final String description; + @Override public String getDescription() { return this.description; } diff --git a/languages/rust/src/main/java/de/jplag/rust/RustTokenType.java b/languages/rust/src/main/java/de/jplag/rust/RustTokenType.java index 8e744c37b..4655b9525 100644 --- a/languages/rust/src/main/java/de/jplag/rust/RustTokenType.java +++ b/languages/rust/src/main/java/de/jplag/rust/RustTokenType.java @@ -114,6 +114,7 @@ public enum RustTokenType implements TokenType { private final String description; + @Override public String getDescription() { return description; } diff --git a/languages/scala/pom.xml b/languages/scala/pom.xml index 02fc41aa2..71c3694aa 100644 --- a/languages/scala/pom.xml +++ b/languages/scala/pom.xml @@ -25,7 +25,7 @@ org.scalameta scalameta_${scala.compat.version} - 4.8.3 + 4.8.7 diff --git a/languages/scala/src/main/scala/de/jplag/scala/ScalaTokenType.java b/languages/scala/src/main/scala/de/jplag/scala/ScalaTokenType.java index a21a5980e..a84255d91 100644 --- a/languages/scala/src/main/scala/de/jplag/scala/ScalaTokenType.java +++ b/languages/scala/src/main/scala/de/jplag/scala/ScalaTokenType.java @@ -74,6 +74,7 @@ public enum ScalaTokenType implements TokenType { private final String description; + @Override public String getDescription() { return description; } diff --git a/languages/scheme/src/main/java/de/jplag/scheme/SchemeTokenType.java b/languages/scheme/src/main/java/de/jplag/scheme/SchemeTokenType.java index 8b2109ee1..a041d46d8 100644 --- a/languages/scheme/src/main/java/de/jplag/scheme/SchemeTokenType.java +++ b/languages/scheme/src/main/java/de/jplag/scheme/SchemeTokenType.java @@ -47,6 +47,7 @@ public enum SchemeTokenType implements TokenType { private final String description; + @Override public String getDescription() { return this.description; } diff --git a/languages/scxml/src/main/java/de/jplag/scxml/ScxmlTokenType.java b/languages/scxml/src/main/java/de/jplag/scxml/ScxmlTokenType.java index 98ef60f4a..ad99427cb 100644 --- a/languages/scxml/src/main/java/de/jplag/scxml/ScxmlTokenType.java +++ b/languages/scxml/src/main/java/de/jplag/scxml/ScxmlTokenType.java @@ -152,6 +152,7 @@ public enum ScxmlTokenType implements TokenType { /** * @return the description for this token type */ + @Override public String getDescription() { return description; } diff --git a/languages/swift/src/main/java/de/jplag/swift/SwiftTokenType.java b/languages/swift/src/main/java/de/jplag/swift/SwiftTokenType.java index 3b69cb6eb..0bfc07640 100644 --- a/languages/swift/src/main/java/de/jplag/swift/SwiftTokenType.java +++ b/languages/swift/src/main/java/de/jplag/swift/SwiftTokenType.java @@ -53,6 +53,7 @@ public enum SwiftTokenType implements TokenType { private final String description; + @Override public String getDescription() { return description; } diff --git a/languages/text/src/main/java/de/jplag/text/TextTokenType.java b/languages/text/src/main/java/de/jplag/text/TextTokenType.java index 1fc2277d9..23b3ce893 100644 --- a/languages/text/src/main/java/de/jplag/text/TextTokenType.java +++ b/languages/text/src/main/java/de/jplag/text/TextTokenType.java @@ -7,6 +7,7 @@ public TextTokenType(String description) { this.description = description.toLowerCase(); } + @Override public String getDescription() { return this.description; } diff --git a/languages/text/src/test/java/jplag/text/NaturalLanguageTest.java b/languages/text/src/test/java/jplag/text/NaturalLanguageTest.java index b31c65b0f..9e16e4532 100644 --- a/languages/text/src/test/java/jplag/text/NaturalLanguageTest.java +++ b/languages/text/src/test/java/jplag/text/NaturalLanguageTest.java @@ -13,7 +13,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.slf4j.Logger; @@ -54,19 +53,19 @@ void testParsingJavaDoc() throws ParsingException { @ParameterizedTest @ValueSource(strings = {"\n", "\r", "\r\n",}) - void testLineBreakInputs(String input, @TempDir Path tempDir) throws IOException, ParsingException { - Path filePath = tempDir.resolve("input.txt"); - Files.writeString(filePath, input); - List result = language.parse(Set.of(filePath.toFile())); + void testLineBreakInputs(String input) throws IOException, ParsingException { + File testFile = File.createTempFile("input", "txt"); + Files.writeString(testFile.toPath(), input); + List result = language.parse(Set.of(testFile)); assertEquals(1, result.size()); } @ParameterizedTest @ValueSource(strings = {"\ntoken", "\rtoken", "\r\ntoken",}) - void testTokenAfterLineBreak(String input, @TempDir Path tempDir) throws IOException, ParsingException { - Path filePath = tempDir.resolve("input.txt"); - Files.writeString(filePath, input); - List result = language.parse(Set.of(filePath.toFile())); + void testTokenAfterLineBreak(String input) throws IOException, ParsingException { + File testFile = File.createTempFile("input", "txt"); + Files.writeString(testFile.toPath(), input); + List result = language.parse(Set.of(testFile)); assertEquals(2, result.get(0).getLine()); } diff --git a/pom.xml b/pom.xml index 242d8b994..4116a8142 100644 --- a/pom.xml +++ b/pom.xml @@ -74,9 +74,9 @@ 17 17 - 2.37.0 + 2.38.0 2.0.7 - 5.9.3 + 5.10.0 2.7.7 4.13.0 diff --git a/report-viewer/package-lock.json b/report-viewer/package-lock.json index 13597f849..760bb7622 100644 --- a/report-viewer/package-lock.json +++ b/report-viewer/package-lock.json @@ -8,15 +8,15 @@ "name": "report-viewer", "version": "0.0.0", "dependencies": { - "@fortawesome/fontawesome-svg-core": "^6.4.0", - "@fortawesome/free-regular-svg-icons": "^6.4.0", - "@fortawesome/free-solid-svg-icons": "^6.4.0", + "@fortawesome/fontawesome-svg-core": "^6.4.2", + "@fortawesome/free-regular-svg-icons": "^6.4.2", + "@fortawesome/free-solid-svg-icons": "^6.4.2", "@fortawesome/vue-fontawesome": "^3.0.3", "chart.js": "^3.9.1", "chartjs-plugin-datalabels": "^2.2.0", "highlight.js": "^11.8.0", "jszip": "^3.10.0", - "pinia": "^2.1.4", + "pinia": "^2.1.6", "slash": "^5.1.0", "vue": "^3.3.4", "vue-chart-3": "^3.1.8", @@ -25,14 +25,14 @@ "vue-virtual-scroller": "^2.0.0-beta.8" }, "devDependencies": { - "@playwright/test": "^1.36.0", + "@playwright/test": "^1.36.2", "@rushstack/eslint-patch": "^1.3.2", "@types/jsdom": "^21.1.0", - "@types/node": "^20.4.2", + "@types/node": "^20.4.10", "@vitejs/plugin-vue": "^4.2.3", - "@vue/eslint-config-prettier": "^7.1.0", + "@vue/eslint-config-prettier": "^8.0.0", "@vue/eslint-config-typescript": "^11.0.3", - "@vue/test-utils": "^2.4.0", + "@vue/test-utils": "^2.4.1", "@vue/tsconfig": "^0.4.0", "autoprefixer": "^10.4.14", "eslint": "^8.45.0", @@ -41,13 +41,13 @@ "jsdom": "^22.1.0", "lint-staged": "^13.2.3", "npm-run-all": "^4.1.5", - "postcss": "^8.4.26", + "postcss": "^8.4.27", "prettier": "^3.0.0", "tailwindcss": "^3.3.3", "typescript": "^5.1.6", - "vite": "^4.3.9", - "vitest": "^0.32.4", - "vue-tsc": "^1.8.5" + "vite": "^4.4.8", + "vitest": "^0.34.1", + "vue-tsc": "^1.8.8" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -82,10 +82,346 @@ "node": ">=6.0.0" } }, + "node_modules/@esbuild/android-arm": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.14.tgz", + "integrity": "sha512-blODaaL+lngG5bdK/t4qZcQvq2BBqrABmYwqPPcS5VRxrCSGHb9R/rA3fqxh7R18I7WU4KKv+NYkt22FDfalcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.14.tgz", + "integrity": "sha512-rZ2v+Luba5/3D6l8kofWgTnqE+qsC/L5MleKIKFyllHTKHrNBMqeRCnZI1BtRx8B24xMYxeU32iIddRQqMsOsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.14.tgz", + "integrity": "sha512-qSwh8y38QKl+1Iqg+YhvCVYlSk3dVLk9N88VO71U4FUjtiSFylMWK3Ugr8GC6eTkkP4Tc83dVppt2n8vIdlSGg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.14.tgz", + "integrity": "sha512-9Hl2D2PBeDYZiNbnRKRWuxwHa9v5ssWBBjisXFkVcSP5cZqzZRFBUWEQuqBHO4+PKx4q4wgHoWtfQ1S7rUqJ2Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.14.tgz", + "integrity": "sha512-ZnI3Dg4ElQ6tlv82qLc/UNHtFsgZSKZ7KjsUNAo1BF1SoYDjkGKHJyCrYyWjFecmXpvvG/KJ9A/oe0H12odPLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.14.tgz", + "integrity": "sha512-h3OqR80Da4oQCIa37zl8tU5MwHQ7qgPV0oVScPfKJK21fSRZEhLE4IIVpmcOxfAVmqjU6NDxcxhYaM8aDIGRLw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.14.tgz", + "integrity": "sha512-ha4BX+S6CZG4BoH9tOZTrFIYC1DH13UTCRHzFc3GWX74nz3h/N6MPF3tuR3XlsNjMFUazGgm35MPW5tHkn2lzQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.14.tgz", + "integrity": "sha512-5+7vehI1iqru5WRtJyU2XvTOvTGURw3OZxe3YTdE9muNNIdmKAVmSHpB3Vw2LazJk2ifEdIMt/wTWnVe5V98Kg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.14.tgz", + "integrity": "sha512-IXORRe22In7U65NZCzjwAUc03nn8SDIzWCnfzJ6t/8AvGx5zBkcLfknI+0P+hhuftufJBmIXxdSTbzWc8X/V4w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.14.tgz", + "integrity": "sha512-BfHlMa0nibwpjG+VXbOoqJDmFde4UK2gnW351SQ2Zd4t1N3zNdmUEqRkw/srC1Sa1DRBE88Dbwg4JgWCbNz/FQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.14.tgz", + "integrity": "sha512-j2/Ex++DRUWIAaUDprXd3JevzGtZ4/d7VKz+AYDoHZ3HjJzCyYBub9CU1wwIXN+viOP0b4VR3RhGClsvyt/xSw==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.14.tgz", + "integrity": "sha512-qn2+nc+ZCrJmiicoAnJXJJkZWt8Nwswgu1crY7N+PBR8ChBHh89XRxj38UU6Dkthl2yCVO9jWuafZ24muzDC/A==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.14.tgz", + "integrity": "sha512-aGzXzd+djqeEC5IRkDKt3kWzvXoXC6K6GyYKxd+wsFJ2VQYnOWE954qV2tvy5/aaNrmgPTb52cSCHFE+Z7Z0yg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.14.tgz", + "integrity": "sha512-8C6vWbfr0ygbAiMFLS6OPz0BHvApkT2gCboOGV76YrYw+sD/MQJzyITNsjZWDXJwPu9tjrFQOVG7zijRzBCnLw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.14.tgz", + "integrity": "sha512-G/Lf9iu8sRMM60OVGOh94ZW2nIStksEcITkXdkD09/T6QFD/o+g0+9WVyR/jajIb3A0LvBJ670tBnGe1GgXMgw==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.14.tgz", + "integrity": "sha512-TBgStYBQaa3EGhgqIDM+ECnkreb0wkcKqL7H6m+XPcGUoU4dO7dqewfbm0mWEQYH3kzFHrzjOFNpSAVzDZRSJw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.14.tgz", + "integrity": "sha512-stvCcjyCQR2lMTroqNhAbvROqRjxPEq0oQ380YdXxA81TaRJEucH/PzJ/qsEtsHgXlWFW6Ryr/X15vxQiyRXVg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.14.tgz", + "integrity": "sha512-apAOJF14CIsN5ht1PA57PboEMsNV70j3FUdxLmA2liZ20gEQnfTG5QU0FhENo5nwbTqCB2O3WDsXAihfODjHYw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.14.tgz", + "integrity": "sha512-fYRaaS8mDgZcGybPn2MQbn1ZNZx+UXFSUoS5Hd2oEnlsyUcr/l3c6RnXf1bLDRKKdLRSabTmyCy7VLQ7VhGdOQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.14.tgz", + "integrity": "sha512-1c44RcxKEJPrVj62XdmYhxXaU/V7auELCmnD+Ri+UCt+AGxTvzxl9uauQhrFso8gj6ZV1DaORV0sT9XSHOAk8Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.14.tgz", + "integrity": "sha512-EXAFttrdAxZkFQmpvcAQ2bywlWUsONp/9c2lcfvPUhu8vXBBenCXpoq9YkUvVP639ld3YGiYx0YUQ6/VQz3Maw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@esbuild/win32-x64": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.14.tgz", - "integrity": "sha512-gPQmsi2DKTaEgG14hc3CHXHp62k8g6qr0Pas+I4lUxRMugGSATh/Bi8Dgusoz9IQ0IfdrvLpco6kujEIBoaogA==", + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.14.tgz", + "integrity": "sha512-K0QjGbcskx+gY+qp3v4/940qg8JitpXbdxFhRDA1aYoNaPff88+aEwoq45aqJ+ogpxQxmU0ZTjgnrQD/w8iiUg==", "cpu": [ "x64" ], @@ -155,45 +491,45 @@ } }, "node_modules/@fortawesome/fontawesome-common-types": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.4.0.tgz", - "integrity": "sha512-HNii132xfomg5QVZw0HwXXpN22s7VBHQBv9CeOu9tfJnhsWQNd2lmTNi8CSrnw5B+5YOmzu1UoPAyxaXsJ6RgQ==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.4.2.tgz", + "integrity": "sha512-1DgP7f+XQIJbLFCTX1V2QnxVmpLdKdzzo2k8EmvDOePfchaIGQ9eCHj2up3/jNEbZuBqel5OxiaOJf37TWauRA==", "hasInstallScript": true, "engines": { "node": ">=6" } }, "node_modules/@fortawesome/fontawesome-svg-core": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.4.0.tgz", - "integrity": "sha512-Bertv8xOiVELz5raB2FlXDPKt+m94MQ3JgDfsVbrqNpLU9+UE2E18GKjLKw+d3XbeYPqg1pzyQKGsrzbw+pPaw==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.4.2.tgz", + "integrity": "sha512-gjYDSKv3TrM2sLTOKBc5rH9ckje8Wrwgx1CxAPbN5N3Fm4prfi7NsJVWd1jklp7i5uSCVwhZS5qlhMXqLrpAIg==", "hasInstallScript": true, "dependencies": { - "@fortawesome/fontawesome-common-types": "6.4.0" + "@fortawesome/fontawesome-common-types": "6.4.2" }, "engines": { "node": ">=6" } }, "node_modules/@fortawesome/free-regular-svg-icons": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.4.0.tgz", - "integrity": "sha512-ZfycI7D0KWPZtf7wtMFnQxs8qjBXArRzczABuMQqecA/nXohquJ5J/RCR77PmY5qGWkxAZDxpnUFVXKwtY/jPw==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.4.2.tgz", + "integrity": "sha512-0+sIUWnkgTVVXVAPQmW4vxb9ZTHv0WstOa3rBx9iPxrrrDH6bNLsDYuwXF9b6fGm+iR7DKQvQshUH/FJm3ed9Q==", "hasInstallScript": true, "dependencies": { - "@fortawesome/fontawesome-common-types": "6.4.0" + "@fortawesome/fontawesome-common-types": "6.4.2" }, "engines": { "node": ">=6" } }, "node_modules/@fortawesome/free-solid-svg-icons": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.4.0.tgz", - "integrity": "sha512-kutPeRGWm8V5dltFP1zGjQOEAzaLZj4StdQhWVZnfGFCvAPVvHh8qk5bRrU4KXnRRRNni5tKQI9PBAdI6MP8nQ==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.4.2.tgz", + "integrity": "sha512-sYwXurXUEQS32fZz9hVCUUv/xu49PEJEyUOsA51l6PU/qVgfbTb2glsTEaJngVVT8VqBATRIdh7XVgV1JF1LkA==", "hasInstallScript": true, "dependencies": { - "@fortawesome/fontawesome-common-types": "6.4.0" + "@fortawesome/fontawesome-common-types": "6.4.2" }, "engines": { "node": ">=6" @@ -341,14 +677,46 @@ "node": ">= 8" } }, + "node_modules/@one-ini/wasm": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz", + "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==", + "dev": true + }, + "node_modules/@pkgr/utils": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.2.tgz", + "integrity": "sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "fast-glob": "^3.3.0", + "is-glob": "^4.0.3", + "open": "^9.1.0", + "picocolors": "^1.0.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/@pkgr/utils/node_modules/tslib": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", + "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==", + "dev": true + }, "node_modules/@playwright/test": { - "version": "1.36.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.36.0.tgz", - "integrity": "sha512-yN+fvMYtiyLFDCQos+lWzoX4XW3DNuaxjBu68G0lkgLgC6BP+m/iTxJQoSicz/x2G5EsrqlZTqTIP9sTgLQerg==", + "version": "1.36.2", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.36.2.tgz", + "integrity": "sha512-2rVZeyPRjxfPH6J0oGJqE8YxiM1IBRyM8hyrXYK7eSiAqmbNhxwcLa7dZ7fy9Kj26V7FYia5fh9XJRq4Dqme+g==", "dev": true, "dependencies": { "@types/node": "*", - "playwright-core": "1.36.0" + "playwright-core": "1.36.2" }, "bin": { "playwright": "cli.js" @@ -414,9 +782,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.4.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.2.tgz", - "integrity": "sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==", + "version": "20.4.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.10.tgz", + "integrity": "sha512-vwzFiiy8Rn6E0MtA13/Cxxgpan/N6UeNYR9oUu6kuJWxu6zCk98trcDp8CBhbtaeuq9SykCmXkFr2lWLoPcvLg==", "dev": true }, "node_modules/@types/semver": { @@ -633,13 +1001,13 @@ } }, "node_modules/@vitest/expect": { - "version": "0.32.4", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.32.4.tgz", - "integrity": "sha512-m7EPUqmGIwIeoU763N+ivkFjTzbaBn0n9evsTOcde03ugy2avPs3kZbYmw3DkcH1j5mxhMhdamJkLQ6dM1bk/A==", + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.1.tgz", + "integrity": "sha512-q2CD8+XIsQ+tHwypnoCk8Mnv5e6afLFvinVGCq3/BOT4kQdVQmY6rRfyKkwcg635lbliLPqbunXZr+L1ssUWiQ==", "dev": true, "dependencies": { - "@vitest/spy": "0.32.4", - "@vitest/utils": "0.32.4", + "@vitest/spy": "0.34.1", + "@vitest/utils": "0.34.1", "chai": "^4.3.7" }, "funding": { @@ -647,12 +1015,12 @@ } }, "node_modules/@vitest/runner": { - "version": "0.32.4", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.32.4.tgz", - "integrity": "sha512-cHOVCkiRazobgdKLnczmz2oaKK9GJOw6ZyRcaPdssO1ej+wzHVIkWiCiNacb3TTYPdzMddYkCgMjZ4r8C0JFCw==", + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.34.1.tgz", + "integrity": "sha512-YfQMpYzDsYB7yqgmlxZ06NI4LurHWfrH7Wy3Pvf/z/vwUSgq1zLAb1lWcItCzQG+NVox+VvzlKQrYEXb47645g==", "dev": true, "dependencies": { - "@vitest/utils": "0.32.4", + "@vitest/utils": "0.34.1", "p-limit": "^4.0.0", "pathe": "^1.1.1" }, @@ -688,12 +1056,12 @@ } }, "node_modules/@vitest/snapshot": { - "version": "0.32.4", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.32.4.tgz", - "integrity": "sha512-IRpyqn9t14uqsFlVI2d7DFMImGMs1Q9218of40bdQQgMePwVdmix33yMNnebXcTzDU5eiV3eUsoxxH5v0x/IQA==", + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.34.1.tgz", + "integrity": "sha512-0O9LfLU0114OqdF8lENlrLsnn024Tb1CsS9UwG0YMWY2oGTQfPtkW+B/7ieyv0X9R2Oijhi3caB1xgGgEgclSQ==", "dev": true, "dependencies": { - "magic-string": "^0.30.0", + "magic-string": "^0.30.1", "pathe": "^1.1.1", "pretty-format": "^29.5.0" }, @@ -702,9 +1070,9 @@ } }, "node_modules/@vitest/spy": { - "version": "0.32.4", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.32.4.tgz", - "integrity": "sha512-oA7rCOqVOOpE6rEoXuCOADX7Lla1LIa4hljI2MSccbpec54q+oifhziZIJXxlE/CvI2E+ElhBHzVu0VEvJGQKQ==", + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.34.1.tgz", + "integrity": "sha512-UT4WcI3EAPUNO8n6y9QoEqynGGEPmmRxC+cLzneFFXpmacivjHZsNbiKD88KUScv5DCHVDgdBsLD7O7s1enFcQ==", "dev": true, "dependencies": { "tinyspy": "^2.1.1" @@ -714,9 +1082,9 @@ } }, "node_modules/@vitest/utils": { - "version": "0.32.4", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.32.4.tgz", - "integrity": "sha512-Gwnl8dhd1uJ+HXrYyV0eRqfmk9ek1ASE/LWfTCuWMw+d07ogHqp4hEAV28NiecimK6UY9DpSEPh+pXBA5gtTBg==", + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.1.tgz", + "integrity": "sha512-/ql9dsFi4iuEbiNcjNHQWXBum7aL8pyhxvfnD9gNtbjR9fUKAjxhj4AA3yfLXg6gJpMGGecvtF8Au2G9y3q47Q==", "dev": true, "dependencies": { "diff-sequences": "^29.4.3", @@ -728,30 +1096,30 @@ } }, "node_modules/@volar/language-core": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.9.0.tgz", - "integrity": "sha512-+PTRrGanAD2PxqMty0ZC46xhgW5BWzb67RLHhZyB3Im4+eMXsKlYjFUt7Z8ZCwTWQQOnj8NQ6gSgUEoOTwAHrQ==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.10.0.tgz", + "integrity": "sha512-ddyWwSYqcbEZNFHm+Z3NZd6M7Ihjcwl/9B5cZd8kECdimVXUFdFi60XHWD27nrWtUQIsUYIG7Ca1WBwV2u2LSQ==", "dev": true, "dependencies": { - "@volar/source-map": "1.9.0" + "@volar/source-map": "1.10.0" } }, "node_modules/@volar/source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.9.0.tgz", - "integrity": "sha512-TQWLY8ozUOHBHTMC2pHZsNbtM25Q9QCEwAL8JFR/gmR9Yv0d9qup/gQdd5sDI7RmoPYKD+gqjLrbM4Ib41QSJQ==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.10.0.tgz", + "integrity": "sha512-/ibWdcOzDGiq/GM1JU2eX8fH1bvAhl66hfe8yEgLEzg9txgr6qb5sQ/DEz5PcDL75tF5H5sCRRwn8Eu8ezi9mw==", "dev": true, "dependencies": { "muggle-string": "^0.3.1" } }, "node_modules/@volar/typescript": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.9.0.tgz", - "integrity": "sha512-B8X4/H6V93uD7zu5VCw05eB0Ukcc39SFKsZoeylkAk2sJ50oaJLpajnQ8Ov4c+FnVQ6iPA6Xy1qdWoWJjh6xEg==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.10.0.tgz", + "integrity": "sha512-OtqGtFbUKYC0pLNIk3mHQp5xWnvL1CJIUc9VE39VdZ/oqpoBh5jKfb9uJ45Y4/oP/WYTrif/Uxl1k8VTPz66Gg==", "dev": true, "dependencies": { - "@volar/language-core": "1.9.0" + "@volar/language-core": "1.10.0" } }, "node_modules/@vue/compiler-core": { @@ -806,17 +1174,17 @@ "integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==" }, "node_modules/@vue/eslint-config-prettier": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@vue/eslint-config-prettier/-/eslint-config-prettier-7.1.0.tgz", - "integrity": "sha512-Pv/lVr0bAzSIHLd9iz0KnvAr4GKyCEl+h52bc4e5yWuDVtLgFwycF7nrbWTAQAS+FU6q1geVd07lc6EWfJiWKQ==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@vue/eslint-config-prettier/-/eslint-config-prettier-8.0.0.tgz", + "integrity": "sha512-55dPqtC4PM/yBjhAr+yEw6+7KzzdkBuLmnhBrDfp4I48+wy+Giqqj9yUr5T2uD/BkBROjjmqnLZmXRdOx/VtQg==", "dev": true, "dependencies": { - "eslint-config-prettier": "^8.3.0", - "eslint-plugin-prettier": "^4.0.0" + "eslint-config-prettier": "^8.8.0", + "eslint-plugin-prettier": "^5.0.0" }, "peerDependencies": { - "eslint": ">= 7.28.0", - "prettier": ">= 2.0.0" + "eslint": ">= 8.0.0", + "prettier": ">= 3.0.0" } }, "node_modules/@vue/eslint-config-typescript": { @@ -844,13 +1212,13 @@ } }, "node_modules/@vue/language-core": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-1.8.5.tgz", - "integrity": "sha512-DKQNiNQzNV7nrkZQujvjfX73zqKdj2+KoM4YeKl+ft3f+crO3JB4ycPnmgaRMNX/ULJootdQPGHKFRl5cXxwaw==", + "version": "1.8.8", + "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-1.8.8.tgz", + "integrity": "sha512-i4KMTuPazf48yMdYoebTkgSOJdFraE4pQf0B+FTOFkbB+6hAfjrSou/UmYWRsWyZV6r4Rc6DDZdI39CJwL0rWw==", "dev": true, "dependencies": { - "@volar/language-core": "~1.9.0", - "@volar/source-map": "~1.9.0", + "@volar/language-core": "~1.10.0", + "@volar/source-map": "~1.10.0", "@vue/compiler-dom": "^3.3.0", "@vue/reactivity": "^3.3.0", "@vue/shared": "^3.3.0", @@ -948,23 +1316,19 @@ "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==" }, "node_modules/@vue/test-utils": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@vue/test-utils/-/test-utils-2.4.0.tgz", - "integrity": "sha512-BKB9aj1yky63/I3IwSr1FjUeHYsKXI7D6S9F378AHt7a5vC0dLkOBtSsFXoRGC/7BfHmiB9HRhT+i9xrUHoAKw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@vue/test-utils/-/test-utils-2.4.1.tgz", + "integrity": "sha512-VO8nragneNzUZUah6kOjiFmD/gwRjUauG9DROh6oaOeFwX1cZRUNHhdeogE8635cISigXFTtGLUQWx5KCb0xeg==", "dev": true, "dependencies": { - "js-beautify": "1.14.6", - "vue-component-type-helpers": "1.6.5" + "js-beautify": "1.14.9", + "vue-component-type-helpers": "1.8.4" }, "peerDependencies": { - "@vue/compiler-dom": "^3.0.1", "@vue/server-renderer": "^3.0.1", "vue": "^3.0.1" }, "peerDependenciesMeta": { - "@vue/compiler-dom": { - "optional": true - }, "@vue/server-renderer": { "optional": true } @@ -977,13 +1341,13 @@ "dev": true }, "node_modules/@vue/typescript": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@vue/typescript/-/typescript-1.8.5.tgz", - "integrity": "sha512-domFBbNr3PEcjGBeB+cmgUM3cI6pJsJezguIUKZ1rphkfIkICyoMjCd3TitoP32yo2KABLiaXcGFzgFfQf6B3w==", + "version": "1.8.8", + "resolved": "https://registry.npmjs.org/@vue/typescript/-/typescript-1.8.8.tgz", + "integrity": "sha512-jUnmMB6egu5wl342eaUH236v8tdcEPXXkPgj+eI/F6JwW/lb+yAU6U07ZbQ3MVabZRlupIlPESB7ajgAGixhow==", "dev": true, "dependencies": { - "@volar/typescript": "~1.9.0", - "@vue/language-core": "1.8.5" + "@volar/typescript": "~1.10.0", + "@vue/language-core": "1.8.8" } }, "node_modules/abab": { @@ -1248,6 +1612,15 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/big-integer": { + "version": "1.6.51", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -1263,6 +1636,18 @@ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", "dev": true }, + "node_modules/bplist-parser": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", + "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==", + "dev": true, + "dependencies": { + "big-integer": "^1.6.44" + }, + "engines": { + "node": ">= 5.10.0" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1317,6 +1702,21 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/bundle-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", + "integrity": "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==", + "dev": true, + "dependencies": { + "run-applescript": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -1546,10 +1946,13 @@ } }, "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } }, "node_modules/concat-map": { "version": "0.0.1", @@ -1676,6 +2079,52 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/default-browser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz", + "integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==", + "dev": true, + "dependencies": { + "bundle-name": "^3.0.0", + "default-browser-id": "^3.0.0", + "execa": "^7.1.1", + "titleize": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz", + "integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==", + "dev": true, + "dependencies": { + "bplist-parser": "^0.2.0", + "untildify": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/define-properties": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", @@ -1765,27 +2214,45 @@ "dev": true }, "node_modules/editorconfig": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", - "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz", + "integrity": "sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==", "dev": true, "dependencies": { - "commander": "^2.19.0", - "lru-cache": "^4.1.5", - "semver": "^5.6.0", - "sigmund": "^1.0.1" + "@one-ini/wasm": "0.1.1", + "commander": "^10.0.0", + "minimatch": "9.0.1", + "semver": "^7.5.3" }, "bin": { "editorconfig": "bin/editorconfig" + }, + "engines": { + "node": ">=14" } }, - "node_modules/editorconfig/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "node_modules/editorconfig/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "bin": { - "semver": "bin/semver" + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/editorconfig/node_modules/minimatch": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", + "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/electron-to-chromium": { @@ -1901,9 +2368,9 @@ } }, "node_modules/esbuild": { - "version": "0.17.14", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.14.tgz", - "integrity": "sha512-vOO5XhmVj/1XQR9NQ1UPq6qvMYL7QFJU57J5fKBKBKxp17uDt5PgxFDb4A2nEiXhr1qQs4x0F5+66hVVw4ruNw==", + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.14.tgz", + "integrity": "sha512-uNPj5oHPYmj+ZhSQeYQVFZ+hAlJZbAGOmmILWIqrGvPVlNLbyOvU5Bu6Woi8G8nskcx0vwY0iFoMPrzT86Ko+w==", "dev": true, "hasInstallScript": true, "bin": { @@ -1913,28 +2380,28 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.17.14", - "@esbuild/android-arm64": "0.17.14", - "@esbuild/android-x64": "0.17.14", - "@esbuild/darwin-arm64": "0.17.14", - "@esbuild/darwin-x64": "0.17.14", - "@esbuild/freebsd-arm64": "0.17.14", - "@esbuild/freebsd-x64": "0.17.14", - "@esbuild/linux-arm": "0.17.14", - "@esbuild/linux-arm64": "0.17.14", - "@esbuild/linux-ia32": "0.17.14", - "@esbuild/linux-loong64": "0.17.14", - "@esbuild/linux-mips64el": "0.17.14", - "@esbuild/linux-ppc64": "0.17.14", - "@esbuild/linux-riscv64": "0.17.14", - "@esbuild/linux-s390x": "0.17.14", - "@esbuild/linux-x64": "0.17.14", - "@esbuild/netbsd-x64": "0.17.14", - "@esbuild/openbsd-x64": "0.17.14", - "@esbuild/sunos-x64": "0.17.14", - "@esbuild/win32-arm64": "0.17.14", - "@esbuild/win32-ia32": "0.17.14", - "@esbuild/win32-x64": "0.17.14" + "@esbuild/android-arm": "0.18.14", + "@esbuild/android-arm64": "0.18.14", + "@esbuild/android-x64": "0.18.14", + "@esbuild/darwin-arm64": "0.18.14", + "@esbuild/darwin-x64": "0.18.14", + "@esbuild/freebsd-arm64": "0.18.14", + "@esbuild/freebsd-x64": "0.18.14", + "@esbuild/linux-arm": "0.18.14", + "@esbuild/linux-arm64": "0.18.14", + "@esbuild/linux-ia32": "0.18.14", + "@esbuild/linux-loong64": "0.18.14", + "@esbuild/linux-mips64el": "0.18.14", + "@esbuild/linux-ppc64": "0.18.14", + "@esbuild/linux-riscv64": "0.18.14", + "@esbuild/linux-s390x": "0.18.14", + "@esbuild/linux-x64": "0.18.14", + "@esbuild/netbsd-x64": "0.18.14", + "@esbuild/openbsd-x64": "0.18.14", + "@esbuild/sunos-x64": "0.18.14", + "@esbuild/win32-arm64": "0.18.14", + "@esbuild/win32-ia32": "0.18.14", + "@esbuild/win32-x64": "0.18.14" } }, "node_modules/escalade": { @@ -2025,21 +2492,29 @@ } }, "node_modules/eslint-plugin-prettier": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", - "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.0.tgz", + "integrity": "sha512-AgaZCVuYDXHUGxj/ZGu1u8H8CYgDY3iG6w5kUFw4AzMVXzB7VvbKgYR4nATIN+OvUrghMbiDLeimVjVY5ilq3w==", "dev": true, "dependencies": { - "prettier-linter-helpers": "^1.0.0" + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.8.5" }, "engines": { - "node": ">=12.0.0" + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/prettier" }, "peerDependencies": { - "eslint": ">=7.28.0", - "prettier": ">=2.0.0" + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "prettier": ">=3.0.0" }, "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, "eslint-config-prettier": { "optional": true } @@ -2228,15 +2703,15 @@ "dev": true }, "node_modules/fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", "dev": true }, "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -2983,6 +3458,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -3016,6 +3506,24 @@ "node": ">=0.10.0" } }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -3168,6 +3676,33 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-wsl/node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -3189,14 +3724,14 @@ } }, "node_modules/js-beautify": { - "version": "1.14.6", - "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.14.6.tgz", - "integrity": "sha512-GfofQY5zDp+cuHc+gsEXKPpNw2KbPddreEo35O6jT6i0RVK6LhsoYBhq5TvK4/n74wnA0QbK8gGd+jUZwTMKJw==", + "version": "1.14.9", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.14.9.tgz", + "integrity": "sha512-coM7xq1syLcMyuVGyToxcj2AlzhkDjmfklL8r0JgJ7A76wyGMpJ1oA35mr4APdYNO/o/4YY8H54NQIJzhMbhBg==", "dev": true, "dependencies": { "config-chain": "^1.1.13", - "editorconfig": "^0.15.3", - "glob": "^8.0.3", + "editorconfig": "^1.0.3", + "glob": "^8.1.0", "nopt": "^6.0.0" }, "bin": { @@ -3205,7 +3740,7 @@ "js-beautify": "js/bin/js-beautify.js" }, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/js-yaml": { @@ -3375,15 +3910,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/lint-staged/node_modules/commander": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.0.tgz", - "integrity": "sha512-zS5PnTI22FIRM6ylNW8G4Ap0IEOyk62fhLSD0+uHRT9McRCLGpkVNvao4bjimpK/GShynyQkFFxHhwMcETmduA==", - "dev": true, - "engines": { - "node": ">=14" - } - }, "node_modules/lint-staged/node_modules/pidtree": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", @@ -3628,22 +4154,12 @@ "get-func-name": "^2.0.0" } }, - "node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, "node_modules/magic-string": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz", - "integrity": "sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==", + "version": "0.30.2", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.2.tgz", + "integrity": "sha512-lNZdu7pewtq/ZvWUp9Wpf/x7WzMTsR26TWV03BRZrXFsv+BI6dy8RAiKgm1uM/kyR0rCfUcqvOlXKG66KhIGug==", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.13" + "@jridgewell/sourcemap-codec": "^1.4.15" }, "engines": { "node": ">=12" @@ -4152,6 +4668,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/open": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz", + "integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==", + "dev": true, + "dependencies": { + "default-browser": "^4.0.0", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -4352,9 +4886,9 @@ } }, "node_modules/pinia": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.1.4.tgz", - "integrity": "sha512-vYlnDu+Y/FXxv1ABo1vhjC+IbqvzUdiUC3sfDRrRyY2CQSrqqaa+iiHmqtARFxJVqWQMCJfXx1PBvFs9aJVLXQ==", + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.1.6.tgz", + "integrity": "sha512-bIU6QuE5qZviMmct5XwCesXelb5VavdOWKWaB17ggk++NUwQWWbP5YnsONTk3b752QkW9sACiR81rorpeOMSvQ==", "dependencies": { "@vue/devtools-api": "^6.5.0", "vue-demi": ">=0.14.5" @@ -4422,9 +4956,9 @@ } }, "node_modules/playwright-core": { - "version": "1.36.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.36.0.tgz", - "integrity": "sha512-7RTr8P6YJPAqB+8j5ATGHqD6LvLLM39sYVNsslh78g8QeLcBs5750c6+msjrHUwwGt+kEbczBj1XB22WMwn+WA==", + "version": "1.36.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.36.2.tgz", + "integrity": "sha512-sQYZt31dwkqxOrP7xy2ggDfEzUxM1lodjhsQ3NMMv5uGTRDsLxU0e4xf4wwMkF2gplIxf17QMBCodSFgm6bFVQ==", "dev": true, "bin": { "playwright-core": "cli.js" @@ -4434,9 +4968,9 @@ } }, "node_modules/postcss": { - "version": "8.4.26", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.26.tgz", - "integrity": "sha512-jrXHFF8iTloAenySjM/ob3gSj7pCu0Ji49hnjqzsgSRa50hkWCKD0HQ+gMNJkW38jBI68MpAAg7ZWwHwX8NMMw==", + "version": "8.4.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz", + "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==", "funding": [ { "type": "opencollective", @@ -4600,9 +5134,9 @@ } }, "node_modules/pretty-format": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.0.tgz", - "integrity": "sha512-XH+D4n7Ey0iSR6PdAnBs99cWMZdGsdKrR33iUHQNr79w1szKTCIZDVdXuccAsHVwDBp0XeWPfNEoaxP9EZgRmQ==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.2.tgz", + "integrity": "sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg==", "dev": true, "dependencies": { "@jest/schemas": "^29.6.0", @@ -4636,12 +5170,6 @@ "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", "dev": true }, - "node_modules/pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", - "dev": true - }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", @@ -4897,9 +5425,9 @@ } }, "node_modules/rollup": { - "version": "3.21.6", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.21.6.tgz", - "integrity": "sha512-SXIICxvxQxR3D4dp/3LDHZIJPC8a4anKMHd4E3Jiz2/JnY+2bEjqrOokAauc5ShGVNFHlEFjBXAXlaxkJqIqSg==", + "version": "3.26.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.26.3.tgz", + "integrity": "sha512-7Tin0C8l86TkpcMtXvQu6saWH93nhG3dGQ1/+l5V2TDMceTxO7kDiK6GzbfLWNNxqJXm591PcEZUozZm51ogwQ==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -4918,6 +5446,110 @@ "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", "dev": true }, + "node_modules/run-applescript": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", + "integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==", + "dev": true, + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-applescript/node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/run-applescript/node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/run-applescript/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-applescript/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/run-applescript/node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/run-applescript/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-applescript/node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -4994,9 +5626,9 @@ } }, "node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -5081,12 +5713,6 @@ "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true }, - "node_modules/sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha512-fCvEXfh6NWpm+YSuY2bpXb/VIihqWA6hLsgboC+0nl71Q7N7o2eaCW8mJa/NLvQhs6jpd3VZV4UiUQlV6+lc8g==", - "dev": true - }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -5451,6 +6077,28 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, + "node_modules/synckit": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz", + "integrity": "sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==", + "dev": true, + "dependencies": { + "@pkgr/utils": "^2.3.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/synckit/node_modules/tslib": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", + "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==", + "dev": true + }, "node_modules/tailwindcss": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.3.tgz", @@ -5528,9 +6176,9 @@ "dev": true }, "node_modules/tinypool": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.5.0.tgz", - "integrity": "sha512-paHQtnrlS1QZYKF/GnLoOM/DN9fqaGOFbCbxzAhwniySnzl9Ebk8w73/dd34DAhe/obUbPAOldTyYXQZxnPBPQ==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.7.0.tgz", + "integrity": "sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==", "dev": true, "engines": { "node": ">=14.0.0" @@ -5545,6 +6193,18 @@ "node": ">=14.0.0" } }, + "node_modules/titleize": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz", + "integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -5672,9 +6332,9 @@ } }, "node_modules/ufo": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.1.2.tgz", - "integrity": "sha512-TrY6DsjTQQgyS3E3dBaOXf0TpPD8u9FVrVYmKVegJuFw51n/YB9XPt+U6ydzFG5ZIN7+DIjPbNmXoBj9esYhgQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.2.0.tgz", + "integrity": "sha512-RsPyTbqORDNDxqAdQPQBpgqhWle1VcTSou/FraClYlHf6TZnQcGslpLcAphNR+sQW4q5lLWLbOsRlh9j24baQg==", "dev": true }, "node_modules/unbox-primitive": { @@ -5701,6 +6361,15 @@ "node": ">= 4.0.0" } }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/update-browserslist-db": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", @@ -5766,14 +6435,14 @@ } }, "node_modules/vite": { - "version": "4.3.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz", - "integrity": "sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==", + "version": "4.4.8", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.8.tgz", + "integrity": "sha512-LONawOUUjxQridNWGQlNizfKH89qPigK36XhMI7COMGztz8KNY0JHim7/xDd71CZwGT4HtSRgI7Hy+RlhG0Gvg==", "dev": true, "dependencies": { - "esbuild": "^0.17.5", - "postcss": "^8.4.23", - "rollup": "^3.21.0" + "esbuild": "^0.18.10", + "postcss": "^8.4.26", + "rollup": "^3.25.2" }, "bin": { "vite": "bin/vite.js" @@ -5781,12 +6450,16 @@ "engines": { "node": "^14.18.0 || >=16.0.0" }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@types/node": ">= 14", "less": "*", + "lightningcss": "^1.21.0", "sass": "*", "stylus": "*", "sugarss": "*", @@ -5799,6 +6472,9 @@ "less": { "optional": true }, + "lightningcss": { + "optional": true + }, "sass": { "optional": true }, @@ -5814,9 +6490,9 @@ } }, "node_modules/vite-node": { - "version": "0.32.4", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.32.4.tgz", - "integrity": "sha512-L2gIw+dCxO0LK14QnUMoqSYpa9XRGnTTTDjW2h19Mr+GR0EFj4vx52W41gFXfMLqpA00eK4ZjOVYo1Xk//LFEw==", + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.34.1.tgz", + "integrity": "sha512-odAZAL9xFMuAg8aWd7nSPT+hU8u2r9gU3LRm9QKjxBEF2rRdWpMuqkrkjvyVQEdNFiBctqr2Gg4uJYizm5Le6w==", "dev": true, "dependencies": { "cac": "^6.7.14", @@ -5837,34 +6513,34 @@ } }, "node_modules/vitest": { - "version": "0.32.4", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.32.4.tgz", - "integrity": "sha512-3czFm8RnrsWwIzVDu/Ca48Y/M+qh3vOnF16czJm98Q/AN1y3B6PBsyV8Re91Ty5s7txKNjEhpgtGPcfdbh2MZg==", + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.34.1.tgz", + "integrity": "sha512-G1PzuBEq9A75XSU88yO5G4vPT20UovbC/2osB2KEuV/FisSIIsw7m5y2xMdB7RsAGHAfg2lPmp2qKr3KWliVlQ==", "dev": true, "dependencies": { "@types/chai": "^4.3.5", "@types/chai-subset": "^1.3.3", "@types/node": "*", - "@vitest/expect": "0.32.4", - "@vitest/runner": "0.32.4", - "@vitest/snapshot": "0.32.4", - "@vitest/spy": "0.32.4", - "@vitest/utils": "0.32.4", + "@vitest/expect": "0.34.1", + "@vitest/runner": "0.34.1", + "@vitest/snapshot": "0.34.1", + "@vitest/spy": "0.34.1", + "@vitest/utils": "0.34.1", "acorn": "^8.9.0", "acorn-walk": "^8.2.0", "cac": "^6.7.14", "chai": "^4.3.7", "debug": "^4.3.4", "local-pkg": "^0.4.3", - "magic-string": "^0.30.0", + "magic-string": "^0.30.1", "pathe": "^1.1.1", "picocolors": "^1.0.0", "std-env": "^3.3.3", "strip-literal": "^1.0.1", "tinybench": "^2.5.0", - "tinypool": "^0.5.0", + "tinypool": "^0.7.0", "vite": "^3.0.0 || ^4.0.0", - "vite-node": "0.32.4", + "vite-node": "0.34.1", "why-is-node-running": "^2.2.2" }, "bin": { @@ -5941,9 +6617,9 @@ } }, "node_modules/vue-component-type-helpers": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-1.6.5.tgz", - "integrity": "sha512-iGdlqtajmiqed8ptURKPJ/Olz0/mwripVZszg6tygfZSIL9kYFPJTNY6+Q6OjWGznl2L06vxG5HvNvAnWrnzbg==", + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-1.8.4.tgz", + "integrity": "sha512-6bnLkn8O0JJyiFSIF0EfCogzeqNXpnjJ0vW/SZzNHfe6sPx30lTtTXlE5TFs2qhJlAtDFybStVNpL73cPe3OMQ==", "dev": true }, "node_modules/vue-draggable-next": { @@ -6042,13 +6718,13 @@ } }, "node_modules/vue-tsc": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.8.5.tgz", - "integrity": "sha512-Jr8PTghJIwp69MFsEZoADDcv2l+lXA8juyN/5AYA5zxyZNvIHjSbgKgkYIYc1qnihrOyIG1VOnfk4ZE0jqn8bw==", + "version": "1.8.8", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.8.8.tgz", + "integrity": "sha512-bSydNFQsF7AMvwWsRXD7cBIXaNs/KSjvzWLymq/UtKE36697sboX4EccSHFVxvgdBlI1frYPc/VMKJNB7DFeDQ==", "dev": true, "dependencies": { - "@vue/language-core": "1.8.5", - "@vue/typescript": "1.8.5", + "@vue/language-core": "1.8.8", + "@vue/typescript": "1.8.8", "semver": "^7.3.8" }, "bin": { @@ -6281,12 +6957,6 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, - "node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", - "dev": true - }, "node_modules/yaml": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.2.2.tgz", diff --git a/report-viewer/package.json b/report-viewer/package.json index dd8c1d713..081a25dee 100644 --- a/report-viewer/package.json +++ b/report-viewer/package.json @@ -17,15 +17,15 @@ "prepare": "cd .. && husky install report-viewer/.husky" }, "dependencies": { - "@fortawesome/fontawesome-svg-core": "^6.4.0", - "@fortawesome/free-regular-svg-icons": "^6.4.0", - "@fortawesome/free-solid-svg-icons": "^6.4.0", + "@fortawesome/fontawesome-svg-core": "^6.4.2", + "@fortawesome/free-regular-svg-icons": "^6.4.2", + "@fortawesome/free-solid-svg-icons": "^6.4.2", "@fortawesome/vue-fontawesome": "^3.0.3", "chart.js": "^3.9.1", "chartjs-plugin-datalabels": "^2.2.0", "highlight.js": "^11.8.0", "jszip": "^3.10.0", - "pinia": "^2.1.4", + "pinia": "^2.1.6", "slash": "^5.1.0", "vue": "^3.3.4", "vue-chart-3": "^3.1.8", @@ -34,14 +34,14 @@ "vue-virtual-scroller": "^2.0.0-beta.8" }, "devDependencies": { - "@playwright/test": "^1.36.0", + "@playwright/test": "^1.36.2", "@rushstack/eslint-patch": "^1.3.2", "@types/jsdom": "^21.1.0", - "@types/node": "^20.4.2", + "@types/node": "^20.4.10", "@vitejs/plugin-vue": "^4.2.3", - "@vue/eslint-config-prettier": "^7.1.0", + "@vue/eslint-config-prettier": "^8.0.0", "@vue/eslint-config-typescript": "^11.0.3", - "@vue/test-utils": "^2.4.0", + "@vue/test-utils": "^2.4.1", "@vue/tsconfig": "^0.4.0", "autoprefixer": "^10.4.14", "eslint": "^8.45.0", @@ -50,12 +50,12 @@ "jsdom": "^22.1.0", "lint-staged": "^13.2.3", "npm-run-all": "^4.1.5", - "postcss": "^8.4.26", + "postcss": "^8.4.27", "prettier": "^3.0.0", "tailwindcss": "^3.3.3", "typescript": "^5.1.6", - "vite": "^4.3.9", - "vitest": "^0.32.4", - "vue-tsc": "^1.8.5" + "vite": "^4.4.8", + "vitest": "^0.34.1", + "vue-tsc": "^1.8.8" } } diff --git a/report-viewer/vitest.config.ts b/report-viewer/vitest.config.ts index 23da12e5c..1a9b1be61 100644 --- a/report-viewer/vitest.config.ts +++ b/report-viewer/vitest.config.ts @@ -1,15 +1,10 @@ import { fileURLToPath } from 'node:url' -import { mergeConfig } from 'vite' import { configDefaults, defineConfig } from 'vitest/config' -import viteConfig from './vite.config' -export default mergeConfig( - viteConfig, - defineConfig({ - test: { - environment: 'jsdom', - exclude: [...configDefaults.exclude, 'tests/e2e/*'], - root: fileURLToPath(new URL('./', import.meta.url)) - } - }) -) +export default defineConfig({ + test: { + environment: 'jsdom', + exclude: [...configDefaults.exclude, 'tests/e2e/*'], + root: fileURLToPath(new URL('./', import.meta.url)) + } +})