Moved to test packages

X-SVN-Rev: 1232
This commit is contained in:
Alan Liu 2000-04-24 20:38:00 +00:00
parent 29a5eb3759
commit 1732485c3d
14 changed files with 4054 additions and 0 deletions

View File

@ -0,0 +1,55 @@
/*
* @(#)$RCSfile: TestAll.java,v $ $Revision: 1.1 $ $Date: 2000/04/24 20:38:00 $
*
* (C) Copyright IBM Corp. 1998-1999. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.richtext.tests;
import com.ibm.test.TestFmwk;
public class TestAll extends TestFmwk {
static final String COPYRIGHT =
"(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
public static void main(String[] args) throws Exception {
new TestAll().run(args);
}
public void TestAttributeSet() throws Exception {
run(new TestAttributeSet());
}
public void TestAttributeMap() throws Exception {
run(new TestAttributeMap());
}
public void TestFormatter() throws Exception {
run(new TestFormatter());
}
public void TestMText() throws Exception {
run(new TestMText());
}
public void TestParagraphStyles() throws Exception {
run(new TestParagraphStyles());
}
public void TestMTextStreaming() throws Exception {
run(new TestMTextStreaming());
}
public void TestTextPanel() throws Exception {
run(new TestTextPanel());
}
}

View File

@ -0,0 +1,409 @@
/*
* @(#)$RCSfile: TestAttributeMap.java,v $ $Revision: 1.1 $ $Date: 2000/04/24 20:38:00 $
*
* (C) Copyright IBM Corp. 1998-1999. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.richtext.tests;
import com.ibm.test.TestFmwk;
import com.ibm.textlayout.attributes.AttributeSet;
import com.ibm.textlayout.attributes.TextAttribute;
import com.ibm.textlayout.attributes.Map;
import com.ibm.textlayout.attributes.AttributeMap;
import java.util.Enumeration;
// Java2 imports
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import java.util.Map.Entry;
public class TestAttributeMap extends TestFmwk {
static final String COPYRIGHT =
"(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
// There are JDK 1.1 versions of AttributeMap and AttributeSet.
// Some of the tests in this class require Java 2 API's. I have
// tried to isolate these tests by conditionalizing them on
// this static variable. If you are back-porting to 1.1, remove
// the Java 2 tests ONLY.
private static final boolean gJDK11 = false;
public static void main(String[] args) throws Exception {
new TestAttributeMap().run(args);
}
private AttributeSet maps; // A Set of AttributeMaps
private AttributeSet sets; // A Set of Sets
private static final class TestAttribute extends TextAttribute {
TestAttribute(String name) {
super(name);
}
}
private static final TestAttribute[] attributes = {
new TestAttribute("0"), new TestAttribute("1"), new TestAttribute("2")
};
private static final Object[] values = {
"Hello world", new Float(-42), new Object(), new AttributeMap(new TestAttribute("3"), "HH")
};
/**
* Returns lhs.equals(rhs) - but also checks for symmetry, and
* consistency with hashCode().
*/
private boolean equalMaps(AttributeMap lhs, Object rhs) {
boolean equal = lhs.equals(rhs);
if (equal != (rhs.equals(lhs))) {
errln("AttributeMap.equals is not symetric");
}
if (equal) {
if (lhs.hashCode() != rhs.hashCode()) {
errln("AttributeMaps are equal but hashCodes differ");
}
}
return equal;
}
public TestAttributeMap() {
maps = AttributeSet.EMPTY_SET;
maps = maps.addElement(AttributeMap.EMPTY_ATTRIBUTE_MAP);
maps.addElement(new AttributeMap(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUB));
maps.addElement(new AttributeMap(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUPER));
for (int i=0; i < attributes.length; i++) {
for (int j=0; j < values.length; j++) {
maps = maps.addElement(new AttributeMap(attributes[i], values[j]));
}
}
AttributeMap bigMap = new AttributeMap(new TestAttribute("4"), "value");
for (int i=0; i < Math.min(attributes.length, values.length); i++) {
bigMap = bigMap.addAttribute(attributes[i], values[values.length-i-1]);
}
maps = maps.addElement(bigMap);
sets = AttributeSet.EMPTY_SET;
sets = new AttributeSet(AttributeSet.EMPTY_SET);
for (int i=0; i < attributes.length; i++) {
AttributeSet newSet = new AttributeSet(attributes[i]);
sets = sets.addElement(newSet);
}
AttributeSet allAttrs = AttributeSet.EMPTY_SET;
for (int i=0; i < attributes.length; i++) {
allAttrs = allAttrs.addElement(attributes[i]);
}
sets = sets.addElement(allAttrs);
}
/**
* Run tests on AttributeMap. If a test fails an exception will propogate out
* of this method.
*/
public void test() {
easyTests();
Enumeration mapIter = maps.elements();
while (mapIter.hasMoreElements()) {
AttributeMap testMap = (AttributeMap) mapIter.nextElement();
_testModifiers(testMap);
_testViews(testMap);
Enumeration unionIter = maps.elements();
while (unionIter.hasMoreElements()) {
_testUnionWith(testMap, (AttributeMap) unionIter.nextElement());
}
Enumeration setIter = sets.elements();
while (setIter.hasMoreElements()) {
AttributeSet testSet = (AttributeSet) setIter.nextElement();
_testIntersectWith(testMap, testSet);
_testRemoveAttributes(testMap, testSet);
}
}
}
/**
* Invoke modifiers on map. All should throw
* UnsupportedOperationException, and leave map unmodified.
*/
void _testModifiers(AttributeMap map) {
if (gJDK11) {
return;
}
AttributeMap originalMap = new AttributeMap(map);
try {
map.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
errln("Put should throw UnsupportedOperationException.");
}
catch(UnsupportedOperationException e) {
}
try {
Object key = TextAttribute.WEIGHT;
Iterator iter = map.keySet().iterator();
if (iter.hasNext()) {
key = iter.next();
}
map.remove(key);
errln("Set should throw UnsupportedOperationException.");
}
catch(UnsupportedOperationException e) {
}
try {
map.putAll(map);
errln("putAll should throw UnsupportedOperationException.");
}
catch(UnsupportedOperationException e) {
}
try {
map.clear();
errln("clear should throw UnsupportedOperationException.");
}
catch(UnsupportedOperationException e) {
}
if (!originalMap.equals(map)) {
errln("Modifiers changed map.");
}
}
/**
* Ensure that map.addAttributes(addMap) is equivalent to calling
* map.add on all of addMap's entries.
*/
void _testUnionWith(AttributeMap map, AttributeMap addMap) {
AttributeMap lhs = map.addAttributes(addMap);
AttributeMap rhs = map;
Enumeration iter = addMap.getKeySet().elements();
while (iter.hasMoreElements()) {
Object attr = iter.nextElement();
Object value = addMap.get(attr);
rhs = rhs.addAttribute(attr, value);
}
if (!equalMaps(lhs, rhs)) {
errln("Maps are not equal.");
}
}
/**
* Ensure that map.removeAttributes(remove) is equivalent to calling
* map.removeAttribute on remove's elements.
*/
void _testRemoveAttributes(AttributeMap map, AttributeSet remove) {
AttributeMap lhs = map.removeAttributes(remove);
AttributeMap rhs = map;
Enumeration iter = remove.elements();
while (iter.hasMoreElements()) {
Object attr = iter.nextElement();
rhs = rhs.removeAttribute(attr);
}
if (!equalMaps(lhs, rhs)) {
errln("Maps are not equal.");
}
}
/**
* Ensure that map.intersectWith(intersect) is equivalent to
* map.removeAttributes(map.keySet() - intersect);
*/
void _testIntersectWith(AttributeMap map, AttributeSet intersect) {
AttributeMap lhs = map.intersectWith(intersect);
AttributeSet keySet = map.getKeySet();
AttributeSet removeSet = keySet.subtract(intersect);
AttributeMap rhs = map.removeAttributes(removeSet);
if (!equalMaps(lhs, rhs)) {
map.intersectWith(intersect);
logln("intersect: " + intersect);
logln("keySet: " + keySet);
logln("removeSet: " + removeSet);
logln("map: " + map);
logln("lhs: " + lhs);
logln("rhs: " + rhs);
errln("Maps are not equal.");
}
}
/**
* Ensure that:
* map, map.keySet(), and map.entrySet() are the same size;
* map.containsKey() is true for every key in keySet();
* map.containsValue() is true for every value in values;
* every entry key is in keySet, every entry value is in map.values();
* map.get() is consistent with entry's key, value;
* sum of hashcodes of entries equals map.hashCode().
*/
void _testViews(AttributeMap map) {
AttributeSet keySet = map.getKeySet();
Enumeration keyIter = keySet.elements();
while (keyIter.hasMoreElements()) {
if (!map.containsKey(keyIter.nextElement())) {
errln("keySet contains key not in map");
}
}
if (gJDK11) {
return;
}
Collection values = map.values();
Set entrySet = map.entrySet();
if (keySet.size() != map.size() || entrySet.size() != map.size()) {
errln("Set sizes are inconsistent with map size.");
}
int hashCode = 0;
Iterator valueIter = values.iterator();
while (valueIter.hasNext()) {
if (!map.containsValue(valueIter.next())) {
errln("value set contains value not in map");
}
}
Iterator entryIter = entrySet.iterator();
while (entryIter.hasNext()) {
Entry entry = (Entry) entryIter.next();
Object key = entry.getKey();
if (!keySet.contains(key)) {
errln("Entry key is not in key set.");
}
Object value = map.get(entry.getKey());
if (!values.contains(value)) {
errln("Entry value is not in value set.");
}
if (map.get(key) != value) {
errln("map.get did not return entry value.");
}
hashCode += entry.hashCode();
}
if (hashCode != map.hashCode()) {
errln("map hashcode is not sum of entry hashcodes.");
}
}
/**
* Look for correct behavior in obvious cases.
*/
void easyTests() {
AttributeMap map = new AttributeMap();
if (!map.equals(AttributeMap.EMPTY_ATTRIBUTE_MAP)) {
errln("Default-constructed map is not equal to empty map.");
}
map = map.addAttribute(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
Object otherMap = new AttributeMap(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
if (!map.equals(otherMap)) {
errln("Maps are inconsistent after map.add");
}
otherMap = map.addAttributes(map);
if (!equalMaps(map,otherMap)) {
errln("Maps are inconsistent after addAttributes");
}
map = map.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
if (map.size() != 2) {
errln("Map size is wrong. map="+map);
}
if (equalMaps(map,otherMap)) {
errln("Maps should not be equal");
}
Object posture = new Float(0);
map = map.addAttribute(TextAttribute.POSTURE, posture);
if (map.size() != 2) {
errln("Map size is wrong");
}
if (!map.get(TextAttribute.POSTURE).equals(posture)) {
errln("Map element is wrong");
}
map = map.removeAttribute(TextAttribute.UNDERLINE);
if (map.size() != 1) {
errln("Map size is wrong");
}
if (map.get(TextAttribute.UNDERLINE) != null) {
errln("Map should not have element");
}
// map has POSTURE_REGULAR. If we addAttributes a map with
// POSTURE_ITALIC the new map should have POSTURE_ITALIC
map = map.addAttributes(new AttributeMap(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE));
if (map.get(TextAttribute.POSTURE) != TextAttribute.POSTURE_OBLIQUE) {
errln("Map element is wrong");
}
_testModifiers(map);
_testViews(map);
Enumeration mapIter = maps.elements();
while (mapIter.hasMoreElements()) {
AttributeMap testMap = (AttributeMap) mapIter.nextElement();
Object newValue = new Object();
AttributeMap newMap = testMap.addAttribute(attributes[0], newValue);
if (newMap.get(attributes[0]) != newValue) {
errln("Did not get expected value back. map=" + map);
}
}
}
}

View File

@ -0,0 +1,91 @@
/*
* @(#)$RCSfile: TestAttributeSet.java,v $ $Revision: 1.1 $ $Date: 2000/04/24 20:38:00 $
*
* (C) Copyright IBM Corp. 1998-1999. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.richtext.tests;
import com.ibm.test.TestFmwk;
import com.ibm.textlayout.attributes.AttributeSet;
import java.util.Enumeration;
public class TestAttributeSet extends TestFmwk {
static final String COPYRIGHT =
"(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
public static void main(String[] args) throws Exception {
new TestAttributeSet().run(args);
}
public void test() {
final Object elem1 = new Object();
final Object elem2 = new Float(4);
final Object elem3 = "String";
final Object elem4 = Boolean.FALSE;
AttributeSet set1 = new AttributeSet(new Object[] {elem1, elem2, elem3});
if (set1.size() != 3) {
errln("Size is wrong.");
}
if (set1.contains(elem4)){
errln("Set contents are wrong.");
}
if (!set1.contains(elem1)) {
errln("Set contents are wrong.");
}
AttributeSet set2 = new AttributeSet(elem4);
if (set2.size() != 1) {
errln("Size is wrong.");
}
if (!set2.contains(elem4)){
errln("Set contents are wrong.");
}
if (set2.contains(elem1)) {
errln("Set contents are wrong.");
}
Enumeration iter = set2.elements();
if (!iter.nextElement().equals(elem4)) {
errln("Invalid object in iterator.");
}
AttributeSet union = set2.unionWith(set1);
if (!set1.unionWith(set2).equals(union)) {
errln("unionWith is not commutative.");
}
if (!union.contains(elem1) || !union.contains(elem4)) {
errln("Set contents are wrong.");
}
if (!set1.addElement(elem4).equals(union)) {
errln("addElement is wrong.");
}
if (!union.intersectWith(set1).equals(set1)) {
errln("intersectWith is wrong.");
}
if (!union.subtract(set1).equals(set2)) {
errln("subtract is wrong.");
}
}
}

View File

@ -0,0 +1,250 @@
/*
* @(#)$RCSfile: TestFormatter.java,v $ $Revision: 1.1 $ $Date: 2000/04/24 20:38:00 $
*
* (C) Copyright IBM Corp. 1998-1999. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.richtext.tests;
import com.ibm.test.TestFmwk;
import com.ibm.textlayout.attributes.AttributeMap;
import com.ibm.textlayout.attributes.TextAttribute;
import com.ibm.richtext.styledtext.MText;
import com.ibm.richtext.styledtext.MConstText;
import com.ibm.richtext.styledtext.StandardTabRuler;
import com.ibm.richtext.styledtext.StyledText;
import com.ibm.richtext.textformat.TextOffset;
import com.ibm.richtext.textformat.MFormatter;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.util.Hashtable;
public final class TestFormatter extends TestFmwk {
static final String COPYRIGHT =
"(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
public static void main(String[] args) throws Exception {
new TestFormatter().run(args);
}
private static final Point ORIGIN = new Point(0, 0);
private static final AttributeMap DEFAULTS;
static {
final Float floatZero = new Float(0.0f);
Hashtable defaults = new Hashtable();
defaults.put(TextAttribute.FAMILY, "Serif");
defaults.put(TextAttribute.WEIGHT, new Float(1.0f));
defaults.put(TextAttribute.POSTURE, floatZero);
defaults.put(TextAttribute.SIZE, new Float(18.0f));
defaults.put(TextAttribute.SUPERSCRIPT, new Integer(0));
defaults.put(TextAttribute.FOREGROUND, Color.black);
defaults.put(TextAttribute.UNDERLINE, new Integer(-1));
defaults.put(TextAttribute.STRIKETHROUGH, Boolean.FALSE);
defaults.put(TextAttribute.EXTRA_LINE_SPACING, floatZero);
defaults.put(TextAttribute.FIRST_LINE_INDENT, floatZero);
defaults.put(TextAttribute.MIN_LINE_SPACING, floatZero);
defaults.put(TextAttribute.LINE_FLUSH, TextAttribute.FLUSH_LEADING);
defaults.put(TextAttribute.LEADING_MARGIN, floatZero);
defaults.put(TextAttribute.TRAILING_MARGIN, floatZero);
defaults.put(TextAttribute.TAB_RULER, new StandardTabRuler());
DEFAULTS = new AttributeMap(defaults);
}
// arg to testLineExceptions
private static final int UNKNOWN = -1;
private Graphics fGraphics;
public TestFormatter() {
fGraphics = new BufferedImage(100, 100, BufferedImage.TYPE_3BYTE_BGR).getGraphics();
//JDK 1.1:
//Frame f = new Frame();
//f.show();
//fGraphics = f.getGraphics();
}
private String fiveLines = "a\nb\nc\nd\ne";
private String twelveLines = fiveLines + "\n" + fiveLines + "\nf\n";
AttributeMap PLAIN = AttributeMap.EMPTY_ATTRIBUTE_MAP;
public void test() {
MConstText text = new StyledText(fiveLines, PLAIN);
_testLineExceptions(makeFormatter(text, 100, true), 5);
_testLineAccess(makeFormatter(text, 100, true), 5);
text = new StyledText(twelveLines, PLAIN);
_testLineExceptions(makeFormatter(text, 3, false), 12);
_testLineAccess(makeFormatter(text, 100, true), 12);
_testWithModification();
}
private void _testWithModification() {
MText text = new StyledText(fiveLines, PLAIN);
MFormatter formatter = makeFormatter(text, 100, true);
Rectangle viewRect = new Rectangle(0, 0, 100, Integer.MAX_VALUE);
formatter.stopBackgroundFormatting();
text.append(new StyledText("\n", PLAIN));
formatter.updateFormat(text.length()-1, 1, viewRect, ORIGIN);
_testLineAccess(formatter, 6);
formatter.stopBackgroundFormatting();
text.append(new StyledText("ad", PLAIN));
formatter.updateFormat(text.length()-2, 2, viewRect, ORIGIN);
_testLineAccess(formatter, 6);
_testLineExceptions(formatter, 6);
formatter.stopBackgroundFormatting();
text.remove(0, 1);
formatter.updateFormat(0, 0, viewRect, ORIGIN);
_testLineAccess(formatter, 6);
_testLineExceptions(formatter, 6);
}
private MFormatter makeFormatter(MConstText text,
int lineBound,
boolean wrap) {
return MFormatter.createFormatter(text,
DEFAULTS,
lineBound,
wrap,
fGraphics);
}
private void _testLineExceptions(MFormatter formatter,
int numLines) {
if (numLines == UNKNOWN) {
numLines = formatter.getLineCount();
}
boolean caught = false;
try {
formatter.lineRangeLow(numLines);
}
catch(IllegalArgumentException e) {
caught = true;
}
if (!caught) {
errln("Didn't get exception");
}
caught = false;
try {
formatter.lineRangeLimit(numLines);
}
catch(IllegalArgumentException e) {
caught = true;
}
if (!caught) {
errln("Didn't get exception");
}
caught = false;
try {
formatter.lineGraphicStart(numLines+1);
}
catch(IllegalArgumentException e) {
caught = true;
}
if (!caught) {
errln("Didn't get exception");
}
caught = false;
}
private void _testLineAccess(MFormatter formatter,
int numLines) {
if (numLines == UNKNOWN) {
numLines = formatter.getLineCount();
}
if (formatter.lineGraphicStart(0) != 0) {
errln("Line 0 doesn't start at height 0");
}
if (formatter.lineRangeLow(0) != 0) {
errln("Line 0 doesn't start at character 0");
}
int lastLimit = formatter.lineRangeLimit(0);
final int lineBound = formatter.lineBound();
int[] hitX = new int[] { -1, 1, lineBound + 2 };
TextOffset offset = new TextOffset();
for (int i=1; i < numLines; i++) {
int height = formatter.lineGraphicStart(i);
if (lastLimit != formatter.lineRangeLow(i)) {
errln("lastLine limit is not current line start");
}
int limit = formatter.lineRangeLimit(i);
if (limit < lastLimit || (limit == lastLimit && i != numLines-1)) {
errln("line has negative or 0 length");
}
int nextHeight = formatter.lineGraphicStart(i+1);
if (nextHeight <= height) {
errln("0-height line");
}
int incAmount = Math.max((nextHeight-height)/4, 1);
for (int hitY = height; hitY < nextHeight; hitY += incAmount) {
if (formatter.lineAtHeight(hitY) != i) {
errln("lineAtHeight is wrong");
}
for (int j=0; j < hitX.length; j++) {
offset = formatter.pointToTextOffset(offset,
hitX[j], hitY, ORIGIN, null, false);
if (offset.fOffset < lastLimit || offset.fOffset > limit) {
errln("Inconsistent offset from pointToTextOffset");
}
//if (formatter.lineContaining(offset) != i) {
// int debug = formatter.lineContaining(offset);
// errln("lineContaining is incorrect");
//}
}
}
lastLimit = limit;
}
}
}

View File

@ -0,0 +1,721 @@
/*
* @(#)$RCSfile: TestMText.java,v $ $Revision: 1.1 $ $Date: 2000/04/24 20:38:00 $
*
* (C) Copyright IBM Corp. 1998-1999. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.richtext.tests;
import com.ibm.test.TestFmwk;
import com.ibm.textlayout.attributes.AttributeMap;
import com.ibm.textlayout.attributes.TextAttribute;
import com.ibm.richtext.styledtext.MConstText;
import com.ibm.richtext.styledtext.MText;
import com.ibm.richtext.styledtext.StyledText;
import com.ibm.richtext.styledtext.StyleModifier;
import java.text.CharacterIterator;
import java.util.Random;
import java.io.*;
public class TestMText extends TestFmwk {
static final String COPYRIGHT =
"(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
public static void main(String[] args) throws Exception {
new TestMText().run(args);
}
private static final int TEST_ITERATIONS = 5000;
private static final int STYLE_TEST_ITERATIONS = 5000;
private static final long RAND_SEED = 598436;
private static final int NOT_IN_MONKEY_TEST = -5000;
private int testIteration = NOT_IN_MONKEY_TEST;
private int theCase = NOT_IN_MONKEY_TEST;
private static StyleModifier createMinusModifier(final Object attr) {
return new StyleModifier() {
public AttributeMap modifyStyle(AttributeMap style) {
return style.removeAttribute(attr);
}
};
}
public void test() {
simpleTest();
styleTest();
monkeyTest(true);
}
public void simpleTest() {
AttributeMap boldStyle = new AttributeMap(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
AttributeMap italicStyle = new AttributeMap(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
MConstText allBold = new StyledText("bbbbb", boldStyle);
MConstText allItalic = new StyledText("iii", italicStyle);
MConstText plain = new StyledText("pppppp", AttributeMap.EMPTY_ATTRIBUTE_MAP);
{
MText buf = new StyledText();
int ts = buf.getTimeStamp();
buf.append(allBold);
buf.append(allItalic);
if (ts == buf.getTimeStamp()) {
errln("Time stamp not incremented");
}
// should be bbbbbiii now
if (buf.length() != allBold.length() + allItalic.length()) {
errln("Length is wrong.");
}
for (int i=0; i < buf.length(); i++) {
char rightChar;
AttributeMap rightStyle;
if (i < allBold.length()) {
rightChar = allBold.at(0);
rightStyle = boldStyle;
}
else {
rightChar = allItalic.at(0);
rightStyle = italicStyle;
}
if (buf.at(i) != rightChar) {
errln("Character is wrong.");
}
if (!buf.characterStyleAt(i).equals(rightStyle)) {
errln("Style is wrong.");
}
}
int pos = 0;
if (!buf.characterStyleAt(pos).equals(boldStyle)) {
errln("First style is wrong.");
}
if (buf.characterStyleLimit(pos) != allBold.length()) {
errln("Run length is wrong.");
}
pos = allBold.length();
if (!buf.characterStyleAt(pos).equals(italicStyle)) {
errln("Second style is wrong.");
}
if (buf.characterStyleLimit(pos) != buf.length()) {
errln("Run length is wrong.");
}
{
buf.resetDamagedRange();
int oldLength = buf.length();
buf.replace(buf.length(), buf.length(), allBold, 0, allBold.length());
// bbbbbiiibbbbb
if (buf.damagedRangeStart() != oldLength) {
errln("Damaged range start is incorrect");
}
if (buf.damagedRangeLimit() != buf.length()) {
errln("Damaged range limit is incorrect");
}
}
int start = allBold.length();
int limit = start + allItalic.length();
buf.remove(start, limit);
// bbbbbbbbbb
if (buf.length() != 2 * allBold.length()) {
errln("Text should be twice the length of bold text.");
}
pos = buf.length() / 2;
if (buf.characterStyleStart(pos) != 0 ||
buf.characterStyleLimit(pos) != buf.length()) {
errln("Run range is wrong.");
}
if (!buf.characterStyleAt(pos).equals(boldStyle)) {
errln("Run style is wrong.");
}
ts = buf.getTimeStamp();
CharacterIterator cIter = buf.createCharacterIterator();
for (char ch = cIter.first(); ch != cIter.DONE; ch = cIter.next()) {
if (ch != allBold.at(0)) {
errln("Character is wrong.");
}
}
if (ts != buf.getTimeStamp()) {
errln("Time stamp should not have changed");
}
buf.replace(0, 1, plain, 0, plain.length());
if (ts == buf.getTimeStamp()) {
errln("Time stamp not incremented");
}
// ppppppbbbbbbbbb
buf.replace(plain.length(), buf.length(), allItalic, 0, allItalic.length());
// ppppppiii
if (buf.length() != allItalic.length()+plain.length()) {
errln("Length is wrong.");
}
pos = 0;
if (buf.characterStyleLimit(pos) != plain.length()) {
errln("Run limit is wrong.");
}
pos = plain.length();
if (buf.characterStyleLimit(pos) != buf.length()) {
errln("Run limit is wrong.");
}
buf.replace(plain.length(), plain.length(), allBold, 0, allBold.length());
// ppppppbbbbbiii
AttributeMap st = buf.characterStyleAt(1);
if (!st.equals(AttributeMap.EMPTY_ATTRIBUTE_MAP)) {
errln("Style is wrong.");
}
if (buf.characterStyleStart(1) != 0 || buf.characterStyleLimit(1) != plain.length()) {
errln("Style start is wrong.");
}
st = buf.characterStyleAt(buf.length() - 1);
if (!st.equals(italicStyle)) {
errln("Style is wrong.");
}
if (buf.characterStyleStart(buf.length() - 1) != plain.length()+allBold.length()) {
errln("Style start is wrong.");
}
if (buf.characterStyleLimit(buf.length() - 1) != buf.length()) {
errln("Style limit is wrong.");
}
}
}
private static int randInt(Random rand, int limit) {
return randInt(rand, 0, limit);
}
private static int randInt(Random rand, int start, int limit) {
if (start > limit) {
throw new IllegalArgumentException("Range length is negative.");
}
else if (start == limit) {
return start;
}
return start + (Math.abs(rand.nextInt())%(limit-start)) ;
}
public void styleTest() {
MText text = new StyledText("0123456789", AttributeMap.EMPTY_ATTRIBUTE_MAP);
AttributeMap[] styles = new AttributeMap[text.length()];
for (int i=0; i < styles.length; i++) {
styles[i] = AttributeMap.EMPTY_ATTRIBUTE_MAP;
}
AttributeMap[] oldStyles = new AttributeMap[styles.length];
System.arraycopy(styles, 0, oldStyles, 0, styles.length);
AttributeMap bigStyle = new AttributeMap(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON).
addAttribute(TextAttribute.SIZE, new Float(23.0f));
StyleModifier[] modifiers = {
StyleModifier.createReplaceModifier(new AttributeMap(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD)),
StyleModifier.createAddModifier(new AttributeMap(TextAttribute.WEIGHT, new Float(1.0f))),
createMinusModifier(TextAttribute.WEIGHT),
StyleModifier.createAddModifier(new AttributeMap(TextAttribute.POSTURE, new Float(0.0f))),
StyleModifier.createReplaceModifier(new AttributeMap(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE)),
createMinusModifier(TextAttribute.POSTURE),
StyleModifier.createAddModifier(bigStyle),
StyleModifier.createReplaceModifier(bigStyle),
createMinusModifier(bigStyle.getKeySet())
};
Random rand = new Random(RAND_SEED);
final int stopAt = 4;
for (int testIteration=0; testIteration < STYLE_TEST_ITERATIONS + 1; testIteration++) {
System.arraycopy(styles, 0, oldStyles, 0, styles.length);
int startingAt = Integer.MAX_VALUE;
int endingAt = Integer.MIN_VALUE;
int oldTs = text.getTimeStamp();
// hack way to do an invariant check before starting...
if (testIteration != 0) {
// modify styles
text.resetDamagedRange();
startingAt = randInt(rand, styles.length+1);
endingAt = randInt(rand, startingAt, styles.length+1);
StyleModifier modifier = modifiers[randInt(rand, modifiers.length)];
if (testIteration == stopAt) {
testIteration = stopAt;
}
text.modifyCharacterStyles(startingAt, endingAt, modifier);
for (int j=startingAt; j < endingAt; j++) {
styles[j] = modifier.modifyStyle(styles[j]);
}
}
// check invariants
AttributeMap oldStyle = null;
int textLength = text.length();
for (int runStart = 0; runStart < textLength;) {
AttributeMap currentStyle = text.characterStyleAt(runStart);
int runLimit = text.characterStyleLimit(runStart);
if (runStart >= runLimit) {
errln("Run length is not positive");
}
if (currentStyle.equals(oldStyle)) {
errln("Styles didn't merge");
}
for (int pos=runStart; pos < runLimit; pos++) {
AttributeMap charStyleAtPos = text.characterStyleAt(pos);
if (currentStyle != charStyleAtPos) {
errln("Iterator style is not equal to text style at " + pos + ".");
}
AttributeMap expected = styles[pos];
if (!currentStyle.equals(expected)) {
errln("Iterator style doesn't match expected style at " + pos + ".");
}
if (!(text.characterStyleStart(pos) == runStart) ||
!(text.characterStyleLimit(pos) == runLimit)) {
errln("style run start / limit is not consistent");
}
}
runStart = runLimit;
}
if (textLength > 0) {
if (text.characterStyleAt(textLength) !=
text.characterStyleAt(textLength-1)) {
errln("Character styles at end aren't the same");
}
}
// check damaged range:
int damageStart = Integer.MAX_VALUE;
int damageLimit = Integer.MIN_VALUE;
for (int i=0; i < textLength; i++) {
if (!styles[i].equals(oldStyles[i])) {
damageStart = Math.min(i, damageStart);
damageLimit = Math.max(i+1, damageLimit);
}
}
if (damageStart != text.damagedRangeStart() ||
damageLimit != text.damagedRangeLimit()) {
logln("Test iteration: " + testIteration);
logln("startingAt: " + startingAt + "; endingAt: " + endingAt);
logln("damageStart: " + damageStart + "; damageLimit: " + damageLimit);
logln("text.rangeStart: " + text.damagedRangeStart() +
"text.rangeLimit: " + text.damagedRangeLimit());
errln("Damage range start or limit is not expected value");
}
if ((damageLimit == Integer.MIN_VALUE) != (oldTs == text.getTimeStamp())) {
errln("timeStamp is incorrect");
}
}
}
protected void err(String message) {
if (testIteration != NOT_IN_MONKEY_TEST) {
message = "testIteration="+testIteration+"; testCase="+theCase+message;
}
super.err(message);
}
/**
* Perform a random series of operations on an MText and
* check the result of each operation against a set of invariants.
*/
public void monkeyTest(boolean streaming) {
/*
You can add any operation to the switch statement provided it
preserves the following invariants:
- The String plainText contains the same text as the StyledStringBuffer.
Obviously, for the test to be meaningful plainText must be computed
independently of the buffer (ie don't write: plainText = buf.getStyledString().toString()).
- Every 'b' is bold, every 'i' is italic, every 'p' is plain, and
no other characters appear in the text.
*/
AttributeMap boldAttrs = new AttributeMap(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
AttributeMap italicAttrs = new AttributeMap(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
AttributeMap emptyAttrs = AttributeMap.EMPTY_ATTRIBUTE_MAP;
final String bold1Str_getString = "b";
MConstText bold1Str = new StyledText(bold1Str_getString, boldAttrs);
final String italic1Str_getString = "i";
MConstText italic1Str = new StyledText(italic1Str_getString, italicAttrs);
final String plain1Str_getString = "p";
MConstText plain1Str = new StyledText(plain1Str_getString, emptyAttrs);
StyledText temp = new StyledText();
temp.append(bold1Str);
temp.append(italic1Str);
final String boldItalicStr_getString = bold1Str_getString.concat(italic1Str_getString);
MConstText boldItalicStr = temp;
temp = new StyledText();
temp.append(bold1Str);
temp.append(bold1Str);
temp.append(bold1Str);
final String bold3Str_getString = "bbb";
MConstText bold3Str = temp;
MText buf = new StyledText();
String plainText = new String();
//int testIteration=0; - now instance variables so errln can report it
//int theCase=0;
final int NUM_CASES = 14;
boolean[] casesExecuted = new boolean[NUM_CASES];
final int stopAt = -1;
Random rand = new Random(RAND_SEED);
final String ALWAYS_DIFFERENT = "\uFEFF";
for (testIteration=0; testIteration < TEST_ITERATIONS; testIteration++) {
theCase = randInt(rand, NUM_CASES);
casesExecuted[theCase] = true;
if (testIteration == stopAt) {
testIteration = stopAt; // Convenient place to put breakpoint
}
int timeStamp = buf.getTimeStamp();
String oldPlainText = plainText;
if (oldPlainText == null) {
errln("oldPlainText is null!");
}
switch (theCase) {
case 0:
// create new string; replace chars at start with different style
buf = new StyledText();
buf.append(bold3Str);
buf.replace(0, 1, italic1Str, 0, italic1Str.length());
buf.replace(0, 0, italic1Str, 0, italic1Str.length());
plainText = bold3Str_getString.substring(1, bold3Str.length());
plainText = italic1Str_getString.concat(plainText);
plainText = italic1Str_getString.concat(plainText);
oldPlainText = null;
break;
case 1:
// delete the last character from the string
if (buf.length() == 0) {
buf.replace(0, 0, italic1Str, 0, italic1Str.length());
plainText = italic1Str_getString;
oldPlainText = ALWAYS_DIFFERENT;
}
buf.remove(buf.length()-1, buf.length());
plainText = plainText.substring(0, plainText.length()-1);
break;
case 2:
// replace some of the buffer with boldItalicStr
int rStart = randInt(rand, buf.length()+1);
int rStop = randInt(rand, rStart, buf.length()+1);
buf.replace(rStart, rStop, boldItalicStr);
{
String newString = (rStart>0)? plainText.substring(0, rStart) : new String();
newString = newString.concat(boldItalicStr_getString);
if (rStop < plainText.length())
newString = newString.concat(plainText.substring(rStop, plainText.length()));
oldPlainText = ALWAYS_DIFFERENT;
plainText = newString;
}
break;
case 3:
// repeatedly insert strings into the center of the buffer
{
int insPos = buf.length() / 2;
String prefix = plainText.substring(0, insPos);
String suffix = plainText.substring(insPos, plainText.length());
String middle = new String();
for (int ii=0; ii<4; ii++) {
MConstText which = (ii%2==0)? boldItalicStr : bold3Str;
String whichString = (ii%2==0)? boldItalicStr_getString : bold3Str_getString;
int tempPos = insPos+middle.length();
buf.insert(tempPos, which);
middle = middle.concat(whichString);
}
plainText = prefix.concat(middle).concat(suffix);
oldPlainText = ALWAYS_DIFFERENT;
}
break;
case 4:
// insert bold1Str at end
buf.append(bold1Str);
plainText = plainText.concat(bold1Str_getString);
break;
case 5:
// delete a character from the string
if (buf.length() > 0) {
int delPos = randInt(rand, buf.length()-1);
buf.remove(delPos, delPos+1);
plainText = plainText.substring(0, delPos).concat(plainText.substring(delPos+1));
}
else {
buf.replace(0, 0, plain1Str, 0, plain1Str.length());
plainText = plain1Str_getString;
}
break;
case 6:
// replace the contents of the buffer (except the first character) with itself
{
int start = buf.length() > 1? 1 : 0;
buf.replace(start, buf.length(), buf);
plainText = plainText.substring(0, start).concat(plainText);
if (buf.length() > 0) {
oldPlainText = ALWAYS_DIFFERENT;
}
}
break;
case 7:
// append the contents of the buffer to itself
{
MConstText content = buf;
buf.insert(buf.length(), content);
plainText = plainText.concat(plainText);
}
break;
case 8:
// replace the buffer with boldItalicStr+bold3Str
{
MText replacement = new StyledText();
replacement.append(boldItalicStr);
replacement.append(bold3Str);
buf.replace(0, buf.length(), replacement, 0, replacement.length());
plainText = boldItalicStr_getString.concat(bold3Str_getString);
oldPlainText = ALWAYS_DIFFERENT;
}
break;
case 9:
// insert bold1Str at end - same as 4 but uses different API
buf.replace(buf.length(),
buf.length(),
bold1Str_getString.toCharArray(),
0,
bold1Str_getString.length(),
boldAttrs);
plainText = plainText.concat(bold1Str_getString);
break;
case 10:
// remove all
buf.remove();
plainText = "";
oldPlainText = ALWAYS_DIFFERENT;
break;
case 11:
// remove all - different way
buf.remove(0, buf.length());
plainText = "";
break;
case 12:
// insert 'i' at 3rd character (or last, if fewer than 3 chars)
{
int insPos = Math.min(buf.length(), 3);
buf.replace(insPos, insPos, 'i', italicAttrs);
plainText = (plainText.substring(0, insPos)).
concat(italic1Str_getString).
concat(plainText.substring(insPos));
}
break;
case 13:
if (streaming) {
Throwable error = null;
try {
ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
ObjectOutputStream objOut = new ObjectOutputStream(bytesOut);
objOut.writeObject(buf);
ByteArrayInputStream bytesIn =
new ByteArrayInputStream(bytesOut.toByteArray());
ObjectInputStream objIn = new ObjectInputStream(bytesIn);
buf = (MText) objIn.readObject();
oldPlainText = null;
}
catch(IOException e) {
error = e;
}
catch(ClassNotFoundException e) {
error = e;
}
if (error != null) {
error.printStackTrace();
errln("Streaming problem: " + error);
}
}
break;
default:
errln("Invalid case.");
}
// Check time stamp if oldPlainText != null.
// Time stamp should be different iff
// oldPlainText == plainText
if (oldPlainText != null) {
if ((timeStamp==buf.getTimeStamp()) !=
oldPlainText.equals(plainText)) {
logln("plainText hashCode: " + plainText.hashCode());
logln("oldPlainText hashCode: " + oldPlainText.hashCode());
errln("Time stamp is incorrect");
}
}
// now check invariants:
if (plainText.length() != buf.length()) {
errln("Lengths don't match");
}
for (int j=0; j < buf.length(); j++) {
if (buf.at(j) != plainText.charAt(j)) {
errln("Characters don't match.");
}
}
int start;
for (start = 0; start < buf.length();) {
if (start != buf.characterStyleStart(start)) {
errln("style start is wrong");
}
int limit = buf.characterStyleLimit(start);
if (start >= limit) {
errln("start >= limit");
}
char current = plainText.charAt(start);
AttributeMap comp = null;
if (current == 'p') {
comp = emptyAttrs;
}
else if (current == 'b') {
comp = boldAttrs;
}
else if (current == 'i') {
comp = italicAttrs;
}
else {
errln("An invalid character snuck in!");
}
AttributeMap startStyle = buf.characterStyleAt(start);
if (!comp.equals(startStyle)) {
errln("Style is not expected style.");
}
for (int j = start; j < limit; j++) {
if (plainText.charAt(j) != current) {
errln("Character doesn't match style.");
}
if (buf.characterStyleAt(j) != startStyle) {
errln("Incorrect style in run");
}
}
if (limit < buf.length()) {
if (plainText.charAt(limit) == current) {
errln("Style run ends too soon.");
}
}
start = limit;
}
if (start != buf.length()) {
errln("Last limit is not buffer length.");
}
// won't try to compute and check damaged range; however,
// if nonempty it should always be within text
int damageStart = buf.damagedRangeStart();
int damageLimit = buf.damagedRangeLimit();
if (damageStart == Integer.MAX_VALUE) {
if (damageLimit != Integer.MIN_VALUE) {
errln("Invalid empty interval");
}
}
else {
if (damageStart > damageLimit) {
errln("Damage range inverted");
}
if (damageStart < 0 || damageLimit > buf.length()) {
errln("Damage range endpoint out of bounds");
}
}
}
testIteration = NOT_IN_MONKEY_TEST;
boolean allCasesExecuted = true;
for (int index=0; index < NUM_CASES; index++) {
allCasesExecuted &= casesExecuted[index];
if (casesExecuted[index] == false) {
logln("Case " + index + " not executed.");
}
}
//if (allCasesExecuted) {
// logln("All cases executed.");
//}
}
}

View File

@ -0,0 +1,162 @@
/*
* @(#)$RCSfile: TestMTextStreaming.java,v $ $Revision: 1.1 $ $Date: 2000/04/24 20:38:00 $
*
* (C) Copyright IBM Corp. 1998-1999. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.richtext.tests;
import com.ibm.test.TestFmwk;
import java.io.*;
import java.awt.Color;
import com.ibm.richtext.styledtext.MText;
import com.ibm.richtext.styledtext.StandardTabRuler;
import com.ibm.richtext.styledtext.StyledText;
import com.ibm.richtext.styledtext.StyleModifier;
import com.ibm.textlayout.attributes.AttributeMap;
import com.ibm.textlayout.attributes.TextAttribute;
public class TestMTextStreaming extends TestFmwk {
static final String COPYRIGHT =
"(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
public static void main(String[] args) throws Exception {
new TestMTextStreaming().run(args);
}
public TestMTextStreaming() {
}
public void test() {
simpleTest();
allAttributesTest();
}
private void simpleTest() {
AttributeMap style = AttributeMap.EMPTY_ATTRIBUTE_MAP;
MText text = new StyledText("Hello world!", style);
streamAndCompare(text);
}
private static class TestModifier extends StyleModifier {
private Object fKey;
private Object fValue;
public AttributeMap modifyStyle(AttributeMap style) {
return style.addAttribute(fKey, fValue);
}
TestModifier(Object key, Object value) {
fKey = key;
fValue = value;
}
}
private void allAttributesTest() {
AttributeMap style = AttributeMap.EMPTY_ATTRIBUTE_MAP;
MText text = new StyledText("Hello world!", style);
int length = text.length();
final boolean CHARACTER = true;
final boolean PARAGRAPH = false;
addStyle(text, 0, length/2, TextAttribute.FAMILY, "Times", CHARACTER);
addStyle(text, length/2, length, TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, CHARACTER);
addStyle(text, 0, length/2, TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE, CHARACTER);
addStyle(text, 0, length/2, TextAttribute.SIZE, new Float(13.7f), CHARACTER);
addStyle(text, length/2, length, TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUB, CHARACTER);
addStyle(text, 0, length/2, TextAttribute.FOREGROUND, Color.blue, CHARACTER);
addStyle(text, 0, length/2, TextAttribute.BACKGROUND, Color.red, CHARACTER);
addStyle(text, 0, length-1, TextAttribute.STRIKETHROUGH, Boolean.TRUE, CHARACTER);
addStyle(text, 0, length, TextAttribute.EXTRA_LINE_SPACING, new Float(4), PARAGRAPH);
addStyle(text, 0, length, TextAttribute.FIRST_LINE_INDENT, new Float(6), PARAGRAPH);
addStyle(text, 0, length, TextAttribute.MIN_LINE_SPACING, new Float(7), PARAGRAPH);
addStyle(text, 0, length, TextAttribute.LINE_FLUSH, TextAttribute.FLUSH_TRAILING, PARAGRAPH);
addStyle(text, 0, length, TextAttribute.LEADING_MARGIN, new Float(9), PARAGRAPH);
addStyle(text, 0, length, TextAttribute.TRAILING_MARGIN, new Float(9), PARAGRAPH);
addStyle(text, 0, length, TextAttribute.TAB_RULER, new StandardTabRuler(), PARAGRAPH);
streamAndCompare(text);
}
private static void addStyle(MText text,
int start,
int limit,
Object key,
Object value,
boolean character) {
StyleModifier modifier = new TestModifier(key, value);
if (character) {
text.modifyCharacterStyles(start, limit, modifier);
}
else {
text.modifyParagraphStyles(start, limit, modifier);
}
}
public void streamAndCompare(MText text) {
Throwable error = null;
try {
ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
ObjectOutputStream objOut = new ObjectOutputStream(bytesOut);
objOut.writeObject(text);
ByteArrayInputStream bytesIn =
new ByteArrayInputStream(bytesOut.toByteArray());
ObjectInputStream objIn = new ObjectInputStream(bytesIn);
MText streamedText = (MText) objIn.readObject();
if (!isEqual(text, streamedText)) {
isEqual(text, streamedText);
errln("Streamed text is not equal");
}
}
/* catch(OptionalDataException e) {
error = e;
}
catch(StreamCorruptedException e) {
error = e;
}*/
catch(IOException e) {
error = e;
}
catch(ClassNotFoundException e) {
error = e;
}
if (error != null) {
error.printStackTrace();
errln("Serialization failed.");
}
}
public static boolean isEqual(MText lhs, MText rhs) {
return lhs.equals(rhs);
}
}

View File

@ -0,0 +1,339 @@
/*
* @(#)$RCSfile: TestParagraphStyles.java,v $ $Revision: 1.1 $ $Date: 2000/04/24 20:38:00 $
*
* (C) Copyright IBM Corp. 1998-1999. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.richtext.tests;
import com.ibm.test.TestFmwk;
import com.ibm.richtext.styledtext.StyledText;
import com.ibm.richtext.styledtext.MConstText;
import com.ibm.richtext.styledtext.MText;
import com.ibm.textlayout.attributes.AttributeMap;
import com.ibm.richtext.styledtext.StyleModifier;
import java.util.Random;
public final class TestParagraphStyles extends TestFmwk {
static final String COPYRIGHT =
"(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
public static void main(String[] args) throws Exception {
new TestParagraphStyles().run(args);
}
private static final int RAND_SEED = 1234;
private static final int NUM_TESTS = 2500;
private static final boolean isParagraphBreak(char c) {
return c =='\u2029' || c == '\n';
}
private static final Object KEY = "KEY";
private static final AttributeMap PLAIN = AttributeMap.EMPTY_ATTRIBUTE_MAP;
private static final AttributeMap A_STYLE = new AttributeMap(KEY, new Character('a'));
private static final StyleModifier A_MOD =
StyleModifier.createReplaceModifier(A_STYLE);
private static final AttributeMap B_STYLE = new AttributeMap(KEY, new Character('b'));
private static final StyleModifier B_MOD =
StyleModifier.createReplaceModifier(B_STYLE);
private static final AttributeMap C_STYLE = new AttributeMap(KEY, new Character('c'));
private static final StyleModifier C_MOD =
StyleModifier.createReplaceModifier(C_STYLE);
private static final AttributeMap D_STYLE = new AttributeMap(KEY, new Character('d'));
private static final StyleModifier D_MOD =
StyleModifier.createReplaceModifier(D_STYLE);
private static final AttributeMap E_STYLE = new AttributeMap(KEY, new Character('e'));
private static final StyleModifier E_MOD =
StyleModifier.createReplaceModifier(E_STYLE);
public void test() {
easyTests();
randomTest();
}
private void easyTests() {
MText text = new StyledText("a\nb\nc\nd\n", PLAIN);
text.modifyParagraphStyles(0, text.length(), A_MOD);
verifyParagraphCount(text);
MText src = new StyledText("XXX\nYYY", PLAIN);
src.modifyParagraphStyles(0, src.length(), B_MOD);
verifyParagraphCount(src);
MText temp = text.extractWritable(0, text.length());
temp.append(src);
verifyParagraphCount(temp);
for (int i=0; i < text.length(); i++) {
if (!temp.paragraphStyleAt(i).equals(text.paragraphStyleAt(i))) {
errln("Paragraph styles are wrong");
}
}
for (int i=0; i < src.length(); i++) {
if (!temp.paragraphStyleAt(i+text.length()).equals(src.paragraphStyleAt(i))) {
errln("Paragraph styles are wrong");
}
}
temp = text.extractWritable(0, text.length());
temp.replace(0, 1, src, 0, src.length());
verifyParagraphCount(temp);
if (temp.paragraphLimit(0) != 4) {
errln("Paragraph limit is wrong");
}
if (!temp.paragraphStyleAt(0).equals(B_STYLE)) {
errln("First style is wrong");
}
if (!temp.paragraphStyleAt(4).equals(A_STYLE)) {
errln("Style after insert is wrong");
}
// test append
MConstText newSrc = src.extract(4, 7);
MText initC = new StyledText("cccccc", PLAIN);
initC.modifyParagraphStyles(0, initC.length(), C_MOD);
initC.append(newSrc);
// now initC should be one paragraph with style B
if (initC.paragraphLimit(0) != initC.length()) {
errln("Should only be one paragraph");
}
if (initC.paragraphStyleAt(0) != initC.paragraphStyleAt(initC.length())) {
errln("Two different paragraph styles");
}
if (!initC.paragraphStyleAt(initC.length()/2).equals(B_STYLE)) {
errln("Incorrect paragraph style");
}
text = new StyledText("aaa\n", PLAIN);
text.modifyParagraphStyles(0, text.length(), A_MOD);
text.modifyParagraphStyles(text.length(), text.length(), B_MOD);
if (text.paragraphStyleAt(text.length()) != B_STYLE) {
errln("0-length paragraph at end has incorrect style");
}
}
private static int randInt(Random rand, int limit) {
return randInt(rand, 0, limit);
}
private static int randInt(Random rand, int start, int limit) {
if (start > limit) {
throw new IllegalArgumentException("Range is 0-length.");
}
else if (start == limit) {
return start;
}
return start + (Math.abs(rand.nextInt())%(limit-start)) ;
}
private void randomTest() {
MText noParagraph = new StyledText("zzzz", PLAIN);
noParagraph.modifyParagraphStyles(0, noParagraph.length(), A_MOD);
MText twoParagraphs = new StyledText("aaa\nbbb", PLAIN);
twoParagraphs.modifyParagraphStyles(0, twoParagraphs.paragraphLimit(0), B_MOD);
MText threeParagraphs = new StyledText("cc\ndd\nee", PLAIN);
threeParagraphs.modifyParagraphStyles(0, 3, C_MOD);
threeParagraphs.modifyParagraphStyles(3, 6, D_MOD);
threeParagraphs.modifyParagraphStyles(6, 8, E_MOD);
MText trailingP1 = new StyledText("hhhh\n", PLAIN);
trailingP1.modifyParagraphStyles(0, trailingP1.paragraphLimit(0), C_MOD);
MText trailingP2 = new StyledText("iii\n", PLAIN);
trailingP2.modifyParagraphStyles(0, 0, D_MOD);
trailingP2.modifyParagraphStyles(trailingP2.length(), trailingP2.length(), B_MOD);
if (!trailingP2.paragraphStyleAt(trailingP2.length()-1).equals(D_STYLE)) {
errln("Style incorrect in trailingP2");
}
if (!trailingP2.paragraphStyleAt(trailingP2.length()).equals(B_STYLE)) {
errln("Ending style incorrect in trailingP2");
}
MConstText[] tests = { noParagraph, twoParagraphs,
threeParagraphs, trailingP1, trailingP2 };
Random random = new Random(RAND_SEED);
int stopAt = 465;
int i = 0;
try {
for (i=0; i < NUM_TESTS; i++) {
int srcIndex = randInt(random, tests.length);
int targetIndex = randInt(random, tests.length);
MText target = new StyledText(tests[targetIndex]);
MConstText src = tests[srcIndex];
int srcStart = randInt(random, src.length());
int srcLimit = randInt(random, srcStart, src.length());
int start = randInt(random, target.length());
int limit = randInt(random, start, target.length());
if (i == stopAt) {
stopAt = i;
}
insertAndCheck(src, srcStart, srcLimit, target, start, limit);
}
}
finally {
if (i < NUM_TESTS) {
logln("iteration=" + i);
}
}
}
private void insertAndCheck(MConstText src, int srcStart, int srcLimit,
MText target, int start, int limit) {
// p-style after insertion
AttributeMap after;
if (limit == target.length() && srcLimit > srcStart) {
after = src.paragraphStyleAt(srcLimit);
}
else {
after = target.paragraphStyleAt(limit);
}
AttributeMap before;
boolean srcHasPBreak = false;
for (int i=srcStart; i < srcLimit; i++) {
if (isParagraphBreak(src.at(i))) {
srcHasPBreak = true;
break;
}
}
if (start > 0 && isParagraphBreak(target.at(start-1))) {
before = target.paragraphStyleAt(start-1);
}
else {
before = srcHasPBreak? src.paragraphStyleAt(srcStart) : after;
}
boolean stylePropogated = !before.equals(target.paragraphStyleAt(Math.max(0, start-1)));
target.resetDamagedRange();
target.replace(start, limit, src, srcStart, srcLimit);
final int damageLimit = (start==limit && srcStart==srcLimit)?
Integer.MIN_VALUE : start + (srcLimit-srcStart);
if (target.damagedRangeLimit() != damageLimit) {
logln("limit: " + damageLimit + "; target.limit: " +
target.damagedRangeLimit());
errln("Damaged range limit is incorrect");
}
final int damageStart = (damageLimit==Integer.MIN_VALUE)? Integer.MAX_VALUE :
(stylePropogated? target.paragraphStart(Math.max(0, start-1)) : start);
if (target.damagedRangeStart() > damageStart) {
logln("start: " + damageStart + "; target.start: " +
target.damagedRangeStart());
errln("Damaged range start is incorrect");
}
verifyParagraphCount(target);
// check endpoints
if (!before.equals(target.paragraphStyleAt(Math.max(start-1, 0)))) {
errln("Incorrect paragraph style before modified range");
}
int lengthDelta = (srcLimit-srcStart) - (limit-start);
int indexAfterInsert = Math.min(target.length(), limit + lengthDelta);
if (!after.equals(target.paragraphStyleAt(indexAfterInsert))) {
errln("Incorrect paragraph style after modified range");
}
if (srcHasPBreak) {
int startP = target.paragraphLimit(start);
int limitOfTest = target.paragraphStart(indexAfterInsert);
int offset = start - srcStart;
while (startP < limitOfTest) {
int limitP = target.paragraphLimit(startP);
if (src.paragraphLimit(startP-offset) + offset != limitP) {
errln("paragraph limits are not consistent");
}
if (!src.paragraphStyleAt(startP-offset)
.equals(target.paragraphStyleAt(startP))) {
errln("paragraph styles are not consistent");
}
startP = limitP;
}
}
else {
for (int i=start; i < start+(srcLimit-srcStart); i++) {
if (!after.equals(target.paragraphStyleAt(i))) {
errln("paragraph style changed unexpectedly");
}
}
}
}
private void verifyParagraphCount(MConstText text) {
int pCount = 0;
int textLength = text.length();
if (textLength == 0) {
pCount = 1;
}
else {
for (int s=0; s < textLength; s = text.paragraphLimit(s)) {
pCount++;
}
if (isParagraphBreak(text.at(textLength-1))) {
pCount++;
}
}
int sepCount = 0;
for (int i=0; i < textLength; i++) {
if (isParagraphBreak(text.at(i))) {
sepCount++;
}
}
if (sepCount + 1 != pCount) {
logln("sepCount=" + sepCount + "; pCount=" + pCount);
errln("Paragraph count is not consistent with characters");
}
}
private void checkEndpoint(MConstText text) {
boolean emptyFinalParagraph;
int length = text.length();
if (length != 0) {
char ch = text.at(length-1);
emptyFinalParagraph = isParagraphBreak(ch);
}
else {
emptyFinalParagraph = true;
}
if ((text.paragraphStart(length) == length) != emptyFinalParagraph) {
errln("Final paragraph length is incorrect");
}
}
}

View File

@ -0,0 +1,55 @@
/*
* @(#)$RCSfile: TestAll.java,v $ $Revision: 1.1 $ $Date: 2000/04/24 20:38:00 $
*
* (C) Copyright IBM Corp. 1998-1999. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.richtext.tests;
import com.ibm.test.TestFmwk;
public class TestAll extends TestFmwk {
static final String COPYRIGHT =
"(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
public static void main(String[] args) throws Exception {
new TestAll().run(args);
}
public void TestAttributeSet() throws Exception {
run(new TestAttributeSet());
}
public void TestAttributeMap() throws Exception {
run(new TestAttributeMap());
}
public void TestFormatter() throws Exception {
run(new TestFormatter());
}
public void TestMText() throws Exception {
run(new TestMText());
}
public void TestParagraphStyles() throws Exception {
run(new TestParagraphStyles());
}
public void TestMTextStreaming() throws Exception {
run(new TestMTextStreaming());
}
public void TestTextPanel() throws Exception {
run(new TestTextPanel());
}
}

View File

@ -0,0 +1,409 @@
/*
* @(#)$RCSfile: TestAttributeMap.java,v $ $Revision: 1.1 $ $Date: 2000/04/24 20:38:00 $
*
* (C) Copyright IBM Corp. 1998-1999. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.richtext.tests;
import com.ibm.test.TestFmwk;
import com.ibm.textlayout.attributes.AttributeSet;
import com.ibm.textlayout.attributes.TextAttribute;
import com.ibm.textlayout.attributes.Map;
import com.ibm.textlayout.attributes.AttributeMap;
import java.util.Enumeration;
// Java2 imports
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import java.util.Map.Entry;
public class TestAttributeMap extends TestFmwk {
static final String COPYRIGHT =
"(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
// There are JDK 1.1 versions of AttributeMap and AttributeSet.
// Some of the tests in this class require Java 2 API's. I have
// tried to isolate these tests by conditionalizing them on
// this static variable. If you are back-porting to 1.1, remove
// the Java 2 tests ONLY.
private static final boolean gJDK11 = false;
public static void main(String[] args) throws Exception {
new TestAttributeMap().run(args);
}
private AttributeSet maps; // A Set of AttributeMaps
private AttributeSet sets; // A Set of Sets
private static final class TestAttribute extends TextAttribute {
TestAttribute(String name) {
super(name);
}
}
private static final TestAttribute[] attributes = {
new TestAttribute("0"), new TestAttribute("1"), new TestAttribute("2")
};
private static final Object[] values = {
"Hello world", new Float(-42), new Object(), new AttributeMap(new TestAttribute("3"), "HH")
};
/**
* Returns lhs.equals(rhs) - but also checks for symmetry, and
* consistency with hashCode().
*/
private boolean equalMaps(AttributeMap lhs, Object rhs) {
boolean equal = lhs.equals(rhs);
if (equal != (rhs.equals(lhs))) {
errln("AttributeMap.equals is not symetric");
}
if (equal) {
if (lhs.hashCode() != rhs.hashCode()) {
errln("AttributeMaps are equal but hashCodes differ");
}
}
return equal;
}
public TestAttributeMap() {
maps = AttributeSet.EMPTY_SET;
maps = maps.addElement(AttributeMap.EMPTY_ATTRIBUTE_MAP);
maps.addElement(new AttributeMap(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUB));
maps.addElement(new AttributeMap(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUPER));
for (int i=0; i < attributes.length; i++) {
for (int j=0; j < values.length; j++) {
maps = maps.addElement(new AttributeMap(attributes[i], values[j]));
}
}
AttributeMap bigMap = new AttributeMap(new TestAttribute("4"), "value");
for (int i=0; i < Math.min(attributes.length, values.length); i++) {
bigMap = bigMap.addAttribute(attributes[i], values[values.length-i-1]);
}
maps = maps.addElement(bigMap);
sets = AttributeSet.EMPTY_SET;
sets = new AttributeSet(AttributeSet.EMPTY_SET);
for (int i=0; i < attributes.length; i++) {
AttributeSet newSet = new AttributeSet(attributes[i]);
sets = sets.addElement(newSet);
}
AttributeSet allAttrs = AttributeSet.EMPTY_SET;
for (int i=0; i < attributes.length; i++) {
allAttrs = allAttrs.addElement(attributes[i]);
}
sets = sets.addElement(allAttrs);
}
/**
* Run tests on AttributeMap. If a test fails an exception will propogate out
* of this method.
*/
public void test() {
easyTests();
Enumeration mapIter = maps.elements();
while (mapIter.hasMoreElements()) {
AttributeMap testMap = (AttributeMap) mapIter.nextElement();
_testModifiers(testMap);
_testViews(testMap);
Enumeration unionIter = maps.elements();
while (unionIter.hasMoreElements()) {
_testUnionWith(testMap, (AttributeMap) unionIter.nextElement());
}
Enumeration setIter = sets.elements();
while (setIter.hasMoreElements()) {
AttributeSet testSet = (AttributeSet) setIter.nextElement();
_testIntersectWith(testMap, testSet);
_testRemoveAttributes(testMap, testSet);
}
}
}
/**
* Invoke modifiers on map. All should throw
* UnsupportedOperationException, and leave map unmodified.
*/
void _testModifiers(AttributeMap map) {
if (gJDK11) {
return;
}
AttributeMap originalMap = new AttributeMap(map);
try {
map.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
errln("Put should throw UnsupportedOperationException.");
}
catch(UnsupportedOperationException e) {
}
try {
Object key = TextAttribute.WEIGHT;
Iterator iter = map.keySet().iterator();
if (iter.hasNext()) {
key = iter.next();
}
map.remove(key);
errln("Set should throw UnsupportedOperationException.");
}
catch(UnsupportedOperationException e) {
}
try {
map.putAll(map);
errln("putAll should throw UnsupportedOperationException.");
}
catch(UnsupportedOperationException e) {
}
try {
map.clear();
errln("clear should throw UnsupportedOperationException.");
}
catch(UnsupportedOperationException e) {
}
if (!originalMap.equals(map)) {
errln("Modifiers changed map.");
}
}
/**
* Ensure that map.addAttributes(addMap) is equivalent to calling
* map.add on all of addMap's entries.
*/
void _testUnionWith(AttributeMap map, AttributeMap addMap) {
AttributeMap lhs = map.addAttributes(addMap);
AttributeMap rhs = map;
Enumeration iter = addMap.getKeySet().elements();
while (iter.hasMoreElements()) {
Object attr = iter.nextElement();
Object value = addMap.get(attr);
rhs = rhs.addAttribute(attr, value);
}
if (!equalMaps(lhs, rhs)) {
errln("Maps are not equal.");
}
}
/**
* Ensure that map.removeAttributes(remove) is equivalent to calling
* map.removeAttribute on remove's elements.
*/
void _testRemoveAttributes(AttributeMap map, AttributeSet remove) {
AttributeMap lhs = map.removeAttributes(remove);
AttributeMap rhs = map;
Enumeration iter = remove.elements();
while (iter.hasMoreElements()) {
Object attr = iter.nextElement();
rhs = rhs.removeAttribute(attr);
}
if (!equalMaps(lhs, rhs)) {
errln("Maps are not equal.");
}
}
/**
* Ensure that map.intersectWith(intersect) is equivalent to
* map.removeAttributes(map.keySet() - intersect);
*/
void _testIntersectWith(AttributeMap map, AttributeSet intersect) {
AttributeMap lhs = map.intersectWith(intersect);
AttributeSet keySet = map.getKeySet();
AttributeSet removeSet = keySet.subtract(intersect);
AttributeMap rhs = map.removeAttributes(removeSet);
if (!equalMaps(lhs, rhs)) {
map.intersectWith(intersect);
logln("intersect: " + intersect);
logln("keySet: " + keySet);
logln("removeSet: " + removeSet);
logln("map: " + map);
logln("lhs: " + lhs);
logln("rhs: " + rhs);
errln("Maps are not equal.");
}
}
/**
* Ensure that:
* map, map.keySet(), and map.entrySet() are the same size;
* map.containsKey() is true for every key in keySet();
* map.containsValue() is true for every value in values;
* every entry key is in keySet, every entry value is in map.values();
* map.get() is consistent with entry's key, value;
* sum of hashcodes of entries equals map.hashCode().
*/
void _testViews(AttributeMap map) {
AttributeSet keySet = map.getKeySet();
Enumeration keyIter = keySet.elements();
while (keyIter.hasMoreElements()) {
if (!map.containsKey(keyIter.nextElement())) {
errln("keySet contains key not in map");
}
}
if (gJDK11) {
return;
}
Collection values = map.values();
Set entrySet = map.entrySet();
if (keySet.size() != map.size() || entrySet.size() != map.size()) {
errln("Set sizes are inconsistent with map size.");
}
int hashCode = 0;
Iterator valueIter = values.iterator();
while (valueIter.hasNext()) {
if (!map.containsValue(valueIter.next())) {
errln("value set contains value not in map");
}
}
Iterator entryIter = entrySet.iterator();
while (entryIter.hasNext()) {
Entry entry = (Entry) entryIter.next();
Object key = entry.getKey();
if (!keySet.contains(key)) {
errln("Entry key is not in key set.");
}
Object value = map.get(entry.getKey());
if (!values.contains(value)) {
errln("Entry value is not in value set.");
}
if (map.get(key) != value) {
errln("map.get did not return entry value.");
}
hashCode += entry.hashCode();
}
if (hashCode != map.hashCode()) {
errln("map hashcode is not sum of entry hashcodes.");
}
}
/**
* Look for correct behavior in obvious cases.
*/
void easyTests() {
AttributeMap map = new AttributeMap();
if (!map.equals(AttributeMap.EMPTY_ATTRIBUTE_MAP)) {
errln("Default-constructed map is not equal to empty map.");
}
map = map.addAttribute(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
Object otherMap = new AttributeMap(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
if (!map.equals(otherMap)) {
errln("Maps are inconsistent after map.add");
}
otherMap = map.addAttributes(map);
if (!equalMaps(map,otherMap)) {
errln("Maps are inconsistent after addAttributes");
}
map = map.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
if (map.size() != 2) {
errln("Map size is wrong. map="+map);
}
if (equalMaps(map,otherMap)) {
errln("Maps should not be equal");
}
Object posture = new Float(0);
map = map.addAttribute(TextAttribute.POSTURE, posture);
if (map.size() != 2) {
errln("Map size is wrong");
}
if (!map.get(TextAttribute.POSTURE).equals(posture)) {
errln("Map element is wrong");
}
map = map.removeAttribute(TextAttribute.UNDERLINE);
if (map.size() != 1) {
errln("Map size is wrong");
}
if (map.get(TextAttribute.UNDERLINE) != null) {
errln("Map should not have element");
}
// map has POSTURE_REGULAR. If we addAttributes a map with
// POSTURE_ITALIC the new map should have POSTURE_ITALIC
map = map.addAttributes(new AttributeMap(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE));
if (map.get(TextAttribute.POSTURE) != TextAttribute.POSTURE_OBLIQUE) {
errln("Map element is wrong");
}
_testModifiers(map);
_testViews(map);
Enumeration mapIter = maps.elements();
while (mapIter.hasMoreElements()) {
AttributeMap testMap = (AttributeMap) mapIter.nextElement();
Object newValue = new Object();
AttributeMap newMap = testMap.addAttribute(attributes[0], newValue);
if (newMap.get(attributes[0]) != newValue) {
errln("Did not get expected value back. map=" + map);
}
}
}
}

View File

@ -0,0 +1,91 @@
/*
* @(#)$RCSfile: TestAttributeSet.java,v $ $Revision: 1.1 $ $Date: 2000/04/24 20:38:00 $
*
* (C) Copyright IBM Corp. 1998-1999. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.richtext.tests;
import com.ibm.test.TestFmwk;
import com.ibm.textlayout.attributes.AttributeSet;
import java.util.Enumeration;
public class TestAttributeSet extends TestFmwk {
static final String COPYRIGHT =
"(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
public static void main(String[] args) throws Exception {
new TestAttributeSet().run(args);
}
public void test() {
final Object elem1 = new Object();
final Object elem2 = new Float(4);
final Object elem3 = "String";
final Object elem4 = Boolean.FALSE;
AttributeSet set1 = new AttributeSet(new Object[] {elem1, elem2, elem3});
if (set1.size() != 3) {
errln("Size is wrong.");
}
if (set1.contains(elem4)){
errln("Set contents are wrong.");
}
if (!set1.contains(elem1)) {
errln("Set contents are wrong.");
}
AttributeSet set2 = new AttributeSet(elem4);
if (set2.size() != 1) {
errln("Size is wrong.");
}
if (!set2.contains(elem4)){
errln("Set contents are wrong.");
}
if (set2.contains(elem1)) {
errln("Set contents are wrong.");
}
Enumeration iter = set2.elements();
if (!iter.nextElement().equals(elem4)) {
errln("Invalid object in iterator.");
}
AttributeSet union = set2.unionWith(set1);
if (!set1.unionWith(set2).equals(union)) {
errln("unionWith is not commutative.");
}
if (!union.contains(elem1) || !union.contains(elem4)) {
errln("Set contents are wrong.");
}
if (!set1.addElement(elem4).equals(union)) {
errln("addElement is wrong.");
}
if (!union.intersectWith(set1).equals(set1)) {
errln("intersectWith is wrong.");
}
if (!union.subtract(set1).equals(set2)) {
errln("subtract is wrong.");
}
}
}

View File

@ -0,0 +1,250 @@
/*
* @(#)$RCSfile: TestFormatter.java,v $ $Revision: 1.1 $ $Date: 2000/04/24 20:38:00 $
*
* (C) Copyright IBM Corp. 1998-1999. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.richtext.tests;
import com.ibm.test.TestFmwk;
import com.ibm.textlayout.attributes.AttributeMap;
import com.ibm.textlayout.attributes.TextAttribute;
import com.ibm.richtext.styledtext.MText;
import com.ibm.richtext.styledtext.MConstText;
import com.ibm.richtext.styledtext.StandardTabRuler;
import com.ibm.richtext.styledtext.StyledText;
import com.ibm.richtext.textformat.TextOffset;
import com.ibm.richtext.textformat.MFormatter;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.util.Hashtable;
public final class TestFormatter extends TestFmwk {
static final String COPYRIGHT =
"(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
public static void main(String[] args) throws Exception {
new TestFormatter().run(args);
}
private static final Point ORIGIN = new Point(0, 0);
private static final AttributeMap DEFAULTS;
static {
final Float floatZero = new Float(0.0f);
Hashtable defaults = new Hashtable();
defaults.put(TextAttribute.FAMILY, "Serif");
defaults.put(TextAttribute.WEIGHT, new Float(1.0f));
defaults.put(TextAttribute.POSTURE, floatZero);
defaults.put(TextAttribute.SIZE, new Float(18.0f));
defaults.put(TextAttribute.SUPERSCRIPT, new Integer(0));
defaults.put(TextAttribute.FOREGROUND, Color.black);
defaults.put(TextAttribute.UNDERLINE, new Integer(-1));
defaults.put(TextAttribute.STRIKETHROUGH, Boolean.FALSE);
defaults.put(TextAttribute.EXTRA_LINE_SPACING, floatZero);
defaults.put(TextAttribute.FIRST_LINE_INDENT, floatZero);
defaults.put(TextAttribute.MIN_LINE_SPACING, floatZero);
defaults.put(TextAttribute.LINE_FLUSH, TextAttribute.FLUSH_LEADING);
defaults.put(TextAttribute.LEADING_MARGIN, floatZero);
defaults.put(TextAttribute.TRAILING_MARGIN, floatZero);
defaults.put(TextAttribute.TAB_RULER, new StandardTabRuler());
DEFAULTS = new AttributeMap(defaults);
}
// arg to testLineExceptions
private static final int UNKNOWN = -1;
private Graphics fGraphics;
public TestFormatter() {
fGraphics = new BufferedImage(100, 100, BufferedImage.TYPE_3BYTE_BGR).getGraphics();
//JDK 1.1:
//Frame f = new Frame();
//f.show();
//fGraphics = f.getGraphics();
}
private String fiveLines = "a\nb\nc\nd\ne";
private String twelveLines = fiveLines + "\n" + fiveLines + "\nf\n";
AttributeMap PLAIN = AttributeMap.EMPTY_ATTRIBUTE_MAP;
public void test() {
MConstText text = new StyledText(fiveLines, PLAIN);
_testLineExceptions(makeFormatter(text, 100, true), 5);
_testLineAccess(makeFormatter(text, 100, true), 5);
text = new StyledText(twelveLines, PLAIN);
_testLineExceptions(makeFormatter(text, 3, false), 12);
_testLineAccess(makeFormatter(text, 100, true), 12);
_testWithModification();
}
private void _testWithModification() {
MText text = new StyledText(fiveLines, PLAIN);
MFormatter formatter = makeFormatter(text, 100, true);
Rectangle viewRect = new Rectangle(0, 0, 100, Integer.MAX_VALUE);
formatter.stopBackgroundFormatting();
text.append(new StyledText("\n", PLAIN));
formatter.updateFormat(text.length()-1, 1, viewRect, ORIGIN);
_testLineAccess(formatter, 6);
formatter.stopBackgroundFormatting();
text.append(new StyledText("ad", PLAIN));
formatter.updateFormat(text.length()-2, 2, viewRect, ORIGIN);
_testLineAccess(formatter, 6);
_testLineExceptions(formatter, 6);
formatter.stopBackgroundFormatting();
text.remove(0, 1);
formatter.updateFormat(0, 0, viewRect, ORIGIN);
_testLineAccess(formatter, 6);
_testLineExceptions(formatter, 6);
}
private MFormatter makeFormatter(MConstText text,
int lineBound,
boolean wrap) {
return MFormatter.createFormatter(text,
DEFAULTS,
lineBound,
wrap,
fGraphics);
}
private void _testLineExceptions(MFormatter formatter,
int numLines) {
if (numLines == UNKNOWN) {
numLines = formatter.getLineCount();
}
boolean caught = false;
try {
formatter.lineRangeLow(numLines);
}
catch(IllegalArgumentException e) {
caught = true;
}
if (!caught) {
errln("Didn't get exception");
}
caught = false;
try {
formatter.lineRangeLimit(numLines);
}
catch(IllegalArgumentException e) {
caught = true;
}
if (!caught) {
errln("Didn't get exception");
}
caught = false;
try {
formatter.lineGraphicStart(numLines+1);
}
catch(IllegalArgumentException e) {
caught = true;
}
if (!caught) {
errln("Didn't get exception");
}
caught = false;
}
private void _testLineAccess(MFormatter formatter,
int numLines) {
if (numLines == UNKNOWN) {
numLines = formatter.getLineCount();
}
if (formatter.lineGraphicStart(0) != 0) {
errln("Line 0 doesn't start at height 0");
}
if (formatter.lineRangeLow(0) != 0) {
errln("Line 0 doesn't start at character 0");
}
int lastLimit = formatter.lineRangeLimit(0);
final int lineBound = formatter.lineBound();
int[] hitX = new int[] { -1, 1, lineBound + 2 };
TextOffset offset = new TextOffset();
for (int i=1; i < numLines; i++) {
int height = formatter.lineGraphicStart(i);
if (lastLimit != formatter.lineRangeLow(i)) {
errln("lastLine limit is not current line start");
}
int limit = formatter.lineRangeLimit(i);
if (limit < lastLimit || (limit == lastLimit && i != numLines-1)) {
errln("line has negative or 0 length");
}
int nextHeight = formatter.lineGraphicStart(i+1);
if (nextHeight <= height) {
errln("0-height line");
}
int incAmount = Math.max((nextHeight-height)/4, 1);
for (int hitY = height; hitY < nextHeight; hitY += incAmount) {
if (formatter.lineAtHeight(hitY) != i) {
errln("lineAtHeight is wrong");
}
for (int j=0; j < hitX.length; j++) {
offset = formatter.pointToTextOffset(offset,
hitX[j], hitY, ORIGIN, null, false);
if (offset.fOffset < lastLimit || offset.fOffset > limit) {
errln("Inconsistent offset from pointToTextOffset");
}
//if (formatter.lineContaining(offset) != i) {
// int debug = formatter.lineContaining(offset);
// errln("lineContaining is incorrect");
//}
}
}
lastLimit = limit;
}
}
}

View File

@ -0,0 +1,721 @@
/*
* @(#)$RCSfile: TestMText.java,v $ $Revision: 1.1 $ $Date: 2000/04/24 20:38:00 $
*
* (C) Copyright IBM Corp. 1998-1999. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.richtext.tests;
import com.ibm.test.TestFmwk;
import com.ibm.textlayout.attributes.AttributeMap;
import com.ibm.textlayout.attributes.TextAttribute;
import com.ibm.richtext.styledtext.MConstText;
import com.ibm.richtext.styledtext.MText;
import com.ibm.richtext.styledtext.StyledText;
import com.ibm.richtext.styledtext.StyleModifier;
import java.text.CharacterIterator;
import java.util.Random;
import java.io.*;
public class TestMText extends TestFmwk {
static final String COPYRIGHT =
"(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
public static void main(String[] args) throws Exception {
new TestMText().run(args);
}
private static final int TEST_ITERATIONS = 5000;
private static final int STYLE_TEST_ITERATIONS = 5000;
private static final long RAND_SEED = 598436;
private static final int NOT_IN_MONKEY_TEST = -5000;
private int testIteration = NOT_IN_MONKEY_TEST;
private int theCase = NOT_IN_MONKEY_TEST;
private static StyleModifier createMinusModifier(final Object attr) {
return new StyleModifier() {
public AttributeMap modifyStyle(AttributeMap style) {
return style.removeAttribute(attr);
}
};
}
public void test() {
simpleTest();
styleTest();
monkeyTest(true);
}
public void simpleTest() {
AttributeMap boldStyle = new AttributeMap(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
AttributeMap italicStyle = new AttributeMap(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
MConstText allBold = new StyledText("bbbbb", boldStyle);
MConstText allItalic = new StyledText("iii", italicStyle);
MConstText plain = new StyledText("pppppp", AttributeMap.EMPTY_ATTRIBUTE_MAP);
{
MText buf = new StyledText();
int ts = buf.getTimeStamp();
buf.append(allBold);
buf.append(allItalic);
if (ts == buf.getTimeStamp()) {
errln("Time stamp not incremented");
}
// should be bbbbbiii now
if (buf.length() != allBold.length() + allItalic.length()) {
errln("Length is wrong.");
}
for (int i=0; i < buf.length(); i++) {
char rightChar;
AttributeMap rightStyle;
if (i < allBold.length()) {
rightChar = allBold.at(0);
rightStyle = boldStyle;
}
else {
rightChar = allItalic.at(0);
rightStyle = italicStyle;
}
if (buf.at(i) != rightChar) {
errln("Character is wrong.");
}
if (!buf.characterStyleAt(i).equals(rightStyle)) {
errln("Style is wrong.");
}
}
int pos = 0;
if (!buf.characterStyleAt(pos).equals(boldStyle)) {
errln("First style is wrong.");
}
if (buf.characterStyleLimit(pos) != allBold.length()) {
errln("Run length is wrong.");
}
pos = allBold.length();
if (!buf.characterStyleAt(pos).equals(italicStyle)) {
errln("Second style is wrong.");
}
if (buf.characterStyleLimit(pos) != buf.length()) {
errln("Run length is wrong.");
}
{
buf.resetDamagedRange();
int oldLength = buf.length();
buf.replace(buf.length(), buf.length(), allBold, 0, allBold.length());
// bbbbbiiibbbbb
if (buf.damagedRangeStart() != oldLength) {
errln("Damaged range start is incorrect");
}
if (buf.damagedRangeLimit() != buf.length()) {
errln("Damaged range limit is incorrect");
}
}
int start = allBold.length();
int limit = start + allItalic.length();
buf.remove(start, limit);
// bbbbbbbbbb
if (buf.length() != 2 * allBold.length()) {
errln("Text should be twice the length of bold text.");
}
pos = buf.length() / 2;
if (buf.characterStyleStart(pos) != 0 ||
buf.characterStyleLimit(pos) != buf.length()) {
errln("Run range is wrong.");
}
if (!buf.characterStyleAt(pos).equals(boldStyle)) {
errln("Run style is wrong.");
}
ts = buf.getTimeStamp();
CharacterIterator cIter = buf.createCharacterIterator();
for (char ch = cIter.first(); ch != cIter.DONE; ch = cIter.next()) {
if (ch != allBold.at(0)) {
errln("Character is wrong.");
}
}
if (ts != buf.getTimeStamp()) {
errln("Time stamp should not have changed");
}
buf.replace(0, 1, plain, 0, plain.length());
if (ts == buf.getTimeStamp()) {
errln("Time stamp not incremented");
}
// ppppppbbbbbbbbb
buf.replace(plain.length(), buf.length(), allItalic, 0, allItalic.length());
// ppppppiii
if (buf.length() != allItalic.length()+plain.length()) {
errln("Length is wrong.");
}
pos = 0;
if (buf.characterStyleLimit(pos) != plain.length()) {
errln("Run limit is wrong.");
}
pos = plain.length();
if (buf.characterStyleLimit(pos) != buf.length()) {
errln("Run limit is wrong.");
}
buf.replace(plain.length(), plain.length(), allBold, 0, allBold.length());
// ppppppbbbbbiii
AttributeMap st = buf.characterStyleAt(1);
if (!st.equals(AttributeMap.EMPTY_ATTRIBUTE_MAP)) {
errln("Style is wrong.");
}
if (buf.characterStyleStart(1) != 0 || buf.characterStyleLimit(1) != plain.length()) {
errln("Style start is wrong.");
}
st = buf.characterStyleAt(buf.length() - 1);
if (!st.equals(italicStyle)) {
errln("Style is wrong.");
}
if (buf.characterStyleStart(buf.length() - 1) != plain.length()+allBold.length()) {
errln("Style start is wrong.");
}
if (buf.characterStyleLimit(buf.length() - 1) != buf.length()) {
errln("Style limit is wrong.");
}
}
}
private static int randInt(Random rand, int limit) {
return randInt(rand, 0, limit);
}
private static int randInt(Random rand, int start, int limit) {
if (start > limit) {
throw new IllegalArgumentException("Range length is negative.");
}
else if (start == limit) {
return start;
}
return start + (Math.abs(rand.nextInt())%(limit-start)) ;
}
public void styleTest() {
MText text = new StyledText("0123456789", AttributeMap.EMPTY_ATTRIBUTE_MAP);
AttributeMap[] styles = new AttributeMap[text.length()];
for (int i=0; i < styles.length; i++) {
styles[i] = AttributeMap.EMPTY_ATTRIBUTE_MAP;
}
AttributeMap[] oldStyles = new AttributeMap[styles.length];
System.arraycopy(styles, 0, oldStyles, 0, styles.length);
AttributeMap bigStyle = new AttributeMap(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON).
addAttribute(TextAttribute.SIZE, new Float(23.0f));
StyleModifier[] modifiers = {
StyleModifier.createReplaceModifier(new AttributeMap(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD)),
StyleModifier.createAddModifier(new AttributeMap(TextAttribute.WEIGHT, new Float(1.0f))),
createMinusModifier(TextAttribute.WEIGHT),
StyleModifier.createAddModifier(new AttributeMap(TextAttribute.POSTURE, new Float(0.0f))),
StyleModifier.createReplaceModifier(new AttributeMap(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE)),
createMinusModifier(TextAttribute.POSTURE),
StyleModifier.createAddModifier(bigStyle),
StyleModifier.createReplaceModifier(bigStyle),
createMinusModifier(bigStyle.getKeySet())
};
Random rand = new Random(RAND_SEED);
final int stopAt = 4;
for (int testIteration=0; testIteration < STYLE_TEST_ITERATIONS + 1; testIteration++) {
System.arraycopy(styles, 0, oldStyles, 0, styles.length);
int startingAt = Integer.MAX_VALUE;
int endingAt = Integer.MIN_VALUE;
int oldTs = text.getTimeStamp();
// hack way to do an invariant check before starting...
if (testIteration != 0) {
// modify styles
text.resetDamagedRange();
startingAt = randInt(rand, styles.length+1);
endingAt = randInt(rand, startingAt, styles.length+1);
StyleModifier modifier = modifiers[randInt(rand, modifiers.length)];
if (testIteration == stopAt) {
testIteration = stopAt;
}
text.modifyCharacterStyles(startingAt, endingAt, modifier);
for (int j=startingAt; j < endingAt; j++) {
styles[j] = modifier.modifyStyle(styles[j]);
}
}
// check invariants
AttributeMap oldStyle = null;
int textLength = text.length();
for (int runStart = 0; runStart < textLength;) {
AttributeMap currentStyle = text.characterStyleAt(runStart);
int runLimit = text.characterStyleLimit(runStart);
if (runStart >= runLimit) {
errln("Run length is not positive");
}
if (currentStyle.equals(oldStyle)) {
errln("Styles didn't merge");
}
for (int pos=runStart; pos < runLimit; pos++) {
AttributeMap charStyleAtPos = text.characterStyleAt(pos);
if (currentStyle != charStyleAtPos) {
errln("Iterator style is not equal to text style at " + pos + ".");
}
AttributeMap expected = styles[pos];
if (!currentStyle.equals(expected)) {
errln("Iterator style doesn't match expected style at " + pos + ".");
}
if (!(text.characterStyleStart(pos) == runStart) ||
!(text.characterStyleLimit(pos) == runLimit)) {
errln("style run start / limit is not consistent");
}
}
runStart = runLimit;
}
if (textLength > 0) {
if (text.characterStyleAt(textLength) !=
text.characterStyleAt(textLength-1)) {
errln("Character styles at end aren't the same");
}
}
// check damaged range:
int damageStart = Integer.MAX_VALUE;
int damageLimit = Integer.MIN_VALUE;
for (int i=0; i < textLength; i++) {
if (!styles[i].equals(oldStyles[i])) {
damageStart = Math.min(i, damageStart);
damageLimit = Math.max(i+1, damageLimit);
}
}
if (damageStart != text.damagedRangeStart() ||
damageLimit != text.damagedRangeLimit()) {
logln("Test iteration: " + testIteration);
logln("startingAt: " + startingAt + "; endingAt: " + endingAt);
logln("damageStart: " + damageStart + "; damageLimit: " + damageLimit);
logln("text.rangeStart: " + text.damagedRangeStart() +
"text.rangeLimit: " + text.damagedRangeLimit());
errln("Damage range start or limit is not expected value");
}
if ((damageLimit == Integer.MIN_VALUE) != (oldTs == text.getTimeStamp())) {
errln("timeStamp is incorrect");
}
}
}
protected void err(String message) {
if (testIteration != NOT_IN_MONKEY_TEST) {
message = "testIteration="+testIteration+"; testCase="+theCase+message;
}
super.err(message);
}
/**
* Perform a random series of operations on an MText and
* check the result of each operation against a set of invariants.
*/
public void monkeyTest(boolean streaming) {
/*
You can add any operation to the switch statement provided it
preserves the following invariants:
- The String plainText contains the same text as the StyledStringBuffer.
Obviously, for the test to be meaningful plainText must be computed
independently of the buffer (ie don't write: plainText = buf.getStyledString().toString()).
- Every 'b' is bold, every 'i' is italic, every 'p' is plain, and
no other characters appear in the text.
*/
AttributeMap boldAttrs = new AttributeMap(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
AttributeMap italicAttrs = new AttributeMap(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
AttributeMap emptyAttrs = AttributeMap.EMPTY_ATTRIBUTE_MAP;
final String bold1Str_getString = "b";
MConstText bold1Str = new StyledText(bold1Str_getString, boldAttrs);
final String italic1Str_getString = "i";
MConstText italic1Str = new StyledText(italic1Str_getString, italicAttrs);
final String plain1Str_getString = "p";
MConstText plain1Str = new StyledText(plain1Str_getString, emptyAttrs);
StyledText temp = new StyledText();
temp.append(bold1Str);
temp.append(italic1Str);
final String boldItalicStr_getString = bold1Str_getString.concat(italic1Str_getString);
MConstText boldItalicStr = temp;
temp = new StyledText();
temp.append(bold1Str);
temp.append(bold1Str);
temp.append(bold1Str);
final String bold3Str_getString = "bbb";
MConstText bold3Str = temp;
MText buf = new StyledText();
String plainText = new String();
//int testIteration=0; - now instance variables so errln can report it
//int theCase=0;
final int NUM_CASES = 14;
boolean[] casesExecuted = new boolean[NUM_CASES];
final int stopAt = -1;
Random rand = new Random(RAND_SEED);
final String ALWAYS_DIFFERENT = "\uFEFF";
for (testIteration=0; testIteration < TEST_ITERATIONS; testIteration++) {
theCase = randInt(rand, NUM_CASES);
casesExecuted[theCase] = true;
if (testIteration == stopAt) {
testIteration = stopAt; // Convenient place to put breakpoint
}
int timeStamp = buf.getTimeStamp();
String oldPlainText = plainText;
if (oldPlainText == null) {
errln("oldPlainText is null!");
}
switch (theCase) {
case 0:
// create new string; replace chars at start with different style
buf = new StyledText();
buf.append(bold3Str);
buf.replace(0, 1, italic1Str, 0, italic1Str.length());
buf.replace(0, 0, italic1Str, 0, italic1Str.length());
plainText = bold3Str_getString.substring(1, bold3Str.length());
plainText = italic1Str_getString.concat(plainText);
plainText = italic1Str_getString.concat(plainText);
oldPlainText = null;
break;
case 1:
// delete the last character from the string
if (buf.length() == 0) {
buf.replace(0, 0, italic1Str, 0, italic1Str.length());
plainText = italic1Str_getString;
oldPlainText = ALWAYS_DIFFERENT;
}
buf.remove(buf.length()-1, buf.length());
plainText = plainText.substring(0, plainText.length()-1);
break;
case 2:
// replace some of the buffer with boldItalicStr
int rStart = randInt(rand, buf.length()+1);
int rStop = randInt(rand, rStart, buf.length()+1);
buf.replace(rStart, rStop, boldItalicStr);
{
String newString = (rStart>0)? plainText.substring(0, rStart) : new String();
newString = newString.concat(boldItalicStr_getString);
if (rStop < plainText.length())
newString = newString.concat(plainText.substring(rStop, plainText.length()));
oldPlainText = ALWAYS_DIFFERENT;
plainText = newString;
}
break;
case 3:
// repeatedly insert strings into the center of the buffer
{
int insPos = buf.length() / 2;
String prefix = plainText.substring(0, insPos);
String suffix = plainText.substring(insPos, plainText.length());
String middle = new String();
for (int ii=0; ii<4; ii++) {
MConstText which = (ii%2==0)? boldItalicStr : bold3Str;
String whichString = (ii%2==0)? boldItalicStr_getString : bold3Str_getString;
int tempPos = insPos+middle.length();
buf.insert(tempPos, which);
middle = middle.concat(whichString);
}
plainText = prefix.concat(middle).concat(suffix);
oldPlainText = ALWAYS_DIFFERENT;
}
break;
case 4:
// insert bold1Str at end
buf.append(bold1Str);
plainText = plainText.concat(bold1Str_getString);
break;
case 5:
// delete a character from the string
if (buf.length() > 0) {
int delPos = randInt(rand, buf.length()-1);
buf.remove(delPos, delPos+1);
plainText = plainText.substring(0, delPos).concat(plainText.substring(delPos+1));
}
else {
buf.replace(0, 0, plain1Str, 0, plain1Str.length());
plainText = plain1Str_getString;
}
break;
case 6:
// replace the contents of the buffer (except the first character) with itself
{
int start = buf.length() > 1? 1 : 0;
buf.replace(start, buf.length(), buf);
plainText = plainText.substring(0, start).concat(plainText);
if (buf.length() > 0) {
oldPlainText = ALWAYS_DIFFERENT;
}
}
break;
case 7:
// append the contents of the buffer to itself
{
MConstText content = buf;
buf.insert(buf.length(), content);
plainText = plainText.concat(plainText);
}
break;
case 8:
// replace the buffer with boldItalicStr+bold3Str
{
MText replacement = new StyledText();
replacement.append(boldItalicStr);
replacement.append(bold3Str);
buf.replace(0, buf.length(), replacement, 0, replacement.length());
plainText = boldItalicStr_getString.concat(bold3Str_getString);
oldPlainText = ALWAYS_DIFFERENT;
}
break;
case 9:
// insert bold1Str at end - same as 4 but uses different API
buf.replace(buf.length(),
buf.length(),
bold1Str_getString.toCharArray(),
0,
bold1Str_getString.length(),
boldAttrs);
plainText = plainText.concat(bold1Str_getString);
break;
case 10:
// remove all
buf.remove();
plainText = "";
oldPlainText = ALWAYS_DIFFERENT;
break;
case 11:
// remove all - different way
buf.remove(0, buf.length());
plainText = "";
break;
case 12:
// insert 'i' at 3rd character (or last, if fewer than 3 chars)
{
int insPos = Math.min(buf.length(), 3);
buf.replace(insPos, insPos, 'i', italicAttrs);
plainText = (plainText.substring(0, insPos)).
concat(italic1Str_getString).
concat(plainText.substring(insPos));
}
break;
case 13:
if (streaming) {
Throwable error = null;
try {
ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
ObjectOutputStream objOut = new ObjectOutputStream(bytesOut);
objOut.writeObject(buf);
ByteArrayInputStream bytesIn =
new ByteArrayInputStream(bytesOut.toByteArray());
ObjectInputStream objIn = new ObjectInputStream(bytesIn);
buf = (MText) objIn.readObject();
oldPlainText = null;
}
catch(IOException e) {
error = e;
}
catch(ClassNotFoundException e) {
error = e;
}
if (error != null) {
error.printStackTrace();
errln("Streaming problem: " + error);
}
}
break;
default:
errln("Invalid case.");
}
// Check time stamp if oldPlainText != null.
// Time stamp should be different iff
// oldPlainText == plainText
if (oldPlainText != null) {
if ((timeStamp==buf.getTimeStamp()) !=
oldPlainText.equals(plainText)) {
logln("plainText hashCode: " + plainText.hashCode());
logln("oldPlainText hashCode: " + oldPlainText.hashCode());
errln("Time stamp is incorrect");
}
}
// now check invariants:
if (plainText.length() != buf.length()) {
errln("Lengths don't match");
}
for (int j=0; j < buf.length(); j++) {
if (buf.at(j) != plainText.charAt(j)) {
errln("Characters don't match.");
}
}
int start;
for (start = 0; start < buf.length();) {
if (start != buf.characterStyleStart(start)) {
errln("style start is wrong");
}
int limit = buf.characterStyleLimit(start);
if (start >= limit) {
errln("start >= limit");
}
char current = plainText.charAt(start);
AttributeMap comp = null;
if (current == 'p') {
comp = emptyAttrs;
}
else if (current == 'b') {
comp = boldAttrs;
}
else if (current == 'i') {
comp = italicAttrs;
}
else {
errln("An invalid character snuck in!");
}
AttributeMap startStyle = buf.characterStyleAt(start);
if (!comp.equals(startStyle)) {
errln("Style is not expected style.");
}
for (int j = start; j < limit; j++) {
if (plainText.charAt(j) != current) {
errln("Character doesn't match style.");
}
if (buf.characterStyleAt(j) != startStyle) {
errln("Incorrect style in run");
}
}
if (limit < buf.length()) {
if (plainText.charAt(limit) == current) {
errln("Style run ends too soon.");
}
}
start = limit;
}
if (start != buf.length()) {
errln("Last limit is not buffer length.");
}
// won't try to compute and check damaged range; however,
// if nonempty it should always be within text
int damageStart = buf.damagedRangeStart();
int damageLimit = buf.damagedRangeLimit();
if (damageStart == Integer.MAX_VALUE) {
if (damageLimit != Integer.MIN_VALUE) {
errln("Invalid empty interval");
}
}
else {
if (damageStart > damageLimit) {
errln("Damage range inverted");
}
if (damageStart < 0 || damageLimit > buf.length()) {
errln("Damage range endpoint out of bounds");
}
}
}
testIteration = NOT_IN_MONKEY_TEST;
boolean allCasesExecuted = true;
for (int index=0; index < NUM_CASES; index++) {
allCasesExecuted &= casesExecuted[index];
if (casesExecuted[index] == false) {
logln("Case " + index + " not executed.");
}
}
//if (allCasesExecuted) {
// logln("All cases executed.");
//}
}
}

View File

@ -0,0 +1,162 @@
/*
* @(#)$RCSfile: TestMTextStreaming.java,v $ $Revision: 1.1 $ $Date: 2000/04/24 20:38:00 $
*
* (C) Copyright IBM Corp. 1998-1999. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.richtext.tests;
import com.ibm.test.TestFmwk;
import java.io.*;
import java.awt.Color;
import com.ibm.richtext.styledtext.MText;
import com.ibm.richtext.styledtext.StandardTabRuler;
import com.ibm.richtext.styledtext.StyledText;
import com.ibm.richtext.styledtext.StyleModifier;
import com.ibm.textlayout.attributes.AttributeMap;
import com.ibm.textlayout.attributes.TextAttribute;
public class TestMTextStreaming extends TestFmwk {
static final String COPYRIGHT =
"(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
public static void main(String[] args) throws Exception {
new TestMTextStreaming().run(args);
}
public TestMTextStreaming() {
}
public void test() {
simpleTest();
allAttributesTest();
}
private void simpleTest() {
AttributeMap style = AttributeMap.EMPTY_ATTRIBUTE_MAP;
MText text = new StyledText("Hello world!", style);
streamAndCompare(text);
}
private static class TestModifier extends StyleModifier {
private Object fKey;
private Object fValue;
public AttributeMap modifyStyle(AttributeMap style) {
return style.addAttribute(fKey, fValue);
}
TestModifier(Object key, Object value) {
fKey = key;
fValue = value;
}
}
private void allAttributesTest() {
AttributeMap style = AttributeMap.EMPTY_ATTRIBUTE_MAP;
MText text = new StyledText("Hello world!", style);
int length = text.length();
final boolean CHARACTER = true;
final boolean PARAGRAPH = false;
addStyle(text, 0, length/2, TextAttribute.FAMILY, "Times", CHARACTER);
addStyle(text, length/2, length, TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, CHARACTER);
addStyle(text, 0, length/2, TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE, CHARACTER);
addStyle(text, 0, length/2, TextAttribute.SIZE, new Float(13.7f), CHARACTER);
addStyle(text, length/2, length, TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUB, CHARACTER);
addStyle(text, 0, length/2, TextAttribute.FOREGROUND, Color.blue, CHARACTER);
addStyle(text, 0, length/2, TextAttribute.BACKGROUND, Color.red, CHARACTER);
addStyle(text, 0, length-1, TextAttribute.STRIKETHROUGH, Boolean.TRUE, CHARACTER);
addStyle(text, 0, length, TextAttribute.EXTRA_LINE_SPACING, new Float(4), PARAGRAPH);
addStyle(text, 0, length, TextAttribute.FIRST_LINE_INDENT, new Float(6), PARAGRAPH);
addStyle(text, 0, length, TextAttribute.MIN_LINE_SPACING, new Float(7), PARAGRAPH);
addStyle(text, 0, length, TextAttribute.LINE_FLUSH, TextAttribute.FLUSH_TRAILING, PARAGRAPH);
addStyle(text, 0, length, TextAttribute.LEADING_MARGIN, new Float(9), PARAGRAPH);
addStyle(text, 0, length, TextAttribute.TRAILING_MARGIN, new Float(9), PARAGRAPH);
addStyle(text, 0, length, TextAttribute.TAB_RULER, new StandardTabRuler(), PARAGRAPH);
streamAndCompare(text);
}
private static void addStyle(MText text,
int start,
int limit,
Object key,
Object value,
boolean character) {
StyleModifier modifier = new TestModifier(key, value);
if (character) {
text.modifyCharacterStyles(start, limit, modifier);
}
else {
text.modifyParagraphStyles(start, limit, modifier);
}
}
public void streamAndCompare(MText text) {
Throwable error = null;
try {
ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
ObjectOutputStream objOut = new ObjectOutputStream(bytesOut);
objOut.writeObject(text);
ByteArrayInputStream bytesIn =
new ByteArrayInputStream(bytesOut.toByteArray());
ObjectInputStream objIn = new ObjectInputStream(bytesIn);
MText streamedText = (MText) objIn.readObject();
if (!isEqual(text, streamedText)) {
isEqual(text, streamedText);
errln("Streamed text is not equal");
}
}
/* catch(OptionalDataException e) {
error = e;
}
catch(StreamCorruptedException e) {
error = e;
}*/
catch(IOException e) {
error = e;
}
catch(ClassNotFoundException e) {
error = e;
}
if (error != null) {
error.printStackTrace();
errln("Serialization failed.");
}
}
public static boolean isEqual(MText lhs, MText rhs) {
return lhs.equals(rhs);
}
}

View File

@ -0,0 +1,339 @@
/*
* @(#)$RCSfile: TestParagraphStyles.java,v $ $Revision: 1.1 $ $Date: 2000/04/24 20:38:00 $
*
* (C) Copyright IBM Corp. 1998-1999. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
package com.ibm.richtext.tests;
import com.ibm.test.TestFmwk;
import com.ibm.richtext.styledtext.StyledText;
import com.ibm.richtext.styledtext.MConstText;
import com.ibm.richtext.styledtext.MText;
import com.ibm.textlayout.attributes.AttributeMap;
import com.ibm.richtext.styledtext.StyleModifier;
import java.util.Random;
public final class TestParagraphStyles extends TestFmwk {
static final String COPYRIGHT =
"(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
public static void main(String[] args) throws Exception {
new TestParagraphStyles().run(args);
}
private static final int RAND_SEED = 1234;
private static final int NUM_TESTS = 2500;
private static final boolean isParagraphBreak(char c) {
return c =='\u2029' || c == '\n';
}
private static final Object KEY = "KEY";
private static final AttributeMap PLAIN = AttributeMap.EMPTY_ATTRIBUTE_MAP;
private static final AttributeMap A_STYLE = new AttributeMap(KEY, new Character('a'));
private static final StyleModifier A_MOD =
StyleModifier.createReplaceModifier(A_STYLE);
private static final AttributeMap B_STYLE = new AttributeMap(KEY, new Character('b'));
private static final StyleModifier B_MOD =
StyleModifier.createReplaceModifier(B_STYLE);
private static final AttributeMap C_STYLE = new AttributeMap(KEY, new Character('c'));
private static final StyleModifier C_MOD =
StyleModifier.createReplaceModifier(C_STYLE);
private static final AttributeMap D_STYLE = new AttributeMap(KEY, new Character('d'));
private static final StyleModifier D_MOD =
StyleModifier.createReplaceModifier(D_STYLE);
private static final AttributeMap E_STYLE = new AttributeMap(KEY, new Character('e'));
private static final StyleModifier E_MOD =
StyleModifier.createReplaceModifier(E_STYLE);
public void test() {
easyTests();
randomTest();
}
private void easyTests() {
MText text = new StyledText("a\nb\nc\nd\n", PLAIN);
text.modifyParagraphStyles(0, text.length(), A_MOD);
verifyParagraphCount(text);
MText src = new StyledText("XXX\nYYY", PLAIN);
src.modifyParagraphStyles(0, src.length(), B_MOD);
verifyParagraphCount(src);
MText temp = text.extractWritable(0, text.length());
temp.append(src);
verifyParagraphCount(temp);
for (int i=0; i < text.length(); i++) {
if (!temp.paragraphStyleAt(i).equals(text.paragraphStyleAt(i))) {
errln("Paragraph styles are wrong");
}
}
for (int i=0; i < src.length(); i++) {
if (!temp.paragraphStyleAt(i+text.length()).equals(src.paragraphStyleAt(i))) {
errln("Paragraph styles are wrong");
}
}
temp = text.extractWritable(0, text.length());
temp.replace(0, 1, src, 0, src.length());
verifyParagraphCount(temp);
if (temp.paragraphLimit(0) != 4) {
errln("Paragraph limit is wrong");
}
if (!temp.paragraphStyleAt(0).equals(B_STYLE)) {
errln("First style is wrong");
}
if (!temp.paragraphStyleAt(4).equals(A_STYLE)) {
errln("Style after insert is wrong");
}
// test append
MConstText newSrc = src.extract(4, 7);
MText initC = new StyledText("cccccc", PLAIN);
initC.modifyParagraphStyles(0, initC.length(), C_MOD);
initC.append(newSrc);
// now initC should be one paragraph with style B
if (initC.paragraphLimit(0) != initC.length()) {
errln("Should only be one paragraph");
}
if (initC.paragraphStyleAt(0) != initC.paragraphStyleAt(initC.length())) {
errln("Two different paragraph styles");
}
if (!initC.paragraphStyleAt(initC.length()/2).equals(B_STYLE)) {
errln("Incorrect paragraph style");
}
text = new StyledText("aaa\n", PLAIN);
text.modifyParagraphStyles(0, text.length(), A_MOD);
text.modifyParagraphStyles(text.length(), text.length(), B_MOD);
if (text.paragraphStyleAt(text.length()) != B_STYLE) {
errln("0-length paragraph at end has incorrect style");
}
}
private static int randInt(Random rand, int limit) {
return randInt(rand, 0, limit);
}
private static int randInt(Random rand, int start, int limit) {
if (start > limit) {
throw new IllegalArgumentException("Range is 0-length.");
}
else if (start == limit) {
return start;
}
return start + (Math.abs(rand.nextInt())%(limit-start)) ;
}
private void randomTest() {
MText noParagraph = new StyledText("zzzz", PLAIN);
noParagraph.modifyParagraphStyles(0, noParagraph.length(), A_MOD);
MText twoParagraphs = new StyledText("aaa\nbbb", PLAIN);
twoParagraphs.modifyParagraphStyles(0, twoParagraphs.paragraphLimit(0), B_MOD);
MText threeParagraphs = new StyledText("cc\ndd\nee", PLAIN);
threeParagraphs.modifyParagraphStyles(0, 3, C_MOD);
threeParagraphs.modifyParagraphStyles(3, 6, D_MOD);
threeParagraphs.modifyParagraphStyles(6, 8, E_MOD);
MText trailingP1 = new StyledText("hhhh\n", PLAIN);
trailingP1.modifyParagraphStyles(0, trailingP1.paragraphLimit(0), C_MOD);
MText trailingP2 = new StyledText("iii\n", PLAIN);
trailingP2.modifyParagraphStyles(0, 0, D_MOD);
trailingP2.modifyParagraphStyles(trailingP2.length(), trailingP2.length(), B_MOD);
if (!trailingP2.paragraphStyleAt(trailingP2.length()-1).equals(D_STYLE)) {
errln("Style incorrect in trailingP2");
}
if (!trailingP2.paragraphStyleAt(trailingP2.length()).equals(B_STYLE)) {
errln("Ending style incorrect in trailingP2");
}
MConstText[] tests = { noParagraph, twoParagraphs,
threeParagraphs, trailingP1, trailingP2 };
Random random = new Random(RAND_SEED);
int stopAt = 465;
int i = 0;
try {
for (i=0; i < NUM_TESTS; i++) {
int srcIndex = randInt(random, tests.length);
int targetIndex = randInt(random, tests.length);
MText target = new StyledText(tests[targetIndex]);
MConstText src = tests[srcIndex];
int srcStart = randInt(random, src.length());
int srcLimit = randInt(random, srcStart, src.length());
int start = randInt(random, target.length());
int limit = randInt(random, start, target.length());
if (i == stopAt) {
stopAt = i;
}
insertAndCheck(src, srcStart, srcLimit, target, start, limit);
}
}
finally {
if (i < NUM_TESTS) {
logln("iteration=" + i);
}
}
}
private void insertAndCheck(MConstText src, int srcStart, int srcLimit,
MText target, int start, int limit) {
// p-style after insertion
AttributeMap after;
if (limit == target.length() && srcLimit > srcStart) {
after = src.paragraphStyleAt(srcLimit);
}
else {
after = target.paragraphStyleAt(limit);
}
AttributeMap before;
boolean srcHasPBreak = false;
for (int i=srcStart; i < srcLimit; i++) {
if (isParagraphBreak(src.at(i))) {
srcHasPBreak = true;
break;
}
}
if (start > 0 && isParagraphBreak(target.at(start-1))) {
before = target.paragraphStyleAt(start-1);
}
else {
before = srcHasPBreak? src.paragraphStyleAt(srcStart) : after;
}
boolean stylePropogated = !before.equals(target.paragraphStyleAt(Math.max(0, start-1)));
target.resetDamagedRange();
target.replace(start, limit, src, srcStart, srcLimit);
final int damageLimit = (start==limit && srcStart==srcLimit)?
Integer.MIN_VALUE : start + (srcLimit-srcStart);
if (target.damagedRangeLimit() != damageLimit) {
logln("limit: " + damageLimit + "; target.limit: " +
target.damagedRangeLimit());
errln("Damaged range limit is incorrect");
}
final int damageStart = (damageLimit==Integer.MIN_VALUE)? Integer.MAX_VALUE :
(stylePropogated? target.paragraphStart(Math.max(0, start-1)) : start);
if (target.damagedRangeStart() > damageStart) {
logln("start: " + damageStart + "; target.start: " +
target.damagedRangeStart());
errln("Damaged range start is incorrect");
}
verifyParagraphCount(target);
// check endpoints
if (!before.equals(target.paragraphStyleAt(Math.max(start-1, 0)))) {
errln("Incorrect paragraph style before modified range");
}
int lengthDelta = (srcLimit-srcStart) - (limit-start);
int indexAfterInsert = Math.min(target.length(), limit + lengthDelta);
if (!after.equals(target.paragraphStyleAt(indexAfterInsert))) {
errln("Incorrect paragraph style after modified range");
}
if (srcHasPBreak) {
int startP = target.paragraphLimit(start);
int limitOfTest = target.paragraphStart(indexAfterInsert);
int offset = start - srcStart;
while (startP < limitOfTest) {
int limitP = target.paragraphLimit(startP);
if (src.paragraphLimit(startP-offset) + offset != limitP) {
errln("paragraph limits are not consistent");
}
if (!src.paragraphStyleAt(startP-offset)
.equals(target.paragraphStyleAt(startP))) {
errln("paragraph styles are not consistent");
}
startP = limitP;
}
}
else {
for (int i=start; i < start+(srcLimit-srcStart); i++) {
if (!after.equals(target.paragraphStyleAt(i))) {
errln("paragraph style changed unexpectedly");
}
}
}
}
private void verifyParagraphCount(MConstText text) {
int pCount = 0;
int textLength = text.length();
if (textLength == 0) {
pCount = 1;
}
else {
for (int s=0; s < textLength; s = text.paragraphLimit(s)) {
pCount++;
}
if (isParagraphBreak(text.at(textLength-1))) {
pCount++;
}
}
int sepCount = 0;
for (int i=0; i < textLength; i++) {
if (isParagraphBreak(text.at(i))) {
sepCount++;
}
}
if (sepCount + 1 != pCount) {
logln("sepCount=" + sepCount + "; pCount=" + pCount);
errln("Paragraph count is not consistent with characters");
}
}
private void checkEndpoint(MConstText text) {
boolean emptyFinalParagraph;
int length = text.length();
if (length != 0) {
char ch = text.at(length-1);
emptyFinalParagraph = isParagraphBreak(ch);
}
else {
emptyFinalParagraph = true;
}
if ((text.paragraphStart(length) == length) != emptyFinalParagraph) {
errln("Final paragraph length is incorrect");
}
}
}