KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > test > jsf > el > CompletionTest


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-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.test.jsf.el;
21 import java.awt.Color JavaDoc;
22 import java.awt.Component JavaDoc;
23 import java.awt.Font JavaDoc;
24 import java.awt.Graphics JavaDoc;
25 import java.beans.PropertyChangeEvent JavaDoc;
26 import java.beans.PropertyChangeListener JavaDoc;
27 import java.io.File JavaDoc;
28 import java.lang.reflect.Method JavaDoc;
29 import java.util.Arrays JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.List JavaDoc;
32 import javax.swing.JEditorPane JavaDoc;
33 import javax.swing.JLabel JavaDoc;
34 import javax.swing.JList JavaDoc;
35 import javax.swing.SwingUtilities JavaDoc;
36 import javax.swing.text.Caret JavaDoc;
37 import junit.framework.Test;
38 import org.netbeans.editor.Utilities;
39 import org.netbeans.editor.ext.CompletionQuery.ResultItem;
40 import org.netbeans.jellytools.JellyTestCase;
41 import org.netbeans.jellytools.modules.editor.CompletionJListOperator;
42 import org.netbeans.jemmy.JemmyException;
43 import org.netbeans.jemmy.util.PNGEncoder;
44 import org.netbeans.junit.AssertionFailedErrorException;
45 import org.netbeans.junit.NbTestCase;
46 import org.netbeans.editor.BaseDocument;
47 import org.netbeans.spi.editor.completion.CompletionItem;
48 import org.netbeans.editor.TokenID;
49 import org.netbeans.editor.TokenItem;
50 import org.netbeans.editor.ext.ExtSyntaxSupport;
51 import org.openide.actions.UndoAction;
52 import org.openide.cookies.EditorCookie;
53 import org.openide.cookies.EditorCookie.Observable;
54 import org.openide.filesystems.FileObject;
55 import org.openide.loaders.DataObject;
56 import org.openide.util.actions.SystemAction;
57
58
59
60 /**
61  * Test goes throught files and looking for CC Test Steps.
62  * The CC Test Steps are writen in document body as three lines:
63  * JSP comments which start with '<%--CC' prefix, where:
64  *<ul>
65  *<li> first line contains ccPrefix with optional '|' character which represents
66  * cursor position
67  *<li> second line contains ccChoice item which will be used for CC substitution
68  *<li> third line contains ccResult
69  *</ul>
70  *
71  * For example:<p>
72  * <pre><%--CC
73  * <%@ taglib |
74  * uri
75  * <%@ taglib uri=""
76  * --%>
77  * </pre><p>
78  * does:
79  * <ul>
80  * <li> inserts '<%@ taglib ' string into new line
81  * <li> invokes CC
82  * <li> dumps Completion Query Result
83  * <li> choses "uri" item from the query result and substitute it
84  * <li> checks if subtituted line is: '<%@ taglib uri=""'
85  * <li> undoes all changes
86  * </ul>
87  * @author ms113234
88  *
89  */

90 public class CompletionTest extends JellyTestCase {
91     private FileObject testFileObj;
92     protected boolean debug = false;
93     protected final static List JavaDoc xmlExts = Arrays.asList(new String JavaDoc[]
94     {"xml","xsd","html","tld","jspx"});
95     protected final static List JavaDoc jspExts = Arrays.asList(new String JavaDoc[] {"jsp","tag"});
96     
97     /** Need to be defined because of JUnit */
98     public CompletionTest(String JavaDoc name, FileObject testFileObj) {
99         super(name);
100         this.testFileObj = testFileObj;
101     }
102     
103     public void setUp() {
104         System.out.println("######## "+getName()+" #######");
105     }
106     
107     public static Test suite() {
108         // find folder with test projects and define file objects filter
109
File JavaDoc dataDir = new CompletionTest(null, null).getDataDir();
110         File JavaDoc projectsDir = new File JavaDoc(dataDir, "tests");
111         FileObjectFilter filter = new FileObjectFilter() {
112             public boolean accept(FileObject fo) {
113                 String JavaDoc ext = fo.getExt();
114                 String JavaDoc name = fo.getName();
115                 return (name.startsWith("test") || name.startsWith("Test"))
116                 && (xmlExts.contains(ext) || jspExts.contains(ext) || jspExts.equals("java"));
117             }
118         };
119         return RecurrentSuiteFactory.createSuite(CompletionTest.class,
120                 projectsDir, filter);
121     }
122     
123     public void runTest() throws Exception JavaDoc {
124         String JavaDoc ext = testFileObj.getExt();
125         if (jspExts.contains(ext)) {
126             test(testFileObj, "<%--CC", "--%>");
127         } else if (xmlExts.contains(ext)) {
128             test(testFileObj, "<!--CC", "-->");
129         } else if (ext.equals("java")) {
130             test(testFileObj, "/**CC", "*/");
131         } else {
132             throw new JemmyException("File extension of: "+testFileObj.getNameExt()
133             +" is unsupported.");
134         }
135     }
136     
137     private void test(FileObject fileObj, String JavaDoc stepStart, String JavaDoc stepEnd) throws Exception JavaDoc {
138         boolean inStepData = false;
139         String JavaDoc[] stepData = new String JavaDoc[3];
140         int dataLineIdx = 0;
141         
142         try {
143             // get token chain
144
DataObject dataObj = DataObject.find(fileObj);
145             EditorCookie.Observable ed = (Observable) dataObj.getCookie(Observable.class);
146             
147             // prepare synchronization and register listener
148
final Waiter waiter = new Waiter();
149             final PropertyChangeListener JavaDoc pcl = new PropertyChangeListener JavaDoc() {
150                 public void propertyChange(PropertyChangeEvent JavaDoc evt) {
151                     if (evt.getPropertyName().equals(Observable.PROP_OPENED_PANES)) {
152                         waiter.notifyFinished();
153                     }
154                 }
155             };
156             ed.addPropertyChangeListener(pcl);
157             // open document
158
BaseDocument doc = (BaseDocument) ed.openDocument();
159             ed.open();
160             // wait for PROP_OPENED_PANES and remove listener
161
assertTrue("The editor pane was not opened in 10 secs.", waiter.waitFinished(10000));
162             ed.removePropertyChangeListener(pcl);
163             // wait 2s for editor initialization
164
Thread.sleep(3000);
165             JEditorPane JavaDoc editor = ed.getOpenedPanes()[0];
166             ExtSyntaxSupport ess = (ExtSyntaxSupport) doc.getSyntaxSupport();
167             TokenItem token = ess.getTokenChain(0, doc.getLength());
168             List JavaDoc steps = new java.util.ArrayList JavaDoc();
169             // go through token chain an look for CC test steps
170
while (token != null) {
171                 TokenID tokenID = token.getTokenID();
172                 if (debug) {
173                     String JavaDoc tImage = token.getImage();
174                     int tEnd = token.getOffset() + tImage.length();
175                     System.err.println("# [" + token.getOffset() + "," + tEnd + "] "
176                             + tokenID.getName() + " :: " + token.getImage());
177                 }
178                 if (tokenID.getName().indexOf("comment") == -1) {
179                     token = token.getNext();
180                     continue;
181                 }
182                 if (inStepData){
183                     // probably end of step data
184
if (token.getImage().indexOf(stepEnd) > -1) {
185                         inStepData = false;
186                         // check obtained CC data and create test step CCsecs
187
if (dataLineIdx == 3) {
188                             int offset = token.getOffset() + token.getImage()
189                             .length();
190                             TestStep step = new TestStep(stepData, offset);
191                             steps.add(step);
192                         } else {
193                             ref("EE: expected data lines number: 3 but was: "
194                                     + dataLineIdx);
195                         }
196                     } else {
197                         // assert CC TEst Data lenght
198
if (dataLineIdx > 2) {
199                             String JavaDoc msg = "EE: to much lines in CC Test Data";
200                             ref(msg);
201                             ref(dumpToken(token));
202                             fail(msg);
203                         }
204                         String JavaDoc str = token.getImage();
205                         // suppress new lines
206
if (str.endsWith("\n")) {
207                             str = str.substring(0, str.length()-1);
208                         }
209                         stepData[dataLineIdx++] = str;
210                     }
211                 } else {
212                     String JavaDoc text = token.getImage();
213                     if(text.startsWith(stepStart)) {
214                         if (text.endsWith(stepEnd)) {
215                             // all steps line in one toke as .java does
216
String JavaDoc[] lines = text.split("\n\r?|\r\n?");
217                             if (lines.length == 5) {
218                                 int offset = token.getOffset() + token.getImage().length();
219                                 for (int i = 0; i < 3; i++) {
220                                     stepData[i] = lines[i+1];
221                                 }
222                                 TestStep step = new TestStep(stepData, offset);
223                                 steps.add(step);
224                             } else {
225                                 String JavaDoc msg = "EE: expected 5 lines lenght token but got: "
226                                         + lines.length;
227                                 ref(msg);
228                                 ref(text);
229                                 for (int i = 0; i < lines.length; i++) {
230                                     ref(i+"::"+lines[i]);
231                                 }
232                             }
233                         } else {
234                             // each step line in separate line as .jsp does
235
inStepData = true;
236                             dataLineIdx = 0;
237                         }
238                     }
239                 }
240                 token = token.getNext();
241             } // while (token != null)
242
Iterator JavaDoc it = steps.iterator();
243             while (it.hasNext()) {
244                 exec(editor, (TestStep) it.next());
245             }
246         } catch (Exception JavaDoc ex) {
247             throw new AssertionFailedErrorException(ex);
248         }
249         compareReferenceFiles();
250     }
251     
252     private void exec(JEditorPane JavaDoc editor, TestStep step) throws Exception JavaDoc {
253         boolean ccError = false;
254         try {
255             ref(step.toString());
256             System.out.println("step: "+step.toString());
257             BaseDocument doc = (BaseDocument) editor.getDocument();
258             // insert prefix and set cursor
259
doc.insertString(step.getOffset(), "\n" + step.getPrefix(), null);
260             Caret JavaDoc caret = editor.getCaret();
261             caret.setDot(step.getCursorPos());
262             // run the test at a reasonable speed
263
Thread.sleep(500);
264             // call CC, the CC window should not appear in case of instant
265
// substitution
266
CompletionJListOperator comp = null;
267             try {
268                 comp = CompletionJListOperator.showCompletion();
269             } catch (JemmyException e) {
270                 ccError = true;
271                 ref("EE: The CC window did not appear");
272                 e.printStackTrace();
273             }
274             // run the test at a reasonable speed
275
Thread.sleep(1500);
276             if (comp != null) {
277                 // dump CC result to golden file
278
Iterator JavaDoc items = comp.getCompletionItems().iterator();
279                 CompletionItem selectedItem = null;
280                 while (items.hasNext()) {
281                     TextGraphics2D g = new TextGraphics2D(comp.getSource());
282                     Object JavaDoc next = items.next();
283                     String JavaDoc dispText = null;
284                     if (next instanceof ResultItem) {
285                         ResultItem resItem = (ResultItem) next;
286                         Component JavaDoc component = resItem.getPaintComponent((JList JavaDoc)comp.getSource(),
287                                 false, true);
288                         // get display version of the component
289
Method JavaDoc drawM = findMethod(component.getClass(), "draw", new Class JavaDoc[] {Graphics JavaDoc.class});
290                         if(drawM != null) {
291                             drawM.setAccessible(true);
292                             drawM.invoke(component, new Object JavaDoc[] {g});
293                         } else if (component instanceof JLabel JavaDoc) {
294                             // ??? use java.awt.Component.paint(Grraphics g) method instead?
295
System.out.println("graph1: "+((JLabel JavaDoc) component).getText().trim());
296                             g.drawString(((JLabel JavaDoc) component).getText().trim(), 0, 0);
297                         } else {
298                             System.out.println("graph2: "+((JLabel JavaDoc) component).getText().trim());
299                             g.drawString(component.toString(), 0, 0);
300                         }
301                     } else if (next instanceof CompletionItem) {
302                         CompletionItem cItem = (CompletionItem) next;
303                         cItem.render(g, Font.decode("Dialog-Plain-12"), Color.BLACK, Color.WHITE, 400, 30, false);
304                     } else {
305                         System.out.println("next:"+ next.toString());
306                         g.drawString(next.toString(),0 ,0);
307                     }
308                     dispText = g.getTextUni();
309                     System.out.println("DispText: "+dispText);
310                     // find choice item
311
if (dispText.equals(step.getChoice())) {
312                         assertInstanceOf(CompletionItem.class, next);
313                         selectedItem = (CompletionItem) next;
314                     }
315                     System.out.println("getTextUni: "+g.getTextUni());
316                     ref(g.getTextUni());
317                 }
318                 class DefaultActionRunner implements Runnable JavaDoc {
319                     CompletionItem item;
320                     JEditorPane JavaDoc editor;
321                     public DefaultActionRunner(CompletionItem item,
322                             JEditorPane JavaDoc editor) {
323                         this.item=item;
324                         this.editor=editor;
325                     }
326                     
327                     public void run() {
328                         item.defaultAction(editor);
329                     }
330                     
331                 }
332                 // substitute completion and check result
333
if (selectedItem != null) {
334                     // move to separate class
335
Runnable JavaDoc run = new DefaultActionRunner(selectedItem, editor);
336                     // XXX wait before substitution
337
Thread.currentThread().sleep(500);
338                     runInAWT(run);
339                 } else {
340                     ref("EE: cannot find completion item: " + step.getChoice());
341                 }
342             } else if (!ccError) {
343                 // comp == null && ccError == false => instant substitution
344
ref("Instant substitution performed");
345             }
346             // wait till CompletionJList is hidden
347
if (comp != null) {
348                 int i = 0;
349                 while (comp.isShowing()) {
350                     Thread.currentThread().sleep(500);
351                     if (i++ >= 12) {
352                         // log status
353
long time = System.currentTimeMillis();
354                         String JavaDoc screenFile = time + "-screen.png";
355                         log("["+time+"]The CompletionJList was not hidden in 5 secs");
356                         log("step: "+step);
357                         log("captureScreen:" + screenFile);
358                         try {
359                             PNGEncoder.captureScreen(getWorkDir().getAbsolutePath()
360                             +File.separator+screenFile);
361                         } catch (Exception JavaDoc e1) {}
362                         break;
363                     }
364                 }
365             }
366             Thread.currentThread().sleep(500); //XXX
367
int rowStart = Utilities.getRowStart(doc, step.getOffset() + 1);
368             int rowEnd = Utilities.getRowEnd(doc, step.getOffset() + 1);
369             String JavaDoc result = doc.getText(new int[] {rowStart, rowEnd});
370             if (!result.equals(step.getResult())) {
371                 ref("EE: unexpected CC result:\n< " + result + "\n> "
372                         + step.getResult());
373             }
374             ref("End cursor position = " + caret.getDot());
375         } finally {
376             Thread.currentThread().sleep(500); //XXX
377
// undo all changes
378
final UndoAction ua = (UndoAction)SystemAction.get(UndoAction.class);
379             assertNotNull("Cannot obtain UndoAction", ua);
380             while (ua.isEnabled()) {
381                 runInAWT(new Runnable JavaDoc() {
382                     public void run() {
383                         ua.performAction();
384                     }
385                 });
386                 Thread.currentThread().sleep(50); //XXX
387
}
388             Thread.currentThread().sleep(500);
389         }
390         
391     }
392     
393     private static void runInAWT(Runnable JavaDoc r) {
394         if (SwingUtilities.isEventDispatchThread()) {
395             r.run();
396         } else {
397             SwingUtilities.invokeLater(r);
398         }
399     }
400     
401     private Method JavaDoc findMethod(Class JavaDoc clazz, String JavaDoc name, Class JavaDoc[] paramTypes) {
402         Method JavaDoc method = null;
403         for (Class JavaDoc cls=clazz; cls.getSuperclass() != null; cls=cls.getSuperclass()) {
404             try {
405                 method = cls.getDeclaredMethod(name, paramTypes);
406             } catch (NoSuchMethodException JavaDoc e) {
407                 // ignore
408
}
409             if (method != null) {
410                 return method;
411             }
412         }
413         return null;
414     }
415     
416     protected void assertInstanceOf(Class JavaDoc expectedType, Object JavaDoc actual) {
417         if (!expectedType.isAssignableFrom(actual.getClass())) {
418             fail("Expected type: "+expectedType.getName()+"\nbut was: "+
419                     actual.getClass().getName());
420         }
421     }
422     
423     private static class TestStep {
424         private String JavaDoc prefix;
425         private String JavaDoc choice;
426         private String JavaDoc result;
427         private int offset;
428         private int cursorPos;
429         
430         public TestStep(String JavaDoc data[], int offset) {
431             this.prefix = data[0];
432             this.choice = data[1];
433             this.result = data[2];
434             this.offset = offset;
435             
436             cursorPos = prefix.indexOf('|');
437             if (cursorPos != -1) {
438                 prefix = prefix.replaceFirst("\\|", "");
439             } else {
440                 cursorPos = prefix.length();
441             }
442             cursorPos += offset + 1;
443         }
444         
445         public String JavaDoc toString() {
446             StringBuffer JavaDoc sb = new StringBuffer JavaDoc(prefix);
447             sb.insert(cursorPos - offset - 1, '|');
448             return "[" + sb + ", " + choice + ", "+ result + ", " + offset + "]";
449         }
450         
451         public String JavaDoc getPrefix() {
452             return prefix;
453         }
454         
455         public String JavaDoc getChoice() {
456             return choice;
457         }
458         
459         public String JavaDoc getResult() {
460             return result;
461         }
462         
463         public int getOffset() {
464             return offset;
465         }
466         
467         public int getCursorPos() {
468             return cursorPos;
469         }
470         
471     };
472     
473     /** Use for execution inside IDE */
474     public static void main(java.lang.String JavaDoc[] args) {
475         // run whole suite
476
junit.textui.TestRunner.run(suite());
477     }
478     
479     private String JavaDoc dumpToken(TokenItem tokenItem) {
480         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
481         sb.append("<token \name='");
482         sb.append(tokenItem.getTokenID().getName());
483         sb.append("'>\n");
484         sb.append(tokenItem.getTokenContextPath());
485         sb.append("</token>");
486         return sb.toString();
487     }
488 }
489
Popular Tags