You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by is...@apache.org on 2022/12/19 06:20:50 UTC
[ignite-3] branch main updated: IGNITE-18221: Filter non-repitable options in interactive suggestions (#1432)
This is an automated email from the ASF dual-hosted git repository.
isapego pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new 2ace66a2b4 IGNITE-18221: Filter non-repitable options in interactive suggestions (#1432)
2ace66a2b4 is described below
commit 2ace66a2b4842e1c2b2f66fa436801f4e9211658
Author: Ivan Gagarkin <ga...@gmail.com>
AuthorDate: Mon Dec 19 10:20:44 2022 +0400
IGNITE-18221: Filter non-repitable options in interactive suggestions (#1432)
Co-authored-by: Ivan Gagarkin <ig...@gridgain.com>
---
.../cli/core/repl/completer/CompleterConf.java | 1 +
.../completer/DynamicCompleterActivationPoint.java | 1 +
.../completer/{ => filter}/CompleterFilter.java | 2 +-
.../{ => filter}/DynamicCompleterFilter.java | 2 +-
.../{ => filter}/ExclusionsCompleterFilter.java | 2 +-
.../filter/NonRepeatableOptionsFilter.java | 79 ++++++++++++++++++++++
.../ShortOptionsFilter.java} | 19 ++++--
.../core/repl/executor/IgnitePicocliCommands.java | 18 +++--
.../cli/core/repl/executor/ReplExecutor.java | 11 ++-
.../{ => filter}/DynamicCompleterFilterTest.java | 3 +-
.../ExclusionsCompleterFilterTest.java | 3 +-
.../filter/NonRepeatableOptionsFilterTest.java | 57 ++++++++++++++++
.../completer/filter/ShortOptionsFilterTest.java | 46 +++++++++++++
13 files changed, 220 insertions(+), 24 deletions(-)
diff --git a/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/CompleterConf.java b/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/CompleterConf.java
index d2840cde77..ca7b74c20f 100644
--- a/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/CompleterConf.java
+++ b/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/CompleterConf.java
@@ -24,6 +24,7 @@ import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.ignite.internal.cli.commands.Options;
+import org.apache.ignite.internal.cli.core.repl.completer.filter.CompleterFilter;
/**
* Configuration for dynamic completer. It declares for what command and option the completer could be applied.
diff --git a/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/DynamicCompleterActivationPoint.java b/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/DynamicCompleterActivationPoint.java
index 8f1ccce061..a2d8cdd5e1 100644
--- a/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/DynamicCompleterActivationPoint.java
+++ b/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/DynamicCompleterActivationPoint.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.cli.core.repl.completer;
import jakarta.inject.Singleton;
import org.apache.ignite.internal.cli.commands.Options;
+import org.apache.ignite.internal.cli.core.repl.completer.filter.ExclusionsCompleterFilter;
import org.apache.ignite.internal.cli.core.repl.completer.hocon.ClusterConfigDynamicCompleterFactory;
import org.apache.ignite.internal.cli.core.repl.completer.hocon.NodeConfigDynamicCompleterFactory;
import org.apache.ignite.internal.cli.core.repl.completer.node.NodeNameDynamicCompleterFactory;
diff --git a/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/CompleterFilter.java b/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/filter/CompleterFilter.java
similarity index 93%
rename from modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/CompleterFilter.java
rename to modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/filter/CompleterFilter.java
index 6830f9712b..9e183fa48f 100644
--- a/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/CompleterFilter.java
+++ b/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/filter/CompleterFilter.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.cli.core.repl.completer;
+package org.apache.ignite.internal.cli.core.repl.completer.filter;
/**
* Filters the result of completer.
diff --git a/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/DynamicCompleterFilter.java b/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/filter/DynamicCompleterFilter.java
similarity index 97%
rename from modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/DynamicCompleterFilter.java
rename to modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/filter/DynamicCompleterFilter.java
index 59f5459438..bc2fe7f204 100644
--- a/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/DynamicCompleterFilter.java
+++ b/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/filter/DynamicCompleterFilter.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.cli.core.repl.completer;
+package org.apache.ignite.internal.cli.core.repl.completer.filter;
import static org.apache.ignite.internal.cli.commands.Options.Constants.CLUSTER_URL_OPTION;
import static org.apache.ignite.internal.cli.commands.Options.Constants.HELP_OPTION;
diff --git a/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/ExclusionsCompleterFilter.java b/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/filter/ExclusionsCompleterFilter.java
similarity index 95%
copy from modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/ExclusionsCompleterFilter.java
copy to modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/filter/ExclusionsCompleterFilter.java
index 30d4d2c601..f2d0165678 100644
--- a/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/ExclusionsCompleterFilter.java
+++ b/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/filter/ExclusionsCompleterFilter.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.cli.core.repl.completer;
+package org.apache.ignite.internal.cli.core.repl.completer.filter;
import java.util.Arrays;
import java.util.Set;
diff --git a/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/filter/NonRepeatableOptionsFilter.java b/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/filter/NonRepeatableOptionsFilter.java
new file mode 100644
index 0000000000..a5011cbf97
--- /dev/null
+++ b/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/filter/NonRepeatableOptionsFilter.java
@@ -0,0 +1,79 @@
+/*
+ * 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 org.apache.ignite.internal.cli.core.repl.completer.filter;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import picocli.CommandLine.Model.CommandSpec;
+import picocli.CommandLine.Model.ITypeInfo;
+
+/** Filters out non-repeatable options from candidates. */
+public class NonRepeatableOptionsFilter implements CompleterFilter {
+
+ private final CommandSpec topCommandSpec;
+
+ public NonRepeatableOptionsFilter(CommandSpec spec) {
+ this.topCommandSpec = spec;
+ }
+
+ /** Filters candidates. */
+ @Override
+ public String[] filter(String[] words, String[] candidates) {
+ CommandSpec commandSpec = findCommandSpec(words);
+ Map<String, ITypeInfo> optionTypes = commandSpec.options().stream()
+ .flatMap(it -> Arrays.stream(it.names()).map(name -> new OptionInfo(name, it.typeInfo())))
+ .collect(Collectors.toMap(OptionInfo::getName, OptionInfo::getType));
+ Set<String> shouldBeExcludedFromCandidates = Arrays.stream(words)
+ .filter(optionTypes::containsKey)
+ .filter(it -> !optionTypes.get(it).isMultiValue())
+ .collect(Collectors.toSet());
+ return Arrays.stream(candidates)
+ .filter(it -> !shouldBeExcludedFromCandidates.contains(it))
+ .toArray(String[]::new);
+ }
+
+ private CommandSpec findCommandSpec(String[] words) {
+ int cursor = 0;
+ CommandSpec commandSpec = topCommandSpec;
+ while (commandSpec.subcommands().containsKey(words[cursor])) {
+ commandSpec = commandSpec.subcommands().get(words[cursor]).getCommandSpec();
+ cursor++;
+ }
+ return commandSpec;
+ }
+
+ private static class OptionInfo {
+ private final String name;
+ private final ITypeInfo type;
+
+ private OptionInfo(String name, ITypeInfo type) {
+ this.name = name;
+ this.type = type;
+ }
+
+ private String getName() {
+ return name;
+ }
+
+ private ITypeInfo getType() {
+ return type;
+ }
+ }
+}
diff --git a/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/ExclusionsCompleterFilter.java b/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/filter/ShortOptionsFilter.java
similarity index 61%
rename from modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/ExclusionsCompleterFilter.java
rename to modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/filter/ShortOptionsFilter.java
index 30d4d2c601..43eed57f8a 100644
--- a/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/ExclusionsCompleterFilter.java
+++ b/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/completer/filter/ShortOptionsFilter.java
@@ -15,25 +15,30 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.cli.core.repl.completer;
+package org.apache.ignite.internal.cli.core.repl.completer.filter;
import java.util.Arrays;
import java.util.Set;
+import java.util.stream.Collectors;
+import org.apache.ignite.internal.cli.commands.Options;
-/** Filters out exclusions from candidates. */
-public class ExclusionsCompleterFilter implements CompleterFilter {
+/** Filters out short option names from candidates. */
+public class ShortOptionsFilter implements CompleterFilter {
- private final Set<String> exclusions;
+ private final Set<String> shortOptionNames = shortOptionNames();
- public ExclusionsCompleterFilter(String... exclusions) {
- this.exclusions = Set.of(exclusions);
+ private static Set<String> shortOptionNames() {
+ return Arrays.stream(Options.values())
+ .filter(it -> !it.fullName().equals(it.shortName()))
+ .map(Options::shortName)
+ .collect(Collectors.toSet());
}
/** Filters candidates. */
@Override
public String[] filter(String[] ignored, String[] candidates) {
return Arrays.stream(candidates)
- .filter(it -> !exclusions.contains(it))
+ .filter(it -> !shortOptionNames.contains(it))
.toArray(String[]::new);
}
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/executor/IgnitePicocliCommands.java b/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/executor/IgnitePicocliCommands.java
index 75485b2c47..e7097097ec 100644
--- a/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/executor/IgnitePicocliCommands.java
+++ b/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/executor/IgnitePicocliCommands.java
@@ -23,9 +23,9 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import org.apache.ignite.internal.cli.core.repl.completer.CompleterFilter;
import org.apache.ignite.internal.cli.core.repl.completer.DynamicCompleter;
import org.apache.ignite.internal.cli.core.repl.completer.DynamicCompleterRegistry;
+import org.apache.ignite.internal.cli.core.repl.completer.filter.CompleterFilter;
import org.jline.builtins.Options.HelpException;
import org.jline.console.ArgDesc;
import org.jline.console.CmdDesc;
@@ -191,7 +191,7 @@ public class IgnitePicocliCommands implements CommandRegistry {
assert candidates != null;
// let picocli generate completion candidates for the token where the cursor is at
- final String[] words = commandLine.words().toArray(new String[0]);
+ String[] words = commandLine.words().toArray(new String[0]);
List<CharSequence> cs = new ArrayList<CharSequence>();
AutoComplete.complete(cmd.getCommandSpec(),
words,
@@ -199,11 +199,9 @@ public class IgnitePicocliCommands implements CommandRegistry {
0,
commandLine.cursor(),
cs);
-
- List<String> staticCandidates = new ArrayList<>();
- for (CharSequence c : cs) {
- staticCandidates.add(c.toString());
- }
+ String[] staticCandidates = cs.stream()
+ .map(CharSequence::toString)
+ .toArray(String[]::new);
List<DynamicCompleter> completers = completerRegistry.findCompleters(words);
if (!completers.isEmpty()) {
@@ -222,9 +220,9 @@ public class IgnitePicocliCommands implements CommandRegistry {
return;
}
- String[] filteredCandidates = completerFilters.get(0).filter(words, staticCandidates.toArray(String[]::new));
- for (int i = 1; i < completerFilters.size(); i++) {
- filteredCandidates = completerFilters.get(i).filter(words, filteredCandidates);
+ String[] filteredCandidates = staticCandidates;
+ for (CompleterFilter filter : completerFilters) {
+ filteredCandidates = filter.filter(words, filteredCandidates);
}
for (String c : filteredCandidates) {
diff --git a/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/executor/ReplExecutor.java b/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/executor/ReplExecutor.java
index e7226aef06..ce394c2abc 100644
--- a/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/executor/ReplExecutor.java
+++ b/modules/cli/src/main/java/org/apache/ignite/internal/cli/core/repl/executor/ReplExecutor.java
@@ -33,8 +33,11 @@ import org.apache.ignite.internal.cli.core.flow.question.JlineQuestionWriterRead
import org.apache.ignite.internal.cli.core.flow.question.QuestionAskerFactory;
import org.apache.ignite.internal.cli.core.repl.Repl;
import org.apache.ignite.internal.cli.core.repl.completer.DynamicCompleterActivationPoint;
-import org.apache.ignite.internal.cli.core.repl.completer.DynamicCompleterFilter;
import org.apache.ignite.internal.cli.core.repl.completer.DynamicCompleterRegistry;
+import org.apache.ignite.internal.cli.core.repl.completer.filter.CompleterFilter;
+import org.apache.ignite.internal.cli.core.repl.completer.filter.DynamicCompleterFilter;
+import org.apache.ignite.internal.cli.core.repl.completer.filter.NonRepeatableOptionsFilter;
+import org.apache.ignite.internal.cli.core.repl.completer.filter.ShortOptionsFilter;
import org.apache.ignite.internal.cli.core.repl.context.CommandLineContextProvider;
import org.apache.ignite.internal.cli.core.repl.expander.NoopExpander;
import org.jline.console.impl.SystemRegistryImpl;
@@ -175,7 +178,11 @@ public class ReplExecutor {
activationPoint.activateDynamicCompleter(completerRegistry);
DynamicCompleterFilter dynamicCompleterFilter = factory.create(DynamicCompleterFilter.class);
+ List<CompleterFilter> filters = List.of(dynamicCompleterFilter,
+ new ShortOptionsFilter(),
+ new NonRepeatableOptionsFilter(cmd.getCommandSpec())
+ );
- return new IgnitePicocliCommands(cmd, completerRegistry, List.of(dynamicCompleterFilter));
+ return new IgnitePicocliCommands(cmd, completerRegistry, filters);
}
}
diff --git a/modules/cli/src/test/java/org/apache/ignite/internal/cli/core/repl/completer/DynamicCompleterFilterTest.java b/modules/cli/src/test/java/org/apache/ignite/internal/cli/core/repl/completer/filter/DynamicCompleterFilterTest.java
similarity index 96%
rename from modules/cli/src/test/java/org/apache/ignite/internal/cli/core/repl/completer/DynamicCompleterFilterTest.java
rename to modules/cli/src/test/java/org/apache/ignite/internal/cli/core/repl/completer/filter/DynamicCompleterFilterTest.java
index 9d238c6d96..ee0c5df94a 100644
--- a/modules/cli/src/test/java/org/apache/ignite/internal/cli/core/repl/completer/DynamicCompleterFilterTest.java
+++ b/modules/cli/src/test/java/org/apache/ignite/internal/cli/core/repl/completer/filter/DynamicCompleterFilterTest.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.cli.core.repl.completer;
+package org.apache.ignite.internal.cli.core.repl.completer.filter;
import static java.util.Arrays.asList;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -23,6 +23,7 @@ import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.emptyArray;
import org.apache.ignite.internal.cli.core.repl.Session;
+import org.apache.ignite.internal.cli.core.repl.completer.filter.DynamicCompleterFilter;
import org.junit.jupiter.api.Test;
class DynamicCompleterFilterTest {
diff --git a/modules/cli/src/test/java/org/apache/ignite/internal/cli/core/repl/completer/ExclusionsCompleterFilterTest.java b/modules/cli/src/test/java/org/apache/ignite/internal/cli/core/repl/completer/filter/ExclusionsCompleterFilterTest.java
similarity index 90%
rename from modules/cli/src/test/java/org/apache/ignite/internal/cli/core/repl/completer/ExclusionsCompleterFilterTest.java
rename to modules/cli/src/test/java/org/apache/ignite/internal/cli/core/repl/completer/filter/ExclusionsCompleterFilterTest.java
index 225aea12b2..76093ecc70 100644
--- a/modules/cli/src/test/java/org/apache/ignite/internal/cli/core/repl/completer/ExclusionsCompleterFilterTest.java
+++ b/modules/cli/src/test/java/org/apache/ignite/internal/cli/core/repl/completer/filter/ExclusionsCompleterFilterTest.java
@@ -15,13 +15,14 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.cli.core.repl.completer;
+package org.apache.ignite.internal.cli.core.repl.completer.filter;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.hasSize;
import java.util.List;
+import org.apache.ignite.internal.cli.core.repl.completer.filter.ExclusionsCompleterFilter;
import org.junit.jupiter.api.Test;
class ExclusionsCompleterFilterTest {
diff --git a/modules/cli/src/test/java/org/apache/ignite/internal/cli/core/repl/completer/filter/NonRepeatableOptionsFilterTest.java b/modules/cli/src/test/java/org/apache/ignite/internal/cli/core/repl/completer/filter/NonRepeatableOptionsFilterTest.java
new file mode 100644
index 0000000000..89c0b311c9
--- /dev/null
+++ b/modules/cli/src/test/java/org/apache/ignite/internal/cli/core/repl/completer/filter/NonRepeatableOptionsFilterTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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 org.apache.ignite.internal.cli.core.repl.completer.filter;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.hamcrest.Matchers.hasSize;
+
+import io.micronaut.configuration.picocli.MicronautFactory;
+import io.micronaut.context.ApplicationContext;
+import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
+import jakarta.inject.Inject;
+import java.util.Arrays;
+import java.util.List;
+import org.apache.ignite.internal.cli.commands.TopLevelCliReplCommand;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import picocli.CommandLine;
+
+@MicronautTest
+class NonRepeatableOptionsFilterTest {
+
+ @Inject
+ private ApplicationContext ctx;
+
+ private CommandLine cmd;
+
+ @BeforeEach
+ void setUp() {
+ cmd = new CommandLine(TopLevelCliReplCommand.class, new MicronautFactory(ctx));
+ }
+
+ @Test
+ void filterNonRepeatableOptions() {
+ NonRepeatableOptionsFilter filter = new NonRepeatableOptionsFilter(cmd.getCommandSpec());
+ String[] words = {"cluster", "init", "--cluster-name", "name", "--cmg-node", "node"};
+ String[] candidates = {"--cluster-name", "--cmg-node", "--cluster-endpoint-url", "--meta-storage-node"};
+ List<String> filteredCandidates = Arrays.asList(filter.filter(words, candidates));
+ assertThat(filteredCandidates, hasSize(3));
+ assertThat(filteredCandidates, containsInAnyOrder("--cmg-node", "--cluster-endpoint-url", "--meta-storage-node"));
+ }
+}
diff --git a/modules/cli/src/test/java/org/apache/ignite/internal/cli/core/repl/completer/filter/ShortOptionsFilterTest.java b/modules/cli/src/test/java/org/apache/ignite/internal/cli/core/repl/completer/filter/ShortOptionsFilterTest.java
new file mode 100644
index 0000000000..49b9fa0230
--- /dev/null
+++ b/modules/cli/src/test/java/org/apache/ignite/internal/cli/core/repl/completer/filter/ShortOptionsFilterTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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 org.apache.ignite.internal.cli.core.repl.completer.filter;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.arrayWithSize;
+import static org.hamcrest.Matchers.containsInAnyOrder;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import org.apache.ignite.internal.cli.commands.Options;
+import org.junit.jupiter.api.Test;
+
+class ShortOptionsFilterTest {
+
+ @Test
+ void filterShortOptions() {
+ String[] allOptions = Arrays.stream(Options.values())
+ .flatMap(it -> Stream.of(it.fullName(), it.shortName()))
+ .distinct()
+ .toArray(String[]::new);
+ String[] candidates = new ShortOptionsFilter().filter(new String[0], allOptions);
+ List<String> longOptionNames = Arrays.stream(Options.values())
+ .map(Options::fullName)
+ .collect(Collectors.toList());
+ assertThat(candidates, arrayWithSize(longOptionNames.size()));
+ assertThat(Arrays.asList(candidates), containsInAnyOrder(longOptionNames.toArray(new String[0])));
+ }
+}