Skip to content

Commit

Permalink
New Options class for reading commandline options.
Browse files Browse the repository at this point in the history
  • Loading branch information
heySourabh committed Aug 21, 2023
1 parent bfeeeea commit fd473d1
Show file tree
Hide file tree
Showing 2 changed files with 191 additions and 0 deletions.
71 changes: 71 additions & 0 deletions src/main/util/Options.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package main.util;

import java.util.Arrays;
import java.util.List;
import java.util.NoSuchElementException;

import static java.lang.String.valueOf;

/**
* A simple utility for reading command line arguments.
*/
public class Options {
private final String[] args;

public Options(String[] args) {
this.args = args;
}

public String get(String arg) {
String argName = (arg.startsWith("--") ? arg : ("--" + arg)).trim();
List<String> option = Arrays.stream(args)
.dropWhile(a -> !a.equals(argName))
.limit(2)
.toList();
if (option.size() != 2) {
throw new NoSuchElementException("Cannot find argument named: " + argName);
}

return option.get(1);
}

public String getOrDefault(String argName, String defaultValue) {
try {
return get(argName);
} catch (NoSuchElementException ex) {
return defaultValue;
}
}

private int parseInt(String argName, String argValue) {
try {
return Integer.parseInt(argValue);
} catch (NumberFormatException ex) {
throw new IllegalArgumentException("Unable to parse value '" + argValue + "' as integer for the argument named '" + argName + "'");
}
}

public int getInt(String argName) {
return parseInt(argName, get(argName));
}

public int getIntOrDefault(String argName, int defaultValue) {
return parseInt(argName, getOrDefault(argName, valueOf(defaultValue)));
}

private double parseDouble(String argName, String argValue) {
try {
return Double.parseDouble(argValue);
} catch (NumberFormatException ex) {
throw new IllegalArgumentException("Unable to parse value '" + argValue + "' as double for the argument named '" + argName + "'");
}
}

public double getDouble(String argName) {
return parseDouble(argName, get(argName));
}

public double getDoubleOrDefault(String argName, double defaultValue) {
return parseDouble(argName, getOrDefault(argName, valueOf(defaultValue)));
}
}
120 changes: 120 additions & 0 deletions test/main/util/OptionsTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package main.util;

import org.junit.Test;

import java.util.NoSuchElementException;

import static org.junit.Assert.*;

public class OptionsTest {
@Test
public void test_throws_when_argument_is_not_present() {
String[] args = new String[]{
"--Mach", "3",
"--AoA", "2.5",
"--name", "String argument",
"--incomplete",
};
Options options = new Options(args);

NoSuchElementException exception = assertThrows(NoSuchElementException.class, () -> options.get("not-arg"));
assertEquals("Cannot find argument named: --not-arg", exception.getMessage());
exception = assertThrows(NoSuchElementException.class, () -> options.get("incomplete"));
assertEquals("Cannot find argument named: --incomplete", exception.getMessage());
}

@Test
public void test_string_option() {
String[] args = new String[]{
"--Mach", "3",
"--AoA", "2.5",
"--name", "String argument"
};
Options options = new Options(args);

assertEquals("String argument", options.get("name"));
assertEquals("String argument", options.get("--name"));
}

@Test
public void test_default_value() {
String[] args = new String[]{
"--Mach", "3",
"--AoA", "2.5",
"--name", "String argument"
};
Options options = new Options(args);

assertEquals("String argument", options.getOrDefault("--name", "Default argument"));
assertEquals("Default argument", options.getOrDefault("unknown", "Default argument"));
}

@Test
public void test_int_argument() {
String[] args = new String[]{
"--Mach", "3",
"--AoA", "2.5",
"--name", "String argument"
};
Options options = new Options(args);

assertEquals(3, options.getInt("Mach"));
}

@Test
public void test_int_argument_with_default_value() {
String[] args = new String[]{
"--Mach", "3",
"--AoA", "2.5",
"--name", "String argument"
};
Options options = new Options(args);

assertEquals(3, options.getIntOrDefault("Mach", 4));
assertEquals(6, options.getIntOrDefault("Count", 6));
}

@Test
public void test_int_parsing_exception() {
String[] args = new String[]{
"--Mach", "3.5",
"--AoA", "2.5",
"--name", "String argument"
};
Options options = new Options(args);
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> options.getInt("Mach"));
assertEquals("Unable to parse value '3.5' as integer for the argument named 'Mach'", exception.getMessage());
exception = assertThrows(IllegalArgumentException.class, () -> options.getIntOrDefault("Mach", 5));
assertEquals("Unable to parse value '3.5' as integer for the argument named 'Mach'", exception.getMessage());
}

@Test
public void test_double_argument() {
String[] args = new String[]{
"--Mach", "3",
"--AoA", "2.5",
"--name", "String argument"
};
Options options = new Options(args);

assertEquals(2.5, options.getDouble("AoA"), 1e-15);
assertEquals(3, options.getDouble("Mach"), 1e-15);
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> options.getDouble("name"));
assertEquals("Unable to parse value 'String argument' as double for the argument named 'name'", exception.getMessage());
}

@Test
public void test_double_argument_with_default_value() {
String[] args = new String[]{
"--Mach", "3",
"--AoA", "2.5",
"--name", "String argument"
};
Options options = new Options(args);
assertEquals(2.5, options.getDoubleOrDefault("AoA", 2.5), 1e-15);
assertEquals(3, options.getDoubleOrDefault("undefined", 3), 1e-15);

IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> options.getDoubleOrDefault("name", 2.5));
assertEquals("Unable to parse value 'String argument' as double for the argument named 'name'", exception.getMessage());
}
}

0 comments on commit fd473d1

Please sign in to comment.