001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.xml.text.completion;
042:
043: import java.awt.Component;
044: import java.awt.Container;
045: import java.awt.event.InputEvent;
046: import java.awt.event.KeyEvent;
047: import junit.textui.TestRunner;
048: import org.netbeans.editor.ext.ListCompletionView;
049: import org.netbeans.jellytools.EditorOperator;
050: import org.netbeans.jellytools.NewWizardOperator;
051: import org.netbeans.jemmy.ComponentChooser;
052: import org.netbeans.jemmy.operators.ComponentOperator;
053: import org.netbeans.jemmy.operators.JTextComponentOperator;
054: import org.netbeans.modules.xml.text.syntax.XMLOptions;
055: import org.netbeans.tests.xml.JXTest;
056: import org.openide.loaders.DataObject;
057: import org.openide.options.SystemOption;
058:
059: /**
060: * <P>
061: * <P>
062: * <FONT COLOR="#CC3333" FACE="Courier New, Monospaced" SIZE="+1">
063: * <B>
064: * <BR> XML Module Jemmy Test: CompletionJTest
065: * </B>
066: * </FONT>
067: * <BR><BR><B>What it tests:</B><BR>
068: *
069: * - basic functionality of XML code completion<br>
070: *
071: * <BR><BR><B>How it works:</B><BR>
072: *
073: * Creates simple XML document by code completion.
074: *
075: * <BR><BR><B>Settings:</B><BR>
076: * none<BR>
077: *
078: * <BR><BR><B>Output (Golden file):</B><BR>
079: * XML documents<BR>
080: *
081: * <BR><B>To Do:</B><BR>
082: * none<BR>
083: *
084: * <P>Created on April 03, 2003, 12:33 PM
085: * <P>
086: */
087:
088: public class CompletionJTest extends JXTest {
089: // constants for showCompl() method
090: private static int NO_WAIT = 0;
091: private static int EMPTY = 1;
092: private static int NO_EMPTY = 2;
093:
094: /** Caret Column Position */
095: int col;
096: /** Editor Operator */
097: EditorOperator editor;
098:
099: /**
100: * Creates new CoreTemplatesTest
101: * @param testName
102: */
103: public CompletionJTest(String testName) {
104: super (testName);
105: }
106:
107: /** Main test method. */
108: public void test() {
109: String folder;
110: String name = "Document";
111: String ext = "xml";
112: XMLOptions options;
113: DataObject dao;
114:
115: try {
116: folder = getFilesystemName() + DELIM
117: + getDataPackageName(DELIM);
118:
119: options = (XMLOptions) SystemOption.findObject(
120: XMLOptions.class, true);
121: options.setCompletionAutoPopup(false);
122:
123: dao = TestUtil.THIS.findData(name + "." + ext);
124: if (dao != null)
125: dao.delete();
126: // catalog is only real XML template in the module :-(
127: NewWizardOperator.create("XML" + DELIM
128: + "OASIS XML Catalog", folder, name);
129: editor = new EditorOperator(name);
130: } catch (Exception ex) {
131: log("Cannot setup test.", ex);
132: }
133:
134: clearText();
135: editor
136: .txtEditorPane()
137: .setText(
138: ""
139: + "<?xml version='1.0' encoding='UTF-8'?>\n"
140: + "<!DOCTYPE html PUBLIC '-//Test//DTD XHTML 1.0 Subset//EN' 'xhtml.dtd'>\n");
141:
142: insert("<h");
143: save();
144: //tml>
145: showCompl(NO_EMPTY);
146: enter();
147: insert(">\n");
148: //<head>
149: insertTag("<", ">\n", 1);
150: //<title>Test page</title>
151:
152: /*!!! #36306 hack
153: insertTag("<t", "Test page", -1);
154: */
155: insert("<t");
156: showCompl(NO_EMPTY);
157: esc();
158: insert("Test page");
159: //!!! end hack
160:
161: end();
162: insert("\n");
163: //</head>
164: insertTag("</", "\n", -1);
165: //<body>
166: insertTag("<", ">\n", 0);
167: //<h1 title="test">Test</h1>
168: insertTag("<h", " ", 0);
169: insertTag("t", "test\">Test", -1);
170: insertTag("</", "\n", -1);
171: //<table border="1">
172: insertTag("<t", " ", 0);
173: insertTag("b", "1\">\n", 1);
174: //<tr align="center">
175: insertTag("<t", " ", 4);
176: insertTag("a", "center\">\n", -1);
177: //<td>1</td><td>2</td>
178:
179: /*!!! #36306 hack
180: insertTag("<td", "1", -1);
181: end();
182: insertTag("<td", "2", -1);
183: */
184:
185: insert("<td");
186: showCompl(NO_EMPTY);
187: esc();
188: insert("1");
189: end();
190:
191: insert("<td");
192: showCompl(NO_EMPTY);
193: esc();
194: insert("2");
195: //!!! end hack
196:
197: end();
198: insert("\n");
199: //</tr>
200: insertTag("</", "\n", -1);
201: //</table>
202: insertTag("</", "\n", -1);
203: //</body>
204: insertTag("</", "\n", -1);
205: //</html>
206: insertTag("</", "\n", -1);
207: save();
208: ref(editor.getText());
209: compareReferenceFiles();
210: }
211:
212: /** Inserts a tag using completion, i.e.:
213: * <ul>
214: * <li>types <i>pref</i> at caret position
215: * <li>triggers code completion
216: * <li>enters index-th element from completion list
217: * <li>types <i>suf</i> at caret position
218: * </ul>
219: * @param pref prefix
220: * @param suf sufix
221: * @param index index of inserting item, -1 =>
222: */
223: final protected void insertTag(String pref, String suf, int index) {
224: insert(pref);
225: if (index < 0) {
226: showCompl(NO_WAIT);
227: } else {
228: showCompl(NO_EMPTY);
229: }
230: for (int i = 0; i < index; i++) {
231: down();
232: }
233: if (index > -1) {
234: enter();
235: }
236: //!!! sometime completion doesn't finish on time
237: sleepTest(500);
238: insert(suf);
239: }
240:
241: /** Types a text at caret position
242: *
243: * @param txt String
244: */
245: protected final void insert(String txt) {
246: editor.txtEditorPane().typeText(txt);
247: }
248:
249: /** Moves caret about <i>x</i> lines and <i>y</i> rows
250: *
251: * @param x delta X
252: * @param y delta Y
253: */
254: protected final void move(int x, int y) {
255: col += y;
256: editor.setCaretPosition(editor.getLineNumber() + x, col);
257: }
258:
259: /** Saves the document */
260: protected final void save() {
261: editor.save();
262: }
263:
264: /** Clears the document */
265: protected final void clearText() {
266: col = 0;
267: JTextComponentOperator text = new JTextComponentOperator(editor);
268:
269: text.setText("X"); //!!! because clearText is to slow.
270: text.clearText();
271: }
272:
273: /** Triggers code completion in given mode.
274: * <ul>
275: * <li>NO_WAIT - only trigger completion and continue
276: * <li>EMPTY - trigger completion and wait for completion list
277: * <li>NO_EMPTY - trigger completion and wait for non-empty completion list
278: * </ul>
279: */
280: protected final void showCompl(int mode) {
281: editor.pressKey(KeyEvent.VK_SPACE, InputEvent.CTRL_MASK);
282: if (mode == NO_WAIT) {
283: return;
284: } else if (mode == NO_EMPTY) {
285: waitCompl(1);
286: } else if (mode == EMPTY) {
287: waitCompl(0);
288: }
289: }
290:
291: /** Triggers code completion and checks if completion list contains at least
292: * <i>minSize</i> items.
293: * @param minSize
294: */
295: protected final void checkCompletion(int minSize) {
296: showCompl(NO_WAIT);
297: waitCompl(minSize);
298: esc();
299: }
300:
301: /** Waits completion list with at least <i>minSize</i> items.
302: * @param minSize - nuber of items
303: */
304: private void waitCompl(int minSize) {
305: CompletionChooser completionChoser = new CompletionChooser(
306: minSize);
307: ListCompletionView completionView = (ListCompletionView) ComponentOperator
308: .waitComponent((Container) editor
309: .getWindowContainerOperator().getSource(),
310: completionChoser);
311: int size = completionView.getModel().getSize();
312: }
313:
314: /** Searches for a completion listh with at least <i>minSize</i> items */
315: private class CompletionChooser implements ComponentChooser {
316: int minSize;
317:
318: public CompletionChooser() {
319: this (0);
320: }
321:
322: public CompletionChooser(int minSize) {
323: this .minSize = minSize;
324: }
325:
326: public boolean checkComponent(Component component) {
327: //System.out.println("> " + component);
328:
329: if (component instanceof ListCompletionView) {
330: ListCompletionView cmpl = (ListCompletionView) component;
331: if (cmpl.getModel().getSize() >= minSize)
332: return true;
333: }
334: return false;
335: }
336:
337: public String getDescription() {
338: return ("Instace of ScrollCompletionPane");
339: }
340: }
341:
342: // KEYS
343:
344: /** Deletes given number of characters from current caret possition.
345: * Position of caret will not change.
346: * @param length number of characters to be deleted
347: */
348: protected final void delete(int len) {
349: editor.delete(len);
350: }
351:
352: /** Deletes given number of characters before current caret possition.
353: * @param length number of characters to be deleted
354: */
355: protected final void backSp(int len) {
356: for (int i = 0; i < len; i++) {
357: editor.pushKey(KeyEvent.VK_BACK_SPACE);
358: }
359: }
360:
361: /** Presses key [ESC] */
362: protected final void esc() {
363: editor.pressKey(KeyEvent.VK_ESCAPE);
364: }
365:
366: /** Presses key [ENTER] */
367: protected final void enter() {
368: editor.pressKey(KeyEvent.VK_ENTER);
369: }
370:
371: /** Presses key [DOWN] */
372: protected final void down() {
373: editor.pressKey(KeyEvent.VK_DOWN);
374: }
375:
376: /** Presses key [UP] */
377: protected final void up() {
378: editor.pressKey(KeyEvent.VK_UP);
379: }
380:
381: /** Presses key [LEFT] */
382: protected final void left() {
383: editor.pressKey(KeyEvent.VK_LEFT);
384: }
385:
386: /** Presses key [RIGHT] */
387: protected final void right() {
388: editor.pressKey(KeyEvent.VK_RIGHT);
389: }
390:
391: /** Presses key [END] */
392: protected final void end() {
393: editor.pressKey(KeyEvent.VK_END);
394: }
395:
396: /** Main method for debuging purpose
397: *
398: * @param args
399: */
400: public static void main(String[] args) {
401: //JamController.setFast(false);
402: DEBUG = true;
403: TestRunner.run(CompletionJTest.class);
404: }
405: }
|