1 33 34 package edu.rice.cs.drjava.ui; 35 36 import edu.rice.cs.drjava.model.DJDocument; 37 import edu.rice.cs.drjava.model.OpenDefinitionsDocument; 38 import edu.rice.cs.drjava.model.SingleDisplayModel; 39 import edu.rice.cs.drjava.model.compiler.CompilerError; 40 import edu.rice.cs.drjava.model.junit.JUnitError; 41 import edu.rice.cs.drjava.model.junit.JUnitErrorModel; 42 import edu.rice.cs.util.UnexpectedException; 43 import edu.rice.cs.util.swing.BorderlessScrollPane; 44 import edu.rice.cs.util.text.SwingDocument; 45 import edu.rice.cs.util.swing.RightClickMouseAdapter; 46 47 import javax.swing.*; 48 import javax.swing.border.EmptyBorder ; 49 import javax.swing.text.*; 50 import java.awt.*; 51 import java.awt.event.ActionEvent ; 52 import java.awt.event.ActionListener ; 53 import java.awt.event.MouseEvent ; 54 import java.io.File ; 55 import java.util.List ; 56 import java.util.ArrayList ; 57 import java.util.HashMap ; 58 59 62 public class JUnitPanel extends ErrorPanel { 63 private static final String START_JUNIT_MSG = "Testing in progress. Please wait ...\n"; 64 private static final String JUNIT_FINISHED_MSG = "All tests completed successfully.\n"; 65 private static final String NO_TESTS_MSG = ""; 66 67 private static final SimpleAttributeSet OUT_OF_SYNC_ATTRIBUTES = _getOutOfSyncAttributes(); 68 private static final SimpleAttributeSet _getOutOfSyncAttributes() { 69 SimpleAttributeSet s = new SimpleAttributeSet(); 70 s.addAttribute(StyleConstants.Foreground, Color.red.darker()); 71 s.addAttribute(StyleConstants.Bold, Boolean.TRUE); 72 return s; 73 } 74 75 private static final SimpleAttributeSet TEST_PASS_ATTRIBUTES = _getTestPassAttributes(); 76 private static final SimpleAttributeSet _getTestPassAttributes() { 77 SimpleAttributeSet s = new SimpleAttributeSet(); 78 s.addAttribute(StyleConstants.Foreground, Color.green.darker()); 79 return s; 80 } 81 82 private static final SimpleAttributeSet TEST_FAIL_ATTRIBUTES = _getTestFailAttributes(); 83 private static final SimpleAttributeSet _getTestFailAttributes() { 84 SimpleAttributeSet s = new SimpleAttributeSet(); 85 s.addAttribute(StyleConstants.Foreground, Color.red); 86 return s; 87 } 88 89 private static final String TEST_OUT_OF_SYNC = 90 "The documents being tested have been modified and should be recompiled!\n"; 91 92 protected JUnitErrorListPane _errorListPane; 93 private final MainFrame _mainFrame; private int _testCount; 95 private boolean _testsSuccessful; 96 97 private JUnitProgressBar _progressBar; 98 private List <OpenDefinitionsDocument> _odds = new ArrayList <OpenDefinitionsDocument>(); 99 100 private Action _showStackTraceAction = new AbstractAction("Show Stack Trace") { 101 public void actionPerformed(ActionEvent ae) { 102 if (_error != null) { 103 _displayStackTrace(_error); 104 } 105 } 106 }; 107 108 private JButton _showStackTraceButton; 109 110 111 private JUnitError _error = null; 112 private Window _stackFrame = null; 113 private JTextArea _stackTextArea; 114 private final JLabel _errorLabel = new JLabel(); 115 private final JLabel _testLabel = new JLabel(); 116 private final JLabel _fileLabel = new JLabel(); 117 118 122 public JUnitPanel(SingleDisplayModel model, MainFrame frame) { 123 super(model, frame, "Test Output", "Test Progress"); 124 _mainFrame = frame; 125 _testCount = 0; 126 _testsSuccessful = true; 127 128 _progressBar = new JUnitProgressBar(); 129 _progressBar.setUI(new javax.swing.plaf.basic.BasicProgressBarUI ()); 130 _showStackTraceButton = new JButton(_showStackTraceAction); 131 customPanel.add(_progressBar, BorderLayout.NORTH); 132 customPanel.add(_showStackTraceButton, BorderLayout.SOUTH); 133 134 _errorListPane = new JUnitErrorListPane(); 135 setErrorListPane(_errorListPane); 136 } 137 138 139 public JUnitErrorListPane getErrorListPane() { return _errorListPane; } 140 141 protected JUnitErrorModel getErrorModel() { return getModel().getJUnitModel().getJUnitErrorModel(); } 142 143 146 protected void _updateStyles(AttributeSet newSet) { 147 super._updateStyles(newSet); 148 OUT_OF_SYNC_ATTRIBUTES.addAttributes(newSet); 149 StyleConstants.setBold(OUT_OF_SYNC_ATTRIBUTES, true); TEST_PASS_ATTRIBUTES.addAttributes(newSet); 151 TEST_FAIL_ATTRIBUTES.addAttributes(newSet); 152 } 153 154 155 public void setJUnitInProgress() { 156 _errorListPane.setJUnitInProgress(); 157 } 158 159 160 protected void _close() { 161 super._close(); 162 getModel().getJUnitModel().resetJUnitErrors(); 163 reset(); 164 } 165 166 167 public void reset() { 168 JUnitErrorModel juem = getModel().getJUnitModel().getJUnitErrorModel(); 169 boolean testsHaveRun = false; 170 if (juem != null) { 171 _numErrors = juem.getNumErrors(); 172 testsHaveRun = juem.haveTestsRun(); 173 } 174 else _numErrors = 0; 175 _errorListPane.updateListPane(testsHaveRun); } 177 178 179 public void progressReset(int numTests) { 180 _progressBar.reset(); 181 _progressBar.start(numTests); 182 _testsSuccessful = true; 183 _testCount = 0; 184 } 185 186 189 public void progressStep(boolean successful) { 190 _testCount++; 191 _testsSuccessful &= successful; 192 _progressBar.step(_testCount, _testsSuccessful); 193 } 194 195 public void testStarted(String className, String testName) { } 196 197 private void _displayStackTrace (JUnitError e) { 198 _errorLabel.setText((e.isWarning() ? "Error: " : "Failure: ") + 199 e.message()); 200 _fileLabel.setText("File: "+(new File (e.fileName())).getName()); 201 if (!e.testName().equals("")) { 202 _testLabel.setText("Test: "+e.testName()); 203 } 204 else { 205 _testLabel.setText(""); 206 } 207 _stackTextArea.setText(e.stackTrace()); 208 _stackTextArea.setCaretPosition(0); 209 _stackFrame.setVisible(true); 210 } 211 212 213 public class JUnitErrorListPane extends ErrorPanel.ErrorListPane { 214 private JPopupMenu _popMenu; 215 private String _runningTestName; 216 private boolean _warnedOutOfSync; 217 private static final String JUNIT_WARNING = "junit.framework.TestSuite$1.warning"; 218 219 220 private final HashMap <String , Position> _runningTestNamePositions; 221 222 223 public JUnitErrorListPane() { 224 removeMouseListener(defaultMouseListener); 225 _popMenu = new JPopupMenu(); 226 _popMenu.add(_showStackTraceAction); 227 _error = null; 228 _setupStackTraceFrame(); 229 addMouseListener(new PopupAdapter()); 230 _runningTestName = null; 231 _runningTestNamePositions = new HashMap <String , Position>(); 232 _showStackTraceButton.setEnabled(false); 233 } 234 235 private String _getTestFromName(String name) { 236 int paren = name.indexOf('('); 237 238 if ((paren > -1) && (paren < name.length())) return name.substring(0, paren); 239 240 else throw new IllegalArgumentException ("Name does not contain any parens: " + name); 241 } 242 243 private String _getClassFromName(String name) { 244 int paren = name.indexOf('('); 245 246 if ((paren > -1) && (paren < name.length())) return name.substring(paren + 1, name.length() - 1); 247 else throw new IllegalArgumentException ("Name does not contain any parens: " + name); 248 } 249 250 251 public void testStarted(String name) { 252 String testName = _getTestFromName(name); 253 String className = _getClassFromName(name); 254 String fullName = className + "." + testName; 255 if (fullName.equals(JUNIT_WARNING)) return; 256 SwingDocument doc = getSwingDocument(); 257 int index = doc.getLength(); 258 259 try { 260 if (! className.equals(_runningTestName)) { 262 _runningTestName = className; 263 doc.insertString(index, " " + className + "\n", NORMAL_ATTRIBUTES); 264 index = doc.getLength(); 265 } 266 267 doc.insertString(index, " ", NORMAL_ATTRIBUTES); 269 index = doc.getLength(); 270 doc.insertString(index, testName + "\n", NORMAL_ATTRIBUTES); 271 Position pos = doc.createPosition(index); 272 _runningTestNamePositions.put(fullName, pos); 273 setCaretPosition(index); 274 } 275 catch (BadLocationException ble) { 276 throw new UnexpectedException(ble); 278 } 279 } 280 281 282 public void testEnded(String name, boolean wasSuccessful, boolean causedError) { 283 String testName = _getTestFromName(name); 284 String fullName = _getClassFromName(name) + "." + testName; 285 if (fullName.equals(JUNIT_WARNING)) return; 286 287 SwingDocument doc = getSwingDocument(); 288 Position namePos = _runningTestNamePositions.get(fullName); 289 AttributeSet set; 290 if (! wasSuccessful || causedError) set = TEST_FAIL_ATTRIBUTES; 291 else set = TEST_PASS_ATTRIBUTES; 292 if (namePos != null) { 293 int index = namePos.getOffset(); 294 int length = testName.length(); 295 doc.setCharacterAttributes(index, length, set, false); 296 } 297 } 298 299 300 public void setJUnitInProgress() { 301 assert EventQueue.isDispatchThread(); 302 _errorListPositions = new Position[0]; 303 progressReset(0); 304 _runningTestNamePositions.clear(); 305 _runningTestName = null; 306 _warnedOutOfSync = false; 307 308 SwingDocument doc = new SwingDocument(); 309 311 doc.append(START_JUNIT_MSG, BOLD_ATTRIBUTES); 312 setDocument(doc); 313 selectNothing(); 314 } 315 316 317 protected void _updateWithErrors() throws BadLocationException { 318 SwingDocument doc = getSwingDocument(); 320 _updateWithErrors("test", "failed", doc); 322 } 323 324 325 protected String _getNumErrorsMessage(String failureName, String failureMeaning) { 326 StringBuilder numErrMsg; 327 328 329 int numCompErrs = getErrorModel().getNumCompErrors(); 330 int numWarnings = getErrorModel().getNumWarnings(); 331 332 if (! getErrorModel().hasOnlyWarnings()) { 333 numErrMsg = new StringBuilder (numCompErrs + " " + failureName); if (numCompErrs > 1) numErrMsg.append("s"); 335 numErrMsg.append(" " + failureMeaning); 336 if (numWarnings > 0) numErrMsg.append(" and " + numWarnings + " warning"); 337 } 338 else numErrMsg = new StringBuilder (numWarnings + " warning"); 339 340 if (numWarnings > 1) numErrMsg.append("s"); 341 if (numWarnings > 0) numErrMsg.append(" found"); 342 343 numErrMsg.append(":\n"); 344 345 return numErrMsg.toString(); 346 } 347 348 protected void _updateWithErrors(String failureName, String failureMeaning, SwingDocument doc) 349 throws BadLocationException { 350 _replaceInProgressText(_getNumErrorsMessage(failureName, failureMeaning)); 352 353 _insertErrors(doc); 354 355 switchToError(0); 357 } 358 359 362 public void _replaceInProgressText(String msg) throws BadLocationException { 363 assert ! _mainFrame.isVisible() || EventQueue.isDispatchThread(); 364 int start = 0; 365 if (_warnedOutOfSync) { start = TEST_OUT_OF_SYNC.length(); } 366 int len = START_JUNIT_MSG.length(); 367 SwingDocument doc = getSwingDocument(); 368 if (doc.getLength() >= len + start) { 369 doc.remove(start, len); 370 doc.insertString(start, msg, BOLD_ATTRIBUTES); 371 } 372 } 373 374 376 protected String _getWarningText() { return "Error: "; } 377 378 379 protected String _getErrorText() { return "Failure: "; } 380 381 382 protected void _updateNoErrors(boolean haveTestsRun) throws BadLocationException { 383 _replaceInProgressText(haveTestsRun ? JUNIT_FINISHED_MSG : NO_TESTS_MSG); 386 387 selectNothing(); 388 setCaretPosition(0); 389 } 390 391 411 private void _setupStackTraceFrame() { 412 JDialog _dialog = new JDialog(_frame,"JUnit Error Stack Trace",false); 414 _stackFrame = _dialog; 415 _stackTextArea = new JTextArea(); 416 _stackTextArea.setEditable(false); 417 _stackTextArea.setLineWrap(false); 418 JScrollPane scroll = new 419 BorderlessScrollPane(_stackTextArea, 420 JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 421 JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 422 423 ActionListener closeListener = new ActionListener () { 424 public void actionPerformed(ActionEvent e) { 425 _frame.setPopupLoc(_stackFrame); 426 _stackFrame.setVisible(true); 427 } 428 }; 429 JButton closeButton = new JButton("Close"); 430 closeButton.addActionListener(closeListener); 431 JPanel closePanel = new JPanel(new BorderLayout()); 432 closePanel.setBorder(new EmptyBorder (5,5,0,0)); 433 closePanel.add(closeButton, BorderLayout.EAST); 434 JPanel cp = new JPanel(new BorderLayout()); 435 _dialog.setContentPane(cp); 436 cp.setBorder(new EmptyBorder (5,5,5,5)); 437 cp.add(scroll, BorderLayout.CENTER); 438 cp.add(closePanel, BorderLayout.SOUTH); 439 JPanel topPanel = new JPanel(new GridLayout(0,1,0,5)); 440 topPanel.setBorder(new EmptyBorder (0,0,5,0)); 441 topPanel.add(_fileLabel); 442 topPanel.add(_testLabel); 443 topPanel.add(_errorLabel); 444 cp.add(topPanel, BorderLayout.NORTH); 445 _dialog.setSize(600, 500); 446 } 448 449 452 public void selectItem(CompilerError error) { 453 super.selectItem(error); 454 _error = (JUnitError) error; 455 _showStackTraceButton.setEnabled(true); 456 } 457 458 459 462 protected void _removeListHighlight() { 463 super._removeListHighlight(); 464 _showStackTraceButton.setEnabled(false); 465 } 466 467 480 481 private class PopupAdapter extends RightClickMouseAdapter { 482 486 public void mousePressed(MouseEvent e) { 487 if (_selectError(e)) { 488 super.mousePressed(e); 489 } 490 } 491 492 496 public void mouseReleased(MouseEvent e) { 497 if (_selectError(e)) { 498 super.mouseReleased(e); 499 } 500 } 501 502 507 private boolean _selectError(MouseEvent e) { 508 _error = (JUnitError)_errorAtPoint(e.getPoint()); 510 511 if (_isEmptySelection() && _error != null) { 512 _errorListPane.switchToError(_error); 513 return true; 514 } 515 else { 516 selectNothing(); 517 return false; 518 } 519 } 520 521 525 protected void _popupAction(MouseEvent e) { 526 _popMenu.show(e.getComponent(), e.getX(), e.getY()); 527 } 528 529 } 533 } 534 535 536 541 static class JUnitProgressBar extends JProgressBar { 542 private boolean _hasError = false; 543 544 public JUnitProgressBar() { 545 super(); 546 setForeground(getStatusColor()); 547 } 548 549 private Color getStatusColor() { 550 if (_hasError) { 551 return Color.red; 552 } 553 else { 554 return Color.green; 555 } 556 } 557 558 public void reset() { 559 _hasError = false; 560 setForeground(getStatusColor()); 561 setValue(0); 562 } 563 564 public void start(int total) { 565 setMaximum(total); 566 reset(); 567 } 568 569 public void step(int value, boolean successful) { 570 setValue(value); 571 if (!_hasError && !successful) { 572 _hasError= true; 573 setForeground(getStatusColor()); 574 } 575 } 576 } 577 } 578 | Popular Tags |