8192863: jshell tool: /<id><tab> gives "No such command"

Reviewed-by: jlahoda
This commit is contained in:
Robert Field 2017-12-07 13:23:18 -08:00
parent 103f1b33cc
commit e08ffc05d9
8 changed files with 282 additions and 219 deletions

View File

@ -216,7 +216,7 @@ class ConsoleIOContext extends IOContext {
int[] anchor = new int[] {-1};
List<Suggestion> suggestions;
List<String> doc;
boolean command = prefix.isEmpty() && text.trim().startsWith("/");
boolean command = prefix.isEmpty() && text.startsWith("/");
if (command) {
suggestions = repl.commandCompletionSuggestions(text, cursor, anchor);
doc = repl.commandDocumentation(text, cursor, true);

View File

@ -114,6 +114,7 @@ import jdk.internal.editor.spi.BuildInEditorProvider;
import jdk.internal.editor.external.ExternalEditor;
import static java.util.Arrays.asList;
import static java.util.Arrays.stream;
import static java.util.Collections.singletonList;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
import static jdk.jshell.Snippet.SubKind.TEMP_VAR_EXPRESSION_SUBKIND;
@ -135,6 +136,9 @@ public class JShellTool implements MessageHandler {
private static final Pattern LINEBREAK = Pattern.compile("\\R");
private static final Pattern ID = Pattern.compile("[se]?\\d+([-\\s].*)?");
private static final Pattern RERUN_ID = Pattern.compile("/" + ID.pattern());
private static final Pattern RERUN_PREVIOUS = Pattern.compile("/\\-\\d+( .*)?");
private static final Pattern SET_SUB = Pattern.compile("/?set .*");
static final String RECORD_SEPARATOR = "\u241E";
private static final String RB_NAME_PREFIX = "jdk.internal.jshell.tool.resources";
private static final String VERSION_RB_NAME = RB_NAME_PREFIX + ".version";
@ -1305,8 +1309,8 @@ public class JShellTool implements MessageHandler {
Command[] candidates = findCommand(cmd, c -> c.kind.isRealCommand);
switch (candidates.length) {
case 0:
// not found, it is either a snippet command or an error
if (ID.matcher(cmd.substring(1)).matches()) {
// not found, it is either a rerun-ID command or an error
if (RERUN_ID.matcher(cmd).matches()) {
// it is in the form of a snipppet id, see if it is a valid history reference
rerunHistoryEntriesById(input);
} else {
@ -1839,7 +1843,7 @@ public class JShellTool implements MessageHandler {
public List<String> commandDocumentation(String code, int cursor, boolean shortDescription) {
code = code.substring(0, cursor).replaceAll("\\h+", " ");
String stripped = code.replaceFirst("/help ", "");
String stripped = code.replaceFirst("/(he(lp?)?|\\?) ", "");
boolean inHelp = !code.equals(stripped);
int space = stripped.indexOf(' ');
String prefix = space != (-1) ? stripped.substring(0, space) : stripped;
@ -1847,24 +1851,30 @@ public class JShellTool implements MessageHandler {
List<Entry<String, String>> toShow;
if (stripped.matches("/set .*") || stripped.matches("set .*")) {
if (SET_SUB.matcher(stripped).matches()) {
String setSubcommand = stripped.replaceFirst("/?set ([^ ]*)($| .*)", "$1");
toShow =
Arrays.stream(SET_SUBCOMMANDS)
.filter(s -> s.startsWith(setSubcommand))
.map(s -> new SimpleEntry<>("/set " + s, "help.set." + s))
.collect(Collectors.toList());
.map(s -> new SimpleEntry<>("/set " + s, "help.set." + s))
.collect(toList());
} else if (RERUN_ID.matcher(stripped).matches()) {
toShow =
singletonList(new SimpleEntry<>("/<id>", "help.rerun"));
} else if (RERUN_PREVIOUS.matcher(stripped).matches()) {
toShow =
singletonList(new SimpleEntry<>("/-<n>", "help.rerun"));
} else {
toShow =
commands.values()
.stream()
.filter(c -> c.command.startsWith(prefix)
|| c.command.substring(1).startsWith(prefix))
.filter(c -> c.kind.showInHelp ||
(inHelp && c.kind == CommandKind.HELP_SUBJECT))
|| c.command.substring(1).startsWith(prefix))
.filter(c -> c.kind.showInHelp
|| (inHelp && c.kind == CommandKind.HELP_SUBJECT))
.sorted((c1, c2) -> c1.command.compareTo(c2.command))
.map(c -> new SimpleEntry<>(c.command, c.helpKey))
.collect(Collectors.toList());
.collect(toList());
}
if (toShow.size() == 1 && !inHelp) {

View File

@ -45,9 +45,9 @@ public class HistoryUITest extends UITesting {
public void testPrevNextSnippet() throws Exception {
doRunTest((inputSink, out) -> {
inputSink.write("void test1() {\nSystem.err.println(1);\n}\n");
waitOutput(out, "\u0005");
waitOutput(out, PROMPT);
inputSink.write("void test2() {\nSystem.err.println(2);\n}\n");
waitOutput(out, "\u0005");
waitOutput(out, PROMPT);
inputSink.write(CTRL_UP);
waitOutput(out, "^void test2\\(\\) \\{");
inputSink.write(CTRL_UP);
@ -63,7 +63,7 @@ public class HistoryUITest extends UITesting {
inputSink.write(UP);
waitOutput(out, "^" + clearOut("System.err.println(2);") + "void test2\\(\\) \\{");
inputSink.write(UP);
waitOutput(out, "^\u0007");
waitOutput(out, "^" + BELL);
inputSink.write(DOWN);
waitOutput(out, "^" + clearOut("void test2() {") + "System.err.println\\(2\\);");
inputSink.write(DOWN);
@ -71,7 +71,7 @@ public class HistoryUITest extends UITesting {
inputSink.write(DOWN);
waitOutput(out, "^" + clearOut("}"));
inputSink.write(DOWN);
waitOutput(out, "^\u0007");
waitOutput(out, "^" + BELL);
});
}
//where:

View File

@ -62,11 +62,11 @@ public class PasteAndMeasurementsUITest extends UITesting {
"\u0006\u001b\\[6nSystem.err.println\\(1\\);\n" +
"\u0006\u001b\\[6n\\}\n" +
"\\| created method test1\\(\\)\n" +
"\u0005\u001b\\[6nvoid test2\\(\\) \\{\n" +
PROMPT + "\u001b\\[6nvoid test2\\(\\) \\{\n" +
"\u0006\u001b\\[6nSystem.err.println\\(1\\);\n" +
"\u0006\u001b\\[6n\\}\n" +
"\\| created method test2\\(\\)\n" +
"\u0005\u001b\\[6n");
PROMPT + "\u001b\\[6n");
});
}
private static final String ANSI_SUPPORTED_PROPERTY = "test.terminal.ansi.supported";

View File

@ -84,15 +84,15 @@ public class ToolShiftTabTest extends UITesting {
doRunTest((inputSink, out) -> {
inputSink.write("4");
inputSink.write(FIX + "m");
inputSink.write("\u0003 55");
inputSink.write(INTERRUPT + " 55");
inputSink.write(FIX + "m");
inputSink.write("\u0003 55");
inputSink.write(INTERRUPT + " 55");
inputSink.write(FIX + "m");
inputSink.write("\u0003 55");
inputSink.write(INTERRUPT + " 55");
inputSink.write(FIX + "m");
inputSink.write("\u0003 55");
inputSink.write(INTERRUPT + " 55");
inputSink.write(FIX + "m");
inputSink.write("\u0003'X'");
inputSink.write(INTERRUPT + "'X'");
inputSink.write(FIX + "m");
inputSink.write("nl\n");
waitOutput(out, "| created method nl()");

View File

@ -23,7 +23,7 @@
/**
* @test
* @bug 8177076 8185840 8178109
* @bug 8177076 8185840 8178109 8192863
* @modules
* jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
@ -36,8 +36,6 @@
* @run testng ToolTabCommandTest
*/
import java.util.regex.Pattern;
import org.testng.annotations.Test;
@Test
@ -49,79 +47,121 @@ public class ToolTabCommandTest extends UITesting {
doRunTest((inputSink, out) -> {
inputSink.write("1\n");
waitOutput(out, "\u0005");
inputSink.write("/\011");
waitOutput(out, ".*/edit.*/list.*\n\n" + Pattern.quote(getResource("jshell.console.see.synopsis")) + "\n\r\u0005/");
inputSink.write("\011");
waitOutput(out, ".*\n/edit\n" + Pattern.quote(getResource("help.edit.summary")) +
"\n.*\n/list\n" + Pattern.quote(getResource("help.list.summary")) +
".*\n\n" + Pattern.quote(getResource("jshell.console.see.full.documentation")) + "\n\r\u0005/");
inputSink.write("\011");
waitOutput(out, PROMPT);
inputSink.write("/" + TAB);
waitOutput(out, ".*/edit.*/list.*\n\n" + resource("jshell.console.see.synopsis") +
REDRAW_PROMPT + "/");
inputSink.write(TAB);
waitOutput(out, ".*\n/edit\n" + resource("help.edit.summary") +
"\n.*\n/list\n" + resource("help.list.summary") +
".*\n\n" + resource("jshell.console.see.full.documentation") +
REDRAW_PROMPT + "/");
inputSink.write(TAB);
waitOutput(out, "/!\n" +
Pattern.quote(getResource("help.bang")) + "\n" +
resource("help.bang") + "\n" +
"\n" +
Pattern.quote(getResource("jshell.console.see.next.command.doc")) + "\n" +
"\r\u0005/");
inputSink.write("\011");
resource("jshell.console.see.next.command.doc") +
REDRAW_PROMPT + "/");
inputSink.write(TAB);
waitOutput(out, "/-<n>\n" +
Pattern.quote(getResource("help.previous")) + "\n" +
resource("help.previous") + "\n" +
"\n" +
Pattern.quote(getResource("jshell.console.see.next.command.doc")) + "\n" +
"\r\u0005/");
resource("jshell.console.see.next.command.doc") +
REDRAW_PROMPT + "/");
inputSink.write("ed\011");
inputSink.write("ed" + TAB);
waitOutput(out, "edit $");
inputSink.write("\011");
inputSink.write(TAB);
waitOutput(out, ".*-all.*" +
"\n\n" + Pattern.quote(getResource("jshell.console.see.synopsis")) + "\n\r\u0005/");
inputSink.write("\011");
waitOutput(out, Pattern.quote(getResource("help.edit.summary")) + "\n\n" +
Pattern.quote(getResource("jshell.console.see.full.documentation")) + "\n\r\u0005/edit ");
inputSink.write("\011");
waitOutput(out, Pattern.quote(getResource("help.edit").replaceAll("\t", " ")));
"\n\n" + resource("jshell.console.see.synopsis") +
REDRAW_PROMPT + "/");
inputSink.write(TAB);
waitOutput(out, resource("help.edit.summary") + "\n\n" +
resource("jshell.console.see.full.documentation") +
REDRAW_PROMPT + "/edit ");
inputSink.write(TAB);
waitOutput(out, resource("help.edit"));
inputSink.write("\u0003/env \011");
waitOutput(out, "\u0005/env -\n" +
inputSink.write(INTERRUPT + "/env " + TAB);
waitOutput(out, PROMPT + "/env -\n" +
"-add-exports -add-modules -class-path -module-path \n" +
"\n" +
Pattern.quote(getResource("jshell.console.see.synopsis")) + "\n" +
"\r\u0005/env -");
resource("jshell.console.see.synopsis") +
REDRAW_PROMPT + "/env -");
inputSink.write("\011");
waitOutput(out, Pattern.quote(getResource("help.env.summary")) + "\n\n" +
Pattern.quote(getResource("jshell.console.see.full.documentation")) + "\n" +
"\r\u0005/env -");
inputSink.write(TAB);
waitOutput(out, resource("help.env.summary") + "\n\n" +
resource("jshell.console.see.full.documentation") +
REDRAW_PROMPT + "/env -");
inputSink.write("\011");
waitOutput(out, Pattern.quote(getResource("help.env").replaceAll("\t", " ")) + "\n" +
"\r\u0005/env -");
inputSink.write(TAB);
waitOutput(out, resource("help.env") +
REDRAW_PROMPT + "/env -");
inputSink.write("\011");
inputSink.write(TAB);
waitOutput(out, "-add-exports -add-modules -class-path -module-path \n" +
"\n" +
Pattern.quote(getResource("jshell.console.see.synopsis")) + "\n" +
"\r\u0005/env -");
resource("jshell.console.see.synopsis") +
REDRAW_PROMPT + "/env -");
inputSink.write("\u0003/exit \011");
waitOutput(out, Pattern.quote(getResource("help.exit.summary")) + "\n\n" +
Pattern.quote(getResource("jshell.console.see.full.documentation")) + "\n\r\u0005/exit ");
inputSink.write("\011");
waitOutput(out, Pattern.quote(getResource("help.exit").replaceAll("\t", " ")) + "\n" +
"\r\u0005/exit ");
inputSink.write("\011");
waitOutput(out, Pattern.quote(getResource("help.exit.summary")) + "\n\n" +
Pattern.quote(getResource("jshell.console.see.full.documentation")) + "\n\r\u0005/exit ");
inputSink.write("\u0003");
inputSink.write(INTERRUPT + "/exit " + TAB);
waitOutput(out, resource("help.exit.summary") + "\n\n" +
resource("jshell.console.see.full.documentation") +
REDRAW_PROMPT + "/exit ");
inputSink.write(TAB);
waitOutput(out, resource("help.exit") +
REDRAW_PROMPT + "/exit ");
inputSink.write(TAB);
waitOutput(out, resource("help.exit.summary") + "\n\n" +
resource("jshell.console.see.full.documentation") +
REDRAW_PROMPT + "/exit ");
inputSink.write(INTERRUPT);
inputSink.write("int zebraStripes = 11\n");
waitOutput(out, "zebraStripes ==> 11\n\u0005");
inputSink.write("/exit zeb\011");
inputSink.write("/exit zeb" + TAB);
waitOutput(out, "braStr.*es");
inputSink.write("\u0003/doesnotexist\011");
waitOutput(out, "\u0005/doesnotexist\n" +
Pattern.quote(getResource("jshell.console.no.such.command")) + "\n" +
"\n" +
"\r\u0005/doesnotexist");
inputSink.write(INTERRUPT + "/doesnotexist" + TAB);
waitOutput(out, PROMPT + "/doesnotexist\n" +
resource("jshell.console.no.such.command") + "\n" +
REDRAW_PROMPT + "/doesnotexist");
});
}
public void testRerunCommands() throws Exception {
// set terminal height so that help output won't hit page breaks
System.setProperty("test.terminal.height", "1000000");
doRunTest((inputSink, out) -> {
inputSink.write("1\n");
waitOutput(out, PROMPT);
inputSink.write("2\n");
waitOutput(out, PROMPT);
inputSink.write("/1" + TAB);
waitOutput(out, resource("help.rerun.summary") + "\n\n" +
resource("jshell.console.see.full.documentation") +
REDRAW_PROMPT + "/1");
inputSink.write(TAB);
waitOutput(out, resource("help.rerun") +
REDRAW_PROMPT + "/1");
inputSink.write(TAB);
waitOutput(out, resource("help.rerun.summary") + "\n\n" +
resource("jshell.console.see.full.documentation") +
REDRAW_PROMPT + "/1");
inputSink.write(INTERRUPT);
inputSink.write("/-1" + TAB);
waitOutput(out, resource("help.rerun.summary") + "\n\n" +
resource("jshell.console.see.full.documentation") +
REDRAW_PROMPT + "/-1");
inputSink.write(TAB);
waitOutput(out, resource("help.rerun") +
REDRAW_PROMPT + "/-1");
inputSink.write(TAB);
waitOutput(out, resource("help.rerun.summary") + "\n\n" +
resource("jshell.console.see.full.documentation") +
REDRAW_PROMPT + "/-1");
});
}
@ -130,62 +170,62 @@ public class ToolTabCommandTest extends UITesting {
System.setProperty("test.terminal.height", "1000000");
doRunTest((inputSink, out) -> {
inputSink.write("/help \011");
waitOutput(out, ".*/edit.*/list.*intro.*\n\n" + Pattern.quote(getResource("jshell.console.see.synopsis")) + "\n" +
"\r\u0005/");
inputSink.write("\011");
waitOutput(out, ".*\n/edit\n" + Pattern.quote(getResource("help.edit.summary")) +
"\n.*\n/list\n" + Pattern.quote(getResource("help.list.summary")) +
"\n.*\nintro\n" + Pattern.quote(getResource("help.intro.summary")) +
".*\n\n" + Pattern.quote(getResource("jshell.console.see.full.documentation")) + "\n" +
"\r\u0005/");
inputSink.write("/env\011");
inputSink.write("/help " + TAB);
waitOutput(out, ".*/edit.*/list.*intro.*\n\n" + resource("jshell.console.see.synopsis") +
REDRAW_PROMPT + "/");
inputSink.write(TAB);
waitOutput(out, ".*\n/edit\n" + resource("help.edit.summary") +
"\n.*\n/list\n" + resource("help.list.summary") +
"\n.*\nintro\n" + resource("help.intro.summary") +
".*\n\n" + resource("jshell.console.see.full.documentation") +
REDRAW_PROMPT + "/");
inputSink.write("/env" + TAB);
waitOutput(out, "help /env ");
inputSink.write("\011");
waitOutput(out, ".*\n/env\n" + Pattern.quote(getResource("help.env.summary")) +
".*\n\n" + Pattern.quote(getResource("jshell.console.see.full.documentation")) + "\n" +
"\r\u0005/help /env ");
inputSink.write("\011");
waitOutput(out, ".*\n/env\n" + Pattern.quote(getResource("help.env").replaceAll("\t", " ")) + "\n" +
"\r\u0005/help /env ");
inputSink.write("\u0003/help intro\011");
inputSink.write(TAB);
waitOutput(out, ".*\n/env\n" + resource("help.env.summary") +
".*\n\n" + resource("jshell.console.see.full.documentation") +
REDRAW_PROMPT + "/help /env ");
inputSink.write(TAB);
waitOutput(out, ".*\n/env\n" + resource("help.env") +
REDRAW_PROMPT + "/help /env ");
inputSink.write(INTERRUPT + "/help intro" + TAB);
waitOutput(out, "help intro ");
inputSink.write("\011");
waitOutput(out, ".*\nintro\n" + Pattern.quote(getResource("help.intro.summary")) +
".*\n\n" + Pattern.quote(getResource("jshell.console.see.full.documentation")) + "\n" +
"\r\u0005/help intro ");
inputSink.write("\011");
waitOutput(out, ".*\nintro\n" + Pattern.quote(getResource("help.intro").replaceAll("\t", " ")) + "\n" +
"\r\u0005/help intro ");
inputSink.write("\u0003/help /set \011");
waitOutput(out, ".*format.*truncation.*\n\n" + Pattern.quote(getResource("jshell.console.see.synopsis")) + "\n" +
"\r\u0005/help /set ");
inputSink.write("\011");
waitOutput(out, ".*\n/set format\n" + Pattern.quote(getResource("help.set.format.summary")) +
"\n.*\n/set truncation\n" + Pattern.quote(getResource("help.set.truncation.summary")) +
".*\n\n" + Pattern.quote(getResource("jshell.console.see.full.documentation")) + "\n" +
"\r\u0005/help /set ");
inputSink.write("truncation\011");
waitOutput(out, ".*truncation\n" + Pattern.quote(getResource("jshell.console.see.synopsis")) + "\n" +
"\r\u0005/help /set truncation");
inputSink.write("\011");
waitOutput(out, ".*/set truncation\n" + Pattern.quote(getResource("help.set.truncation.summary")) + "\n" +
"\n" + Pattern.quote(getResource("jshell.console.see.full.documentation")) + "\n" +
"\r\u0005/help /set truncation");
inputSink.write("\011");
waitOutput(out, ".*/set truncation\n" + Pattern.quote(getResource("help.set.truncation").replaceAll("\t", " ")) +
"\r\u0005/help /set truncation");
inputSink.write("\u0003/help env \011");
waitOutput(out, ".*\n/env\n" + Pattern.quote(getResource("help.env.summary")) +
".*\n\n" + Pattern.quote(getResource("jshell.console.see.full.documentation")) + "\n" +
"\r\u0005/help env ");
inputSink.write("\u0003/help set truncation\011");
waitOutput(out, ".*truncation\n" + Pattern.quote(getResource("jshell.console.see.synopsis")) + "\n" +
"\r\u0005/help set truncation");
inputSink.write("\011");
waitOutput(out, ".*\n/set truncation\n" + Pattern.quote(getResource("help.set.truncation.summary")) +
".*\n\n" + Pattern.quote(getResource("jshell.console.see.full.documentation")) + "\n" +
"\r\u0005/help set truncation");
inputSink.write(TAB);
waitOutput(out, ".*\nintro\n" + resource("help.intro.summary") +
".*\n\n" + resource("jshell.console.see.full.documentation") +
REDRAW_PROMPT + "/help intro ");
inputSink.write(TAB);
waitOutput(out, ".*\nintro\n" + resource("help.intro") +
REDRAW_PROMPT + "/help intro ");
inputSink.write(INTERRUPT + "/help /set " + TAB);
waitOutput(out, ".*format.*truncation.*\n\n" + resource("jshell.console.see.synopsis") +
REDRAW_PROMPT + "/help /set ");
inputSink.write(TAB);
waitOutput(out, ".*\n/set format\n" + resource("help.set.format.summary") +
"\n.*\n/set truncation\n" + resource("help.set.truncation.summary") +
".*\n\n" + resource("jshell.console.see.full.documentation") +
REDRAW_PROMPT + "/help /set ");
inputSink.write("truncation" + TAB);
waitOutput(out, ".*truncation\n" + resource("jshell.console.see.synopsis") +
REDRAW_PROMPT + "/help /set truncation");
inputSink.write(TAB);
waitOutput(out, ".*/set truncation\n" + resource("help.set.truncation.summary") + "\n" +
"\n" + resource("jshell.console.see.full.documentation") +
REDRAW_PROMPT + "/help /set truncation");
inputSink.write(TAB);
waitOutput(out, ".*/set truncation\n" + resource("help.set.truncation") +
"\r" + PROMPT + "/help /set truncation");
inputSink.write(INTERRUPT + "/help env " + TAB);
waitOutput(out, ".*\n/env\n" + resource("help.env.summary") +
".*\n\n" + resource("jshell.console.see.full.documentation") +
REDRAW_PROMPT + "/help env ");
inputSink.write(INTERRUPT + "/help set truncation" + TAB);
waitOutput(out, ".*truncation\n" + resource("jshell.console.see.synopsis") +
REDRAW_PROMPT + "/help set truncation");
inputSink.write(TAB);
waitOutput(out, ".*\n/set truncation\n" + resource("help.set.truncation.summary") +
".*\n\n" + resource("jshell.console.see.full.documentation") +
REDRAW_PROMPT + "/help set truncation");
});
}
}

View File

@ -46,7 +46,6 @@ import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.regex.Pattern;
import jdk.internal.jshell.tool.ConsoleIOContextTestSupport;
import org.testng.annotations.Test;
@ -58,143 +57,148 @@ public class ToolTabSnippetTest extends UITesting {
Path classes = prepareZip();
doRunTest((inputSink, out) -> {
inputSink.write("/env -class-path " + classes.toString() + "\n");
waitOutput(out, Pattern.quote(getResource("jshell.msg.set.restore")) + "\n\u0005");
waitOutput(out, resource("jshell.msg.set.restore") + "\n\u0005");
inputSink.write("import jshelltest.*;\n");
waitOutput(out, "\n\u0005");
//-> <tab>
inputSink.write("\011");
inputSink.write(TAB);
waitOutput(out, getMessage("jshell.console.completion.all.completions.number", "[0-9]+"));
inputSink.write("\011");
waitOutput(out, ".*String.*StringBuilder.*\n\r\u0005");
inputSink.write(TAB);
waitOutput(out, ".*String.*StringBuilder.*" +
REDRAW_PROMPT + "");
//new JShellTes<tab>
inputSink.write("new JShellTes\011");
waitOutput(out, "t\nJShellTest\\( JShellTestAux\\( \n\r\u0005new JShellTest");
inputSink.write("new JShellTes" + TAB);
waitOutput(out, "t\nJShellTest\\( JShellTestAux\\( " +
REDRAW_PROMPT + "new JShellTest");
//new JShellTest<tab>
inputSink.write("\011");
inputSink.write(TAB);
waitOutput(out, "JShellTest\\( JShellTestAux\\( \n" +
"\n" +
Pattern.quote(getResource("jshell.console.completion.current.signatures")) + "\n" +
resource("jshell.console.completion.current.signatures") + "\n" +
"jshelltest.JShellTest\n" +
"\n" +
Pattern.quote(getResource("jshell.console.see.documentation")) + "\n" +
"\r\u0005new JShellTest");
inputSink.write("\011");
resource("jshell.console.see.documentation") +
REDRAW_PROMPT + "new JShellTest");
inputSink.write(TAB);
waitOutput(out, "jshelltest.JShellTest\n" +
"JShellTest 0\n" +
"\r\u0005new JShellTest");
inputSink.write("\011");
"JShellTest 0" +
REDRAW_PROMPT + "new JShellTest");
inputSink.write(TAB);
waitOutput(out, "JShellTest\\( JShellTestAux\\( \n" +
"\n" +
Pattern.quote(getResource("jshell.console.completion.current.signatures")) + "\n" +
resource("jshell.console.completion.current.signatures") + "\n" +
"jshelltest.JShellTest\n" +
"\n" +
Pattern.quote(getResource("jshell.console.see.documentation")) + "\n" +
"\r\u0005new JShellTest");
resource("jshell.console.see.documentation") +
REDRAW_PROMPT + "new JShellTest");
//new JShellTest(<tab>
inputSink.write("(\011");
inputSink.write("(" + TAB);
waitOutput(out, "\\(\n" +
Pattern.quote(getResource("jshell.console.completion.current.signatures")) + "\n" +
resource("jshell.console.completion.current.signatures") + "\n" +
"JShellTest\\(String str\\)\n" +
"JShellTest\\(String str, int i\\)\n" +
"\n" +
Pattern.quote(getResource("jshell.console.see.documentation")) + "\n" +
"\r\u0005new JShellTest\\(");
inputSink.write("\011");
resource("jshell.console.see.documentation") +
REDRAW_PROMPT + "new JShellTest\\(");
inputSink.write(TAB);
waitOutput(out, "JShellTest\\(String str\\)\n" +
"JShellTest 1\n" +
"1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n" +
"\n" +
Pattern.quote(getResource("jshell.console.see.next.page")) + "\n" +
"\r\u0005new JShellTest\\(");
inputSink.write("\011");
resource("jshell.console.see.next.page") +
REDRAW_PROMPT + "new JShellTest\\(");
inputSink.write(TAB);
waitOutput(out, "1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n" +
"\n" +
Pattern.quote(getResource("jshell.console.see.next.javadoc")) + "\n" +
"\r\u0005new JShellTest\\(");
inputSink.write("\011");
resource("jshell.console.see.next.javadoc") +
REDRAW_PROMPT + "new JShellTest\\(");
inputSink.write(TAB);
waitOutput(out, "JShellTest\\(String str, int i\\)\n" +
"JShellTest 2\n" +
"\n" +
getMessage("jshell.console.completion.all.completions.number", "[0-9]+") + "\n" +
"\r\u0005new JShellTest\\(");
inputSink.write("\011");
waitOutput(out, ".*String.*StringBuilder.*\n\r\u0005new JShellTest\\(");
getMessage("jshell.console.completion.all.completions.number", "[0-9]+") +
REDRAW_PROMPT + "new JShellTest\\(");
inputSink.write(TAB);
waitOutput(out, ".*String.*StringBuilder.*" +
REDRAW_PROMPT + "new JShellTest\\(");
inputSink.write("\u0003String str = \"\";\nnew JShellTest(");
waitOutput(out, "\u0005new JShellTest\\(");
inputSink.write(INTERRUPT + "String str = \"\";\nnew JShellTest(");
waitOutput(out, PROMPT + "new JShellTest\\(");
inputSink.write("\011");
inputSink.write(TAB);
waitOutput(out, "\n" +
"str \n" +
"\n" +
Pattern.quote(getResource("jshell.console.completion.current.signatures")) + "\n" +
resource("jshell.console.completion.current.signatures") + "\n" +
"JShellTest\\(String str\\)\n" +
"JShellTest\\(String str, int i\\)\n" +
"\n" +
Pattern.quote(getResource("jshell.console.see.documentation")) + "\n" +
"\r\u0005new JShellTest\\(");
inputSink.write("\011");
resource("jshell.console.see.documentation") +
REDRAW_PROMPT + "new JShellTest\\(");
inputSink.write(TAB);
waitOutput(out, "JShellTest\\(String str\\)\n" +
"JShellTest 1\n" +
"1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n" +
"\n" +
Pattern.quote(getResource("jshell.console.see.next.page")) + "\n" +
"\r\u0005new JShellTest\\(");
inputSink.write("\011");
resource("jshell.console.see.next.page") +
REDRAW_PROMPT + "new JShellTest\\(");
inputSink.write(TAB);
waitOutput(out, "1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n" +
"\n" +
Pattern.quote(getResource("jshell.console.see.next.javadoc")) + "\n" +
"\r\u0005new JShellTest\\(");
inputSink.write("\011");
resource("jshell.console.see.next.javadoc") +
REDRAW_PROMPT + "new JShellTest\\(");
inputSink.write(TAB);
waitOutput(out, "JShellTest\\(String str, int i\\)\n" +
"JShellTest 2\n" +
"\n" +
getMessage("jshell.console.completion.all.completions.number", "[0-9]+") + "\n" +
"\r\u0005new JShellTest\\(");
inputSink.write("\011");
waitOutput(out, ".*String.*StringBuilder.*\n\r\u0005new JShellTest\\(");
getMessage("jshell.console.completion.all.completions.number", "[0-9]+") +
REDRAW_PROMPT + "new JShellTest\\(");
inputSink.write(TAB);
waitOutput(out, ".*String.*StringBuilder.*" +
REDRAW_PROMPT + "new JShellTest\\(");
inputSink.write("\u0003JShellTest t = new JShellTest\011");
waitOutput(out, "\u0005JShellTest t = new JShellTest\n" +
inputSink.write(INTERRUPT + "JShellTest t = new JShellTest" + TAB);
waitOutput(out, PROMPT + "JShellTest t = new JShellTest\n" +
"JShellTest\\( \n" +
"\n" +
Pattern.quote(getResource("jshell.console.completion.current.signatures")) + "\n" +
resource("jshell.console.completion.current.signatures") + "\n" +
"jshelltest.JShellTest\n" +
"\n" +
Pattern.quote(getResource("jshell.console.completion.all.completions")) + "\n" +
"\r\u0005JShellTest t = new JShellTest");
inputSink.write("\011");
resource("jshell.console.completion.all.completions") +
REDRAW_PROMPT + "JShellTest t = new JShellTest");
inputSink.write(TAB);
waitOutput(out, "JShellTest\\( JShellTestAux\\( \n" +
"\n" +
Pattern.quote(getResource("jshell.console.see.documentation")) + "\n" +
"\r\u0005JShellTest t = new JShellTest");
resource("jshell.console.see.documentation") +
REDRAW_PROMPT + "JShellTest t = new JShellTest");
inputSink.write("\u0003JShellTest t = new \011");
waitOutput(out, "\u0005JShellTest t = new \n" +
inputSink.write(INTERRUPT + "JShellTest t = new " + TAB);
waitOutput(out, PROMPT + "JShellTest t = new \n" +
"JShellTest\\( \n" +
"\n" +
getMessage("jshell.console.completion.all.completions.number", "[0-9]+") + "\n" +
"\r\u0005JShellTest t = new ");
inputSink.write("\011");
waitOutput(out, ".*String.*StringBuilder.*\n\r\u0005JShellTest t = new ");
getMessage("jshell.console.completion.all.completions.number", "[0-9]+") +
REDRAW_PROMPT + "JShellTest t = new ");
inputSink.write(TAB);
waitOutput(out, ".*String.*StringBuilder.*" +
REDRAW_PROMPT + "JShellTest t = new ");
inputSink.write("\u0003class JShelX{}\n");
inputSink.write("new JShel\011");
waitOutput(out, "\u0005new JShel\n" +
"JShelX\\(\\) JShellTest\\( JShellTestAux\\( \n" +
"\r\u0005new JShel");
inputSink.write(INTERRUPT + "class JShelX{}\n");
inputSink.write("new JShel" + TAB);
waitOutput(out, PROMPT + "new JShel\n" +
"JShelX\\(\\) JShellTest\\( JShellTestAux\\( " +
REDRAW_PROMPT + "new JShel");
//no crash:
inputSink.write("\u0003new Stringbuil\011");
waitOutput(out, "\u0005new Stringbuil\u0007");
inputSink.write(INTERRUPT + "new Stringbuil" + TAB);
waitOutput(out, PROMPT + "new Stringbuil" + BELL);
//no crash: 8188072
inputSink.write("\u0003for (int:\011");
waitOutput(out, "\u0005for \\(int:\u0007");
inputSink.write(INTERRUPT + "for (int:" + TAB);
waitOutput(out, PROMPT + "for \\(int:" + BELL);
});
}
@ -218,15 +222,15 @@ public class ToolTabSnippetTest extends UITesting {
}
};
//-> <tab>
inputSink.write("\011");
inputSink.write(TAB);
testCompleteComputationStarted.await();
//-> <tab><tab>
inputSink.write("\011\011");
inputSink.write(TAB + TAB);
testCompleteComputationContinue.countDown();
waitOutput(out, "\u0005");
waitOutput(out, PROMPT);
//-> <tab>
inputSink.write("\011");
waitOutput(out, "\u0005");
inputSink.write(TAB);
waitOutput(out, PROMPT);
ConsoleIOContextTestSupport.IMPL = null;
});
}
@ -234,24 +238,24 @@ public class ToolTabSnippetTest extends UITesting {
public void testNoRepeat() throws Exception {
doRunTest((inputSink, out) -> {
inputSink.write("String xyzAA;\n");
waitOutput(out, "\u0005");
waitOutput(out, PROMPT);
//xyz<tab>
inputSink.write("String s = xyz\011");
inputSink.write("String s = xyz" + TAB);
waitOutput(out, "^String s = xyzAA");
inputSink.write(".");
waitOutput(out, "^\\.");
inputSink.write("\u0003");
waitOutput(out, "\u0005");
inputSink.write(INTERRUPT);
waitOutput(out, PROMPT);
inputSink.write("double xyzAB;\n");
waitOutput(out, "\u0005");
waitOutput(out, PROMPT);
//xyz<tab>
inputSink.write("String s = xyz\011");
inputSink.write("String s = xyz" + TAB);
String allCompletions =
Pattern.quote(getResource("jshell.console.completion.all.completions"));
resource("jshell.console.completion.all.completions");
waitOutput(out, ".*xyzAA.*" + allCompletions + ".*\u0005String s = xyzA");
});
}

View File

@ -41,6 +41,11 @@ import jdk.jshell.tool.JavaShellToolBuilder;
public class UITesting {
protected static final String TAB = "\011";
protected static final String INTERRUPT = "\u0003";
protected static final String BELL = "\u0007";
protected static final String PROMPT = "\u0005";
protected static final String REDRAW_PROMPT = "\n\r" + PROMPT;
private final boolean laxLineEndings;
public UITesting() {
@ -100,10 +105,10 @@ public class UITesting {
runner.start();
try {
waitOutput(out, "\u0005");
waitOutput(out, PROMPT);
test.test(inputSink, out);
} finally {
inputSink.write("\003\003/exit");
inputSink.write(INTERRUPT + INTERRUPT + "/exit");
runner.join(1000);
if (runner.isAlive()) {
@ -198,6 +203,10 @@ public class UITesting {
return resources.getString(key);
}
protected String resource(String key) {
return Pattern.quote(getResource(key).replaceAll("\t", " "));
}
protected String getMessage(String key, Object... args) {
return MessageFormat.format(resources.getString(key), args);
}