Make picocli fully handle config validation

This commit is contained in:
RatzzFatzz
2025-12-04 23:20:49 +01:00
parent 5eca28ecb9
commit 181c718e7a
13 changed files with 116 additions and 46 deletions

View File

@@ -0,0 +1,61 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.fields;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig;
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.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.*;
class AttributeConfigTest {
private static Stream<Arguments> provideTestCases() {
return Stream.of(
Arguments.of(args("-a", "jpn:ger"), attrConf("jpn", "ger")),
Arguments.of(args("-a", "jpn:ger", "jpn:eng"), attrConf("jpn", "ger", "jpn", "eng")),
Arguments.of(args("-a", "jpn:ger", "jpn:OFF"), attrConf("jpn", "ger", "jpn", "OFF"))
);
}
@ParameterizedTest
@MethodSource("provideTestCases")
void validate(String[] cmdArgs, List<AttributeConfig> expectedConfig) {
Main underTest = new Main();
CommandLine.populateCommand(underTest, cmdArgs);
assertIterableEquals(expectedConfig, underTest.getConfig().getAttributeConfig());
}
@Test
void validate() {
Main sut = new Main();
assertThrows(CommandLine.MissingParameterException.class, () -> CommandLine.populateCommand(sut, new String[]{"-l", "/"}));
assertThrows(CommandLine.MissingParameterException.class, () -> CommandLine.populateCommand(sut, new String[]{"-l", "/", "-a"}));
assertThrows(CommandLine.ParameterException.class, () -> CommandLine.populateCommand(sut, new String[]{"-l", "/", "-a", "ger:"}));
assertThrows(CommandLine.ParameterException.class,
() -> CommandLine.populateCommand(sut, new String[]{"-l", "/", "-a", "ger:qwf"})); // Invalid language code
}
private static String[] args(String... args) {
String[] staticArray = new String[]{"-l", "/"};
String[] result = new String[staticArray.length + args.length];
System.arraycopy(staticArray, 0, result, 0, staticArray.length);
System.arraycopy(args, 0, result, staticArray.length, args.length);
return result;
}
private static List<AttributeConfig> attrConf(String... languages) {
List<AttributeConfig> conf = new ArrayList<>();
for (int i = 0; i < languages.length; i += 2) {
conf.add(new AttributeConfig(languages[i], languages[i+1]));
}
return conf;
}
}

View File

@@ -0,0 +1,38 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.fields;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig;
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.util.function.Function;
import java.util.stream.Stream;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.TestUtil.args;
import static org.junit.jupiter.api.Assertions.assertEquals;
class BooleanConfigParameterTest {
private static Stream<Arguments> provideTestCases() {
return Stream.of(
Arguments.of(args("-s"), true, (Function<InputConfig, Boolean>) InputConfig::isSafeMode),
Arguments.of(args("--safemode"), true, (Function<InputConfig, Boolean>) InputConfig::isSafeMode),
Arguments.of(args(), false, (Function<InputConfig, Boolean>) InputConfig::isSafeMode),
Arguments.of(args("-cf"), true, (Function<InputConfig, Boolean>) InputConfig::isForceCoherent),
Arguments.of(args("--force-coherent"), true, (Function<InputConfig, Boolean>) InputConfig::isForceCoherent),
Arguments.of(args(), false, (Function<InputConfig, Boolean>) InputConfig::isForceCoherent),
Arguments.of(args("-n"), true, (Function<InputConfig, Boolean>) InputConfig::isOnlyNewFiles),
Arguments.of(args(), false, (Function<InputConfig, Boolean>) InputConfig::isOnlyNewFiles)
);
}
@ParameterizedTest
@MethodSource("provideTestCases")
void validate(String[] cmdArgs, boolean expected, Function<InputConfig, Boolean> fieldUnderTest) {
Main sut = new Main();
CommandLine.populateCommand(sut, cmdArgs);
assertEquals(expected, fieldUnderTest.apply(sut.getConfig()));
}
}

View File

@@ -0,0 +1,43 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.fields;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.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;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.TestUtil.args;
import static org.junit.jupiter.api.Assertions.*;
class IntegerConfigParameterTest {
private static Stream<Arguments> provideTestCases() {
return Stream.of(
Arguments.of(args(), 2, (Function<InputConfig, Integer>) InputConfig::getThreads),
Arguments.of(args("-t", "5"), 5, (Function<InputConfig, Integer>) InputConfig::getThreads),
Arguments.of(args("--threads", "5"), 5, (Function<InputConfig, Integer>) InputConfig::getThreads)
);
}
@ParameterizedTest
@MethodSource("provideTestCases")
void validate(String[] cmdArgs, int expected, Function<InputConfig, Integer> fieldUnderTest) {
Main sut = new Main();
CommandLine.populateCommand(sut, cmdArgs);
assertEquals(expected, fieldUnderTest.apply(sut.getConfig()));
}
@Test
void validate() {
Main sut = new Main();
assertThrows(CommandLine.MissingParameterException.class, () -> CommandLine.populateCommand(sut, args("-t")));
assertThrows(CommandLine.MissingParameterException.class, () -> CommandLine.populateCommand(sut, args("--threads")));
}
}

View File

@@ -0,0 +1,45 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.fields;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig;
import org.apache.commons.lang3.SystemUtils;
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.File;
import java.nio.file.Path;
import java.util.function.Function;
import java.util.stream.Stream;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.TestUtil.args;
import static org.junit.jupiter.api.Assertions.*;
class MkvToolNixPathConfigParameterTest {
private static final String TEST_MKVTOOLNIX_DIR = SystemUtils.IS_OS_WINDOWS ? "src/test/resources/mkvtoolnix_exe" : "src/test/resources/mkvtoolnix";
private static Stream<Arguments> provideTestCases() {
return Stream.of(
Arguments.of(args("-m", TEST_MKVTOOLNIX_DIR), TEST_MKVTOOLNIX_DIR, (Function<InputConfig, File>) InputConfig::getMkvToolNix),
Arguments.of(args("--mkvtoolnix", TEST_MKVTOOLNIX_DIR), TEST_MKVTOOLNIX_DIR, (Function<InputConfig, File>) InputConfig::getMkvToolNix)
);
}
@ParameterizedTest
@MethodSource("provideTestCases")
void validate(String[] cmdArgs, String expected, Function<InputConfig, File> fieldUnderTest) {
Main sut = new Main();
CommandLine.populateCommand(sut, cmdArgs);
assertEquals(Path.of(expected).toFile().getAbsolutePath(), fieldUnderTest.apply(sut.getConfig()).getAbsolutePath());
}
@Test
void validate() {
Main sut = new Main();
assertThrows(CommandLine.ParameterException.class, () -> CommandLine.populateCommand(sut, args("-m")));
assertThrows(CommandLine.ParameterException.class, () -> CommandLine.populateCommand(sut, args("")));
}
}

View File

@@ -0,0 +1,54 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.fields;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.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.File;
import java.nio.file.Path;
import java.util.function.Function;
import java.util.stream.Stream;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.PathUtils.TEST_DIR;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.PathUtils.TEST_FILE;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
class PathConfigParameterTest {
private static Stream<Arguments> provideTestCases() {
return Stream.of(
Arguments.of(args("-l", TEST_DIR), Path.of(TEST_DIR).toFile(), true, (Function<InputConfig, File>) InputConfig::getLibraryPath),
Arguments.of(args("-l", TEST_FILE), Path.of(TEST_FILE).toFile(), true, (Function<InputConfig, File>) InputConfig::getLibraryPath)
);
}
@ParameterizedTest
@MethodSource("provideTestCases")
void validate(String[] cmdArgs, File expected, boolean exists, Function<InputConfig, File> fieldUnderTest) {
Main sut = new Main();
CommandLine.populateCommand(sut, cmdArgs);
assertEquals(expected.getAbsolutePath(), fieldUnderTest.apply(sut.getConfig()).getAbsolutePath());
assertEquals(exists, fieldUnderTest.apply(sut.getConfig()).exists());
}
@Test
void validate() {
Main sut = new Main();
// assertThrows(CommandLine.ParameterException.class, () -> new CommandLine(sut).execute(args("-l", "arst")));
assertThrows(CommandLine.MissingParameterException.class, () -> CommandLine.populateCommand(sut, args("-l")));
assertThrows(CommandLine.UnmatchedArgumentException.class, () -> CommandLine.populateCommand(sut, args("")));
}
private static String[] args(String... args) {
String[] staticArray = new String[]{"-a", "ger:ger"};
String[] result = new String[staticArray.length + args.length];
System.arraycopy(staticArray, 0, result, 0, staticArray.length);
System.arraycopy(args, 0, result, staticArray.length, args.length);
return result;
}
}

View File

@@ -0,0 +1,43 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.fields;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.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.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.TestUtil.args;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
class PatternConfigParameterTest {
private static Stream<Arguments> provideTestCases() {
return Stream.of(
Arguments.of(args("-i", "[abd]?.*"), Pattern.compile("[abd]?.*"), (Function<InputConfig, Pattern>) InputConfig::getIncludePattern),
Arguments.of(args("-i", ".*"), Pattern.compile(".*"), (Function<InputConfig, Pattern>) InputConfig::getIncludePattern),
Arguments.of(args(), Pattern.compile(".*"), (Function<InputConfig, Pattern>) InputConfig::getIncludePattern)
);
}
@ParameterizedTest
@MethodSource("provideTestCases")
void validate(String[] cmdArgs, Pattern expected, Function<InputConfig, Pattern> fieldUnderTest) {
Main sut = new Main();
CommandLine.populateCommand(sut, cmdArgs);
assertEquals(expected.pattern(), fieldUnderTest.apply(sut.getConfig()).pattern());
}
@Test
void validate() {
Main sut = new Main();
assertThrows(CommandLine.MissingParameterException.class, () -> CommandLine.populateCommand(sut, args("-i")));
assertThrows(CommandLine.ParameterException.class, () -> CommandLine.populateCommand(sut, args("-i", "[")));
}
}

View File

@@ -0,0 +1,51 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.fields;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.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.util.Set;
import java.util.function.Function;
import java.util.stream.Stream;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.TestUtil.args;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
class SetConfigParameterTest {
private static Stream<Arguments> provideTestCases() {
return Stream.of(
Arguments.of(args("--commentary-keywords", "test"), 1, (Function<InputConfig, Set<String>>) InputConfig::getCommentaryKeywords),
Arguments.of(args("--commentary-keywords", "test", "test1", "test2", "test3", "test4"), 5, (Function<InputConfig, Set<String>>) InputConfig::getCommentaryKeywords),
Arguments.of(args(), 2, (Function<InputConfig, Set<String>>) InputConfig::getCommentaryKeywords),
Arguments.of(args("--forced-keywords", "test"), 1, (Function<InputConfig, Set<String>>) InputConfig::getForcedKeywords),
Arguments.of(args("--forced-keywords", "test", "test1", "test2", "test3", "test4"), 5, (Function<InputConfig, Set<String>>) InputConfig::getForcedKeywords),
Arguments.of(args(), 3, (Function<InputConfig, Set<String>>) InputConfig::getForcedKeywords),
Arguments.of(args("--preferred-subtitles", "test"), 1, (Function<InputConfig, Set<String>>) InputConfig::getPreferredSubtitles),
Arguments.of(args("--preferred-subtitles", "test", "test1", "test2", "test3", "test4"), 5, (Function<InputConfig, Set<String>>) InputConfig::getPreferredSubtitles),
Arguments.of(args(), 1, (Function<InputConfig, Set<String>>) InputConfig::getPreferredSubtitles)
);
}
@ParameterizedTest
@MethodSource("provideTestCases")
void validate(String[] cmdArgs, int expectedSize, Function<InputConfig, Set<String>> fieldUnderTest) {
Main sut = new Main();
CommandLine.populateCommand(sut, cmdArgs);
assertEquals(expectedSize, fieldUnderTest.apply(sut.getConfig()).size());
}
@Test
void validate() {
Main sut = new Main();
assertThrows(CommandLine.MissingParameterException.class, () -> CommandLine.populateCommand(sut, args("--commentary-keywords")));
assertThrows(CommandLine.MissingParameterException.class, () -> CommandLine.populateCommand(sut, args("--forced-keywords")));
assertThrows(CommandLine.MissingParameterException.class, () -> CommandLine.populateCommand(sut, args("-e")));
assertThrows(CommandLine.MissingParameterException.class, () -> CommandLine.populateCommand(sut, args("--preferred-subtitles")));
}
}