KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > rice > cs > drjava > model > SingleDisplayModelTest


1 /*BEGIN_COPYRIGHT_BLOCK
2  *
3  * This file is part of DrJava. Download the current version of this project from http://www.drjava.org/
4  * or http://sourceforge.net/projects/drjava/
5  *
6  * DrJava Open Source License
7  *
8  * Copyright (C) 2001-2005 JavaPLT group at Rice University (javaplt@rice.edu). All rights reserved.
9  *
10  * Developed by: Java Programming Languages Team, Rice University, http://www.cs.rice.edu/~javaplt/
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
13  * documentation files (the "Software"), to deal with the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
15  * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
16  *
17  * - Redistributions of source code must retain the above copyright notice, this list of conditions and the
18  * following disclaimers.
19  * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
20  * following disclaimers in the documentation and/or other materials provided with the distribution.
21  * - Neither the names of DrJava, the JavaPLT, Rice University, nor the names of its contributors may be used to
22  * endorse or promote products derived from this Software without specific prior written permission.
23  * - Products derived from this software may not be called "DrJava" nor use the term "DrJava" as part of their
24  * names without prior written permission from the JavaPLT group. For permission, write to javaplt@rice.edu.
25  *
26  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
27  * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28  * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
29  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
30  * WITH THE SOFTWARE.
31  *
32  *END_COPYRIGHT_BLOCK*/

33
34 package edu.rice.cs.drjava.model;
35
36 import javax.swing.text.BadLocationException JavaDoc;
37 import java.io.File JavaDoc;
38 import java.io.IOException JavaDoc;
39
40 import java.util.Arrays JavaDoc;
41
42 import edu.rice.cs.util.FileOpenSelector;
43 import edu.rice.cs.util.Log;
44 import edu.rice.cs.util.OperationCanceledException;
45 import edu.rice.cs.util.StringOps;
46 import edu.rice.cs.util.swing.Utilities;
47
48 /** Test functions of the single display model.
49  * @version $Id: SingleDisplayModelTest.java 4043 2006-11-22 23:04:59Z rcartwright $
50  */

51 public class SingleDisplayModelTest extends GlobalModelTestCase {
52
53   // _log is inherited from GlobalModelTestCase
54

55   private Object JavaDoc _readyLock = new Object JavaDoc(); // lock used for wait/notify on interpreterReady event
56

57   /** Get the instance of the SingleDisplayModel.*/
58   private DefaultGlobalModel getSDModel() { return _model; }
59
60   protected void assertNotEmpty() {
61     assertTrue("number of documents", getSDModel().getOpenDefinitionsDocuments().size() > 0);
62   }
63
64   protected void assertActiveDocument(OpenDefinitionsDocument doc) {
65     assertEquals("active document", doc, getSDModel().getActiveDocument());
66   }
67
68   /** Creates and returns a new document, makes sure newFile and activeDocumentChanged events are fired, and then
69    * adds some text.
70    * @return the new modified document
71    */

72   protected OpenDefinitionsDocument setupDocument(String JavaDoc text) throws BadLocationException JavaDoc {
73     
74     assertNotEmpty();
75     SDTestListener listener = new SDTestListener() {
76       public synchronized void newFileCreated(OpenDefinitionsDocument doc) { newCount++; }
77       public synchronized void activeDocumentChanged(OpenDefinitionsDocument doc) { switchCount++; }
78     };
79
80     getSDModel().addListener(listener);
81
82     listener.assertSwitchCount(0);
83
84     // Open a new document
85
int numOpen = getSDModel().getOpenDefinitionsDocuments().size();
86     OpenDefinitionsDocument doc = getSDModel().newFile();
87     assertNumOpenDocs(numOpen + 1);
88
89     listener.assertNewCount(1);
90     listener.assertSwitchCount(1);
91     assertLength(0, doc);
92     assertModified(false, doc);
93
94     changeDocumentText(text, doc); // not atomic but no other thread is trying to modify doc
95
getSDModel().removeListener(listener);
96     
97     _log.log("New File " + doc + " created");
98
99     return doc;
100   }
101
102   /** Tests the invariant that at least one document is open at time of creation. */
103   public void testNotEmptyOnStartup() throws BadLocationException JavaDoc {
104     // Should be one empty document after creation
105
assertNumOpenDocs(1);
106     OpenDefinitionsDocument doc = getSDModel().getActiveDocument();
107     assertModified(false, doc);
108     assertLength(0, doc);
109     _log.log("testNotEmptyOnStartup completed");
110   }
111
112   /** Tests the setNext and setPrevious functions, making sure that the activeDocumentChanged event is called. */
113   public void testDocumentSwitching() throws BadLocationException JavaDoc {
114     // Check for proper events
115
SDTestListener listener = new SDTestListener() {
116       public synchronized void newFileCreated(OpenDefinitionsDocument doc) { newCount++; }
117       public synchronized void activeDocumentChanged(OpenDefinitionsDocument doc) { switchCount++; }
118     };
119     getSDModel().addListener(listener);
120
121     // Set up first document
122
OpenDefinitionsDocument doc3 = getSDModel().getActiveDocument();
123     changeDocumentText(FOO_TEXT, doc3);
124     listener.assertSwitchCount(0);
125
126     // Set up two more documents
127
OpenDefinitionsDocument doc2 = setupDocument(BAR_TEXT);
128     assertNumOpenDocs(2);
129     listener.assertNewCount(1);
130     listener.assertSwitchCount(1);
131     assertActiveDocument(doc2);
132
133     OpenDefinitionsDocument doc1 = setupDocument(BAZ_TEXT);
134     assertNumOpenDocs(3);
135     listener.assertNewCount(2);
136     listener.assertSwitchCount(2);
137     assertActiveDocument(doc1);
138
139     // Make sure setPrevious doesn't move (at start of list)
140
getSDModel().setActivePreviousDocument();
141     listener.assertSwitchCount(3);
142     assertActiveDocument(doc3);
143
144     // Test setPrevious
145
getSDModel().setActiveNextDocument();
146     listener.assertSwitchCount(4);
147     assertActiveDocument(doc1);
148     
149     // Test setPrevious
150
getSDModel().setActiveNextDocument();
151     listener.assertSwitchCount(5);
152     assertActiveDocument(doc2);
153
154     getSDModel().setActiveNextDocument();
155     listener.assertSwitchCount(6);
156     assertActiveDocument(doc3);
157
158     // Make sure setNext doesn't move (at end of list)
159
getSDModel().setActiveNextDocument();
160     listener.assertSwitchCount(7);
161     assertActiveDocument(doc1);
162
163     // Test setPrevious
164
getSDModel().setActivePreviousDocument();
165     listener.assertSwitchCount(8);
166     assertActiveDocument(doc3);
167
168     // Test setActive
169
getSDModel().setActiveDocument(doc1);
170     listener.assertSwitchCount(9);
171     assertActiveDocument(doc1);
172
173     // Make sure number of docs hasn't changed
174
assertNumOpenDocs(3);
175     getSDModel().removeListener(listener);
176     _log.log("testDocumentSwitching completed");
177   }
178
179   /** Ensures that an unmodified, empty document is closed after a file is opened, while a modified document
180    * is left open.
181    */

182   public void testCloseUnmodifiedAutomatically() throws BadLocationException JavaDoc, IOException JavaDoc,
183     OperationCanceledException, AlreadyOpenException {
184     
185     assertNumOpenDocs(1); // This assertion depends on the active document being set before setUp() is finished
186
OpenDefinitionsDocument doc = getSDModel().getActiveDocument();
187     assertModified(false, doc);
188     assertLength(0, doc);
189
190     final File JavaDoc tempFile = writeToNewTempFile(BAR_TEXT);
191
192     // Check for proper events
193
SDTestListener listener = new SDTestListener() {
194       public void fileOpened(OpenDefinitionsDocument doc) {
195         File JavaDoc file = null;
196         try { file = doc.getFile(); }
197         catch (FileMovedException fme) {
198           // We know file should exist
199
fail("file does not exist");
200         }
201         try {
202           assertEquals("file to open", tempFile.getCanonicalFile(), file.getCanonicalFile());
203           synchronized(this) { openCount++; }
204         }
205         catch (IOException JavaDoc ioe) { fail("could not get canonical file"); }
206       }
207       public synchronized void fileClosed(OpenDefinitionsDocument doc) { closeCount++; }
208       public synchronized void activeDocumentChanged(OpenDefinitionsDocument doc) { switchCount++; }
209     };
210     getSDModel().addListener(listener);
211
212     // Open file, should replace the old
213
doc = getSDModel().openFile(new FileSelector(tempFile));
214     listener.assertOpenCount(1);
215     listener.assertCloseCount(1);
216     listener.assertSwitchCount(1);
217     assertNumOpenDocs(1);
218     assertModified(false, doc);
219     assertContents(BAR_TEXT, doc);
220     getSDModel().removeListener(listener);
221     _log.log("testCloseUnmodifiedAutomatically completed");
222   }
223
224   /** Tests that active document is switched on close, and that a new file is created after the last one is closed. */
225   public void testCloseFiles() throws BadLocationException JavaDoc {
226     // Check for proper events
227
SDTestListener listener = new SDTestListener() {
228       public synchronized boolean canAbandonFile(OpenDefinitionsDocument doc) {
229         canAbandonCount++;
230         return true; // yes allow the abandon
231
}
232       public synchronized void newFileCreated(OpenDefinitionsDocument doc) { newCount++; }
233       public synchronized void fileClosed(OpenDefinitionsDocument doc) { closeCount++; }
234       public synchronized void activeDocumentChanged(OpenDefinitionsDocument doc) { switchCount++; }
235       public synchronized void interpreterReady(File JavaDoc wd) { // closing all files calls resetInteractions
236
// Utilities.show("interpreterReady(" + wd + ") called");
237
// Utilities.show("Traceback is:\n" + StringOps.getStackTrace());
238
interpreterReadyCount++;
239         synchronized(_readyLock) { _readyLock.notify(); }
240       }
241     };
242     
243     _model.addListener(listener);
244     
245     // Set up two documents
246
OpenDefinitionsDocument doc1 = _model.getActiveDocument();
247     changeDocumentText(FOO_TEXT, doc1);
248     OpenDefinitionsDocument doc2 = setupDocument(BAR_TEXT);
249     assertActiveDocument(doc2);
250     assertNumOpenDocs(2);
251     listener.assertNewCount(1);
252     listener.assertSwitchCount(1);
253
254     // Close one
255
_model.closeFile(_model.getActiveDocument());
256     assertNumOpenDocs(1);
257     listener.assertCloseCount(1);
258     listener.assertAbandonCount(1);
259     listener.assertSwitchCount(2);
260     assertActiveDocument(doc1);
261     assertContents(FOO_TEXT, _model.getActiveDocument());
262
263     // Close the other
264
_model.closeFile(_model.getActiveDocument());
265     listener.assertCloseCount(2);
266     listener.assertAbandonCount(2);
267
268     // Ensure a new document was created
269
assertNumOpenDocs(1);
270     listener.assertNewCount(2);
271     listener.assertSwitchCount(3);
272     assertLength(0, _model.getActiveDocument());
273     
274     _log.log("Starting second phase of testCloseFiles");
275
276     // Set up two documents
277
doc1 = _model.getActiveDocument();
278     changeDocumentText(FOO_TEXT, doc1);
279     doc2 = setupDocument(BAR_TEXT);
280     assertNumOpenDocs(2);
281     listener.assertNewCount(3);
282     
283     _log.log("Just before calling _model.closeAllFiles()");
284
285     // Close all files, ensure new one was created
286
_model.closeAllFiles();
287     Utilities.clearEventQueue();
288     assertNumOpenDocs(1);
289     assertLength(0, _model.getActiveDocument());
290     
291     // wait for interpreter to be ready
292
try {
293       synchronized(_readyLock) {
294         if (listener.getInterpreterReadyCount() == 0) _readyLock.wait(10000); // intentionally not a while
295
}
296     }
297     catch(InterruptedException JavaDoc e) { fail("Wait for interpreterReady event was interrupted by " + e); }
298     listener.assertInterpreterReadyCount(1);
299     listener.assertNewCount(4);
300     listener.assertCloseCount(4);
301     listener.assertAbandonCount(4);
302
303     _model.removeListener(listener);
304 // _log.log("testCloseFiles completed");
305
}
306
307   /** Tests the getCompleteFileName method. */
308   public void testCompleteFilename() throws BadLocationException JavaDoc, IOException JavaDoc, OperationCanceledException,
309     AlreadyOpenException {
310     // Untitled
311
OpenDefinitionsDocument doc = _model.getActiveDocument();
312     assertEquals("untitled display filename", "(Untitled)", doc.getCompletePath());
313
314     // Ends in ".java"
315
File JavaDoc file = File.createTempFile("DrJava-filename-test", ".java", _tempDir).getCanonicalFile();
316     file.deleteOnExit();
317     String JavaDoc name = file.getAbsolutePath();
318     doc = _model.openFile(new FileSelector(file));
319             
320     assertEquals(".java display filename", name, doc.getCompletePath());
321
322     // Doesn't contain ".java"
323
file = File.createTempFile("DrJava-filename-test", ".txt", _tempDir).getCanonicalFile();
324     file.deleteOnExit();
325     name = file.getAbsolutePath();
326     doc = _model.openFile(new FileSelector(file));
327     assertEquals(".txt display filename", name, doc.getCompletePath());
328
329     // Modified File
330
file = File.createTempFile("DrJava-filename-test", ".java", _tempDir).getCanonicalFile();
331     file.deleteOnExit();
332     name = file.getAbsolutePath();
333     doc = _model.openFile(new FileSelector(file));
334     changeDocumentText("foo", doc);
335     assertEquals(".java.txt display filename", name + " *", doc.getCompletePath());
336     _log.log("testDisplayFilename completed");
337   }
338   
339   public void testDeleteFileWhileOpen()
340     throws IOException JavaDoc, OperationCanceledException, AlreadyOpenException {
341     String JavaDoc txt = "This is some test text";
342     File JavaDoc f = writeToNewTempFile(txt);
343     OpenDefinitionsDocument doc1 = _model.openFile(new FileSelector(f));
344     OpenDefinitionsDocument doc2 = _model.newFile();
345     f.delete();
346     _model.closeFile(doc1);
347      _log.log("testDeleteFileWhileOpen completed");
348     // TODO: possibly test with more files; test to make sure the
349
// active document get's switched correctly.
350

351     // Closing one file works. It doesn't work when you are closing
352
// multiple files including the one that doesn't exist on the file system.
353

354     // Furthermore, if the user clicks "YES" to save to a different location,
355
// it doesn't prompt for the location to save, but immediately procedes with
356
// the closing and runs into the DocumentNotFound exception which ultimately
357
// leads to the View breaking. Solution may lie in whatever is not letting
358
// the file selector show up when clicking "YES" to resave.
359
}
360   public void testDeleteFileBeforeCloseAll()
361     throws IOException JavaDoc, OperationCanceledException, AlreadyOpenException {
362     final File JavaDoc[] files = new File JavaDoc[10];
363     for (int i = 0; i < 10; i++) {
364       String JavaDoc txt = "Text for file " + i;
365       files[i] = writeToNewTempFile(txt);
366     }
367     FileOpenSelector fos = new FileOpenSelector() {
368       public File JavaDoc[] getFiles() throws OperationCanceledException { return files; }
369     };
370     _model.openFiles(fos);
371     _log.log("Opened files " + Arrays.toString(files));
372     OpenDefinitionsDocument doc = _model.getSortedOpenDefinitionsDocuments().get(5);
373     _model.setActiveDocument(doc);
374     _log.log("Active document is: " + doc);
375     files[5].delete();
376     _log.log("Delected document: " + doc);
377     _model.closeAllFiles();
378     _log.log("testDeleteFileBeforeCloseAll completed");
379   }
380   
381   /** A GlobalModelListener for testing. By default it expects no events to be fired. To customize,
382     * subclass and override one or more methods.
383     */

384   public static class SDTestListener extends TestListener implements GlobalModelListener {
385     
386     /** Extra counter for SDTestListener */
387     protected volatile int switchCount;
388
389     public void resetCounts() {
390       super.resetCounts();
391       switchCount = 0;
392     }
393
394     public void assertSwitchCount(int i) { assertEquals("number of active document switches", i, switchCount); }
395
396     public void activeDocumentChanged(OpenDefinitionsDocument doc) {
397       fail("activeDocumentChanged fired unexpectedly");
398     }
399     
400     public int getInterpreterReadyCount() { return interpreterReadyCount; }
401   }
402 }
403
Popular Tags