diff --git a/main/main/Help.java b/main/main/Help.java index db0a3da..283862d 100644 --- a/main/main/Help.java +++ b/main/main/Help.java @@ -25,7 +25,7 @@ * */ @Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.RECORD_COMPONENT) +@Target({ElementType.RECORD_COMPONENT, ElementType.TYPE}) public @interface Help { /** * Returns the option help texts. diff --git a/main/main/Name.java b/main/main/Name.java index cb541c9..9cf4512 100644 --- a/main/main/Name.java +++ b/main/main/Name.java @@ -33,7 +33,7 @@ * */ @Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.RECORD_COMPONENT) +@Target({ElementType.RECORD_COMPONENT, ElementType.TYPE}) public @interface Name { /** * Returns the option names. diff --git a/test/test/AllTests.java b/test/test/AllTests.java index c784e82..775fccd 100644 --- a/test/test/AllTests.java +++ b/test/test/AllTests.java @@ -3,6 +3,7 @@ import test.api.JTest; import test.jdk.JarRecordTests; import test.jdk.JarOptionTests; +import test.jdk.JarSealedTests; import test.unit.ArgumentMapTests; import test.unit.ConverterResolverTests; import test.unit.OptionTests; @@ -21,6 +22,7 @@ public static void main(String[] args) { // jdk examples JarRecordTests::main, JarOptionTests::main, + // JarSealedTests::main, // unit tests ArgumentMapTests::main, ConverterResolverTests::main, diff --git a/test/test/jdk/JarSealedTests.java b/test/test/jdk/JarSealedTests.java new file mode 100644 index 0000000..78524f7 --- /dev/null +++ b/test/test/jdk/JarSealedTests.java @@ -0,0 +1,152 @@ +package test.jdk; + +import main.Name; +import test.api.JTest; +import test.api.JTest.Test; + +import java.nio.file.Path; +import java.time.ZonedDateTime; +import java.util.List; +import static test.api.Assertions.assertEquals; + +public class JarSealedTests { + + public static void main(String... args) { + JTest.runTests(new JarSealedTests(), args); + } + + + /** + * Records has an implicit @Name of: + * lower case initial character (short name) and kebab-case (long name). + * An empty array in @Name means it is not an option but command line parameters (often trailing) + */ + sealed interface JarOpts { + + record Create() implements JarOpts {} + @Name({"-i", "--generate-index"}) record GenerateIndex(String name) implements JarOpts {} + @Name({"-t", "--list"}) record List() implements JarOpts {} + record Update() implements JarOpts {} + @Name({"-x", "--extract"}) record Extract() implements JarOpts {} + record DescribeModule() implements JarOpts {} + @Name({"-C"}) record ChangeDirOption(String dir, Path path) implements JarOpts {} + record File(Path jarFile) implements JarOpts {} + + // To be discussed. + @Name("--release") record Release(int version, + @Name({"-C"}) java.util.List options) implements JarOpts {} + + @Name({"-e", "--main-class"}) record Verbose(Path jarFile) implements JarOpts {} + @Name({"-e", "--main-class"}) record MainClass(String name) implements JarOpts {} + record Manifest(String name) implements JarOpts {} + @Name({"-M", "--no-manifest"}) record NoManifest() implements JarOpts {} + @Name("--module-version") record ModuleVersion(String version) implements JarOpts {} + @Name("--hash-modules") record HashModules(String hash) implements JarOpts {} + @Name({"-p", "--module-path"}) record ModulePath(String modulePath) implements JarOpts {} + @Name({"-0", "--no-compress"}) record NoCompress() implements JarOpts {} + @Name("--date") record Date(ZonedDateTime date) implements JarOpts {} + @Name({"-?", "-h", "--help"}) record Help() implements JarOpts {} + @Name("--help:compat") record HelpCompat() implements JarOpts {} + @Name("--help-extra") record HelpExtra() implements JarOpts {} + @Name("--version") record Version() implements JarOpts {} + @Name({}) record Arg(Path path){} + } + + /* + + @Name("--release") + // To be discussed. + record Release(int version, ReleaseChangeDirOptions options) implements JarOpts { + + @Name({"-C"}) sealed interface ReleaseChangeDirOptions { + record ReleaseChangeDirOption(String dir, Path path) implements ReleaseChangeDirOptions {} + } + } + + */ + + + private static List splitInput(String line) { + // return Splitter.of(lookup(), JarOptions.class).split(line.split("\\s+")); + return List.of(); + } + + @Test + void example1() { + var options = splitInput("--create --file classes.jar Foo.class Bar.class"); + var expected = List.of( + new JarOpts.Create(), + new JarOpts.File(Path.of("classes.jar")), + new JarOpts.Arg(Path.of("Foo.class")), + new JarOpts.Arg(Path.of("Bar.class")) + ); + assertEquals(expected, options); + } + + @Test + void example2() { + var options = + splitInput("--create --date=\"2021-01-06T14:36:00+02:00\" --file=classes.jar Foo.class Bar.class"); + + var expected = List.of( + new JarOpts.Create(), + new JarOpts.Date(ZonedDateTime.parse("2021-01-06T14:36:00+02:00")), + new JarOpts.File(Path.of("classes.jar")), + new JarOpts.Arg(Path.of("Foo.class")), + new JarOpts.Arg(Path.of("Bar.class")) + ); + assertEquals(expected, options); + } + + @Test + void example3() { + var options = splitInput("--create --file classes.jar --manifest mymanifest -C foo/ ."); + + var expected = List.of( + new JarOpts.Create(), + new JarOpts.File(Path.of("classes.jar")), + new JarOpts.Manifest("mymanifest"), + new JarOpts.ChangeDirOption("foo/", Path.of(".")) + ); + + assertEquals(expected, options); + } + + @Test + void example4() { + var options = + splitInput( + "--create --file foo.jar --main-class com.foo.Main --module-version 1.0 -C foo/classes" + + " resources"); + + var expected = List.of( + new JarOpts.Create(), + new JarOpts.File(Path.of("foo.jar")), + new JarOpts.MainClass("com.foo.Main"), + new JarOpts.ModuleVersion("1.0"), + new JarOpts.ChangeDirOption("foo/classes", Path.of("resources")) + ); + + assertEquals(expected, options); + } + + @Test + void example5() { + var options = + splitInput( + """ + --create --file foo.jar --main-class com.foo.Hello -C classes . + --release 10 -C classes-10 ."""); + + var expected = List.of( + new JarOpts.Create(), + new JarOpts.File(Path.of("foo.jar")), + new JarOpts.MainClass("com.foo.Hello"), + new JarOpts.ChangeDirOption("classes", Path.of(".")), + new JarOpts.Release(10, List.of(new JarOpts.ChangeDirOption("classes-10", Path.of(".")))) + ); + + assertEquals(expected, options); + } + +}