Added
Link Here
|
1 |
/* |
2 |
* The contents of this file are subject to the terms of the Common Development |
3 |
* and Distribution License (the License). You may not use this file except in |
4 |
* compliance with the License. |
5 |
* |
6 |
* You can obtain a copy of the License at http://www.netbeans.org/cddl.html |
7 |
* or http://www.netbeans.org/cddl.txt. |
8 |
* |
9 |
* When distributing Covered Code, include this CDDL Header Notice in each file |
10 |
* and include the License file at http://www.netbeans.org/cddl.txt. |
11 |
* If applicable, add the following below the CDDL Header, with the fields |
12 |
* enclosed by brackets [] replaced by your own identifying information: |
13 |
* "Portions Copyrighted [year] [name of copyright owner]" |
14 |
* |
15 |
* The Original Software is NetBeans. The Initial Developer of the Original |
16 |
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun |
17 |
* Microsystems, Inc. All Rights Reserved. |
18 |
*/ |
19 |
|
20 |
package org.openide.text; |
21 |
|
22 |
|
23 |
import java.beans.PropertyChangeListener; |
24 |
import java.io.*; |
25 |
import java.util.ArrayList; |
26 |
import java.util.List; |
27 |
import javax.swing.JEditorPane; |
28 |
import junit.framework.*; |
29 |
import org.netbeans.junit.*; |
30 |
import org.openide.util.Lookup; |
31 |
import org.openide.util.Mutex; |
32 |
import org.openide.util.lookup.*; |
33 |
|
34 |
|
35 |
/** Testing the behavior of editor reusal framework. |
36 |
* The behavior was discussed thoroughly at issue 94607. |
37 |
* |
38 |
* @author Petr Nejedly |
39 |
*/ |
40 |
public class ReusableEditorTest extends NbTestCase { |
41 |
CES c1, c2, c3; |
42 |
|
43 |
/** |
44 |
* Test ctor |
45 |
* @param testName |
46 |
*/ |
47 |
public ReusableEditorTest(java.lang.String testName) { |
48 |
super(testName); |
49 |
} |
50 |
|
51 |
|
52 |
/** |
53 |
* Prepares few editors at the test dispoition. |
54 |
*/ |
55 |
protected void setUp () { |
56 |
c1 = createSupport("c1"); |
57 |
c2 = createSupport("c2"); |
58 |
c3 = createSupport("c3"); |
59 |
} |
60 |
|
61 |
/** |
62 |
* Closes any precreated editors left open. |
63 |
*/ |
64 |
@Override |
65 |
protected void tearDown() { |
66 |
forceClose(c1); |
67 |
forceClose(c2); |
68 |
forceClose(c3); |
69 |
} |
70 |
|
71 |
/** |
72 |
* Test that verifies SHOW_REUSE closes original tab (keeps only one) |
73 |
* Scenario: |
74 |
* 1. Open first file with SHOW_REUSE |
75 |
* 2. Open second file with SHOW_REUSE |
76 |
* 3. Verify first is closed |
77 |
* 4. Open first file with SHOW_REUSE |
78 |
* 5. Verify second is closed |
79 |
*/ |
80 |
public void testReuse() { |
81 |
openAndCheck(c1, Line.SHOW_REUSE); // 1 |
82 |
openAndCheck(c2, Line.SHOW_REUSE); // 2 |
83 |
assertClosed(c1); // 3 |
84 |
openAndCheck(c1, Line.SHOW_REUSE); // 4 |
85 |
assertClosed(c2); // 5 |
86 |
} |
87 |
|
88 |
/** Test that verifies SHOW_REUSE doesn't reuse modified, even saved tab |
89 |
* 1. Open first file with SHOW_REUSE |
90 |
* 2. Modify it |
91 |
* 3. Open second file with SHOW_REUSE |
92 |
* 4. Verify first still open |
93 |
* 5. Modify second file |
94 |
* 6. Unmodify second file |
95 |
* 7. Open third file with SHOW_REUSE |
96 |
* 8. Verify second still open |
97 |
*/ |
98 |
public void testKeepTouched() { |
99 |
openAndCheck(c1, Line.SHOW_REUSE); // 1 |
100 |
c1.notifyModified(); // 2 |
101 |
openAndCheck(c2, Line.SHOW_REUSE); // 3 |
102 |
assertOpened(c1); // 4 |
103 |
c2.notifyModified(); // 5 |
104 |
c2.notifyUnmodified(); // 6 |
105 |
openAndCheck(c3, Line.SHOW_REUSE); // 7 |
106 |
assertOpened(c2); // 8 |
107 |
assertOpened(c1); |
108 |
} |
109 |
|
110 |
/** Test that verifies SHOW_REUSE don't consider non-reusable tabs. |
111 |
* There are three things tested: |
112 |
* A) Don't replace ordinary tabs |
113 |
* B) Don't mark ordinary tabs as reusable if switched to |
114 |
* C) Keep reusable tab mark even through (B) |
115 |
* |
116 |
* Scenario: |
117 |
* 1. Open first file using SHOW_GOTO |
118 |
* 2. Open second file using SHOW_REUSE |
119 |
* 3. Verify first still opened (A) |
120 |
* 4. open first using SHOW_REUSE |
121 |
* 5. verify second still opened |
122 |
* 6. open third file using SHOW_REUSE |
123 |
* 7. verify first still opened (B) |
124 |
* 8. verify second closed (C) |
125 |
*/ |
126 |
public void testLeaveNonreusable() { |
127 |
openAndCheck(c1, Line.SHOW_GOTO); // 1 |
128 |
openAndCheck(c2, Line.SHOW_REUSE); // 2 |
129 |
assertOpened(c1); // 3 |
130 |
|
131 |
openAndCheck(c1, Line.SHOW_REUSE); // 4 |
132 |
assertOpened(c2); // 5 |
133 |
openAndCheck(c3, Line.SHOW_REUSE); // 6 |
134 |
assertOpened(c1); // 7 |
135 |
|
136 |
assertClosed(c2); // 8 |
137 |
} |
138 |
|
139 |
/** Test that verifies SHOW_REUSE_NEW don't close existing reusable tab, |
140 |
* but can be reused itself |
141 |
* |
142 |
* Scenario: |
143 |
* 1. Open first file using SHOW_REUSE |
144 |
* 2. Open second file using SHOW_REUSE_NEW |
145 |
* 3. Verify first still opened |
146 |
* 4. Open third using SHOW_REUSE |
147 |
* 5. verify second closed |
148 |
*/ |
149 |
public void testReuseNewKeepsOld() { |
150 |
openAndCheck(c1, Line.SHOW_REUSE); // 1 |
151 |
openAndCheck(c2, Line.SHOW_REUSE_NEW); // 2 |
152 |
assertOpened(c1); // 3 |
153 |
openAndCheck(c3, Line.SHOW_REUSE); // 4 |
154 |
assertClosed(c2); // 5 |
155 |
} |
156 |
|
157 |
/** |
158 |
* Test that specifies behaviour of SHOW_REUSE_NEW in case currently |
159 |
* reusable tab is not the selected one. |
160 |
* |
161 |
* Scenario: |
162 |
* 1. Open first file using SHOW_REUSE |
163 |
* 2. Open second file using SHOW_GOTO |
164 |
* 3. Open third file using SHOW_REUSE_NEW |
165 |
* 4. Verify first still open. |
166 |
*/ |
167 |
public void testReuseNewKeepsOldEvenWhenNotFocused() { |
168 |
openAndCheck(c1, Line.SHOW_REUSE); // 1 |
169 |
openAndCheck(c2, Line.SHOW_GOTO); // 2 |
170 |
openAndCheck(c3, Line.SHOW_REUSE_NEW); // 3 |
171 |
assertOpened(c1); // 4 |
172 |
} |
173 |
|
174 |
private CES createSupport(String txt) { |
175 |
Env env = new Env(); |
176 |
env.content = txt; |
177 |
CES c = new CES(env, Lookups.singleton(txt)); |
178 |
env.support = c; |
179 |
return c; |
180 |
} |
181 |
|
182 |
private void openAndCheck(final CES ces, final int mode) { |
183 |
Mutex.EVENT.readAccess(new Mutex.Action<Void>() { |
184 |
public Void run() { |
185 |
ces.getLineSet().getCurrent(0).show(mode); |
186 |
return null; |
187 |
} |
188 |
|
189 |
}); |
190 |
assertOpened(ces); |
191 |
} |
192 |
|
193 |
private void forceClose(CES ces) { |
194 |
if (ces.isModified()) ces.notifyUnmodified(); |
195 |
ces.close(); |
196 |
} |
197 |
|
198 |
private void assertClosed(CES ces) { |
199 |
assertEquals(0, getOpenedCount(ces)); |
200 |
} |
201 |
|
202 |
private void assertOpened(CES ces) { |
203 |
assertEquals(1, getOpenedCount(ces)); |
204 |
} |
205 |
|
206 |
private int getOpenedCount(final CES ces) { |
207 |
return Mutex.EVENT.readAccess(new Mutex.Action<Integer>() { |
208 |
public Integer run() { |
209 |
JEditorPane[] panes = ces.getOpenedPanes(); |
210 |
return panes == null ? 0 : panes.length; |
211 |
} |
212 |
}); |
213 |
} |
214 |
|
215 |
|
216 |
|
217 |
// |
218 |
// Implementation of the CloneableEditorSupport.Env |
219 |
// |
220 |
private class Env implements CloneableEditorSupport.Env { |
221 |
// Env variables |
222 |
private String content = ""; |
223 |
private boolean valid = true; |
224 |
private boolean modified = false; |
225 |
private java.util.Date date = new java.util.Date (); |
226 |
private List<PropertyChangeListener> propL = new ArrayList<PropertyChangeListener>(); |
227 |
private java.beans.VetoableChangeListener vetoL; |
228 |
/** the support to work with */ |
229 |
CloneableEditorSupport support; |
230 |
|
231 |
public synchronized void addPropertyChangeListener(PropertyChangeListener l) { |
232 |
propL.add (l); |
233 |
} |
234 |
public synchronized void removePropertyChangeListener(PropertyChangeListener l) { |
235 |
propL.remove (l); |
236 |
} |
237 |
|
238 |
public synchronized void addVetoableChangeListener(java.beans.VetoableChangeListener l) { |
239 |
assertNull ("This is the first veto listener", vetoL); |
240 |
vetoL = l; |
241 |
} |
242 |
public void removeVetoableChangeListener(java.beans.VetoableChangeListener l) { |
243 |
assertEquals ("Removing the right veto one", vetoL, l); |
244 |
vetoL = null; |
245 |
} |
246 |
|
247 |
public org.openide.windows.CloneableOpenSupport findCloneableOpenSupport() { |
248 |
return support; |
249 |
} |
250 |
|
251 |
public String getMimeType() { |
252 |
return "text/plain"; |
253 |
} |
254 |
|
255 |
public java.util.Date getTime() { |
256 |
return date; |
257 |
} |
258 |
|
259 |
public java.io.InputStream inputStream() throws java.io.IOException { |
260 |
return new java.io.ByteArrayInputStream (content.getBytes ()); |
261 |
} |
262 |
public java.io.OutputStream outputStream() throws java.io.IOException { |
263 |
class ContentStream extends java.io.ByteArrayOutputStream { |
264 |
public void close () throws java.io.IOException { |
265 |
super.close (); |
266 |
content = new String (toByteArray ()); |
267 |
} |
268 |
} |
269 |
|
270 |
return new ContentStream (); |
271 |
} |
272 |
|
273 |
public boolean isValid() { |
274 |
return valid; |
275 |
} |
276 |
|
277 |
public boolean isModified() { |
278 |
return modified; |
279 |
} |
280 |
|
281 |
public void markModified() throws java.io.IOException { |
282 |
modified = true; |
283 |
} |
284 |
|
285 |
public void unmarkModified() { |
286 |
modified = false; |
287 |
} |
288 |
} |
289 |
|
290 |
/** Implementation of the CES */ |
291 |
private static final class CES extends CloneableEditorSupport { |
292 |
public CES (Env env, Lookup l) { |
293 |
super (env, l); |
294 |
} |
295 |
|
296 |
protected String messageName() { |
297 |
return "Name"; |
298 |
} |
299 |
|
300 |
protected String messageOpened() { |
301 |
return "Opened"; |
302 |
} |
303 |
|
304 |
protected String messageOpening() { |
305 |
return "Opening"; |
306 |
} |
307 |
|
308 |
protected String messageSave() { |
309 |
return "Save"; |
310 |
} |
311 |
|
312 |
protected String messageToolTip() { |
313 |
return "ToolTip"; |
314 |
} |
315 |
|
316 |
} |
317 |
|
318 |
} |