001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Vadim L. Bogdanov
019: * @version $Revision$
020: */package javax.swing.text.html;
021:
022: import java.awt.Cursor;
023: import java.awt.event.ActionEvent;
024: import java.io.IOException;
025: import java.io.StringReader;
026: import java.io.StringWriter;
027: import java.util.Arrays;
028:
029: import javax.swing.Action;
030: import javax.swing.JEditorPane;
031: import javax.swing.SwingTestCase;
032: import javax.swing.event.HyperlinkEvent;
033: import javax.swing.event.HyperlinkListener;
034: import javax.swing.text.AttributeSet;
035: import javax.swing.text.BadLocationException;
036: import javax.swing.text.DefaultStyledDocument;
037: import javax.swing.text.Document;
038: import javax.swing.text.Element;
039: import javax.swing.text.SimpleAttributeSet;
040: import javax.swing.text.StyleConstants;
041: import javax.swing.text.StyledEditorKit;
042: import javax.swing.text.ViewFactory;
043: import javax.swing.text.html.HTMLEditorKit.InsertHTMLTextAction;
044:
045: public class HTMLEditorKitTest extends SwingTestCase {
046: private static final String HTML_TEXT = "<title>t</title>html <i>text</i>";
047: private static final String LOADED_HTML_TEXT = " \nhtml text";
048: private HTMLEditorKit editorKit;
049: private HTMLDocument document;
050:
051: public HTMLEditorKitTest(final String name) {
052: super (name);
053: }
054:
055: protected void setUp() throws Exception {
056: super .setUp();
057: setIgnoreNotImplemented(true);
058:
059: editorKit = new HTMLEditorKit();
060: document = (HTMLDocument) editorKit.createDefaultDocument();
061: document.setAsynchronousLoadPriority(-1); // synchronous loading
062: }
063:
064: protected void tearDown() throws Exception {
065: super .tearDown();
066: }
067:
068: public void testHTMLEditorKit() {
069: editorKit = new HTMLEditorKit();
070:
071: assertNotNull(editorKit.getActions());
072: }
073:
074: public void testClone() {
075: // TODO: implement
076: }
077:
078: public void testCreateDefaultDocument() {
079: Document doc = editorKit.createDefaultDocument();
080: assertTrue(doc instanceof HTMLDocument);
081:
082: HTMLDocument htmlDoc = (HTMLDocument) doc;
083: assertSame(editorKit.getParser(), htmlDoc.getParser());
084: assertEquals(4, htmlDoc.getAsynchronousLoadPriority());
085: assertNotNull(htmlDoc.getStyleSheet());
086: assertFalse(editorKit.getStyleSheet().equals(
087: htmlDoc.getStyleSheet()));
088:
089: assertTrue(Arrays.asList(
090: htmlDoc.getStyleSheet().getStyleSheets()).contains(
091: editorKit.getStyleSheet()));
092: }
093:
094: public void testDeinstallJEditorPane() {
095: JEditorPane pane = new JEditorPane();
096: int mouseListenersCount = pane.getMouseListeners().length;
097: int mouseMotionListenersCount = pane.getMouseMotionListeners().length;
098:
099: editorKit.install(pane);
100: editorKit.deinstall(pane);
101:
102: assertEquals(mouseListenersCount,
103: pane.getMouseListeners().length);
104: assertEquals(mouseMotionListenersCount, pane
105: .getMouseMotionListeners().length);
106: }
107:
108: public void testGetAccessibleContext() {
109: // TODO: implement
110: }
111:
112: public void testGetActions() throws Exception {
113: Action[] ancestorActions = new StyledEditorKit().getActions();
114: Action[] actions = editorKit.getActions();
115: assertEquals(12, actions.length - ancestorActions.length);
116:
117: Action[] predefinedInsertHTMLTextActions = createPredefinedInsertHTMLTextActions();
118: for (int i = 0; i < predefinedInsertHTMLTextActions.length; i++) {
119: Action action = findActionWithName(actions,
120: predefinedInsertHTMLTextActions[i]
121: .getValue(Action.NAME));
122: if (action != null) {
123: assertTrue("Action is not same"
124: + action.getValue(Action.NAME),
125: compareInsertHTMLTextActions(action,
126: predefinedInsertHTMLTextActions[i]));
127: } else {
128: fail("Action not found: "
129: + predefinedInsertHTMLTextActions[i]
130: .getValue(Action.NAME));
131: }
132: }
133: }
134:
135: public void testNextLinkAction() throws Exception {
136: Action action = findActionWithName(editorKit.getActions(),
137: "next-link-action");
138: assertNotNull(action);
139:
140: JEditorPane pane = new JEditorPane();
141: pane.setEditable(false);
142: pane.setEditorKit(editorKit);
143: document = ((HTMLDocument) pane.getDocument());
144: document.setAsynchronousLoadPriority(-1); // synchronous loading
145: pane
146: .setText("<p><a href=http://a.com>a.com</a>text<a href=http://b.com>b.com</a></p>");
147: pane.setCaretPosition(0);
148:
149: action.actionPerformed(new ActionEvent(pane, 0, null));
150: Element e = document.getCharacterElement(pane
151: .getCaretPosition());
152: assertEquals("http://a.com", getURLString(e));
153: action.actionPerformed(new ActionEvent(pane, 0, null));
154: e = document.getCharacterElement(pane.getCaretPosition());
155: assertEquals("http://b.com", getURLString(e));
156: }
157:
158: public void testPreviousLinkAction() throws Exception {
159: Action action = findActionWithName(editorKit.getActions(),
160: "previous-link-action");
161: assertNotNull(action);
162:
163: JEditorPane pane = new JEditorPane();
164: pane.setEditable(false);
165: pane.setEditorKit(editorKit);
166: document = ((HTMLDocument) pane.getDocument());
167: document.setAsynchronousLoadPriority(-1); // synchronous loading
168: pane
169: .setText("<p><a href=http://a.com>a.com</a>text<a href=http://b.com>b.com</a></p>");
170: pane.setCaretPosition(document.getLength() - 1);
171:
172: action.actionPerformed(new ActionEvent(pane, 0, null));
173: Element e = document.getCharacterElement(pane
174: .getCaretPosition());
175: assertEquals("http://b.com", getURLString(e));
176: action.actionPerformed(new ActionEvent(pane, 0, null));
177: e = document.getCharacterElement(pane.getCaretPosition());
178: assertEquals("http://a.com", getURLString(e));
179: }
180:
181: public void testActivateLinkAction() throws Exception {
182: Action action = findActionWithName(editorKit.getActions(),
183: "activate-link-action");
184: assertNotNull(action);
185:
186: JEditorPane pane = new JEditorPane();
187: pane.setEditable(false);
188: pane.setEditorKit(editorKit);
189: document = ((HTMLDocument) pane.getDocument());
190: document.setAsynchronousLoadPriority(-1); // synchronous loading
191: pane
192: .setText("<p><a href=http://a.com>a.com</a>text<a href=http://b.com>b.com</a></p>");
193: pane.setCaretPosition(1);
194:
195: class TestHyperlinkListener implements HyperlinkListener {
196: public boolean occured;
197:
198: public void hyperlinkUpdate(HyperlinkEvent event) {
199: occured = true;
200: }
201: }
202:
203: TestHyperlinkListener listener = new TestHyperlinkListener();
204: pane.addHyperlinkListener(listener);
205:
206: action.actionPerformed(new ActionEvent(pane, 0, null));
207: assertTrue(listener.occured);
208: }
209:
210: public void testInsertHRAction() throws Exception {
211: InsertHTMLTextAction action = (InsertHTMLTextAction) findActionWithName(
212: editorKit.getActions(), "InsertHR");
213: assertNotNull(action);
214:
215: JEditorPane pane = new JEditorPane();
216: pane.setEditorKit(editorKit);
217: document = ((HTMLDocument) pane.getDocument());
218: document.setAsynchronousLoadPriority(-1); // synchronous loading
219: pane.setText("<p>test</p>");
220: final int pos = document.getLength() - 1;
221: pane.setCaretPosition(pos);
222:
223: action.actionPerformed(new ActionEvent(pane, 0, null));
224: Element e = document.getCharacterElement(pos + 1);
225: assertEquals(HTML.Tag.HR, getHTMLTagByElement(e));
226: assertNotNull(e);
227: HTML.Tag parentTag = getHTMLTagByElement(e.getParentElement());
228: assertTrue(HTML.Tag.P.equals(parentTag)
229: || HTML.Tag.IMPLIED.equals(parentTag));
230: }
231:
232: public void testGetContentType() {
233: assertEquals("text/html", editorKit.getContentType());
234: }
235:
236: public void testGetInputAttributes() throws Exception {
237: JEditorPane pane = new JEditorPane();
238: editorKit.install(pane);
239: editorKit.read(new StringReader("normal<i>italic</i>"), pane
240: .getDocument(), 0);
241:
242: pane.setCaretPosition(pane.getDocument().getLength() - 1);
243: assertNotNull(editorKit.getInputAttributes());
244: }
245:
246: public void testGetViewFactory() {
247: ViewFactory factory = editorKit.getViewFactory();
248: assertTrue(factory instanceof HTMLEditorKit.HTMLFactory);
249: assertSame(factory, editorKit.getViewFactory());
250: assertSame(factory, new HTMLEditorKit().getViewFactory());
251: }
252:
253: public void testInsertHTML() throws Exception {
254: final String HTML_TEXT2 = "<i>_another text_</i>";
255: final String HTML_TEXT3 = ("");
256: final String INSERTION_RESULT = " \nhtml_another text_ text";
257:
258: editorKit.read(new StringReader(HTML_TEXT), document, 0);
259: String s = document.getText(0, document.getLength());
260: assertEquals(LOADED_HTML_TEXT, s);
261:
262: editorKit.insertHTML(document, 7, HTML_TEXT2, 0, 0, HTML.Tag.I);
263: assertEquals(INSERTION_RESULT, document.getText(0, document
264: .getLength()));
265:
266: // test pos > document's length
267: testExceptionalCase(new ExceptionalCase() {
268: public Class expectedExceptionClass() {
269: return BadLocationException.class;
270: }
271:
272: public void exceptionalAction() throws Exception {
273: editorKit.insertHTML(document,
274: document.getLength() + 1, HTML_TEXT3, 0, 0,
275: HTML.Tag.P);
276: }
277: });
278:
279: // test pos < 0
280: testExceptionalCase(new ExceptionalCase() {
281: public Class expectedExceptionClass() {
282: return BadLocationException.class;
283: }
284:
285: public void exceptionalAction() throws Exception {
286: editorKit.insertHTML(document, -1, HTML_TEXT2, 0, 0,
287: HTML.Tag.I);
288: }
289: });
290:
291: // empty insertion, no exception should be thrown
292: editorKit
293: .insertHTML(document, -1, HTML_TEXT3, 0, 0, HTML.Tag.I);
294: }
295:
296: public void testInstallJEditorPane() {
297: JEditorPane pane = new JEditorPane();
298: int mouseListenersCount = pane.getMouseListeners().length;
299: int mouseMotionListenersCount = pane.getMouseMotionListeners().length;
300:
301: editorKit.install(pane);
302:
303: assertEquals(mouseListenersCount + 1,
304: pane.getMouseListeners().length);
305: assertEquals(mouseMotionListenersCount + 1, pane
306: .getMouseMotionListeners().length);
307: }
308:
309: public void testRead() throws Exception {
310: final StringReader in1 = new StringReader(HTML_TEXT);
311: final StringReader in2 = new StringReader("another text");
312: final StringReader in3 = new StringReader("");
313: final StringReader in4 = new StringReader("");
314: final StringReader in5 = new StringReader("");
315: final String text2 = " \nhtml\nanother text\n text";
316:
317: editorKit.read(in1, document, 0);
318: String s = document.getText(0, document.getLength());
319: assertEquals(LOADED_HTML_TEXT, s);
320: testExceptionalCase(new ExceptionalCase() {
321: public Class expectedExceptionClass() {
322: return IOException.class;
323: }
324:
325: public void exceptionalAction() throws Exception {
326: in1.ready();
327: }
328: });
329:
330: editorKit.read(in2, document, 7);
331: assertEquals(text2, document.getText(0, document.getLength()));
332:
333: // test pos > document's length
334: testExceptionalCase(new ExceptionalCase() {
335: public Class expectedExceptionClass() {
336: return BadLocationException.class;
337: }
338:
339: public void exceptionalAction() throws Exception {
340: editorKit.read(in3, document, document.getLength() + 1);
341: }
342: });
343:
344: // test pos outside BODY
345: testExceptionalCase(new ExceptionalCase() {
346: public Class expectedExceptionClass() {
347: return RuntimeException.class;
348: }
349:
350: public void exceptionalAction() throws Exception {
351: editorKit.read(in4, document, 0);
352: }
353: });
354:
355: // test pos < 0
356: testExceptionalCase(new ExceptionalCase() {
357: public Class expectedExceptionClass() {
358: return RuntimeException.class;
359: }
360:
361: public void exceptionalAction() throws Exception {
362: editorKit.read(in5, document, -1);
363: }
364: });
365: }
366:
367: public void testSetIsAutoFormSubmission() {
368: assertTrue(editorKit.isAutoFormSubmission());
369:
370: editorKit.setAutoFormSubmission(false);
371: assertFalse(editorKit.isAutoFormSubmission());
372: }
373:
374: public void testSetGetDefaultCursor() {
375: assertSame(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR),
376: editorKit.getDefaultCursor());
377:
378: Cursor newCursor = new Cursor(Cursor.DEFAULT_CURSOR);
379: editorKit.setDefaultCursor(newCursor);
380: assertSame(newCursor, editorKit.getDefaultCursor());
381: }
382:
383: public void testSetGetLinkCursor() {
384: assertSame(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR),
385: editorKit.getLinkCursor());
386:
387: Cursor newCursor = new Cursor(Cursor.DEFAULT_CURSOR);
388: editorKit.setLinkCursor(newCursor);
389: assertSame(newCursor, editorKit.getLinkCursor());
390: }
391:
392: public void testSetStyleSheet() {
393: StyleSheet ss = new StyleSheet();
394: editorKit.setStyleSheet(ss);
395: assertSame(ss, editorKit.getStyleSheet());
396:
397: editorKit = new HTMLEditorKit();
398: assertSame(ss, editorKit.getStyleSheet());
399: }
400:
401: public void testGetStyleSheet() {
402: StyleSheet ss = editorKit.getStyleSheet();
403: assertNotNull(ss);
404: assertSame(ss, editorKit.getStyleSheet());
405:
406: editorKit = new HTMLEditorKit();
407: assertSame(ss, editorKit.getStyleSheet());
408: }
409:
410: public void testWrite() throws Exception {
411: StringWriter writer = new StringWriter();
412: final String content = "Hello, World!";
413: final int start = 1;
414: final int end = 4;
415: DefaultStyledDocument doc = new DefaultStyledDocument();
416: doc.insertString(0, content, null);
417:
418: editorKit.write(writer, doc, start, end);
419: String output = writer.toString();
420: assertTrue(output.indexOf("<html>") != -1);
421: if (isHarmony()) {
422: assertFalse(output.indexOf(content) != -1);
423: assertTrue(output.indexOf(content.substring(start, end)) != -1);
424: }
425:
426: writer = new StringWriter();
427: doc = (HTMLDocument) editorKit.createDefaultDocument();
428: doc.insertString(0, content, null);
429: editorKit.write(writer, doc, start, end);
430: output = writer.toString();
431: assertTrue(output.indexOf("<html>") != -1);
432: assertFalse(output.indexOf(content) != -1);
433: assertTrue(output.indexOf(content.substring(start, end)) != -1);
434: }
435:
436: public void testGetParser() {
437: HTMLEditorKit.Parser parser = editorKit.getParser();
438: assertNotNull(parser);
439: assertSame(parser, editorKit.getParser());
440: assertSame(parser, new HTMLEditorKit().getParser());
441: }
442:
443: public void testCreateInputAttributes() throws Exception {
444: document.insertAfterStart(document.getDefaultRootElement(),
445: "<b>bold</b>");
446: Element e = document.getDefaultRootElement().getElement(0);
447: SimpleAttributeSet attrSet = new SimpleAttributeSet();
448: editorKit.createInputAttributes(e, attrSet);
449: assertTrue(attrSet.containsAttribute(
450: StyleConstants.NameAttribute, HTML.Tag.CONTENT));
451: assertEquals("bold", attrSet.getAttribute(
452: CSS.Attribute.FONT_WEIGHT).toString());
453: }
454:
455: public void testParserCallback() {
456: Object implied = HTMLEditorKit.ParserCallback.IMPLIED;
457: assertTrue(implied instanceof String);
458: assertFalse("".equals(implied));
459: }
460:
461: private Action[] createPredefinedInsertHTMLTextActions() {
462: Action[] actions = {
463: new HTMLEditorKit.InsertHTMLTextAction(
464: "InsertOrderedList", "<ol><li></li></ol>",
465: HTML.Tag.BODY, HTML.Tag.OL),
466: new HTMLEditorKit.InsertHTMLTextAction(
467: "InsertOrderedListItem", "<ol><li></li></ol>",
468: HTML.Tag.OL, HTML.Tag.LI, HTML.Tag.BODY,
469: HTML.Tag.OL),
470: new HTMLEditorKit.InsertHTMLTextAction(
471: "InsertUnorderedList", "<ul><li></li></ul>",
472: HTML.Tag.BODY, HTML.Tag.UL),
473: new HTMLEditorKit.InsertHTMLTextAction(
474: "InsertUnorderedListItem",
475: "<ul><li></li></ul>", HTML.Tag.UL, HTML.Tag.LI,
476: HTML.Tag.BODY, HTML.Tag.UL),
477: new HTMLEditorKit.InsertHTMLTextAction("InsertTable",
478: "<table border=1><tr><td></td></tr></table>",
479: HTML.Tag.BODY, HTML.Tag.TABLE),
480: new HTMLEditorKit.InsertHTMLTextAction(
481: "InsertTableDataCell",
482: "<table border=1><tr><td></td></tr></table>",
483: HTML.Tag.TR, HTML.Tag.TD, HTML.Tag.BODY,
484: HTML.Tag.TABLE),
485: new HTMLEditorKit.InsertHTMLTextAction(
486: "InsertTableRow",
487: "<table border=1><tr><td></td></tr></table>",
488: HTML.Tag.TABLE, HTML.Tag.TR, HTML.Tag.BODY,
489: HTML.Tag.TABLE),
490: new HTMLEditorKit.InsertHTMLTextAction("InsertPre",
491: "<pre></pre>", HTML.Tag.BODY, HTML.Tag.PRE), };
492:
493: return actions;
494: }
495:
496: private boolean compareInsertHTMLTextActions(final Action a1,
497: final Action a2) {
498: if (!(a1 instanceof HTMLEditorKit.InsertHTMLTextAction)
499: || !(a2 instanceof HTMLEditorKit.InsertHTMLTextAction)) {
500: return false;
501: }
502: HTMLEditorKit.InsertHTMLTextAction htmlAction1 = (HTMLEditorKit.InsertHTMLTextAction) a1;
503: HTMLEditorKit.InsertHTMLTextAction htmlAction2 = (HTMLEditorKit.InsertHTMLTextAction) a2;
504: return compareActionFields(htmlAction1.addTag,
505: htmlAction2.addTag)
506: && compareActionFields(htmlAction1.alternateAddTag,
507: htmlAction2.alternateAddTag)
508: && compareActionFields(htmlAction1.alternateParentTag,
509: htmlAction2.alternateParentTag)
510: && compareActionFields(htmlAction1.html,
511: htmlAction2.html)
512: && compareActionFields(htmlAction1.parentTag,
513: htmlAction2.parentTag);
514: }
515:
516: private boolean compareActionFields(final Object f1, final Object f2) {
517: return f1 != null && f1.equals(f2) || f1 == f2;
518: }
519:
520: private Action findActionWithName(final Action[] actions,
521: final Object name) {
522: for (int i = 0; i < actions.length; i++) {
523: if (name.equals(actions[i].getValue(Action.NAME))) {
524: return actions[i];
525: }
526: }
527: return null;
528: }
529:
530: private static HTML.Tag getHTMLTagByElement(final Element elem) {
531: final Object result = elem.getAttributes().getAttribute(
532: StyleConstants.NameAttribute);
533: return (result instanceof HTML.Tag) ? (HTML.Tag) result : null;
534: }
535:
536: private static String getURLString(final Element e) {
537: AttributeSet aSet = (AttributeSet) e.getAttributes()
538: .getAttribute(HTML.Tag.A);
539: return aSet == null ? null : (String) aSet
540: .getAttribute(HTML.Attribute.HREF);
541: }
542: }
|