1/* 2 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24/* 25 * @test 26 * @bug 8143037 8142447 8144095 8140265 8144906 8146138 8147887 8147886 8148316 8148317 8143955 8157953 8080347 8154714 8166649 8167643 8170162 8172102 8165405 8174796 8174797 8175304 27 * @summary Tests for Basic tests for REPL tool 28 * @modules jdk.compiler/com.sun.tools.javac.api 29 * jdk.compiler/com.sun.tools.javac.main 30 * jdk.jdeps/com.sun.tools.javap 31 * jdk.jshell/jdk.internal.jshell.tool 32 * @library /tools/lib 33 * @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask 34 * @build KullaTesting TestingInputStream Compiler 35 * @run testng/timeout=600 ToolBasicTest 36 */ 37 38import java.io.File; 39import java.io.IOException; 40import java.io.PrintWriter; 41import java.io.StringWriter; 42import java.nio.file.Files; 43import java.nio.file.Path; 44import java.nio.file.Paths; 45import java.util.ArrayList; 46import java.util.Arrays; 47import java.util.List; 48import java.util.Locale; 49import java.util.Scanner; 50import java.util.function.BiFunction; 51import java.util.function.Consumer; 52import java.util.function.Function; 53import java.util.stream.Collectors; 54import java.util.stream.Stream; 55 56import org.testng.annotations.Test; 57 58import static org.testng.Assert.assertEquals; 59import static org.testng.Assert.assertTrue; 60import static org.testng.Assert.fail; 61 62@Test 63public class ToolBasicTest extends ReplToolTesting { 64 65 public void elideStartUpFromList() { 66 test( 67 (a) -> assertCommandOutputContains(a, "123", "==> 123"), 68 (a) -> assertCommandCheckOutput(a, "/list", (s) -> { 69 int cnt; 70 try (Scanner scanner = new Scanner(s)) { 71 cnt = 0; 72 while (scanner.hasNextLine()) { 73 String line = scanner.nextLine(); 74 if (!line.trim().isEmpty()) { 75 ++cnt; 76 } 77 } 78 } 79 assertEquals(cnt, 1, "Expected only one listed line"); 80 }) 81 ); 82 } 83 84 public void elideStartUpFromSave() throws IOException { 85 Compiler compiler = new Compiler(); 86 Path path = compiler.getPath("myfile"); 87 test( 88 (a) -> assertCommandOutputContains(a, "123", "==> 123"), 89 (a) -> assertCommand(a, "/save " + path.toString(), "") 90 ); 91 try (Stream<String> lines = Files.lines(path)) { 92 assertEquals(lines.count(), 1, "Expected only one saved line"); 93 } 94 } 95 96 public void testInterrupt() { 97 ReplTest interrupt = (a) -> assertCommand(a, "\u0003", ""); 98 for (String s : new String[] { "", "\u0003" }) { 99 test(false, new String[]{"--no-startup"}, 100 (a) -> assertCommand(a, "int a = 2 +" + s, ""), 101 interrupt, 102 (a) -> assertCommand(a, "int a\u0003", ""), 103 (a) -> assertCommand(a, "int a = 2 + 2\u0003", ""), 104 (a) -> assertCommandCheckOutput(a, "/vars", assertVariables()), 105 (a) -> evaluateExpression(a, "int", "2", "2"), 106 (a) -> assertCommandCheckOutput(a, "/vars", assertVariables()), 107 (a) -> assertCommand(a, "void f() {", ""), 108 (a) -> assertCommand(a, "int q = 10;" + s, ""), 109 interrupt, 110 (a) -> assertCommand(a, "void f() {}\u0003", ""), 111 (a) -> assertCommandCheckOutput(a, "/methods", assertMethods()), 112 (a) -> assertMethod(a, "int f() { return 0; }", "()int", "f"), 113 (a) -> assertCommandCheckOutput(a, "/methods", assertMethods()), 114 (a) -> assertCommand(a, "class A {" + s, ""), 115 interrupt, 116 (a) -> assertCommand(a, "class A {}\u0003", ""), 117 (a) -> assertCommandCheckOutput(a, "/types", assertClasses()), 118 (a) -> assertClass(a, "interface A {}", "interface", "A"), 119 (a) -> assertCommandCheckOutput(a, "/types", assertClasses()), 120 (a) -> assertCommand(a, "import java.util.stream." + s, ""), 121 interrupt, 122 (a) -> assertCommand(a, "import java.util.stream.\u0003", ""), 123 (a) -> assertCommandCheckOutput(a, "/imports", assertImports()), 124 (a) -> assertImport(a, "import java.util.stream.Stream", "", "java.util.stream.Stream"), 125 (a) -> assertCommandCheckOutput(a, "/imports", assertImports()) 126 ); 127 } 128 } 129 130 private final Object lock = new Object(); 131 private PrintWriter out; 132 private boolean isStopped; 133 private Thread t; 134 private void assertStop(boolean after, String cmd, String output) { 135 if (!after) { 136 isStopped = false; 137 StringWriter writer = new StringWriter(); 138 out = new PrintWriter(writer); 139 setCommandInput(cmd + "\n"); 140 t = new Thread(() -> { 141 try { 142 // no chance to know whether cmd is being evaluated 143 Thread.sleep(5000); 144 } catch (InterruptedException ignored) { 145 } 146 int i = 1; 147 int n = 30; 148 synchronized (lock) { 149 do { 150 setCommandInput("\u0003"); 151 if (!isStopped) { 152 out.println("Not stopped. Try again: " + i); 153 try { 154 lock.wait(1000); 155 } catch (InterruptedException ignored) { 156 } 157 } 158 } while (i++ < n && !isStopped); 159 if (!isStopped) { 160 System.err.println(writer.toString()); 161 fail("Evaluation was not stopped: '" + cmd + "'"); 162 } 163 } 164 }); 165 t.start(); 166 } else { 167 synchronized (lock) { 168 out.println("Evaluation was stopped successfully: '" + cmd + "'"); 169 isStopped = true; 170 lock.notify(); 171 } 172 try { 173 t.join(); 174 t = null; 175 } catch (InterruptedException ignored) { 176 } 177 assertOutput(getCommandOutput(), "", "command"); 178 assertOutput(getCommandErrorOutput(), "", "command error"); 179 assertOutput(getUserOutput().trim(), output, "user"); 180 assertOutput(getUserErrorOutput(), "", "user error"); 181 } 182 } 183 184 public void testStop() { 185 test( 186 (a) -> assertStop(a, "while (true) {}", ""), 187 (a) -> assertStop(a, "while (true) { try { Thread.sleep(100); } catch (InterruptedException ex) { } }", "") 188 ); 189 } 190 191 public void testRerun() { 192 test(false, new String[] {"--no-startup"}, 193 (a) -> assertCommand(a, "/0", "| No such command or snippet id: /0\n| Type /help for help."), 194 (a) -> assertCommand(a, "/5", "| No such command or snippet id: /5\n| Type /help for help.") 195 ); 196 String[] codes = new String[] { 197 "int a = 0;", // var 198 "class A {}", // class 199 "void f() {}", // method 200 "bool b;", // active failed 201 "void g() { h(); }", // active corralled 202 }; 203 List<ReplTest> tests = new ArrayList<>(); 204 for (String s : codes) { 205 tests.add((a) -> assertCommand(a, s, null)); 206 } 207 // Test /1 through /5 -- assure references are correct 208 for (int i = 0; i < codes.length; ++i) { 209 final int finalI = i; 210 Consumer<String> check = (s) -> { 211 String[] ss = s.split("\n"); 212 assertEquals(ss[0], codes[finalI]); 213 assertTrue(ss.length > 1, s); 214 }; 215 tests.add((a) -> assertCommandCheckOutput(a, "/" + (finalI + 1), check)); 216 } 217 // Test /-1 ... note that the snippets added by history must be stepped over 218 for (int i = 0; i < codes.length; ++i) { 219 final int finalI = i; 220 Consumer<String> check = (s) -> { 221 String[] ss = s.split("\n"); 222 assertEquals(ss[0], codes[codes.length - finalI - 1]); 223 assertTrue(ss.length > 1, s); 224 }; 225 tests.add((a) -> assertCommandCheckOutput(a, "/-" + (2 * finalI + 1), check)); 226 } 227 tests.add((a) -> assertCommandCheckOutput(a, "/!", assertStartsWith("int a = 0;"))); 228 test(false, new String[]{"--no-startup"}, 229 tests.toArray(new ReplTest[tests.size()])); 230 } 231 232 public void test8142447() { 233 Function<String, BiFunction<String, Integer, ReplTest>> assertRerun = cmd -> (code, assertionCount) -> 234 (a) -> assertCommandCheckOutput(a, cmd, s -> { 235 String[] ss = s.split("\n"); 236 assertEquals(ss[0], code); 237 loadVariable(a, "int", "assertionCount", Integer.toString(assertionCount), Integer.toString(assertionCount)); 238 }); 239 ReplTest assertVariables = (a) -> assertCommandCheckOutput(a, "/v", assertVariables()); 240 241 Compiler compiler = new Compiler(); 242 Path startup = compiler.getPath("StartupFileOption/startup.txt"); 243 compiler.writeToFile(startup, "int assertionCount = 0;\n" + // id: s1 244 "void add(int n) { assertionCount += n; }"); 245 test(new String[]{"--startup", startup.toString()}, 246 (a) -> assertCommand(a, "add(1)", ""), // id: 1 247 (a) -> assertCommandCheckOutput(a, "add(ONE)", s -> assertEquals(s.split("\n")[0], "| Error:")), // id: e1 248 (a) -> assertVariable(a, "int", "ONE", "1", "1"), 249 assertRerun.apply("/1").apply("add(1)", 2), assertVariables, 250 assertRerun.apply("/e1").apply("add(ONE)", 3), assertVariables, 251 assertRerun.apply("/s1").apply("int assertionCount = 0;", 0), assertVariables 252 ); 253 254 test(false, new String[] {"--no-startup"}, 255 (a) -> assertCommand(a, "/s1", "| No such command or snippet id: /s1\n| Type /help for help."), 256 (a) -> assertCommand(a, "/1", "| No such command or snippet id: /1\n| Type /help for help."), 257 (a) -> assertCommand(a, "/e1", "| No such command or snippet id: /e1\n| Type /help for help.") 258 ); 259 } 260 261 public void testClasspathDirectory() { 262 Compiler compiler = new Compiler(); 263 Path outDir = Paths.get("testClasspathDirectory"); 264 compiler.compile(outDir, "package pkg; public class A { public String toString() { return \"A\"; } }"); 265 Path classpath = compiler.getPath(outDir); 266 test( 267 (a) -> assertCommand(a, "/env --class-path " + classpath, 268 "| Setting new options and restoring state."), 269 (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "A") 270 ); 271 test(new String[] { "--class-path", classpath.toString() }, 272 (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "A") 273 ); 274 } 275 276 public void testEnvInStartUp() { 277 Compiler compiler = new Compiler(); 278 Path outDir = Paths.get("testClasspathDirectory"); 279 compiler.compile(outDir, "package pkg; public class A { public String toString() { return \"A\"; } }"); 280 Path classpath = compiler.getPath(outDir); 281 Path sup = compiler.getPath("startup.jsh"); 282 compiler.writeToFile(sup, 283 "int xxx;\n" + 284 "/env -class-path " + classpath + "\n" + 285 "int aaa = 735;\n" 286 ); 287 test( 288 (a) -> assertCommand(a, "/set start -retain " + sup, ""), 289 (a) -> assertCommand(a, "/reset", 290 "| Resetting state."), 291 (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "A"), 292 (a) -> assertCommand(a, "aaa", "aaa ==> 735") 293 ); 294 test( 295 (a) -> assertCommandOutputContains(a, "/env", "--class-path"), 296 (a) -> assertCommandOutputContains(a, "xxx", "cannot find symbol", "variable xxx"), 297 (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "A"), 298 (a) -> assertCommand(a, "aaa", "aaa ==> 735") 299 ); 300 } 301 302 private String makeSimpleJar() { 303 Compiler compiler = new Compiler(); 304 Path outDir = Paths.get("testClasspathJar"); 305 compiler.compile(outDir, "package pkg; public class A { public String toString() { return \"A\"; } }"); 306 String jarName = "test.jar"; 307 compiler.jar(outDir, jarName, "pkg/A.class"); 308 return compiler.getPath(outDir).resolve(jarName).toString(); 309 } 310 311 public void testClasspathJar() { 312 String jarPath = makeSimpleJar(); 313 test( 314 (a) -> assertCommand(a, "/env --class-path " + jarPath, 315 "| Setting new options and restoring state."), 316 (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "A") 317 ); 318 test(new String[] { "--class-path", jarPath }, 319 (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "A") 320 ); 321 } 322 323 public void testClasspathUserHomeExpansion() { 324 String jarPath = makeSimpleJar(); 325 String tilde = "~" + File.separator; 326 test( 327 (a) -> assertCommand(a, "/env --class-path " + tilde + "forblato", 328 "| File '" + System.getProperty("user.home") + File.separator 329 + "forblato' for '--class-path' is not found."), 330 (a) -> assertCommand(a, "/env --class-path " + jarPath + File.pathSeparator 331 + tilde + "forblato", 332 "| File '" + System.getProperty("user.home") + File.separator 333 + "forblato' for '--class-path' is not found.") 334 ); 335 } 336 337 public void testBadClasspath() { 338 String jarPath = makeSimpleJar(); 339 Compiler compiler = new Compiler(); 340 Path t1 = compiler.getPath("whatever/thing.zip"); 341 compiler.writeToFile(t1, ""); 342 Path t2 = compiler.getPath("whatever/thing.jmod"); 343 compiler.writeToFile(t2, ""); 344 test( 345 (a) -> assertCommand(a, "/env --class-path " + t1.toString(), 346 "| Invalid '--class-path' argument: " + t1.toString()), 347 (a) -> assertCommand(a, "/env --class-path " + jarPath + File.pathSeparator + t1.toString(), 348 "| Invalid '--class-path' argument: " + t1.toString()), 349 (a) -> assertCommand(a, "/env --class-path " + t2.toString(), 350 "| Invalid '--class-path' argument: " + t2.toString()) 351 ); 352 } 353 354 public void testModulePath() { 355 Compiler compiler = new Compiler(); 356 Path modsDir = Paths.get("mods"); 357 Path outDir = Paths.get("mods", "org.astro"); 358 compiler.compile(outDir, "package org.astro; public class World { public static String name() { return \"world\"; } }"); 359 compiler.compile(outDir, "module org.astro { exports org.astro; }"); 360 Path modsPath = compiler.getPath(modsDir); 361 test(new String[] { "--module-path", modsPath.toString(), "--add-modules", "org.astro" }, 362 (a) -> assertCommand(a, "import org.astro.World;", ""), 363 (a) -> evaluateExpression(a, "String", 364 "String.format(\"Greetings %s!\", World.name());", 365 "\"Greetings world!\"") 366 ); 367 } 368 369 public void testModulePathUserHomeExpansion() { 370 String tilde = "~" + File.separatorChar; 371 test( 372 (a) -> assertCommand(a, "/env --module-path " + tilde + "snardugol", 373 "| File '" + System.getProperty("user.home") 374 + File.separatorChar + "snardugol' for '--module-path' is not found.") 375 ); 376 } 377 378 public void testBadModulePath() { 379 Compiler compiler = new Compiler(); 380 Path t1 = compiler.getPath("whatever/thing.zip"); 381 compiler.writeToFile(t1, ""); 382 test( 383 (a) -> assertCommand(a, "/env --module-path " + t1.toString(), 384 "| Invalid '--module-path' argument: " + t1.toString()) 385 ); 386 } 387 388 public void testStartupFileOption() { 389 Compiler compiler = new Compiler(); 390 Path startup = compiler.getPath("StartupFileOption/startup.txt"); 391 compiler.writeToFile(startup, "class A { public String toString() { return \"A\"; } }"); 392 test(new String[]{"--startup", startup.toString()}, 393 (a) -> evaluateExpression(a, "A", "new A()", "A") 394 ); 395 test(new String[]{"--no-startup"}, 396 (a) -> assertCommandCheckOutput(a, "Pattern.compile(\"x+\")", assertStartsWith("| Error:\n| cannot find symbol")) 397 ); 398 test( 399 (a) -> assertCommand(a, "Pattern.compile(\"x+\")", "$1 ==> x+", "", null, "", "") 400 ); 401 } 402 403 public void testLoadingFromArgs() { 404 Compiler compiler = new Compiler(); 405 Path path = compiler.getPath("loading.repl"); 406 compiler.writeToFile(path, "int a = 10; double x = 20; double a = 10;"); 407 test(new String[] { path.toString() }, 408 (a) -> assertCommand(a, "x", "x ==> 20.0"), 409 (a) -> assertCommand(a, "a", "a ==> 10.0") 410 ); 411 Path unknown = compiler.getPath("UNKNOWN.jar"); 412 test(Locale.ROOT, true, new String[]{unknown.toString()}, 413 "| File '" + unknown 414 + "' for 'jshell' is not found."); 415 } 416 417 public void testReset() { 418 test( 419 (a) -> assertReset(a, "/res"), 420 (a) -> assertCommandCheckOutput(a, "/methods", assertMethods()), 421 (a) -> assertVariable(a, "int", "x"), 422 (a) -> assertCommandCheckOutput(a, "/vars", assertVariables()), 423 (a) -> assertMethod(a, "void f() { }", "()void", "f"), 424 (a) -> assertCommandCheckOutput(a, "/methods", assertMethods()), 425 (a) -> assertClass(a, "class A { }", "class", "A"), 426 (a) -> assertCommandCheckOutput(a, "/types", assertClasses()), 427 (a) -> assertImport(a, "import java.util.stream.*;", "", "java.util.stream.*"), 428 (a) -> assertCommandCheckOutput(a, "/imports", assertImports()), 429 (a) -> assertReset(a, "/reset"), 430 (a) -> assertCommandCheckOutput(a, "/vars", assertVariables()), 431 (a) -> assertCommandCheckOutput(a, "/methods", assertMethods()), 432 (a) -> assertCommandCheckOutput(a, "/types", assertClasses()), 433 (a) -> assertCommandCheckOutput(a, "/imports", assertImports()) 434 ); 435 } 436 437 public void testOpen() { 438 Compiler compiler = new Compiler(); 439 Path path = compiler.getPath("testOpen.repl"); 440 compiler.writeToFile(path, 441 "int a = 10;\ndouble x = 20;\ndouble a = 10;\n" + 442 "class A { public String toString() { return \"A\"; } }\nimport java.util.stream.*;"); 443 for (String s : new String[]{"/o", "/open"}) { 444 test( 445 (a) -> assertCommand(a, s + " " + path.toString(), ""), 446 (a) -> assertCommand(a, "a", "a ==> 10.0"), 447 (a) -> evaluateExpression(a, "A", "new A();", "A"), 448 (a) -> evaluateExpression(a, "long", "Stream.of(\"A\").count();", "1"), 449 (a) -> { 450 loadVariable(a, "double", "x", "20.0", "20.0"); 451 loadVariable(a, "double", "a", "10.0", "10.0"); 452 loadVariable(a, "A", "$7", "new A();", "A"); 453 loadVariable(a, "long", "$8", "Stream.of(\"A\").count();", "1"); 454 loadClass(a, "class A { public String toString() { return \"A\"; } }", 455 "class", "A"); 456 loadImport(a, "import java.util.stream.*;", "", "java.util.stream.*"); 457 assertCommandCheckOutput(a, "/types", assertClasses()); 458 }, 459 (a) -> assertCommandCheckOutput(a, "/methods", assertMethods()), 460 (a) -> assertCommandCheckOutput(a, "/vars", assertVariables()), 461 (a) -> assertCommandCheckOutput(a, "/imports", assertImports()) 462 ); 463 Path unknown = compiler.getPath("UNKNOWN.repl"); 464 test( 465 (a) -> assertCommand(a, s + " " + unknown, 466 "| File '" + unknown + "' for '/open' is not found.") 467 ); 468 } 469 } 470 471 public void testOpenResource() { 472 test( 473 (a) -> assertCommand(a, "/open PRINTING", ""), 474 (a) -> assertCommandOutputContains(a, "/list", 475 "void println", "System.out.printf"), 476 (a) -> assertCommand(a, "printf(\"%4.2f\", Math.PI)", 477 "", "", null, "3.14", "") 478 ); 479 } 480 481 public void testSave() throws IOException { 482 Compiler compiler = new Compiler(); 483 Path path = compiler.getPath("testSave.repl"); 484 List<String> list = Arrays.asList( 485 "int a;", 486 "class A { public String toString() { return \"A\"; } }" 487 ); 488 test( 489 (a) -> assertVariable(a, "int", "a"), 490 (a) -> assertCommand(a, "()", null, null, null, "", ""), 491 (a) -> assertClass(a, "class A { public String toString() { return \"A\"; } }", "class", "A"), 492 (a) -> assertCommand(a, "/save " + path.toString(), "") 493 ); 494 assertEquals(Files.readAllLines(path), list); 495 { 496 List<String> output = new ArrayList<>(); 497 test( 498 (a) -> assertCommand(a, "int a;", null), 499 (a) -> assertCommand(a, "()", null, null, null, "", ""), 500 (a) -> assertClass(a, "class A { public String toString() { return \"A\"; } }", "class", "A"), 501 (a) -> assertCommandCheckOutput(a, "/list -all", (out) -> 502 output.addAll(Stream.of(out.split("\n")) 503 .filter(str -> !str.isEmpty()) 504 .map(str -> str.substring(str.indexOf(':') + 2)) 505 .filter(str -> !str.startsWith("/")) 506 .collect(Collectors.toList()))), 507 (a) -> assertCommand(a, "/save -all " + path.toString(), "") 508 ); 509 assertEquals(Files.readAllLines(path), output); 510 } 511 List<String> output = new ArrayList<>(); 512 test( 513 (a) -> assertVariable(a, "int", "a"), 514 (a) -> assertCommand(a, "()", null, null, null, "", ""), 515 (a) -> assertClass(a, "class A { public String toString() { return \"A\"; } }", "class", "A"), 516 (a) -> assertCommandCheckOutput(a, "/history", (out) -> 517 output.addAll(Stream.of(out.split("\n")) 518 .filter(str -> !str.isEmpty()) 519 .collect(Collectors.toList()))), 520 (a) -> assertCommand(a, "/save -history " + path.toString(), "") 521 ); 522 output.add("/save -history " + path.toString()); 523 assertEquals(Files.readAllLines(path), output); 524 } 525 526 public void testStartRetain() { 527 Compiler compiler = new Compiler(); 528 Path startUpFile = compiler.getPath("startUp.txt"); 529 test( 530 (a) -> assertVariable(a, "int", "a"), 531 (a) -> assertVariable(a, "double", "b", "10", "10.0"), 532 (a) -> assertMethod(a, "void f() {}", "()V", "f"), 533 (a) -> assertImport(a, "import java.util.stream.*;", "", "java.util.stream.*"), 534 (a) -> assertCommand(a, "/save " + startUpFile.toString(), null), 535 (a) -> assertCommand(a, "/set start -retain " + startUpFile.toString(), null) 536 ); 537 Path unknown = compiler.getPath("UNKNOWN"); 538 test( 539 (a) -> assertCommandOutputStartsWith(a, "/set start -retain " + unknown.toString(), 540 "| File '" + unknown + "' for '/set start' is not found.") 541 ); 542 test(false, new String[0], 543 (a) -> { 544 loadVariable(a, "int", "a"); 545 loadVariable(a, "double", "b", "10.0", "10.0"); 546 loadMethod(a, "void f() {}", "()void", "f"); 547 loadImport(a, "import java.util.stream.*;", "", "java.util.stream.*"); 548 assertCommandCheckOutput(a, "/types", assertClasses()); 549 }, 550 (a) -> assertCommandCheckOutput(a, "/vars", assertVariables()), 551 (a) -> assertCommandCheckOutput(a, "/methods", assertMethods()), 552 (a) -> assertCommandCheckOutput(a, "/imports", assertImports()) 553 ); 554 } 555 556 public void testStartSave() throws IOException { 557 Compiler compiler = new Compiler(); 558 Path startSave = compiler.getPath("startSave.txt"); 559 test(a -> assertCommand(a, "/save -start " + startSave.toString(), null)); 560 List<String> lines = Files.lines(startSave) 561 .filter(s -> !s.isEmpty()) 562 .collect(Collectors.toList()); 563 assertEquals(lines, START_UP); 564 } 565 566 public void testConstrainedUpdates() { 567 test( 568 a -> assertClass(a, "class XYZZY { }", "class", "XYZZY"), 569 a -> assertVariable(a, "XYZZY", "xyzzy"), 570 a -> assertCommandCheckOutput(a, "import java.util.stream.*", 571 (out) -> assertTrue(out.trim().isEmpty(), "Expected no output, got: " + out)) 572 ); 573 } 574 575 public void testRemoteExit() { 576 test( 577 a -> assertVariable(a, "int", "x"), 578 a -> assertCommandCheckOutput(a, "/vars", assertVariables()), 579 a -> assertCommandOutputContains(a, "System.exit(5);", "terminated"), 580 a -> assertCommandCheckOutput(a, "/vars", s -> 581 assertTrue(s.trim().isEmpty(), s)), 582 a -> assertMethod(a, "void f() { }", "()void", "f"), 583 a -> assertCommandCheckOutput(a, "/methods", assertMethods()) 584 ); 585 } 586 587 public void testFeedbackNegative() { 588 test(a -> assertCommandCheckOutput(a, "/set feedback aaaa", 589 assertStartsWith("| Does not match any current feedback mode"))); 590 } 591 592 public void testFeedbackSilent() { 593 for (String off : new String[]{"s", "silent"}) { 594 test( 595 a -> assertCommand(a, "/set feedback " + off, ""), 596 a -> assertCommand(a, "int a", ""), 597 a -> assertCommand(a, "void f() {}", ""), 598 a -> assertCommandCheckOutput(a, "aaaa", assertStartsWith("| Error:")), 599 a -> assertCommandCheckOutput(a, "static void f() {}", assertStartsWith("| Warning:")) 600 ); 601 } 602 } 603 604 public void testFeedbackNormal() { 605 Compiler compiler = new Compiler(); 606 Path testNormalFile = compiler.getPath("testConciseNormal"); 607 String[] sources = new String[] {"int a", "void f() {}", "class A {}", "a = 10"}; 608 String[] sources2 = new String[] {"int a //again", "void f() {int y = 4;}", "class A {} //again", "a = 10"}; 609 String[] output = new String[] { 610 "a ==> 0", 611 "| created method f()", 612 "| created class A", 613 "a ==> 10" 614 }; 615 compiler.writeToFile(testNormalFile, sources2); 616 for (String feedback : new String[]{"/set fe", "/set feedback"}) { 617 for (String feedbackState : new String[]{"n", "normal"}) { 618 test( 619 a -> assertCommand(a, feedback + " " + feedbackState, "| Feedback mode: normal"), 620 a -> assertCommand(a, sources[0], output[0]), 621 a -> assertCommand(a, sources[1], output[1]), 622 a -> assertCommand(a, sources[2], output[2]), 623 a -> assertCommand(a, sources[3], output[3]), 624 a -> assertCommand(a, "/o " + testNormalFile.toString(), "") 625 ); 626 } 627 } 628 } 629 630 public void testVarsWithNotActive() { 631 test( 632 a -> assertVariable(a, "Blath", "x"), 633 a -> assertCommandOutputContains(a, "/var -all", "(not-active)") 634 ); 635 } 636 637 public void testHistoryReference() { 638 test(false, new String[]{"--no-startup"}, 639 a -> assertCommand(a, "System.err.println(1)", "", "", null, "", "1\n"), 640 a -> assertCommand(a, "System.err.println(2)", "", "", null, "", "2\n"), 641 a -> assertCommand(a, "/-2", "System.err.println(1)", "", null, "", "1\n"), 642 a -> assertCommand(a, "/history", 643 "/debug 0\n" + 644 "System.err.println(1)\n" + 645 "System.err.println(2)\n" + 646 "System.err.println(1)\n" + 647 "/history\n"), 648 a -> assertCommand(a, "/-2", "System.err.println(2)", "", null, "", "2\n"), 649 a -> assertCommand(a, "/!", "System.err.println(2)", "", null, "", "2\n"), 650 a -> assertCommand(a, "/2", "System.err.println(2)", "", null, "", "2\n"), 651 a -> assertCommand(a, "/1", "System.err.println(1)", "", null, "", "1\n") 652 ); 653 } 654 655 @Test(enabled = false) // TODO 8158197 656 public void testHeadlessEditPad() { 657 String prevHeadless = System.getProperty("java.awt.headless"); 658 try { 659 System.setProperty("java.awt.headless", "true"); 660 test( 661 (a) -> assertCommandOutputStartsWith(a, "/edit printf", "| Cannot launch editor -- unexpected exception:") 662 ); 663 } finally { 664 System.setProperty("java.awt.headless", prevHeadless==null? "false" : prevHeadless); 665 } 666 } 667 668 public void testAddExports() { 669 test(false, new String[]{"--no-startup"}, 670 a -> assertCommandOutputStartsWith(a, "import jdk.internal.misc.VM;", "| Error:") 671 ); 672 test(false, new String[]{"--no-startup", 673 "-R--add-exports", "-Rjava.base/jdk.internal.misc=ALL-UNNAMED", 674 "-C--add-exports", "-Cjava.base/jdk.internal.misc=ALL-UNNAMED"}, 675 a -> assertImport(a, "import jdk.internal.misc.VM;", "", "jdk.internal.misc.VM"), 676 a -> assertCommand(a, "System.err.println(VM.isBooted())", "", "", null, "", "true\n") 677 ); 678 test(false, new String[]{"--no-startup", "--add-exports", "java.base/jdk.internal.misc"}, 679 a -> assertImport(a, "import jdk.internal.misc.VM;", "", "jdk.internal.misc.VM"), 680 a -> assertCommand(a, "System.err.println(VM.isBooted())", "", "", null, "", "true\n") 681 ); 682 } 683 684} 685