Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 2F06B200C76 for ; Sat, 29 Apr 2017 02:12:35 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 2DA3A160BA3; Sat, 29 Apr 2017 00:12:35 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id D4358160BC2 for ; Sat, 29 Apr 2017 02:12:32 +0200 (CEST) Received: (qmail 27322 invoked by uid 500); 29 Apr 2017 00:12:31 -0000 Mailing-List: contact commits-help@geode.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@geode.apache.org Delivered-To: mailing list commits@geode.apache.org Received: (qmail 27220 invoked by uid 99); 29 Apr 2017 00:12:31 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 29 Apr 2017 00:12:31 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 68575E1797; Sat, 29 Apr 2017 00:12:31 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: ladyvader@apache.org To: commits@geode.apache.org Date: Sat, 29 Apr 2017 00:12:34 -0000 Message-Id: In-Reply-To: <549ba9aaf42941a7a1ac4af57e9a6168@git.apache.org> References: <549ba9aaf42941a7a1ac4af57e9a6168@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [04/18] geode git commit: GEODE-1597: use Spring shell's parser and delete our own parsing code archived-at: Sat, 29 Apr 2017 00:12:35 -0000 http://git-wip-us.apache.org/repos/asf/geode/blob/63ffe764/geode-core/src/test/java/org/apache/geode/management/internal/cli/GfshParserIntegrationTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/GfshParserIntegrationTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/GfshParserIntegrationTest.java index f3e3bd8..a467b34 100644 --- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/GfshParserIntegrationTest.java +++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/GfshParserIntegrationTest.java @@ -14,39 +14,43 @@ */ package org.apache.geode.management.internal.cli; -import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; -import java.util.Arrays; -import java.util.Map; - -import org.junit.After; +import org.apache.geode.management.internal.cli.i18n.CliStrings; +import org.apache.geode.test.junit.categories.IntegrationTest; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; +import org.springframework.shell.core.Completion; import org.springframework.shell.event.ParseResult; -import org.apache.geode.test.junit.categories.IntegrationTest; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; @Category(IntegrationTest.class) public class GfshParserIntegrationTest { - - private CommandManager commandManager; - private GfshParser parser; + private static GfshParser parser; + private List candidates; + private String buffer; + private int cursor; + + @BeforeClass + public static void setUpClass() throws Exception { + parser = new GfshParser(); + } @Before public void setUp() throws Exception { - CommandManager.clearInstance(); - this.commandManager = CommandManager.getInstance(true); - this.parser = new GfshParser(commandManager); + this.candidates = new ArrayList<>(); } - @After - public void tearDown() { - CommandManager.clearInstance(); - } - - private Map params(String input, String commandName, String commandMethod) { + private Map parseParams(String input, String commandMethod) { ParseResult parseResult = parser.parse(input); + GfshParseResult gfshParseResult = (GfshParseResult) parseResult; Map params = gfshParseResult.getParamValueStrings(); for (String param : params.keySet()) { @@ -55,108 +59,425 @@ public class GfshParserIntegrationTest { assertThat(gfshParseResult.getMethod().getName()).isEqualTo(commandMethod); assertThat(gfshParseResult.getUserInput()).isEqualTo(input.trim()); - assertThat(gfshParseResult.getCommandName()).isEqualTo(commandName); return params; } @Test - public void optionStartsWithHyphenWithoutQuotes() throws Exception { + public void getSimpleParserInputTest() { + buffer = "start locator --J=\"-Dgemfire.http-service-port=8080\" --name=loc1"; + assertEquals("start locator --J \"-Dgemfire.http-service-port=8080\" --name loc1", + GfshParser.convertToSimpleParserInput(buffer)); + + buffer = "start locator --J=-Dgemfire.http-service-port=8080 --name=loc1 --J=-Ddummythinghere"; + assertEquals( + "start locator --J \"-Dgemfire.http-service-port=8080,-Ddummythinghere\" --name loc1", + GfshParser.convertToSimpleParserInput(buffer)); + + buffer = "start locator --"; + assertThat(GfshParser.convertToSimpleParserInput(buffer)).isEqualTo("start locator --"); + + buffer = + "start locator --J=-Dgemfire.http-service-port=8080 --name=loc1 --J=-Ddummythinghere --"; + assertEquals( + "start locator --J \"-Dgemfire.http-service-port=8080,-Ddummythinghere\" --name loc1 --", + GfshParser.convertToSimpleParserInput(buffer)); + + buffer = "start server --name=name1 --locators=localhost --J=-Dfoo=bar"; + assertEquals("start server --name name1 --locators localhost --J \"-Dfoo=bar\"", + GfshParser.convertToSimpleParserInput(buffer)); + } + + @Test + public void testParseOptionStartsWithHyphenWithoutQuotes() throws Exception { String input = "rebalance --exclude-region=/GemfireDataCommandsDUnitTestRegion2 --simulate=true --time-out=-1"; - Map params = params(input, "rebalance", "rebalance"); - + Map params = parseParams(input, "rebalance"); assertThat(params.get("exclude-region")).isEqualTo("/GemfireDataCommandsDUnitTestRegion2"); assertThat(params.get("simulate")).isEqualTo("true"); - assertThat(params.get("time-out")).isEqualTo("\"-1\""); + assertThat(params.get("time-out")).isEqualTo("-1"); } @Test - public void optionStartsWithHyphenWithQuotes() throws Exception { + public void testParseOptionStartsWithHyphenWithQuotes() throws Exception { String input = "rebalance --exclude-region=/GemfireDataCommandsDUnitTestRegion2 --simulate=true --time-out=\"-1\""; - Map params = params(input, "rebalance", "rebalance"); + Map params = parseParams(input, "rebalance"); assertThat(params.get("exclude-region")).isEqualTo("/GemfireDataCommandsDUnitTestRegion2"); assertThat(params.get("simulate")).isEqualTo("true"); - assertThat(params.get("time-out")).isEqualTo("\"-1\""); + assertThat(params.get("time-out")).isEqualTo("-1"); } @Test - public void optionContainingHyphen() throws Exception { + public void testParseOptionContainingHyphen() throws Exception { String input = "rebalance --exclude-region=/The-Region --simulate=true"; - Map params = params(input, "rebalance", "rebalance"); + Map params = parseParams(input, "rebalance"); assertThat(params.get("exclude-region")).isEqualTo("/The-Region"); assertThat(params.get("simulate")).isEqualTo("true"); } @Test - public void optionContainingUnderscore() throws Exception { + public void testParseOptionContainingUnderscore() throws Exception { String input = "rebalance --exclude-region=/The_region --simulate=true"; - Map params = params(input, "rebalance", "rebalance"); + Map params = parseParams(input, "rebalance"); assertThat(params.get("exclude-region")).isEqualTo("/The_region"); assertThat(params.get("simulate")).isEqualTo("true"); } @Test - public void oneJOptionWithQuotes() throws Exception { + public void testParseOneJOptionWithQuotes() throws Exception { String input = "start locator --J=\"-Dgemfire.http-service-port=8080\" --name=loc1"; - Map params = params(input, "start locator", "startLocator"); + Map params = parseParams(input, "startLocator"); assertThat(params.get("name")).isEqualTo("loc1"); - assertThat(params.get("J")).isEqualTo("\"-Dgemfire.http-service-port=8080\""); + assertThat(params.get("J")).isEqualTo("-Dgemfire.http-service-port=8080"); } @Test - public void oneJOptionWithSpaceInQuotes() throws Exception { + public void testParseOneJOptionWithSpaceInQuotes() throws Exception { String input = "start locator --J=\"-Dgemfire.http-service-port= 8080\" --name=loc1"; - Map params = params(input, "start locator", "startLocator"); + Map params = parseParams(input, "startLocator"); assertThat(params.get("name")).isEqualTo("loc1"); - assertThat(params.get("J")).isEqualTo("\"-Dgemfire.http-service-port= 8080\""); + assertThat(params.get("J")).isEqualTo("'-Dgemfire.http-service-port= 8080'"); } @Test - public void oneJOption() throws Exception { + public void testParseOneJOption() throws Exception { String input = "start locator --J=-Dgemfire.http-service-port=8080 --name=loc1"; - Map params = params(input, "start locator", "startLocator"); + Map params = parseParams(input, "startLocator"); assertThat(params.get("name")).isEqualTo("loc1"); - assertThat(params.get("J")).isEqualTo("\"-Dgemfire.http-service-port=8080\""); + assertThat(params.get("J")).isEqualTo("-Dgemfire.http-service-port=8080"); } @Test - public void twoJOptions() throws Exception { + public void testParseTwoJOptions() throws Exception { String input = "start locator --J=-Dgemfire.http-service-port=8080 --name=loc1 --J=-Ddummythinghere"; - Map params = params(input, "start locator", "startLocator"); + Map params = parseParams(input, "startLocator"); assertThat(params.get("name")).isEqualTo("loc1"); - assertThat(params.get("J")) - .isEqualTo("\"-Dgemfire.http-service-port=8080\",\"-Ddummythinghere\""); + assertThat(params.get("J")).isEqualTo("-Dgemfire.http-service-port=8080,-Ddummythinghere"); } @Test - public void twoJOptionsOneWithQuotesOneWithout() throws Exception { + public void testParseTwoJOptionsOneWithQuotesOneWithout() throws Exception { String input = "start locator --J=\"-Dgemfire.http-service-port=8080\" --name=loc1 --J=-Ddummythinghere"; - Map params = params(input, "start locator", "startLocator"); + Map params = parseParams(input, "startLocator"); assertThat(params.get("name")).isEqualTo("loc1"); - assertThat(params.get("J")) - .isEqualTo("\"-Dgemfire.http-service-port=8080\",\"-Ddummythinghere\""); + assertThat(params.get("J")).isEqualTo("-Dgemfire.http-service-port=8080,-Ddummythinghere"); } @Test - public void oneJOptionWithQuotesAndLotsOfSpaces() throws Exception { + public void testParseOneJOptionWithQuotesAndLotsOfSpaces() throws Exception { String input = "start locator --J=\"-Dgemfire.http-service-port=8080\" --name=loc1 "; - Map params = params(input, "start locator", "startLocator"); + Map params = parseParams(input, "startLocator"); assertThat(params.get("name")).isEqualTo("loc1"); - assertThat(params.get("J")).isEqualTo("\"-Dgemfire.http-service-port=8080\""); + assertThat(params.get("J")).isEqualTo("-Dgemfire.http-service-port=8080"); + } + + @Test + public void testCompletionDescibe() throws Exception { + buffer = "describe"; + cursor = parser.completeAdvanced(buffer, candidates); + assertThat(candidates.size()).isEqualTo(7); + assertThat(getCompleted(buffer, cursor, candidates.get(0))).isEqualTo("describe client"); + } + + @Test + public void testCompletionDescibeWithSpace() throws Exception { + buffer = "describe "; + cursor = parser.completeAdvanced(buffer, candidates); + assertThat(candidates.size()).isEqualTo(7); + assertThat(getCompleted(buffer, cursor, candidates.get(0))).isEqualTo("describe client"); + } + + @Test + public void testCompletionDeploy() throws Exception { + buffer = "deploy"; + cursor = parser.completeAdvanced(buffer, candidates); + assertThat(candidates.size()).isEqualTo(3); + assertThat(getCompleted(buffer, cursor, candidates.get(0))).isEqualTo(buffer + " --dir"); + } + + @Test + public void testCompletionDeployWithSpace() throws Exception { + buffer = "deploy "; + cursor = parser.completeAdvanced(buffer, candidates); + assertThat(candidates.size()).isEqualTo(3); + assertThat(getCompleted(buffer, cursor, candidates.get(0))).isEqualTo(buffer + "--dir"); + } + + @Test + public void testCompleteWithRequiredOption() throws Exception { + buffer = "describe config"; + cursor = parser.completeAdvanced(buffer, candidates); + assertThat(candidates.size()).isEqualTo(1); + assertThat(getCompleted(buffer, cursor, candidates.get(0))).isEqualTo(buffer + " --member"); + } + + @Test + public void testCompleteWithRequiredOptionWithSpace() throws Exception { + buffer = "describe config "; + cursor = parser.completeAdvanced(buffer, candidates); + assertThat(candidates.size()).isEqualTo(1); + assertThat(getCompleted(buffer, cursor, candidates.get(0))).isEqualTo(buffer + "--member"); + } + + @Test + public void testCompleteCommand() throws Exception { + buffer = "start ser"; + cursor = parser.completeAdvanced(buffer, candidates); + assertThat(candidates.size()).isEqualTo(1); + assertThat("start server").isEqualTo(getCompleted(buffer, cursor, candidates.get(0))); + } + + @Test + public void testCompleteOptionWithOnlyOneCandidate() throws Exception { + buffer = "start server --nam"; + cursor = parser.completeAdvanced(buffer, candidates); + assertThat(candidates.size()).isEqualTo(1); + assertThat(getCompleted(buffer, cursor, candidates.get(0))).isEqualTo(buffer + "e"); + } + + @Test + public void testCompleteOptionWithMultipleCandidates() throws Exception { + buffer = "start server --name=jinmei --loc"; + cursor = parser.completeAdvanced(buffer, candidates); + assertThat(candidates.size()).isEqualTo(3); + assertThat(getCompleted(buffer, cursor, candidates.get(0))) + .isEqualTo(buffer + "ator-wait-time"); + assertThat(getCompleted(buffer, cursor, candidates.get(1))).isEqualTo(buffer + "ators"); + assertThat(getCompleted(buffer, cursor, candidates.get(2))).isEqualTo(buffer + "k-memory"); + } + + @Test + public void testCompleteWithExtraSpace() throws Exception { + buffer = "start server --name=name1 --se"; + cursor = parser.completeAdvanced(buffer, candidates); + assertThat(cursor).isEqualTo("start server --name=name1 ".length()); + assertThat(candidates.size()).isEqualTo(3); + assertTrue(candidates.contains(new Completion("--server-port"))); + assertThat(getCompleted(buffer, cursor, candidates.get(0))) + .isEqualTo(buffer + "curity-properties-file"); + } + + @Test + public void testCompleteWithDashInTheEnd() throws Exception { + buffer = "start server --name=name1 --"; + cursor = parser.completeAdvanced(buffer, candidates); + assertThat(cursor).isEqualTo(buffer.length() - 2); + assertThat(candidates.size()).isEqualTo(50); + assertTrue(candidates.contains(new Completion("--properties-file"))); + assertThat(getCompleted(buffer, cursor, candidates.get(0))).isEqualTo(buffer + "J"); + } + + @Test + public void testCompleteWithSpace() throws Exception { + buffer = "start server --name=name1 "; + cursor = parser.completeAdvanced(buffer, candidates); + assertThat(cursor).isEqualTo(buffer.length() - 1); + assertThat(candidates.size()).isEqualTo(50); + assertTrue(candidates.contains(new Completion(" --properties-file"))); + assertThat(getCompleted(buffer, cursor, candidates.get(0))).isEqualTo(buffer + "--J"); + } + + @Test + public void testCompleteWithOutSpace() throws Exception { + buffer = "start server --name=name1"; + cursor = parser.completeAdvanced(buffer, candidates); + assertThat(cursor).isEqualTo(buffer.length()); + assertThat(candidates.size()).isEqualTo(50); + assertTrue(candidates.contains(new Completion(" --properties-file"))); + assertThat(getCompleted(buffer, cursor, candidates.get(0))).isEqualTo(buffer + " --J"); + } + + @Test + public void testCompleteJ() throws Exception { + buffer = "start server --name=name1 --J="; + cursor = parser.completeAdvanced(buffer, candidates); + assertThat(cursor).isEqualTo(buffer.length()); + assertThat(candidates.size()).isEqualTo(0); + } + + @Test + public void testCompleteWithValue() throws Exception { + buffer = "start server --name=name1 --J"; + cursor = parser.completeAdvanced(buffer, candidates); + assertThat(cursor).isEqualTo(buffer.length()); + assertThat(candidates.size()).isEqualTo(0); + } + + @Test + public void testCompleteWithDash() throws Exception { + buffer = "start server --name=name1 --J=-Dfoo.bar --"; + cursor = parser.completeAdvanced(buffer, candidates); + assertThat(candidates.size()).isEqualTo(49); + } + + @Test + public void testCompleteWithMultipleJ() throws Exception { + buffer = "start server --name=name1 --J=-Dme=her --J=-Dfoo=bar --l"; + cursor = parser.completeAdvanced(buffer, candidates); + assertThat(cursor).isEqualTo("start server --name=name1 --J=-Dme=her --J=-Dfoo=bar ".length()); + assertThat(candidates.size()).isEqualTo(4); + assertTrue(candidates.contains(new Completion("--locators"))); + } + + @Test + public void testMultiJComplete() throws Exception { + buffer = "start server --name=name1 --J=-Dtest=test1 --J=-Dfoo=bar"; + cursor = parser.completeAdvanced(buffer, candidates); + assertThat(cursor).isEqualTo(buffer.length()); + assertThat(candidates.size()).isEqualTo(49); + assertThat(getCompleted(buffer, cursor, candidates.get(0))) + .isEqualTo(buffer + " --assign-buckets"); + } + + @Test + public void testMultiJCompleteWithDifferentOrder() throws Exception { + buffer = "start server --J=-Dtest=test1 --J=-Dfoo=bar --name=name1"; + cursor = parser.completeAdvanced(buffer, candidates); + assertThat(cursor).isEqualTo(buffer.length()); + assertThat(candidates.size()).isEqualTo(49); + assertThat(getCompleted(buffer, cursor, candidates.get(0))) + .isEqualTo(buffer + " --assign-buckets"); + } + + @Test + public void testJComplete3() throws Exception { + buffer = "start server --name=name1 --locators=localhost --J=-Dfoo=bar"; + cursor = parser.completeAdvanced(buffer, candidates); + assertThat(cursor).isEqualTo(buffer.length()); + assertThat(candidates.size()).isEqualTo(48); + assertThat(getCompleted(buffer, cursor, candidates.get(0))) + .isEqualTo(buffer + " --assign-buckets"); + } + + @Test + public void testJComplete4() throws Exception { + buffer = "start server --name=name1 --locators=localhost --J=-Dfoo=bar --"; + cursor = parser.completeAdvanced(buffer, candidates); + assertThat(cursor).isEqualTo(buffer.length() - 2); + assertThat(candidates.size()).isEqualTo(48); + assertThat(getCompleted(buffer, cursor, candidates.get(0))) + .isEqualTo(buffer + "assign-buckets"); + } + + @Test + public void testCompletRegionType() throws Exception { + buffer = "create region --name=test --type"; + cursor = parser.completeAdvanced(buffer, candidates); + assertThat(candidates.size()).isEqualTo(23); + assertThat(getCompleted(buffer, cursor, candidates.get(0))).isEqualTo(buffer + "=LOCAL"); + } + + @Test + public void testCompletPartialRegionType() throws Exception { + buffer = "create region --name=test --type=LO"; + cursor = parser.completeAdvanced(buffer, candidates); + assertThat(candidates.size()).isEqualTo(5); + assertThat(getCompleted(buffer, cursor, candidates.get(0))).isEqualTo(buffer + "CAL"); + } + + @Test + public void testCompletHelp() throws Exception { + buffer = "create region --name=test --type LO"; + cursor = parser.completeSuperAdvanced(buffer, candidates); + System.out.println(""); + } + + @Test + public void testCompletLogLevel() throws Exception { + buffer = "change loglevel --loglevel"; + cursor = parser.completeAdvanced(buffer, candidates); + assertThat(candidates.size()).isEqualTo(8); + assertThat(getCompleted(buffer, cursor, candidates.get(0))).isEqualTo(buffer + "=ALL"); + } + + @Test + public void testObtainHelp() { + String command = CliStrings.START_PULSE; + String helpString = "NAME\n" + "start pulse\n" + "IS AVAILABLE\n" + "true\n" + "SYNOPSIS\n" + + "Open a new window in the default Web browser with the URL for the Pulse application.\n" + + "SYNTAX\n" + "start pulse [--url=value]\n" + "PARAMETERS\n" + "url\n" + + "URL of the Pulse Web application.\n" + "Required: false\n" + + "Default (if the parameter is not specified): http://localhost:7070/pulse\n"; + assertThat(parser.getCommandManager().obtainHelp(command)).isEqualTo(helpString); + } + + + @Test + public void testStringArrayConverter() { + String command = "create disk-store --name=foo --dir=bar"; + GfshParseResult result = parser.parse(command); + assertThat(result).isNotNull(); + assertThat(result.getParamValue("dir")).isEqualTo("bar"); + } + + @Test + public void testDirConverter() { + String command = "compact offline-disk-store --name=foo --disk-dirs=bar"; + GfshParseResult result = parser.parse(command); + assertThat(result).isNotNull(); + assertThat(result.getParamValue("disk-dirs")).isEqualTo("bar"); + } + + @Test + public void testMultiDirInvalid() throws Exception { + String command = "create disk-store --name=testCreateDiskStore1 --group=Group1 " + + "--allow-force-compaction=true --auto-compact=false --compaction-threshold=67 " + + "--max-oplog-size=355 --queue-size=5321 --time-interval=2023 --write-buffer-size=3110 " + + "--dir=/testCreateDiskStore1.1#1452637463 " + "--dir=/testCreateDiskStore1.2"; + GfshParseResult result = parser.parse(command); + assertThat(result).isNull(); + } + + @Test + public void testMultiDirValid() throws Exception { + String command = "create disk-store --name=testCreateDiskStore1 --group=Group1 " + + "--allow-force-compaction=true --auto-compact=false --compaction-threshold=67 " + + "--max-oplog-size=355 --queue-size=5321 --time-interval=2023 --write-buffer-size=3110 " + + "--dir=/testCreateDiskStore1.1#1452637463,/testCreateDiskStore1.2"; + GfshParseResult result = parser.parse(command); + assertThat(result).isNotNull(); + assertThat(result.getParamValue("dir")) + .isEqualTo("/testCreateDiskStore1.1#1452637463,/testCreateDiskStore1.2"); + } + + @Test + public void testEmptyKey() throws Exception { + String command = "remove --key=\"\" --region=/GemfireDataCommandsTestRegion"; + GfshParseResult result = parser.parse(command); + assertThat(result).isNotNull(); + assertThat(result.getParamValue("key")).isEqualTo(""); + } + + @Test + public void testJsonKey() throws Exception { + String command = "get --key=('id':'testKey0') --region=regionA"; + GfshParseResult result = parser.parse(command); + assertThat(result).isNotNull(); + } + + @Test + public void testUnspecifiedValueToStringArray() { + String command = "change loglevel --loglevel=finer --groups=group1,group2"; + ParseResult result = parser.parse(command); + String[] memberIdValue = (String[]) result.getArguments()[0]; + assertThat(memberIdValue).isNull(); + } + + private String getCompleted(String buffer, int cursor, Completion completed) { + return buffer.substring(0, cursor) + completed.getValue(); } } http://git-wip-us.apache.org/repos/asf/geode/blob/63ffe764/geode-core/src/test/java/org/apache/geode/management/internal/cli/GfshParserJUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/GfshParserJUnitTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/GfshParserJUnitTest.java index 44e99f4..2fd8c2f 100644 --- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/GfshParserJUnitTest.java +++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/GfshParserJUnitTest.java @@ -14,41 +14,16 @@ */ package org.apache.geode.management.internal.cli; -import static org.junit.Assert.*; +import static org.assertj.core.api.Assertions.assertThat; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; - -import org.junit.After; +import org.apache.geode.test.junit.categories.UnitTest; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.springframework.shell.core.CommandMarker; -import org.springframework.shell.core.Completion; -import org.springframework.shell.core.Converter; -import org.springframework.shell.core.MethodTarget; -import org.springframework.shell.core.Parser; -import org.springframework.shell.core.annotation.CliAvailabilityIndicator; -import org.springframework.shell.core.annotation.CliCommand; -import org.springframework.shell.core.annotation.CliOption; -import org.springframework.shell.event.ParseResult; -import org.apache.geode.management.cli.CliMetaData; -import org.apache.geode.management.cli.CommandProcessingException; -import org.apache.geode.management.cli.ConverterHint; -import org.apache.geode.management.cli.Result; -import org.apache.geode.management.internal.cli.annotation.CliArgument; -import org.apache.geode.management.internal.cli.converters.StringArrayConverter; -import org.apache.geode.management.internal.cli.converters.StringListConverter; -import org.apache.geode.management.internal.cli.i18n.CliStrings; -import org.apache.geode.management.internal.cli.parser.SyntaxConstants; -import org.apache.geode.management.internal.cli.result.ResultBuilder; -import org.apache.geode.management.internal.security.ResourceOperation; -import org.apache.geode.security.ResourcePermission.Operation; -import org.apache.geode.security.ResourcePermission.Resource; -import org.apache.geode.test.junit.categories.UnitTest; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; /** * GfshParserJUnitTest - Includes tests to check the parsing and auto-completion capabilities of @@ -57,807 +32,103 @@ import org.apache.geode.test.junit.categories.UnitTest; @Category(UnitTest.class) public class GfshParserJUnitTest { - private static final String COMMAND1_NAME = "command1"; - private static final String COMMAND1_NAME_ALIAS = "command1_alias"; - private static final String COMMAND2_NAME = "c2"; - - private static final String COMMAND1_HELP = "help for " + COMMAND1_NAME; - - // ARGUMENTS - private static final String ARGUMENT1_NAME = "argument1"; - private static final String ARGUMENT1_HELP = "help for argument1"; - private static final String ARGUMENT1_CONTEXT = "context for argument 1"; - private static final Completion[] ARGUMENT1_COMPLETIONS = - {new Completion("arg1"), new Completion("arg1alt")}; - private static final String ARGUMENT2_NAME = "argument2"; - private static final String ARGUMENT2_CONTEXT = "context for argument 2"; - private static final String ARGUMENT2_HELP = "help for argument2"; - private static final String ARGUMENT2_UNSPECIFIED_DEFAULT_VALUE = - "{unspecified default value for argument2}"; - private static final Completion[] ARGUMENT2_COMPLETIONS = - {new Completion("arg2"), new Completion("arg2alt")}; - - // OPTIONS - private static final String OPTION1_NAME = "option1"; - private static final String OPTION1_SYNONYM = "opt1"; - private static final String OPTION1_HELP = "help for option1"; - private static final String OPTION1_CONTEXT = "context for option1"; - private static final Completion[] OPTION1_COMPLETIONS = - {new Completion("option1"), new Completion("option1Alternate")}; - private static final String OPTION2_NAME = "option2"; - private static final String OPTION2_HELP = "help for option2"; - private static final String OPTION2_CONTEXT = "context for option2"; - private static final String OPTION2_SPECIFIED_DEFAULT_VALUE = - "{specified default value for option2}"; - private static final Completion[] OPTION2_COMPLETIONS = - {new Completion("option2"), new Completion("option2Alternate")}; - private static final String OPTION3_NAME = "option3"; - private static final String OPTION3_SYNONYM = "opt3"; - private static final String OPTION3_HELP = "help for option3"; - private static final String OPTION3_CONTEXT = "context for option3"; - private static final String OPTION3_UNSPECIFIED_DEFAULT_VALUE = - "{unspecified default value for option3}"; - private static final Completion[] OPTION3_COMPLETIONS = - {new Completion("option3"), new Completion("option3Alternate")}; - - private Method methodCommand1; - private Method methodTestParamConcat; - private Method methodTestMultiWordArg; - - private CommandManager commandManager; - private GfshParser parser; + private String input; + private List tokens; @Before - public void setUp() throws Exception { - methodCommand1 = Commands.class.getMethod("command1", String.class, String.class, String.class, - String.class, String.class); - methodTestParamConcat = Commands.class.getMethod("testParamConcat", String.class, - String[].class, List.class, Integer.class, String[].class); - methodTestMultiWordArg = - Commands.class.getMethod("testMultiWordArg", String.class, String.class); - - // Make sure no prior tests leave the CommandManager in a funky state - CommandManager.clearInstance(); - - commandManager = CommandManager.getInstance(false); - commandManager.add(Commands.class.newInstance()); - commandManager.add(SimpleConverter.class.newInstance()); - commandManager.add(StringArrayConverter.class.newInstance()); - commandManager.add(StringListConverter.class.newInstance()); - - // Set up the parser - parser = new GfshParser(commandManager); - - CliUtil.isGfshVM = false; + public void before() { + tokens = new ArrayList<>(); } - @After - public void tearDown() { - CommandManager.clearInstance(); - } - - /** - * Tests the auto-completion capability of {@link GfshParser} with the method - * {@link GfshParser#complete(String, int, List)} - */ @Test - public void testComplete() throws Exception { - // Get the names of the command - String[] command1Names = ((CliCommand) methodCommand1.getAnnotation(CliCommand.class)).value(); - - // Input contains an entirely different string - String input = "moc"; - List completionCandidates = new ArrayList(); - List completionValues = new ArrayList(); - parser.complete(input, input.length(), completionCandidates); - assertSimpleCompletionValues(completionValues, completionCandidates); - - // Input contains a string which is prefix - // of more than 1 command - input = "c"; - clearAndSimpleComplete(completionCandidates, completionValues, input, parser); - // completions will come alphabetically sorted - completionValues.add(COMMAND2_NAME); - completionValues.add(COMMAND1_NAME); - assertSimpleCompletionValues(completionValues, completionCandidates); - - // Input contains only prefix of the command - // name which is not a prefix of other command. - // It may be the prefix for the synonym of command - input = command1Names[0].substring(0, 3); - clearAndSimpleComplete(completionCandidates, completionValues, input, parser); - completionValues.add(COMMAND1_NAME); - assertSimpleCompletionValues(completionValues, completionCandidates); - - // Input contains only the command name - input = command1Names[0]; - clearAndSimpleComplete(completionCandidates, completionValues, input, parser); - // Here we expect the completions for argument1 - // For arguments, the formatted value will equal the actual arguments - // But the actual value will contain the ARGUMENT_SEPARATOR - for (Completion completion : ARGUMENT1_COMPLETIONS) { - completionValues.add(" " + completion.getValue()); - } - assertSimpleCompletionValues(completionValues, completionCandidates); - - // Input contains command name and prefix of first - // argument - input = command1Names[0] + " " + ARGUMENT1_COMPLETIONS[0].getValue().substring(0, 3); - clearAndSimpleComplete(completionCandidates, completionValues, input, parser); - // Here we expect the completions for argument2 - // which have the provided first argument as the prefix - for (Completion completion : ARGUMENT1_COMPLETIONS) { - if (completion.getValue().startsWith(ARGUMENT1_COMPLETIONS[0].getValue().substring(0, 3))) { - completionValues.add(" " + completion.getValue()); - } - } - assertSimpleCompletionValues(completionValues, completionCandidates); - - // Input contains command name, first argument, second argument - // and first option - input = command1Names[0] + " " + ARGUMENT1_COMPLETIONS[0].getValue() - + SyntaxConstants.ARGUMENT_SEPARATOR + ARGUMENT2_COMPLETIONS[0].getValue() - + SyntaxConstants.ARGUMENT_SEPARATOR + SyntaxConstants.LONG_OPTION_SPECIFIER + OPTION1_NAME; - clearAndSimpleComplete(completionCandidates, completionValues, input, parser); - // Here we expect the values for the first option - for (Completion completion : OPTION1_COMPLETIONS) { - completionValues.add(SyntaxConstants.OPTION_VALUE_SPECIFIER + completion.getValue()); - } - assertSimpleCompletionValues(completionValues, completionCandidates); - - // Input contains command name, first argument, second argument, - // first option and prefix of one of the values provided - // by the auto-completor. - input = command1Names[1] + " " + ARGUMENT1_COMPLETIONS[0].getValue() - + SyntaxConstants.ARGUMENT_SEPARATOR + ARGUMENT2_COMPLETIONS[0].getValue() - + SyntaxConstants.ARGUMENT_SEPARATOR + " " + SyntaxConstants.LONG_OPTION_SPECIFIER - + OPTION1_NAME + SyntaxConstants.OPTION_VALUE_SPECIFIER - + OPTION1_COMPLETIONS[0].getValue().substring(0, 2); - clearAndSimpleComplete(completionCandidates, completionValues, input, parser); - // Here we expect the values for the first option - for (Completion completion : OPTION1_COMPLETIONS) { - if (completion.getValue().startsWith(OPTION1_COMPLETIONS[0].getValue().substring(0, 2))) { - completionValues.add(SyntaxConstants.OPTION_VALUE_SPECIFIER + completion.getValue()); - } - } - assertSimpleCompletionValues(completionValues, completionCandidates); - - // Input contains command name, first argument, second argument, - // first option and one of the values provided - // by the auto-completor. - input = command1Names[0] + " " + ARGUMENT1_COMPLETIONS[0].getValue() - + SyntaxConstants.ARGUMENT_SEPARATOR + ARGUMENT2_COMPLETIONS[0].getValue() - + SyntaxConstants.ARGUMENT_SEPARATOR + " " + SyntaxConstants.LONG_OPTION_SPECIFIER - + OPTION1_NAME + SyntaxConstants.OPTION_VALUE_SPECIFIER + OPTION1_COMPLETIONS[0].getValue(); - clearAndSimpleComplete(completionCandidates, completionValues, input, parser); - // Here we expect the remaining options - // As only first option is mandatory, we expect the - // the other non-mandatory options. - completionValues.add(" " + SyntaxConstants.LONG_OPTION_SPECIFIER + OPTION2_NAME); - completionValues.add(" " + SyntaxConstants.LONG_OPTION_SPECIFIER + OPTION3_NAME); - assertSimpleCompletionValues(completionValues, completionCandidates); - - // Input contains command name, first argument, second argument, - // first option, one value for the option and value separator at - // the end - input = command1Names[0] + " " + ARGUMENT1_COMPLETIONS[0].getValue() - + SyntaxConstants.ARGUMENT_SEPARATOR + ARGUMENT2_COMPLETIONS[0].getValue() - + SyntaxConstants.ARGUMENT_SEPARATOR + " " + SyntaxConstants.LONG_OPTION_SPECIFIER - + OPTION1_NAME + SyntaxConstants.OPTION_VALUE_SPECIFIER + OPTION1_COMPLETIONS[0].getValue() - + SyntaxConstants.VALUE_SEPARATOR; - clearAndSimpleComplete(completionCandidates, completionValues, input, parser); - // Here we expect the other values for completion - completionValues.add(SyntaxConstants.VALUE_SEPARATOR + OPTION1_COMPLETIONS[1].getValue()); - assertSimpleCompletionValues(completionValues, completionCandidates); - - // Input contains command name, first argument, second argument, - // first option and both the values for the option - input = command1Names[0] + " " + ARGUMENT1_COMPLETIONS[0].getValue() - + SyntaxConstants.ARGUMENT_SEPARATOR + ARGUMENT2_COMPLETIONS[0].getValue() - + SyntaxConstants.ARGUMENT_SEPARATOR + " " + SyntaxConstants.LONG_OPTION_SPECIFIER - + OPTION1_NAME + SyntaxConstants.OPTION_VALUE_SPECIFIER + OPTION1_COMPLETIONS[0].getValue() - + SyntaxConstants.VALUE_SEPARATOR + OPTION1_COMPLETIONS[1].getValue(); - clearAndSimpleComplete(completionCandidates, completionValues, input, parser); - // Here we expect the remaining options - // As only first option is mandatory, we expect the - // the other non-mandatory options. - completionValues.add(" " + SyntaxConstants.LONG_OPTION_SPECIFIER + OPTION2_NAME); - completionValues.add(" " + SyntaxConstants.LONG_OPTION_SPECIFIER + OPTION3_NAME); - assertSimpleCompletionValues(completionValues, completionCandidates); - - // Input contains command name, first argument, second argument, - // first option, both the values for the option and valueSeparator - // at the end - input = command1Names[0] + " " + ARGUMENT1_COMPLETIONS[0].getValue() - + SyntaxConstants.ARGUMENT_SEPARATOR + ARGUMENT2_COMPLETIONS[0].getValue() - + SyntaxConstants.ARGUMENT_SEPARATOR + " " + SyntaxConstants.LONG_OPTION_SPECIFIER - + OPTION1_NAME + SyntaxConstants.OPTION_VALUE_SPECIFIER + OPTION1_COMPLETIONS[0].getValue() - + SyntaxConstants.VALUE_SEPARATOR + OPTION1_COMPLETIONS[1].getValue() - + SyntaxConstants.VALUE_SEPARATOR; - clearAndSimpleComplete(completionCandidates, completionValues, input, parser); - // Here we expect nothing for completion - assertSimpleCompletionValues(completionValues, completionCandidates); - } - - private void clearAndSimpleComplete(List completionCandidates, - List completionValues, String input, Parser parser) { - completionCandidates.clear(); - completionValues.clear(); - parser.complete(input, input.length(), completionCandidates); + public void testSplitUserInputDoubleQuotes() { + input = "query --query=\"select * from /region\""; + tokens = GfshParser.splitUserInput(input); + assertThat(tokens.size()).isEqualTo(3); + assertThat(tokens.get(0)).isEqualTo("query"); + assertThat(tokens.get(1)).isEqualTo("--query"); + assertThat(tokens.get(2)).isEqualTo("\"select * from /region\""); } - private void assertSimpleCompletionValues(List expected, List actual) { - assertEquals("Check size", expected.size(), actual.size()); - assertEquals(expected, actual); - } - - /** - * Tests the auto-completion capability of {@link GfshParser} with the method - * {@link GfshParser#completeAdvanced(String, int, List)} - */ @Test - public void testCompleteAdvanced() throws Exception { - // Get the names of the command - String[] command1Names = ((CliCommand) methodCommand1.getAnnotation(CliCommand.class)).value(); - - // Input contains an entirely different string - String input = "moc"; - List completionCandidates = new ArrayList(); - List completionValues = new ArrayList(); - parser.completeAdvanced(input, input.length(), completionCandidates); - assertAdvancedCompletionValues(completionValues, completionCandidates); - - // Input contains a string which is prefix - // of more than 1 command - input = "c"; - clearAndAdvancedComplete(completionCandidates, completionValues, input, parser); - // completions will come alphabetically sorted - completionValues.add(new Completion(COMMAND2_NAME)); - completionValues.add(new Completion(COMMAND1_NAME)); - assertAdvancedCompletionValues(completionValues, completionCandidates); - - // Input contains only prefix of the command - // name which is not a prefix of other command. - // It may be the prefix for the synonym of command - input = command1Names[0].substring(0, 3); - clearAndAdvancedComplete(completionCandidates, completionValues, input, parser); - completionValues.add(new Completion(COMMAND1_NAME)); - assertAdvancedCompletionValues(completionValues, completionCandidates); - - // Input contains only the command name - input = command1Names[0]; - clearAndAdvancedComplete(completionCandidates, completionValues, input, parser); - // Here we expect the completions for argument1 - // For arguments, the formatted value will equal the actual arguments - // But the actual value will contain the ARGUMENT_SEPARATOR - for (Completion completion : ARGUMENT1_COMPLETIONS) { - completionValues.add( - new Completion(" " + completion.getValue(), completion.getFormattedValue(), null, 0)); - } - assertAdvancedCompletionValues(completionValues, completionCandidates); - - // Input contains command name and prefix of first - // argument - input = command1Names[0] + " " + ARGUMENT1_COMPLETIONS[0].getValue().substring(0, 3); - clearAndAdvancedComplete(completionCandidates, completionValues, input, parser); - // Here we expect the completions for argument2 - // which have the provided first argument as the prefix - for (Completion completion : ARGUMENT1_COMPLETIONS) { - if (completion.getValue().startsWith(ARGUMENT1_COMPLETIONS[0].getValue().substring(0, 3))) { - completionValues.add( - new Completion(" " + completion.getValue(), completion.getFormattedValue(), null, 0)); - } - } - assertAdvancedCompletionValues(completionValues, completionCandidates); - - // Input contains command name, first argument, second argument - // and first option - input = command1Names[0] + " " + ARGUMENT1_COMPLETIONS[0].getValue() - + SyntaxConstants.ARGUMENT_SEPARATOR + ARGUMENT2_COMPLETIONS[0].getValue() - + SyntaxConstants.ARGUMENT_SEPARATOR + SyntaxConstants.LONG_OPTION_SPECIFIER + OPTION1_NAME; - clearAndAdvancedComplete(completionCandidates, completionValues, input, parser); - // Here we expect the values for the first option - for (Completion completion : OPTION1_COMPLETIONS) { - completionValues - .add(new Completion(SyntaxConstants.OPTION_VALUE_SPECIFIER + completion.getValue(), - completion.getValue(), null, 0)); - } - assertAdvancedCompletionValues(completionValues, completionCandidates); - - // Input contains command name, first argument, second argument, - // first option and prefix of one of the values provided - // by the auto-completor. - input = command1Names[1] + " " + ARGUMENT1_COMPLETIONS[0].getValue() - + SyntaxConstants.ARGUMENT_SEPARATOR + ARGUMENT2_COMPLETIONS[0].getValue() - + SyntaxConstants.ARGUMENT_SEPARATOR + " " + SyntaxConstants.LONG_OPTION_SPECIFIER - + OPTION1_NAME + SyntaxConstants.OPTION_VALUE_SPECIFIER - + OPTION1_COMPLETIONS[0].getValue().substring(0, 2); - clearAndAdvancedComplete(completionCandidates, completionValues, input, parser); - // Here we expect the values for the first option - for (Completion completion : OPTION1_COMPLETIONS) { - if (completion.getValue().startsWith(OPTION1_COMPLETIONS[0].getValue().substring(0, 2))) { - completionValues - .add(new Completion(SyntaxConstants.OPTION_VALUE_SPECIFIER + completion.getValue(), - completion.getValue(), null, 0)); - } - } - assertAdvancedCompletionValues(completionValues, completionCandidates); - - // Input contains command name, first argument, second argument, - // first option and one of the values provided - // by the auto-completor. - input = command1Names[0] + " " + ARGUMENT1_COMPLETIONS[0].getValue() - + SyntaxConstants.ARGUMENT_SEPARATOR + ARGUMENT2_COMPLETIONS[0].getValue() - + SyntaxConstants.ARGUMENT_SEPARATOR + " " + SyntaxConstants.LONG_OPTION_SPECIFIER - + OPTION1_NAME + SyntaxConstants.OPTION_VALUE_SPECIFIER + OPTION1_COMPLETIONS[0].getValue(); - clearAndAdvancedComplete(completionCandidates, completionValues, input, parser); - // Here we expect the remaining options - // As only first option is mandatory, we expect the - // the other non-mandatory options. - completionValues.add(new Completion(" " + SyntaxConstants.LONG_OPTION_SPECIFIER + OPTION2_NAME, - OPTION2_NAME, null, 0)); - completionValues.add(new Completion(" " + SyntaxConstants.LONG_OPTION_SPECIFIER + OPTION3_NAME, - OPTION3_NAME, null, 0)); - assertAdvancedCompletionValues(completionValues, completionCandidates); - - // Input contains command name, first argument, second argument, - // first option, one value for the option and value separator at - // the end - input = command1Names[0] + " " + ARGUMENT1_COMPLETIONS[0].getValue() - + SyntaxConstants.ARGUMENT_SEPARATOR + ARGUMENT2_COMPLETIONS[0].getValue() - + SyntaxConstants.ARGUMENT_SEPARATOR + " " + SyntaxConstants.LONG_OPTION_SPECIFIER - + OPTION1_NAME + SyntaxConstants.OPTION_VALUE_SPECIFIER + OPTION1_COMPLETIONS[0].getValue() - + SyntaxConstants.VALUE_SEPARATOR; - clearAndAdvancedComplete(completionCandidates, completionValues, input, parser); - // Here we expect the other values for completion - completionValues - .add(new Completion(SyntaxConstants.VALUE_SEPARATOR + OPTION1_COMPLETIONS[1].getValue(), - OPTION1_COMPLETIONS[1].getValue(), null, 0)); - assertAdvancedCompletionValues(completionValues, completionCandidates); - - // Input contains command name, first argument, second argument, - // first option and both the values for the option - input = command1Names[0] + " " + ARGUMENT1_COMPLETIONS[0].getValue() - + SyntaxConstants.ARGUMENT_SEPARATOR + ARGUMENT2_COMPLETIONS[0].getValue() - + SyntaxConstants.ARGUMENT_SEPARATOR + " " + SyntaxConstants.LONG_OPTION_SPECIFIER - + OPTION1_NAME + SyntaxConstants.OPTION_VALUE_SPECIFIER + OPTION1_COMPLETIONS[0].getValue() - + SyntaxConstants.VALUE_SEPARATOR + OPTION1_COMPLETIONS[1].getValue(); - clearAndAdvancedComplete(completionCandidates, completionValues, input, parser); - // Here we expect the remaining options - // As only first option is mandatory, we expect the - // the other non-mandatory options. - completionValues.add(new Completion(" " + SyntaxConstants.LONG_OPTION_SPECIFIER + OPTION2_NAME, - OPTION2_NAME, null, 0)); - completionValues.add(new Completion(" " + SyntaxConstants.LONG_OPTION_SPECIFIER + OPTION3_NAME, - OPTION3_NAME, null, 0)); - assertAdvancedCompletionValues(completionValues, completionCandidates); - - // Input contains command name, first argument, second argument, - // first option, both the values for the option and valueSeparator - // at the end - input = command1Names[0] + " " + ARGUMENT1_COMPLETIONS[0].getValue() - + SyntaxConstants.ARGUMENT_SEPARATOR + ARGUMENT2_COMPLETIONS[0].getValue() - + SyntaxConstants.ARGUMENT_SEPARATOR + " " + SyntaxConstants.LONG_OPTION_SPECIFIER - + OPTION1_NAME + SyntaxConstants.OPTION_VALUE_SPECIFIER + OPTION1_COMPLETIONS[0].getValue() - + SyntaxConstants.VALUE_SEPARATOR + OPTION1_COMPLETIONS[1].getValue() - + SyntaxConstants.VALUE_SEPARATOR; - clearAndAdvancedComplete(completionCandidates, completionValues, input, parser); - // Here we expect nothing for completion - assertAdvancedCompletionValues(completionValues, completionCandidates); - } - - private void clearAndAdvancedComplete(List completionCandidates, - List completionValues, String input, Parser parser) { - completionCandidates.clear(); - completionValues.clear(); - parser.completeAdvanced(input, input.length(), completionCandidates); + public void testSplitUserInputSingleQuotes() { + input = "query --query='select * from /region'"; + tokens = GfshParser.splitUserInput(input); + assertThat(tokens.size()).isEqualTo(3); + assertThat(tokens.get(0)).isEqualTo("query"); + assertThat(tokens.get(1)).isEqualTo("--query"); + assertThat(tokens.get(2)).isEqualTo("'select * from /region'"); } - private void assertAdvancedCompletionValues(List expected, List actual) { - assertEquals("Check size", expected.size(), actual.size()); - for (int i = 0; i < expected.size(); i++) { - assertEquals("Check completion value no." + i + ". Expected(" + expected.get(i) - + ") & Actual(" + actual.get(i) + ").", expected.get(i).getValue(), - actual.get(i).getValue()); - if (expected.get(i).getFormattedValue() != null) { - assertEquals( - "Check completion formatted value no." + i + ". Expected(" - + expected.get(i).getFormattedValue() + ") & Actual(" - + actual.get(i).getFormattedValue() + ").", - expected.get(i).getFormattedValue(), actual.get(i).getFormattedValue()); - } - } + @Test + public void testSplitUserInputWithJ() { + input = + "start server --name=server1 --J=\"-Dgemfire.start-dev-rest-api=true\" --J='-Dgemfire.http-service-port=8080' --J='-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=30000'"; + tokens = GfshParser.splitUserInput(input); + assertThat(tokens.size()).isEqualTo(10); + assertThat(tokens.get(5)).isEqualTo("\"-Dgemfire.start-dev-rest-api=true\""); + assertThat(tokens.get(7)).isEqualTo("'-Dgemfire.http-service-port=8080'"); + assertThat(tokens.get(9)) + .isEqualTo("'-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=30000'"); } - /** - * Test for checking parsing of {@link GfshParser} with method {@link GfshParser#parse(String)} - *

- * Does not include testing for multiple values as this change is still pending in spring-shell - */ @Test - public void testParse() throws Exception { - // Get the names of the command - String[] command1Names = ((CliCommand) methodCommand1.getAnnotation(CliCommand.class)).value(); - - // Input contains an entirely different string - String input = "moc"; - ParseResult parse = null; - CommandProcessingException expectedException = null; - try { - parse = parser.parse(input); - } catch (CommandProcessingException expected) { - expectedException = expected; - } finally { - assertNotNull("Expecting a " + CommandProcessingException.class - + " for an invalid command name: " + input, expectedException); - assertEquals( - "CommandProcessingException type doesn't match. " + "Actual(" - + expectedException.getErrorType() + ") & Expected(" - + CommandProcessingException.COMMAND_INVALID_OR_UNAVAILABLE + ") ", - expectedException.getErrorType(), - CommandProcessingException.COMMAND_INVALID_OR_UNAVAILABLE); - } - - // Input contains a string which is prefix - // of more than 1 command - input = "c"; - expectedException = null; - try { - parse = parser.parse(input); - } catch (CommandProcessingException e) { - expectedException = e; - } finally { - assertNotNull("Expecting a " + CommandProcessingException.class - + " for an invalid/incomplete command name: " + input, expectedException); - assertEquals( - "CommandProcessingException type doesn't match. Actual(" - + expectedException.getErrorType() + ") & Expected(" - + CommandProcessingException.COMMAND_INVALID_OR_UNAVAILABLE + ") ", - expectedException.getErrorType(), - CommandProcessingException.COMMAND_INVALID_OR_UNAVAILABLE); - } - - // Input contains only prefix of the command - // name which is not a prefix of other command. - // It may be the prefix for the synonym of command - input = "com"; - expectedException = null; - try { - parse = parser.parse(input); - } catch (CommandProcessingException expected) { - expectedException = expected; - } finally { - // FIXME - Nikhil/Abhishek prefix shouldn't work - assertNotNull("Expecting a " + CommandProcessingException.class - + " for an invalid/incomplete command name: " + input, expectedException); - assertEquals( - "CommandProcessingException type doesn't match. Actual(" - + expectedException.getErrorType() + ") & Expected(" - + CommandProcessingException.COMMAND_INVALID_OR_UNAVAILABLE + ") ", - expectedException.getErrorType(), - CommandProcessingException.COMMAND_INVALID_OR_UNAVAILABLE); - } - - // Input contains only command name - input = command1Names[0]; - expectedException = null; - try { - parse = parser.parse(input); - } catch (CommandProcessingException expected) { - expectedException = expected; - } finally { - assertNotNull("Expecting a " + CommandProcessingException.class - + " for an invalid/incomplete command name: " + input, expectedException); - assertEquals( - "CommandProcessingException type doesn't match. Actual(" - + expectedException.getErrorType() + ") & Expected(" - + CommandProcessingException.REQUIRED_ARGUMENT_MISSING + ") ", - CommandProcessingException.REQUIRED_ARGUMENT_MISSING, expectedException.getErrorType()); - } - - // Input contains first argument and first option with value - input = command1Names[0] + " ARGUMENT1_VALUE " + SyntaxConstants.LONG_OPTION_SPECIFIER - + OPTION1_NAME + SyntaxConstants.OPTION_VALUE_SPECIFIER + "somevalue"; - parse = parser.parse(input); - assertNotNull(parse); - assertEquals("Check ParseResult method", parse.getMethod(), methodCommand1); - assertEquals("Check no. of method arguments", 5, parse.getArguments().length); - assertEquals("Check argument1", "ARGUMENT1_VALUE", parse.getArguments()[0]); - assertEquals("Check argument2", ARGUMENT2_UNSPECIFIED_DEFAULT_VALUE, parse.getArguments()[1]); - assertEquals("Check option1 value", "somevalue", parse.getArguments()[2]); - assertEquals("Check option2 value", null, parse.getArguments()[3]); - assertEquals("Check option3 value", OPTION3_UNSPECIFIED_DEFAULT_VALUE, parse.getArguments()[4]); - - // Input contains only both arguments but is terminated by long option - // specifiers. These hyphens at the end are ignored by the parser - input = command1Names[1] + " ARGUMENT1_VALUE? ARGUMENT2_VALUE -- ----------"; - try { - parse = parser.parse(input); - } catch (CommandProcessingException expected) { - expectedException = expected; - } finally { - assertNotNull("Expecting a " + CommandProcessingException.class - + " for an invalid/incomplete command name: " + input, expectedException); - // assertEquals("CommandProcessingException type doesn't match. Actual(" - // + expectedException.getErrorType() + ") & Expected(" - // + CommandProcessingException.REQUIRED_OPTION_MISSING + ") ", - // expectedException.getErrorType(), - // CommandProcessingException.REQUIRED_OPTION_MISSING); - } - - // Input contains both arguments. The first option is specified with value - // The second is specified without value and the third option is not - // specified - input = command1Names[1] + " ARGUMENT1_VALUE? ARGUMENT2_VALUE " - + SyntaxConstants.LONG_OPTION_SPECIFIER + OPTION1_NAME - + SyntaxConstants.OPTION_VALUE_SPECIFIER + "option1value" + " " - + SyntaxConstants.LONG_OPTION_SPECIFIER + OPTION2_NAME; - parse = parser.parse(input); - assertNotNull(parse); - assertEquals("Check ParseResult method", parse.getMethod(), methodCommand1); - assertEquals("Check no. of method arguments", 5, parse.getArguments().length); - assertEquals("Check argument1", "ARGUMENT1_VALUE", parse.getArguments()[0]); - assertEquals("Check argument2", "ARGUMENT2_VALUE", parse.getArguments()[1]); - assertEquals("Check option1 value", "option1value", parse.getArguments()[2]); - assertEquals("Check option2 value", OPTION2_SPECIFIED_DEFAULT_VALUE, parse.getArguments()[3]); - assertEquals("Check option3 value", OPTION3_UNSPECIFIED_DEFAULT_VALUE, parse.getArguments()[4]); - - // Input contains both arguments. All the three options - // are specified with values - input = command1Names[1] + " ARGUMENT1_VALUE? ARGUMENT2_VALUE " - + SyntaxConstants.LONG_OPTION_SPECIFIER + OPTION1_SYNONYM - + SyntaxConstants.OPTION_VALUE_SPECIFIER + "option1value" + " " - + SyntaxConstants.LONG_OPTION_SPECIFIER + OPTION2_NAME - + SyntaxConstants.OPTION_VALUE_SPECIFIER + "option2value" + " " - + SyntaxConstants.LONG_OPTION_SPECIFIER + OPTION3_NAME - + SyntaxConstants.OPTION_VALUE_SPECIFIER + "option3value"; - parse = parser.parse(input); - assertNotNull(parse); - assertEquals("Check ParseResult method", parse.getMethod(), methodCommand1); - assertEquals("Check no. of method arguments", 5, parse.getArguments().length); - assertEquals("Check argument1", "ARGUMENT1_VALUE", parse.getArguments()[0]); - assertEquals("Check argument2", "ARGUMENT2_VALUE", parse.getArguments()[1]); - assertEquals("Check option1 value", "option1value", parse.getArguments()[2]); - assertEquals("Check option2 value", "option2value", parse.getArguments()[3]); - assertEquals("Check option3 value", "option3value", parse.getArguments()[4]); - - // Test concatenation of options when they appear more than once in the command - String command = - "testParamConcat --string=string1 --stringArray=1,2 --stringArray=3,4 --stringList=11,12,13 --integer=10 --stringArray=5 --stringList=14,15"; - ParseResult parseResult = parser.parse(command); - assertNotNull(parseResult); - assertEquals("Check ParseResult method", parseResult.getMethod(), methodTestParamConcat); - assertEquals("Check no. of method arguments", 5, parseResult.getArguments().length); - Object[] arguments = parseResult.getArguments(); - assertEquals(arguments[0], "string1"); - assertEquals(((String[]) arguments[1])[0], "1"); - assertEquals(((String[]) arguments[1])[1], "2"); - assertEquals(((String[]) arguments[1])[2], "3"); - assertEquals(((String[]) arguments[1])[3], "4"); - assertEquals(((String[]) arguments[1])[4], "5"); - assertEquals(((List) arguments[2]).get(0), "11"); - assertEquals(((List) arguments[2]).get(1), "12"); - assertEquals(((List) arguments[2]).get(2), "13"); - assertEquals(((List) arguments[2]).get(3), "14"); - assertEquals(((List) arguments[2]).get(4), "15"); - assertEquals(arguments[3], 10); - - // Test concatenation of options when they appear more than once in the command - command = "testParamConcat --stringArray=1,2 --stringArray=\'3,4\'"; - parseResult = parser.parse(command); - assertNotNull(parseResult); - assertEquals("Check ParseResult method", parseResult.getMethod(), methodTestParamConcat); - assertEquals("Check no. of method arguments", 5, parseResult.getArguments().length); - arguments = parseResult.getArguments(); - assertEquals(((String[]) arguments[1])[0], "1"); - assertEquals(((String[]) arguments[1])[1], "2"); - assertEquals(((String[]) arguments[1])[2], "3,4"); - - command = - "testParamConcat --string=\"1\" --colonArray=2:3:4 --stringArray=5,\"6,7\",8 --stringList=\"9,10,11,12\""; - parseResult = parser.parse(command); - assertNotNull(parseResult); - assertEquals("Check ParseResult method", parseResult.getMethod(), methodTestParamConcat); - assertEquals("Check no. of method arguments", 5, parseResult.getArguments().length); - arguments = parseResult.getArguments(); - assertEquals(arguments[0], "1"); - assertEquals(((String[]) arguments[1])[0], "5"); - assertEquals(((String[]) arguments[1])[1], "6,7"); - assertEquals(((String[]) arguments[1])[2], "8"); - assertEquals(((List) arguments[2]).get(0), "9,10,11,12"); - assertEquals(((String[]) arguments[4])[0], "2"); - assertEquals(((String[]) arguments[4])[1], "3"); - assertEquals(((String[]) arguments[4])[2], "4"); - - // try { - // command = "testParamConcat --string=string1 --stringArray=1,2 --string=string2"; - // parseResult = parser.parse(command); - // fail("Should have received a CommandProcessingException due to 'string' being specified - // twice"); - // } catch (CommandProcessingException expected) { - // // Expected - // } - - command = "testMultiWordArg this is just one argument?this is a second argument"; - parseResult = parser.parse(command); - assertNotNull(parseResult); - assertEquals("Check ParseResult method", parseResult.getMethod(), methodTestMultiWordArg); - assertEquals("Check no. of method arguments", 2, parseResult.getArguments().length); - arguments = parseResult.getArguments(); - assertEquals(arguments[0], "this is just one argument"); - assertEquals(arguments[1], "this is a second argument"); + public void testSplitUserInputWithJNoQuotes() { + input = + "start server --name=server1 --J=-Dgemfire.start-dev-rest-api=true --J=-Dgemfire.http-service-port=8080"; + tokens = GfshParser.splitUserInput(input); + assertThat(tokens.size()).isEqualTo(8); + assertThat(tokens.get(5)).isEqualTo("-Dgemfire.start-dev-rest-api=true"); + assertThat(tokens.get(7)).isEqualTo("-Dgemfire.http-service-port=8080"); } @Test - public void testDefaultAvailabilityMessage() throws Exception { - checkAvailabilityMessage(new AvailabilityCommands(), AvailabilityCommands.C2_NAME, - AvailabilityCommands.C2_MSG_UNAVAILABLE, AvailabilityCommands.C2_PROP); + public void testSplitJsonValue() throws Exception { + input = "get --key=('id':'testKey0') --region=regionA"; + tokens = GfshParser.splitUserInput(input); + assertThat(tokens.size()).isEqualTo(5); + assertThat(tokens.get(2)).isEqualTo("('id':'testKey0')"); } - @Ignore("This test was not previously enabled and it fails. Is it valid?") @Test - public void testCustomAvailabilityMessage() throws Exception { - checkAvailabilityMessage(new AvailabilityCommands(), AvailabilityCommands.C1_NAME, - AvailabilityCommands.C1_MSG_UNAVAILABLE, AvailabilityCommands.C1_PROP); + public void testGetSimpleParserInput() throws Exception { + String[] strings = {"command", "--option1", "value1", "--option2", "'test value'"}; + Arrays.stream(strings).forEach(tokens::add); + assertThat(GfshParser.getSimpleParserInputFromTokens(tokens)) + .isEqualTo("command --option1 value1 --option2 'test value'"); } - public void checkAvailabilityMessage(CommandMarker availabilityCommands, String commandString, - String unavailableMessage, String availabiltyBooleanProp) throws Exception { - CommandManager cmdManager = CommandManager.getInstance(false); - cmdManager.add(availabilityCommands); - - GfshParser parser = new GfshParser(cmdManager); - ParseResult parseResult = null; - - // Case 1: Command is not available - try { - parseResult = parser.parse(commandString); - } catch (CommandProcessingException e) { - String actualMessage = e.getMessage(); - String expectedMessage = - CliStrings.format(CliStrings.GFSHPARSER__MSG__0_IS_NOT_AVAILABLE_REASON_1, - new Object[] {commandString, unavailableMessage}); - assertEquals("1. Unavailability message [" + actualMessage + "] is not as expected[" - + expectedMessage + "].", actualMessage, expectedMessage); - } - - // Case 2: Command is 'made' available - try { - System.setProperty(availabiltyBooleanProp, "true"); - parseResult = parser.parse(commandString); - assertNotNull("ParseResult should not be null for available command.", parseResult); - } finally { - System.clearProperty(availabiltyBooleanProp); - } - - // Case 3: Command is not available again - try { - parseResult = parser.parse(commandString); - } catch (CommandProcessingException e) { - String actualMessage = e.getMessage(); - String expectedMessage = - CliStrings.format(CliStrings.GFSHPARSER__MSG__0_IS_NOT_AVAILABLE_REASON_1, - new Object[] {commandString, unavailableMessage}); - assertEquals("2. Unavailabilty message [" + actualMessage + "] is not as expected[" - + expectedMessage + "].", actualMessage, expectedMessage); - } + @Test + public void testGetSimpleParserInputWithJ() throws Exception { + String[] strings = + {"command", "--J", "-Dkey=value", "--option", "'test value'", "--J", "-Dkey2=value2"}; + Arrays.stream(strings).forEach(tokens::add); + assertThat(GfshParser.getSimpleParserInputFromTokens(tokens)) + .isEqualTo("command --J \"-Dkey=value,-Dkey2=value2\" --option 'test value'"); } - static class Commands implements CommandMarker { - - @CliCommand(value = {COMMAND1_NAME, COMMAND1_NAME_ALIAS}, help = COMMAND1_HELP) - @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ) - public static String command1( - @CliArgument(name = ARGUMENT1_NAME, argumentContext = ARGUMENT1_CONTEXT, - help = ARGUMENT1_HELP, mandatory = true) String argument1, - @CliArgument(name = ARGUMENT2_NAME, argumentContext = ARGUMENT2_CONTEXT, - help = ARGUMENT2_HELP, mandatory = false, - unspecifiedDefaultValue = ARGUMENT2_UNSPECIFIED_DEFAULT_VALUE, - systemProvided = false) String argument2, - @CliOption(key = {OPTION1_NAME, OPTION1_SYNONYM}, help = OPTION1_HELP, mandatory = true, - optionContext = OPTION1_CONTEXT) String option1, - @CliOption(key = {OPTION2_NAME}, help = OPTION2_HELP, mandatory = false, - optionContext = OPTION2_CONTEXT, - specifiedDefaultValue = OPTION2_SPECIFIED_DEFAULT_VALUE) String option2, - @CliOption(key = {OPTION3_NAME, OPTION3_SYNONYM}, help = OPTION3_HELP, mandatory = false, - optionContext = OPTION3_CONTEXT, - unspecifiedDefaultValue = OPTION3_UNSPECIFIED_DEFAULT_VALUE) String option3) { - return null; - } - - @CliCommand(value = {COMMAND2_NAME}) - @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ) - public static String command2() { - return null; - } - - @CliCommand(value = {"testParamConcat"}) - @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ) - public static Result testParamConcat(@CliOption(key = {"string"}) String string, - @CliOption(key = {"stringArray"}) @CliMetaData(valueSeparator = ",") String[] stringArray, - @CliOption(key = {"stringList"}, optionContext = ConverterHint.STRING_LIST) @CliMetaData( - valueSeparator = ",") List stringList, - @CliOption(key = {"integer"}) Integer integer, - @CliOption(key = {"colonArray"}) @CliMetaData(valueSeparator = ":") String[] colonArray) { - return null; - } - - @CliCommand(value = {"testMultiWordArg"}) - @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ) - public static Result testMultiWordArg(@CliArgument(name = "arg1") String arg1, - @CliArgument(name = "arg2") String arg2) { - return null; - } + @Test + public void testGetSimpleParserInputWithJWithSingleQuotes() throws Exception { + String[] strings = {"command", "--J", "'-Dkey=value value'"}; + Arrays.stream(strings).forEach(tokens::add); + assertThat(GfshParser.getSimpleParserInputFromTokens(tokens)) + .isEqualTo("command --J \"-Dkey=value value\""); } - static class SimpleConverter implements Converter { - - @Override - public boolean supports(Class type, String optionContext) { - if (type.isAssignableFrom(String.class)) { - return true; - } - return false; - } - - @Override - public String convertFromText(String value, Class targetType, String optionContext) { - return value; - } - - @Override - public boolean getAllPossibleValues(List completions, Class targetType, - String existingData, String context, MethodTarget target) { - if (context.equals(ARGUMENT1_CONTEXT)) { - for (Completion completion : ARGUMENT1_COMPLETIONS) { - completions.add(completion); - } - } else if (context.equals(ARGUMENT2_CONTEXT)) { - for (Completion completion : ARGUMENT2_COMPLETIONS) { - completions.add(completion); - } - } else if (context.equals(OPTION1_CONTEXT)) { - for (Completion completion : OPTION1_COMPLETIONS) { - completions.add(completion); - } - } - return true; - } + @Test + public void testGetSimpleParserInputWithJWithDoubleQuotes() throws Exception { + String[] strings = {"command", "--J", "\"-Dkey=value value\""}; + Arrays.stream(strings).forEach(tokens::add); + assertThat(GfshParser.getSimpleParserInputFromTokens(tokens)) + .isEqualTo("command --J \"-Dkey=value value\""); } - public static class AvailabilityCommands implements CommandMarker { - - static final String C1_NAME = "C1"; - static final String C1_PROP = C1_NAME + "-available"; - static final String C1_MSG_UNAVAILABLE = "Requires " + C1_PROP + "=true"; - static final String C1_MSG_AVAILABLE = C1_NAME + " is available."; - - static final String C2_NAME = "C2"; - static final String C2_PROP = C2_NAME + "-available"; - static final String C2_MSG_UNAVAILABLE = - CliStrings.AVAILABILITYTARGET_MSG_DEFAULT_UNAVAILABILITY_DESCRIPTION; - static final String C2_MSG_AVAILABLE = C2_NAME + " is available."; - - @CliCommand(value = {C1_NAME}) - @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ) - public Result command1() { - return ResultBuilder.createInfoResult(C1_MSG_AVAILABLE); - } - - @CliCommand(value = {C2_NAME}) - @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ) - public Result command2() { - return ResultBuilder.createInfoResult(C2_MSG_AVAILABLE); - } - - @CliAvailabilityIndicator(C1_NAME) - public boolean isCommand1Available() { - return Boolean.getBoolean(C1_PROP); - } - - @CliAvailabilityIndicator(C2_NAME) - public boolean isCommand2Available() { - return Boolean.getBoolean(C2_PROP); - } + @Test + public void testGetSimpleParserInputWithJAtTheEnd() throws Exception { + String[] strings = + {"command", "--option", "'test value'", "--J", "-Dkey=value", "--J", "-Dkey2=value2"}; + Arrays.stream(strings).forEach(tokens::add); + assertThat(GfshParser.getSimpleParserInputFromTokens(tokens)) + .isEqualTo("command --option 'test value' --J \"-Dkey=value,-Dkey2=value2\""); } }