mirror of
https://github.com/RatzzFatzz/MKVAudioSubtitleChanger.git
synced 2026-02-11 10:05:58 +01:00
Major system rework
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.converter;
|
||||
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.converter.AttributeConfigConverter;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.fields;
|
||||
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.fields;
|
||||
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import picocli.CommandLine;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.fields;
|
||||
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig;
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.fields;
|
||||
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.fields;
|
||||
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.fields;
|
||||
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl;
|
||||
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ResultStatistic;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.DateUtils;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
@@ -16,7 +17,9 @@ import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@@ -34,38 +37,44 @@ class FileFilterTest {
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
|
||||
ResultStatistic.getInstance(true);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> accept() {
|
||||
return Stream.of(
|
||||
Arguments.of("~/video.mkv", new String[]{".mkv"}, null, null, ".*", true),
|
||||
Arguments.of("~/video.mp4", new String[]{".mkv"}, null, null, ".*", false),
|
||||
Arguments.of("~/video.mkv", Set.of(".mkv"), -1, ".*", true, 1, 0),
|
||||
Arguments.of("~/video.mp4", Set.of(".mkv"), -1, ".*", false, 0, 0),
|
||||
|
||||
Arguments.of("~/video.mkv", new String[]{".mkv"}, null, null, "v.*", true),
|
||||
Arguments.of("~/video.mkv", new String[]{".mkv"}, null, null, "a.*", false),
|
||||
Arguments.of("~/video.mkv", Set.of(".mkv"), -1, "v.*", true, 1, 0),
|
||||
Arguments.of("~/video.mkv", Set.of(".mkv"), -1, "a.*", false, 1, 1),
|
||||
|
||||
Arguments.of("~/video.mkv", new String[]{".mkv"}, new Date(System.currentTimeMillis() - 1000), new Date(), ".*", false),
|
||||
Arguments.of("~/video.mkv", new String[]{".mkv"}, new Date(), new Date(System.currentTimeMillis() - 1000), ".*", true)
|
||||
Arguments.of("~/video.mkv", Set.of(".mkv"), -1000, ".*", true, 1, 0),
|
||||
Arguments.of("~/video.mkv", Set.of(".mkv"), 1000, ".*", false, 1, 1)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param filterDateOffset move filter data into the future or past by positive and negative values
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void accept(String path, String[] args, Date fileCreationDate, Date filterDate, String pattern, boolean expected) {
|
||||
void accept(String path, Set<String> args, int filterDateOffset, String pattern, boolean expectedHit, int total, int excluded) {
|
||||
when(file.getAbsolutePath()).thenReturn(path);
|
||||
when(file.getName()).thenReturn(List.of(path.split("/")).get(1));
|
||||
when(file.toPath()).thenReturn(Path.of(TEST_FILE));
|
||||
|
||||
InputConfig.getInstance(true).setIncludePattern(Pattern.compile(pattern));
|
||||
if (filterDate != null) InputConfig.getInstance().setFilterDate(filterDate);
|
||||
long currentTime = System.currentTimeMillis();
|
||||
InputConfig.getInstance().setFilterDate(new Date(currentTime + filterDateOffset));
|
||||
|
||||
try (MockedStatic<DateUtils> mockedFiles = Mockito.mockStatic(DateUtils.class)) {
|
||||
mockedFiles
|
||||
.when(() -> DateUtils.convert(anyLong()))
|
||||
.thenReturn(fileCreationDate);
|
||||
.thenReturn(new Date(currentTime));
|
||||
|
||||
assertEquals(expected, FileFilter.accept(file, args));
|
||||
assertEquals(expectedHit, FileFilter.accept(file, new HashSet<>(args)), "File is accepted");
|
||||
assertEquals(total, ResultStatistic.getInstance().getTotal(), "Total files");
|
||||
assertEquals(excluded, ResultStatistic.getInstance().getExcluded(), "Excluded files");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl;
|
||||
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.processors.MkvFileProcessor;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfo;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.TrackAttributes;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
@@ -29,11 +31,12 @@ class MkvFileProcessorTest {
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void detectDesiredTracks(AttributeConfig expectedMatch, List<FileAttribute> tracks, AttributeConfig... configs) {
|
||||
@Disabled
|
||||
void detectDesiredTracks(AttributeConfig expectedMatch, List<TrackAttributes> tracks, AttributeConfig... configs) {
|
||||
InputConfig.getInstance().setPreferredSubtitles(Set.of());
|
||||
FileInfo info = new FileInfo(null);
|
||||
MkvFileProcessor processor = new MkvFileProcessor();
|
||||
processor.detectDesiredTracks(info, tracks, tracks, configs);
|
||||
// processor.detectDesiredTracks(info, tracks, tracks, configs);
|
||||
assertEquals(expectedMatch.getAudioLanguage(), info.getMatchedConfig().getAudioLanguage());
|
||||
assertEquals(expectedMatch.getSubtitleLanguage(), info.getMatchedConfig().getSubtitleLanguage());
|
||||
}
|
||||
@@ -48,43 +51,4 @@ class MkvFileProcessorTest {
|
||||
Arguments.of(List.of(), List.of())
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void retrieveNonForcedTracks(List<FileAttribute> attributes, List<FileAttribute> expected) {
|
||||
InputConfig.getInstance().setPreferredSubtitles(Set.of());
|
||||
InputConfig.getInstance().setForcedKeywords(Set.of("forced"));
|
||||
MkvFileProcessor processor = new MkvFileProcessor();
|
||||
List<FileAttribute> actual = processor.retrieveNonForcedTracks(attributes);
|
||||
|
||||
assertEquals(expected.size(), actual.size());
|
||||
for (int i = 0; i < expected.size(); i++) {
|
||||
assertEquals(expected.get(i), actual.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
private static Stream<Arguments> retrieveNonCommentaryTracks() {
|
||||
return Stream.of(
|
||||
Arguments.of(List.of(SUB_GER, SUB_ENG, AUDIO_GER_COMMENTARY), List.of(SUB_GER, SUB_ENG)),
|
||||
Arguments.of(List.of(SUB_GER, SUB_ENG), List.of(SUB_GER, SUB_ENG)),
|
||||
Arguments.of(List.of(AUDIO_GER, SUB_GER, SUB_ENG), List.of(AUDIO_GER, SUB_GER, SUB_ENG)),
|
||||
Arguments.of(List.of(AUDIO_GER), List.of(AUDIO_GER)),
|
||||
Arguments.of(List.of(AUDIO_GER_COMMENTARY), List.of()),
|
||||
Arguments.of(List.of(), List.of())
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void retrieveNonCommentaryTracks(List<FileAttribute> attributes, List<FileAttribute> expected) {
|
||||
InputConfig.getInstance().setPreferredSubtitles(Set.of());
|
||||
InputConfig.getInstance().setCommentaryKeywords(Set.of("commentary"));
|
||||
MkvFileProcessor processor = new MkvFileProcessor();
|
||||
List<FileAttribute> actual = processor.retrieveNonCommentaryTracks(attributes);
|
||||
|
||||
assertEquals(expected.size(), actual.size());
|
||||
for (int i = 0; i < expected.size(); i++) {
|
||||
assertEquals(expected.get(i), actual.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl;
|
||||
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.LaneType;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.TrackAttributes;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.TrackType;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
@@ -34,13 +34,13 @@ class SubtitleTrackComparatorTest {
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("compareArguments")
|
||||
void compare(List<FileAttribute> input, List<FileAttribute> expected) {
|
||||
List<FileAttribute> result = input.stream().sorted(comparator.reversed()).collect(Collectors.toList());
|
||||
void compare(List<TrackAttributes> input, List<TrackAttributes> expected) {
|
||||
List<TrackAttributes> result = input.stream().sorted(comparator.reversed()).collect(Collectors.toList());
|
||||
|
||||
assertArrayEquals(expected.toArray(new FileAttribute[0]), result.toArray(new FileAttribute[0]));
|
||||
assertArrayEquals(expected.toArray(new TrackAttributes[0]), result.toArray(new TrackAttributes[0]));
|
||||
}
|
||||
|
||||
private static FileAttribute attr(String trackName, boolean defaultTrack) {
|
||||
return new FileAttribute(0, "", trackName, defaultTrack, false, LaneType.SUBTITLES);
|
||||
private static TrackAttributes attr(String trackName, boolean defaultTrack) {
|
||||
return new TrackAttributes(0, "", trackName, defaultTrack, false, false, false, TrackType.SUBTITLES);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.processors;
|
||||
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfo;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.TrackAttributes;
|
||||
import org.apache.logging.log4j.util.Strings;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.FileInfoTestUtil.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class AttributeProcessorTest {
|
||||
|
||||
private static Stream<Arguments> attributeConfigMatching() {
|
||||
return Stream.of(
|
||||
Arguments.of(
|
||||
List.of(withName(AUDIO_ENG, null), SUB_ENG),
|
||||
arr(a("eng:eng")), "eng:eng",
|
||||
Map.ofEntries(on(withName(AUDIO_ENG, null)), on(SUB_ENG))
|
||||
),
|
||||
Arguments.of(
|
||||
List.of(AUDIO_ENG, SUB_ENG),
|
||||
arr(a("eng:eng")), "eng:eng",
|
||||
Map.ofEntries(on(AUDIO_ENG), on(SUB_ENG))
|
||||
),
|
||||
Arguments.of(
|
||||
List.of(AUDIO_ENG, AUDIO_GER, SUB_ENG, SUB_GER),
|
||||
arr(a("eng:eng")), "eng:eng",
|
||||
Map.ofEntries(on(AUDIO_ENG), on(SUB_ENG))
|
||||
),
|
||||
Arguments.of(
|
||||
List.of(AUDIO_ENG_DEFAULT, AUDIO_GER, SUB_ENG, SUB_GER),
|
||||
arr(a("ger:eng")), "ger:eng",
|
||||
Map.ofEntries(off(AUDIO_ENG_DEFAULT), on(AUDIO_GER), on(SUB_ENG))
|
||||
),
|
||||
Arguments.of(
|
||||
List.of(AUDIO_ENG_DEFAULT, AUDIO_GER, SUB_ENG, SUB_GER),
|
||||
arr(a("eng:ger")), "eng:ger",
|
||||
Map.ofEntries(on(SUB_GER))
|
||||
),
|
||||
Arguments.of(
|
||||
List.of(AUDIO_ENG_DEFAULT, AUDIO_GER, SUB_ENG_DEFAULT, SUB_GER),
|
||||
arr(a("eng:OFF")), "eng:OFF",
|
||||
Map.ofEntries(off(SUB_ENG_DEFAULT))
|
||||
),
|
||||
Arguments.of(
|
||||
List.of(AUDIO_ENG_DEFAULT, AUDIO_GER, SUB_ENG_DEFAULT, SUB_GER),
|
||||
arr(a("OFF:OFF")), "OFF:OFF",
|
||||
Map.ofEntries(off(AUDIO_ENG_DEFAULT), off(SUB_ENG_DEFAULT))
|
||||
),
|
||||
Arguments.of(
|
||||
List.of(AUDIO_ENG_DEFAULT, AUDIO_GER, SUB_GER),
|
||||
arr(a("eng:eng"), a("eng:ger")), "eng:ger",
|
||||
Map.ofEntries(on(SUB_GER))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("attributeConfigMatching")
|
||||
void findDefaultMatchAndApplyChanges(List<TrackAttributes> tracks, AttributeConfig[] config, String expectedConfig, Map<TrackAttributes, Boolean> changes) {
|
||||
InputConfig.getInstance().setPreferredSubtitles(new HashSet<>());
|
||||
InputConfig.getInstance().setCommentaryKeywords(new HashSet<>());
|
||||
InputConfig.getInstance().setForcedKeywords(new HashSet<>());
|
||||
|
||||
FileInfo fileInfo = new FileInfo(null);
|
||||
fileInfo.addTracks(tracks);
|
||||
AttributeProcessor.findDefaultMatchAndApplyChanges(fileInfo, config);
|
||||
assertEquals(Strings.isBlank(expectedConfig), fileInfo.getMatchedConfig() == null);
|
||||
assertEquals(expectedConfig, fileInfo.getMatchedConfig().toStringShort());
|
||||
assertEquals(changes.size(), fileInfo.getChanges().getDefaultTrack().size());
|
||||
changes.forEach((key, value) -> {
|
||||
assertTrue(fileInfo.getChanges().getDefaultTrack().containsKey(key));
|
||||
assertEquals(value, fileInfo.getChanges().getDefaultTrack().get(key));
|
||||
});
|
||||
}
|
||||
|
||||
private static AttributeConfig[] arr(AttributeConfig... configs) {
|
||||
return configs;
|
||||
}
|
||||
|
||||
private static AttributeConfig a(String config) {
|
||||
String[] split = config.split(":");
|
||||
return new AttributeConfig(split[0], split[1]);
|
||||
}
|
||||
|
||||
private static Map.Entry<TrackAttributes, Boolean> on(TrackAttributes track) {
|
||||
return Map.entry(track, true);
|
||||
}
|
||||
|
||||
private static Map.Entry<TrackAttributes, Boolean> off(TrackAttributes track) {
|
||||
return Map.entry(track, false);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> filterForPossibleDefaults() {
|
||||
return Stream.of(
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("filterForPossibleDefaults")
|
||||
void filterForPossibleDefaults(List<TrackAttributes> tracks, Set<TrackAttributes> expected) {
|
||||
|
||||
}
|
||||
|
||||
private static Stream<Arguments> findForcedTracksAndApplyChanges() {
|
||||
return Stream.of(
|
||||
Arguments.of(List.of(withName(SUB_GER, "song & signs"), withName(SUB_GER, null)),
|
||||
Set.of("song & signs"), false,
|
||||
Map.ofEntries(on(withName(SUB_GER, "song & signs")))
|
||||
),
|
||||
Arguments.of(List.of(withName(SUB_GER, "song & signs")),
|
||||
Set.of("song & signs"), false,
|
||||
Map.ofEntries(on(withName(SUB_GER, "song & signs")))
|
||||
),
|
||||
Arguments.of(List.of(withName(SUB_GER_FORCED, "song & signs")),
|
||||
Set.of("song & signs"), false,
|
||||
Map.ofEntries()
|
||||
),
|
||||
Arguments.of(List.of(SUB_GER_FORCED, withName(SUB_GER, "song & signs")),
|
||||
Set.of("song & signs"), true,
|
||||
Map.ofEntries(off(SUB_GER_FORCED), on(withName(SUB_GER, "song & signs")))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("findForcedTracksAndApplyChanges")
|
||||
void findForcedTracksAndApplyChanges(List<TrackAttributes> tracks, Set<String> keywords, boolean overwrite, Map<TrackAttributes, Boolean> changes) {
|
||||
InputConfig.getInstance().setPreferredSubtitles(new HashSet<>());
|
||||
InputConfig.getInstance().setCommentaryKeywords(new HashSet<>());
|
||||
InputConfig.getInstance().setHearingImpaired(new HashSet<>());
|
||||
InputConfig.getInstance().setForcedKeywords(keywords);
|
||||
InputConfig.getInstance().setOverwriteForced(overwrite);
|
||||
|
||||
FileInfo fileInfo = new FileInfo(null);
|
||||
fileInfo.addTracks(tracks);
|
||||
AttributeProcessor.findForcedTracksAndApplyChanges(fileInfo);
|
||||
|
||||
assertEquals(changes.size(), fileInfo.getChanges().getForcedTrack().size());
|
||||
changes.forEach((key, value) -> {
|
||||
assertTrue(fileInfo.getChanges().getForcedTrack().containsKey(key));
|
||||
assertEquals(value, fileInfo.getChanges().getForcedTrack().get(key));
|
||||
});
|
||||
}
|
||||
|
||||
private static Stream<Arguments> findCommentaryTracksAndApplyChanges() {
|
||||
return Stream.of(
|
||||
Arguments.of(List.of(withName(SUB_GER, "commentary"), withName(SUB_GER, null)),
|
||||
Set.of("commentary"),
|
||||
Map.ofEntries(on(withName(SUB_GER, "commentary")))
|
||||
),
|
||||
Arguments.of(List.of(withName(SUB_GER, "commentary")),
|
||||
Set.of("commentary"),
|
||||
Map.ofEntries(on(withName(SUB_GER, "commentary")))
|
||||
),
|
||||
Arguments.of(List.of(withName(AUDIO_GER_COMMENTARY, "commentary")),
|
||||
Set.of("commentary"),
|
||||
Map.ofEntries()
|
||||
),
|
||||
Arguments.of(List.of(AUDIO_GER_COMMENTARY, withName(SUB_GER, "commentary")),
|
||||
Set.of("commentary"),
|
||||
Map.ofEntries(on(withName(SUB_GER, "commentary")))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("findCommentaryTracksAndApplyChanges")
|
||||
void findCommentaryTracksAndApplyChanges(List<TrackAttributes> tracks, Set<String> keywords, Map<TrackAttributes, Boolean> changes) {
|
||||
InputConfig.getInstance().setPreferredSubtitles(new HashSet<>());
|
||||
InputConfig.getInstance().setCommentaryKeywords(keywords);
|
||||
InputConfig.getInstance().setHearingImpaired(new HashSet<>());
|
||||
InputConfig.getInstance().setForcedKeywords(new HashSet<>());
|
||||
|
||||
FileInfo fileInfo = new FileInfo(null);
|
||||
fileInfo.addTracks(tracks);
|
||||
AttributeProcessor.findCommentaryTracksAndApplyChanges(fileInfo);
|
||||
|
||||
assertEquals(changes.size(), fileInfo.getChanges().getCommentaryTrack().size());
|
||||
changes.forEach((key, value) -> {
|
||||
assertTrue(fileInfo.getChanges().getCommentaryTrack().containsKey(key));
|
||||
assertEquals(value, fileInfo.getChanges().getCommentaryTrack().get(key));
|
||||
});
|
||||
}
|
||||
|
||||
private static Stream<Arguments> findHearingImpairedTracksAndApplyChanges() {
|
||||
return Stream.of(
|
||||
Arguments.of(List.of(withName(SUB_GER, "SDH"), withName(SUB_GER, null)),
|
||||
Set.of("SDH"),
|
||||
Map.ofEntries(on(withName(SUB_GER, "SDH")))
|
||||
),
|
||||
Arguments.of(List.of(withName(SUB_GER, "SDH")),
|
||||
Set.of("SDH"),
|
||||
Map.ofEntries(on(withName(SUB_GER, "SDH")))
|
||||
),
|
||||
Arguments.of(List.of(withName(AUDIO_GER_COMMENTARY, "SDH")),
|
||||
Set.of("SDH"),
|
||||
Map.ofEntries()
|
||||
),
|
||||
Arguments.of(List.of(AUDIO_GER_HEARING, withName(SUB_GER, "SDH")),
|
||||
Set.of("SDH"),
|
||||
Map.ofEntries(on(withName(SUB_GER, "SDH")))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("findCommentaryTracksAndApplyChanges")
|
||||
void findHearingImpairedTracksAndApplyChanges(List<TrackAttributes> tracks, Set<String> keywords, Map<TrackAttributes, Boolean> changes) {
|
||||
InputConfig.getInstance().setPreferredSubtitles(new HashSet<>());
|
||||
InputConfig.getInstance().setCommentaryKeywords(new HashSet<>());
|
||||
InputConfig.getInstance().setHearingImpaired(keywords);
|
||||
InputConfig.getInstance().setForcedKeywords(new HashSet<>());
|
||||
|
||||
FileInfo fileInfo = new FileInfo(null);
|
||||
fileInfo.addTracks(tracks);
|
||||
AttributeProcessor.findHearingImpairedTracksAndApplyChanges(fileInfo);
|
||||
|
||||
assertEquals(changes.size(), fileInfo.getChanges().getHearingImpairedTrack().size());
|
||||
changes.forEach((key, value) -> {
|
||||
assertTrue(fileInfo.getChanges().getHearingImpairedTrack().containsKey(key));
|
||||
assertEquals(value, fileInfo.getChanges().getHearingImpairedTrack().get(key));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import java.nio.file.attribute.FileAttribute;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@@ -14,67 +15,11 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class FileInfoTest {
|
||||
|
||||
private static Stream<Arguments> isAudioDifferent() {
|
||||
return Stream.of(
|
||||
Arguments.of(createFileInfoAudio(Set.of(AUDIO_GER_DEFAULT), AUDIO_GER_DEFAULT, new AttributeConfig("ger", "")), false),
|
||||
Arguments.of(createFileInfoAudio(Set.of(AUDIO_GER_DEFAULT), AUDIO_ENG, new AttributeConfig("eng", "")), true),
|
||||
Arguments.of(createFileInfoAudio(Set.of(AUDIO_GER_DEFAULT, AUDIO_ENG_DEFAULT), AUDIO_GER_DEFAULT, new AttributeConfig("ger", "")), true),
|
||||
Arguments.of(createFileInfoAudio(Set.of(), AUDIO_GER, new AttributeConfig("ger", "")), true),
|
||||
Arguments.of(createFileInfoAudio(null, AUDIO_GER, new AttributeConfig("ger", "")), true),
|
||||
|
||||
Arguments.of(createFileInfoAudio(Set.of(AUDIO_GER_DEFAULT), null, new AttributeConfig("OFF", "")), true),
|
||||
Arguments.of(createFileInfoAudio(Set.of(), null, new AttributeConfig("OFF", "")), false),
|
||||
Arguments.of(createFileInfoAudio(null, null, new AttributeConfig("OFF", "")), false)
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void isAudioDifferent(FileInfo underTest, boolean expected) {
|
||||
assertEquals(expected, underTest.isAudioDifferent());
|
||||
}
|
||||
|
||||
private static Stream<Arguments> isSubtitleDifferent() {
|
||||
return Stream.of(
|
||||
Arguments.of(createFileInfoSubs(Set.of(SUB_GER_DEFAULT), SUB_GER_DEFAULT, new AttributeConfig("", "ger")), false),
|
||||
Arguments.of(createFileInfoSubs(Set.of(SUB_GER_DEFAULT), SUB_ENG, new AttributeConfig("", "eng")), true),
|
||||
Arguments.of(createFileInfoSubs(Set.of(SUB_GER_DEFAULT, SUB_ENG_DEFAULT), SUB_ENG, new AttributeConfig("", "eng")), true),
|
||||
Arguments.of(createFileInfoSubs(Set.of(), SUB_ENG, new AttributeConfig("", "ger")), true),
|
||||
Arguments.of(createFileInfoSubs(null, SUB_GER, new AttributeConfig("", "ger")), true),
|
||||
Arguments.of(createFileInfoSubs(null, null, new AttributeConfig("", "OFF")), false),
|
||||
Arguments.of(createFileInfoSubs(Set.of(), null, new AttributeConfig("", "OFF")), false),
|
||||
Arguments.of(createFileInfoSubs(Set.of(SUB_GER_DEFAULT), null, new AttributeConfig("", "OFF")), true)
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void isSubtitleDifferent(FileInfo underTest, boolean expected) {
|
||||
assertEquals(expected, underTest.isSubtitleDifferent());
|
||||
}
|
||||
|
||||
private static Stream<Arguments> getStatus() {
|
||||
return Stream.of(
|
||||
Arguments.of(CHANGE_NECESSARY, createFileInfo(Set.of(AUDIO_GER_DEFAULT), AUDIO_ENG, Set.of(), null, Set.of(), Set.of(), Set.of(), new AttributeConfig("eng", "OFF"))),
|
||||
Arguments.of(CHANGE_NECESSARY, createFileInfo(Set.of(), null, Set.of(SUB_GER_DEFAULT), SUB_ENG, Set.of(), Set.of(), Set.of(), new AttributeConfig("OFF", "eng"))),
|
||||
Arguments.of(CHANGE_NECESSARY, createFileInfo(Set.of(AUDIO_GER_DEFAULT), AUDIO_ENG, Set.of(SUB_GER_DEFAULT), SUB_ENG, Set.of(), Set.of(), Set.of(), new AttributeConfig("OFF", "eng"))),
|
||||
Arguments.of(CHANGE_NECESSARY, createFileInfo(Set.of(AUDIO_GER_DEFAULT), AUDIO_GER_DEFAULT, Set.of(SUB_GER_DEFAULT), SUB_GER_DEFAULT, Set.of(AUDIO_ENG_FORCED), Set.of(), Set.of(), new AttributeConfig("ger", "ger"))),
|
||||
Arguments.of(CHANGE_NECESSARY, createFileInfo(Set.of(), null, Set.of(), null, Set.of(AUDIO_ENG_FORCED), Set.of(), Set.of(), new AttributeConfig("OFF", "OFF"))),
|
||||
Arguments.of(CHANGE_NECESSARY, createFileInfo(Set.of(), null, Set.of(), null, Set.of(), Set.of(), Set.of(SUB_GER_FORCED), new AttributeConfig("OFF", "OFF"))),
|
||||
Arguments.of(CHANGE_NECESSARY, createFileInfo(Set.of(), null, Set.of(), null, Set.of(), Set.of(SUB_ENG_FORCED), Set.of(SUB_GER_FORCED), new AttributeConfig("OFF", "OFF"))),
|
||||
Arguments.of(CHANGE_NECESSARY, createFileInfo(Set.of(), null, Set.of(), null, Set.of(AUDIO_ENG_FORCED), Set.of(SUB_ENG_FORCED), Set.of(SUB_GER_FORCED), new AttributeConfig("OFF", "OFF"))),
|
||||
Arguments.of(CHANGE_NECESSARY, createFileInfo(Set.of(AUDIO_GER_DEFAULT), AUDIO_ENG, Set.of(SUB_GER_DEFAULT), SUB_ENG, Set.of(AUDIO_ENG_FORCED), Set.of(SUB_ENG_FORCED), Set.of(SUB_GER_FORCED), new AttributeConfig("eng", "eng"))),
|
||||
Arguments.of(CHANGE_NECESSARY, createFileInfo(Set.of(AUDIO_GER_DEFAULT), AUDIO_GER_DEFAULT, Set.of(SUB_GER_DEFAULT), SUB_GER_DEFAULT, Set.of(), Set.of(SUB_ENG_FORCED), Set.of(SUB_ENG_FORCED, SUB_GER), new AttributeConfig("ger", "ger"))),
|
||||
|
||||
Arguments.of(NO_SUITABLE_CONFIG, createFileInfo(Set.of(AUDIO_ENG_DEFAULT), null, Set.of(SUB_GER_DEFAULT), null, Set.of(), Set.of(), Set.of(), new AttributeConfig("eng", "ger"))),
|
||||
Arguments.of(NO_SUITABLE_CONFIG, createFileInfo(Set.of(AUDIO_ENG_DEFAULT), null, Set.of(), null, Set.of(), Set.of(), Set.of(), new AttributeConfig("eng", "ger"))),
|
||||
Arguments.of(NO_SUITABLE_CONFIG, createFileInfo(Set.of(), null, Set.of(), null, Set.of(), Set.of(), Set.of(), new AttributeConfig("eng", "ger"))),
|
||||
|
||||
Arguments.of(ALREADY_SUITED, createFileInfo(Set.of(), null, Set.of(), null, Set.of(), Set.of(), Set.of(), new AttributeConfig("OFF", "OFF"))),
|
||||
Arguments.of(ALREADY_SUITED, createFileInfo(Set.of(AUDIO_GER_DEFAULT), AUDIO_GER_DEFAULT, Set.of(), null, Set.of(), Set.of(), Set.of(), new AttributeConfig("ger", "OFF"))),
|
||||
Arguments.of(ALREADY_SUITED, createFileInfo(Set.of(), null, Set.of(SUB_ENG_DEFAULT), SUB_ENG_DEFAULT, Set.of(), Set.of(), Set.of(), new AttributeConfig("OFF", "ger"))),
|
||||
Arguments.of(ALREADY_SUITED, createFileInfo(Set.of(AUDIO_GER_DEFAULT), AUDIO_GER_DEFAULT, Set.of(SUB_ENG_DEFAULT), SUB_ENG_DEFAULT, Set.of(), Set.of(), Set.of(), new AttributeConfig("ger", "eng"))),
|
||||
Arguments.of(ALREADY_SUITED, createFileInfo(Set.of(AUDIO_GER_DEFAULT), AUDIO_GER_DEFAULT, Set.of(SUB_ENG_DEFAULT), SUB_ENG_DEFAULT, Set.of(), Set.of(SUB_GER_FORCED), Set.of(SUB_GER_FORCED), new AttributeConfig("ger", "eng")))
|
||||
Arguments.of(CHANGE_NECESSARY, info(new AttributeConfig("ger", "ger"), AUDIO_GER)),
|
||||
Arguments.of(ALREADY_SUITED, info(new AttributeConfig("ger", "ger"), null)),
|
||||
Arguments.of(NO_SUITABLE_CONFIG, info(null, null))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -84,4 +29,11 @@ class FileInfoTest {
|
||||
FileStatus actual = underTest.getStatus();
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
private static FileInfo info(AttributeConfig config, TrackAttributes attr) {
|
||||
FileInfo fileInfo = new FileInfo(null);
|
||||
fileInfo.setMatchedConfig(config);
|
||||
if(attr != null) fileInfo.getChanges().getDefaultTrack().put(attr, true);
|
||||
return fileInfo;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,7 @@
|
||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config;
|
||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.model;
|
||||
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validation.ValidationExecutionStrategy;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.validation.ValidationExecutionStrategy;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
@@ -1,22 +1,28 @@
|
||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.util;
|
||||
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.LaneType;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.TrackAttributes;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.TrackType;
|
||||
|
||||
public class FileInfoTestUtil {
|
||||
public static final FileAttribute AUDIO_GER_DEFAULT = new FileAttribute(0, "ger", "", true, false, LaneType.AUDIO);
|
||||
public static final FileAttribute AUDIO_ENG_DEFAULT = new FileAttribute(1, "eng", "", true, false, LaneType.AUDIO);
|
||||
public static final FileAttribute AUDIO_GER = new FileAttribute(0, "ger", "", false, false, LaneType.AUDIO);
|
||||
public static final FileAttribute AUDIO_ENG = new FileAttribute(1, "eng", "", false, false, LaneType.AUDIO);
|
||||
public static final FileAttribute AUDIO_GER_FORCED = new FileAttribute(0, "ger", "", false, true, LaneType.AUDIO);
|
||||
public static final FileAttribute AUDIO_ENG_FORCED = new FileAttribute(1, "eng", "", false, true, LaneType.AUDIO);
|
||||
public static final FileAttribute AUDIO_GER_COMMENTARY = new FileAttribute(1, "ger", "commentary", false, false, LaneType.AUDIO);
|
||||
public static final FileAttribute AUDIO_ENG_COMMENTARY = new FileAttribute(1, "eng", "commentary", false, false, LaneType.AUDIO);
|
||||
public static final TrackAttributes AUDIO_GER_DEFAULT = new TrackAttributes(0, "ger", "", true, false, false, false, TrackType.AUDIO);
|
||||
public static final TrackAttributes AUDIO_ENG_DEFAULT = new TrackAttributes(1, "eng", "", true, false, false, false, TrackType.AUDIO);
|
||||
public static final TrackAttributes AUDIO_GER = new TrackAttributes(0, "ger", "", false, false, false, false, TrackType.AUDIO);
|
||||
public static final TrackAttributes AUDIO_ENG = new TrackAttributes(1, "eng", "", false, false, false, false, TrackType.AUDIO);
|
||||
public static final TrackAttributes AUDIO_GER_FORCED = new TrackAttributes(0, "ger", "", false, true, false, false, TrackType.AUDIO);
|
||||
public static final TrackAttributes AUDIO_ENG_FORCED = new TrackAttributes(1, "eng", "", false, true, false, false, TrackType.AUDIO);
|
||||
public static final TrackAttributes AUDIO_GER_COMMENTARY = new TrackAttributes(0, "ger", "", false, false, true, false, TrackType.AUDIO);
|
||||
public static final TrackAttributes AUDIO_ENG_COMMENTARY = new TrackAttributes(1, "eng", "", false, false, true, false, TrackType.AUDIO);
|
||||
public static final TrackAttributes AUDIO_GER_HEARING = new TrackAttributes(0, "ger", "", false, false, false, true, TrackType.AUDIO);
|
||||
public static final TrackAttributes AUDIO_ENG_HEARING = new TrackAttributes(1, "ger", "", false, false, false, true, TrackType.AUDIO);
|
||||
|
||||
public static final FileAttribute SUB_GER_DEFAULT = new FileAttribute(0, "ger", "", true, false, LaneType.SUBTITLES);
|
||||
public static final FileAttribute SUB_ENG_DEFAULT = new FileAttribute(1, "eng", "", true, false, LaneType.SUBTITLES);
|
||||
public static final FileAttribute SUB_GER = new FileAttribute(0, "ger", "", false, false, LaneType.SUBTITLES);
|
||||
public static final FileAttribute SUB_ENG = new FileAttribute(1, "eng", "", false, false, LaneType.SUBTITLES);
|
||||
public static final FileAttribute SUB_GER_FORCED = new FileAttribute(0, "ger", "", false, true, LaneType.SUBTITLES);
|
||||
public static final FileAttribute SUB_ENG_FORCED = new FileAttribute(1, "eng", "", false, true, LaneType.SUBTITLES);
|
||||
public static final TrackAttributes SUB_GER_DEFAULT = new TrackAttributes(0, "ger", "", true, false, false, false, TrackType.SUBTITLES);
|
||||
public static final TrackAttributes SUB_ENG_DEFAULT = new TrackAttributes(1, "eng", "", true, false, false, false, TrackType.SUBTITLES);
|
||||
public static final TrackAttributes SUB_GER = new TrackAttributes(0, "ger", "", false, false, false, false, TrackType.SUBTITLES);
|
||||
public static final TrackAttributes SUB_ENG = new TrackAttributes(1, "eng", "", false, false, false, false, TrackType.SUBTITLES);
|
||||
public static final TrackAttributes SUB_GER_FORCED = new TrackAttributes(0, "ger", "", false, true, false, false, TrackType.SUBTITLES);
|
||||
public static final TrackAttributes SUB_ENG_FORCED = new TrackAttributes(1, "eng", "", false, true, false, false, TrackType.SUBTITLES);
|
||||
|
||||
public static TrackAttributes withName(TrackAttributes track, String trackName) {
|
||||
return new TrackAttributes(track.id(), track.language(), trackName, track.defaultt(), track.forced(), track.commentary(), track.hearingImpaired(), track.type());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,46 +1,7 @@
|
||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.util;
|
||||
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfo;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class TestUtil {
|
||||
|
||||
public static FileInfo createFileInfoAudio(Set<FileAttribute> defaultAudio, FileAttribute desiredAudio, AttributeConfig config) {
|
||||
FileInfo fileInfo = new FileInfo(null);
|
||||
fileInfo.setExistingDefaultAudioLanes(defaultAudio);
|
||||
fileInfo.setDesiredDefaultAudioLane(desiredAudio);
|
||||
fileInfo.setMatchedConfig(config);
|
||||
return fileInfo;
|
||||
}
|
||||
|
||||
public static FileInfo createFileInfoSubs(Set<FileAttribute> defaultSubtitle, FileAttribute desiredSubtitle, AttributeConfig config) {
|
||||
FileInfo fileInfo = new FileInfo(null);
|
||||
fileInfo.setExistingDefaultSubtitleLanes(defaultSubtitle);
|
||||
fileInfo.setDesiredDefaultSubtitleLane(desiredSubtitle);
|
||||
fileInfo.setMatchedConfig(config);
|
||||
return fileInfo;
|
||||
}
|
||||
|
||||
public static FileInfo createFileInfo(Set<FileAttribute> defaultAudio, FileAttribute desiredAudio,
|
||||
Set<FileAttribute> defaultSubtitle, FileAttribute desiredSubtitle,
|
||||
Set<FileAttribute> existingForcedAudioLanes,
|
||||
Set<FileAttribute> existingForcedSubs, Set<FileAttribute> desiredForcedSubs,
|
||||
AttributeConfig matchedConfig) {
|
||||
FileInfo fileInfo = new FileInfo(null);
|
||||
fileInfo.setExistingDefaultAudioLanes(defaultAudio);
|
||||
fileInfo.setDesiredDefaultAudioLane(desiredAudio);
|
||||
fileInfo.setExistingDefaultSubtitleLanes(defaultSubtitle);
|
||||
fileInfo.setDesiredDefaultSubtitleLane(desiredSubtitle);
|
||||
fileInfo.setExistingForcedAudioLanes(existingForcedAudioLanes);
|
||||
fileInfo.setExistingForcedSubtitleLanes(existingForcedSubs);
|
||||
fileInfo.setDesiredForcedSubtitleLanes(desiredForcedSubs);
|
||||
fileInfo.setMatchedConfig(matchedConfig);
|
||||
return fileInfo;
|
||||
}
|
||||
|
||||
public static String[] args(String... args) {
|
||||
String[] staticArray = new String[]{"-l", "/", "-a", "jpn:ger"};
|
||||
String[] result = new String[staticArray.length + args.length];
|
||||
|
||||
Reference in New Issue
Block a user