KickJava   Java API By Example, From Geeks To Geeks.

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

96 public class CompletionTest extends JellyTestCase {
97     private static boolean GenerateGoldenFiles = false;//generate golden files, or test
98

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