Moved to test packages
X-SVN-Rev: 1232
This commit is contained in:
parent
29a5eb3759
commit
1732485c3d
55
icu4j/src/com/ibm/richtext/test/unit/TestAll.java
Executable file
55
icu4j/src/com/ibm/richtext/test/unit/TestAll.java
Executable 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());
|
||||
}
|
||||
}
|
409
icu4j/src/com/ibm/richtext/test/unit/TestAttributeMap.java
Executable file
409
icu4j/src/com/ibm/richtext/test/unit/TestAttributeMap.java
Executable 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
91
icu4j/src/com/ibm/richtext/test/unit/TestAttributeSet.java
Executable file
91
icu4j/src/com/ibm/richtext/test/unit/TestAttributeSet.java
Executable 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.");
|
||||
}
|
||||
}
|
||||
}
|
250
icu4j/src/com/ibm/richtext/test/unit/TestFormatter.java
Executable file
250
icu4j/src/com/ibm/richtext/test/unit/TestFormatter.java
Executable 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;
|
||||
}
|
||||
}
|
||||
}
|
721
icu4j/src/com/ibm/richtext/test/unit/TestMText.java
Executable file
721
icu4j/src/com/ibm/richtext/test/unit/TestMText.java
Executable 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.");
|
||||
//}
|
||||
}
|
||||
}
|
162
icu4j/src/com/ibm/richtext/test/unit/TestMTextStreaming.java
Executable file
162
icu4j/src/com/ibm/richtext/test/unit/TestMTextStreaming.java
Executable 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);
|
||||
}
|
||||
}
|
339
icu4j/src/com/ibm/richtext/test/unit/TestParagraphStyles.java
Executable file
339
icu4j/src/com/ibm/richtext/test/unit/TestParagraphStyles.java
Executable 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");
|
||||
}
|
||||
}
|
||||
}
|
55
icu4j/src/com/ibm/test/richtext/TestAll.java
Executable file
55
icu4j/src/com/ibm/test/richtext/TestAll.java
Executable 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());
|
||||
}
|
||||
}
|
409
icu4j/src/com/ibm/test/richtext/TestAttributeMap.java
Executable file
409
icu4j/src/com/ibm/test/richtext/TestAttributeMap.java
Executable 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
91
icu4j/src/com/ibm/test/richtext/TestAttributeSet.java
Executable file
91
icu4j/src/com/ibm/test/richtext/TestAttributeSet.java
Executable 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.");
|
||||
}
|
||||
}
|
||||
}
|
250
icu4j/src/com/ibm/test/richtext/TestFormatter.java
Executable file
250
icu4j/src/com/ibm/test/richtext/TestFormatter.java
Executable 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;
|
||||
}
|
||||
}
|
||||
}
|
721
icu4j/src/com/ibm/test/richtext/TestMText.java
Executable file
721
icu4j/src/com/ibm/test/richtext/TestMText.java
Executable 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.");
|
||||
//}
|
||||
}
|
||||
}
|
162
icu4j/src/com/ibm/test/richtext/TestMTextStreaming.java
Executable file
162
icu4j/src/com/ibm/test/richtext/TestMTextStreaming.java
Executable 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);
|
||||
}
|
||||
}
|
339
icu4j/src/com/ibm/test/richtext/TestParagraphStyles.java
Executable file
339
icu4j/src/com/ibm/test/richtext/TestParagraphStyles.java
Executable 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");
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user