| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package cli |
| |
| import groovy.test.GroovyTestCase |
| |
| abstract class CliBuilderTestCase extends GroovyTestCase { |
| |
| abstract String getImportCliBuilder() |
| |
| void testAnnotationsInterface() { |
| assertScript """ |
| import cli.GreeterI |
| $importCliBuilder |
| // tag::annotationInterface[] |
| // import CliBuilder not shown |
| def cli = new CliBuilder(usage: 'groovy Greeter') // <1> |
| def argz = '--audience Groovologist'.split() |
| def options = cli.parseFromSpec(GreeterI, argz) // <2> |
| assert options.audience() == 'Groovologist' // <3> |
| |
| argz = '-h Some Other Args'.split() |
| options = cli.parseFromSpec(GreeterI, argz) // <4> |
| assert options.help() |
| assert options.remaining() == ['Some', 'Other', 'Args'] // <5> |
| // end::annotationInterface[] |
| """ |
| } |
| |
| void testAnnotationsClass() { |
| assertScript """ |
| import cli.GreeterC |
| $importCliBuilder |
| // tag::annotationClass[] |
| // import CliBuilder not shown |
| def cli = new CliBuilder(usage: 'groovy Greeter [option]') // <1> |
| def options = new GreeterC() // <2> |
| def argz = '--audience Groovologist foo'.split() |
| cli.parseFromInstance(options, argz) // <3> |
| assert options.audience == 'Groovologist' // <4> |
| assert options.remaining == ['foo'] // <5> |
| // end::annotationClass[] |
| """ |
| } |
| |
| // performs toString comparison of usage help - this isn't because we guarantee any specific output |
| // (hence expected is provided as a parameter) but we want to know when it changes significantly and |
| // in particular we want to ensure that no information that we expect to be there just disappears |
| protected void doTestAnnotationsInterfaceToString(String key, String expected) { |
| assertScript """ |
| import cli.GreeterI |
| $importCliBuilder |
| def cli = new CliBuilder($key: 'groovy Greeter') |
| |
| def options = cli.parseFromSpec(GreeterI, ['-h', 'Some', 'Other', 'Args'] as String[]) |
| assert options.help() |
| assert options.remaining() == ['Some', 'Other', 'Args'] |
| StringWriter sw = new StringWriter() |
| cli.writer = new PrintWriter(sw) |
| cli.usage() |
| |
| assert '''$expected'''.normalize() == sw.toString().normalize() |
| """ |
| } |
| |
| void testParseScript() { |
| def argz = '--audience Groovologist foo'.split() |
| new GroovyShell().run(""" |
| $importCliBuilder |
| // tag::annotationScript[] |
| // import CliBuilder not shown |
| import groovy.cli.OptionField |
| import groovy.cli.UnparsedField |
| |
| @OptionField String audience |
| @OptionField Boolean help |
| @UnparsedField List remaining |
| new CliBuilder().parseFromInstance(this, args) |
| assert audience == 'Groovologist' |
| assert remaining == ['foo'] |
| // end::annotationScript[] |
| """, 'TestScript.groovy', argz) |
| } |
| |
| void testWithArgument() { |
| assertScript """ |
| $importCliBuilder |
| // tag::withArgument[] |
| // import CliBuilder not shown |
| def cli = new CliBuilder() |
| cli.a(args: 0, 'a arg') // <1> |
| cli.b(args: 1, 'b arg') // <2> |
| cli.c(args: 1, optionalArg: true, 'c arg') // <3> |
| def options = cli.parse('-a -b foo -c bar baz'.split()) // <4> |
| |
| assert options.a == true |
| assert options.b == 'foo' |
| assert options.c == 'bar' |
| assert options.arguments() == ['baz'] |
| |
| options = cli.parse('-a -c -b foo bar baz'.split()) // <5> |
| |
| assert options.a == true |
| assert options.c == true |
| assert options.b == 'foo' |
| assert options.arguments() == ['bar', 'baz'] |
| // end::withArgument[] |
| """ |
| } |
| |
| void testMultipleArgsAndOptionalValueSeparator() { |
| assertScript """ |
| $importCliBuilder |
| // tag::multipleArgs[] |
| // import CliBuilder not shown |
| def cli = new CliBuilder() |
| cli.a(args: 2, 'a-arg') |
| cli.b(args: '2', valueSeparator: ',', 'b-arg') // <1> |
| cli.c(args: '+', valueSeparator: ',', 'c-arg') // <2> |
| |
| def options = cli.parse('-a 1 2 3 4'.split()) // <3> |
| assert options.a == '1' // <4> |
| assert options.as == ['1', '2'] // <5> |
| assert options.arguments() == ['3', '4'] |
| |
| options = cli.parse('-a1 -a2 3'.split()) // <6> |
| assert options.as == ['1', '2'] |
| assert options.arguments() == ['3'] |
| |
| options = cli.parse(['-b1,2']) // <7> |
| assert options.bs == ['1', '2'] |
| |
| options = cli.parse(['-c', '1']) |
| assert options.cs == ['1'] |
| |
| options = cli.parse(['-c1']) |
| assert options.cs == ['1'] |
| |
| options = cli.parse(['-c1,2,3']) |
| assert options.cs == ['1', '2', '3'] |
| // end::multipleArgs[] |
| """ |
| } |
| |
| void testWithArgumentInterface() { |
| assertScript """ |
| import cli.WithArgsI |
| $importCliBuilder |
| // tag::withArgumentInterface[] |
| def cli = new CliBuilder() |
| def options = cli.parseFromSpec(WithArgsI, '-a -b foo -c bar baz'.split()) |
| assert options.a() |
| assert options.b() == 'foo' |
| assert options.c() == ['bar'] |
| assert options.remaining() == ['baz'] |
| |
| options = cli.parseFromSpec(WithArgsI, '-a -c -b foo bar baz'.split()) |
| assert options.a() |
| assert options.c() == [] |
| assert options.b() == 'foo' |
| assert options.remaining() == ['bar', 'baz'] |
| // end::withArgumentInterface[] |
| """ |
| } |
| |
| void testMultipleArgsAndOptionalValueSeparatorInterface() { |
| assertScript """ |
| import cli.ValSepI |
| $importCliBuilder |
| // tag::multipleArgsInterface[] |
| def cli = new CliBuilder() |
| |
| def options = cli.parseFromSpec(ValSepI, '-a 1 2 3 4'.split()) |
| assert options.a() == ['1', '2'] |
| assert options.remaining() == ['3', '4'] |
| |
| options = cli.parseFromSpec(ValSepI, '-a1 -a2 3'.split()) |
| assert options.a() == ['1', '2'] |
| assert options.remaining() == ['3'] |
| |
| options = cli.parseFromSpec(ValSepI, ['-b1,2'] as String[]) |
| assert options.b() == ['1', '2'] |
| |
| options = cli.parseFromSpec(ValSepI, ['-c', '1'] as String[]) |
| assert options.c() == ['1'] |
| |
| options = cli.parseFromSpec(ValSepI, ['-c1'] as String[]) |
| assert options.c() == ['1'] |
| |
| options = cli.parseFromSpec(ValSepI, ['-c1,2,3'] as String[]) |
| assert options.c() == ['1', '2', '3'] |
| // end::multipleArgsInterface[] |
| """ |
| } |
| |
| void testType() { |
| assertScript """ |
| import java.math.RoundingMode |
| $importCliBuilder |
| // tag::withType[] |
| def argz = '''-a John -b -d 21 -e 1980 -f 3.5 -g 3.14159 |
| -h cv.txt -i DOWN and some more'''.split() |
| def cli = new CliBuilder() |
| cli.a(type: String, 'a-arg') |
| cli.b(type: boolean, 'b-arg') |
| cli.c(type: Boolean, 'c-arg') |
| cli.d(type: int, 'd-arg') |
| cli.e(type: Long, 'e-arg') |
| cli.f(type: Float, 'f-arg') |
| cli.g(type: BigDecimal, 'g-arg') |
| cli.h(type: File, 'h-arg') |
| cli.i(type: RoundingMode, 'i-arg') |
| def options = cli.parse(argz) |
| assert options.a == 'John' |
| assert options.b |
| assert !options.c |
| assert options.d == 21 |
| assert options.e == 1980L |
| assert options.f == 3.5f |
| assert options.g == 3.14159 |
| assert options.h == new File('cv.txt') |
| assert options.i == RoundingMode.DOWN |
| assert options.arguments() == ['and', 'some', 'more'] |
| // end::withType[] |
| """ |
| } |
| |
| void testTypeMultiple() { |
| assertScript """ |
| $importCliBuilder |
| // tag::withTypeMultiple[] |
| def argz = '''-j 3 4 5 -k1.5,2.5,3.5 and some more'''.split() |
| def cli = new CliBuilder() |
| cli.j(args: 3, type: int[], 'j-arg') |
| cli.k(args: '+', valueSeparator: ',', type: BigDecimal[], 'k-arg') |
| def options = cli.parse(argz) |
| assert options.js == [3, 4, 5] // <1> |
| assert options.j == [3, 4, 5] // <1> |
| assert options.k == [1.5, 2.5, 3.5] |
| assert options.arguments() == ['and', 'some', 'more'] |
| // end::withTypeMultiple[] |
| """ |
| } |
| |
| void testConvert() { |
| assertScript """ |
| $importCliBuilder |
| // tag::withConvert[] |
| def argz = '''-a John -b Mary -d 2016-01-01 and some more'''.split() |
| def cli = new CliBuilder() |
| def lower = { it.toLowerCase() } |
| cli.a(convert: lower, 'a-arg') |
| cli.b(convert: { it.toUpperCase() }, 'b-arg') |
| cli.d(convert: { Date.parse('yyyy-MM-dd', it) }, 'd-arg') |
| def options = cli.parse(argz) |
| assert options.a == 'john' |
| assert options.b == 'MARY' |
| assert options.d.format('dd-MM-yyyy') == '01-01-2016' |
| assert options.arguments() == ['and', 'some', 'more'] |
| // end::withConvert[] |
| """ |
| } |
| |
| void testConvertInterface() { |
| assertScript """ |
| import cli.WithConvertI |
| $importCliBuilder |
| // tag::withConvertInterface[] |
| Date newYears = Date.parse("yyyy-MM-dd", "2016-01-01") |
| def argz = '''-a John -b Mary -d 2016-01-01 and some more'''.split() |
| def cli = new CliBuilder() |
| def options = cli.parseFromSpec(WithConvertI, argz) |
| assert options.a() == 'john' |
| assert options.b() == 'MARY' |
| assert options.d() == newYears |
| assert options.remaining() == ['and', 'some', 'more'] |
| // end::withConvertInterface[] |
| """ |
| } |
| |
| void testDefaultValue() { |
| assertScript """ |
| $importCliBuilder |
| // tag::withDefaultValue[] |
| def cli = new CliBuilder() |
| cli.f longOpt: 'from', type: String, args: 1, defaultValue: 'one', 'f option' |
| cli.t longOpt: 'to', type: int, defaultValue: '35', 't option' |
| |
| def options = cli.parse('-f two'.split()) |
| assert options.hasOption('f') |
| assert options.f == 'two' |
| assert !options.hasOption('t') |
| assert options.t == 35 |
| |
| options = cli.parse('-t 45'.split()) |
| assert !options.hasOption('from') |
| assert options.from == 'one' |
| assert options.hasOption('to') |
| assert options.to == 45 |
| // end::withDefaultValue[] |
| """ |
| } |
| |
| void testDefaultValueInterface() { |
| assertScript """ |
| $importCliBuilder |
| import cli.WithDefaultValueI |
| // tag::withDefaultValueInterface[] |
| def cli = new CliBuilder() |
| |
| def options = cli.parseFromSpec(WithDefaultValueI, '-f two'.split()) |
| assert options.from() == 'two' |
| assert options.to() == 35 |
| |
| options = cli.parseFromSpec(WithDefaultValueI, '-t 45'.split()) |
| assert options.from() == 'one' |
| assert options.to() == 45 |
| // end::withDefaultValueInterface[] |
| """ |
| } |
| |
| void testTypeCheckedInterfaceRunner() { |
| assertScript """ |
| $importCliBuilder |
| import cli.TypeCheckedI |
| import groovy.transform.TypeChecked |
| // tag::withTypeCheckedInterface[] |
| @TypeChecked |
| void testTypeCheckedInterface() { |
| def argz = "--name John --age 21 and some more".split() |
| def cli = new CliBuilder() |
| def options = cli.parseFromSpec(TypeCheckedI, argz) |
| String n = options.name() |
| int a = options.age() |
| assert n == 'John' && a == 21 |
| assert options.remaining() == ['and', 'some', 'more'] |
| } |
| // end::withTypeCheckedInterface[] |
| testTypeCheckedInterface() |
| """ |
| } |
| |
| void testTypeCheckedRunner() { |
| assertScript """ |
| $importCliBuilder |
| // tag::withTypeChecked[] |
| import groovy.cli.TypedOption |
| import groovy.transform.TypeChecked |
| |
| @TypeChecked |
| void testTypeChecked() { |
| def cli = new CliBuilder() |
| TypedOption<String> name = cli.option(String, opt: 'n', longOpt: 'name', 'name option') |
| TypedOption<Integer> age = cli.option(Integer, longOpt: 'age', 'age option') |
| def argz = "--name John --age 21 and some more".split() |
| def options = cli.parse(argz) |
| String n = options[name] |
| int a = options[age] |
| assert n == 'John' && a == 21 |
| assert options.arguments() == ['and', 'some', 'more'] |
| } |
| // end::withTypeChecked[] |
| testTypeChecked() |
| """ |
| } |
| } |