1 33 34 package edu.rice.cs.drjava.model.repl; 35 36 import edu.rice.cs.drjava.DrJavaTestCase; 37 import edu.rice.cs.drjava.model.OpenDefinitionsDocument; 38 import edu.rice.cs.drjava.model.repl.newjvm.MainJVM; 39 import edu.rice.cs.drjava.model.FileSaveSelector; 40 41 import edu.rice.cs.util.FileOpenSelector; 42 import edu.rice.cs.util.Log; 43 import edu.rice.cs.util.OperationCanceledException; 44 import edu.rice.cs.util.text.ConsoleDocument; 45 import edu.rice.cs.util.text.EditDocumentException; 46 47 import java.io.File ; 48 import java.io.IOException ; 49 50 import java.net.URL ; 51 52 import java.rmi.RemoteException ; 53 54 57 public final class InteractionsModelTest extends DrJavaTestCase { 58 59 private static Log _log = new Log("InteractionsModelTest.txt", false); 60 protected InteractionsDJDocument _adapter; 61 protected InteractionsModel _model; 62 63 public InteractionsModelTest(String name) { 64 super(name); 65 _adapter = new InteractionsDJDocument(); 66 _model = new TestInteractionsModel(_adapter); 67 } 68 69 public void tearDown() throws Exception { 70 if (_model instanceof IncompleteInputInteractionsModel) ((IncompleteInputInteractionsModel) _model).dispose(); 72 _model = null; 73 _adapter = null; 74 super.tearDown(); 75 } 76 77 82 protected void _assertProcessedContents(String typed, String expected) throws EditDocumentException { 83 assertTrue(_model instanceof TestInteractionsModel); 84 TestInteractionsModel model = (TestInteractionsModel)_model; 85 InteractionsDocument doc = model.getDocument(); 86 doc.reset("This is a test"); 87 doc.append(typed, InteractionsDocument.DEFAULT_STYLE); 88 model.interpretCurrentInteraction(); 89 assertEquals("processed output should match expected", expected, model.toEval); 90 } 91 92 97 protected void _assertMainTransformation(String typed, String expected) { 98 assertEquals("main transformation should match expected", expected, TestInteractionsModel._testClassCall(typed)); 99 } 100 101 102 public void testInterpretCurrentInteraction() throws EditDocumentException { 103 assertTrue(_model instanceof TestInteractionsModel); 104 TestInteractionsModel model = (TestInteractionsModel) _model; 105 String code = "int x = 3;"; 106 InteractionsDocument doc = model.getDocument(); 107 model.interpretCurrentInteraction(); 108 model.replReturnedVoid(); 110 assertEquals("string being interpreted", "", model.toEval); 111 112 doc.append(code, InteractionsDocument.DEFAULT_STYLE); 114 model.interpretCurrentInteraction(); 115 model.replReturnedVoid(); 117 assertEquals("string being interpreted", code, model.toEval); 118 } 119 120 public void testInterpretCurrentInteractionWithIncompleteInput() throws EditDocumentException, InterruptedException { 122 _log.log("testInterpretCurrentInteractionWithIncompleteInput started"); 123 _model = new IncompleteInputInteractionsModel(_adapter); assertReplThrewContinuationException("void m() {"); 125 assertReplThrewContinuationException("void m() {;"); 126 assertReplThrewContinuationException("1+"); 127 assertReplThrewContinuationException("(1+2"); 128 assertReplThrewSyntaxException("(1+2;"); 129 assertReplThrewContinuationException("for (;;"); 130 } 131 132 protected void assertReplThrewContinuationException(String code) throws EditDocumentException, InterruptedException { 133 assertTrue(_model instanceof IncompleteInputInteractionsModel); 134 IncompleteInputInteractionsModel model = (IncompleteInputInteractionsModel) _model; 135 InteractionsDocument doc = model.getDocument(); 136 doc.reset("This is a test"); 137 doc.append(code, InteractionsDocument.DEFAULT_STYLE); 138 model._logInteractionStart(); 139 model.interpretCurrentInteraction(); 140 _log.log("Waiting for InteractionDone()"); 141 model._waitInteractionDone(); 142 assertTrue("Code '"+code+"' should generate a continuation exception but not a syntax exception", 143 (model.isContinuationException() == true) && (model.isSyntaxException() == false)); 144 } 145 146 protected void assertReplThrewSyntaxException(String code) throws EditDocumentException, InterruptedException { 147 assertTrue(_model instanceof IncompleteInputInteractionsModel); 148 IncompleteInputInteractionsModel model = (IncompleteInputInteractionsModel)_model; 149 InteractionsDocument doc = model.getDocument(); 150 doc.reset("This is a test"); 151 doc.append(code, InteractionsDocument.DEFAULT_STYLE); 152 model._logInteractionStart(); 153 model.interpretCurrentInteraction(); 154 model._waitInteractionDone(); 155 assertTrue("Code '" + code + "' should generate a syntax exception but not a continuation exception", 156 (model.isSyntaxException() == true) && (model.isContinuationException() == false)); 157 } 158 159 160 161 public void testInterpretJavaArguments() { 162 _assertMainTransformation("java Foo a b c", "Foo.main(new String[]{\"a\",\"b\",\"c\"});"); 165 _assertMainTransformation("java Foo \"a b c\"", "Foo.main(new String[]{\"a b c\"});"); 168 _assertMainTransformation("java Foo \"a b\"c d", "Foo.main(new String[]{\"a bc\",\"d\"});"); 173 174 _assertMainTransformation("java Foo c:\\\\file.txt", "Foo.main(new String[]{\"c:\\\\file.txt\"});"); 177 178 _assertMainTransformation("java Foo /home/user/file", "Foo.main(new String[]{\"/home/user/file\"});"); 181 } 182 183 188 public void testInterpretJavaEscapedArgs() { 189 _assertMainTransformation("java Foo \\j", "Foo.main(new String[]{\"j\"});"); 192 _assertMainTransformation("java Foo \\\"", "Foo.main(new String[]{\"\\\"\"});"); 195 _assertMainTransformation("java Foo \\\\", "Foo.main(new String[]{\"\\\\\"});"); 198 _assertMainTransformation("java Foo a\\ b", "Foo.main(new String[]{\"a b\"});"); 201 } 202 203 206 public void testInterpretJavaQuotedEscapedArgs() { 207 _assertMainTransformation("java Foo \"a \\\" b\"", "Foo.main(new String[]{\"a \\\" b\"});"); 210 _assertMainTransformation("java Foo \"\\'\"", "Foo.main(new String[]{\"\\\\'\"});"); 213 _assertMainTransformation("java Foo \"\\\\\"", "Foo.main(new String[]{\"\\\\\"});"); 216 _assertMainTransformation("java Foo \"\\\" \\d\"", "Foo.main(new String[]{\"\\\" \\\\d\"});"); 219 239 } 240 241 242 public void testInterpretJavaSingleQuotedArgs() { 243 244 _assertMainTransformation("java Foo 'asdf'", "Foo.main(new String[]{\"asdf\"});"); 246 247 _assertMainTransformation("java Foo 'a b c'", "Foo.main(new String[]{\"a b c\"});"); 249 250 _assertMainTransformation("java Foo 'a b'c", "Foo.main(new String[]{\"a bc\"});"); 252 } 253 254 257 258 259 public void testDebugPort() throws IOException { 260 int port = _model.getDebugPort(); 261 assertTrue("generated debug port", port != -1); 262 263 _model.setWaitingForFirstInterpreter(false); 265 _model.interpreterResetting(); 266 int newPort = _model.getDebugPort(); 267 assertTrue("debug port should change", newPort != port); 268 269 _model.setDebugPort(5); 271 assertEquals("manually set debug port", 5, _model.getDebugPort()); 272 273 _model.setDebugPort(-1); 275 assertEquals("debug port should be -1", -1, _model.getDebugPort()); 276 } 277 278 279 public void testScriptLoading() throws IOException , OperationCanceledException { 280 assertTrue(_model instanceof TestInteractionsModel); 281 TestInteractionsModel model = (TestInteractionsModel)_model; 282 String line1 = "System.out.println(\"hi\")"; 284 String line2 = "System.out.println(\"bye\")"; 285 final File temp = File.createTempFile("drjava-test", ".hist").getCanonicalFile(); 287 temp.deleteOnExit(); 288 History history = new History(5); 289 history.add(line1); 290 history.add(line2); 291 history.writeToFile(new FileSaveSelector() { 292 public File getFile() { return temp; } 293 public boolean warnFileOpen(File f) { return true; } 294 public boolean verifyOverwrite() { return true; } 295 public boolean shouldSaveAfterFileMoved(OpenDefinitionsDocument doc, File oldFile) { return true; } 296 }); 297 298 InteractionsScriptModel ism = model.loadHistoryAsScript(new FileOpenSelector() { 300 public File [] getFiles() { 301 return new File [] {temp}; 302 } 303 }); 304 InteractionsDocument doc = model.getDocument(); 305 306 assertTrue("Should have no previous", !ism.hasPrevInteraction()); 308 try { 309 ism.prevInteraction(); 310 fail("Should not have been able to get previous interaction!"); 311 } 312 catch (IllegalStateException ise) { 313 } 315 316 assertTrue("Should have next", ism.hasNextInteraction()); 318 ism.nextInteraction(); 319 assertEquals("Should have put the first line into the document.", line1, doc.getCurrentInteraction()); 320 321 assertTrue("Should have no previous", !ism.hasPrevInteraction()); 323 try { 324 ism.prevInteraction(); 325 fail("Should not have been able to get previous interaction!"); 326 } 327 catch (IllegalStateException ise) { 328 } 330 331 assertTrue("Should have next", ism.hasNextInteraction()); 333 ism.nextInteraction(); 334 assertEquals("Should have put the second line into the document.", line2, doc.getCurrentInteraction()); 335 336 assertTrue("Should have previous", ism.hasPrevInteraction()); 338 ism.prevInteraction(); 339 assertEquals("Should have put the first line into the document.", line1, doc.getCurrentInteraction()); 340 341 ism.nextInteraction(); 343 ism.executeInteraction(); 344 assertEquals("Should have \"executed\" the second interaction.", line2, model.toEval); 345 model.replReturnedVoid(); 347 348 assertTrue("Should have no next", !ism.hasNextInteraction()); 350 try { 351 ism.nextInteraction(); 352 fail("Should not have been able to get next interaction!"); 353 } 354 catch (IllegalStateException ise) { 355 } 357 358 assertTrue("Should have previous", ism.hasPrevInteraction()); 360 ism.prevInteraction(); 361 assertEquals("Should have put the second line into the document.", line2, doc.getCurrentInteraction()); 362 363 assertTrue("Should have previous", ism.hasPrevInteraction()); 365 ism.prevInteraction(); 366 assertEquals("Should have put the first line into the document.", line1, doc.getCurrentInteraction()); 367 368 assertTrue("Should have no previous", !ism.hasPrevInteraction()); 370 371 ism.executeInteraction(); 373 assertEquals("Should have \"executed\" the first interaction.", line1, model.toEval); 374 model.replReturnedVoid(); 376 377 assertTrue("Should have previous", ism.hasPrevInteraction()); 379 ism.prevInteraction(); 380 assertEquals("Should have put the first line into the document.", line1, doc.getCurrentInteraction()); 381 382 assertTrue("Should have no previous", !ism.hasPrevInteraction()); 384 try { 385 ism.prevInteraction(); 386 fail("Should not have been able to get previous interaction!"); 387 } 388 catch (IllegalStateException ise) { 389 } 391 } 392 393 394 public void testSetChangeInputListener() { 395 InputListener listener1 = new InputListener() { 396 public String getConsoleInput() { return "input1"; } 397 }; 398 399 InputListener listener2 = new InputListener() { 400 public String getConsoleInput() { return "input2"; } 401 }; 402 403 try { 404 _model.getConsoleInput(); 405 fail("Should not have allowed getting input before a listener is installed!"); 406 } 407 catch (IllegalStateException ise) { 408 assertEquals("Should have thrown the correct exception.", 409 "No input listener installed!", ise.getMessage()); 410 } 411 412 _model.setInputListener(listener1); 413 assertEquals("First input listener should return correct input", "input1", _model.getConsoleInput()); 414 _model.changeInputListener(listener1, listener2); 415 assertEquals("Second input listener should return correct input", "input2", _model.getConsoleInput()); 416 } 417 418 419 public void testInteractionsHistoryStoredCorrectly() throws EditDocumentException { 420 final Object _lock = new Object (); 421 String code = "public class A {\n"; 422 423 InteractionsDocument doc = _model.getDocument(); 424 425 doc.insertText(doc.getLength(), code, InteractionsDocument.DEFAULT_STYLE); 427 428 _model.interpretCurrentInteraction(); 429 _model.replReturnedSyntaxError("Encountered Unexpected \"<EOF>\"", "public class A {\n", -1, -1, -1, -1); 431 432 assertEquals("Current interaction should still be there - should not have interpreted", "public class A {\n" + System.getProperty("line.separator"), 433 doc.getCurrentInteraction()); 434 History h = doc.getHistory(); 435 assertEquals("History should be empty", 0, h.size()); 436 437 code = "}\n"; 438 439 doc.insertText(doc.getLength(), code, InteractionsDocument.DEFAULT_STYLE); 440 441 synchronized(_lock) { 442 _model.interpretCurrentInteraction(); 443 _model.replReturnedVoid(); 444 } 445 446 synchronized(_lock) { 447 assertEquals("Current interaction should not be there - should have interpreted", "", doc.getCurrentInteraction()); 448 assertEquals("History should contain one interaction", 1, h.size()); 449 } 450 } 451 452 453 public static class TestInteractionsModel extends InteractionsModel { 454 String toEval = null; 455 String addedClass = null; 456 457 458 public TestInteractionsModel(InteractionsDJDocument adapter) { 459 super(adapter, new File (System.getProperty("user.dir")), 1000, 25); 461 } 462 463 protected void _interpret(String toEval) { this.toEval = toEval; } 464 465 public String getVariableToString(String var) { 466 fail("cannot getVariableToString in a test"); 467 return null; 468 } 469 public String getVariableClassName(String var) { 470 fail("cannot getVariableClassName in a test"); 471 return null; 472 } 473 474 public void addProjectClassPath(URL path) { fail("cannot add to classpath in a test"); } 475 public void addBuildDirectoryClassPath(URL path) { fail("cannot add to classpath in a test"); } 476 public void addProjectFilesClassPath(URL path) { fail("cannot add to classpath in a test"); } 477 public void addExternalFilesClassPath(URL path) { fail("cannot add to classpath in a test"); } 478 public void addExtraClassPath(URL path) { fail("cannot add to classpath in a test"); } 479 protected void _resetInterpreter(File wd) { fail("cannot reset interpreter in a test"); } 480 481 protected void _notifyInteractionStarted() { } 482 protected void _notifyInteractionEnded() { } 483 protected void _notifySyntaxErrorOccurred(int offset, int length) { } 484 protected void _notifyInterpreterExited(int status) { } 485 protected void _notifyInterpreterResetting() { } 486 protected void _notifyInterpreterResetFailed(Throwable t) { } 487 public void _notifyInterpreterReady(File wd) { } 488 protected void _interpreterResetFailed(Throwable t) { } 489 protected void _notifyInteractionIncomplete() { } 490 protected void _notifySlaveJVMUsed() { } 491 public ConsoleDocument getConsoleDocument() { return null; } 492 } 493 494 497 private static class IncompleteInputInteractionsModel extends RMIInteractionsModel { 498 boolean continuationException; boolean syntaxException; 500 501 private volatile boolean _interactionDone = false; 502 private final Object _interactionLock = new Object (); 503 504 public void _logInteractionStart() { _interactionDone = false; } 505 506 public void _waitInteractionDone() throws InterruptedException { 507 synchronized(_interactionLock) { while (! _interactionDone) _interactionLock.wait(); } 508 } 509 510 511 public IncompleteInputInteractionsModel(InteractionsDJDocument adapter) { 512 super(new MainJVM(null), adapter, new File (System.getProperty("user.dir")), 1000, 25); 514 _jvm.setInteractionsModel(this); _jvm.startInterpreterJVM(); 516 continuationException = false; 517 syntaxException = false; 518 } 519 520 protected void _notifyInteractionStarted() { } 521 protected void _notifyInteractionEnded() { 522 _log.log("_notifyInteractionEnded called."); 523 synchronized(_interactionLock) { 524 _interactionDone = true; 525 _interactionLock.notify(); 526 } 527 } 528 protected void _notifySyntaxErrorOccurred(int offset, int length) { } 529 protected void _notifyInterpreterExited(int status) { } 530 protected void _notifyInterpreterResetting() { } 531 protected void _notifyInterpreterResetFailed(Throwable t) { } 532 public void _notifyInterpreterReady(File wd) { } 533 protected void _interpreterResetFailed(Throwable t) { } 534 protected void _notifyInteractionIncomplete() { _notifyInteractionEnded(); } 535 protected void _notifyInterpreterChanged(boolean inProgress) { } 536 protected void _notifySlaveJVMUsed() { } 537 538 public void dispose() throws RemoteException { _jvm.dispose(); } 539 540 public ConsoleDocument getConsoleDocument() { return null; } 541 542 public void replThrewException(String exceptionClass, String message, String stackTrace, String shortMessage) { 543 _log.log("replThrewException called"); 544 if (shortMessage != null) { 545 if (shortMessage.endsWith("<EOF>\"")) { 546 continuationException = true; 547 syntaxException = false; 548 _interactionIsOver(); 549 return; 550 } 551 } 552 syntaxException = true; 553 continuationException = false; 554 _interactionIsOver(); 555 } 556 557 public void replReturnedSyntaxError(String errorMessage, String interaction, int startRow, int startCol, int endRow, 558 int endCol) { 559 _log.log("replReturnedSyntaxError called"); 560 if (errorMessage != null) { 561 if (errorMessage.endsWith("<EOF>\"")) { 562 continuationException = true; 563 syntaxException = false; 564 _interactionIsOver(); 565 return; 566 } 567 } 568 syntaxException = true; 569 continuationException = false; 570 _interactionIsOver(); 571 } 572 573 public boolean isContinuationException() { return continuationException; } 574 public boolean isSyntaxException() { return syntaxException; } 575 } 576 577 } 596 | Popular Tags |