├── .gitignore ├── .idea └── inspectionProfiles │ ├── Project_Default.xml │ └── profiles_settings.xml ├── README ├── build.xml ├── src └── com │ └── cleancoder │ └── args │ ├── Args.java │ ├── ArgsException.java │ ├── ArgumentMarshaler.java │ ├── BooleanArgumentMarshaler.java │ ├── DoubleArgumentMarshaler.java │ ├── IntegerArgumentMarshaler.java │ ├── MapArgumentMarshaler.java │ ├── StringArgumentMarshaler.java │ └── StringArrayArgumentMarshaler.java └── test └── com └── cleancoder └── args ├── ArgsExceptionTest.java └── ArgsTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | build 3 | *.iml 4 | out 5 | classes 6 | getopts.i* 7 | 8 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This is the java version of the Args program described in: http://butunclebob.com/ArticleS.UncleBob.CleanCodeArgs 2 | 3 | public class ArgsMain { 4 | public static void main(String[] args) { 5 | try { 6 | Args arg = new Args("l,p#,d*", args); 7 | boolean logging = arg.getBoolean('l'); 8 | int port = arg.getInt('p'); 9 | String directory = arg.getString('d'); 10 | executeApplication(logging, port, directory); 11 | } catch (ArgsException e) { 12 | System.out.printf("Argument error: %s\n", e.errorMessage()); 13 | } 14 | } 15 | 16 | private static void executeApplication(boolean logging, int port, String directory) { 17 | System.out.printf("logging is %s, port:%d, directory:%s\n",logging, port, directory); 18 | } 19 | } 20 | 21 | Schema: 22 | - char - Boolean arg. 23 | - char* - String arg. 24 | - char# - Integer arg. 25 | - char## - double arg. 26 | - char[*] - one element of a string array. 27 | 28 | Example schema: (f,s*,n#,a##,p[*]) 29 | Coresponding command line: "-f -s Bob -n 1 -a 3.2 -p e1 -p e2 -p e3 30 | 31 | -------------------------------------------------------------------------------- /build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/com/cleancoder/args/Args.java: -------------------------------------------------------------------------------- 1 | package com.cleancoder.args; 2 | 3 | import java.util.*; 4 | 5 | import static com.cleancoder.args.ArgsException.ErrorCode.*; 6 | 7 | public class Args { 8 | private Map marshalers; 9 | private Set argsFound; 10 | private ListIterator currentArgument; 11 | 12 | public Args(String schema, String[] args) throws ArgsException { 13 | marshalers = new HashMap(); 14 | argsFound = new HashSet(); 15 | 16 | parseSchema(schema); 17 | parseArgumentStrings(Arrays.asList(args)); 18 | } 19 | 20 | private void parseSchema(String schema) throws ArgsException { 21 | for (String element : schema.split(",")) 22 | if (element.length() > 0) 23 | parseSchemaElement(element.trim()); 24 | } 25 | 26 | private void parseSchemaElement(String element) throws ArgsException { 27 | char elementId = element.charAt(0); 28 | String elementTail = element.substring(1); 29 | validateSchemaElementId(elementId); 30 | if (elementTail.length() == 0) 31 | marshalers.put(elementId, new BooleanArgumentMarshaler()); 32 | else if (elementTail.equals("*")) 33 | marshalers.put(elementId, new StringArgumentMarshaler()); 34 | else if (elementTail.equals("#")) 35 | marshalers.put(elementId, new IntegerArgumentMarshaler()); 36 | else if (elementTail.equals("##")) 37 | marshalers.put(elementId, new DoubleArgumentMarshaler()); 38 | else if (elementTail.equals("[*]")) 39 | marshalers.put(elementId, new StringArrayArgumentMarshaler()); 40 | else if (elementTail.equals("&")) 41 | marshalers.put(elementId, new MapArgumentMarshaler()); 42 | else 43 | throw new ArgsException(INVALID_ARGUMENT_FORMAT, elementId, elementTail); 44 | } 45 | 46 | private void validateSchemaElementId(char elementId) throws ArgsException { 47 | if (!Character.isLetter(elementId)) 48 | throw new ArgsException(INVALID_ARGUMENT_NAME, elementId, null); 49 | } 50 | 51 | private void parseArgumentStrings(List argsList) throws ArgsException { 52 | for (currentArgument = argsList.listIterator(); currentArgument.hasNext();) { 53 | String argString = currentArgument.next(); 54 | if (argString.startsWith("-")) { 55 | parseArgumentCharacters(argString.substring(1)); 56 | } else { 57 | currentArgument.previous(); 58 | break; 59 | } 60 | } 61 | } 62 | 63 | private void parseArgumentCharacters(String argChars) throws ArgsException { 64 | for (int i = 0; i < argChars.length(); i++) 65 | parseArgumentCharacter(argChars.charAt(i)); 66 | } 67 | 68 | private void parseArgumentCharacter(char argChar) throws ArgsException { 69 | ArgumentMarshaler m = marshalers.get(argChar); 70 | if (m == null) { 71 | throw new ArgsException(UNEXPECTED_ARGUMENT, argChar, null); 72 | } else { 73 | argsFound.add(argChar); 74 | try { 75 | m.set(currentArgument); 76 | } catch (ArgsException e) { 77 | e.setErrorArgumentId(argChar); 78 | throw e; 79 | } 80 | } 81 | } 82 | 83 | public boolean has(char arg) { 84 | return argsFound.contains(arg); 85 | } 86 | 87 | public int nextArgument() { 88 | return currentArgument.nextIndex(); 89 | } 90 | 91 | public boolean getBoolean(char arg) { 92 | return BooleanArgumentMarshaler.getValue(marshalers.get(arg)); 93 | } 94 | 95 | public String getString(char arg) { 96 | return StringArgumentMarshaler.getValue(marshalers.get(arg)); 97 | } 98 | 99 | public int getInt(char arg) { 100 | return IntegerArgumentMarshaler.getValue(marshalers.get(arg)); 101 | } 102 | 103 | public double getDouble(char arg) { 104 | return DoubleArgumentMarshaler.getValue(marshalers.get(arg)); 105 | } 106 | 107 | public String[] getStringArray(char arg) { 108 | return StringArrayArgumentMarshaler.getValue(marshalers.get(arg)); 109 | } 110 | 111 | public Map getMap(char arg) { 112 | return MapArgumentMarshaler.getValue(marshalers.get(arg)); 113 | } 114 | } -------------------------------------------------------------------------------- /src/com/cleancoder/args/ArgsException.java: -------------------------------------------------------------------------------- 1 | package com.cleancoder.args; 2 | 3 | import static com.cleancoder.args.ArgsException.ErrorCode.*; 4 | 5 | public class ArgsException extends Exception { 6 | private char errorArgumentId = '\0'; 7 | private String errorParameter = null; 8 | private ErrorCode errorCode = OK; 9 | 10 | public ArgsException() {} 11 | 12 | public ArgsException(String message) {super(message);} 13 | 14 | public ArgsException(ErrorCode errorCode) { 15 | this.errorCode = errorCode; 16 | } 17 | 18 | public ArgsException(ErrorCode errorCode, String errorParameter) { 19 | this.errorCode = errorCode; 20 | this.errorParameter = errorParameter; 21 | } 22 | 23 | public ArgsException(ErrorCode errorCode, char errorArgumentId, String errorParameter) { 24 | this.errorCode = errorCode; 25 | this.errorParameter = errorParameter; 26 | this.errorArgumentId = errorArgumentId; 27 | } 28 | 29 | public char getErrorArgumentId() { 30 | return errorArgumentId; 31 | } 32 | 33 | public void setErrorArgumentId(char errorArgumentId) { 34 | this.errorArgumentId = errorArgumentId; 35 | } 36 | 37 | public String getErrorParameter() { 38 | return errorParameter; 39 | } 40 | 41 | public void setErrorParameter(String errorParameter) { 42 | this.errorParameter = errorParameter; 43 | } 44 | 45 | public ErrorCode getErrorCode() { 46 | return errorCode; 47 | } 48 | 49 | public void setErrorCode(ErrorCode errorCode) { 50 | this.errorCode = errorCode; 51 | } 52 | 53 | public String errorMessage() { 54 | switch (errorCode) { 55 | case OK: 56 | return "TILT: Should not get here."; 57 | case UNEXPECTED_ARGUMENT: 58 | return String.format("Argument -%c unexpected.", errorArgumentId); 59 | case MISSING_STRING: 60 | return String.format("Could not find string parameter for -%c.", errorArgumentId); 61 | case INVALID_INTEGER: 62 | return String.format("Argument -%c expects an integer but was '%s'.", errorArgumentId, errorParameter); 63 | case MISSING_INTEGER: 64 | return String.format("Could not find integer parameter for -%c.", errorArgumentId); 65 | case INVALID_DOUBLE: 66 | return String.format("Argument -%c expects a double but was '%s'.", errorArgumentId, errorParameter); 67 | case MISSING_DOUBLE: 68 | return String.format("Could not find double parameter for -%c.", errorArgumentId); 69 | case INVALID_ARGUMENT_NAME: 70 | return String.format("'%c' is not a valid argument name.", errorArgumentId); 71 | case INVALID_ARGUMENT_FORMAT: 72 | return String.format("'%s' is not a valid argument format.", errorParameter); 73 | case MISSING_MAP: 74 | return String.format("Could not find map string for -%c.", errorArgumentId); 75 | case MALFORMED_MAP: 76 | return String.format("Map string for -%c is not of form k1:v1,k2:v2...", errorArgumentId); 77 | } 78 | return ""; 79 | } 80 | 81 | public enum ErrorCode { 82 | OK, INVALID_ARGUMENT_FORMAT, UNEXPECTED_ARGUMENT, INVALID_ARGUMENT_NAME, 83 | MISSING_STRING, 84 | MISSING_INTEGER, INVALID_INTEGER, 85 | MISSING_DOUBLE, MALFORMED_MAP, MISSING_MAP, INVALID_DOUBLE} 86 | } 87 | -------------------------------------------------------------------------------- /src/com/cleancoder/args/ArgumentMarshaler.java: -------------------------------------------------------------------------------- 1 | package com.cleancoder.args; 2 | 3 | import java.util.Iterator; 4 | 5 | public interface ArgumentMarshaler { 6 | void set(Iterator currentArgument) throws ArgsException; 7 | } 8 | -------------------------------------------------------------------------------- /src/com/cleancoder/args/BooleanArgumentMarshaler.java: -------------------------------------------------------------------------------- 1 | package com.cleancoder.args; 2 | 3 | import java.util.Iterator; 4 | 5 | public class BooleanArgumentMarshaler implements ArgumentMarshaler { 6 | private boolean booleanValue = false; 7 | 8 | public void set(Iterator currentArgument) throws ArgsException { 9 | booleanValue = true; 10 | } 11 | 12 | public static boolean getValue(ArgumentMarshaler am) { 13 | if (am != null && am instanceof BooleanArgumentMarshaler) 14 | return ((BooleanArgumentMarshaler) am).booleanValue; 15 | else 16 | return false; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/com/cleancoder/args/DoubleArgumentMarshaler.java: -------------------------------------------------------------------------------- 1 | package com.cleancoder.args; 2 | 3 | import static com.cleancoder.args.ArgsException.ErrorCode.*; 4 | 5 | import java.util.*; 6 | 7 | public class DoubleArgumentMarshaler implements ArgumentMarshaler { 8 | private double doubleValue = 0; 9 | 10 | public void set(Iterator currentArgument) throws ArgsException { 11 | String parameter = null; 12 | try { 13 | parameter = currentArgument.next(); 14 | doubleValue = Double.parseDouble(parameter); 15 | } catch (NoSuchElementException e) { 16 | throw new ArgsException(MISSING_DOUBLE); 17 | } catch (NumberFormatException e) { 18 | throw new ArgsException(INVALID_DOUBLE, parameter); 19 | } 20 | } 21 | 22 | public static double getValue(ArgumentMarshaler am) { 23 | if (am != null && am instanceof DoubleArgumentMarshaler) 24 | return ((DoubleArgumentMarshaler) am).doubleValue; 25 | else 26 | return 0.0; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/com/cleancoder/args/IntegerArgumentMarshaler.java: -------------------------------------------------------------------------------- 1 | package com.cleancoder.args; 2 | 3 | import static com.cleancoder.args.ArgsException.ErrorCode.*; 4 | 5 | import java.util.*; 6 | 7 | public class IntegerArgumentMarshaler implements ArgumentMarshaler { 8 | private int intValue = 0; 9 | 10 | public void set(Iterator currentArgument) throws ArgsException { 11 | String parameter = null; 12 | try { 13 | parameter = currentArgument.next(); 14 | intValue = Integer.parseInt(parameter); 15 | } catch (NoSuchElementException e) { 16 | throw new ArgsException(MISSING_INTEGER); 17 | } catch (NumberFormatException e) { 18 | throw new ArgsException(INVALID_INTEGER, parameter); 19 | } 20 | } 21 | 22 | public static int getValue(ArgumentMarshaler am) { 23 | if (am != null && am instanceof IntegerArgumentMarshaler) 24 | return ((IntegerArgumentMarshaler) am).intValue; 25 | else 26 | return 0; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/com/cleancoder/args/MapArgumentMarshaler.java: -------------------------------------------------------------------------------- 1 | package com.cleancoder.args; 2 | 3 | import java.util.HashMap; 4 | import java.util.Iterator; 5 | import java.util.Map; 6 | import java.util.NoSuchElementException; 7 | 8 | import static com.cleancoder.args.ArgsException.ErrorCode.*; 9 | 10 | public class MapArgumentMarshaler implements ArgumentMarshaler { 11 | private Map map = new HashMap<>(); 12 | 13 | public void set(Iterator currentArgument) throws ArgsException { 14 | try { 15 | String[] mapEntries = currentArgument.next().split(","); 16 | for (String entry : mapEntries) { 17 | String[] entryComponents = entry.split(":"); 18 | if (entryComponents.length != 2) 19 | throw new ArgsException(MALFORMED_MAP); 20 | map.put(entryComponents[0], entryComponents[1]); 21 | } 22 | } catch (NoSuchElementException e) { 23 | throw new ArgsException(MISSING_MAP); 24 | } 25 | } 26 | 27 | public static Map getValue(ArgumentMarshaler am) { 28 | if (am != null && am instanceof MapArgumentMarshaler) 29 | return ((MapArgumentMarshaler) am).map; 30 | else 31 | return new HashMap<>(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/com/cleancoder/args/StringArgumentMarshaler.java: -------------------------------------------------------------------------------- 1 | package com.cleancoder.args; 2 | 3 | import java.util.Iterator; 4 | import java.util.NoSuchElementException; 5 | 6 | import static com.cleancoder.args.ArgsException.ErrorCode.MISSING_STRING; 7 | 8 | public class StringArgumentMarshaler implements ArgumentMarshaler { 9 | private String stringValue = ""; 10 | 11 | public void set(Iterator currentArgument) throws ArgsException { 12 | try { 13 | stringValue = currentArgument.next(); 14 | } catch (NoSuchElementException e) { 15 | throw new ArgsException(MISSING_STRING); 16 | } 17 | } 18 | 19 | public static String getValue(ArgumentMarshaler am) { 20 | if (am != null && am instanceof StringArgumentMarshaler) 21 | return ((StringArgumentMarshaler) am).stringValue; 22 | else 23 | return ""; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/com/cleancoder/args/StringArrayArgumentMarshaler.java: -------------------------------------------------------------------------------- 1 | package com.cleancoder.args; 2 | 3 | import static com.cleancoder.args.ArgsException.ErrorCode.*; 4 | 5 | import java.util.*; 6 | 7 | public class StringArrayArgumentMarshaler implements ArgumentMarshaler { 8 | private List strings = new ArrayList(); 9 | 10 | public void set(Iterator currentArgument) throws ArgsException { 11 | try { 12 | strings.add(currentArgument.next()); 13 | } catch (NoSuchElementException e) { 14 | throw new ArgsException(MISSING_STRING); 15 | } 16 | } 17 | 18 | public static String[] getValue(ArgumentMarshaler am) { 19 | if (am != null && am instanceof StringArrayArgumentMarshaler) 20 | return ((StringArrayArgumentMarshaler) am).strings.toArray(new String[0]); 21 | else 22 | return new String[0]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/com/cleancoder/args/ArgsExceptionTest.java: -------------------------------------------------------------------------------- 1 | package com.cleancoder.args; 2 | 3 | import junit.framework.TestCase; 4 | 5 | import static com.cleancoder.args.ArgsException.ErrorCode.*; 6 | 7 | public class ArgsExceptionTest extends TestCase { 8 | public void testUnexpectedMessage() throws Exception { 9 | ArgsException e = new ArgsException(UNEXPECTED_ARGUMENT, 'x', null); 10 | assertEquals("Argument -x unexpected.", e.errorMessage()); 11 | } 12 | 13 | public void testMissingStringMessage() throws Exception { 14 | ArgsException e = new ArgsException(MISSING_STRING, 'x', null); 15 | assertEquals("Could not find string parameter for -x.", e.errorMessage()); 16 | } 17 | 18 | public void testInvalidIntegerMessage() throws Exception { 19 | ArgsException e = new ArgsException(INVALID_INTEGER, 'x', "Forty two"); 20 | assertEquals("Argument -x expects an integer but was 'Forty two'.", e.errorMessage()); 21 | } 22 | 23 | public void testMissingIntegerMessage() throws Exception { 24 | ArgsException e = new ArgsException(MISSING_INTEGER, 'x', null); 25 | assertEquals("Could not find integer parameter for -x.", e.errorMessage()); 26 | } 27 | 28 | public void testInvalidDoubleMessage() throws Exception { 29 | ArgsException e = new ArgsException(INVALID_DOUBLE, 'x', "Forty two"); 30 | assertEquals("Argument -x expects a double but was 'Forty two'.", e.errorMessage()); 31 | } 32 | 33 | public void testMissingDoubleMessage() throws Exception { 34 | ArgsException e = new ArgsException(MISSING_DOUBLE, 'x', null); 35 | assertEquals("Could not find double parameter for -x.", e.errorMessage()); 36 | } 37 | 38 | public void testMissingMapMessage() throws Exception { 39 | ArgsException e = new ArgsException(MISSING_MAP, 'x', null); 40 | assertEquals("Could not find map string for -x.", e.errorMessage()); 41 | } 42 | 43 | public void testMalformedMapMessage() throws Exception { 44 | ArgsException e = new ArgsException(MALFORMED_MAP, 'x', null); 45 | assertEquals("Map string for -x is not of form k1:v1,k2:v2...", e.errorMessage()); 46 | } 47 | 48 | public void testInvalidArgumentName() throws Exception { 49 | ArgsException e = new ArgsException(INVALID_ARGUMENT_NAME, '#', null); 50 | assertEquals("'#' is not a valid argument name.", e.errorMessage()); 51 | } 52 | 53 | public void testInvalidFormat() throws Exception { 54 | ArgsException e = new ArgsException(INVALID_ARGUMENT_FORMAT, 'x', "$"); 55 | assertEquals("'$' is not a valid argument format.", e.errorMessage()); 56 | } 57 | } 58 | 59 | -------------------------------------------------------------------------------- /test/com/cleancoder/args/ArgsTest.java: -------------------------------------------------------------------------------- 1 | package com.cleancoder.args; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Map; 6 | 7 | import static com.cleancoder.args.ArgsException.ErrorCode.*; 8 | import static org.junit.Assert.*; 9 | 10 | public class ArgsTest { 11 | 12 | @Test 13 | public void testCreateWithNoSchemaOrArguments() throws Exception { 14 | Args args = new Args("", new String[0]); 15 | assertEquals(0, args.nextArgument()); 16 | } 17 | 18 | 19 | @Test 20 | public void testWithNoSchemaButWithOneArgument() throws Exception { 21 | try { 22 | new Args("", new String[]{"-x"}); 23 | fail(); 24 | } catch (ArgsException e) { 25 | assertEquals(UNEXPECTED_ARGUMENT, e.getErrorCode()); 26 | assertEquals('x', e.getErrorArgumentId()); 27 | } 28 | } 29 | 30 | @Test 31 | public void testWithNoSchemaButWithMultipleArguments() throws Exception { 32 | try { 33 | new Args("", new String[]{"-x", "-y"}); 34 | fail(); 35 | } catch (ArgsException e) { 36 | assertEquals(UNEXPECTED_ARGUMENT, e.getErrorCode()); 37 | assertEquals('x', e.getErrorArgumentId()); 38 | } 39 | 40 | } 41 | 42 | @Test 43 | public void testNonLetterSchema() throws Exception { 44 | try { 45 | new Args("*", new String[]{}); 46 | fail("Args constructor should have thrown exception"); 47 | } catch (ArgsException e) { 48 | assertEquals(INVALID_ARGUMENT_NAME, e.getErrorCode()); 49 | assertEquals('*', e.getErrorArgumentId()); 50 | } 51 | } 52 | 53 | @Test 54 | public void testInvalidArgumentFormat() throws Exception { 55 | try { 56 | new Args("f~", new String[]{}); 57 | fail("Args constructor should have throws exception"); 58 | } catch (ArgsException e) { 59 | assertEquals(INVALID_ARGUMENT_FORMAT, e.getErrorCode()); 60 | assertEquals('f', e.getErrorArgumentId()); 61 | } 62 | } 63 | 64 | @Test 65 | public void testSimpleBooleanPresent() throws Exception { 66 | Args args = new Args("x", new String[]{"-x"}); 67 | assertEquals(true, args.getBoolean('x')); 68 | assertEquals(1, args.nextArgument()); 69 | } 70 | 71 | @Test 72 | public void testSimpleStringPresent() throws Exception { 73 | Args args = new Args("x*", new String[]{"-x", "param"}); 74 | assertTrue(args.has('x')); 75 | assertEquals("param", args.getString('x')); 76 | assertEquals(2, args.nextArgument()); 77 | } 78 | 79 | @Test 80 | public void testMissingStringArgument() throws Exception { 81 | try { 82 | new Args("x*", new String[]{"-x"}); 83 | fail(); 84 | } catch (ArgsException e) { 85 | assertEquals(MISSING_STRING, e.getErrorCode()); 86 | assertEquals('x', e.getErrorArgumentId()); 87 | } 88 | } 89 | 90 | @Test 91 | public void testSpacesInFormat() throws Exception { 92 | Args args = new Args("x, y", new String[]{"-xy"}); 93 | assertTrue(args.has('x')); 94 | assertTrue(args.has('y')); 95 | assertEquals(1, args.nextArgument()); 96 | } 97 | 98 | @Test 99 | public void testSimpleIntPresent() throws Exception { 100 | Args args = new Args("x#", new String[]{"-x", "42"}); 101 | assertTrue(args.has('x')); 102 | assertEquals(42, args.getInt('x')); 103 | assertEquals(2, args.nextArgument()); 104 | } 105 | 106 | @Test 107 | public void testInvalidInteger() throws Exception { 108 | try { 109 | new Args("x#", new String[]{"-x", "Forty two"}); 110 | fail(); 111 | } catch (ArgsException e) { 112 | assertEquals(INVALID_INTEGER, e.getErrorCode()); 113 | assertEquals('x', e.getErrorArgumentId()); 114 | assertEquals("Forty two", e.getErrorParameter()); 115 | } 116 | 117 | } 118 | 119 | @Test 120 | public void testMissingInteger() throws Exception { 121 | try { 122 | new Args("x#", new String[]{"-x"}); 123 | fail(); 124 | } catch (ArgsException e) { 125 | assertEquals(MISSING_INTEGER, e.getErrorCode()); 126 | assertEquals('x', e.getErrorArgumentId()); 127 | } 128 | } 129 | 130 | @Test 131 | public void testSimpleDoublePresent() throws Exception { 132 | Args args = new Args("x##", new String[]{"-x", "42.3"}); 133 | assertTrue(args.has('x')); 134 | assertEquals(42.3, args.getDouble('x'), .001); 135 | } 136 | 137 | @Test 138 | public void testInvalidDouble() throws Exception { 139 | try { 140 | new Args("x##", new String[]{"-x", "Forty two"}); 141 | fail(); 142 | } catch (ArgsException e) { 143 | assertEquals(INVALID_DOUBLE, e.getErrorCode()); 144 | assertEquals('x', e.getErrorArgumentId()); 145 | assertEquals("Forty two", e.getErrorParameter()); 146 | } 147 | } 148 | 149 | @Test 150 | public void testMissingDouble() throws Exception { 151 | try { 152 | new Args("x##", new String[]{"-x"}); 153 | fail(); 154 | } catch (ArgsException e) { 155 | assertEquals(MISSING_DOUBLE, e.getErrorCode()); 156 | assertEquals('x', e.getErrorArgumentId()); 157 | } 158 | } 159 | 160 | @Test 161 | public void testStringArray() throws Exception { 162 | Args args = new Args("x[*]", new String[]{"-x", "alpha"}); 163 | assertTrue(args.has('x')); 164 | String[] result = args.getStringArray('x'); 165 | assertEquals(1, result.length); 166 | assertEquals("alpha", result[0]); 167 | } 168 | 169 | @Test 170 | public void testMissingStringArrayElement() throws Exception { 171 | try { 172 | new Args("x[*]", new String[] {"-x"}); 173 | fail(); 174 | } catch (ArgsException e) { 175 | assertEquals(MISSING_STRING,e.getErrorCode()); 176 | assertEquals('x', e.getErrorArgumentId()); 177 | } 178 | } 179 | 180 | @Test 181 | public void manyStringArrayElements() throws Exception { 182 | Args args = new Args("x[*]", new String[]{"-x", "alpha", "-x", "beta", "-x", "gamma"}); 183 | assertTrue(args.has('x')); 184 | String[] result = args.getStringArray('x'); 185 | assertEquals(3, result.length); 186 | assertEquals("alpha", result[0]); 187 | assertEquals("beta", result[1]); 188 | assertEquals("gamma", result[2]); 189 | } 190 | 191 | @Test 192 | public void MapArgument() throws Exception { 193 | Args args = new Args("f&", new String[] {"-f", "key1:val1,key2:val2"}); 194 | assertTrue(args.has('f')); 195 | Map map = args.getMap('f'); 196 | assertEquals("val1", map.get("key1")); 197 | assertEquals("val2", map.get("key2")); 198 | } 199 | 200 | @Test(expected=ArgsException.class) 201 | public void malFormedMapArgument() throws Exception { 202 | Args args = new Args("f&", new String[] {"-f", "key1:val1,key2"}); 203 | } 204 | 205 | @Test 206 | public void oneMapArgument() throws Exception { 207 | Args args = new Args("f&", new String[] {"-f", "key1:val1"}); 208 | assertTrue(args.has('f')); 209 | Map map = args.getMap('f'); 210 | assertEquals("val1", map.get("key1")); 211 | } 212 | 213 | @Test 214 | public void testExtraArguments() throws Exception { 215 | Args args = new Args("x,y*", new String[]{"-x", "-y", "alpha", "beta"}); 216 | assertTrue(args.getBoolean('x')); 217 | assertEquals("alpha", args.getString('y')); 218 | assertEquals(3, args.nextArgument()); 219 | } 220 | 221 | @Test 222 | public void testExtraArgumentsThatLookLikeFlags() throws Exception { 223 | Args args = new Args("x,y", new String[]{"-x", "alpha", "-y", "beta"}); 224 | assertTrue(args.has('x')); 225 | assertFalse(args.has('y')); 226 | assertTrue(args.getBoolean('x')); 227 | assertFalse(args.getBoolean('y')); 228 | assertEquals(1, args.nextArgument()); 229 | } 230 | } 231 | --------------------------------------------------------------------------------