You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2024/02/16 16:23:36 UTC
(commons-cli) branch master updated: CLI-324 Make adding OptionGroups and Options to existing Options easier (#230)
This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-cli.git
The following commit(s) were added to refs/heads/master by this push:
new 14a95d9 CLI-324 Make adding OptionGroups and Options to existing Options easier (#230)
14a95d9 is described below
commit 14a95d9e3a17b28d0030b51aef45464137efc74a
Author: Claude Warren <cl...@aiven.io>
AuthorDate: Fri Feb 16 17:23:31 2024 +0100
CLI-324 Make adding OptionGroups and Options to existing Options easier (#230)
* Fixes for CLI-324
* added tests
* reverted change of getOptionGroup to public and added documentation
* added test cases and javadoc to explain functioning
---
src/main/java/org/apache/commons/cli/Options.java | 26 +++++-
.../java/org/apache/commons/cli/OptionsTest.java | 93 ++++++++++++++++++++++
2 files changed, 118 insertions(+), 1 deletion(-)
diff --git a/src/main/java/org/apache/commons/cli/Options.java b/src/main/java/org/apache/commons/cli/Options.java
index ee7ce14..6fff20b 100644
--- a/src/main/java/org/apache/commons/cli/Options.java
+++ b/src/main/java/org/apache/commons/cli/Options.java
@@ -54,6 +54,25 @@ public class Options implements Serializable {
/** A map of the option groups */
private final Map<String, OptionGroup> optionGroups = new LinkedHashMap<>();
+ /**
+ * Adds options to this option. If any Option in {@code options} already exists
+ * in this Options an IllegalArgumentException is thrown
+ *
+ * @param options the options to add.
+ * @return The resulting Options instance.
+ * @since 1.7.0
+ */
+ public Options addOptions(final Options options) {
+ for (Option opt : options.getOptions()) {
+ if (hasOption(opt.getKey())) {
+ throw new IllegalArgumentException("Duplicate key: " + opt.getKey());
+ }
+ addOption(opt);
+ }
+ options.getOptionGroups().forEach(this::addOptionGroup);
+ return this;
+ }
+
/**
* Adds an option instance
*
@@ -233,6 +252,11 @@ public class Options implements Serializable {
* @return a Collection of OptionGroup instances.
*/
Collection<OptionGroup> getOptionGroups() {
+ /* The optionGroups map will have duplicates in the values() results. We
+ * use the HashSet to filter out duplicates and return a collection of
+ * OpitonGroup. The decision to return a Collection rather than a set
+ * was probably to keep symmetry with the getOptions() method.
+ */
return new HashSet<>(optionGroups.values());
}
@@ -250,7 +274,7 @@ public class Options implements Serializable {
*
* @return read-only List of required options
*/
- public List getRequiredOptions() {
+ public List<?> getRequiredOptions() {
return Collections.unmodifiableList(requiredOpts);
}
diff --git a/src/test/java/org/apache/commons/cli/OptionsTest.java b/src/test/java/org/apache/commons/cli/OptionsTest.java
index 3d7004f..1f93bc7 100644
--- a/src/test/java/org/apache/commons/cli/OptionsTest.java
+++ b/src/test/java/org/apache/commons/cli/OptionsTest.java
@@ -21,9 +21,15 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
import org.junit.Test;
@@ -78,6 +84,93 @@ public class OptionsTest {
assertEquals(2, options.getOptionGroups().size());
}
+ @Test
+ public void testAddOptions() {
+ final Options options = new Options();
+
+ final OptionGroup group1 = new OptionGroup();
+ group1.addOption(Option.builder("a").build());
+ group1.addOption(Option.builder("b").build());
+
+ options.addOptionGroup(group1);
+
+ options.addOption(Option.builder("X").build());
+ options.addOption(Option.builder("y").build());
+
+ final Options underTest = new Options();
+ underTest.addOptions(options);
+
+ assertEquals(options.getOptionGroups(), underTest.getOptionGroups());
+ assertArrayEquals(options.getOptions().toArray(), underTest.getOptions().toArray());
+ }
+
+ @Test
+ public void testAddOptions2X() {
+ final Options options = new Options();
+
+ final OptionGroup group1 = new OptionGroup();
+ group1.addOption(Option.builder("a").build());
+ group1.addOption(Option.builder("b").build());
+
+ options.addOptionGroup(group1);
+
+ options.addOption(Option.builder("X").build());
+ options.addOption(Option.builder("y").build());
+
+ assertThrows(IllegalArgumentException.class, () -> options.addOptions(options));
+ }
+
+ @Test
+ public void testAddConflictingOptions() {
+ final Options options1 = new Options();
+ final OptionGroup group1 = new OptionGroup();
+ group1.addOption(Option.builder("a").build());
+ group1.addOption(Option.builder("b").build());
+ options1.addOptionGroup(group1);
+ options1.addOption(Option.builder("x").build());
+ options1.addOption(Option.builder("y").build());
+
+ final Options options2 = new Options();
+ final OptionGroup group2 = new OptionGroup();
+ group2.addOption(Option.builder("x").type(Integer.class).build());
+ group2.addOption(Option.builder("b").type(Integer.class).build());
+ options2.addOptionGroup(group2);
+ options2.addOption(Option.builder("c").build());
+
+ assertThrows(IllegalArgumentException.class, () -> options1.addOptions(options2));
+ }
+
+ @Test
+ public void testAddNonConflictingOptions() {
+ final Options options1 = new Options();
+ final OptionGroup group1 = new OptionGroup();
+ group1.addOption(Option.builder("a").build());
+ group1.addOption(Option.builder("b").build());
+ options1.addOptionGroup(group1);
+ options1.addOption(Option.builder("x").build());
+ options1.addOption(Option.builder("y").build());
+
+ final Options options2 = new Options();
+ final OptionGroup group2 = new OptionGroup();
+ group2.addOption(Option.builder("c").type(Integer.class).build());
+ group2.addOption(Option.builder("d").type(Integer.class).build());
+ options2.addOptionGroup(group2);
+ options1.addOption(Option.builder("e").build());
+ options1.addOption(Option.builder("f").build());
+
+ Options underTest = new Options();
+ underTest.addOptions(options1);
+ underTest.addOptions(options2);
+
+ List<OptionGroup> expected = Arrays.asList(group1, group2);
+ assertTrue(expected.size() == underTest.getOptionGroups().size() && expected.containsAll(underTest.getOptionGroups()));
+ Set<Option> expectOpt = new HashSet<>();
+ expectOpt.addAll(options1.getOptions());
+ expectOpt.addAll(options2.getOptions());
+ assertEquals(8, expectOpt.size());
+ assertTrue(expectOpt.size() == underTest.getOptions().size() && expectOpt.containsAll(underTest.getOptions()));
+ }
+
@Test
public void testHelpOptions() {
OptionBuilder.withLongOpt("long-only1");