diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 000000000..2e88f37d9
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,6 @@
+
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index eb8a03695..2d3fc57dd 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -1,20 +1,19 @@
-name: Deploy to Maven Central
+name: Deploy to Maven Central & GitHub
on:
workflow_dispatch:
release:
types: [created]
jobs:
- publish:
+ publish-maven-central:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- - name: Set up Maven Central Repository
- uses: actions/setup-java@v3
+ - uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Set maven settings.xml
- uses: whelk-io/maven-settings-xml-action@v20
+ uses: whelk-io/maven-settings-xml-action@v21
with:
servers: '[{ "id": "ossrh", "username": "jplag", "password": "${{ secrets.OSSRH_TOKEN }}" }]'
- name: Import GPG key
@@ -26,3 +25,21 @@ jobs:
run: mvn -P deployment -U -B deploy
env:
GPG_PASSPHRASE: ${{ secrets.PGP_PW }}
+
+ publish-release-artifact:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-java@v3
+ with:
+ java-version: '17'
+ distribution: 'temurin'
+ - name: Build JPlag
+ run: mvn -U -B clean package assembly:single
+
+ - name: Attach CLI to Release on GitHub
+ uses: softprops/action-gh-release@v1
+ if: startsWith(github.ref, 'refs/tags/')
+ with:
+ files: jplag.cli/target/jplag-*-jar-with-dependencies.jar
+ fail_on_unmatched_files: true
diff --git a/cli/pom.xml b/cli/pom.xml
index c455f5b6b..12105b8e4 100644
--- a/cli/pom.xml
+++ b/cli/pom.xml
@@ -8,6 +8,8 @@
cli
+
+
de.jplag
jplag
@@ -103,7 +105,7 @@
- de.jplag.CLI
+ de.jplag.cli.CLI
jplag
@@ -117,7 +119,7 @@
- de.jplag.CLI
+ de.jplag.cli.CLI
jplag
true
true
@@ -126,19 +128,6 @@
jplag-${project.version}
-
- org.jacoco
- jacoco-maven-plugin
-
-
- report-aggregate
-
- report-aggregate
-
- verify
-
-
-
diff --git a/cli/src/main/java/de/jplag/CLI.java b/cli/src/main/java/de/jplag/cli/CLI.java
similarity index 83%
rename from cli/src/main/java/de/jplag/CLI.java
rename to cli/src/main/java/de/jplag/cli/CLI.java
index f53292fe1..4fdeac90f 100644
--- a/cli/src/main/java/de/jplag/CLI.java
+++ b/cli/src/main/java/de/jplag/cli/CLI.java
@@ -1,32 +1,32 @@
-package de.jplag;
-
-import static de.jplag.CommandLineArgument.BASE_CODE;
-import static de.jplag.CommandLineArgument.CLUSTER_AGGLOMERATIVE_INTER_CLUSTER_SIMILARITY;
-import static de.jplag.CommandLineArgument.CLUSTER_AGGLOMERATIVE_THRESHOLD;
-import static de.jplag.CommandLineArgument.CLUSTER_ALGORITHM;
-import static de.jplag.CommandLineArgument.CLUSTER_DISABLE;
-import static de.jplag.CommandLineArgument.CLUSTER_METRIC;
-import static de.jplag.CommandLineArgument.CLUSTER_PREPROCESSING_CDF;
-import static de.jplag.CommandLineArgument.CLUSTER_PREPROCESSING_NONE;
-import static de.jplag.CommandLineArgument.CLUSTER_PREPROCESSING_PERCENTILE;
-import static de.jplag.CommandLineArgument.CLUSTER_PREPROCESSING_THRESHOLD;
-import static de.jplag.CommandLineArgument.CLUSTER_SPECTRAL_BANDWIDTH;
-import static de.jplag.CommandLineArgument.CLUSTER_SPECTRAL_KMEANS_ITERATIONS;
-import static de.jplag.CommandLineArgument.CLUSTER_SPECTRAL_MAX_RUNS;
-import static de.jplag.CommandLineArgument.CLUSTER_SPECTRAL_MIN_RUNS;
-import static de.jplag.CommandLineArgument.CLUSTER_SPECTRAL_NOISE;
-import static de.jplag.CommandLineArgument.DEBUG;
-import static de.jplag.CommandLineArgument.EXCLUDE_FILE;
-import static de.jplag.CommandLineArgument.LANGUAGE;
-import static de.jplag.CommandLineArgument.MIN_TOKEN_MATCH;
-import static de.jplag.CommandLineArgument.NEW_DIRECTORY;
-import static de.jplag.CommandLineArgument.OLD_DIRECTORY;
-import static de.jplag.CommandLineArgument.RESULT_FOLDER;
-import static de.jplag.CommandLineArgument.ROOT_DIRECTORY;
-import static de.jplag.CommandLineArgument.SHOWN_COMPARISONS;
-import static de.jplag.CommandLineArgument.SIMILARITY_THRESHOLD;
-import static de.jplag.CommandLineArgument.SUBDIRECTORY;
-import static de.jplag.CommandLineArgument.SUFFIXES;
+package de.jplag.cli;
+
+import static de.jplag.cli.CommandLineArgument.BASE_CODE;
+import static de.jplag.cli.CommandLineArgument.CLUSTER_AGGLOMERATIVE_INTER_CLUSTER_SIMILARITY;
+import static de.jplag.cli.CommandLineArgument.CLUSTER_AGGLOMERATIVE_THRESHOLD;
+import static de.jplag.cli.CommandLineArgument.CLUSTER_ALGORITHM;
+import static de.jplag.cli.CommandLineArgument.CLUSTER_DISABLE;
+import static de.jplag.cli.CommandLineArgument.CLUSTER_METRIC;
+import static de.jplag.cli.CommandLineArgument.CLUSTER_PREPROCESSING_CDF;
+import static de.jplag.cli.CommandLineArgument.CLUSTER_PREPROCESSING_NONE;
+import static de.jplag.cli.CommandLineArgument.CLUSTER_PREPROCESSING_PERCENTILE;
+import static de.jplag.cli.CommandLineArgument.CLUSTER_PREPROCESSING_THRESHOLD;
+import static de.jplag.cli.CommandLineArgument.CLUSTER_SPECTRAL_BANDWIDTH;
+import static de.jplag.cli.CommandLineArgument.CLUSTER_SPECTRAL_KMEANS_ITERATIONS;
+import static de.jplag.cli.CommandLineArgument.CLUSTER_SPECTRAL_MAX_RUNS;
+import static de.jplag.cli.CommandLineArgument.CLUSTER_SPECTRAL_MIN_RUNS;
+import static de.jplag.cli.CommandLineArgument.CLUSTER_SPECTRAL_NOISE;
+import static de.jplag.cli.CommandLineArgument.DEBUG;
+import static de.jplag.cli.CommandLineArgument.EXCLUDE_FILE;
+import static de.jplag.cli.CommandLineArgument.LANGUAGE;
+import static de.jplag.cli.CommandLineArgument.MIN_TOKEN_MATCH;
+import static de.jplag.cli.CommandLineArgument.NEW_DIRECTORY;
+import static de.jplag.cli.CommandLineArgument.OLD_DIRECTORY;
+import static de.jplag.cli.CommandLineArgument.RESULT_FOLDER;
+import static de.jplag.cli.CommandLineArgument.ROOT_DIRECTORY;
+import static de.jplag.cli.CommandLineArgument.SHOWN_COMPARISONS;
+import static de.jplag.cli.CommandLineArgument.SIMILARITY_THRESHOLD;
+import static de.jplag.cli.CommandLineArgument.SUBDIRECTORY;
+import static de.jplag.cli.CommandLineArgument.SUFFIXES;
import java.io.File;
import java.security.SecureRandom;
@@ -45,10 +45,12 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import de.jplag.JPlag;
+import de.jplag.JPlagResult;
+import de.jplag.cli.logger.CollectedLoggerFactory;
import de.jplag.clustering.ClusteringOptions;
import de.jplag.clustering.Preprocessing;
import de.jplag.exceptions.ExitException;
-import de.jplag.logger.CollectedLoggerFactory;
import de.jplag.options.JPlagOptions;
import de.jplag.reporting.reportobject.ReportObjectFactory;
@@ -58,7 +60,7 @@
*/
public final class CLI {
- private static final Logger logger = LoggerFactory.getLogger("JPlag");
+ private static final Logger logger = LoggerFactory.getLogger(CLI.class);
private static final Random RANDOM = new SecureRandom();
diff --git a/cli/src/main/java/de/jplag/CliGroupHelper.java b/cli/src/main/java/de/jplag/cli/CliGroupHelper.java
similarity index 98%
rename from cli/src/main/java/de/jplag/CliGroupHelper.java
rename to cli/src/main/java/de/jplag/cli/CliGroupHelper.java
index c8b0778b5..af801e2bd 100644
--- a/cli/src/main/java/de/jplag/CliGroupHelper.java
+++ b/cli/src/main/java/de/jplag/cli/CliGroupHelper.java
@@ -1,4 +1,4 @@
-package de.jplag;
+package de.jplag.cli;
import java.util.HashMap;
import java.util.Map;
diff --git a/cli/src/main/java/de/jplag/CommandLineArgument.java b/cli/src/main/java/de/jplag/cli/CommandLineArgument.java
similarity index 95%
rename from cli/src/main/java/de/jplag/CommandLineArgument.java
rename to cli/src/main/java/de/jplag/cli/CommandLineArgument.java
index ca0cba910..87ece65ac 100644
--- a/cli/src/main/java/de/jplag/CommandLineArgument.java
+++ b/cli/src/main/java/de/jplag/cli/CommandLineArgument.java
@@ -1,7 +1,7 @@
-package de.jplag;
+package de.jplag.cli;
-import static de.jplag.CLI.ADVANCED_GROUP;
-import static de.jplag.CLI.CLUSTERING_GROUP_NAME;
+import static de.jplag.cli.CLI.ADVANCED_GROUP;
+import static de.jplag.cli.CLI.CLUSTERING_GROUP_NAME;
import static de.jplag.options.JPlagOptions.DEFAULT_SHOWN_COMPARISONS;
import static de.jplag.options.JPlagOptions.DEFAULT_SIMILARITY_THRESHOLD;
import static net.sourceforge.argparse4j.impl.Arguments.append;
@@ -20,6 +20,9 @@
import net.sourceforge.argparse4j.inf.FeatureControl;
import net.sourceforge.argparse4j.inf.Namespace;
+import de.jplag.Language;
+import de.jplag.Messages;
+import de.jplag.NumberOfArgumentValues;
import de.jplag.clustering.ClusteringAlgorithm;
import de.jplag.clustering.ClusteringOptions;
import de.jplag.clustering.algorithm.InterClusterSimilarity;
@@ -34,7 +37,7 @@ public enum CommandLineArgument {
NEW_DIRECTORY(new Builder("-new", String.class).nargs(NumberOfArgumentValues.ONE_OR_MORE_VALUES)),
OLD_DIRECTORY(new Builder("-old", String.class).nargs(NumberOfArgumentValues.ONE_OR_MORE_VALUES)),
LANGUAGE(
- new Builder("-l", String.class).defaultsTo(de.jplag.java.Language.IDENTIFIER)
+ new Builder("-l", String.class).defaultsTo(new de.jplag.java.Language().getIdentifier())
.choices(LanguageLoader.getAllAvailableLanguageIdentifiers())),
BASE_CODE("-bc", String.class),
@@ -82,7 +85,7 @@ public enum CommandLineArgument {
* The identifier of the default {@link Language}.
* @see Language#getIdentifier()
*/
- public static final String DEFAULT_LANGUAGE_IDENTIFIER = de.jplag.java.Language.IDENTIFIER;
+ public static final String DEFAULT_LANGUAGE_IDENTIFIER = new de.jplag.java.Language().getIdentifier();
private final String flag;
private final NumberOfArgumentValues numberOfValues;
@@ -126,7 +129,7 @@ public String flag() {
* @return the flag name of the command line argument without leading dashes and inner dashes replaced with underscores.
*/
public String flagWithoutDash() {
- return flag.replaceAll("^-+", "").replaceAll("-", "_");
+ return flag.replaceAll("^-+", "").replace("-", "_");
}
/**
diff --git a/language-api/src/main/java/de/jplag/LanguageLoader.java b/cli/src/main/java/de/jplag/cli/LanguageLoader.java
similarity index 97%
rename from language-api/src/main/java/de/jplag/LanguageLoader.java
rename to cli/src/main/java/de/jplag/cli/LanguageLoader.java
index 2b4a7e310..77c2de673 100644
--- a/language-api/src/main/java/de/jplag/LanguageLoader.java
+++ b/cli/src/main/java/de/jplag/cli/LanguageLoader.java
@@ -1,4 +1,4 @@
-package de.jplag;
+package de.jplag.cli;
import java.util.Collections;
import java.util.Map;
@@ -11,12 +11,14 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import de.jplag.Language;
+
/**
* This class contains methods to load {@link Language Languages}.
* @author Dominik Fuchss
*/
public final class LanguageLoader {
- private static final Logger logger = LoggerFactory.getLogger("JPlag");
+ private static final Logger logger = LoggerFactory.getLogger(LanguageLoader.class);
private static Map cachedLanguageInstances = null;
diff --git a/cli/src/main/java/de/jplag/logger/CollectedLogger.java b/cli/src/main/java/de/jplag/cli/logger/CollectedLogger.java
similarity index 94%
rename from cli/src/main/java/de/jplag/logger/CollectedLogger.java
rename to cli/src/main/java/de/jplag/cli/logger/CollectedLogger.java
index 62c259fd0..9d21bbcbd 100644
--- a/cli/src/main/java/de/jplag/logger/CollectedLogger.java
+++ b/cli/src/main/java/de/jplag/cli/logger/CollectedLogger.java
@@ -1,4 +1,4 @@
-package de.jplag.logger;
+package de.jplag.cli.logger;
import java.io.PrintStream;
import java.io.Serial;
@@ -27,7 +27,12 @@ public final class CollectedLogger extends MarkerIgnoringBase {
private static final int LOG_LEVEL_WARN = LocationAwareLogger.WARN_INT;
private static final int LOG_LEVEL_ERROR = LocationAwareLogger.ERROR_INT;
- private final int currentLogLevel = LOG_LEVEL_INFO;
+ /**
+ * The default log level that shall be used for external libraries (like Stanford Core NLP)
+ */
+ private static final int LOG_LEVEL_FOR_EXTERNAL_LIBRARIES = LOG_LEVEL_ERROR;
+
+ private static final int CURRENT_LOG_LEVEL = LOG_LEVEL_INFO;
/**
* The short name of this simple log instance
@@ -117,7 +122,11 @@ private String computeShortName() {
}
private boolean isLevelEnabled(int logLevel) {
- return logLevel >= currentLogLevel;
+ return logLevel >= (isJPlagLog() ? CURRENT_LOG_LEVEL : LOG_LEVEL_FOR_EXTERNAL_LIBRARIES);
+ }
+
+ private boolean isJPlagLog() {
+ return this.name.startsWith("de.jplag.");
}
private String renderLevel(int level) {
diff --git a/cli/src/main/java/de/jplag/logger/CollectedLoggerFactory.java b/cli/src/main/java/de/jplag/cli/logger/CollectedLoggerFactory.java
similarity index 97%
rename from cli/src/main/java/de/jplag/logger/CollectedLoggerFactory.java
rename to cli/src/main/java/de/jplag/cli/logger/CollectedLoggerFactory.java
index da2719771..1971e4da9 100644
--- a/cli/src/main/java/de/jplag/logger/CollectedLoggerFactory.java
+++ b/cli/src/main/java/de/jplag/cli/logger/CollectedLoggerFactory.java
@@ -1,4 +1,4 @@
-package de.jplag.logger;
+package de.jplag.cli.logger;
import java.util.ArrayList;
import java.util.List;
diff --git a/cli/src/main/java/de/jplag/logger/CollectedLoggerServiceProvider.java b/cli/src/main/java/de/jplag/cli/logger/CollectedLoggerServiceProvider.java
similarity index 97%
rename from cli/src/main/java/de/jplag/logger/CollectedLoggerServiceProvider.java
rename to cli/src/main/java/de/jplag/cli/logger/CollectedLoggerServiceProvider.java
index 339fdcdab..ba7f053d4 100644
--- a/cli/src/main/java/de/jplag/logger/CollectedLoggerServiceProvider.java
+++ b/cli/src/main/java/de/jplag/cli/logger/CollectedLoggerServiceProvider.java
@@ -1,4 +1,4 @@
-package de.jplag.logger;
+package de.jplag.cli.logger;
import org.kohsuke.MetaInfServices;
import org.slf4j.ILoggerFactory;
diff --git a/cli/src/main/java/de/jplag/logger/Triple.java b/cli/src/main/java/de/jplag/cli/logger/Triple.java
similarity index 68%
rename from cli/src/main/java/de/jplag/logger/Triple.java
rename to cli/src/main/java/de/jplag/cli/logger/Triple.java
index 95ef0eb18..b66aab11b 100644
--- a/cli/src/main/java/de/jplag/logger/Triple.java
+++ b/cli/src/main/java/de/jplag/cli/logger/Triple.java
@@ -1,4 +1,4 @@
-package de.jplag.logger;
+package de.jplag.cli.logger;
public record Triple (A first, B second, C third) {
}
diff --git a/cli/src/test/java/de/jplag/cli/BaseCodeOptionTest.java b/cli/src/test/java/de/jplag/cli/BaseCodeOptionTest.java
index 87d0dde7d..996add653 100644
--- a/cli/src/test/java/de/jplag/cli/BaseCodeOptionTest.java
+++ b/cli/src/test/java/de/jplag/cli/BaseCodeOptionTest.java
@@ -5,8 +5,6 @@
import org.junit.jupiter.api.Test;
-import de.jplag.CommandLineArgument;
-
class BaseCodeOptionTest extends CommandLineInterfaceTest {
private static final String NAME = "BaseCodeName";
diff --git a/cli/src/test/java/de/jplag/cli/ClusteringTest.java b/cli/src/test/java/de/jplag/cli/ClusteringTest.java
index 53c78b53e..11cff50a8 100644
--- a/cli/src/test/java/de/jplag/cli/ClusteringTest.java
+++ b/cli/src/test/java/de/jplag/cli/ClusteringTest.java
@@ -4,7 +4,6 @@
import org.junit.jupiter.api.Test;
-import de.jplag.CommandLineArgument;
import de.jplag.clustering.Preprocessing;
class ClusteringTest extends CommandLineInterfaceTest {
diff --git a/cli/src/test/java/de/jplag/cli/CommandLineInterfaceTest.java b/cli/src/test/java/de/jplag/cli/CommandLineInterfaceTest.java
index e2f2ea69b..ecd47945e 100644
--- a/cli/src/test/java/de/jplag/cli/CommandLineInterfaceTest.java
+++ b/cli/src/test/java/de/jplag/cli/CommandLineInterfaceTest.java
@@ -1,14 +1,12 @@
package de.jplag.cli;
-import static de.jplag.CommandLineArgument.ROOT_DIRECTORY;
+import static de.jplag.cli.CommandLineArgument.ROOT_DIRECTORY;
import static java.util.stream.Collectors.toSet;
import java.util.Arrays;
import net.sourceforge.argparse4j.inf.Namespace;
-import de.jplag.CLI;
-import de.jplag.CommandLineArgument;
import de.jplag.options.JPlagOptions;
/**
diff --git a/cli/src/test/java/de/jplag/cli/LanguageTest.java b/cli/src/test/java/de/jplag/cli/LanguageTest.java
index 8a66e6a56..c79c7e1a5 100644
--- a/cli/src/test/java/de/jplag/cli/LanguageTest.java
+++ b/cli/src/test/java/de/jplag/cli/LanguageTest.java
@@ -9,9 +9,7 @@
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
-import de.jplag.CommandLineArgument;
import de.jplag.Language;
-import de.jplag.LanguageLoader;
class LanguageTest extends CommandLineInterfaceTest {
diff --git a/cli/src/test/java/de/jplag/cli/MinTokenMatchTest.java b/cli/src/test/java/de/jplag/cli/MinTokenMatchTest.java
index 054dd43b4..bedb17026 100644
--- a/cli/src/test/java/de/jplag/cli/MinTokenMatchTest.java
+++ b/cli/src/test/java/de/jplag/cli/MinTokenMatchTest.java
@@ -6,8 +6,6 @@
import org.junit.jupiter.api.Test;
-import de.jplag.CommandLineArgument;
-
class MinTokenMatchTest extends CommandLineInterfaceTest {
@Test
diff --git a/cli/src/test/java/de/jplag/cli/SimiliarityThresholdTest.java b/cli/src/test/java/de/jplag/cli/SimiliarityThresholdTest.java
index 2d9316ca6..ea2870804 100644
--- a/cli/src/test/java/de/jplag/cli/SimiliarityThresholdTest.java
+++ b/cli/src/test/java/de/jplag/cli/SimiliarityThresholdTest.java
@@ -5,7 +5,6 @@
import org.junit.jupiter.api.Test;
-import de.jplag.CommandLineArgument;
import de.jplag.options.JPlagOptions;
class SimiliarityThresholdTest extends CommandLineInterfaceTest {
diff --git a/cli/src/test/java/de/jplag/cli/StoredMatchesTest.java b/cli/src/test/java/de/jplag/cli/StoredMatchesTest.java
index 65800ad2f..9494f02b8 100644
--- a/cli/src/test/java/de/jplag/cli/StoredMatchesTest.java
+++ b/cli/src/test/java/de/jplag/cli/StoredMatchesTest.java
@@ -5,7 +5,6 @@
import org.junit.jupiter.api.Test;
-import de.jplag.CommandLineArgument;
import de.jplag.options.JPlagOptions;
class StoredMatchesTest extends CommandLineInterfaceTest {
diff --git a/core/src/main/java/de/jplag/JPlagResult.java b/core/src/main/java/de/jplag/JPlagResult.java
index a01af55e2..8b4d123d9 100644
--- a/core/src/main/java/de/jplag/JPlagResult.java
+++ b/core/src/main/java/de/jplag/JPlagResult.java
@@ -141,8 +141,7 @@ private int[] calculateDistributionFor(List comparisons, ToDoub
int index = (int) (similarity * SIMILARITY_DISTRIBUTION_SIZE); // divide similarity by bucket size to find index of correct bucket.
index = Math.min(index, SIMILARITY_DISTRIBUTION_SIZE - 1);// index is out of bounds when similarity is 1.0. decrease by one to count
// towards the highest value bucket
- similarityDistribution[SIMILARITY_DISTRIBUTION_SIZE - 1 - index]++; // count comparison towards its determined bucket. bucket order is
- // reversed, so that the highest value bucket has the lowest index
+ similarityDistribution[index]++; // count comparison towards its determined bucket.
}
return similarityDistribution;
}
diff --git a/core/src/main/java/de/jplag/Submission.java b/core/src/main/java/de/jplag/Submission.java
index 65cc80bfb..576af0fbd 100644
--- a/core/src/main/java/de/jplag/Submission.java
+++ b/core/src/main/java/de/jplag/Submission.java
@@ -3,6 +3,7 @@
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
@@ -209,23 +210,19 @@ public String toString() {
* This method is used to copy files that can not be parsed to a special folder.
*/
private void copySubmission() {
- File rootDirectory = submissionRootFile.getParentFile();
- assert rootDirectory != null;
- File submissionDirectory = createSubdirectory(rootDirectory, ERROR_FOLDER, language.getIdentifier(), name);
+ File errorDirectory = createErrorDirectory(language.getIdentifier(), name);
+ logger.info("Copying erroneous submission to {}", errorDirectory.getAbsolutePath());
for (File file : files) {
try {
- Files.copy(file.toPath(), new File(submissionDirectory, file.getName()).toPath());
+ Files.copy(file.toPath(), new File(errorDirectory, file.getName()).toPath());
} catch (IOException exception) {
logger.error("Error copying file: " + exception.getMessage(), exception);
}
}
}
- private static File createSubdirectory(File parent, String... subdirectoryNames) {
- File subdirectory = parent;
- for (String name : subdirectoryNames) {
- subdirectory = new File(subdirectory, name);
- }
+ private static File createErrorDirectory(String... subdirectoryNames) {
+ File subdirectory = Path.of(ERROR_FOLDER, subdirectoryNames).toFile();
if (!subdirectory.exists()) {
subdirectory.mkdirs();
}
diff --git a/core/src/main/java/de/jplag/options/JPlagOptions.java b/core/src/main/java/de/jplag/options/JPlagOptions.java
index 04dd753e3..e392fefdf 100644
--- a/core/src/main/java/de/jplag/options/JPlagOptions.java
+++ b/core/src/main/java/de/jplag/options/JPlagOptions.java
@@ -55,7 +55,7 @@ public record JPlagOptions(Language language, Integer minimumTokenMatch, Set submissionDirectories, Set oldSubmissionDirectories) {
this(language, null, submissionDirectories, oldSubmissionDirectories, null, null, null, null, DEFAULT_SIMILARITY_METRIC,
diff --git a/core/src/main/java/de/jplag/reporting/reportobject/mapper/MetricMapper.java b/core/src/main/java/de/jplag/reporting/reportobject/mapper/MetricMapper.java
index 7f43cdf9a..0b8a819d4 100644
--- a/core/src/main/java/de/jplag/reporting/reportobject/mapper/MetricMapper.java
+++ b/core/src/main/java/de/jplag/reporting/reportobject/mapper/MetricMapper.java
@@ -1,10 +1,11 @@
package de.jplag.reporting.reportobject.mapper;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.function.Function;
-import java.util.stream.Collectors;
import de.jplag.JPlagComparison;
import de.jplag.JPlagResult;
@@ -25,12 +26,12 @@ public MetricMapper(Function submissionToIdFunction) {
}
public Metric getAverageMetric(JPlagResult result) {
- return new Metric(SimilarityMetric.AVG.name(), intArrayToList(result.getSimilarityDistribution()), getTopComparisons(getComparisons(result)),
- Messages.getString("SimilarityMetric.Avg.Description"));
+ return new Metric(SimilarityMetric.AVG.name(), convertDistribution(result.getSimilarityDistribution()),
+ getTopComparisons(getComparisons(result)), Messages.getString("SimilarityMetric.Avg.Description"));
}
public Metric getMaxMetric(JPlagResult result) {
- return new Metric(SimilarityMetric.MAX.name(), intArrayToList(result.getMaxSimilarityDistribution()),
+ return new Metric(SimilarityMetric.MAX.name(), convertDistribution(result.getMaxSimilarityDistribution()),
getMaxSimilarityTopComparisons(getComparisons(result)), Messages.getString("SimilarityMetric.Max.Description"));
}
@@ -39,8 +40,10 @@ private List getComparisons(JPlagResult result) {
return result.getComparisons(maxNumberOfComparisons);
}
- private List intArrayToList(int[] array) {
- return Arrays.stream(array).boxed().collect(Collectors.toList());
+ private List convertDistribution(int[] array) {
+ List list = new ArrayList<>(Arrays.stream(array).boxed().toList());
+ Collections.reverse(list);
+ return list;
}
private List getTopComparisons(List comparisons, Function similarityExtractor) {
diff --git a/core/src/test/java/de/jplag/BaseCodeTest.java b/core/src/test/java/de/jplag/BaseCodeTest.java
index 3eb473dff..093cbd7a1 100644
--- a/core/src/test/java/de/jplag/BaseCodeTest.java
+++ b/core/src/test/java/de/jplag/BaseCodeTest.java
@@ -38,7 +38,7 @@ protected void verifyResults(JPlagResult result) {
assertEquals(2, result.getNumberOfSubmissions());
assertEquals(1, result.getAllComparisons().size());
assertEquals(1, result.getAllComparisons().get(0).matches().size());
- assertEquals(1, result.getSimilarityDistribution()[1]);
+ assertEquals(1, result.getSimilarityDistribution()[8]);
assertEquals(0.85, result.getAllComparisons().get(0).similarity(), DELTA);
}
@@ -87,7 +87,7 @@ protected void verifySimpleSubdirectoryDuplicate(JPlagResult result, int submiss
assertEquals(submissions, result.getNumberOfSubmissions());
assertEquals(comparisons, result.getAllComparisons().size());
assertEquals(1, result.getAllComparisons().get(0).matches().size());
- assertEquals(1, result.getSimilarityDistribution()[3]);
+ assertEquals(1, result.getSimilarityDistribution()[6]);
assertEquals(0.6207, result.getAllComparisons().get(0).similarity(), DELTA);
}
diff --git a/core/src/test/java/de/jplag/InvalidSubmissionTest.java b/core/src/test/java/de/jplag/InvalidSubmissionTest.java
index 27f8dfba6..4b829e7e1 100644
--- a/core/src/test/java/de/jplag/InvalidSubmissionTest.java
+++ b/core/src/test/java/de/jplag/InvalidSubmissionTest.java
@@ -29,7 +29,7 @@ void testInvalidSubmissionsWithDebug() throws ExitException {
} catch (SubmissionException e) {
System.out.println(e.getMessage());
} finally {
- File errorFolder = new File(Path.of(BASE_PATH, SAMPLE_NAME, "errors", "java").toString());
+ File errorFolder = new File(Path.of("errors", "java").toString());
assertTrue(errorFolder.exists());
String[] errorSubmissions = errorFolder.list();
if (errorSubmissions != null)
diff --git a/core/src/test/java/de/jplag/ParallelComparisonTest.java b/core/src/test/java/de/jplag/ParallelComparisonTest.java
index 78cff0817..2a88c82ff 100644
--- a/core/src/test/java/de/jplag/ParallelComparisonTest.java
+++ b/core/src/test/java/de/jplag/ParallelComparisonTest.java
@@ -23,7 +23,7 @@ void testSimpleDuplicate() throws ExitException {
assertEquals(2, result.getNumberOfSubmissions());
assertEquals(1, result.getAllComparisons().size());
assertEquals(1, result.getAllComparisons().get(0).matches().size());
- assertEquals(1, result.getSimilarityDistribution()[3]);
+ assertEquals(1, result.getSimilarityDistribution()[6]);
assertEquals(0.6207, result.getAllComparisons().get(0).similarity(), DELTA);
}
@@ -32,7 +32,7 @@ void testSimpleDuplicate() throws ExitException {
*/
@Test
void testWithMinTokenMatch() throws ExitException {
- var expectedDistribution = new int[] {1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ var expectedDistribution = new int[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
JPlagResult result = runJPlag("SimpleDuplicate", it -> it.withMinimumTokenMatch(5));
assertEquals(2, result.getNumberOfSubmissions());
diff --git a/core/src/test/java/de/jplag/TestBase.java b/core/src/test/java/de/jplag/TestBase.java
index 06abc0d67..162041ba1 100644
--- a/core/src/test/java/de/jplag/TestBase.java
+++ b/core/src/test/java/de/jplag/TestBase.java
@@ -8,7 +8,6 @@
import java.util.stream.Collectors;
import de.jplag.exceptions.ExitException;
-import de.jplag.java.Language;
import de.jplag.options.JPlagOptions;
public abstract class TestBase {
@@ -50,7 +49,7 @@ protected JPlagResult runJPlag(List newPaths, List oldPaths, Fun
throws ExitException {
var newFiles = newPaths.stream().map(path -> new File(path)).collect(Collectors.toSet());
var oldFiles = oldPaths.stream().map(path -> new File(path)).collect(Collectors.toSet());
- JPlagOptions options = new JPlagOptions(LanguageLoader.getLanguage(Language.IDENTIFIER).orElseThrow(), newFiles, oldFiles);
+ JPlagOptions options = new JPlagOptions(new de.jplag.java.Language(), newFiles, oldFiles);
options = customization.apply(options);
JPlag jplag = new JPlag(options);
return jplag.run();
diff --git a/core/src/test/java/de/jplag/reporting/reportobject/mapper/MetricMapperTest.java b/core/src/test/java/de/jplag/reporting/reportobject/mapper/MetricMapperTest.java
index b9917f251..1aedbefa8 100644
--- a/core/src/test/java/de/jplag/reporting/reportobject/mapper/MetricMapperTest.java
+++ b/core/src/test/java/de/jplag/reporting/reportobject/mapper/MetricMapperTest.java
@@ -5,6 +5,7 @@
import static org.mockito.Mockito.mock;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import org.junit.jupiter.api.Assertions;
@@ -17,19 +18,20 @@
import de.jplag.reporting.reportobject.model.TopComparison;
public class MetricMapperTest {
+ private static final List EXPECTED_DISTRIBUTION = List.of(29, 23, 19, 17, 13, 11, 7, 5, 3, 2);
private final MetricMapper metricMapper = new MetricMapper(Submission::getName);
@Test
public void test_getAverageMetric() {
// given
- JPlagResult jPlagResult = createJPlagResult(MockMetric.AVG, distribution(2, 3, 5, 7, 11, 13, 17, 19, 23, 29),
+ JPlagResult jPlagResult = createJPlagResult(MockMetric.AVG, distribution(EXPECTED_DISTRIBUTION),
comparison(submission("1"), submission("2"), .7), comparison(submission("3"), submission("4"), .3));
// when
var result = metricMapper.getAverageMetric(jPlagResult);
// then
Assertions.assertEquals("AVG", result.name());
- Assertions.assertIterableEquals(List.of(2, 3, 5, 7, 11, 13, 17, 19, 23, 29), result.distribution());
+ Assertions.assertIterableEquals(EXPECTED_DISTRIBUTION, result.distribution());
Assertions.assertEquals(List.of(new TopComparison("1", "2", .7), new TopComparison("3", "4", .3)), result.topComparisons());
Assertions.assertEquals(
"Average of both program coverages. This is the default similarity which"
@@ -40,14 +42,14 @@ public void test_getAverageMetric() {
@Test
public void test_getMaxMetric() {
// given
- JPlagResult jPlagResult = createJPlagResult(MockMetric.MAX, distribution(2, 3, 5, 7, 11, 13, 17, 19, 23, 29),
+ JPlagResult jPlagResult = createJPlagResult(MockMetric.MAX, distribution(EXPECTED_DISTRIBUTION),
comparison(submission("00"), submission("01"), .7), comparison(submission("10"), submission("11"), .3));
// when
var result = metricMapper.getMaxMetric(jPlagResult);
// then
Assertions.assertEquals("MAX", result.name());
- Assertions.assertIterableEquals(List.of(2, 3, 5, 7, 11, 13, 17, 19, 23, 29), result.distribution());
+ Assertions.assertIterableEquals(EXPECTED_DISTRIBUTION, result.distribution());
Assertions.assertEquals(List.of(new TopComparison("00", "01", .7), new TopComparison("10", "11", .3)), result.topComparisons());
Assertions.assertEquals(
"Maximum of both program coverages. This ranking is especially useful if the programs are very "
@@ -55,8 +57,10 @@ public void test_getMaxMetric() {
result.description());
}
- private int[] distribution(int... numbers) {
- return numbers;
+ private int[] distribution(List expectedDistribution) {
+ var reversedDistribution = new ArrayList<>(expectedDistribution);
+ Collections.reverse(reversedDistribution);
+ return reversedDistribution.stream().mapToInt(Integer::intValue).toArray();
}
private CreateSubmission submission(String name) {
diff --git a/core/src/test/java/de/jplag/special/TokenPrinterTest.java b/core/src/test/java/de/jplag/special/TokenPrinterTest.java
index 3cf5decab..0340d9d68 100644
--- a/core/src/test/java/de/jplag/special/TokenPrinterTest.java
+++ b/core/src/test/java/de/jplag/special/TokenPrinterTest.java
@@ -8,7 +8,6 @@
import org.junit.jupiter.api.Test;
import de.jplag.JPlagResult;
-import de.jplag.LanguageLoader;
import de.jplag.Submission;
import de.jplag.TestBase;
import de.jplag.TokenPrinter;
@@ -26,17 +25,10 @@ class TokenPrinterTest extends TestBase {
private static final int MIN_TOKEN_MATCH = 5;
private static final String PRINTER_FOLDER = "PRINTER"; // in the folder 'jplag/src/test/resources/samples'
- private static final String LANGUAGE_CPP = de.jplag.cpp.Language.IDENTIFIER;
- private static final String LANGUAGE_R = de.jplag.rlang.Language.IDENTIFIER;
- private static final String LANGUAGE_KOTLIN = de.jplag.kotlin.Language.IDENTIFIER;
-
- private static final String LANGUAGE_GO = de.jplag.golang.Language.IDENTIFIER;
-
@Disabled("Not a meaningful test, used for designing the token set")
@Test
void printCPPFiles() {
- printSubmissions(
- options -> options.withLanguageOption(LanguageLoader.getLanguage(LANGUAGE_CPP).orElseThrow()).withMinimumTokenMatch(MIN_TOKEN_MATCH));
+ printSubmissions(options -> options.withLanguageOption(new de.jplag.cpp.Language()).withMinimumTokenMatch(MIN_TOKEN_MATCH));
}
@Disabled("Not a meaningful test, used for designing the token set")
@@ -48,20 +40,19 @@ void printJavaFiles() {
@Disabled("Not a meaningful test, used for designing the token set")
@Test
void printRLangFiles() {
- printSubmissions(
- options -> options.withLanguageOption(LanguageLoader.getLanguage(LANGUAGE_R).orElseThrow()).withMinimumTokenMatch(MIN_TOKEN_MATCH));
+ printSubmissions(options -> options.withLanguageOption(new de.jplag.rlang.Language()).withMinimumTokenMatch(MIN_TOKEN_MATCH));
}
@Disabled("Not a meaningful test, used for designing the token set")
@Test
void printGoFiles() {
- printSubmissions(options -> options.withLanguageOption(LanguageLoader.getLanguage(LANGUAGE_GO).orElseThrow()));
+ printSubmissions(options -> options.withLanguageOption(new de.jplag.golang.Language()));
}
@Disabled("Not a meaningful test, used for designing the token set")
@Test
void printKotlinFiles() {
- printSubmissions(options -> options.withLanguageOption(LanguageLoader.getLanguage(LANGUAGE_KOTLIN).orElseThrow()));
+ printSubmissions(options -> options.withLanguageOption(new de.jplag.kotlin.Language()));
}
private void printSubmissions(Function optionsCustomization) {
diff --git a/coverage-report/pom.xml b/coverage-report/pom.xml
new file mode 100644
index 000000000..223bed320
--- /dev/null
+++ b/coverage-report/pom.xml
@@ -0,0 +1,117 @@
+
+
+ 4.0.0
+
+ de.jplag
+ aggregator
+ ${revision}
+
+ coverage-report
+
+
+
+ de.jplag
+ jplag
+ ${revision}
+
+
+ de.jplag
+ cli
+ ${revision}
+
+
+ de.jplag
+ endtoend-testing
+ ${revision}
+
+
+
+
+ de.jplag
+ language-api
+ ${revision}
+
+
+ de.jplag
+ text
+ ${revision}
+
+
+ de.jplag
+ java
+ ${revision}
+
+
+ de.jplag
+ python-3
+ ${revision}
+
+
+ de.jplag
+ csharp
+ ${revision}
+
+
+ de.jplag
+ cpp
+ ${revision}
+
+
+ de.jplag
+ golang
+ ${revision}
+
+
+ de.jplag
+ kotlin
+ ${revision}
+
+
+ de.jplag
+ rlang
+ ${revision}
+
+
+ de.jplag
+ rust
+ ${revision}
+
+
+ de.jplag
+ scala
+ ${revision}
+
+
+ de.jplag
+ scheme
+ ${revision}
+
+
+ de.jplag
+ swift
+ ${revision}
+
+
+ de.jplag
+ emf-metamodel
+ ${revision}
+
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+
+
+ report-aggregate
+
+ report-aggregate
+
+ verify
+
+
+
+
+
+
diff --git a/endtoend-testing/README.md b/endtoend-testing/README.md
index 952e7e33d..f554d66bc 100644
--- a/endtoend-testing/README.md
+++ b/endtoend-testing/README.md
@@ -85,35 +85,34 @@ The internal structure consists of several `Option` records, each of which conta
Thus the results can be kept apart from the other configurations.
The test results for the specified options are also specified in the object. This consists of the `ExpectedResult` record which contains the results of the detection.
-Here the herachie is as follows:
+Here the hierarchy is as follows:
```JSON
[{
- "options":{
- "minimum_token_match":"int"
- },
- "tests":{
- "languageIdentifier":{
- "minimal_similarity":"float",
- "maximum_similarity":"float",
- "matched_token_number":"int"
- },
- "/..."
- }
- },
- "options":{
- "minimum_token_match":"int"
- },
- "tests":{
- "languageIdentifier":{
- "minimal_similarity":"float",
- "maximum_similarity":"float",
- "matched_token_number":"int"
- },
- {
- "/..."
- }
- }
+ "options":{
+ "minimum_token_match":"int"
+ },
+ "tests":{
+ "languageIdentifier":{
+ "minimal_similarity":"float",
+ "maximum_similarity":"float",
+ "matched_token_number":"int"
+ },
+ "/..."
+ }
+},
+{
+ "options":{
+ "minimum_token_match":"int"
+ },
+ "tests":{
+ "languageIdentifier":{
+ "minimal_similarity":"float",
+ "maximum_similarity":"float",
+ "matched_token_number":"int"
+ },
+ "/..."
+ }
}]
```
@@ -173,14 +172,11 @@ public void BubbleSortWithoutRecursion(Integer arr[]) {
```
### Copying Plagiarism To The Resources
-The plagiarisms created in [Creating The Plagiarism](#creating-the-plagiarism) must now be copied to the corresponding resources folder. It is important not to mix the languages of the plagiarisms or to copy the data into bottle resource paths.
+The plagiarisms created in [Creating The Plagiarism](#creating-the-plagiarism) need now to be copied to the corresponding resources folder. For each test suite, the resources must be placed in `JPlag/jplag.endToEndTesting/src/test/resources/languageTestFiles//`. For example, for the existing test suite `sortAlgo` of language `java`, the path is `JPlag/jplag.endToEndTesting/src/test/resources/languageTestFiles/java/sortAlgo`.
+It is important to note that the language identifier must match `Language#getIdentifier` to correctly load the language during testing.
-- At the path `JPlag/jplag.endToEndTesting/src/test/resources/languageTestFiles` a new folder for the language should be created if it does not already exist. For example `[...]/resources/languageTestFiles/JAVA`. If you have plagiarized several different code samples, you can also create additional subfolders under the newly created folder for example `[...]/resources/languageTestFiles/JAVA/sortAlgo`.
-
-It is important to note that the resource folder name must be the same as the language identifier name in JPlag/Language.
-Otherwise, the language option cannot be parsed correctly to the enum-type which you can found in every language module under `Language.java` `IDENTIFIER`
-
-Once the tests have been run for the first time, the information for the tests is stored in the folder `../target/testing-directory-submission/LANGUAGE`. This data can be copied to the path `[...]/resources/results/LANGUAGE`. Each subdirectory gets its result JSON file as `[...]/resources/results/LANGUAGE/TEST_SUITE_NAME.json`. Once the test data has been copied, the end-to-end tests can be successfully tested. As soon as a change in the detection takes place, the results will differ from the stored results and the tests will fail if the results have changed.
+To automatically generate expected results, the test in `EndToEndGeneratorTest` can be executed to generate a JSON result description file. This file has to be copied to `JPlag/jplag.endToEndTesting/src/test/resources/results//.json`.
+Once the test data has been copied, the end-to-end tests can be successfully tested. As soon as a change in the detection takes place, the results will differ from the stored results and the tests will fail if the results have changed.
### Extending The Comparison Value
@@ -202,8 +198,8 @@ public record ExpectedResult(
```JAVA
//...
- if (Float.compare(result.resultSimilarityMaximum(), jPlagComparison.maximalSimilarity()) != 0) {
- addToValidationErrors("maximalSimilarity", String.valueOf(result.resultSimilarityMaximum()),
+ if (areDoublesDifferent(result.resultSimilarityMaximum(), jPlagComparison.maximalSimilarity())) {
+ addToValidationErrors("maximal similarity", String.valueOf(result.resultSimilarityMaximum()),
String.valueOf(jPlagComparison.maximalSimilarity()));
}
//...
diff --git a/endtoend-testing/pom.xml b/endtoend-testing/pom.xml
index d09dd3549..370211bfa 100644
--- a/endtoend-testing/pom.xml
+++ b/endtoend-testing/pom.xml
@@ -16,7 +16,7 @@
de.jplag
- java
+ cli
${revision}
test
diff --git a/endtoend-testing/src/main/java/de/jplag/endtoend/constants/TestDirectoryConstants.java b/endtoend-testing/src/main/java/de/jplag/endtoend/constants/TestDirectoryConstants.java
index c1eff2b47..b0cd6a7ff 100644
--- a/endtoend-testing/src/main/java/de/jplag/endtoend/constants/TestDirectoryConstants.java
+++ b/endtoend-testing/src/main/java/de/jplag/endtoend/constants/TestDirectoryConstants.java
@@ -11,12 +11,6 @@ private TestDirectoryConstants() {
// private constructor to prevent instantiation
}
- /**
- * Create the complete path to the temporary result files. Here the temporary system path is extended with the
- * "RESULT_DIRECTORY_NAME", which is predefined in this class.
- */
- public static final Path TEMPORARY_RESULT_DIRECTORY_NAME = Path.of("target", "testing-directory-temporary-result");
-
/**
* Base path to the saved results
*/
diff --git a/endtoend-testing/src/main/java/de/jplag/endtoend/helper/FileHelper.java b/endtoend-testing/src/main/java/de/jplag/endtoend/helper/FileHelper.java
index b8f25b095..06f3232e4 100644
--- a/endtoend-testing/src/main/java/de/jplag/endtoend/helper/FileHelper.java
+++ b/endtoend-testing/src/main/java/de/jplag/endtoend/helper/FileHelper.java
@@ -2,16 +2,6 @@
import java.io.File;
import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.StandardCopyOption;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.Collectors;
-
-import de.jplag.endtoend.constants.TestDirectoryConstants;
/**
* Helper class to perform all necessary operations or functions on files or folders.
@@ -23,79 +13,14 @@ private FileHelper() {
}
/**
- * Merges all contained filenames together without extension
- * @param files whose names are to be merged
- * @return merged filenames
- */
- public static String getEnclosedFileNamesFromCollection(Collection files) {
-
- return files.stream().map(File::getName).map(fileName -> fileName.substring(0, fileName.lastIndexOf('.'))).collect(Collectors.joining());
- }
-
- /**
- * Load all possible languages in resource path
- * @param directoryNames folder names for which the language options should be listed.
- * @return list of all LanguageOptions included in the resource path
- */
- public static List getLanguageOptionsFromPath(String[] directoryNames) {
- return Arrays.stream(directoryNames).map(language -> language).filter(Objects::nonNull).toList();
- }
-
- /**
- * @param directorieRoot path from which all folders should be loaded
- * @return all folders found in the specified path
- */
- public static String[] getAllDirectoriesInPath(Path directorieRoot) {
- return directorieRoot.toFile().list((dir, name) -> new File(dir, name).isDirectory());
- }
-
- /**
- * Copies the passed filenames to a temporary path to use them in the tests
- * @param classNames for which the test case is to be created
- * @return paths created to the test submissions
- * @throws IOException Exception can be thrown in cases that involve reading, copying or locating files.
+ * Returns the name of the passed file, trimming its file extension.
+ * @param file is the file to obtain the name from
+ * @return returns the name of the file without file extension
*/
- public static String[] createNewTestCaseDirectory(String[] classNames) throws IOException {
- // Copy the resources data to the temporary path
- String[] returnSubmissionPath = new String[classNames.length];
- for (int counter = 0; counter < classNames.length; counter++) {
- Path originalPath = Path.of(classNames[counter]);
- returnSubmissionPath[counter] = Path
- .of(TestDirectoryConstants.TEMPORARY_SUBMISSION_DIRECTORY_NAME.toString(), "submission" + (counter + 1)).toAbsolutePath()
- .toString();
- Path copyPath = Path.of(TestDirectoryConstants.TEMPORARY_SUBMISSION_DIRECTORY_NAME.toString(), "submission" + (counter + 1),
- originalPath.getFileName().toString());
-
- File directory = new File(copyPath.toString());
- if (!directory.exists()) {
- directory.mkdirs();
- }
- Files.copy(originalPath, copyPath, StandardCopyOption.REPLACE_EXISTING);
- }
- return returnSubmissionPath;
- }
-
- /**
- * Delete directory with including files
- * @param folder Path to a folder or file to be deleted. This happens recursively to the path
- * @throws IOException if an I/O error occurs
- */
- public static void deleteCopiedFiles(File folder) throws IOException {
- if (!folder.exists()) {
- return;
- }
- File[] files = folder.listFiles();
- if (files == null) { // some JVMs return null for empty dirs
- return;
- }
- for (File file : files) {
- if (file.isDirectory()) {
- deleteCopiedFiles(file);
- } else {
- Files.delete(file.toPath());
- }
- }
- Files.delete(folder.toPath());
+ public static String getFileNameWithoutFileExtension(File file) {
+ String name = file.getName();
+ int index = name.lastIndexOf('.');
+ return index == -1 ? name : name.substring(0, index);
}
/**
@@ -120,19 +45,6 @@ public static void createFileIfItDoesNotExist(File file) throws IOException {
}
}
- /**
- * @param resourcenPaths list of paths that lead to test resources
- * @return all filenames contained in the paths
- */
- public static String[] loadAllTestFileNames(Path resourcenPaths) {
- var files = resourcenPaths.toFile().listFiles();
- String[] fileNames = new String[files.length];
- for (int i = 0; i < files.length; i++) {
- fileNames[i] = files[i].getName();
- }
- return fileNames;
- }
-
/**
* @param file for which the exception text is to be created
* @return exception text for the specified file
diff --git a/endtoend-testing/src/main/java/de/jplag/endtoend/helper/JsonHelper.java b/endtoend-testing/src/main/java/de/jplag/endtoend/helper/JsonHelper.java
deleted file mode 100644
index 8a70a5216..000000000
--- a/endtoend-testing/src/main/java/de/jplag/endtoend/helper/JsonHelper.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package de.jplag.endtoend.helper;
-
-import java.io.IOException;
-import java.nio.file.Path;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.ObjectWriter;
-
-import de.jplag.endtoend.constants.TestDirectoryConstants;
-import de.jplag.endtoend.model.ResultDescription;
-
-/**
- * Helper class for serialization and deserialization of the used json format into the correct record classes. The
- * serialization/deserialization is enabled using the Jackson library. The record classes used can be found at
- * {@link de.jplag.endtoend.model}.
- */
-public class JsonHelper {
- /**
- * private constructor to prevent instantiation
- */
- private JsonHelper() {
- // For Serialization
- }
-
- /**
- * @param directoryName name to the result path
- * @param languageIdentifier for which the results are to be loaded
- * @return ResultDescription as serialized object
- * @throws IOException is thrown for all problems that may occur while parsing the json file. This includes both reading
- */
- public static List getJsonModelListFromPath(String directoryName, String languageIdentifier) throws IOException {
-
- Path jsonPath = Path.of(TestDirectoryConstants.BASE_PATH_TO_RESULT_JSON.toString(), languageIdentifier, directoryName + ".json");
-
- if (jsonPath.toFile().exists() && jsonPath.toFile().length() > 0) {
-
- return Arrays.asList(new ObjectMapper().readValue(jsonPath.toFile(), ResultDescription[].class));
- } else {
- return Collections.emptyList();
- }
- }
-
- /**
- * Saves the passed object as a json file to the given path
- * @param resultDescriptionist list of elements to be saved
- * @param directoryName path to the temporary storage location
- * @param languageIdentifier for which the results should be stored
- * @throws IOException Signals that an I/O exception of some sort has occurred. Thisclass is the general class of
- * exceptions produced by failed orinterrupted I/O operations.
- */
- public static void writeJsonModelsToJsonFile(List resultDescriptionist, String directoryName, String languageIdentifier)
- throws IOException {
- // create an instance of DefaultPrettyPrinter
- // new DefaultPrettyPrinter()
- ObjectWriter writer = new ObjectMapper().writer().withDefaultPrettyPrinter();
-
- Path temporaryDirectory = Path.of(TestDirectoryConstants.TEMPORARY_SUBMISSION_DIRECTORY_NAME.toString(), languageIdentifier,
- directoryName + ".json");
-
- FileHelper.createDirectoryIfItDoesNotExist(temporaryDirectory.getParent().toFile());
- FileHelper.createFileIfItDoesNotExist(temporaryDirectory.toFile());
-
- // convert book object to JSON file
-
- writer.writeValue(temporaryDirectory.toFile(), resultDescriptionist.toArray());
-
- }
-}
diff --git a/endtoend-testing/src/main/java/de/jplag/endtoend/helper/TestSuiteHelper.java b/endtoend-testing/src/main/java/de/jplag/endtoend/helper/TestSuiteHelper.java
index 92f99d5d5..bc4c03050 100644
--- a/endtoend-testing/src/main/java/de/jplag/endtoend/helper/TestSuiteHelper.java
+++ b/endtoend-testing/src/main/java/de/jplag/endtoend/helper/TestSuiteHelper.java
@@ -1,16 +1,11 @@
package de.jplag.endtoend.helper;
import java.io.File;
-import java.io.IOException;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import java.util.stream.Collectors;
import de.jplag.JPlagComparison;
+import de.jplag.Language;
import de.jplag.Submission;
import de.jplag.endtoend.constants.TestDirectoryConstants;
@@ -26,28 +21,6 @@ private TestSuiteHelper() {
// For Serialization
}
- /**
- * Loads all existing test data into a test structure. the complex structure consists of the LanguageOption and their
- * data to be tested. These are divided into folders. for more information please read the README file
- * @return mapped LanguageOption to the data under test
- */
- public static Map> getAllLanguageResources() {
- String[] languageDirectoryNames = FileHelper.getAllDirectoriesInPath(TestDirectoryConstants.BASE_PATH_TO_LANGUAGE_RESOURCES);
- List languageInPathList = FileHelper.getLanguageOptionsFromPath(languageDirectoryNames);
-
- Map> returnMap = new HashMap<>();
-
- for (String languageIdentifier : languageInPathList) {
- var tempMap = new HashMap();
- var allDirectoriesInPath = FileHelper
- .getAllDirectoriesInPath(Path.of(TestDirectoryConstants.BASE_PATH_TO_LANGUAGE_RESOURCES.toString(), languageIdentifier));
- Arrays.asList(allDirectoriesInPath).forEach(directory -> tempMap.put(Path.of(directory).toFile().getName(),
- Path.of(TestDirectoryConstants.BASE_PATH_TO_LANGUAGE_RESOURCES.toString(), languageIdentifier, directory)));
- returnMap.put(languageIdentifier, tempMap);
- }
- return returnMap;
- }
-
/**
* Creates a unique identifier from the submissions in the JPlagComparison object which is used to find the results in
* the json files.
@@ -55,35 +28,30 @@ public static Map> getAllLanguageResources() {
* @return unique identifier for test case recognition
*/
public static String getTestIdentifier(JPlagComparison jPlagComparison) {
-
- return List.of(jPlagComparison.firstSubmission(), jPlagComparison.secondSubmission()).stream().map(Submission::getFiles)
- .map(FileHelper::getEnclosedFileNamesFromCollection).sorted().collect(Collectors.joining("-"));
+ return List.of(jPlagComparison.firstSubmission(), jPlagComparison.secondSubmission()).stream().map(Submission::getRoot)
+ .map(FileHelper::getFileNameWithoutFileExtension).sorted().collect(Collectors.joining("-"));
}
/**
- * Creates the permutation of all data contained in the passed parameters and adds it to the given path.
- * @param fileNames for which the permutations are needed
- * @param path to which the permutations are to be copied
- * @return all permutations of the specified files to the path specified
+ * Returns the file pointing to the directory of the submissions for the given language and result json. The result
+ * json's name is expected to be equal to the test suite identifier.
+ * @param language is the language for the tests
+ * @param resultJSON is the json containing the expected values
+ * @return returns the directory of the submissions
*/
- public static List getTestCases(String[] fileNames, Path path) {
- ArrayList testCases = new ArrayList<>();
-
- for (int outerCounter = 0; outerCounter < fileNames.length; outerCounter++) {
- for (int innerCounter = outerCounter + 1; innerCounter < fileNames.length; innerCounter++) {
- testCases.add(new String[] {Path.of(path.toAbsolutePath().toString(), fileNames[outerCounter]).toString(),
- Path.of(path.toAbsolutePath().toString(), fileNames[innerCounter]).toString()});
- }
- }
- return testCases;
+ public static File getSubmissionDirectory(Language language, File resultJSON) {
+ return getSubmissionDirectory(language, FileHelper.getFileNameWithoutFileExtension(resultJSON));
}
/**
- * The copied data should be deleted after instance closure
- * @throws IOException if an I/O error occurs
+ * Returns the file pointing to the directory of the submissions for the given language and test suite identifier as
+ * described in the Readme.md.
+ * @param language is the langauge for the tests
+ * @param testSuiteIdentifier is the test suite identifier of the tests
+ * @return returns the directory of the submissions
*/
- public static void clear() throws IOException {
- FileHelper.deleteCopiedFiles(new File(TestDirectoryConstants.TEMPORARY_SUBMISSION_DIRECTORY_NAME.toString()));
+ public static File getSubmissionDirectory(Language language, String testSuiteIdentifier) {
+ return TestDirectoryConstants.BASE_PATH_TO_LANGUAGE_RESOURCES.resolve(language.getIdentifier()).resolve(testSuiteIdentifier).toFile();
}
}
diff --git a/endtoend-testing/src/main/java/de/jplag/endtoend/model/ResultDescription.java b/endtoend-testing/src/main/java/de/jplag/endtoend/model/ResultDescription.java
index 1af14bc7b..e5935f9f4 100644
--- a/endtoend-testing/src/main/java/de/jplag/endtoend/model/ResultDescription.java
+++ b/endtoend-testing/src/main/java/de/jplag/endtoend/model/ResultDescription.java
@@ -12,23 +12,4 @@
*/
public record ResultDescription(@JsonIgnore String languageIdentifier, @JsonProperty("options") Options options,
@JsonProperty("tests") Map identifierToResultMap) {
-
- /**
- * @param identifier for which the stored results are needed
- * @return stored results as ExpectedResult object for the passed id
- */
- @JsonIgnore
- public ExpectedResult getExpectedResultByIdentifier(String identifier) {
- return identifierToResultMap.get(identifier);
- }
-
- /**
- * Adds expected results to the existing list of the object. These results are stored in a map with the given
- * identifier.
- * @param identifier under which the results should be stored
- * @param expectedResult expected results belonging to the identifier
- */
- public void putIdentifierToResultMap(String identifier, ExpectedResult expectedResult) {
- identifierToResultMap.put(identifier, expectedResult);
- }
}
\ No newline at end of file
diff --git a/endtoend-testing/src/test/java/de/jplag/endtoend/EndToEndGeneratorTest.java b/endtoend-testing/src/test/java/de/jplag/endtoend/EndToEndGeneratorTest.java
new file mode 100644
index 000000000..7f59c1544
--- /dev/null
+++ b/endtoend-testing/src/test/java/de/jplag/endtoend/EndToEndGeneratorTest.java
@@ -0,0 +1,87 @@
+package de.jplag.endtoend;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectWriter;
+
+import de.jplag.JPlag;
+import de.jplag.JPlagComparison;
+import de.jplag.JPlagResult;
+import de.jplag.Language;
+import de.jplag.cli.LanguageLoader;
+import de.jplag.endtoend.constants.TestDirectoryConstants;
+import de.jplag.endtoend.helper.FileHelper;
+import de.jplag.endtoend.helper.TestSuiteHelper;
+import de.jplag.endtoend.model.ExpectedResult;
+import de.jplag.endtoend.model.Options;
+import de.jplag.endtoend.model.ResultDescription;
+import de.jplag.exceptions.ExitException;
+import de.jplag.options.JPlagOptions;
+
+/**
+ * Test class for automatically generating the json file describing the expected results. To generate a result json,
+ * adapt the three constants to your requirements and enable the test case.
+ */
+class EndToEndGeneratorTest {
+ private static final String LANGUAGE_IDENTIFIER = "java";
+ private static final String TEST_SUITE_IDENTIFIER = "sortAlgo";
+ private static final List OPTIONS = List.of(new Options(3), new Options(9));
+
+ private static final Logger logger = LoggerFactory.getLogger(EndToEndGeneratorTest.class);
+
+ @Disabled("only enable to generate result json file")
+ @Test
+ void generateResultJson() throws ExitException, IOException {
+ Language language = LanguageLoader.getLanguage(LANGUAGE_IDENTIFIER).orElseThrow();
+ File submissionDirectory = TestSuiteHelper.getSubmissionDirectory(language, TEST_SUITE_IDENTIFIER);
+ List resultDescriptions = new ArrayList<>();
+ for (var option : OPTIONS) {
+ JPlagOptions jplagOptions = new JPlagOptions(language, Set.of(submissionDirectory), Set.of())
+ .withMinimumTokenMatch(option.minimumTokenMatch());
+ JPlagResult jplagResult = new JPlag(jplagOptions).run();
+ List jPlagComparisons = jplagResult.getAllComparisons();
+ Map expectedResults = jPlagComparisons.stream()
+ .collect(Collectors.toMap(TestSuiteHelper::getTestIdentifier, comparison -> new ExpectedResult(comparison.minimalSimilarity(),
+ comparison.maximalSimilarity(), comparison.getNumberOfMatchedTokens())));
+ resultDescriptions.add(new ResultDescription(language.getIdentifier(), option, expectedResults));
+ }
+ File outputFile = writeJsonModelsToJsonFile(resultDescriptions, TEST_SUITE_IDENTIFIER, LANGUAGE_IDENTIFIER);
+ logger.info("result JSON written to file '{}'", outputFile);
+ }
+
+ /**
+ * Saves the passed object as a json file to the file identified by the test suite and language. Returns that file.
+ * @param resultDescriptions list of elements to be saved
+ * @param testSuiteIdentifier identifier of the test suite
+ * @param languageIdentifier identifier of the language
+ * @throws IOException Signals that an I/O exception of some sort has occurred. Thisclass is the general class of
+ * exceptions produced by failed orinterrupted I/O operations.
+ */
+ private static File writeJsonModelsToJsonFile(List resultDescriptions, String testSuiteIdentifier, String languageIdentifier)
+ throws IOException {
+ ObjectWriter writer = new ObjectMapper().writer().withDefaultPrettyPrinter();
+ File outputFile = TestDirectoryConstants.TEMPORARY_SUBMISSION_DIRECTORY_NAME.resolve(languageIdentifier)
+ .resolve(testSuiteIdentifier + ".json").toFile();
+
+ FileHelper.createDirectoryIfItDoesNotExist(outputFile.getParentFile());
+ FileHelper.createFileIfItDoesNotExist(outputFile);
+
+ // convert book object to JSON file
+
+ writer.writeValue(outputFile, resultDescriptions.toArray());
+ return outputFile;
+
+ }
+}
diff --git a/endtoend-testing/src/test/java/de/jplag/endtoend/EndToEndSuiteTest.java b/endtoend-testing/src/test/java/de/jplag/endtoend/EndToEndSuiteTest.java
index b86a04437..ef700d8ad 100644
--- a/endtoend-testing/src/test/java/de/jplag/endtoend/EndToEndSuiteTest.java
+++ b/endtoend-testing/src/test/java/de/jplag/endtoend/EndToEndSuiteTest.java
@@ -1,36 +1,34 @@
package de.jplag.endtoend;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.File;
import java.io.IOException;
-import java.nio.file.Path;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
-import java.util.HashMap;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Optional;
import java.util.Set;
-import java.util.StringJoiner;
import java.util.stream.Collectors;
-import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.DynamicContainer;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
import de.jplag.JPlag;
import de.jplag.JPlagComparison;
import de.jplag.JPlagResult;
-import de.jplag.LanguageLoader;
+import de.jplag.Language;
+import de.jplag.cli.LanguageLoader;
+import de.jplag.endtoend.constants.TestDirectoryConstants;
import de.jplag.endtoend.helper.FileHelper;
-import de.jplag.endtoend.helper.JsonHelper;
import de.jplag.endtoend.helper.TestSuiteHelper;
import de.jplag.endtoend.model.ExpectedResult;
-import de.jplag.endtoend.model.Options;
import de.jplag.endtoend.model.ResultDescription;
import de.jplag.exceptions.ExitException;
import de.jplag.options.JPlagOptions;
@@ -40,146 +38,88 @@
* plagiarism in the Java language and to be able to roughly categorize them. The plagiarism is compared with the
* original class. The results are compared with the results from previous tests and changes are detected.
*/
-public class EndToEndSuiteTest {
+class EndToEndSuiteTest {
private static final double EPSILON = 1E-8;
- // Language -> directory names and Paths
- private Map> languageToTestCaseMapper;
-
- private List options;
-
- private static Map> temporaryResultList;
- private static List validationErrors;
- private static String languageIdentifier;
-
- public EndToEndSuiteTest() throws IOException {
- // Loading the test resources
- languageToTestCaseMapper = TestSuiteHelper.getAllLanguageResources();
- // creating the temporary lists for the test run
- validationErrors = new ArrayList<>();
- temporaryResultList = new HashMap<>();
- // creating options object for the testSuite
- setRunOptions();
- }
-
- /**
- * creating the required options object for the endToEnd tests
- */
- private void setRunOptions() {
- options = new ArrayList<>();
- options.add(new Options(9));
- options.add(new Options(3));
- }
-
- /**
- * Creates the result json files based on the current test results after the test run.
- * @throws IOException is thrown for all problems that may occur while parsing the json file. This includes both reading
- */
- @AfterAll
- public static void tearDown() throws IOException {
- for (var resultDescriptionItem : temporaryResultList.entrySet()) {
- JsonHelper.writeJsonModelsToJsonFile(resultDescriptionItem.getValue(), resultDescriptionItem.getKey(), languageIdentifier);
- }
- }
/**
* Creates the test cases over all language options for which data is available and the current test options.
* @return dynamic test cases across all test data and languages
- * @throws IOException is thrown for all problems that may occur while parsing the json file. This includes both reading
+ * @throws IOException is thrown for all problems that may occur while parsing the json file.
*/
@TestFactory
- Collection dynamicOverAllTest() throws IOException {
- for (Entry> languageMap : languageToTestCaseMapper.entrySet()) {
- String currentLanguageIdentifier = languageMap.getKey();
- for (Entry languagePaths : languageMap.getValue().entrySet()) {
- String[] fileNames = FileHelper.loadAllTestFileNames(languagePaths.getValue());
- var testCases = TestSuiteHelper.getTestCases(fileNames, languagePaths.getValue());
- var testCollection = new ArrayList();
- String directoryName = languagePaths.getValue().getFileName().toString();
- List tempResult = JsonHelper.getJsonModelListFromPath(directoryName, currentLanguageIdentifier);
- languageIdentifier = currentLanguageIdentifier;
- for (Options option : options) {
- for (var testCase : testCases) {
- Optional currentResultDescription = tempResult.stream().filter(x -> x.options().equals(option))
- .findFirst();
- testCollection.add(DynamicTest.dynamicTest(getTestCaseDisplayName(option, languageIdentifier, testCase), () -> {
- runTests(directoryName, option, currentLanguageIdentifier, testCase, currentResultDescription);
- }));
- }
+ Collection dynamicOverAllTest() throws IOException, ExitException {
+ File resultsDirectory = TestDirectoryConstants.BASE_PATH_TO_RESULT_JSON.toFile();
+ File[] languageDirectories = resultsDirectory.listFiles(File::isDirectory);
+ List allTests = new LinkedList<>();
+ for (File languageDirectory : languageDirectories) {
+ Language language = LanguageLoader.getLanguage(languageDirectory.getName()).orElseThrow();
+ File[] resultJsons = languageDirectory.listFiles(file -> !file.isDirectory() && file.getName().endsWith(".json"));
+ List languageTests = new LinkedList<>();
+ for (File resultJson : resultJsons) {
+ List testContainers = new LinkedList<>();
+ ResultDescription[] results = new ObjectMapper().readValue(resultJson, ResultDescription[].class);
+ for (var result : results) {
+ var testCases = generateTestsForResultDescription(resultJson, result, language);
+ testContainers.add(DynamicContainer.dynamicContainer("MTM: " + result.options().minimumTokenMatch(), testCases));
}
- return testCollection;
+ languageTests.add(DynamicContainer.dynamicContainer(FileHelper.getFileNameWithoutFileExtension(resultJson), testContainers));
}
+ allTests.add(DynamicContainer.dynamicContainer(language.getIdentifier(), languageTests));
}
- return null;
+ return allTests;
}
/**
- * Superordinate test function to be able to continue to check all data to be tested in case of failed tests
- * @param directoryName name of the current tested directory
- * @param option for the current test run
- * @param currentLanguageIdentifier current JPlag language option
- * @param testFiles files to be tested
- * @param currentResultDescription results stored for the test data
- * @throws IOException Signals that an I/O exception of some sort has occurred. Thisclass is the general class of
- * exceptions produced by failed orinterrupted I/O operations
- * @throws ExitException Exceptions for problems during the execution of JPlag that lead to an preemptive exit.
+ * Generates test cases for each test described in the provided result object.
+ * @param resultJson is the file of the result json
+ * @param result is one test suite configuration of the deserialized {@code resultJson}
+ * @param language is the language to run JPlag with
+ * @return a collection of test cases, each validating one {@link JPlagResult} against its {@link ExpectedResult}
+ * counterpart
*/
- private void runTests(String directoryName, Options option, String currentLanguageIdentifier, String[] testFiles,
- Optional currentResultDescription) throws IOException, ExitException {
- try {
- ResultDescription currentResult = currentResultDescription.orElse(null);
- runJPlagTestSuite(directoryName, option, currentLanguageIdentifier, testFiles, currentResult);
- } finally {
- validationErrors.clear();
- TestSuiteHelper.clear();
- }
+ private Collection generateTestsForResultDescription(File resultJson, ResultDescription result, Language language)
+ throws ExitException {
+ File submissionDirectory = TestSuiteHelper.getSubmissionDirectory(language, resultJson);
+ JPlagOptions jplagOptions = new JPlagOptions(language, Set.of(submissionDirectory), Set.of())
+ .withMinimumTokenMatch(result.options().minimumTokenMatch());
+ JPlagResult jplagResult = new JPlag(jplagOptions).run();
+ Map jPlagComparisons = jplagResult.getAllComparisons().stream()
+ .collect(Collectors.toMap(it -> TestSuiteHelper.getTestIdentifier(it), it -> it));
+ assertEquals(result.identifierToResultMap().size(), jPlagComparisons.size(), "different number of results and expected results");
+
+ return result.identifierToResultMap().keySet().stream().map(identifier -> {
+ JPlagComparison comparison = jPlagComparisons.get(identifier);
+ ExpectedResult expectedResult = result.identifierToResultMap().get(identifier);
+ return generateTest(identifier, expectedResult, comparison);
+ }).toList();
}
/**
- * EndToEnd test for the passed objects
- * @param directoryName name of the current tested directory
- * @param options for the current test run
- * @param languageIdentifier current JPlag language option
- * @param testFiles files to be tested
- * @param currentResultDescription results stored for the test data
- * @throws IOException Signals that an I/O exception of some sort has occurred. Thisclass is the general class of
- * exceptions produced by failed orinterrupted I/O operations
- * @throws ExitException Exceptions for problems during the execution of JPlag that lead to an preemptive exit.
+ * Generates a test case validating the passed result by comparing it to the expected result values.
+ * @param name is the name of the test case.
+ * @param expectedResult contains all expected result values.
+ * @param result is the comparison object generated from running JPlag.
*/
- private void runJPlagTestSuite(String directoryName, Options options, String languageIdentifier, String[] testFiles,
- ResultDescription currentResultDescription) throws IOException, ExitException {
- String[] submissionPath = FileHelper.createNewTestCaseDirectory(testFiles);
-
- var language = LanguageLoader.getLanguage(languageIdentifier).orElseThrow();
- JPlagOptions jplagOptions = new JPlagOptions(language, Arrays.stream(submissionPath).map(path -> new File(path)).collect(Collectors.toSet()),
- Set.of()).withMinimumTokenMatch(options.minimumTokenMatch());
- JPlagResult jplagResult = new JPlag(jplagOptions).run();
-
- List currentJPlagComparison = jplagResult.getAllComparisons();
-
- for (JPlagComparison jPlagComparison : currentJPlagComparison) {
- String identifier = TestSuiteHelper.getTestIdentifier(jPlagComparison);
- addToTemporaryResultMap(directoryName, options, jPlagComparison, languageIdentifier);
-
- assertNotNull(currentResultDescription, "No stored result could be found for the current LanguageOption! " + options);
-
- ExpectedResult result = currentResultDescription.getExpectedResultByIdentifier(TestSuiteHelper.getTestIdentifier(jPlagComparison));
- assertNotNull(result, "No stored result could be found for the identifier! " + identifier);
-
- if (areDoublesDifferent(result.resultSimilarityMinimum(), jPlagComparison.minimalSimilarity())) {
- addToValidationErrors("minimalSimilarity", String.valueOf(result.resultSimilarityMinimum()),
- String.valueOf(jPlagComparison.minimalSimilarity()));
+ private DynamicTest generateTest(String name, ExpectedResult expectedResult, JPlagComparison result) {
+ return DynamicTest.dynamicTest(name, () -> {
+ assertNotNull(result, "No comparison result could be found");
+
+ List validationErrors = new ArrayList<>();
+ if (areDoublesDifferent(expectedResult.resultSimilarityMinimum(), result.minimalSimilarity())) {
+ validationErrors.add(formattedValidationError("minimal similarity", String.valueOf(expectedResult.resultSimilarityMinimum()),
+ String.valueOf(result.minimalSimilarity())));
}
- if (areDoublesDifferent(result.resultSimilarityMaximum(), jPlagComparison.maximalSimilarity())) {
- addToValidationErrors("maximalSimilarity", String.valueOf(result.resultSimilarityMaximum()),
- String.valueOf(jPlagComparison.maximalSimilarity()));
+ if (areDoublesDifferent(expectedResult.resultSimilarityMaximum(), result.maximalSimilarity())) {
+ validationErrors.add(formattedValidationError("maximal similarity", String.valueOf(expectedResult.resultSimilarityMaximum()),
+ String.valueOf(result.maximalSimilarity())));
}
- if (result.resultMatchedTokenNumber() != jPlagComparison.getNumberOfMatchedTokens()) {
- addToValidationErrors("numberOfMatchedTokens", String.valueOf(result.resultMatchedTokenNumber()),
- String.valueOf(jPlagComparison.getNumberOfMatchedTokens()));
+ if (expectedResult.resultMatchedTokenNumber() != result.getNumberOfMatchedTokens()) {
+ validationErrors.add(formattedValidationError("number of matched tokens", String.valueOf(expectedResult.resultMatchedTokenNumber()),
+ String.valueOf(result.getNumberOfMatchedTokens())));
}
- assertTrue(validationErrors.isEmpty(), createValidationErrorOutout());
- }
+ assertTrue(validationErrors.isEmpty(), createValidationErrorOutput(validationErrors));
+ });
}
private boolean areDoublesDifferent(double d1, double d2) {
@@ -187,82 +127,21 @@ private boolean areDoublesDifferent(double d1, double d2) {
}
/**
- * Creates the display message for failed tests
+ * Creates the display message for a result value validation error.
* @param valueName Name of the failed test object
- * @param currentValue current test values
- * @param expectedValue expected test values
+ * @param actualValue actual test value
+ * @param expectedValue expected test value
*/
- private void addToValidationErrors(String valueName, String currentValue, String expectedValue) {
- validationErrors.add(valueName + " was " + currentValue + " but expected " + expectedValue);
+ private String formattedValidationError(String valueName, String actualValue, String expectedValue) {
+ return valueName + " was " + actualValue + " but expected " + expectedValue;
}
/**
- * Creates the display info from the current failed test results
+ * Creates the display info from the passed failed test results
* @return formatted text for the failed comparative values of the current test
*/
- private String createValidationErrorOutout() {
- StringJoiner joiner = new StringJoiner(System.lineSeparator());
- joiner.add(""); // empty line at start
- joiner.add("There were <" + validationErrors.size() + "> validation error(s):");
-
- validationErrors.stream().forEach(errorLine -> joiner.add(errorLine));
- joiner.add(""); // line break at the end
-
- return joiner.toString();
- }
-
- /**
- * Add or create the current test results in a temporary list to be able to save them later.
- * @param directoryName name of the current tested directory
- * @param options for the current test run
- * @param jPlagComparison current test results
- * @param languageIdentifier current JPlag language option
- */
- private void addToTemporaryResultMap(String directoryName, Options options, JPlagComparison jPlagComparison, String languageIdentifier) {
- var element = temporaryResultList.get(directoryName);
-
- if (element != null) {
- for (var item : element) {
- if (item.options().equals(options)) {
- item.putIdentifierToResultMap(TestSuiteHelper.getTestIdentifier(jPlagComparison), new ExpectedResult(
- jPlagComparison.minimalSimilarity(), jPlagComparison.maximalSimilarity(), jPlagComparison.getNumberOfMatchedTokens()));
- return;
- }
- }
- Map temporaryHashMap = new HashMap<>();
- temporaryHashMap.put(TestSuiteHelper.getTestIdentifier(jPlagComparison), new ExpectedResult(jPlagComparison.minimalSimilarity(),
- jPlagComparison.maximalSimilarity(), jPlagComparison.getNumberOfMatchedTokens()));
- element.add(new ResultDescription(languageIdentifier, options, temporaryHashMap));
- } else {
- var temporaryNewResultList = new ArrayList();
- Map temporaryHashMap = new HashMap<>();
- temporaryHashMap.put(TestSuiteHelper.getTestIdentifier(jPlagComparison), new ExpectedResult(jPlagComparison.minimalSimilarity(),
- jPlagComparison.maximalSimilarity(), jPlagComparison.getNumberOfMatchedTokens()));
-
- temporaryNewResultList.add(new ResultDescription(languageIdentifier, options, temporaryHashMap));
-
- temporaryResultList.put(directoryName, temporaryNewResultList);
- }
- }
-
- /**
- * Creates the name of the test for better assignment and readability Pattern: Language: (option values)
- * filename1-filename2
- * @param option under which the current test run
- * @param languageIdentifier current language used in the test
- * @param testFiles test data for assigning by filename
- * @return display name for the individual tests
- */
- private String getTestCaseDisplayName(Options option, String languageIdentifier, String[] testFiles) {
- StringBuilder stringBuilder = new StringBuilder();
- stringBuilder.append("(" + String.valueOf(option.minimumTokenMatch()) + ")");
- for (int counter = 0; counter < testFiles.length; counter++) {
- String fileName = Path.of(testFiles[counter]).toFile().getName();
- stringBuilder.append(fileName.substring(0, fileName.lastIndexOf('.')));
- if (counter + 1 < testFiles.length) {
- stringBuilder.append("-");
- }
- }
- return languageIdentifier + ": " + stringBuilder.toString();
+ private String createValidationErrorOutput(List validationErrors) {
+ return "There were " + validationErrors.size() + " validation error(s):" + System.lineSeparator()
+ + String.join(System.lineSeparator(), validationErrors);
}
}
diff --git a/languages/cpp/src/main/java/de/jplag/cpp/Language.java b/languages/cpp/src/main/java/de/jplag/cpp/Language.java
index 45aae0bef..dcc69edd7 100644
--- a/languages/cpp/src/main/java/de/jplag/cpp/Language.java
+++ b/languages/cpp/src/main/java/de/jplag/cpp/Language.java
@@ -11,7 +11,7 @@
@MetaInfServices(de.jplag.Language.class)
public class Language implements de.jplag.Language {
- public static final String IDENTIFIER = "cpp";
+ private static final String IDENTIFIER = "cpp";
private final Scanner scanner; // cpp code is scanned not parsed
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
new file mode 100644
index 000000000..4b9371ff3
--- /dev/null
+++ b/languages/cpp/src/main/java/de/jplag/cpp/experimental/GCCSourceAnalysis.java
@@ -0,0 +1,75 @@
+package de.jplag.cpp.experimental;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.*;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Uses GCC to find unused variables and saves their location. The scanner can then check if a token belongs to an
+ * unused variable
+ */
+public class GCCSourceAnalysis implements SourceAnalysis {
+
+ public static final String COMPILE_COMMAND = "gcc -Wall -fsyntax-only %s";
+ private Map> linesToDelete = new HashMap<>();
+
+ private final Logger logger;
+
+ public GCCSourceAnalysis() {
+ this.logger = LoggerFactory.getLogger(this.getClass());
+ }
+
+ public boolean isTokenIgnored(de.jplag.cpp.Token token, File file) {
+ String fileName = file.getName();
+ if (linesToDelete.containsKey(fileName)) {
+ var ignoredLineNumbers = linesToDelete.get(fileName);
+ return ignoredLineNumbers.contains(token.beginLine);
+ }
+ return false;
+ }
+
+ public void findUnusedVariableLines(Set files) throws InterruptedException {
+ linesToDelete = new HashMap<>();
+
+ for (File file : files) {
+ try {
+ Runtime runtime = Runtime.getRuntime();
+ Process gcc = runtime.exec(COMPILE_COMMAND.formatted(file.getAbsolutePath()));
+ gcc.waitFor();
+
+ // gcc prints compiler warnings to the error stream, not the standard stream
+ BufferedReader stdError = new BufferedReader(new InputStreamReader(gcc.getErrorStream()));
+
+ String line;
+ while ((line = stdError.readLine()) != null) {
+ processOutputLine(line);
+ }
+ } catch (IOException e) {
+ // error during compilation, skip this submission
+ logger.warn("Failed to compile file {}", file.getAbsolutePath());
+ }
+ }
+ }
+
+ private void processOutputLine(String line) {
+ // example output:
+ // sourceFile.c:151:8: warning: unused variable 't' [-Wunused-variable]
+ if (!line.contains("unused variable")) {
+ return;
+ }
+
+ // contains [sourceFile, line, column, (warning|error), description]
+ var lineSplit = line.split(":");
+
+ String fileName = new File(lineSplit[0]).getName();
+
+ int lineNumber = Integer.parseInt(lineSplit[1]);
+
+ linesToDelete.computeIfAbsent(fileName, key -> new ArrayList<>()).add(lineNumber);
+ }
+}
diff --git a/languages/cpp/src/main/java/de/jplag/cpp/experimental/SourceAnalysis.java b/languages/cpp/src/main/java/de/jplag/cpp/experimental/SourceAnalysis.java
new file mode 100644
index 000000000..0d846370e
--- /dev/null
+++ b/languages/cpp/src/main/java/de/jplag/cpp/experimental/SourceAnalysis.java
@@ -0,0 +1,26 @@
+package de.jplag.cpp.experimental;
+
+import java.io.File;
+import java.util.Set;
+
+/**
+ * Strategy for analyzing source code for unused variables querying the corresponding lines
+ */
+public interface SourceAnalysis {
+
+ /**
+ * Tells the caller if a token is located in a line containing an unused variable. This usually indicates that the token
+ * belongs to a declaration of an unused variable. An edge case is multiple variable declarations in a single line, e.g.
+ * 'int a, b;' where a is used an b is unused.
+ * @param token The token that will be checked
+ * @param file The file the token was scanned in
+ * @return True, if the token should not be added to a TokenList, false if it should
+ */
+ boolean isTokenIgnored(de.jplag.cpp.Token token, File file);
+
+ /**
+ * Executes the source analysis on the files of a submission.
+ * @param files Set of the files contained in the submission
+ */
+ void findUnusedVariableLines(Set files) throws InterruptedException;
+}
diff --git a/languages/cpp/src/main/java/de/jplag/cpp/experimental/UnreachableCodeFilter.java b/languages/cpp/src/main/java/de/jplag/cpp/experimental/UnreachableCodeFilter.java
new file mode 100644
index 000000000..e795c6976
--- /dev/null
+++ b/languages/cpp/src/main/java/de/jplag/cpp/experimental/UnreachableCodeFilter.java
@@ -0,0 +1,139 @@
+package de.jplag.cpp.experimental;
+
+import static de.jplag.SharedTokenType.FILE_END;
+import static de.jplag.cpp.CPPTokenType.*;
+
+import java.util.List;
+import java.util.ListIterator;
+
+import de.jplag.Token;
+import de.jplag.TokenType;
+
+/**
+ * Contains a basic algorithm for detecting tokens contained in unreachable code.
+ */
+public final class UnreachableCodeFilter {
+
+ private UnreachableCodeFilter() {
+ }
+
+ /**
+ * Applies the filtering on the provided token list.
+ * @param tokenList The list that will be filtered. The contents of this parameter will be modified.
+ */
+ public static void applyTo(List tokenList) {
+ TokenFilterState stateMachine = TokenFilterState.STATE_DEFAULT;
+
+ ListIterator iterator = tokenList.listIterator();
+ while (iterator.hasNext()) {
+ var token = iterator.next();
+
+ stateMachine = stateMachine.nextState(token.getType());
+
+ if (stateMachine.shouldTokenBeDeleted()) {
+ iterator.remove();
+ }
+ }
+ }
+
+ /**
+ * Represents the state of a simple state machine for C++ tokens.
+ */
+ private enum TokenFilterState {
+ STATE_DEFAULT {
+ @Override
+ TokenFilterState nextState(TokenType nextType) {
+ if (isBlockStartToken(nextType)) {
+ return STATE_BLOCK_BEGINNING;
+ }
+ if (isJumpToken(nextType)) {
+ return STATE_DEAD_BLOCK_BEGINNING;
+ }
+ if (nextType == C_CASE) {
+ return STATE_CASE_BLOCK;
+ }
+ return STATE_DEFAULT;
+ }
+ },
+ STATE_BLOCK_BEGINNING {
+ @Override
+ TokenFilterState nextState(TokenType nextType) {
+ if (isBlockEndToken(nextType) || nextType == C_BLOCK_BEGIN) {
+ return STATE_DEFAULT;
+ }
+ return STATE_BLOCK_BEGINNING;
+ }
+ },
+ STATE_DEAD_BLOCK {
+ @Override
+ TokenFilterState nextState(TokenType nextType) {
+ if (isBlockEndToken(nextType)) {
+ return STATE_DEFAULT;
+ }
+ if (nextType == C_CASE) {
+ return STATE_CASE_BLOCK;
+ }
+ return STATE_DEAD_BLOCK;
+ }
+
+ @Override
+ public boolean shouldTokenBeDeleted() {
+ return true;
+ }
+ },
+ // the current token starts a dead block, so everything afterwards should be deleted, until the dead block is closed.
+ STATE_DEAD_BLOCK_BEGINNING {
+ @Override
+ TokenFilterState nextState(TokenType nextType) {
+ if (isBlockEndToken(nextType)) {
+ return STATE_DEFAULT;
+ }
+ if (nextType == C_CASE) {
+ return STATE_CASE_BLOCK;
+ }
+ return STATE_DEAD_BLOCK;
+ }
+ },
+ // case blocks don't use braces, but the end of a case block is easy to recognize
+ STATE_CASE_BLOCK {
+ @Override
+ TokenFilterState nextState(TokenType nextType) {
+ if (isBlockEndToken(nextType)) {
+ return STATE_DEFAULT;
+ }
+ if (isJumpToken(nextType)) {
+ return STATE_DEAD_BLOCK_BEGINNING;
+ }
+ return STATE_CASE_BLOCK;
+ }
+ };
+
+ private static boolean isBlockStartToken(TokenType token) {
+ return token == C_WHILE || token == C_IF || token == C_FOR;
+ }
+
+ private static boolean isBlockEndToken(TokenType token) {
+ return token == C_BLOCK_END || token == FILE_END;
+ }
+
+ // jump tokens are tokens that force a code execution jump in EVERY case and therefore indicate unreachable code.
+ private static boolean isJumpToken(TokenType token) {
+ return token == C_RETURN || token == C_BREAK || token == C_CONTINUE || token == C_THROW || token == C_GOTO;
+ }
+
+ /**
+ * Determine if the current token should be deleted, because it is located in dead or unreachable code.
+ * @return true if the token corresponding to the current state is located in dead or unreachable code, false otherwise.
+ */
+ public boolean shouldTokenBeDeleted() {
+ return false;
+ }
+
+ /**
+ * Determine the next state depending on the current state and the next token type.
+ * @param nextType The type of the next token in the token list.
+ * @return the new state corresponding to the next token
+ */
+ abstract TokenFilterState nextState(TokenType nextType);
+ }
+}
diff --git a/languages/csharp/src/test/java/de/jplag/csharp/MinimalCSharpTest.java b/languages/csharp/src/test/java/de/jplag/csharp/MinimalCSharpTest.java
index 2eececf5f..5f8a3135e 100644
--- a/languages/csharp/src/test/java/de/jplag/csharp/MinimalCSharpTest.java
+++ b/languages/csharp/src/test/java/de/jplag/csharp/MinimalCSharpTest.java
@@ -40,7 +40,7 @@
import de.jplag.TokenType;
class MinimalCSharpTest {
- private final Logger logger = LoggerFactory.getLogger("JPlag-Test");
+ private final Logger logger = LoggerFactory.getLogger(MinimalCSharpTest.class);
private static final Path BASE_PATH = Path.of("src", "test", "resources", "de", "jplag", "csharp");
private static final String TEST_SUBJECT = "TestClass.cs";
diff --git a/languages/emf-metamodel-dynamic/README.md b/languages/emf-metamodel-dynamic/README.md
index 2dd9e5bc1..c34b595fd 100644
--- a/languages/emf-metamodel-dynamic/README.md
+++ b/languages/emf-metamodel-dynamic/README.md
@@ -12,4 +12,5 @@ For the token extraction, we visit the containment tree of the metamodel and ext
To use this module, add the `-l emf-metamodel-dynamic` flag in the CLI, or use a `JPlagOption` object set to `LanguageOption.EMF_DYNAMIC` in the Java API as described in the usage information in the [readme of the main project](https://github.com/jplag/JPlag#usage) and [in the wiki](https://github.com/jplag/JPlag/wiki/1.-How-to-Use-JPlag).
### More Info
-More information can be found in the paper *"Token-based Plagiarism Detection for Metamodels"* (MODELS-C 2022, accepted for publication, link coming soon).
\ No newline at end of file
+More information can be found in the paper [*"Token-based Plagiarism Detection for Metamodels" (MODELS-C'22)*](https://dl.acm.org/doi/10.1145/3550356.3556508).
+A short summary can be found on [Kudos](https://www.growkudos.com/publications/10.1145%25252F3550356.3556508/reader).
diff --git a/languages/emf-metamodel-dynamic/src/main/java/de/jplag/emf/dynamic/Language.java b/languages/emf-metamodel-dynamic/src/main/java/de/jplag/emf/dynamic/Language.java
index 9000073bc..152461735 100644
--- a/languages/emf-metamodel-dynamic/src/main/java/de/jplag/emf/dynamic/Language.java
+++ b/languages/emf-metamodel-dynamic/src/main/java/de/jplag/emf/dynamic/Language.java
@@ -12,7 +12,7 @@
@MetaInfServices(de.jplag.Language.class)
public class Language extends de.jplag.emf.Language {
private static final String NAME = "EMF metamodels (dynamically created token set)";
- public static final String IDENTIFIER = "emf-dynamic";
+ private static final String IDENTIFIER = "emf-dynamic";
private static final int DEFAULT_MIN_TOKEN_MATCH = 10;
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 326fd6761..02d258cb9 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
@@ -25,7 +25,7 @@
import de.jplag.testutils.TokenUtils;
class MinimalDynamicMetamodelTest {
- private final Logger logger = LoggerFactory.getLogger("JPlag-Test");
+ private final Logger logger = LoggerFactory.getLogger(MinimalDynamicMetamodelTest.class);
private static final Path BASE_PATH = Path.of("src", "test", "resources", "de", "jplag", "models");
private static final String[] TEST_SUBJECTS = {"bookStore.ecore", "bookStoreExtended.ecore", "bookStoreRenamed.ecore"};
diff --git a/languages/emf-metamodel/README.md b/languages/emf-metamodel/README.md
index c31d567cd..65bf28bd5 100644
--- a/languages/emf-metamodel/README.md
+++ b/languages/emf-metamodel/README.md
@@ -12,4 +12,5 @@ For the token extraction, we visit the containment tree of the metamodel and ext
To use this module, add the `-l emf-metamodel` flag in the CLI, or use a `JPlagOption` object set to `LanguageOption.EMF` in the Java API as described in the usage information in the [readme of the main project](https://github.com/jplag/JPlag#usage) and [in the wiki](https://github.com/jplag/JPlag/wiki/1.-How-to-Use-JPlag).
### More Info
-More information can be found in the paper *"Token-based Plagiarism Detection for Metamodels"* (MODELS-C 2022, accepted for publication, link coming soon).
\ No newline at end of file
+More information can be found in the paper [*"Token-based Plagiarism Detection for Metamodels" (MODELS-C'22)*](https://dl.acm.org/doi/10.1145/3550356.3556508).
+A short summary can be found on [Kudos](https://www.growkudos.com/publications/10.1145%25252F3550356.3556508/reader).
diff --git a/languages/emf-metamodel/src/main/java/de/jplag/emf/Language.java b/languages/emf-metamodel/src/main/java/de/jplag/emf/Language.java
index f7783fde0..d67f160fd 100644
--- a/languages/emf-metamodel/src/main/java/de/jplag/emf/Language.java
+++ b/languages/emf-metamodel/src/main/java/de/jplag/emf/Language.java
@@ -21,7 +21,7 @@ public class Language implements de.jplag.Language {
public static final String FILE_ENDING = "." + EcorePackage.eNAME;
private static final String NAME = "EMF metamodel";
- public static final String IDENTIFIER = "emf";
+ private static final String IDENTIFIER = "emf";
private static final int DEFAULT_MIN_TOKEN_MATCH = 6;
protected final EcoreParser parser;
diff --git a/languages/emf-metamodel/src/test/java/de/jplag/emf/MinimalMetamodelTest.java b/languages/emf-metamodel/src/test/java/de/jplag/emf/MinimalMetamodelTest.java
index e959748b7..9414996a3 100644
--- a/languages/emf-metamodel/src/test/java/de/jplag/emf/MinimalMetamodelTest.java
+++ b/languages/emf-metamodel/src/test/java/de/jplag/emf/MinimalMetamodelTest.java
@@ -25,7 +25,7 @@
import de.jplag.testutils.TokenUtils;
class MinimalMetamodelTest {
- private final Logger logger = LoggerFactory.getLogger("JPlag-Test");
+ private final Logger logger = LoggerFactory.getLogger(MinimalMetamodelTest.class);
private static final Path BASE_PATH = Path.of("src", "test", "resources", "de", "jplag", "models");
private static final String[] TEST_SUBJECTS = {"bookStore.ecore", "bookStoreExtended.ecore", "bookStoreRenamed.ecore"};
diff --git a/languages/golang/src/main/java/de/jplag/golang/Language.java b/languages/golang/src/main/java/de/jplag/golang/Language.java
index f0802ac6f..e3590bd5a 100644
--- a/languages/golang/src/main/java/de/jplag/golang/Language.java
+++ b/languages/golang/src/main/java/de/jplag/golang/Language.java
@@ -13,7 +13,7 @@
public class Language implements de.jplag.Language {
private static final String NAME = "Go Parser";
- public static final String IDENTIFIER = "go";
+ private static final String IDENTIFIER = "go";
private static final int DEFAULT_MIN_TOKEN_MATCH = 8;
private static final String[] FILE_EXTENSIONS = {".go"};
private final GoParserAdapter parserAdapter;
diff --git a/languages/golang/src/test/java/de/jplag/golang/GoLanguageTest.java b/languages/golang/src/test/java/de/jplag/golang/GoLanguageTest.java
index 35a9cd9b0..38d9e7549 100644
--- a/languages/golang/src/test/java/de/jplag/golang/GoLanguageTest.java
+++ b/languages/golang/src/test/java/de/jplag/golang/GoLanguageTest.java
@@ -47,7 +47,7 @@ class GoLanguageTest {
*/
private static final String DELIMITED_COMMENT_END = ".*\\*/\\s*$";
- private final Logger logger = LoggerFactory.getLogger("GoLang language test");
+ private final Logger logger = LoggerFactory.getLogger(GoLanguageTest.class);
private final String[] testFiles = new String[] {COMPLETE_TEST_FILE};
private final File testFileLocation = Path.of("src", "test", "resources", "de", "jplag", "golang").toFile();
private Language language;
diff --git a/languages/java/src/main/java/de/jplag/java/Language.java b/languages/java/src/main/java/de/jplag/java/Language.java
index 5bfefd92e..fd0d2a577 100644
--- a/languages/java/src/main/java/de/jplag/java/Language.java
+++ b/languages/java/src/main/java/de/jplag/java/Language.java
@@ -14,7 +14,7 @@
*/
@MetaInfServices(de.jplag.Language.class)
public class Language implements de.jplag.Language {
- public static final String IDENTIFIER = "java";
+ private static final String IDENTIFIER = "java";
private final Parser parser;
diff --git a/languages/kotlin/src/main/java/de/jplag/kotlin/Language.java b/languages/kotlin/src/main/java/de/jplag/kotlin/Language.java
index 323550d3f..cc294cf2a 100644
--- a/languages/kotlin/src/main/java/de/jplag/kotlin/Language.java
+++ b/languages/kotlin/src/main/java/de/jplag/kotlin/Language.java
@@ -16,7 +16,7 @@
public class Language implements de.jplag.Language {
private static final String NAME = "Kotlin Parser";
- public static final String IDENTIFIER = "kotlin";
+ private static final String IDENTIFIER = "kotlin";
private static final int DEFAULT_MIN_TOKEN_MATCH = 8;
private static final String[] FILE_EXTENSIONS = {".kt"};
private final KotlinParserAdapter parserAdapter;
diff --git a/languages/kotlin/src/test/java/de/jplag/kotlin/KotlinLanguageTest.java b/languages/kotlin/src/test/java/de/jplag/kotlin/KotlinLanguageTest.java
index 828977693..1d0ec1034 100644
--- a/languages/kotlin/src/test/java/de/jplag/kotlin/KotlinLanguageTest.java
+++ b/languages/kotlin/src/test/java/de/jplag/kotlin/KotlinLanguageTest.java
@@ -46,7 +46,7 @@ class KotlinLanguageTest {
*/
private static final String DELIMITED_COMMENT_END = ".*\\*/\\s*$";
- private final Logger logger = LoggerFactory.getLogger("Kotlin language test");
+ private final Logger logger = LoggerFactory.getLogger(KotlinLanguageTest.class);
private final String[] testFiles = new String[] {COMPLETE_TEST_FILE, "Game.kt"};
private final File testFileLocation = Path.of("src", "test", "resources", "de", "jplag", "kotlin").toFile();
private Language language;
diff --git a/languages/python-3/src/main/java/de/jplag/python3/Language.java b/languages/python-3/src/main/java/de/jplag/python3/Language.java
index 48df2731a..8a35adaca 100644
--- a/languages/python-3/src/main/java/de/jplag/python3/Language.java
+++ b/languages/python-3/src/main/java/de/jplag/python3/Language.java
@@ -12,7 +12,7 @@
@MetaInfServices(de.jplag.Language.class)
public class Language implements de.jplag.Language {
- public static final String IDENTIFIER = "python3";
+ private static final String IDENTIFIER = "python3";
private final Parser parser;
diff --git a/languages/rlang/src/main/java/de/jplag/rlang/Language.java b/languages/rlang/src/main/java/de/jplag/rlang/Language.java
index c3ff9a4b7..a05abd066 100644
--- a/languages/rlang/src/main/java/de/jplag/rlang/Language.java
+++ b/languages/rlang/src/main/java/de/jplag/rlang/Language.java
@@ -16,7 +16,7 @@
public class Language implements de.jplag.Language {
private static final String NAME = "R Parser";
- public static final String IDENTIFIER = "rlang";
+ private static final String IDENTIFIER = "rlang";
private static final int DEFAULT_MIN_TOKEN_MATCH = 8;
private static final String[] FILE_EXTENSION = {".R", ".r"};
private final RParserAdapter parserAdapter;
diff --git a/languages/rlang/src/test/java/de/jplag/rlang/RLanguageTest.java b/languages/rlang/src/test/java/de/jplag/rlang/RLanguageTest.java
index 0917666a1..21c9928d7 100644
--- a/languages/rlang/src/test/java/de/jplag/rlang/RLanguageTest.java
+++ b/languages/rlang/src/test/java/de/jplag/rlang/RLanguageTest.java
@@ -36,7 +36,7 @@ class RLanguageTest {
*/
private static final String COMPLETE_TEST_FILE = "Complete.R";
- private final Logger logger = LoggerFactory.getLogger("R language test");
+ private final Logger logger = LoggerFactory.getLogger(RLanguageTest.class);
private final String[] testFiles = new String[] {"Game.R", COMPLETE_TEST_FILE};
private final File testFileLocation = Path.of("src", "test", "resources", "de", "jplag", "rlang").toFile();
private Language language;
diff --git a/languages/rust/src/main/java/de/jplag/rust/Language.java b/languages/rust/src/main/java/de/jplag/rust/Language.java
index d568aaa35..2508d285f 100644
--- a/languages/rust/src/main/java/de/jplag/rust/Language.java
+++ b/languages/rust/src/main/java/de/jplag/rust/Language.java
@@ -16,9 +16,9 @@
public class Language implements de.jplag.Language {
protected static final String[] FILE_EXTENSIONS = {".rs"};
- public static final String NAME = "Rust Language Module";
- public static final String IDENTIFIER = "rust";
- public static final int MINIMUM_TOKEN_MATCH = 8;
+ private static final String NAME = "Rust Language Module";
+ private static final String IDENTIFIER = "rust";
+ private static final int MINIMUM_TOKEN_MATCH = 8;
private final RustParserAdapter parserAdapter;
diff --git a/languages/rust/src/test/java/de/jplag/rust/RustLanguageTest.java b/languages/rust/src/test/java/de/jplag/rust/RustLanguageTest.java
index 7426d27c1..2e0d3e6f8 100644
--- a/languages/rust/src/test/java/de/jplag/rust/RustLanguageTest.java
+++ b/languages/rust/src/test/java/de/jplag/rust/RustLanguageTest.java
@@ -40,7 +40,7 @@ class RustLanguageTest {
private static final double EPSILON = 1E-6;
public static final double BASELINE_COVERAGE = 0.75;
- private final Logger logger = LoggerFactory.getLogger("Rust language test");
+ private final Logger logger = LoggerFactory.getLogger(RustLanguageTest.class);
private final String[] testFiles = new String[] {"deno_core_runtime.rs", COMPLETE_TEST_FILE};
private final File testFileLocation = Path.of("src", "test", "resources", "de", "jplag", "rust").toFile();
private Language language;
diff --git a/languages/scala/src/test/java/de/jplag/scala/ScalaLanguageTest.java b/languages/scala/src/test/java/de/jplag/scala/ScalaLanguageTest.java
index 6117aba6a..9daf3c5b1 100644
--- a/languages/scala/src/test/java/de/jplag/scala/ScalaLanguageTest.java
+++ b/languages/scala/src/test/java/de/jplag/scala/ScalaLanguageTest.java
@@ -46,7 +46,7 @@ class ScalaLanguageTest {
private static final String DELIMITED_COMMENT_END = ".*\\*/\\s*$";
private static final double EPSILON = 1E-6;
- private final Logger logger = LoggerFactory.getLogger("Scala language test");
+ private final Logger logger = LoggerFactory.getLogger(ScalaLanguageTest.class);
private final String[] testFiles = new String[] {"Parser.scala", COMPLETE_TEST_FILE};
private final File testFileLocation = Path.of("src", "test", "resources", "de", "jplag", "scala").toFile();
private Language language;
diff --git a/languages/scheme/src/main/java/de/jplag/scheme/Language.java b/languages/scheme/src/main/java/de/jplag/scheme/Language.java
index f3cba0e62..c5a1b53ac 100644
--- a/languages/scheme/src/main/java/de/jplag/scheme/Language.java
+++ b/languages/scheme/src/main/java/de/jplag/scheme/Language.java
@@ -12,7 +12,7 @@
@MetaInfServices(de.jplag.Language.class)
public class Language implements de.jplag.Language {
- public static final String IDENTIFIER = "scheme";
+ private static final String IDENTIFIER = "scheme";
private final de.jplag.scheme.Parser parser;
public Language() {
diff --git a/languages/swift/src/main/java/de/jplag/swift/Language.java b/languages/swift/src/main/java/de/jplag/swift/Language.java
index 60a592841..19c7426e5 100644
--- a/languages/swift/src/main/java/de/jplag/swift/Language.java
+++ b/languages/swift/src/main/java/de/jplag/swift/Language.java
@@ -15,8 +15,9 @@
@MetaInfServices(de.jplag.Language.class)
public class Language implements de.jplag.Language {
- private static final String NAME = "Swift Parser";
private static final String IDENTIFIER = "swift";
+
+ private static final String NAME = "Swift Parser";
private static final int DEFAULT_MIN_TOKEN_MATCH = 8;
private static final String[] FILE_EXTENSIONS = {".swift"};
private final SwiftParserAdapter parserAdapter;
diff --git a/languages/swift/src/test/java/de/jplag/swift/SwiftFrontendTest.java b/languages/swift/src/test/java/de/jplag/swift/SwiftFrontendTest.java
index 02ebdabed..705843eb0 100644
--- a/languages/swift/src/test/java/de/jplag/swift/SwiftFrontendTest.java
+++ b/languages/swift/src/test/java/de/jplag/swift/SwiftFrontendTest.java
@@ -52,7 +52,7 @@ class SwiftFrontendTest {
*/
private static final String DELIMITED_COMMENT_END = ".*\\*/\\s*$";
- private final Logger logger = LoggerFactory.getLogger("Swift frontend test");
+ private final Logger logger = LoggerFactory.getLogger(SwiftFrontendTest.class);
private final String[] testFiles = new String[] {COMPLETE_TEST_FILE};
private final File testFileLocation = Path.of("src", "test", "resources", "de", "jplag", "swift").toFile();
private Language language;
diff --git a/languages/text/src/main/java/de/jplag/text/Language.java b/languages/text/src/main/java/de/jplag/text/Language.java
index 289635d9e..03693ba0e 100644
--- a/languages/text/src/main/java/de/jplag/text/Language.java
+++ b/languages/text/src/main/java/de/jplag/text/Language.java
@@ -17,7 +17,7 @@
@MetaInfServices(de.jplag.Language.class)
public class Language implements de.jplag.Language {
- public static final String IDENTIFIER = "text";
+ private static final String IDENTIFIER = "text";
private final ParserAdapter parserAdapter;
public Language() {
diff --git a/languages/text/src/main/java/de/jplag/text/ParserAdapter.java b/languages/text/src/main/java/de/jplag/text/ParserAdapter.java
index 8810be7c9..975dbe7e3 100644
--- a/languages/text/src/main/java/de/jplag/text/ParserAdapter.java
+++ b/languages/text/src/main/java/de/jplag/text/ParserAdapter.java
@@ -15,7 +15,6 @@
import edu.stanford.nlp.ling.CoreLabel;
import edu.stanford.nlp.pipeline.CoreDocument;
import edu.stanford.nlp.pipeline.StanfordCoreNLP;
-import edu.stanford.nlp.util.logging.RedwoodConfiguration;
public class ParserAdapter extends AbstractParser {
@@ -34,7 +33,6 @@ public class ParserAdapter extends AbstractParser {
private int currentLineBreakIndex;
public ParserAdapter() {
- RedwoodConfiguration.errorLevel().apply();
Properties properties = new Properties();
properties.put(ANNOTATORS_KEY, ANNOTATORS_VALUE);
this.pipeline = new StanfordCoreNLP(properties);
diff --git a/languages/text/src/test/java/jplag/text/TextLanguageTest.java b/languages/text/src/test/java/jplag/text/TextLanguageTest.java
index 7ce5674bc..09fe29b4c 100644
--- a/languages/text/src/test/java/jplag/text/TextLanguageTest.java
+++ b/languages/text/src/test/java/jplag/text/TextLanguageTest.java
@@ -26,7 +26,7 @@
import de.jplag.text.Language;
class TextLanguageTest {
- private final Logger logger = LoggerFactory.getLogger("JPlag-Test");
+ private final Logger logger = LoggerFactory.getLogger(TextLanguageTest.class);
private static final Path BASE_PATH = Path.of("src", "test", "resources");
private static final String TEST_SUBJECT = "FutureJavaDoc.txt";
diff --git a/pom.xml b/pom.xml
index 6caea8526..5969827ea 100644
--- a/pom.xml
+++ b/pom.xml
@@ -70,7 +70,7 @@
jplag
https://sonarcloud.io
- ${maven.multiModuleProjectDirectory}/jplag.cli/target/site/jacoco-aggregate/jacoco.xml
+ ${maven.multiModuleProjectDirectory}/coverage-report/target/site/jacoco-aggregate/jacoco.xml
17
17
@@ -85,7 +85,7 @@
2.17.0
- 4.0.1-SNAPSHOT
+ 4.1.0
@@ -139,7 +139,7 @@
com.fasterxml.jackson.core
jackson-databind
- 2.13.4.1
+ 2.14.0
@@ -166,7 +166,7 @@
org.mockito
mockito-core
- 4.8.0
+ 4.9.0
test
@@ -284,6 +284,10 @@
true
resolveCiFriendliesOnly
+
+ expand
+ expand
+
@@ -400,6 +404,7 @@
cli
core
+ coverage-report
endtoend-testing
languages
language-api
diff --git a/report-viewer/package-lock.json b/report-viewer/package-lock.json
index 79bf99b6c..79b288696 100644
--- a/report-viewer/package-lock.json
+++ b/report-viewer/package-lock.json
@@ -11,22 +11,22 @@
"@highlightjs/vue-plugin": "^2.1.0",
"chart.js": "^3.9.1",
"chartjs-plugin-datalabels": "^2.1.0",
- "core-js": "^3.25.5",
- "gitart-vue-dialog": "^2.4.0",
+ "core-js": "^3.26.1",
+ "gitart-vue-dialog": "^2.4.1",
"highlight.js": "^11.6.0",
"jszip": "^3.10.0",
"node-polyfill-webpack-plugin": "^2.0.0",
"slash": "^5.0.0",
- "vue": "^3.2.40",
+ "vue": "^3.2.45",
"vue-chart-3": "^3.1.8",
"vue-draggable-next": "^2.1.1",
- "vue-router": "^4.1.5",
+ "vue-router": "^4.1.6",
"vue3-highlightjs": "^1.0.5",
"vuex": "^4.0.2"
},
"devDependencies": {
- "@typescript-eslint/eslint-plugin": "^5.40.0",
- "@typescript-eslint/parser": "^5.40.0",
+ "@typescript-eslint/eslint-plugin": "^5.43.0",
+ "@typescript-eslint/parser": "^5.43.0",
"@vue/cli-plugin-babel": "~5.0.8",
"@vue/cli-plugin-eslint": "~5.0.8",
"@vue/cli-plugin-router": "~5.0.8",
@@ -35,12 +35,12 @@
"@vue/compiler-sfc": "^3.2.39",
"@vue/eslint-config-prettier": "^7.0.0",
"@vue/eslint-config-typescript": "^10.0.0",
- "eslint": "^8.25.0",
+ "eslint": "^8.27.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-vue": "^8.7.1",
"lint-staged": "^13.0.3",
"prettier": "^2.7.1",
- "typescript": "~4.8.4"
+ "typescript": "~4.9.3"
}
},
"node_modules/@achrinza/node-ipc": {
@@ -1775,9 +1775,9 @@
}
},
"node_modules/@humanwhocodes/config-array": {
- "version": "0.10.5",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.5.tgz",
- "integrity": "sha512-XVVDtp+dVvRxMoxSiSfasYaG02VEe1qH5cKgMQJWhol6HwzbcqoCMJi8dAGoYAO57jhUyhI6cWuRiTcRaDaYug==",
+ "version": "0.11.6",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.6.tgz",
+ "integrity": "sha512-jJr+hPTJYKyDILJfhNSHsjiwXYf26Flsz8DvNndOsHs5pwSnpGUEy8yzF0JYhCEvTDdV2vuOK5tt8BVhwO5/hg==",
"dev": true,
"dependencies": {
"@humanwhocodes/object-schema": "^1.2.1",
@@ -2184,6 +2184,12 @@
"integrity": "sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==",
"dev": true
},
+ "node_modules/@types/semver": {
+ "version": "7.3.13",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz",
+ "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==",
+ "dev": true
+ },
"node_modules/@types/serve-index": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz",
@@ -2228,16 +2234,17 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "5.40.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.40.0.tgz",
- "integrity": "sha512-FIBZgS3DVJgqPwJzvZTuH4HNsZhHMa9SjxTKAZTlMsPw/UzpEjcf9f4dfgDJEHjK+HboUJo123Eshl6niwEm/Q==",
+ "version": "5.43.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.43.0.tgz",
+ "integrity": "sha512-wNPzG+eDR6+hhW4yobEmpR36jrqqQv1vxBq5LJO3fBAktjkvekfr4BRl+3Fn1CM/A+s8/EiGUbOMDoYqWdbtXA==",
"dev": true,
"dependencies": {
- "@typescript-eslint/scope-manager": "5.40.0",
- "@typescript-eslint/type-utils": "5.40.0",
- "@typescript-eslint/utils": "5.40.0",
+ "@typescript-eslint/scope-manager": "5.43.0",
+ "@typescript-eslint/type-utils": "5.43.0",
+ "@typescript-eslint/utils": "5.43.0",
"debug": "^4.3.4",
"ignore": "^5.2.0",
+ "natural-compare-lite": "^1.4.0",
"regexpp": "^3.2.0",
"semver": "^7.3.7",
"tsutils": "^3.21.0"
@@ -2275,14 +2282,14 @@
}
},
"node_modules/@typescript-eslint/parser": {
- "version": "5.40.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.40.0.tgz",
- "integrity": "sha512-Ah5gqyX2ySkiuYeOIDg7ap51/b63QgWZA7w6AHtFrag7aH0lRQPbLzUjk0c9o5/KZ6JRkTTDKShL4AUrQa6/hw==",
+ "version": "5.43.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.43.0.tgz",
+ "integrity": "sha512-2iHUK2Lh7PwNUlhFxxLI2haSDNyXvebBO9izhjhMoDC+S3XI9qt2DGFUsiJ89m2k7gGYch2aEpYqV5F/+nwZug==",
"dev": true,
"dependencies": {
- "@typescript-eslint/scope-manager": "5.40.0",
- "@typescript-eslint/types": "5.40.0",
- "@typescript-eslint/typescript-estree": "5.40.0",
+ "@typescript-eslint/scope-manager": "5.43.0",
+ "@typescript-eslint/types": "5.43.0",
+ "@typescript-eslint/typescript-estree": "5.43.0",
"debug": "^4.3.4"
},
"engines": {
@@ -2302,13 +2309,13 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
- "version": "5.40.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.40.0.tgz",
- "integrity": "sha512-d3nPmjUeZtEWRvyReMI4I1MwPGC63E8pDoHy0BnrYjnJgilBD3hv7XOiETKLY/zTwI7kCnBDf2vWTRUVpYw0Uw==",
+ "version": "5.43.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.43.0.tgz",
+ "integrity": "sha512-XNWnGaqAtTJsUiZaoiGIrdJYHsUOd3BZ3Qj5zKp9w6km6HsrjPk/TGZv0qMTWyWj0+1QOqpHQ2gZOLXaGA9Ekw==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "5.40.0",
- "@typescript-eslint/visitor-keys": "5.40.0"
+ "@typescript-eslint/types": "5.43.0",
+ "@typescript-eslint/visitor-keys": "5.43.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -2319,13 +2326,13 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
- "version": "5.40.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.40.0.tgz",
- "integrity": "sha512-nfuSdKEZY2TpnPz5covjJqav+g5qeBqwSHKBvz7Vm1SAfy93SwKk/JeSTymruDGItTwNijSsno5LhOHRS1pcfw==",
+ "version": "5.43.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.43.0.tgz",
+ "integrity": "sha512-K21f+KY2/VvYggLf5Pk4tgBOPs2otTaIHy2zjclo7UZGLyFH86VfUOm5iq+OtDtxq/Zwu2I3ujDBykVW4Xtmtg==",
"dev": true,
"dependencies": {
- "@typescript-eslint/typescript-estree": "5.40.0",
- "@typescript-eslint/utils": "5.40.0",
+ "@typescript-eslint/typescript-estree": "5.43.0",
+ "@typescript-eslint/utils": "5.43.0",
"debug": "^4.3.4",
"tsutils": "^3.21.0"
},
@@ -2346,9 +2353,9 @@
}
},
"node_modules/@typescript-eslint/types": {
- "version": "5.40.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.40.0.tgz",
- "integrity": "sha512-V1KdQRTXsYpf1Y1fXCeZ+uhjW48Niiw0VGt4V8yzuaDTU8Z1Xl7yQDyQNqyAFcVhpYXIVCEuxSIWTsLDpHgTbw==",
+ "version": "5.43.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.43.0.tgz",
+ "integrity": "sha512-jpsbcD0x6AUvV7tyOlyvon0aUsQpF8W+7TpJntfCUWU1qaIKu2K34pMwQKSzQH8ORgUrGYY6pVIh1Pi8TNeteg==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -2359,13 +2366,13 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "5.40.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.40.0.tgz",
- "integrity": "sha512-b0GYlDj8TLTOqwX7EGbw2gL5EXS2CPEWhF9nGJiGmEcmlpNBjyHsTwbqpyIEPVpl6br4UcBOYlcI2FJVtJkYhg==",
+ "version": "5.43.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.43.0.tgz",
+ "integrity": "sha512-BZ1WVe+QQ+igWal2tDbNg1j2HWUkAa+CVqdU79L4HP9izQY6CNhXfkNwd1SS4+sSZAP/EthI1uiCSY/+H0pROg==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "5.40.0",
- "@typescript-eslint/visitor-keys": "5.40.0",
+ "@typescript-eslint/types": "5.43.0",
+ "@typescript-eslint/visitor-keys": "5.43.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -2401,15 +2408,16 @@
}
},
"node_modules/@typescript-eslint/utils": {
- "version": "5.40.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.40.0.tgz",
- "integrity": "sha512-MO0y3T5BQ5+tkkuYZJBjePewsY+cQnfkYeRqS6tPh28niiIwPnQ1t59CSRcs1ZwJJNOdWw7rv9pF8aP58IMihA==",
+ "version": "5.43.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.43.0.tgz",
+ "integrity": "sha512-8nVpA6yX0sCjf7v/NDfeaOlyaIIqL7OaIGOWSPFqUKK59Gnumd3Wa+2l8oAaYO2lk0sO+SbWFWRSvhu8gLGv4A==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.9",
- "@typescript-eslint/scope-manager": "5.40.0",
- "@typescript-eslint/types": "5.40.0",
- "@typescript-eslint/typescript-estree": "5.40.0",
+ "@types/semver": "^7.3.12",
+ "@typescript-eslint/scope-manager": "5.43.0",
+ "@typescript-eslint/types": "5.43.0",
+ "@typescript-eslint/typescript-estree": "5.43.0",
"eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0",
"semver": "^7.3.7"
@@ -2441,12 +2449,12 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
- "version": "5.40.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.40.0.tgz",
- "integrity": "sha512-ijJ+6yig+x9XplEpG2K6FUdJeQGGj/15U3S56W9IqXKJqleuD7zJ2AX/miLezwxpd7ZxDAqO87zWufKg+RPZyQ==",
+ "version": "5.43.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.43.0.tgz",
+ "integrity": "sha512-icl1jNH/d18OVHLfcwdL3bWUKsBeIiKYTGxMJCoGe7xFht+E4QgzOqoWYrU8XSLJWhVw8nTacbm03v23J/hFTg==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "5.40.0",
+ "@typescript-eslint/types": "5.43.0",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
@@ -3005,36 +3013,36 @@
}
},
"node_modules/@vue/compiler-core": {
- "version": "3.2.40",
- "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.40.tgz",
- "integrity": "sha512-2Dc3Stk0J/VyQ4OUr2yEC53kU28614lZS+bnrCbFSAIftBJ40g/2yQzf4mPBiFuqguMB7hyHaujdgZAQ67kZYA==",
+ "version": "3.2.45",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.45.tgz",
+ "integrity": "sha512-rcMj7H+PYe5wBV3iYeUgbCglC+pbpN8hBLTJvRiK2eKQiWqu+fG9F+8sW99JdL4LQi7Re178UOxn09puSXvn4A==",
"dependencies": {
"@babel/parser": "^7.16.4",
- "@vue/shared": "3.2.40",
+ "@vue/shared": "3.2.45",
"estree-walker": "^2.0.2",
"source-map": "^0.6.1"
}
},
"node_modules/@vue/compiler-dom": {
- "version": "3.2.40",
- "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.40.tgz",
- "integrity": "sha512-OZCNyYVC2LQJy4H7h0o28rtk+4v+HMQygRTpmibGoG9wZyomQiS5otU7qo3Wlq5UfHDw2RFwxb9BJgKjVpjrQw==",
+ "version": "3.2.45",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.45.tgz",
+ "integrity": "sha512-tyYeUEuKqqZO137WrZkpwfPCdiiIeXYCcJ8L4gWz9vqaxzIQRccTSwSWZ/Axx5YR2z+LvpUbmPNXxuBU45lyRw==",
"dependencies": {
- "@vue/compiler-core": "3.2.40",
- "@vue/shared": "3.2.40"
+ "@vue/compiler-core": "3.2.45",
+ "@vue/shared": "3.2.45"
}
},
"node_modules/@vue/compiler-sfc": {
- "version": "3.2.40",
- "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.40.tgz",
- "integrity": "sha512-tzqwniIN1fu1PDHC3CpqY/dPCfN/RN1thpBC+g69kJcrl7mbGiHKNwbA6kJ3XKKy8R6JLKqcpVugqN4HkeBFFg==",
+ "version": "3.2.45",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.45.tgz",
+ "integrity": "sha512-1jXDuWah1ggsnSAOGsec8cFjT/K6TMZ0sPL3o3d84Ft2AYZi2jWJgRMjw4iaK0rBfA89L5gw427H4n1RZQBu6Q==",
"dependencies": {
"@babel/parser": "^7.16.4",
- "@vue/compiler-core": "3.2.40",
- "@vue/compiler-dom": "3.2.40",
- "@vue/compiler-ssr": "3.2.40",
- "@vue/reactivity-transform": "3.2.40",
- "@vue/shared": "3.2.40",
+ "@vue/compiler-core": "3.2.45",
+ "@vue/compiler-dom": "3.2.45",
+ "@vue/compiler-ssr": "3.2.45",
+ "@vue/reactivity-transform": "3.2.45",
+ "@vue/shared": "3.2.45",
"estree-walker": "^2.0.2",
"magic-string": "^0.25.7",
"postcss": "^8.1.10",
@@ -3042,12 +3050,12 @@
}
},
"node_modules/@vue/compiler-ssr": {
- "version": "3.2.40",
- "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.40.tgz",
- "integrity": "sha512-80cQcgasKjrPPuKcxwuCx7feq+wC6oFl5YaKSee9pV3DNq+6fmCVwEEC3vvkf/E2aI76rIJSOYHsWSEIxK74oQ==",
+ "version": "3.2.45",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.45.tgz",
+ "integrity": "sha512-6BRaggEGqhWht3lt24CrIbQSRD5O07MTmd+LjAn5fJj568+R9eUD2F7wMQJjX859seSlrYog7sUtrZSd7feqrQ==",
"dependencies": {
- "@vue/compiler-dom": "3.2.40",
- "@vue/shared": "3.2.40"
+ "@vue/compiler-dom": "3.2.45",
+ "@vue/shared": "3.2.45"
}
},
"node_modules/@vue/component-compiler-utils": {
@@ -3115,9 +3123,9 @@
"dev": true
},
"node_modules/@vue/devtools-api": {
- "version": "6.1.4",
- "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.1.4.tgz",
- "integrity": "sha512-IiA0SvDrJEgXvVxjNkHPFfDx6SXw0b/TUkqMcDZWNg9fnCAHbTpoo59YfJ9QLFkwa3raau5vSlRVzMSLDnfdtQ=="
+ "version": "6.4.5",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.4.5.tgz",
+ "integrity": "sha512-JD5fcdIuFxU4fQyXUu3w2KpAJHzTVdN+p4iOX2lMWSHMOoQdMAcpFLZzm9Z/2nmsoZ1a96QEhZ26e50xLBsgOQ=="
},
"node_modules/@vue/eslint-config-prettier": {
"version": "7.0.0",
@@ -3152,60 +3160,60 @@
}
},
"node_modules/@vue/reactivity": {
- "version": "3.2.40",
- "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.40.tgz",
- "integrity": "sha512-N9qgGLlZmtUBMHF9xDT4EkD9RdXde1Xbveb+niWMXuHVWQP5BzgRmE3SFyUBBcyayG4y1lhoz+lphGRRxxK4RA==",
+ "version": "3.2.45",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.45.tgz",
+ "integrity": "sha512-PRvhCcQcyEVohW0P8iQ7HDcIOXRjZfAsOds3N99X/Dzewy8TVhTCT4uXpAHfoKjVTJRA0O0K+6QNkDIZAxNi3A==",
"dependencies": {
- "@vue/shared": "3.2.40"
+ "@vue/shared": "3.2.45"
}
},
"node_modules/@vue/reactivity-transform": {
- "version": "3.2.40",
- "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.40.tgz",
- "integrity": "sha512-HQUCVwEaacq6fGEsg2NUuGKIhUveMCjOk8jGHqLXPI2w6zFoPrlQhwWEaINTv5kkZDXKEnCijAp+4gNEHG03yw==",
+ "version": "3.2.45",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.45.tgz",
+ "integrity": "sha512-BHVmzYAvM7vcU5WmuYqXpwaBHjsS8T63jlKGWVtHxAHIoMIlmaMyurUSEs1Zcg46M4AYT5MtB1U274/2aNzjJQ==",
"dependencies": {
"@babel/parser": "^7.16.4",
- "@vue/compiler-core": "3.2.40",
- "@vue/shared": "3.2.40",
+ "@vue/compiler-core": "3.2.45",
+ "@vue/shared": "3.2.45",
"estree-walker": "^2.0.2",
"magic-string": "^0.25.7"
}
},
"node_modules/@vue/runtime-core": {
- "version": "3.2.40",
- "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.40.tgz",
- "integrity": "sha512-U1+rWf0H8xK8aBUZhnrN97yoZfHbjgw/bGUzfgKPJl69/mXDuSg8CbdBYBn6VVQdR947vWneQBFzdhasyzMUKg==",
+ "version": "3.2.45",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.45.tgz",
+ "integrity": "sha512-gzJiTA3f74cgARptqzYswmoQx0fIA+gGYBfokYVhF8YSXjWTUA2SngRzZRku2HbGbjzB6LBYSbKGIaK8IW+s0A==",
"dependencies": {
- "@vue/reactivity": "3.2.40",
- "@vue/shared": "3.2.40"
+ "@vue/reactivity": "3.2.45",
+ "@vue/shared": "3.2.45"
}
},
"node_modules/@vue/runtime-dom": {
- "version": "3.2.40",
- "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.40.tgz",
- "integrity": "sha512-AO2HMQ+0s2+MCec8hXAhxMgWhFhOPJ/CyRXnmTJ6XIOnJFLrH5Iq3TNwvVcODGR295jy77I6dWPj+wvFoSYaww==",
+ "version": "3.2.45",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.45.tgz",
+ "integrity": "sha512-cy88YpfP5Ue2bDBbj75Cb4bIEZUMM/mAkDMfqDTpUYVgTf/kuQ2VQ8LebuZ8k6EudgH8pYhsGWHlY0lcxlvTwA==",
"dependencies": {
- "@vue/runtime-core": "3.2.40",
- "@vue/shared": "3.2.40",
+ "@vue/runtime-core": "3.2.45",
+ "@vue/shared": "3.2.45",
"csstype": "^2.6.8"
}
},
"node_modules/@vue/server-renderer": {
- "version": "3.2.40",
- "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.40.tgz",
- "integrity": "sha512-gtUcpRwrXOJPJ4qyBpU3EyxQa4EkV8I4f8VrDePcGCPe4O/hd0BPS7v9OgjIQob6Ap8VDz9G+mGTKazE45/95w==",
+ "version": "3.2.45",
+ "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.45.tgz",
+ "integrity": "sha512-ebiMq7q24WBU1D6uhPK//2OTR1iRIyxjF5iVq/1a5I1SDMDyDu4Ts6fJaMnjrvD3MqnaiFkKQj+LKAgz5WIK3g==",
"dependencies": {
- "@vue/compiler-ssr": "3.2.40",
- "@vue/shared": "3.2.40"
+ "@vue/compiler-ssr": "3.2.45",
+ "@vue/shared": "3.2.45"
},
"peerDependencies": {
- "vue": "3.2.40"
+ "vue": "3.2.45"
}
},
"node_modules/@vue/shared": {
- "version": "3.2.40",
- "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.40.tgz",
- "integrity": "sha512-0PLQ6RUtZM0vO3teRfzGi4ltLUO5aO+kLgwh4Um3THSR03rpQWLTuRCkuO5A41ITzwdWeKdPHtSARuPkoo5pCQ=="
+ "version": "3.2.45",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.45.tgz",
+ "integrity": "sha512-Ewzq5Yhimg7pSztDV+RH1UDKBzmtqieXQlpTVm2AwraoRL/Rks96mvd8Vgi7Lj+h+TH8dv7mXD3FRZR3TUvbSg=="
},
"node_modules/@vue/vue-loader-v15": {
"name": "vue-loader",
@@ -4811,9 +4819,9 @@
}
},
"node_modules/core-js": {
- "version": "3.25.5",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.25.5.tgz",
- "integrity": "sha512-nbm6eZSjm+ZuBQxCUPQKQCoUEfFOXjUZ8dTTyikyKaWrTYmAVbykQfwsKE5dBK88u3QCkCrzsx/PPlKfhsvgpw==",
+ "version": "3.26.1",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.26.1.tgz",
+ "integrity": "sha512-21491RRQVzUn0GGM9Z1Jrpr6PNPxPi+Za8OM9q4tksTSnlbXXGKK1nXNg/QvwFYettXvSX6zWKCtHHfjN4puyA==",
"hasInstallScript": true,
"funding": {
"type": "opencollective",
@@ -5902,14 +5910,15 @@
}
},
"node_modules/eslint": {
- "version": "8.25.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.25.0.tgz",
- "integrity": "sha512-DVlJOZ4Pn50zcKW5bYH7GQK/9MsoQG2d5eDH0ebEkE8PbgzTTmtt/VTH9GGJ4BfeZCpBLqFfvsjX35UacUL83A==",
+ "version": "8.27.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.27.0.tgz",
+ "integrity": "sha512-0y1bfG2ho7mty+SiILVf9PfuRA49ek4Nc60Wmmu62QlobNR+CeXa4xXIJgcuwSQgZiWaPH+5BDsctpIW0PR/wQ==",
"dev": true,
"dependencies": {
"@eslint/eslintrc": "^1.3.3",
- "@humanwhocodes/config-array": "^0.10.5",
+ "@humanwhocodes/config-array": "^0.11.6",
"@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
"ajv": "^6.10.0",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
@@ -5925,14 +5934,14 @@
"fast-deep-equal": "^3.1.3",
"file-entry-cache": "^6.0.1",
"find-up": "^5.0.0",
- "glob-parent": "^6.0.1",
+ "glob-parent": "^6.0.2",
"globals": "^13.15.0",
- "globby": "^11.1.0",
"grapheme-splitter": "^1.0.4",
"ignore": "^5.2.0",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
"is-glob": "^4.0.0",
+ "is-path-inside": "^3.0.3",
"js-sdsl": "^4.1.4",
"js-yaml": "^4.1.0",
"json-stable-stringify-without-jsonify": "^1.0.1",
@@ -7121,9 +7130,9 @@
}
},
"node_modules/gitart-vue-dialog": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/gitart-vue-dialog/-/gitart-vue-dialog-2.4.0.tgz",
- "integrity": "sha512-ko7q7ftZ8gJ0gOsL6/9NYlSyc1DEI2Ez32kXmRfO64mreYMD6z2U4eporL/lz1kBP9XtgORVBJcvXDeJDL/94g==",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/gitart-vue-dialog/-/gitart-vue-dialog-2.4.1.tgz",
+ "integrity": "sha512-eVYQiHhCRtw4fR7eCUbD4Sj3KDF8ZJt22We1SOkHsdbEAzjwqgjAiYAAgKcLT16FXMjURv8XSWDLU8VNL9Nf3A==",
"peerDependencies": {
"vue": "^3.2.6"
}
@@ -9325,6 +9334,12 @@
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
"dev": true
},
+ "node_modules/natural-compare-lite": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz",
+ "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
+ "dev": true
+ },
"node_modules/negotiator": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
@@ -12529,9 +12544,9 @@
}
},
"node_modules/typescript": {
- "version": "4.8.4",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
- "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
+ "version": "4.9.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz",
+ "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
@@ -12727,15 +12742,15 @@
"integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ=="
},
"node_modules/vue": {
- "version": "3.2.40",
- "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.40.tgz",
- "integrity": "sha512-1mGHulzUbl2Nk3pfvI5aXYYyJUs1nm4kyvuz38u4xlQkLUn1i2R7nDbI4TufECmY8v1qNBHYy62bCaM+3cHP2A==",
+ "version": "3.2.45",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.45.tgz",
+ "integrity": "sha512-9Nx/Mg2b2xWlXykmCwiTUCWHbWIj53bnkizBxKai1g61f2Xit700A1ljowpTIM11e3uipOeiPcSqnmBg6gyiaA==",
"dependencies": {
- "@vue/compiler-dom": "3.2.40",
- "@vue/compiler-sfc": "3.2.40",
- "@vue/runtime-dom": "3.2.40",
- "@vue/server-renderer": "3.2.40",
- "@vue/shared": "3.2.40"
+ "@vue/compiler-dom": "3.2.45",
+ "@vue/compiler-sfc": "3.2.45",
+ "@vue/runtime-dom": "3.2.45",
+ "@vue/server-renderer": "3.2.45",
+ "@vue/shared": "3.2.45"
}
},
"node_modules/vue-chart-3": {
@@ -12933,11 +12948,11 @@
}
},
"node_modules/vue-router": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.1.5.tgz",
- "integrity": "sha512-IsvoF5D2GQ/EGTs/Th4NQms9gd2NSqV+yylxIyp/OYp8xOwxmU8Kj/74E9DTSYAyH5LX7idVUngN3JSj1X4xcQ==",
+ "version": "4.1.6",
+ "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.1.6.tgz",
+ "integrity": "sha512-DYWYwsG6xNPmLq/FmZn8Ip+qrhFEzA14EI12MsMgVxvHFDYvlr4NXpVF5hrRH1wVcDP8fGi5F4rxuJSl8/r+EQ==",
"dependencies": {
- "@vue/devtools-api": "^6.1.4"
+ "@vue/devtools-api": "^6.4.5"
},
"funding": {
"url": "https://github.com/sponsors/posva"
@@ -15004,9 +15019,9 @@
"requires": {}
},
"@humanwhocodes/config-array": {
- "version": "0.10.5",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.5.tgz",
- "integrity": "sha512-XVVDtp+dVvRxMoxSiSfasYaG02VEe1qH5cKgMQJWhol6HwzbcqoCMJi8dAGoYAO57jhUyhI6cWuRiTcRaDaYug==",
+ "version": "0.11.6",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.6.tgz",
+ "integrity": "sha512-jJr+hPTJYKyDILJfhNSHsjiwXYf26Flsz8DvNndOsHs5pwSnpGUEy8yzF0JYhCEvTDdV2vuOK5tt8BVhwO5/hg==",
"dev": true,
"requires": {
"@humanwhocodes/object-schema": "^1.2.1",
@@ -15357,6 +15372,12 @@
"integrity": "sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==",
"dev": true
},
+ "@types/semver": {
+ "version": "7.3.13",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz",
+ "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==",
+ "dev": true
+ },
"@types/serve-index": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz",
@@ -15401,16 +15422,17 @@
}
},
"@typescript-eslint/eslint-plugin": {
- "version": "5.40.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.40.0.tgz",
- "integrity": "sha512-FIBZgS3DVJgqPwJzvZTuH4HNsZhHMa9SjxTKAZTlMsPw/UzpEjcf9f4dfgDJEHjK+HboUJo123Eshl6niwEm/Q==",
+ "version": "5.43.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.43.0.tgz",
+ "integrity": "sha512-wNPzG+eDR6+hhW4yobEmpR36jrqqQv1vxBq5LJO3fBAktjkvekfr4BRl+3Fn1CM/A+s8/EiGUbOMDoYqWdbtXA==",
"dev": true,
"requires": {
- "@typescript-eslint/scope-manager": "5.40.0",
- "@typescript-eslint/type-utils": "5.40.0",
- "@typescript-eslint/utils": "5.40.0",
+ "@typescript-eslint/scope-manager": "5.43.0",
+ "@typescript-eslint/type-utils": "5.43.0",
+ "@typescript-eslint/utils": "5.43.0",
"debug": "^4.3.4",
"ignore": "^5.2.0",
+ "natural-compare-lite": "^1.4.0",
"regexpp": "^3.2.0",
"semver": "^7.3.7",
"tsutils": "^3.21.0"
@@ -15428,53 +15450,53 @@
}
},
"@typescript-eslint/parser": {
- "version": "5.40.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.40.0.tgz",
- "integrity": "sha512-Ah5gqyX2ySkiuYeOIDg7ap51/b63QgWZA7w6AHtFrag7aH0lRQPbLzUjk0c9o5/KZ6JRkTTDKShL4AUrQa6/hw==",
+ "version": "5.43.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.43.0.tgz",
+ "integrity": "sha512-2iHUK2Lh7PwNUlhFxxLI2haSDNyXvebBO9izhjhMoDC+S3XI9qt2DGFUsiJ89m2k7gGYch2aEpYqV5F/+nwZug==",
"dev": true,
"requires": {
- "@typescript-eslint/scope-manager": "5.40.0",
- "@typescript-eslint/types": "5.40.0",
- "@typescript-eslint/typescript-estree": "5.40.0",
+ "@typescript-eslint/scope-manager": "5.43.0",
+ "@typescript-eslint/types": "5.43.0",
+ "@typescript-eslint/typescript-estree": "5.43.0",
"debug": "^4.3.4"
}
},
"@typescript-eslint/scope-manager": {
- "version": "5.40.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.40.0.tgz",
- "integrity": "sha512-d3nPmjUeZtEWRvyReMI4I1MwPGC63E8pDoHy0BnrYjnJgilBD3hv7XOiETKLY/zTwI7kCnBDf2vWTRUVpYw0Uw==",
+ "version": "5.43.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.43.0.tgz",
+ "integrity": "sha512-XNWnGaqAtTJsUiZaoiGIrdJYHsUOd3BZ3Qj5zKp9w6km6HsrjPk/TGZv0qMTWyWj0+1QOqpHQ2gZOLXaGA9Ekw==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "5.40.0",
- "@typescript-eslint/visitor-keys": "5.40.0"
+ "@typescript-eslint/types": "5.43.0",
+ "@typescript-eslint/visitor-keys": "5.43.0"
}
},
"@typescript-eslint/type-utils": {
- "version": "5.40.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.40.0.tgz",
- "integrity": "sha512-nfuSdKEZY2TpnPz5covjJqav+g5qeBqwSHKBvz7Vm1SAfy93SwKk/JeSTymruDGItTwNijSsno5LhOHRS1pcfw==",
+ "version": "5.43.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.43.0.tgz",
+ "integrity": "sha512-K21f+KY2/VvYggLf5Pk4tgBOPs2otTaIHy2zjclo7UZGLyFH86VfUOm5iq+OtDtxq/Zwu2I3ujDBykVW4Xtmtg==",
"dev": true,
"requires": {
- "@typescript-eslint/typescript-estree": "5.40.0",
- "@typescript-eslint/utils": "5.40.0",
+ "@typescript-eslint/typescript-estree": "5.43.0",
+ "@typescript-eslint/utils": "5.43.0",
"debug": "^4.3.4",
"tsutils": "^3.21.0"
}
},
"@typescript-eslint/types": {
- "version": "5.40.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.40.0.tgz",
- "integrity": "sha512-V1KdQRTXsYpf1Y1fXCeZ+uhjW48Niiw0VGt4V8yzuaDTU8Z1Xl7yQDyQNqyAFcVhpYXIVCEuxSIWTsLDpHgTbw==",
+ "version": "5.43.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.43.0.tgz",
+ "integrity": "sha512-jpsbcD0x6AUvV7tyOlyvon0aUsQpF8W+7TpJntfCUWU1qaIKu2K34pMwQKSzQH8ORgUrGYY6pVIh1Pi8TNeteg==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
- "version": "5.40.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.40.0.tgz",
- "integrity": "sha512-b0GYlDj8TLTOqwX7EGbw2gL5EXS2CPEWhF9nGJiGmEcmlpNBjyHsTwbqpyIEPVpl6br4UcBOYlcI2FJVtJkYhg==",
+ "version": "5.43.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.43.0.tgz",
+ "integrity": "sha512-BZ1WVe+QQ+igWal2tDbNg1j2HWUkAa+CVqdU79L4HP9izQY6CNhXfkNwd1SS4+sSZAP/EthI1uiCSY/+H0pROg==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "5.40.0",
- "@typescript-eslint/visitor-keys": "5.40.0",
+ "@typescript-eslint/types": "5.43.0",
+ "@typescript-eslint/visitor-keys": "5.43.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -15494,15 +15516,16 @@
}
},
"@typescript-eslint/utils": {
- "version": "5.40.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.40.0.tgz",
- "integrity": "sha512-MO0y3T5BQ5+tkkuYZJBjePewsY+cQnfkYeRqS6tPh28niiIwPnQ1t59CSRcs1ZwJJNOdWw7rv9pF8aP58IMihA==",
+ "version": "5.43.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.43.0.tgz",
+ "integrity": "sha512-8nVpA6yX0sCjf7v/NDfeaOlyaIIqL7OaIGOWSPFqUKK59Gnumd3Wa+2l8oAaYO2lk0sO+SbWFWRSvhu8gLGv4A==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.9",
- "@typescript-eslint/scope-manager": "5.40.0",
- "@typescript-eslint/types": "5.40.0",
- "@typescript-eslint/typescript-estree": "5.40.0",
+ "@types/semver": "^7.3.12",
+ "@typescript-eslint/scope-manager": "5.43.0",
+ "@typescript-eslint/types": "5.43.0",
+ "@typescript-eslint/typescript-estree": "5.43.0",
"eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0",
"semver": "^7.3.7"
@@ -15520,12 +15543,12 @@
}
},
"@typescript-eslint/visitor-keys": {
- "version": "5.40.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.40.0.tgz",
- "integrity": "sha512-ijJ+6yig+x9XplEpG2K6FUdJeQGGj/15U3S56W9IqXKJqleuD7zJ2AX/miLezwxpd7ZxDAqO87zWufKg+RPZyQ==",
+ "version": "5.43.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.43.0.tgz",
+ "integrity": "sha512-icl1jNH/d18OVHLfcwdL3bWUKsBeIiKYTGxMJCoGe7xFht+E4QgzOqoWYrU8XSLJWhVw8nTacbm03v23J/hFTg==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "5.40.0",
+ "@typescript-eslint/types": "5.43.0",
"eslint-visitor-keys": "^3.3.0"
}
},
@@ -15935,36 +15958,36 @@
}
},
"@vue/compiler-core": {
- "version": "3.2.40",
- "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.40.tgz",
- "integrity": "sha512-2Dc3Stk0J/VyQ4OUr2yEC53kU28614lZS+bnrCbFSAIftBJ40g/2yQzf4mPBiFuqguMB7hyHaujdgZAQ67kZYA==",
+ "version": "3.2.45",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.45.tgz",
+ "integrity": "sha512-rcMj7H+PYe5wBV3iYeUgbCglC+pbpN8hBLTJvRiK2eKQiWqu+fG9F+8sW99JdL4LQi7Re178UOxn09puSXvn4A==",
"requires": {
"@babel/parser": "^7.16.4",
- "@vue/shared": "3.2.40",
+ "@vue/shared": "3.2.45",
"estree-walker": "^2.0.2",
"source-map": "^0.6.1"
}
},
"@vue/compiler-dom": {
- "version": "3.2.40",
- "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.40.tgz",
- "integrity": "sha512-OZCNyYVC2LQJy4H7h0o28rtk+4v+HMQygRTpmibGoG9wZyomQiS5otU7qo3Wlq5UfHDw2RFwxb9BJgKjVpjrQw==",
+ "version": "3.2.45",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.45.tgz",
+ "integrity": "sha512-tyYeUEuKqqZO137WrZkpwfPCdiiIeXYCcJ8L4gWz9vqaxzIQRccTSwSWZ/Axx5YR2z+LvpUbmPNXxuBU45lyRw==",
"requires": {
- "@vue/compiler-core": "3.2.40",
- "@vue/shared": "3.2.40"
+ "@vue/compiler-core": "3.2.45",
+ "@vue/shared": "3.2.45"
}
},
"@vue/compiler-sfc": {
- "version": "3.2.40",
- "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.40.tgz",
- "integrity": "sha512-tzqwniIN1fu1PDHC3CpqY/dPCfN/RN1thpBC+g69kJcrl7mbGiHKNwbA6kJ3XKKy8R6JLKqcpVugqN4HkeBFFg==",
+ "version": "3.2.45",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.45.tgz",
+ "integrity": "sha512-1jXDuWah1ggsnSAOGsec8cFjT/K6TMZ0sPL3o3d84Ft2AYZi2jWJgRMjw4iaK0rBfA89L5gw427H4n1RZQBu6Q==",
"requires": {
"@babel/parser": "^7.16.4",
- "@vue/compiler-core": "3.2.40",
- "@vue/compiler-dom": "3.2.40",
- "@vue/compiler-ssr": "3.2.40",
- "@vue/reactivity-transform": "3.2.40",
- "@vue/shared": "3.2.40",
+ "@vue/compiler-core": "3.2.45",
+ "@vue/compiler-dom": "3.2.45",
+ "@vue/compiler-ssr": "3.2.45",
+ "@vue/reactivity-transform": "3.2.45",
+ "@vue/shared": "3.2.45",
"estree-walker": "^2.0.2",
"magic-string": "^0.25.7",
"postcss": "^8.1.10",
@@ -15972,12 +15995,12 @@
}
},
"@vue/compiler-ssr": {
- "version": "3.2.40",
- "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.40.tgz",
- "integrity": "sha512-80cQcgasKjrPPuKcxwuCx7feq+wC6oFl5YaKSee9pV3DNq+6fmCVwEEC3vvkf/E2aI76rIJSOYHsWSEIxK74oQ==",
+ "version": "3.2.45",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.45.tgz",
+ "integrity": "sha512-6BRaggEGqhWht3lt24CrIbQSRD5O07MTmd+LjAn5fJj568+R9eUD2F7wMQJjX859seSlrYog7sUtrZSd7feqrQ==",
"requires": {
- "@vue/compiler-dom": "3.2.40",
- "@vue/shared": "3.2.40"
+ "@vue/compiler-dom": "3.2.45",
+ "@vue/shared": "3.2.45"
}
},
"@vue/component-compiler-utils": {
@@ -16038,9 +16061,9 @@
}
},
"@vue/devtools-api": {
- "version": "6.1.4",
- "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.1.4.tgz",
- "integrity": "sha512-IiA0SvDrJEgXvVxjNkHPFfDx6SXw0b/TUkqMcDZWNg9fnCAHbTpoo59YfJ9QLFkwa3raau5vSlRVzMSLDnfdtQ=="
+ "version": "6.4.5",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.4.5.tgz",
+ "integrity": "sha512-JD5fcdIuFxU4fQyXUu3w2KpAJHzTVdN+p4iOX2lMWSHMOoQdMAcpFLZzm9Z/2nmsoZ1a96QEhZ26e50xLBsgOQ=="
},
"@vue/eslint-config-prettier": {
"version": "7.0.0",
@@ -16064,57 +16087,57 @@
}
},
"@vue/reactivity": {
- "version": "3.2.40",
- "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.40.tgz",
- "integrity": "sha512-N9qgGLlZmtUBMHF9xDT4EkD9RdXde1Xbveb+niWMXuHVWQP5BzgRmE3SFyUBBcyayG4y1lhoz+lphGRRxxK4RA==",
+ "version": "3.2.45",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.45.tgz",
+ "integrity": "sha512-PRvhCcQcyEVohW0P8iQ7HDcIOXRjZfAsOds3N99X/Dzewy8TVhTCT4uXpAHfoKjVTJRA0O0K+6QNkDIZAxNi3A==",
"requires": {
- "@vue/shared": "3.2.40"
+ "@vue/shared": "3.2.45"
}
},
"@vue/reactivity-transform": {
- "version": "3.2.40",
- "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.40.tgz",
- "integrity": "sha512-HQUCVwEaacq6fGEsg2NUuGKIhUveMCjOk8jGHqLXPI2w6zFoPrlQhwWEaINTv5kkZDXKEnCijAp+4gNEHG03yw==",
+ "version": "3.2.45",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.45.tgz",
+ "integrity": "sha512-BHVmzYAvM7vcU5WmuYqXpwaBHjsS8T63jlKGWVtHxAHIoMIlmaMyurUSEs1Zcg46M4AYT5MtB1U274/2aNzjJQ==",
"requires": {
"@babel/parser": "^7.16.4",
- "@vue/compiler-core": "3.2.40",
- "@vue/shared": "3.2.40",
+ "@vue/compiler-core": "3.2.45",
+ "@vue/shared": "3.2.45",
"estree-walker": "^2.0.2",
"magic-string": "^0.25.7"
}
},
"@vue/runtime-core": {
- "version": "3.2.40",
- "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.40.tgz",
- "integrity": "sha512-U1+rWf0H8xK8aBUZhnrN97yoZfHbjgw/bGUzfgKPJl69/mXDuSg8CbdBYBn6VVQdR947vWneQBFzdhasyzMUKg==",
+ "version": "3.2.45",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.45.tgz",
+ "integrity": "sha512-gzJiTA3f74cgARptqzYswmoQx0fIA+gGYBfokYVhF8YSXjWTUA2SngRzZRku2HbGbjzB6LBYSbKGIaK8IW+s0A==",
"requires": {
- "@vue/reactivity": "3.2.40",
- "@vue/shared": "3.2.40"
+ "@vue/reactivity": "3.2.45",
+ "@vue/shared": "3.2.45"
}
},
"@vue/runtime-dom": {
- "version": "3.2.40",
- "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.40.tgz",
- "integrity": "sha512-AO2HMQ+0s2+MCec8hXAhxMgWhFhOPJ/CyRXnmTJ6XIOnJFLrH5Iq3TNwvVcODGR295jy77I6dWPj+wvFoSYaww==",
+ "version": "3.2.45",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.45.tgz",
+ "integrity": "sha512-cy88YpfP5Ue2bDBbj75Cb4bIEZUMM/mAkDMfqDTpUYVgTf/kuQ2VQ8LebuZ8k6EudgH8pYhsGWHlY0lcxlvTwA==",
"requires": {
- "@vue/runtime-core": "3.2.40",
- "@vue/shared": "3.2.40",
+ "@vue/runtime-core": "3.2.45",
+ "@vue/shared": "3.2.45",
"csstype": "^2.6.8"
}
},
"@vue/server-renderer": {
- "version": "3.2.40",
- "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.40.tgz",
- "integrity": "sha512-gtUcpRwrXOJPJ4qyBpU3EyxQa4EkV8I4f8VrDePcGCPe4O/hd0BPS7v9OgjIQob6Ap8VDz9G+mGTKazE45/95w==",
+ "version": "3.2.45",
+ "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.45.tgz",
+ "integrity": "sha512-ebiMq7q24WBU1D6uhPK//2OTR1iRIyxjF5iVq/1a5I1SDMDyDu4Ts6fJaMnjrvD3MqnaiFkKQj+LKAgz5WIK3g==",
"requires": {
- "@vue/compiler-ssr": "3.2.40",
- "@vue/shared": "3.2.40"
+ "@vue/compiler-ssr": "3.2.45",
+ "@vue/shared": "3.2.45"
}
},
"@vue/shared": {
- "version": "3.2.40",
- "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.40.tgz",
- "integrity": "sha512-0PLQ6RUtZM0vO3teRfzGi4ltLUO5aO+kLgwh4Um3THSR03rpQWLTuRCkuO5A41ITzwdWeKdPHtSARuPkoo5pCQ=="
+ "version": "3.2.45",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.45.tgz",
+ "integrity": "sha512-Ewzq5Yhimg7pSztDV+RH1UDKBzmtqieXQlpTVm2AwraoRL/Rks96mvd8Vgi7Lj+h+TH8dv7mXD3FRZR3TUvbSg=="
},
"@vue/vue-loader-v15": {
"version": "npm:vue-loader@15.9.8",
@@ -17351,9 +17374,9 @@
}
},
"core-js": {
- "version": "3.25.5",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.25.5.tgz",
- "integrity": "sha512-nbm6eZSjm+ZuBQxCUPQKQCoUEfFOXjUZ8dTTyikyKaWrTYmAVbykQfwsKE5dBK88u3QCkCrzsx/PPlKfhsvgpw=="
+ "version": "3.26.1",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.26.1.tgz",
+ "integrity": "sha512-21491RRQVzUn0GGM9Z1Jrpr6PNPxPi+Za8OM9q4tksTSnlbXXGKK1nXNg/QvwFYettXvSX6zWKCtHHfjN4puyA=="
},
"core-js-compat": {
"version": "3.23.4",
@@ -18192,14 +18215,15 @@
"dev": true
},
"eslint": {
- "version": "8.25.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.25.0.tgz",
- "integrity": "sha512-DVlJOZ4Pn50zcKW5bYH7GQK/9MsoQG2d5eDH0ebEkE8PbgzTTmtt/VTH9GGJ4BfeZCpBLqFfvsjX35UacUL83A==",
+ "version": "8.27.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.27.0.tgz",
+ "integrity": "sha512-0y1bfG2ho7mty+SiILVf9PfuRA49ek4Nc60Wmmu62QlobNR+CeXa4xXIJgcuwSQgZiWaPH+5BDsctpIW0PR/wQ==",
"dev": true,
"requires": {
"@eslint/eslintrc": "^1.3.3",
- "@humanwhocodes/config-array": "^0.10.5",
+ "@humanwhocodes/config-array": "^0.11.6",
"@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
"ajv": "^6.10.0",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
@@ -18215,14 +18239,14 @@
"fast-deep-equal": "^3.1.3",
"file-entry-cache": "^6.0.1",
"find-up": "^5.0.0",
- "glob-parent": "^6.0.1",
+ "glob-parent": "^6.0.2",
"globals": "^13.15.0",
- "globby": "^11.1.0",
"grapheme-splitter": "^1.0.4",
"ignore": "^5.2.0",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
"is-glob": "^4.0.0",
+ "is-path-inside": "^3.0.3",
"js-sdsl": "^4.1.4",
"js-yaml": "^4.1.0",
"json-stable-stringify-without-jsonify": "^1.0.1",
@@ -19062,9 +19086,9 @@
}
},
"gitart-vue-dialog": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/gitart-vue-dialog/-/gitart-vue-dialog-2.4.0.tgz",
- "integrity": "sha512-ko7q7ftZ8gJ0gOsL6/9NYlSyc1DEI2Ez32kXmRfO64mreYMD6z2U4eporL/lz1kBP9XtgORVBJcvXDeJDL/94g==",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/gitart-vue-dialog/-/gitart-vue-dialog-2.4.1.tgz",
+ "integrity": "sha512-eVYQiHhCRtw4fR7eCUbD4Sj3KDF8ZJt22We1SOkHsdbEAzjwqgjAiYAAgKcLT16FXMjURv8XSWDLU8VNL9Nf3A==",
"requires": {}
},
"glob": {
@@ -20667,6 +20691,12 @@
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
"dev": true
},
+ "natural-compare-lite": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz",
+ "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
+ "dev": true
+ },
"negotiator": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
@@ -23038,9 +23068,9 @@
}
},
"typescript": {
- "version": "4.8.4",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
- "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
+ "version": "4.9.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz",
+ "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==",
"dev": true
},
"unbox-primitive": {
@@ -23185,15 +23215,15 @@
"integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ=="
},
"vue": {
- "version": "3.2.40",
- "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.40.tgz",
- "integrity": "sha512-1mGHulzUbl2Nk3pfvI5aXYYyJUs1nm4kyvuz38u4xlQkLUn1i2R7nDbI4TufECmY8v1qNBHYy62bCaM+3cHP2A==",
+ "version": "3.2.45",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.45.tgz",
+ "integrity": "sha512-9Nx/Mg2b2xWlXykmCwiTUCWHbWIj53bnkizBxKai1g61f2Xit700A1ljowpTIM11e3uipOeiPcSqnmBg6gyiaA==",
"requires": {
- "@vue/compiler-dom": "3.2.40",
- "@vue/compiler-sfc": "3.2.40",
- "@vue/runtime-dom": "3.2.40",
- "@vue/server-renderer": "3.2.40",
- "@vue/shared": "3.2.40"
+ "@vue/compiler-dom": "3.2.45",
+ "@vue/compiler-sfc": "3.2.45",
+ "@vue/runtime-dom": "3.2.45",
+ "@vue/server-renderer": "3.2.45",
+ "@vue/shared": "3.2.45"
}
},
"vue-chart-3": {
@@ -23342,11 +23372,11 @@
}
},
"vue-router": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.1.5.tgz",
- "integrity": "sha512-IsvoF5D2GQ/EGTs/Th4NQms9gd2NSqV+yylxIyp/OYp8xOwxmU8Kj/74E9DTSYAyH5LX7idVUngN3JSj1X4xcQ==",
+ "version": "4.1.6",
+ "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.1.6.tgz",
+ "integrity": "sha512-DYWYwsG6xNPmLq/FmZn8Ip+qrhFEzA14EI12MsMgVxvHFDYvlr4NXpVF5hrRH1wVcDP8fGi5F4rxuJSl8/r+EQ==",
"requires": {
- "@vue/devtools-api": "^6.1.4"
+ "@vue/devtools-api": "^6.4.5"
}
},
"vue-style-loader": {
diff --git a/report-viewer/package.json b/report-viewer/package.json
index e18f2eaaf..e7e56c2bc 100644
--- a/report-viewer/package.json
+++ b/report-viewer/package.json
@@ -12,22 +12,22 @@
"@highlightjs/vue-plugin": "^2.1.0",
"chart.js": "^3.9.1",
"chartjs-plugin-datalabels": "^2.1.0",
- "core-js": "^3.25.5",
- "gitart-vue-dialog": "^2.4.0",
+ "core-js": "^3.26.1",
+ "gitart-vue-dialog": "^2.4.1",
"highlight.js": "^11.6.0",
"jszip": "^3.10.0",
"node-polyfill-webpack-plugin": "^2.0.0",
"slash": "^5.0.0",
- "vue": "^3.2.40",
+ "vue": "^3.2.45",
"vue-chart-3": "^3.1.8",
"vue-draggable-next": "^2.1.1",
- "vue-router": "^4.1.5",
+ "vue-router": "^4.1.6",
"vue3-highlightjs": "^1.0.5",
"vuex": "^4.0.2"
},
"devDependencies": {
- "@typescript-eslint/eslint-plugin": "^5.40.0",
- "@typescript-eslint/parser": "^5.40.0",
+ "@typescript-eslint/eslint-plugin": "^5.43.0",
+ "@typescript-eslint/parser": "^5.43.0",
"@vue/cli-plugin-babel": "~5.0.8",
"@vue/cli-plugin-eslint": "~5.0.8",
"@vue/cli-plugin-router": "~5.0.8",
@@ -36,12 +36,12 @@
"@vue/compiler-sfc": "^3.2.39",
"@vue/eslint-config-prettier": "^7.0.0",
"@vue/eslint-config-typescript": "^10.0.0",
- "eslint": "^8.25.0",
+ "eslint": "^8.27.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-vue": "^8.7.1",
"lint-staged": "^13.0.3",
"prettier": "^2.7.1",
- "typescript": "~4.8.4"
+ "typescript": "~4.9.3"
},
"gitHooks": {
"pre-commit": "lint-staged"