1 19 20 21 package org.openide.text; 22 23 24 25 import java.io.IOException ; 26 import javax.swing.text.*; 27 import org.netbeans.junit.*; 28 import org.openide.util.Exceptions; 29 import org.openide.util.RequestProcessor; 30 31 36 public class UndoRedoCooperationTest extends NbTestCase implements CloneableEditorSupport.Env { 37 38 private CES support; 39 private String content = "Hello"; 41 private boolean valid = true; 42 private boolean modified = false; 43 44 private String cannotBeModified; 45 private java.util.Date date = new java.util.Date (); 46 private java.util.List propL = new java.util.ArrayList (); 47 private java.beans.VetoableChangeListener vetoL; 48 49 50 public UndoRedoCooperationTest (String s) { 51 super(s); 52 } 53 54 protected javax.swing.text.EditorKit createEditorKit() { 55 return new NbLikeEditorKit(); 56 } 57 58 protected void setUp () { 59 support = new CES (this, org.openide.util.Lookup.EMPTY); 60 } 61 62 public void testOneThreadDoingEditsOneThreadDoingReverts () throws Exception { 63 final StyledDocument d = support.openDocument (); 64 d.insertString (0, "Ahoj\n", null); 65 assertTrue ("We can do undo now", support.getUndoRedo ().canUndo ()); 66 67 class Blocker implements javax.swing.event.DocumentListener { 68 public void insertUpdate(javax.swing.event.DocumentEvent e) { 69 synchronized (UndoRedoCooperationTest.this) { 70 UndoRedoCooperationTest.this.notify (); 71 try { 72 UndoRedoCooperationTest.this.wait (); 73 } catch (InterruptedException ex) { 74 ex.printStackTrace(); 75 } 76 } 77 } 78 79 public void removeUpdate(javax.swing.event.DocumentEvent e) { 80 } 81 82 public void changedUpdate(javax.swing.event.DocumentEvent e) { 83 } 84 } 85 d.addDocumentListener (new Blocker ()); 86 87 88 class Run implements Runnable { 89 public void run () { 90 try { 91 d.insertString (2, "Kuk", null); 92 } catch (BadLocationException ex) { 93 ex.printStackTrace(); 94 } 95 } 96 } 97 class Undo implements Runnable { 98 public void run () { 99 support.getUndoRedo ().undo (); 100 support.getUndoRedo ().undo (); 101 assertFalse (support.getUndoRedo ().canUndo ()); 102 assertTrue (support.getUndoRedo ().canRedo ()); 103 } 104 } 105 106 RequestProcessor.Task t1, t2; 107 synchronized (this) { 108 t1 = new RequestProcessor ("Inserting into document").post (new Run ()); 109 wait (); 110 t2 = new RequestProcessor ("Doing undo").post (new Undo ()); 112 113 Thread.sleep (100); 115 notify (); 117 } 118 119 t1.waitFinished (); 121 t2.waitFinished (); 122 } 123 124 public void testDeadlock8692 () throws Exception { 125 doTest (0); 126 } 127 128 public void testUndoRedo () throws Exception { 129 doTest (1000); 130 } 131 132 private void doTest (int sleep) throws Exception { 133 final StyledDocument d = support.openDocument (); 134 d.insertString (0, "Ahoj\n", null); 135 support.saveDocument (); 136 assertFalse ("Previous save make it non-modified", support.isModified ()); 137 138 cannotBeModified = "My reason"; 139 140 class R implements Runnable { 141 private Exception ex; 142 143 public void run () { 144 try { 145 d.remove (0, 2); 146 } catch (BadLocationException ex) { 147 this.ex = ex; 148 } 149 } 150 } 151 152 R r = new R (); 153 NbDocument.runAtomic (d, r); 154 155 if (sleep > 0) { 156 Thread.sleep (sleep); 157 } 158 159 javax.swing.SwingUtilities.invokeAndWait (new Runnable () { 162 public void run () { 163 } 165 }); 166 167 assertEquals ("Text contains orignal version", "Aho", d.getText (0, 3)); 168 } 169 170 public void testUndoMustBePossibleWithPlainDocument () throws Exception { 171 support.plain = true; 172 173 final StyledDocument d = support.openDocument (); 174 175 assertTrue ("Document is not empty", d.getLength () > 0); 176 177 d.remove (0, d.getLength ()); 178 String s = d.getText (0, d.getLength ()); 179 assertEquals ("The document is empty", "", s); 180 181 assertTrue ("There is something to undo", support.getUndoRedo ().canUndo ()); 182 support.getUndoRedo ().undo (); 183 184 s = d.getText (0, d.getLength ()); 185 assertEquals ("Contains the original content", content, s); 186 } 187 188 public void testClearTheMap() throws Exception { 189 support.plain = false; 190 191 final StyledDocument d = support.openDocument (); 192 193 support.getUndoRedo().discardAllEdits(); 194 195 assertTrue ("Document is not empty", d.getLength () > 0); 196 197 cannotBeModified = "Cannot"; 198 try { 199 d.remove (0, d.getLength ()); 200 } catch (BadLocationException be) { } 201 202 String s = d.getText (0, d.getLength ()); 203 assertEquals ("The document is the same", "Hello", s); 204 } 205 206 public void testEmptyRunAtomic() throws Exception { 207 content = ""; 208 final StyledDocument d = support.openDocument (); 209 d.insertString(0, "a", null); 210 assertTrue(support.isModified()); 211 NbDocument.runAtomic(d, new Runnable () { 214 public void run() { 215 } 217 }); 218 assertTrue("Empty runAtomic() must not reset the modified flag", support.isModified()); 219 } 220 221 public void testCanUndoDoesNotMarkDocumentUnmodified() throws Exception { 222 content = ""; 223 final StyledDocument d = support.openDocument (); 224 d.insertString(0, "a", null); 225 assertTrue(support.isModified()); 226 assertTrue(support.getUndoRedo().canUndo()); 227 assertTrue("canUndo() must not reset the modified flag", support.isModified()); 228 } 229 230 231 235 public synchronized void addPropertyChangeListener(java.beans.PropertyChangeListener l) { 236 propL.add (l); 237 } 238 public synchronized void removePropertyChangeListener(java.beans.PropertyChangeListener l) { 239 propL.remove (l); 240 } 241 242 public synchronized void addVetoableChangeListener(java.beans.VetoableChangeListener l) { 243 assertNull ("This is the first veto listener", vetoL); 244 vetoL = l; 245 } 246 public void removeVetoableChangeListener(java.beans.VetoableChangeListener l) { 247 assertEquals ("Removing the right veto one", vetoL, l); 248 vetoL = null; 249 } 250 251 public org.openide.windows.CloneableOpenSupport findCloneableOpenSupport() { 252 return support; 253 } 254 255 public String getMimeType() { 256 return "text/plain"; 257 } 258 259 public java.util.Date getTime() { 260 return date; 261 } 262 263 public java.io.InputStream inputStream() throws java.io.IOException { 264 return new java.io.ByteArrayInputStream (content.getBytes ()); 265 } 266 public java.io.OutputStream outputStream() throws java.io.IOException { 267 class ContentStream extends java.io.ByteArrayOutputStream { 268 public void close () throws java.io.IOException { 269 super.close (); 270 content = new String (toByteArray ()); 271 } 272 } 273 274 return new ContentStream (); 275 } 276 277 public boolean isValid() { 278 return valid; 279 } 280 281 public boolean isModified() { 282 return modified; 283 } 284 285 public void markModified() throws java.io.IOException { 286 if (cannotBeModified != null) { 287 IOException e = new IOException (); 288 Exceptions.attachLocalizedMessage(e, cannotBeModified); 289 throw e; 290 } 291 292 modified = true; 293 } 294 295 public void unmarkModified() { 296 modified = false; 297 } 298 299 300 private final class CES extends CloneableEditorSupport { 301 public boolean plain; 302 303 304 public CES (Env env, org.openide.util.Lookup l) { 305 super (env, l); 306 } 307 308 protected String messageName() { 309 return "Name"; 310 } 311 312 protected String messageOpened() { 313 return "Opened"; 314 } 315 316 protected String messageOpening() { 317 return "Opening"; 318 } 319 320 protected String messageSave() { 321 return "Save"; 322 } 323 324 protected String messageToolTip() { 325 return "ToolTip"; 326 } 327 328 protected javax.swing.text.EditorKit createEditorKit() { 329 if (plain) { 330 return super.createEditorKit (); 331 } else { 332 return UndoRedoCooperationTest.this.createEditorKit (); 333 } 334 } 335 } 337 } 338 | Popular Tags |