8148316: jshell tool: Configurable output format

8148317: jshell tool: unify commands into /set
8149524: JShell: CompletenessAnalysis fails on class Case<E1 extends Enum<E1>, E2 extends Enum<E2>, E3 extends Enum<E3>> {}

Reviewed-by: jlahoda
This commit is contained in:
Robert Field 2016-03-08 11:53:35 -08:00
parent 528c1dfc4e
commit 51ea08084f
10 changed files with 1996 additions and 425 deletions

View file

@ -0,0 +1,271 @@
/*
* Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.internal.jshell.tool;
import java.util.Arrays;
import java.util.stream.Stream;
/**
* Parse command arguments, derived from StreamTokenizer by
* @author James Gosling
*/
class ArgTokenizer {
private final String str;
private final int length;
private int next = 0;
private char buf[] = new char[20];
private int mark;
private final byte ctype[] = new byte[256];
private static final byte CT_ALPHA = 0;
private static final byte CT_WHITESPACE = 1;
private static final byte CT_QUOTE = 8;
private String sval;
private boolean isQuoted = false;
ArgTokenizer(String arg) {
this.str = arg;
this.length = arg.length();
quoteChar('"');
quoteChar('\'');
whitespaceChars(0x09, 0x0D);
whitespaceChars(0x1C, 0x20);
whitespaceChars(0x85, 0x85);
whitespaceChars(0xA0, 0xA0);
}
String next() {
nextToken();
return sval;
}
String[] next(String... strings) {
return next(Arrays.stream(strings));
}
String[] next(Stream<String> stream) {
nextToken();
if (sval == null) {
return null;
}
String[] matches = stream
.filter(s -> s.startsWith(sval))
.toArray(size -> new String[size]);
return matches;
}
String val() {
return sval;
}
boolean isQuoted() {
return isQuoted;
}
String whole() {
return str;
}
void mark() {
mark = next;
}
void rewind() {
next = mark;
}
/**
* Reads a single character.
*
* @return The character read, or -1 if the end of the stream has been
* reached
*/
private int read() {
if (next >= length) {
return -1;
}
return str.charAt(next++);
}
/**
* Specifies that all characters <i>c</i> in the range
* <code>low&nbsp;&lt;=&nbsp;<i>c</i>&nbsp;&lt;=&nbsp;high</code>
* are white space characters. White space characters serve only to
* separate tokens in the input stream.
*
* <p>Any other attribute settings for the characters in the specified
* range are cleared.
*
* @param low the low end of the range.
* @param hi the high end of the range.
*/
private void whitespaceChars(int low, int hi) {
if (low < 0)
low = 0;
if (hi >= ctype.length)
hi = ctype.length - 1;
while (low <= hi)
ctype[low++] = CT_WHITESPACE;
}
/**
* Specifies that matching pairs of this character delimit string
* constants in this tokenizer.
* <p>
* If a string quote character is encountered, then a string is
* recognized, consisting of all characters after (but not including)
* the string quote character, up to (but not including) the next
* occurrence of that same string quote character, or a line
* terminator, or end of file. The usual escape sequences such as
* {@code "\u005Cn"} and {@code "\u005Ct"} are recognized and
* converted to single characters as the string is parsed.
*
* <p>Any other attribute settings for the specified character are cleared.
*
* @param ch the character.
*/
private void quoteChar(int ch) {
if (ch >= 0 && ch < ctype.length)
ctype[ch] = CT_QUOTE;
}
private int unicode2ctype(int c) {
switch (c) {
case 0x1680:
case 0x180E:
case 0x200A:
case 0x202F:
case 0x205F:
case 0x3000:
return CT_WHITESPACE;
default:
return CT_ALPHA;
}
}
/**
* Parses the next token of this tokenizer.
*/
public void nextToken() {
byte ct[] = ctype;
int c;
int lctype;
sval = null;
isQuoted = false;
do {
c = read();
if (c < 0) {
return;
}
lctype = (c < 256) ? ct[c] : unicode2ctype(c);
} while (lctype == CT_WHITESPACE);
if (lctype == CT_ALPHA) {
int i = 0;
do {
if (i >= buf.length) {
buf = Arrays.copyOf(buf, buf.length * 2);
}
buf[i++] = (char) c;
c = read();
lctype = c < 0 ? CT_WHITESPACE : (c < 256)? ct[c] : unicode2ctype(c);
} while (lctype == CT_ALPHA);
if (c >= 0) --next; // push last back
sval = String.copyValueOf(buf, 0, i);
return;
}
if (lctype == CT_QUOTE) {
int quote = c;
int i = 0;
/* Invariants (because \Octal needs a lookahead):
* (i) c contains char value
* (ii) d contains the lookahead
*/
int d = read();
while (d >= 0 && d != quote) {
if (d == '\\') {
c = read();
int first = c; /* To allow \377, but not \477 */
if (c >= '0' && c <= '7') {
c = c - '0';
int c2 = read();
if ('0' <= c2 && c2 <= '7') {
c = (c << 3) + (c2 - '0');
c2 = read();
if ('0' <= c2 && c2 <= '7' && first <= '3') {
c = (c << 3) + (c2 - '0');
d = read();
} else
d = c2;
} else
d = c2;
} else {
switch (c) {
case 'a':
c = 0x7;
break;
case 'b':
c = '\b';
break;
case 'f':
c = 0xC;
break;
case 'n':
c = '\n';
break;
case 'r':
c = '\r';
break;
case 't':
c = '\t';
break;
case 'v':
c = 0xB;
break;
}
d = read();
}
} else {
c = d;
d = read();
}
if (i >= buf.length) {
buf = Arrays.copyOf(buf, buf.length * 2);
}
buf[i++] = (char)c;
}
if (d == quote) {
isQuoted = true;
}
sval = String.copyValueOf(buf, 0, i);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -231,7 +231,7 @@ class CompletenessAnalyzer {
// Declarations and type parameters (thus expressions)
EXTENDS(TokenKind.EXTENDS, XEXPR|XDECL), // extends
COMMA(TokenKind.COMMA, XEXPR|XDECL|XSTART), // ,
COMMA(TokenKind.COMMA, XEXPR|XDECL), // ,
AMP(TokenKind.AMP, XEXPR|XDECL), // &
GT(TokenKind.GT, XEXPR|XDECL), // >
LT(TokenKind.LT, XEXPR|XDECL1), // <

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -50,13 +50,9 @@ import org.testng.annotations.Test;
public class CommandCompletionTest extends ReplToolTesting {
public void testCommand() {
assertCompletion("/f|", false, "/feedback ");
assertCompletion("/deb|", false);
assertCompletion("/feedback v|", false, "verbose");
assertCompletion("/c|", false, "/classes ", "/classpath ");
assertCompletion("/h|", false, "/help ", "/history ");
assertCompletion("/feedback |", false,
"?", "concise", "default", "normal", "off", "verbose");
}
public void testList() {
@ -108,7 +104,7 @@ public class CommandCompletionTest extends ReplToolTesting {
public void testSave() throws IOException {
Compiler compiler = new Compiler();
assertCompletion("/s|", false, "/save ", "/seteditor ", "/setstart ");
assertCompletion("/s|", false, "/save ", "/set ");
List<String> p1 = listFiles(Paths.get(""));
Collections.addAll(p1, "all ", "history ", "start ");
FileSystems.getDefault().getRootDirectories().forEach(s -> p1.add(s.toString()));

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,6 +23,7 @@
/*
* @test
* @bug 8149524
* @summary Test SourceCodeAnalysis
* @build KullaTesting TestingInputStream
* @run testng CompletenessTest
@ -60,6 +61,7 @@ public class CompletenessTest extends KullaTesting {
"try { } finally { }",
"try (java.util.zip.ZipFile zf = new java.util.zip.ZipFile(zipFileName)) { }",
"foo: while (true) { printf(\"Innn\"); break foo; }",
"class Case<E1 extends Enum<E1>, E2 extends Enum<E2>, E3 extends Enum<E3>> {}",
";",
};

View file

@ -113,7 +113,7 @@ public class ExternalEditorTest extends EditorTestBase {
@Override
public void testEditor(boolean defaultStartup, String[] args, ReplTest... tests) {
ReplTest[] t = new ReplTest[tests.length + 1];
t[0] = a -> assertCommandCheckOutput(a, "/seteditor " + executionScript,
t[0] = a -> assertCommandCheckOutput(a, "/set editor " + executionScript,
assertStartsWith("| Editor set to: " + executionScript));
System.arraycopy(tests, 0, t, 1, tests.length);
super.testEditor(defaultStartup, args, t);
@ -193,8 +193,8 @@ public class ExternalEditorTest extends EditorTestBase {
@Test
public void setUnknownEditor() {
test(
a -> assertCommand(a, "/seteditor", "| /seteditor requires a path argument\n"),
a -> assertCommand(a, "/seteditor UNKNOWN", "| Editor set to: UNKNOWN\n"),
a -> assertCommand(a, "/set editor", "| /set editor requires a path argument\n"),
a -> assertCommand(a, "/set editor UNKNOWN", "| Editor set to: UNKNOWN\n"),
a -> assertCommand(a, "int a;", null),
a -> assertCommand(a, "/e 1",
"| Edit Error: process IO failure: Cannot run program \"UNKNOWN\": error=2, No such file or directory\n")
@ -204,7 +204,7 @@ public class ExternalEditorTest extends EditorTestBase {
@Test(enabled = false)
public void testRemoveTempFile() {
test(new String[]{"-nostartup"},
a -> assertCommandCheckOutput(a, "/seteditor " + executionScript,
a -> assertCommandCheckOutput(a, "/set editor " + executionScript,
assertStartsWith("| Editor set to: " + executionScript)),
a -> assertVariable(a, "int", "a", "0", "0"),
a -> assertEditOutput(a, "/e 1", assertStartsWith("| Edit Error: Failure read edit file:"), () -> {

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -397,6 +397,15 @@ public class ReplToolTesting {
assertCommand(after, cmd, out, "", null, "", "");
}
public void assertCommandOutputContains(boolean after, String cmd, String has) {
assertCommandCheckOutput(after, cmd, (s) ->
assertTrue(s.contains(has), "Output: \'" + s + "' does not contain: " + has));
}
public void assertCommandOutputStartsWith(boolean after, String cmd, String starts) {
assertCommandCheckOutput(after, cmd, assertStartsWith(starts));
}
public void assertCommandCheckOutput(boolean after, String cmd, Consumer<String> check) {
if (!after) {
assertCommand(false, cmd, null);
@ -437,13 +446,13 @@ public class ReplToolTesting {
}
private List<String> computeCompletions(String code, boolean isSmart) {
JShellTool repl = this.repl != null ? this.repl
JShellTool js = this.repl != null ? this.repl
: new JShellTool(null, null, null, null, null, null, null);
int cursor = code.indexOf('|');
code = code.replace("|", "");
assertTrue(cursor > -1, "'|' not found: " + code);
List<Suggestion> completions =
repl.commandCompletionSuggestions(code, cursor, new int[1]); //XXX: ignoring anchor for now
js.commandCompletionSuggestions(code, cursor, new int[1]); //XXX: ignoring anchor for now
return completions.stream()
.filter(s -> isSmart == s.isSmart)
.map(s -> s.continuation)
@ -481,6 +490,15 @@ public class ReplToolTesting {
return name.hashCode();
}
@Override
public boolean equals(Object o) {
if (o instanceof MemberInfo) {
MemberInfo mi = (MemberInfo) o;
return name.equals(mi.name);
}
return false;
}
public abstract Consumer<String> checkOutput();
public String getSource() {
@ -536,6 +554,11 @@ public class ReplToolTesting {
"Output: " + output + " does not fit pattern: " + finalPattern);
}
@Override
public int hashCode() {
return name.hashCode();
}
@Override
public boolean equals(Object o) {
if (o instanceof VariableInfo) {
@ -585,6 +608,10 @@ public class ReplToolTesting {
return s -> assertTrue(checkOutput.test(s), "Expected: '" + expectedOutput + "', actual: " + s);
}
@Override
public int hashCode() {
return (name.hashCode() << 2) ^ type.hashCode() ;
}
@Override
public boolean equals(Object o) {
@ -615,6 +642,11 @@ public class ReplToolTesting {
return s -> assertTrue(checkOutput.test(s), "Expected: '" + expectedOutput + "', actual: " + s);
}
@Override
public int hashCode() {
return name.hashCode() ;
}
@Override
public boolean equals(Object o) {
if (o instanceof ClassInfo) {
@ -640,6 +672,11 @@ public class ReplToolTesting {
return s -> assertTrue("".equals(s), "Expected: '', actual: " + s);
}
@Override
public int hashCode() {
return (name.hashCode() << 2) ^ type.hashCode() ;
}
@Override
public boolean equals(Object o) {
if (o instanceof ImportInfo) {

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,7 +23,7 @@
/*
* @test
* @bug 8143037 8142447 8144095 8140265 8144906 8146138 8147887 8147886
* @bug 8143037 8142447 8144095 8140265 8144906 8146138 8147887 8147886 8148316 8148317
* @requires os.family != "solaris"
* @summary Tests for Basic tests for REPL tool
* @library /tools/lib
@ -90,8 +90,7 @@ public class ToolBasicTest extends ReplToolTesting {
public void elideStartUpFromList() {
test(
(a) -> assertCommandCheckOutput(a, "123", (s) ->
assertTrue(s.contains("type int"), s)),
(a) -> assertCommandOutputContains(a, "123", "type int"),
(a) -> assertCommandCheckOutput(a, "/list", (s) -> {
int cnt;
try (Scanner scanner = new Scanner(s)) {
@ -112,8 +111,7 @@ public class ToolBasicTest extends ReplToolTesting {
Compiler compiler = new Compiler();
Path path = compiler.getPath("myfile");
test(
(a) -> assertCommandCheckOutput(a, "123",
(s) -> assertTrue(s.contains("type int"), s)),
(a) -> assertCommandOutputContains(a, "123", "type int"),
(a) -> assertCommand(a, "/save " + path.toString(), "")
);
try (Stream<String> lines = Files.lines(path)) {
@ -594,12 +592,12 @@ public class ToolBasicTest extends ReplToolTesting {
(a) -> assertMethod(a, "void f() {}", "()V", "f"),
(a) -> assertImport(a, "import java.util.stream.*;", "", "java.util.stream.*"),
(a) -> assertCommand(a, "/save " + startUpFile.toString(), null),
(a) -> assertCommand(a, "/setstart " + startUpFile.toString(), null)
(a) -> assertCommand(a, "/set start " + startUpFile.toString(), null)
);
Path unknown = compiler.getPath("UNKNOWN");
test(
(a) -> assertCommand(a, "/setstart " + unknown.toString(),
"| File '" + unknown + "' for /setstart is not found.\n")
(a) -> assertCommand(a, "/set start " + unknown.toString(),
"| File '" + unknown + "' for /set start is not found.\n")
);
test(false, new String[0],
(a) -> {
@ -619,7 +617,7 @@ public class ToolBasicTest extends ReplToolTesting {
}
private void removeStartup() {
Preferences preferences = Preferences.userRoot().node("tool/REPL");
Preferences preferences = Preferences.userRoot().node("tool/JShell");
if (preferences != null) {
preferences.remove("STARTUP");
}
@ -636,7 +634,7 @@ public class ToolBasicTest extends ReplToolTesting {
}
public void testNoArgument() {
String[] commands = {"/save", "/open", "/setstart"};
String[] commands = {"/save", "/open", "/set start"};
test(Stream.of(commands)
.map(cmd -> {
String c = cmd;
@ -670,8 +668,7 @@ public class ToolBasicTest extends ReplToolTesting {
test(
a -> assertVariable(a, "int", "x"),
a -> assertCommandCheckOutput(a, "/vars", assertVariables()),
a -> assertCommandCheckOutput(a, "System.exit(5);", s ->
assertTrue(s.contains("terminated"), s)),
a -> assertCommandOutputContains(a, "System.exit(5);", "terminated"),
a -> assertCommandCheckOutput(a, "/vars", s ->
assertTrue(s.trim().isEmpty(), s)),
a -> assertMethod(a, "void f() { }", "()void", "f"),
@ -699,8 +696,7 @@ public class ToolBasicTest extends ReplToolTesting {
s -> assertEquals(s, "| No definition or id named " + arg +
" found. There are no active definitions.\n")),
a -> assertVariable(a, "int", "aardvark"),
a -> assertCommandCheckOutput(a, "/list aardvark",
s -> assertTrue(s.contains("aardvark"))),
a -> assertCommandOutputContains(a, "/list aardvark", "aardvark"),
a -> assertCommandCheckOutput(a, "/list start",
s -> checkLineToList(s, START_UP)),
a -> assertCommandCheckOutput(a, "/list all",
@ -714,14 +710,14 @@ public class ToolBasicTest extends ReplToolTesting {
}
public void testFeedbackNegative() {
test(a -> assertCommandCheckOutput(a, "/feedback aaaa",
assertStartsWith("| Follow /feedback with of the following")));
test(a -> assertCommandCheckOutput(a, "/set feedback aaaa",
assertStartsWith("| Does not match any current feedback mode")));
}
public void testFeedbackOff() {
for (String off : new String[]{"o", "off"}) {
test(
a -> assertCommand(a, "/feedback " + off, ""),
a -> assertCommand(a, "/set feedback " + off, ""),
a -> assertCommand(a, "int a", ""),
a -> assertCommand(a, "void f() {}", ""),
a -> assertCommandCheckOutput(a, "aaaa", assertStartsWith("| Error:")),
@ -730,23 +726,6 @@ public class ToolBasicTest extends ReplToolTesting {
}
}
public void testFeedbackConcise() {
Compiler compiler = new Compiler();
Path testConciseFile = compiler.getPath("testConciseFeedback");
String[] sources = new String[] {"int a", "void f() {}", "class A {}", "a = 10"};
compiler.writeToFile(testConciseFile, sources);
for (String concise : new String[]{"c", "concise"}) {
test(
a -> assertCommand(a, "/feedback " + concise, ""),
a -> assertCommand(a, sources[0], ""),
a -> assertCommand(a, sources[1], ""),
a -> assertCommand(a, sources[2], ""),
a -> assertCommand(a, sources[3], "| a : 10\n"),
a -> assertCommand(a, "/o " + testConciseFile.toString(), "| a : 10\n")
);
}
}
public void testFeedbackNormal() {
Compiler compiler = new Compiler();
Path testNormalFile = compiler.getPath("testConciseNormal");
@ -759,58 +738,20 @@ public class ToolBasicTest extends ReplToolTesting {
"| Variable a has been assigned the value 10\n"
};
compiler.writeToFile(testNormalFile, sources2);
for (String feedback : new String[]{"/f", "/feedback"}) {
for (String feedbackState : new String[]{"n", "normal", "v", "verbose"}) {
String f = null;
if (feedbackState.startsWith("n")) {
f = "normal";
} else if (feedbackState.startsWith("v")) {
f = "verbose";
}
final String finalF = f;
for (String feedback : new String[]{"/set f", "/set feedback"}) {
for (String feedbackState : new String[]{"n", "normal", "o", "off"}) {
test(
a -> assertCommand(a, feedback + " " + feedbackState, "| Feedback mode: " + finalF +"\n"),
a -> assertCommand(a, feedback + " " + feedbackState, "| Feedback mode: normal\n"),
a -> assertCommand(a, sources[0], output[0]),
a -> assertCommand(a, sources[1], output[1]),
a -> assertCommand(a, sources[2], output[2]),
a -> assertCommand(a, sources[3], output[3]),
a -> assertCommand(a, "/o " + testNormalFile.toString(),
"| Modified variable a of type int\n" +
"| Modified method f()\n" +
"| Update overwrote method f()\n" +
"| Modified class A\n" +
"| Update overwrote class A\n" +
"| Variable a has been assigned the value 10\n")
a -> assertCommand(a, "/o " + testNormalFile.toString(), "")
);
}
}
}
public void testFeedbackDefault() {
Compiler compiler = new Compiler();
Path testDefaultFile = compiler.getPath("testDefaultFeedback");
String[] sources = new String[] {"int a", "void f() {}", "class A {}", "a = 10"};
String[] output = new String[] {
"| Added variable a of type int\n",
"| Added method f()\n",
"| Added class A\n",
"| Variable a has been assigned the value 10\n"
};
compiler.writeToFile(testDefaultFile, sources);
for (String defaultFeedback : new String[]{"", "d", "default"}) {
test(
a -> assertCommand(a, "/feedback o", ""),
a -> assertCommand(a, "int x", ""),
a -> assertCommand(a, "/feedback " + defaultFeedback, "| Feedback mode: default\n"),
a -> assertCommand(a, sources[0], output[0]),
a -> assertCommand(a, sources[1], output[1]),
a -> assertCommand(a, sources[2], output[2]),
a -> assertCommand(a, sources[3], output[3]),
a -> assertCommand(a, "/o " + testDefaultFile.toString(), "")
);
}
}
public void testDrop() {
test(false, new String[]{"-nostartup"},
a -> assertVariable(a, "int", "a"),
@ -906,7 +847,7 @@ public class ToolBasicTest extends ReplToolTesting {
public void testCommandPrefix() {
test(a -> assertCommandCheckOutput(a, "/s",
assertStartsWith("| Command: /s is ambiguous: /seteditor, /save, /setstart")),
assertStartsWith("| Command: /s is ambiguous: /save, /set")),
a -> assertCommand(a, "int var", "| Added variable var of type int\n"),
a -> assertCommandCheckOutput(a, "/va",
assertStartsWith("| int var = 0")),

View file

@ -0,0 +1,159 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8148316 8148317
* @summary Tests for output customization
* @library /tools/lib
* @build KullaTesting TestingInputStream ToolBox Compiler
* @run testng ToolFormatTest
*/
import org.testng.annotations.Test;
@Test
public class ToolFormatTest extends ReplToolTesting {
public void testSetFormat() {
try {
test(
(a) -> assertCommandOutputStartsWith(a, "/set newmode test command", "| Created new feedback mode: test"),
(a) -> assertCommand(a, "/set field test pre '$ '", ""),
(a) -> assertCommand(a, "/set field test post ''", ""),
(a) -> assertCommand(a, "/set field test action 'ADD ' added-primary", ""),
(a) -> assertCommand(a, "/set field test action 'MOD ' modified-primary", ""),
(a) -> assertCommand(a, "/set field test action 'REP ' replaced-primary", ""),
(a) -> assertCommand(a, "/set field test action 'UP-ADD ' added-update", ""),
(a) -> assertCommand(a, "/set field test action 'UP-MOD ' modified-update", ""),
(a) -> assertCommand(a, "/set field test action 'UP-REP ' replaced-update", ""),
(a) -> assertCommand(a, "/set field test resolve 'OK' ok-*", ""),
(a) -> assertCommand(a, "/set field test resolve 'DEF' defined-*", ""),
(a) -> assertCommand(a, "/set field test resolve 'NODEF' notdefined-*", ""),
(a) -> assertCommand(a, "/set field test name ':%s ' ", ""),
(a) -> assertCommand(a, "/set field test type '[%s]' ", ""),
(a) -> assertCommand(a, "/set field test result '=%s ' ", ""),
(a) -> assertCommand(a, "/set format test '{pre}{action}{type}{name}{result}{resolve}' *-*-*", ""),
(a) -> assertCommand(a, "/set format test '{pre}HI this is enum' enum", ""),
(a) -> assertCommand(a, "/set feedback test", "$ Feedback mode: test"),
(a) -> assertCommand(a, "class D {}", "$ ADD :D OK"),
(a) -> assertCommand(a, "void m() {}", "$ ADD []:m OK"),
(a) -> assertCommand(a, "interface EX extends EEX {}", "$ ADD :EX NODEF"),
(a) -> assertCommand(a, "56", "$ ADD [int]:$4 =56 OK"),
(a) -> assertCommand(a, "class D { int hh; }", "$ REP :D OK$ OVERWROTE-UPDATE:D OK"),
(a) -> assertCommandOutputStartsWith(a, "/set feedback normal", "| Feedback mode: normal")
);
} finally {
assertCommandCheckOutput(false, "/set feedback normal", s -> {
});
}
}
public void testNewModeQuiet() {
try {
test(
(a) -> assertCommandOutputStartsWith(a, "/set newmode nmq quiet normal", "| Created new feedback mode: nmq"),
(a) -> assertCommand(a, "/set feedback nmq", ""),
(a) -> assertCommand(a, "/se ne nmq2 q nor", ""),
(a) -> assertCommand(a, "/se fee nmq2", ""),
(a) -> assertCommand(a, "/set newmode nmc command normal", ""),
(a) -> assertCommandOutputStartsWith(a, "/set feedback nmc", "| Feedback mode: nmc"),
(a) -> assertCommandOutputStartsWith(a, "/set newmode nm", "| Created new feedback mode: nm"),
(a) -> assertCommandOutputStartsWith(a, "/set feedback nm", "| Feedback mode: nm")
);
} finally {
assertCommandCheckOutput(false, "/set feedback normal", s -> {
});
}
}
public void testSetError() {
try {
test(
(a) -> assertCommandOutputStartsWith(a, "/set newmode te command normal", "| Created new feedback mode: te"),
(a) -> assertCommand(a, "/set field te errorpre 'ERROR: '", ""),
(a) -> assertCommandOutputStartsWith(a, "/set feedback te", ""),
(a) -> assertCommandCheckOutput(a, "/set ", assertStartsWith("ERROR: The /set command requires arguments")),
(a) -> assertCommandCheckOutput(a, "/set xyz", assertStartsWith("ERROR: Not a valid argument to /set")),
(a) -> assertCommandCheckOutput(a, "/set f", assertStartsWith("ERROR: Ambiguous argument to /set")),
(a) -> assertCommandCheckOutput(a, "/set feedback", assertStartsWith("ERROR: Expected a feedback mode")),
(a) -> assertCommandCheckOutput(a, "/set feedback xyz", assertStartsWith("ERROR: Does not match any current feedback mode")),
(a) -> assertCommandCheckOutput(a, "/set format", assertStartsWith("ERROR: Expected a feedback mode")),
(a) -> assertCommandCheckOutput(a, "/set format xyz", assertStartsWith("ERROR: Does not match any current feedback mode")),
(a) -> assertCommandCheckOutput(a, "/set format te", assertStartsWith("ERROR: Expected format missing")),
(a) -> assertCommandCheckOutput(a, "/set format te aaa", assertStartsWith("ERROR: Format 'aaa' must be quoted")),
(a) -> assertCommandCheckOutput(a, "/set format te 'aaa'", assertStartsWith("ERROR: At least one selector required")),
(a) -> assertCommandCheckOutput(a, "/set format te 'aaa' frog", assertStartsWith("ERROR: Not a valid case")),
(a) -> assertCommandCheckOutput(a, "/set format te 'aaa' import-frog", assertStartsWith("ERROR: Not a valid action")),
(a) -> assertCommandCheckOutput(a, "/set newmode", assertStartsWith("ERROR: Expected new feedback mode")),
(a) -> assertCommandCheckOutput(a, "/set newmode te", assertStartsWith("ERROR: Expected a new feedback mode name")),
(a) -> assertCommandCheckOutput(a, "/set newmode x xyz", assertStartsWith("ERROR: Specify either 'command' or 'quiet'")),
(a) -> assertCommandCheckOutput(a, "/set newmode x quiet y", assertStartsWith("ERROR: Does not match any current feedback mode")),
(a) -> assertCommandCheckOutput(a, "/set prompt", assertStartsWith("ERROR: Expected a feedback mode")),
(a) -> assertCommandCheckOutput(a, "/set prompt te", assertStartsWith("ERROR: Expected format missing")),
(a) -> assertCommandCheckOutput(a, "/set prompt te aaa xyz", assertStartsWith("ERROR: Format 'aaa' must be quoted")),
(a) -> assertCommandCheckOutput(a, "/set prompt te 'aaa' xyz", assertStartsWith("ERROR: Format 'xyz' must be quoted")),
(a) -> assertCommandCheckOutput(a, "/set prompt", assertStartsWith("ERROR: Expected a feedback mode")),
(a) -> assertCommandCheckOutput(a, "/set prompt te", assertStartsWith("ERROR: Expected format missing")),
(a) -> assertCommandCheckOutput(a, "/set prompt te aaa", assertStartsWith("ERROR: Format 'aaa' must be quoted")),
(a) -> assertCommandCheckOutput(a, "/set prompt te 'aaa'", assertStartsWith("ERROR: Expected format missing")),
(a) -> assertCommandCheckOutput(a, "/set field", assertStartsWith("ERROR: Expected a feedback mode")),
(a) -> assertCommandCheckOutput(a, "/set field xyz", assertStartsWith("ERROR: Does not match any current feedback mode: xyz")),
(a) -> assertCommandCheckOutput(a, "/set field te xyz", assertStartsWith("ERROR: Not a valid field: xyz, must be one of: when")),
(a) -> assertCommandCheckOutput(a, "/set field te action", assertStartsWith("ERROR: Expected format missing")),
(a) -> assertCommandCheckOutput(a, "/set field te action 'act'", assertStartsWith("ERROR: At least one selector required"))
);
} finally {
assertCommandCheckOutput(false, "/set feedback normal", s -> {
});
}
}
public void testSetHelp() {
try {
test(
(a) -> assertCommandOutputContains(a, "/help /set", "command to launch"),
(a) -> assertCommandOutputContains(a, "/help /set format", "vardecl"),
(a) -> assertCommandOutputContains(a, "/hel /se for", "vardecl"),
(a) -> assertCommandOutputContains(a, "/help /set editor", "temporary file")
);
} finally {
assertCommandCheckOutput(false, "/set feedback normal", s -> {
});
}
}
public void testSetHelpError() {
try {
test(
(a) -> assertCommandOutputStartsWith(a, "/set newmode te command normal", "| Created new feedback mode: te"),
(a) -> assertCommand(a, "/set field te errorpre 'ERROR: '", ""),
(a) -> assertCommandOutputStartsWith(a, "/set feedback te", "| Feedback mode: te"),
(a) -> assertCommandOutputContains(a, "/help /set xyz", "ERROR: Not a valid argument to /set: xyz"),
(a) -> assertCommandOutputContains(a, "/help /set f", "ERROR: Ambiguous argument to /set: f")
);
} finally {
assertCommandCheckOutput(false, "/set feedback normal", s -> {
});
}
}
}