ToolSimpleTest.java revision 4167:9bd0f08b517a
1/* 2 * Copyright (c) 2016, 2017, 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 8153716 8143955 8151754 8150382 8153920 8156910 8131024 8160089 8153897 8167128 8154513 8170015 8170368 8172102 8172103 8165405 8173073 8173848 8174041 8173916 8174028 8174262 8174797 8177079 8180508 27 * @summary Simple jshell tool tests 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 * @build KullaTesting TestingInputStream 33 * @run testng ToolSimpleTest 34 */ 35import java.util.Arrays; 36import java.util.ArrayList; 37import java.util.List; 38import java.util.Locale; 39import java.util.function.Consumer; 40import java.util.regex.Pattern; 41import java.util.stream.Collectors; 42import java.util.stream.Stream; 43 44import org.testng.annotations.Test; 45 46import static org.testng.Assert.assertEquals; 47import static org.testng.Assert.assertTrue; 48 49public class ToolSimpleTest extends ReplToolTesting { 50 51 @Test 52 public void testRemaining() { 53 test( 54 (a) -> assertCommand(a, "int z; z =", "z ==> 0"), 55 (a) -> assertCommand(a, "5", "z ==> 5"), 56 (a) -> assertCommand(a, "/*nada*/; int q =", ""), 57 (a) -> assertCommand(a, "77", "q ==> 77"), 58 (a) -> assertCommand(a, "//comment;", ""), 59 (a) -> assertCommand(a, "int v;", "v ==> 0"), 60 (a) -> assertCommand(a, "int v; int c", 61 "v ==> 0\n" + 62 "c ==> 0") 63 ); 64 } 65 66 @Test 67 public void testOpenComment() { 68 test( 69 (a) -> assertCommand(a, "int z = /* blah", ""), 70 (a) -> assertCommand(a, "baz */ 5", "z ==> 5"), 71 (a) -> assertCommand(a, "/** hoge ", ""), 72 (a) -> assertCommand(a, "baz **/", ""), 73 (a) -> assertCommand(a, "int v", "v ==> 0") 74 ); 75 } 76 77 @Test 78 public void testLessThan() { 79 test( 80 (a) -> assertCommand(a, "45", "$1 ==> 45"), 81 (a) -> assertCommand(a, "72", "$2 ==> 72"), 82 (a) -> assertCommand(a, "$1 < $2", "$3 ==> true"), 83 (a) -> assertCommand(a, "int a, b", "a ==> 0\n" + 84 "b ==> 0"), 85 (a) -> assertCommand(a, "a < b", "$6 ==> false") 86 ); 87 } 88 89 @Test 90 public void oneLineOfError() { 91 test( 92 (a) -> assertCommand(a, "12+", null), 93 (a) -> assertCommandCheckOutput(a, " true", (s) -> 94 assertTrue(s.contains("12+") && !s.contains("true"), "Output: '" + s + "'")) 95 ); 96 } 97 98 @Test 99 public void defineVariables() { 100 test( 101 (a) -> assertCommandCheckOutput(a, "/list", assertList()), 102 (a) -> assertCommandCheckOutput(a, "/vars", assertVariables()), 103 (a) -> assertVariable(a, "int", "a"), 104 (a) -> assertCommandCheckOutput(a, "/list", assertList()), 105 (a) -> assertCommandCheckOutput(a, "/vars", assertVariables()), 106 (a) -> assertVariable(a, "double", "a", "1", "1.0"), 107 (a) -> assertCommandCheckOutput(a, "/list", assertList()), 108 (a) -> assertCommandCheckOutput(a, "/vars", assertVariables()), 109 (a) -> evaluateExpression(a, "double", "2 * a", "2.0"), 110 (a) -> assertCommandCheckOutput(a, "/list", assertList()), 111 (a) -> assertCommandCheckOutput(a, "/vars", assertVariables()) 112 ); 113 } 114 115 @Test 116 public void defineMethods() { 117 test( 118 (a) -> assertCommandCheckOutput(a, "/list", assertList()), 119 (a) -> assertCommandCheckOutput(a, "/methods", assertMethods()), 120 (a) -> assertMethod(a, "int f() { return 0; }", "()int", "f"), 121 (a) -> assertCommandCheckOutput(a, "/list", assertList()), 122 (a) -> assertCommandCheckOutput(a, "/methods", assertMethods()), 123 (a) -> assertMethod(a, "void f(int a) { g(); }", "(int)void", "f"), 124 (a) -> assertCommandCheckOutput(a, "/list", assertList()), 125 (a) -> assertCommandCheckOutput(a, "/methods", assertMethods()), 126 (a) -> assertMethod(a, "void g() {}", "()void", "g"), 127 (a) -> assertCommandCheckOutput(a, "/list", assertList()), 128 (a) -> assertCommandCheckOutput(a, "/methods", assertMethods()) 129 ); 130 } 131 132 @Test 133 public void defineTypes() { 134 test( 135 (a) -> assertCommandCheckOutput(a, "/list", assertList()), 136 (a) -> assertCommandCheckOutput(a, "/types", assertClasses()), 137 (a) -> assertClass(a, "class A { }", "class", "A"), 138 (a) -> assertCommandCheckOutput(a, "/list", assertList()), 139 (a) -> assertCommandCheckOutput(a, "/types", assertClasses()), 140 (a) -> assertClass(a, "interface A { }", "interface", "A"), 141 (a) -> assertCommandCheckOutput(a, "/list", assertList()), 142 (a) -> assertCommandCheckOutput(a, "/types", assertClasses()), 143 (a) -> assertClass(a, "enum A { }", "enum", "A"), 144 (a) -> assertCommandCheckOutput(a, "/list", assertList()), 145 (a) -> assertCommandCheckOutput(a, "/types", assertClasses()), 146 (a) -> assertClass(a, "@interface A { }", "@interface", "A"), 147 (a) -> assertCommandCheckOutput(a, "/list", assertList()), 148 (a) -> assertCommandCheckOutput(a, "/types", assertClasses()) 149 ); 150 } 151 152 @Test 153 public void defineImports() { 154 test( 155 (a) -> assertCommandCheckOutput(a, "/list", assertList()), 156 (a) -> assertCommandCheckOutput(a, "/imports", assertImports()), 157 (a) -> assertImport(a, "import java.util.stream.Stream;", "", "java.util.stream.Stream"), 158 (a) -> assertCommandCheckOutput(a, "/list", assertList()), 159 (a) -> assertCommandCheckOutput(a, "/imports", assertImports()), 160 (a) -> assertImport(a, "import java.util.stream.*;", "", "java.util.stream.*"), 161 (a) -> assertCommandCheckOutput(a, "/list", assertList()), 162 (a) -> assertCommandCheckOutput(a, "/imports", assertImports()), 163 (a) -> assertImport(a, "import static java.lang.Math.PI;", "static", "java.lang.Math.PI"), 164 (a) -> assertCommandCheckOutput(a, "/list", assertList()), 165 (a) -> assertCommandCheckOutput(a, "/imports", assertImports()), 166 (a) -> assertImport(a, "import static java.lang.Math.*;", "static", "java.lang.Math.*"), 167 (a) -> assertCommandCheckOutput(a, "/list", assertList()), 168 (a) -> assertCommandCheckOutput(a, "/imports", assertImports()) 169 ); 170 } 171 172 @Test 173 public void defineVar() { 174 test( 175 (a) -> assertCommand(a, "int x = 72", "x ==> 72"), 176 (a) -> assertCommand(a, "x", "x ==> 72"), 177 (a) -> assertCommand(a, "/vars", "| int x = 72") 178 ); 179 } 180 181 @Test 182 public void defineUnresolvedVar() { 183 test( 184 (a) -> assertCommand(a, "undefined x", 185 "| created variable x, however, it cannot be referenced until class undefined is declared"), 186 (a) -> assertCommand(a, "/vars", "| undefined x = (not-active)") 187 ); 188 } 189 190 @Test 191 public void testUnresolved() { 192 test( 193 (a) -> assertCommand(a, "int f() { return g() + x + new A().a; }", 194 "| created method f(), however, it cannot be invoked until method g(), variable x, and class A are declared"), 195 (a) -> assertCommand(a, "f()", 196 "| attempted to call method f() which cannot be invoked until method g(), variable x, and class A are declared"), 197 (a) -> assertCommandOutputStartsWith(a, "int g() { return x; }", 198 "| created method g(), however, it cannot be invoked until variable x is declared"), 199 (a) -> assertCommand(a, "g()", "| attempted to call method g() which cannot be invoked until variable x is declared") 200 ); 201 } 202 203 @Test 204 public void testUnknownCommand() { 205 test((a) -> assertCommand(a, "/unknown", 206 "| Invalid command: /unknown\n" + 207 "| Type /help for help.")); 208 } 209 210 @Test 211 public void testEmptyClassPath() { 212 test(after -> assertCommand(after, "/env --class-path", "| Argument to class-path missing.")); 213 } 214 215 @Test 216 public void testInvalidClassPath() { 217 test( 218 a -> assertCommand(a, "/env --class-path snurgefusal", 219 "| File 'snurgefusal' for '--class-path' is not found.") 220 ); 221 } 222 223 @Test 224 public void testNoArgument() { 225 test( 226 (a) -> assertCommand(a, "/save", 227 "| '/save' requires a filename argument."), 228 (a) -> assertCommand(a, "/open", 229 "| '/open' requires a filename argument."), 230 (a) -> assertCommandOutputStartsWith(a, "/drop", 231 "| In the /drop argument, please specify an import, variable, method, or class to drop.") 232 ); 233 } 234 235 @Test 236 public void testDebug() { 237 test( 238 (a) -> assertCommand(a, "/deb", "| Debugging on"), 239 (a) -> assertCommand(a, "/debug", "| Debugging off"), 240 (a) -> assertCommand(a, "/debug", "| Debugging on"), 241 (a) -> assertCommand(a, "/deb", "| Debugging off") 242 ); 243 } 244 245 @Test 246 public void testDrop() { 247 test(false, new String[]{"--no-startup"}, 248 a -> assertVariable(a, "int", "a"), 249 a -> dropVariable(a, "/drop 1", "int a = 0", "| dropped variable a"), 250 a -> assertMethod(a, "int b() { return 0; }", "()int", "b"), 251 a -> dropMethod(a, "/drop 2", "int b()", "| dropped method b()"), 252 a -> assertClass(a, "class A {}", "class", "A"), 253 a -> dropClass(a, "/drop 3", "class A", "| dropped class A"), 254 a -> assertImport(a, "import java.util.stream.*;", "", "java.util.stream.*"), 255 a -> dropImport(a, "/drop 4", "import java.util.stream.*", ""), 256 a -> assertCommand(a, "for (int i = 0; i < 10; ++i) {}", ""), 257 a -> assertCommand(a, "/drop 5", ""), 258 a -> assertCommand(a, "/list", ""), 259 a -> assertCommandCheckOutput(a, "/vars", assertVariables()), 260 a -> assertCommandCheckOutput(a, "/methods", assertMethods()), 261 a -> assertCommandCheckOutput(a, "/types", assertClasses()), 262 a -> assertCommandCheckOutput(a, "/imports", assertImports()) 263 ); 264 test(false, new String[]{"--no-startup"}, 265 a -> assertVariable(a, "int", "a"), 266 a -> dropVariable(a, "/drop a", "int a = 0", "| dropped variable a"), 267 a -> assertMethod(a, "int b() { return 0; }", "()int", "b"), 268 a -> dropMethod(a, "/drop b", "int b()", "| dropped method b()"), 269 a -> assertClass(a, "class A {}", "class", "A"), 270 a -> dropClass(a, "/drop A", "class A", "| dropped class A"), 271 a -> assertCommandCheckOutput(a, "/vars", assertVariables()), 272 a -> assertCommandCheckOutput(a, "/methods", assertMethods()), 273 a -> assertCommandCheckOutput(a, "/types", assertClasses()), 274 a -> assertCommandCheckOutput(a, "/imports", assertImports()) 275 ); 276 } 277 278 @Test 279 public void testDropRange() { 280 test(false, new String[]{"--no-startup"}, 281 a -> assertVariable(a, "int", "a"), 282 a -> assertMethod(a, "int b() { return 0; }", "()int", "b"), 283 a -> assertClass(a, "class A {}", "class", "A"), 284 a -> assertImport(a, "import java.util.stream.*;", "", "java.util.stream.*"), 285 a -> assertCommand(a, "for (int i = 0; i < 10; ++i) {}", ""), 286 a -> assertCommand(a, "/drop 3-5 b 1", 287 "| dropped class A\n" + 288 "| dropped method b()\n" + 289 "| dropped variable a\n"), 290 a -> assertCommand(a, "/list", "") 291 ); 292 } 293 294 @Test 295 public void testDropNegative() { 296 test(false, new String[]{"--no-startup"}, 297 a -> assertCommandOutputStartsWith(a, "/drop 0", "| No snippet with id: 0"), 298 a -> assertCommandOutputStartsWith(a, "/drop a", "| No such snippet: a"), 299 a -> assertCommandCheckOutput(a, "/drop", 300 assertStartsWith("| In the /drop argument, please specify an import, variable, method, or class to drop.")), 301 a -> assertVariable(a, "int", "a"), 302 a -> assertCommand(a, "a", "a ==> 0"), 303 a -> assertCommand(a, "/drop 2", ""), 304 a -> assertCommand(a, "/drop 2", 305 "| This command does not accept the snippet '2' : a\n" + 306 "| See /types, /methods, /vars, or /list") 307 ); 308 } 309 310 @Test 311 public void testAmbiguousDrop() { 312 test( 313 a -> assertVariable(a, "int", "a"), 314 a -> assertMethod(a, "int a() { return 0; }", "()int", "a"), 315 a -> assertClass(a, "class a {}", "class", "a"), 316 a -> assertCommand(a, "/drop a", 317 "| dropped variable a\n" + 318 "| dropped method a()\n" + 319 "| dropped class a") 320 ); 321 test( 322 a -> assertMethod(a, "int a() { return 0; }", "()int", "a"), 323 a -> assertMethod(a, "double a(int a) { return 0; }", "(int)double", "a"), 324 a -> assertMethod(a, "double a(double a) { return 0; }", "(double)double", "a"), 325 a -> assertCommand(a, "/drop a", 326 "| dropped method a()\n" + 327 "| dropped method a(int)\n" + 328 "| dropped method a(double)\n") 329 ); 330 } 331 332 @Test 333 public void testApplicationOfPost() { 334 test( 335 (a) -> assertCommand(a, "/set mode t normal -command", "| Created new feedback mode: t"), 336 (a) -> assertCommand(a, "/set feedback t", "| Feedback mode: t"), 337 (a) -> assertCommand(a, "/set format t post \"$%n\"", ""), 338 (a) -> assertCommand(a, "/set prompt t \"+\" \"-\"", ""), 339 (a) -> assertCommand(a, "/set prompt t", "| /set prompt t \"+\" \"-\"$") 340 ); 341 } 342 343 @Test 344 public void testHelpLength() { 345 Consumer<String> testOutput = (s) -> { 346 List<String> ss = Stream.of(s.split("\n")) 347 .filter(l -> !l.isEmpty()) 348 .collect(Collectors.toList()); 349 assertTrue(ss.size() >= 10, "Help does not print enough lines:" + s); 350 }; 351 test( 352 (a) -> assertCommandCheckOutput(a, "/?", testOutput), 353 (a) -> assertCommandCheckOutput(a, "/help", testOutput), 354 (a) -> assertCommandCheckOutput(a, "/help /list", testOutput) 355 ); 356 } 357 358 @Test 359 public void testHelp() { 360 test( 361 (a) -> assertHelp(a, "/?", "/list", "/help", "/exit", "intro"), 362 (a) -> assertHelp(a, "/help", "/list", "/help", "/exit", "intro"), 363 (a) -> assertHelp(a, "/help short", "shortcuts", "<tab>"), 364 (a) -> assertHelp(a, "/? /li", "/list -all", "snippets"), 365 (a) -> assertHelp(a, "/help /set prompt", "optionally contain '%s'", "quoted"), 366 (a) -> assertHelp(a, "/help /help", "/help <command>"), 367 (a) -> assertHelp(a, "/help li", "/list -start"), 368 (a) -> assertHelp(a, "/help fe", "/set feedback -retain") 369 ); 370 } 371 372 @Test 373 public void testHelpFormat() { 374 test( 375 (a) -> assertCommandCheckOutput(a, "/help", s -> { 376 String[] lines = s.split("\\R"); 377 assertTrue(lines.length > 20, 378 "Too few lines of /help output: " + lines.length 379 + "\n" + s); 380 for (int i = 0; i < lines.length; ++i) { 381 String l = lines[i]; 382 assertTrue(l.startsWith("| "), 383 "Expected /help line to start with | :\n" + l); 384 assertTrue(l.length() <= 80, 385 "/help line too long: " + l.length() + "\n" + l); 386 } 387 }) 388 ); 389 } 390 391 private void assertHelp(boolean a, String command, String... find) { 392 assertCommandCheckOutput(a, command, s -> { 393 for (String f : find) { 394 assertTrue(s.contains(f), 395 "Expected output of " + command + " to contain: " + f 396 + "\n" + s); 397 } 398 }); 399 } 400 401 // Check that each line of output contains the corresponding string from the list 402 private void checkLineToList(String in, List<String> match) { 403 String trimmed = in.trim(); 404 String[] res = trimmed.isEmpty() 405 ? new String[0] 406 : trimmed.split("\n"); 407 assertEquals(res.length, match.size(), "Got: " + Arrays.asList(res)); 408 for (int i = 0; i < match.size(); ++i) { 409 assertTrue(res[i].contains(match.get(i))); 410 } 411 } 412 413 @Test 414 public void testListArgs() { 415 String arg = "qqqq"; 416 List<String> startVarList = new ArrayList<>(START_UP); 417 startVarList.add("int aardvark"); 418 startVarList.add("int weevil"); 419 test( 420 a -> assertCommandCheckOutput(a, "/list -all", 421 s -> checkLineToList(s, START_UP)), 422 a -> assertCommandOutputStartsWith(a, "/list " + arg, 423 "| No such snippet: " + arg), 424 a -> assertVariable(a, "int", "aardvark"), 425 a -> assertVariable(a, "int", "weevil"), 426 a -> assertCommandOutputContains(a, "/list aardvark", "aardvark"), 427 a -> assertCommandCheckOutput(a, "/list -start", 428 s -> checkLineToList(s, START_UP)), 429 a -> assertCommandCheckOutput(a, "/list -all", 430 s -> checkLineToList(s, startVarList)), 431 a -> assertCommandOutputStartsWith(a, "/list s3", 432 "s3 : import"), 433 a -> assertCommandCheckOutput(a, "/list 1-2 s3", 434 s -> { 435 assertTrue(Pattern.matches(".*aardvark.*\\R.*weevil.*\\R.*s3.*import.*", s.trim()), 436 "No match: " + s); 437 }), 438 a -> assertCommandOutputStartsWith(a, "/list " + arg, 439 "| No such snippet: " + arg) 440 ); 441 } 442 443 @Test 444 public void testVarsArgs() { 445 String arg = "qqqq"; 446 List<String> startVarList = new ArrayList<>(); 447 test( 448 a -> assertCommandCheckOutput(a, "/vars -all", 449 s -> checkLineToList(s, startVarList)), 450 a -> assertCommand(a, "/vars " + arg, 451 "| No such snippet: " + arg), 452 a -> assertVariable(a, "int", "aardvark"), 453 a -> assertMethod(a, "int f() { return 0; }", "()int", "f"), 454 a -> assertVariable(a, "int", "a"), 455 a -> assertVariable(a, "double", "a", "1", "1.0"), 456 a -> assertCommandOutputStartsWith(a, "/vars aardvark", 457 "| int aardvark = 0"), 458 a -> assertCommandCheckOutput(a, "/vars -start", 459 s -> checkLineToList(s, startVarList)), 460 a -> assertCommandOutputStartsWith(a, "/vars -all", 461 "| int aardvark = 0\n| int a = "), 462 a -> assertCommandOutputStartsWith(a, "/vars 1-4", 463 "| int aardvark = 0\n| int a = "), 464 a -> assertCommandOutputStartsWith(a, "/vars f", 465 "| This command does not accept the snippet 'f'"), 466 a -> assertCommand(a, "/var " + arg, 467 "| No such snippet: " + arg) 468 ); 469 } 470 471 @Test 472 public void testMethodsArgs() { 473 String arg = "qqqq"; 474 List<String> printingMethodList = new ArrayList<>(PRINTING_CMD_METHOD); 475 test(new String[]{"--startup", "PRINTING"}, 476 a -> assertCommandCheckOutput(a, "/methods -all", 477 s -> checkLineToList(s, printingMethodList)), 478 a -> assertCommandCheckOutput(a, "/methods -start", 479 s -> checkLineToList(s, printingMethodList)), 480 a -> assertCommandCheckOutput(a, "/methods print println printf", 481 s -> checkLineToList(s, printingMethodList)), 482 a -> assertCommandCheckOutput(a, "/methods println", 483 s -> assertEquals(s.trim().split("\n").length, 10)), 484 a -> assertCommandCheckOutput(a, "/methods", 485 s -> checkLineToList(s, printingMethodList)), 486 a -> assertCommandOutputStartsWith(a, "/methods " + arg, 487 "| No such snippet: " + arg), 488 a -> assertMethod(a, "int f() { return 0; }", "()int", "f"), 489 a -> assertVariable(a, "int", "aardvark"), 490 a -> assertMethod(a, "void f(int a) { g(); }", "(int)void", "f"), 491 a -> assertMethod(a, "void g() {}", "()void", "g"), 492 a -> assertCommandOutputStartsWith(a, "/methods " + arg, 493 "| No such snippet: " + arg), 494 a -> assertCommandOutputStartsWith(a, "/methods aardvark", 495 "| This command does not accept the snippet 'aardvark' : int aardvark"), 496 a -> assertCommandCheckOutput(a, "/methods -start", 497 s -> checkLineToList(s, printingMethodList)), 498 a -> assertCommandCheckOutput(a, "/methods print println printf", 499 s -> checkLineToList(s, printingMethodList)), 500 a -> assertCommandOutputStartsWith(a, "/methods g", 501 "| void g()"), 502 a -> assertCommandOutputStartsWith(a, "/methods f", 503 "| int f()\n" + 504 "| void f(int)") 505 ); 506 } 507 508 @Test 509 public void testMethodsWithErrors() { 510 test(new String[]{"--no-startup"}, 511 a -> assertCommand(a, "double m(int x) { return x; }", 512 "| created method m(int)"), 513 a -> assertCommand(a, "GARBAGE junk() { return TRASH; }", 514 "| created method junk(), however, it cannot be referenced until class GARBAGE, and variable TRASH are declared"), 515 a -> assertCommand(a, "int w = 5;", 516 "w ==> 5"), 517 a -> assertCommand(a, "int tyer() { return w; }", 518 "| created method tyer()"), 519 a -> assertCommand(a, "String w = \"hi\";", 520 "w ==> \"hi\""), 521 a -> assertCommand(a, "/methods", 522 "| double m(int)\n" + 523 "| GARBAGE junk()\n" + 524 "| which cannot be referenced until class GARBAGE, and variable TRASH are declared\n" + 525 "| int tyer()\n" + 526 "| which cannot be invoked until this error is corrected: \n" + 527 "| incompatible types: java.lang.String cannot be converted to int\n" + 528 "| int tyer() { return w; }\n" + 529 "| ^\n") 530 ); 531 } 532 533 @Test 534 public void testTypesWithErrors() { 535 test(new String[]{"--no-startup"}, 536 a -> assertCommand(a, "class C extends NONE { int x; }", 537 "| created class C, however, it cannot be referenced until class NONE is declared"), 538 a -> assertCommand(a, "class D { void m() { System.out.println(nada); } }", 539 "| created class D, however, it cannot be instantiated or its methods invoked until variable nada is declared"), 540 a -> assertCommand(a, "/types", 541 "| class C\n" + 542 "| which cannot be referenced until class NONE is declared\n" + 543 "| class D\n" + 544 "| which cannot be instantiated or its methods invoked until variable nada is declared\n") 545 ); 546 } 547 548 @Test 549 public void testTypesArgs() { 550 String arg = "qqqq"; 551 List<String> startTypeList = new ArrayList<>(); 552 test( 553 a -> assertCommandCheckOutput(a, "/types -all", 554 s -> checkLineToList(s, startTypeList)), 555 a -> assertCommandCheckOutput(a, "/types -start", 556 s -> checkLineToList(s, startTypeList)), 557 a -> assertCommandOutputStartsWith(a, "/types " + arg, 558 "| No such snippet: " + arg), 559 a -> assertVariable(a, "int", "aardvark"), 560 (a) -> assertClass(a, "class A { }", "class", "A"), 561 (a) -> assertClass(a, "interface A { }", "interface", "A"), 562 a -> assertCommandOutputStartsWith(a, "/types -all", 563 "| class A\n" + 564 "| interface A"), 565 (a) -> assertClass(a, "enum E { }", "enum", "E"), 566 (a) -> assertClass(a, "@interface B { }", "@interface", "B"), 567 a -> assertCommand(a, "/types aardvark", 568 "| This command does not accept the snippet 'aardvark' : int aardvark;"), 569 a -> assertCommandOutputStartsWith(a, "/types A", 570 "| interface A"), 571 a -> assertCommandOutputStartsWith(a, "/types E", 572 "| enum E"), 573 a -> assertCommandOutputStartsWith(a, "/types B", 574 "| @interface B"), 575 a -> assertCommandOutputStartsWith(a, "/types " + arg, 576 "| No such snippet: " + arg), 577 a -> assertCommandCheckOutput(a, "/types -start", 578 s -> checkLineToList(s, startTypeList)) 579 ); 580 } 581 582 @Test 583 public void testBlankLinesInSnippetContinuation() { 584 test(Locale.ROOT, false, new String[]{"--no-startup"}, "", 585 a -> assertCommand(a, "class C {", 586 ""), 587 a -> assertCommand(a, "", 588 ""), 589 a -> assertCommand(a, "", 590 ""), 591 a -> assertCommand(a, " int x;", 592 ""), 593 a -> assertCommand(a, "", 594 ""), 595 a -> assertCommand(a, "", 596 ""), 597 a -> assertCommand(a, "}", 598 "| created class C"), 599 a -> assertCommand(a, "/list", 600 "\n" + 601 " 1 : class C {\n" + 602 " \n" + 603 " \n" + 604 " int x;\n" + 605 " \n" + 606 " \n" + 607 " }") 608 ); 609 } 610 611 @Test 612 public void testCompoundStart() { 613 test(new String[]{"--startup", "DEFAULT", "--startup", "PRINTING"}, 614 (a) -> assertCommand(a, "printf(\"%4.2f\", Math.PI)", 615 "", "", null, "3.14", "") 616 ); 617 } 618 619 @Test 620 public void testJavaSeStart() { 621 test(new String[]{"--startup", "JAVASE"}, 622 (a) -> assertCommand(a, "ZoneOffsetTransitionRule.TimeDefinition.WALL", 623 "$1 ==> WALL") 624 ); 625 } 626 627 @Test 628 public void defineClasses() { 629 test( 630 (a) -> assertCommandCheckOutput(a, "/list", assertList()), 631 (a) -> assertCommandCheckOutput(a, "/types", assertClasses()), 632 (a) -> assertClass(a, "class A { }", "class", "A"), 633 (a) -> assertCommandCheckOutput(a, "/list", assertList()), 634 (a) -> assertCommandCheckOutput(a, "/types", assertClasses()), 635 (a) -> assertClass(a, "interface A { }", "interface", "A"), 636 (a) -> assertCommandCheckOutput(a, "/list", assertList()), 637 (a) -> assertCommandCheckOutput(a, "/types", assertClasses()), 638 (a) -> assertClass(a, "enum A { }", "enum", "A"), 639 (a) -> assertCommandCheckOutput(a, "/list", assertList()), 640 (a) -> assertCommandCheckOutput(a, "/types", assertClasses()), 641 (a) -> assertClass(a, "@interface A { }", "@interface", "A"), 642 (a) -> assertCommandCheckOutput(a, "/list", assertList()), 643 (a) -> assertCommandCheckOutput(a, "/types", assertClasses()) 644 ); 645 } 646 647 @Test 648 public void testCommandPrefix() { 649 test(a -> assertCommandCheckOutput(a, "/s", 650 assertStartsWith("| Command: '/s' is ambiguous: /save, /set")), 651 a -> assertCommand(a, "int var", "var ==> 0"), 652 a -> assertCommandCheckOutput(a, "/va", 653 assertStartsWith("| int var = 0")), 654 a -> assertCommandCheckOutput(a, "/save", 655 assertStartsWith("| '/save' requires a filename argument."))); 656 } 657 658 @Test 659 public void testOptionQ() { 660 test(Locale.ROOT, false, new String[]{"-q", "--no-startup"}, "", 661 (a) -> assertCommand(a, "1+1", "$1 ==> 2"), 662 (a) -> assertCommand(a, "int x = 5", "") 663 ); 664 } 665 666 @Test 667 public void testOptionS() { 668 test(Locale.ROOT, false, new String[]{"-s", "--no-startup"}, "", 669 (a) -> assertCommand(a, "1+1", "") 670 ); 671 } 672 673 @Test 674 public void testOptionV() { 675 test(new String[]{"-v", "--no-startup"}, 676 (a) -> assertCommand(a, "1+1", 677 "$1 ==> 2\n" + 678 "| created scratch variable $1 : int") 679 ); 680 } 681 682 @Test 683 public void testOptionFeedback() { 684 test(Locale.ROOT, false, new String[]{"--feedback", "concise", "--no-startup"}, "", 685 (a) -> assertCommand(a, "1+1", "$1 ==> 2"), 686 (a) -> assertCommand(a, "int x = 5", "") 687 ); 688 } 689 690 @Test 691 public void testCompoundOptions() { 692 Consumer<String> confirmNoStartup = s -> { 693 assertEquals(0, Stream.of(s.split("\n")) 694 .filter(l -> !l.isEmpty()) 695 .count(), "Expected no lines: " + s); 696 }; 697 test(Locale.ROOT, false, new String[]{"-nq"}, "", 698 (a) -> assertCommandCheckOutput(a, "/list -all", confirmNoStartup), 699 (a) -> assertCommand(a, "1+1", "$1 ==> 2"), 700 (a) -> assertCommand(a, "int x = 5", "") 701 ); 702 test(Locale.ROOT, false, new String[]{"-qn"}, "", 703 (a) -> assertCommandCheckOutput(a, "/list -all", confirmNoStartup), 704 (a) -> assertCommand(a, "1+1", "$1 ==> 2"), 705 (a) -> assertCommand(a, "int x = 5", "") 706 ); 707 test(Locale.ROOT, false, new String[]{"-ns"}, "", 708 (a) -> assertCommandCheckOutput(a, "/list -all", confirmNoStartup), 709 (a) -> assertCommand(a, "1+1", "") 710 ); 711 } 712 713 @Test 714 public void testOptionR() { 715 test(new String[]{"-R-Dthe.sound=blorp", "--no-startup"}, 716 (a) -> assertCommand(a, "System.getProperty(\"the.sound\")", 717 "$1 ==> \"blorp\"") 718 ); 719 } 720 721 @Test 722 public void testWrapSourceHandlerDiagCrash() { 723 test(new String[]{"--add-exports", "jdk.javadoc/ALL-UNNAMED"}, 724 (a) -> assertCommand(a, "1+1", "$1 ==> 2") 725 ); 726 } 727 728 @Test 729 public void test8156910() { 730 test( 731 (a) -> assertCommandOutputContains(a, "System.out.println(\"%5d\", 10);", "%5d"), 732 (a) -> assertCommandOutputContains(a, "1234", "==> 1234") 733 ); 734 } 735} 736