Skip to content
This repository was archived by the owner on Jul 6, 2023. It is now read-only.

Commit bc796f7

Browse files
authored
Merge pull request #116 from praveenag/lambda-returns
Assigning cypher expressions to parameters
2 parents 95750ec + 16202b5 commit bc796f7

File tree

4 files changed

+87
-22
lines changed

4 files changed

+87
-22
lines changed

cypher-shell/src/main/java/org/neo4j/shell/commands/Param.java

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import javax.annotation.Nonnull;
88
import java.util.Collections;
99
import java.util.List;
10+
import java.util.function.BiPredicate;
1011
import java.util.regex.Matcher;
1112
import java.util.regex.Pattern;
1213

@@ -17,7 +18,10 @@
1718
public class Param implements Command {
1819
// Match arguments such as "(key) (value with possible spaces)" where key and value are any strings
1920
private static final Pattern backtickPattern = Pattern.compile("^\\s*(?<key>(`([^`])*`)+?):?\\s+(?<value>.+)$");
21+
private static final Pattern backtickLambdaPattern = Pattern.compile("^\\s*(?<key>(`([^`])*`)+?)\\s*=>\\s*(?<value>.+)$");
2022
private static final Pattern argPattern = Pattern.compile("^\\s*(?<key>[\\p{L}_][\\p{L}0-9_]*):?\\s+(?<value>.+)$");
23+
private static final Pattern lambdaPattern = Pattern.compile("^\\s*(?<key>[\\p{L}_][\\p{L}0-9_]*)\\s*=>\\s*(?<value>.+)$");
24+
private static final Pattern lambdaMapPattern = Pattern.compile("^\\s*(?<key>[\\p{L}_][\\p{L}0-9_]*):\\s*=>\\s*(?<value>.+)$");
2125

2226
public static final String COMMAND_NAME = ":param";
2327
private final VariableHolder variableHolder;
@@ -41,7 +45,7 @@ public String getDescription() {
4145
@Nonnull
4246
@Override
4347
public String getUsage() {
44-
return "name value";
48+
return "name => value";
4549
}
4650

4751
@Nonnull
@@ -58,21 +62,44 @@ public List<String> getAliases() {
5862

5963
@Override
6064
public void execute(@Nonnull final String argString) throws CommandException {
61-
Matcher alphanumericMatcher = argPattern.matcher(argString);
62-
if (alphanumericMatcher.matches()) {
63-
variableHolder.set(alphanumericMatcher.group("key"), alphanumericMatcher.group("value"));
64-
} else {
65-
checkForBackticks(argString);
65+
Matcher lambdaMapMatcher = lambdaMapPattern.matcher(argString);
66+
if (lambdaMapMatcher.matches()) {
67+
throw new CommandException(AnsiFormattedText.from("Incorrect usage.\nusage: ")
68+
.bold().append(COMMAND_NAME).boldOff().append(" ").append(getUsage()));
6669
}
70+
if (!assignIfValidParameter(argString)) {
71+
throw new CommandException(AnsiFormattedText.from("Incorrect number of arguments.\nusage: ")
72+
.bold().append(COMMAND_NAME).boldOff().append(" ").append(getUsage()));
73+
}
74+
}
75+
76+
private boolean assignIfValidParameter(@Nonnull String argString) throws CommandException {
77+
return setParameterIfItMatchesPattern(argString, lambdaPattern, assignIfValidParameter())
78+
|| setParameterIfItMatchesPattern(argString, argPattern, assignIfValidParameter())
79+
|| setParameterIfItMatchesPattern(argString, backtickLambdaPattern, backTickMatchPattern())
80+
|| setParameterIfItMatchesPattern(argString, backtickPattern, backTickMatchPattern());
6781
}
6882

69-
private void checkForBackticks(@Nonnull String argString) throws CommandException {
70-
Matcher matcher = backtickPattern.matcher(argString);
71-
if (argString.trim().startsWith("`") && matcher.matches() && matcher.group("key").length() > 2) {
83+
private boolean setParameterIfItMatchesPattern(@Nonnull String argString, Pattern pattern,
84+
BiPredicate<String, Matcher> matchingFunction) throws CommandException {
85+
Matcher matcher = pattern.matcher(argString);
86+
if (matchingFunction.test(argString, matcher)) {
7287
variableHolder.set(matcher.group("key"), matcher.group("value"));
88+
return true;
7389
} else {
74-
throw new CommandException(AnsiFormattedText.from("Incorrect number of arguments.\nusage: ")
75-
.bold().append(COMMAND_NAME).boldOff().append(" ").append(getUsage()));
90+
return false;
7691
}
7792
}
93+
94+
private BiPredicate<String, Matcher> assignIfValidParameter() {
95+
return (argString, matcher) -> matcher.matches();
96+
}
97+
98+
private BiPredicate<String, Matcher> backTickMatchPattern() {
99+
return (argString, backtickLambdaMatcher) -> {
100+
return argString.trim().startsWith("`")
101+
&& backtickLambdaMatcher.matches()
102+
&& backtickLambdaMatcher.group("key").length() > 2;
103+
};
104+
}
78105
}

cypher-shell/src/main/java/org/neo4j/shell/commands/Params.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ private void listParam(@Nonnull String name) throws CommandException {
8585
}
8686

8787
private void listParam(int leftColWidth, @Nonnull String key, @Nonnull Object value) {
88-
logger.printOut(String.format("%-" + leftColWidth + "s: %s", key, value));
88+
logger.printOut(String.format("%-" + leftColWidth + "s => %s", key, value));
8989
}
9090

9191
private void listAllParams() {

cypher-shell/src/test/java/org/neo4j/shell/commands/ParamTest.java

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import org.neo4j.shell.VariableHolder;
99
import org.neo4j.shell.exception.CommandException;
1010

11+
import static junit.framework.TestCase.assertEquals;
1112
import static junit.framework.TestCase.fail;
1213
import static org.hamcrest.CoreMatchers.containsString;
1314
import static org.mockito.Mockito.mock;
@@ -44,12 +45,26 @@ public void shouldFailIfOneArg() throws CommandException {
4445
}
4546

4647
@Test
47-
public void setValue() throws CommandException {
48+
public void setParam() throws CommandException {
4849
cmd.execute("bob 9");
4950

5051
verify(mockShell).set("bob", "9");
5152
}
5253

54+
@Test
55+
public void setLambdasAsParam() throws CommandException {
56+
cmd.execute("bob => 9");
57+
58+
verify(mockShell).set("bob", "9");
59+
}
60+
61+
@Test
62+
public void setLambdasAsParamWithBackticks() throws CommandException {
63+
cmd.execute("`bob` => 9");
64+
65+
verify(mockShell).set("`bob`", "9");
66+
}
67+
5368
@Test
5469
public void setSpecialCharacterParameter() throws CommandException {
5570
cmd.execute("bØb 9");
@@ -58,14 +73,21 @@ public void setSpecialCharacterParameter() throws CommandException {
5873
}
5974

6075
@Test
61-
public void setValueWithSpecialCharacters() throws CommandException {
76+
public void setSpecialCharacterParameterForLambdaExpressions() throws CommandException {
77+
cmd.execute("`first=>Name` => \"Bruce\"");
78+
79+
verify(mockShell).set("`first=>Name`", "\"Bruce\"");
80+
}
81+
82+
@Test
83+
public void setParamWithSpecialCharacters() throws CommandException {
6284
cmd.execute("`bob#` 9");
6385

6486
verify(mockShell).set("`bob#`", "9");
6587
}
6688

6789
@Test
68-
public void setValueWithOddNoOfBackTicks() throws CommandException {
90+
public void setParamWithOddNoOfBackTicks() throws CommandException {
6991
cmd.execute(" `bo `` sömething ``` 9");
7092

7193
verify(mockShell).set("`bo `` sömething ```", "9");
@@ -81,6 +103,16 @@ public void shouldFailForVariablesWithoutEscaping() throws CommandException {
81103
fail("Expected error");
82104
}
83105

106+
@Test
107+
public void shouldFailForVariablesMixingMapStyleAssignmentAndLambdas() throws CommandException {
108+
thrown.expect(CommandException.class);
109+
thrown.expectMessage(containsString("Incorrect usage"));
110+
111+
cmd.execute("bob: => 9");
112+
113+
fail("Expected error");
114+
}
115+
84116
@Test
85117
public void shouldFailForEmptyVariables() throws CommandException {
86118
thrown.expect(CommandException.class);
@@ -143,4 +175,10 @@ public void shouldNotExecuteEscapedCypher() throws CommandException {
143175
cmd.execute("bob \"RETURN 5 as bob\"");
144176
verify(mockShell).set("bob", "\"RETURN 5 as bob\"");
145177
}
178+
179+
@Test
180+
public void printUsage() throws CommandException {
181+
String usage = cmd.getUsage();
182+
assertEquals(usage, "name => value");
183+
}
146184
}

cypher-shell/src/test/java/org/neo4j/shell/commands/ParamsTest.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public void runCommand() throws CommandException {
5656
// when
5757
cmd.execute("");
5858
// then
59-
verify(logger).printOut("var: 9");
59+
verify(logger).printOut("var => 9");
6060
verifyNoMoreInteractions(logger);
6161
}
6262

@@ -68,8 +68,8 @@ public void runCommandAlignment() throws CommandException {
6868
// when
6969
cmd.execute("");
7070
// then
71-
verify(logger).printOut("param: 99999");
72-
verify(logger).printOut("var : 9");
71+
verify(logger).printOut("param => 99999");
72+
verify(logger).printOut("var => 9");
7373
verifyNoMoreInteractions(logger);
7474
}
7575

@@ -81,7 +81,7 @@ public void runCommandWithArg() throws CommandException {
8181
// when
8282
cmd.execute("var");
8383
// then
84-
verify(logger).printOut("var: 9");
84+
verify(logger).printOut("var => 9");
8585
verifyNoMoreInteractions(logger);
8686
}
8787

@@ -93,7 +93,7 @@ public void runCommandWithArgWithExtraSpace() throws CommandException {
9393
// when
9494
cmd.execute(" var");
9595
// then
96-
verify(logger).printOut("var: 9");
96+
verify(logger).printOut("var => 9");
9797
verifyNoMoreInteractions(logger);
9898
}
9999

@@ -105,7 +105,7 @@ public void runCommandWithArgWithBackticks() throws CommandException {
105105
// when
106106
cmd.execute("`var`");
107107
// then
108-
verify(logger).printOut("`var`: 9");
108+
verify(logger).printOut("`var` => 9");
109109
verifyNoMoreInteractions(logger);
110110
}
111111

@@ -117,7 +117,7 @@ public void runCommandWithSpecialCharacters() throws CommandException {
117117
// when
118118
cmd.execute("`var ```");
119119
// then
120-
verify(logger).printOut("`var ```: 9");
120+
verify(logger).printOut("`var ``` => 9");
121121
verifyNoMoreInteractions(logger);
122122
}
123123

0 commit comments

Comments
 (0)