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 Alexey A. Ivanov
019: * @version $Revision$
020: */package javax.swing.text;
021:
022: import java.util.List;
023: import java.util.Vector;
024: import javax.swing.event.DocumentEvent;
025: import javax.swing.event.DocumentListener;
026: import javax.swing.event.DocumentEvent.ElementChange;
027: import javax.swing.text.AbstractDocument.DefaultDocumentEvent;
028: import javax.swing.text.DefaultStyledDocument.ElementBuffer;
029: import javax.swing.text.DefaultStyledDocument.ElementSpec;
030: import junit.framework.TestCase;
031:
032: /**
033: * Tests DefaultStyledDocument class, in particular which ElementSpecs are
034: * created during insertString with different parameters.
035: * <p>
036: * These tests insert some text into document containing one paragraph of
037: * attributed text:
038: * <code>"plainbolditalic"</code> plus implied newline character.
039: * Thus document has one <em>paragraph</em> (Branch)
040: * with three <em>contents</em> (Leaf) under the paragraph.
041: * <p>
042: * The text is inserted into leaf of <code>leafIndex</code> at
043: * offset <code>insertOffset</code>. By default <code>leafIndex = 1</code>
044: * (the second style run with bold attributes), and offset is two chars to
045: * the right from the start, i.e. the text is inserted after <code>"bo"</code>.
046: *
047: * <p>
048: * Tests are classified as follows:
049: * <dl>
050: * <dt>0x</dt>
051: * <dd>No attributes are set or passed as parameters.</dd>
052: *
053: * <dt>1x</dt>
054: * <dd>The paragraph contains <code>bold</code> attributes;
055: * the text is inserted with <code>null</code>
056: * as <code>attrs</code> parameter.</dd>
057: *
058: * <dt>2x</dt>
059: * <dd>The character attributes set to <code>bold</code>;
060: * the text is inserted with <code>null</code>
061: * as <code>attrs</code> parameter.</dd>
062: *
063: * <dt>3x</dt>
064: * <dd>No attributes are set;
065: * the text is inserted with <code>italic</code> attributes.</dd>
066: *
067: * <dt>4x</dt>
068: * <dd>The paragraph contains <code>bold</code> attributes;
069: * the text is inserted with <code>italic</code> attributes.</dd>
070: *
071: * <dt>5x</dt>
072: * <dd>The character attributes set to <code>bold</code>;
073: * the text is inserted with <code>italic</code> attributes.</dd>
074: * </dl>
075: * <p>Each test-case region currently contains four tests.
076: *
077: */
078: public class DefaultStyledDocument_ElementBuffer_Specs3Test extends
079: TestCase implements DocumentListener {
080: private DefaultStyledDocument doc;
081:
082: private Element root;
083:
084: private ElementBuffer buf;
085:
086: private ElementSpec[] specs;
087:
088: private Element paragraph;
089:
090: private Element leaf;
091:
092: private static final int leafIndex = 1;
093:
094: private int insertOffset;
095:
096: private DefaultDocumentEvent insertEvent;
097:
098: private static final AttributeSet bold = DefStyledDoc_Helpers.bold;
099:
100: private static final AttributeSet italic = DefStyledDoc_Helpers.italic;
101:
102: private static final class ElementAssert {
103: private final AttributeSet attrs;
104:
105: private final int start;
106:
107: private final int end;
108:
109: public ElementAssert(AttributeSet attrs, int start, int end) {
110: this .attrs = attrs;
111: this .start = start;
112: this .end = end;
113: }
114:
115: public void check(final Element element) {
116: if (attrs == null) {
117: assertEquals("Attribute count", 0, element
118: .getAttributes().getAttributeCount());
119: } else {
120: assertTrue("Attributes", attrs.isEqual(element
121: .getAttributes()));
122: }
123: assertEquals("Start offset", start, element
124: .getStartOffset());
125: assertEquals("End offset", end, element.getEndOffset());
126: }
127: }
128:
129: @Override
130: protected void setUp() throws Exception {
131: super .setUp();
132: doc = new DefStyledDoc_Helpers.DefStyledDocWithLogging();
133: root = doc.getDefaultRootElement();
134: buf = new DefStyledDoc_Helpers.ElementBufferWithLogging(doc,
135: root) {
136: private static final long serialVersionUID = 1L;
137:
138: @Override
139: public void insert(int offset, int length,
140: ElementSpec[] spec, DefaultDocumentEvent event) {
141: super .insert(offset, length, specs = spec, event);
142: }
143: };
144: doc.buffer = buf;
145: doc.insertString(doc.getLength(), "plain", null); // 5 chars
146: doc.insertString(doc.getLength(), "bold", bold); // 4 chars
147: doc.insertString(doc.getLength(), "italic", italic); // 6 chars
148: paragraph = root.getElement(0);
149: leaf = paragraph.getElement(leafIndex);
150: insertOffset = leaf.getStartOffset() + 2;
151: doc.addDocumentListener(this );
152: }
153:
154: /**
155: * Adds text with no attributes.
156: */
157: public void testInsertString01() throws Exception {
158: doc.insertString(insertOffset, "^^^", null);
159: assertEquals(2, getEdits(insertEvent).size());
160: List<?> edits = getEdits(insertEvent);
161: assertChange(edits.get(1), paragraph, 1, 3);
162: ElementChange change = (ElementChange) edits.get(1);
163: assertSame(leaf, change.getChildrenRemoved()[0]);
164: final Element[] added = change.getChildrenAdded();
165: for (int i = 0; i < added.length; i++) {
166: assertSame("@" + i, paragraph.getElement(i + leafIndex),
167: added[i]);
168: }
169: ElementAssert[] expected = { new ElementAssert(null, 0, 5),
170: new ElementAssert(bold, 5, 7),
171: new ElementAssert(null, 7, 10),
172: new ElementAssert(bold, 10, 12),
173: new ElementAssert(italic, 12, 18),
174: new ElementAssert(null, 18, 19) };
175: assertEquals(expected.length, paragraph.getElementCount());
176: for (int i = 0; i < expected.length; i++) {
177: expected[i].check(paragraph.getElement(i));
178: }
179: assertEquals(1, specs.length);
180: assertSpec(specs[0], ElementSpec.ContentType,
181: ElementSpec.OriginateDirection, 0, 3);
182: }
183:
184: /**
185: * Adds text with the same attributes.
186: */
187: public void testInsertString02() throws Exception {
188: doc.insertString(insertOffset, "^^^", bold);
189: List<?> edits = getEdits(insertEvent);
190: assertEquals(1, edits.size());
191: assertEquals(5, leaf.getStartOffset());
192: assertEquals(5 + 4 + 3, leaf.getEndOffset());
193: assertEquals(1, specs.length);
194: assertSpec(specs[0], ElementSpec.ContentType,
195: ElementSpec.JoinPreviousDirection, 0, 3);
196: // These actions are performed:
197: // createLeaf(paragraph[0, 19], bold=true , 5, 7)
198: // createLeaf(paragraph[0, 19], , 7, 10)
199: // createLeaf(paragraph[0, 19], bold=true , 10, 12)
200: }
201:
202: /**
203: * Puts non-attributed new line character.
204: */
205: public void testInsertString03() throws Exception {
206: doc.insertString(insertOffset, "\n", null);
207: final List<?> edits = getEdits(insertEvent);
208: assertEquals(3, edits.size());
209: assertSame(paragraph, root.getElement(0));
210: assertChange(edits.get(1), root.getElement(0), 3, 2);
211: // assertChange(edits.get(2), root.getElement(1), 1, 1);
212: assertChange(edits.get(2), root, 0, 1);
213: final ElementAssert[] par1Expected = {
214: new ElementAssert(null, 0, 5),
215: new ElementAssert(bold, 5, 7),
216: new ElementAssert(null, 7, 8) };
217: assertEquals(par1Expected.length, paragraph.getElementCount());
218: for (int i = 0; i < par1Expected.length; i++) {
219: par1Expected[i].check(paragraph.getElement(i));
220: }
221: final ElementAssert[] par2Expected = {
222: new ElementAssert(bold, 8, 10),
223: new ElementAssert(italic, 10, 16),
224: new ElementAssert(null, 16, 17) };
225: final Element par2 = root.getElement(1);
226: assertEquals(par2Expected.length, par2.getElementCount());
227: for (int i = 0; i < par2Expected.length; i++) {
228: par2Expected[i].check(par2.getElement(i));
229: }
230: assertEquals(3, specs.length);
231: assertSpec(specs[0], ElementSpec.ContentType,
232: ElementSpec.OriginateDirection, 0, 1);
233: assertSpec(specs[1], ElementSpec.EndTagType,
234: ElementSpec.OriginateDirection, 0, 0);
235: assertSpec(specs[2], ElementSpec.StartTagType,
236: ElementSpec.JoinFractureDirection, 0, 0);
237: // These actions are performed:
238: // createLeaf(paragraph[0, 17], bold=true , 5, 7)
239: // createLeaf(paragraph[0, 17], , 7, 8)
240: // createBranch(section[0, 17], resolver=**AttributeSet** )
241: // createLeaf(paragraph[N/A], bold=true , 8, 10)
242: // createLeaf(paragraph[N/A], italic=true , 10, 16)
243: // createLeaf(paragraph[N/A], , 16, 17)
244: }
245:
246: /**
247: * Puts non-attributed 'one\ntwo'.
248: */
249: public void testInsertString04() throws Exception {
250: doc.insertString(insertOffset, "one\ntwo", null);
251: List<?> edits = getEdits(insertEvent);
252: assertEquals(4, edits.size());
253: assertChange(edits.get(1), root.getElement(0), 3, 2);
254: assertChange(edits.get(2), root.getElement(1), 0, 1);
255: assertChange(edits.get(3), root, 0, 1);
256: assertEquals(4, specs.length);
257: assertSpec(specs[0], ElementSpec.ContentType,
258: ElementSpec.OriginateDirection, 0, 4);
259: assertSpec(specs[1], ElementSpec.EndTagType,
260: ElementSpec.OriginateDirection, 0, 0);
261: assertSpec(specs[2], ElementSpec.StartTagType,
262: ElementSpec.JoinFractureDirection, 0, 0);
263: assertSpec(specs[3], ElementSpec.ContentType,
264: ElementSpec.OriginateDirection, 0, 3);
265: // These actions are performed:
266: // createLeaf(paragraph[0, 23], bold=true , 5, 7)
267: // createLeaf(paragraph[0, 23], , 7, 11)
268: // createBranch(section[0, 23], resolver=**AttributeSet** )
269: // createLeaf(paragraph[N/A], bold=true , 14, 16)
270: // createLeaf(paragraph[N/A], italic=true , 16, 22)
271: // createLeaf(paragraph[N/A], , 22, 23)
272: // createLeaf(paragraph[14, 23], , 11, 14)
273: }
274:
275: /**
276: * Puts 'one\ntwo' with bold attributes (the same as in the portion
277: * where text is inserted).
278: */
279: public void testInsertString05() throws Exception {
280: doc.insertString(insertOffset, "one\ntwo", bold);
281: List<?> edits = getEdits(insertEvent);
282: assertEquals(4, edits.size());
283: assertChange(edits.get(1), root.getElement(0), 3, 1);
284: assertChange(edits.get(2), root.getElement(1), 1, 1);
285: assertChange(edits.get(3), root, 0, 1);
286: assertEquals(4, specs.length);
287: assertSpec(specs[0], ElementSpec.ContentType,
288: ElementSpec.JoinPreviousDirection, 0, 4);
289: assertSpec(specs[1], ElementSpec.EndTagType,
290: ElementSpec.OriginateDirection, 0, 0);
291: assertSpec(specs[2], ElementSpec.StartTagType,
292: ElementSpec.JoinFractureDirection, 0, 0);
293: assertSpec(specs[3], ElementSpec.ContentType,
294: ElementSpec.JoinNextDirection, 0, 3);
295: // These actions are performed:
296: // createLeaf(paragraph[0, 23], bold=true , 5, 11)
297: // createBranch(section[0, 23], resolver=**AttributeSet** )
298: // createLeaf(paragraph[N/A], bold=true , 14, 16)
299: // createLeaf(paragraph[N/A], italic=true , 16, 22)
300: // createLeaf(paragraph[N/A], , 22, 23)
301: // createLeaf(paragraph[14, 23], bold=true , 11, 16)
302: }
303:
304: private static void assertChange(final Object object,
305: final Element element, final int removed, final int added) {
306: DefStyledDoc_Helpers.assertChange(object, element, removed,
307: added);
308: }
309:
310: private static void assertSpec(final ElementSpec spec,
311: final short type, final short direction, final int offset,
312: final int length) {
313: DefStyledDoc_Helpers.assertSpec(spec, type, direction, offset,
314: length);
315: }
316:
317: private static Vector<?> getEdits(final DefaultDocumentEvent event) {
318: return DefStyledDoc_Helpers.getEdits(event);
319: }
320:
321: public void changedUpdate(DocumentEvent e) {
322: }
323:
324: public void insertUpdate(DocumentEvent e) {
325: insertEvent = (DefaultDocumentEvent) e;
326: }
327:
328: public void removeUpdate(DocumentEvent e) {
329: }
330: }
|