001: /*
002: * (C) Copyright IBM Corp. 1998-2004. All Rights Reserved.
003: *
004: * The program is provided "as is" without any warranty express or
005: * implied, including the warranty of non-infringement and the implied
006: * warranties of merchantibility and fitness for a particular purpose.
007: * IBM will not be liable for any damages suffered by you as a result
008: * of using the Program. In no event will IBM be liable for any
009: * special, indirect or consequential damages or lost profits even if
010: * IBM has been advised of the possibility of their occurrence. IBM
011: * will not be liable for any third party claims against you.
012: */
013: package com.ibm.richtext.test.unit;
014:
015: import com.ibm.icu.dev.test.TestFmwk;
016:
017: import com.ibm.richtext.textlayout.attributes.AttributeSet;
018: import com.ibm.richtext.textlayout.attributes.TextAttribute;
019: import com.ibm.richtext.textlayout.attributes.AttributeMap;
020: import java.util.Enumeration;
021:
022: // Java2 imports
023: import java.util.Collection;
024: import java.util.Iterator;
025: import java.util.Set;
026: import java.util.Map.Entry;
027:
028: public class TestAttributeMap extends TestFmwk {
029:
030: static final String COPYRIGHT = "(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
031:
032: // There are JDK 1.1 versions of AttributeMap and AttributeSet.
033: // Some of the tests in this class require Java 2 API's. I have
034: // tried to isolate these tests by conditionalizing them on
035: // this static variable. If you are back-porting to 1.1, remove
036: // the Java 2 tests ONLY.
037: private static final boolean gJDK11 = false;
038:
039: public static void main(String[] args) throws Exception {
040:
041: new TestAttributeMap().run(args);
042: }
043:
044: private AttributeSet maps; // A Set of AttributeMaps
045: private AttributeSet sets; // A Set of Sets
046:
047: private static final class TestAttribute extends TextAttribute {
048:
049: TestAttribute(String name) {
050: super (name);
051: }
052: }
053:
054: private static final TestAttribute[] attributes = {
055: new TestAttribute("0"), new TestAttribute("1"),
056: new TestAttribute("2") };
057:
058: private static final Object[] values = { "Hello world",
059: new Float(-42), new Object(),
060: new AttributeMap(new TestAttribute("3"), "HH") };
061:
062: /**
063: * Returns lhs.equals(rhs) - but also checks for symmetry, and
064: * consistency with hashCode().
065: */
066: private boolean equalMaps(AttributeMap lhs, Object rhs) {
067:
068: boolean equal = lhs.equals(rhs);
069: if (equal != (rhs.equals(lhs))) {
070: errln("AttributeMap.equals is not symetric");
071: }
072: if (equal) {
073: if (lhs.hashCode() != rhs.hashCode()) {
074: errln("AttributeMaps are equal but hashCodes differ");
075: }
076: }
077: return equal;
078: }
079:
080: public TestAttributeMap() {
081:
082: maps = AttributeSet.EMPTY_SET;
083: maps = maps.addElement(AttributeMap.EMPTY_ATTRIBUTE_MAP);
084: maps.addElement(new AttributeMap(TextAttribute.SUPERSCRIPT,
085: TextAttribute.SUPERSCRIPT_SUB));
086: maps.addElement(new AttributeMap(TextAttribute.SUPERSCRIPT,
087: TextAttribute.SUPERSCRIPT_SUPER));
088:
089: for (int i = 0; i < attributes.length; i++) {
090: for (int j = 0; j < values.length; j++) {
091: maps = maps.addElement(new AttributeMap(attributes[i],
092: values[j]));
093: }
094: }
095:
096: AttributeMap bigMap = new AttributeMap(new TestAttribute("4"),
097: "value");
098: for (int i = 0; i < Math.min(attributes.length, values.length); i++) {
099: bigMap = bigMap.addAttribute(attributes[i],
100: values[values.length - i - 1]);
101: }
102: maps = maps.addElement(bigMap);
103:
104: sets = AttributeSet.EMPTY_SET;
105:
106: sets = new AttributeSet(AttributeSet.EMPTY_SET);
107:
108: for (int i = 0; i < attributes.length; i++) {
109: AttributeSet newSet = new AttributeSet(attributes[i]);
110: sets = sets.addElement(newSet);
111: }
112:
113: AttributeSet allAttrs = AttributeSet.EMPTY_SET;
114: for (int i = 0; i < attributes.length; i++) {
115: allAttrs = allAttrs.addElement(attributes[i]);
116: }
117:
118: sets = sets.addElement(allAttrs);
119: }
120:
121: /**
122: * Run tests on AttributeMap. If a test fails an exception will propogate out
123: * of this method.
124: */
125: public void test() {
126:
127: easyTests();
128:
129: Enumeration mapIter = maps.elements();
130: while (mapIter.hasMoreElements()) {
131:
132: AttributeMap testMap = (AttributeMap) mapIter.nextElement();
133:
134: _testModifiers(testMap);
135: _testViews(testMap);
136:
137: Enumeration unionIter = maps.elements();
138: while (unionIter.hasMoreElements()) {
139: _testUnionWith(testMap, (AttributeMap) unionIter
140: .nextElement());
141: }
142:
143: Enumeration setIter = sets.elements();
144: while (setIter.hasMoreElements()) {
145: AttributeSet testSet = (AttributeSet) setIter
146: .nextElement();
147: _testIntersectWith(testMap, testSet);
148: _testRemoveAttributes(testMap, testSet);
149: }
150: }
151: }
152:
153: /**
154: * Invoke modifiers on map. All should throw
155: * UnsupportedOperationException, and leave map unmodified.
156: */
157: void _testModifiers(AttributeMap map) {
158:
159: if (gJDK11) {
160: return;
161: }
162:
163: AttributeMap originalMap = new AttributeMap(map);
164:
165: try {
166: map.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
167: errln("Put should throw UnsupportedOperationException.");
168: } catch (UnsupportedOperationException e) {
169: System.out.print("");
170: }
171:
172: try {
173: Object key = TextAttribute.WEIGHT;
174: Iterator iter = map.keySet().iterator();
175: if (iter.hasNext()) {
176: key = iter.next();
177: }
178: map.remove(key);
179: errln("Set should throw UnsupportedOperationException.");
180: } catch (UnsupportedOperationException e) {
181: System.out.print("");
182: }
183:
184: try {
185: map.putAll(map);
186: errln("putAll should throw UnsupportedOperationException.");
187: } catch (UnsupportedOperationException e) {
188: System.out.print("");
189: }
190:
191: try {
192: map.clear();
193: errln("clear should throw UnsupportedOperationException.");
194: } catch (UnsupportedOperationException e) {
195: System.out.print("");
196: }
197:
198: if (!originalMap.equals(map)) {
199: errln("Modifiers changed map.");
200: }
201: }
202:
203: /**
204: * Ensure that map.addAttributes(addMap) is equivalent to calling
205: * map.add on all of addMap's entries.
206: */
207: void _testUnionWith(AttributeMap map, AttributeMap addMap) {
208:
209: AttributeMap lhs = map.addAttributes(addMap);
210:
211: AttributeMap rhs = map;
212:
213: Enumeration iter = addMap.getKeySet().elements();
214: while (iter.hasMoreElements()) {
215: Object attr = iter.nextElement();
216: Object value = addMap.get(attr);
217: rhs = rhs.addAttribute(attr, value);
218: }
219:
220: if (!equalMaps(lhs, rhs)) {
221: errln("Maps are not equal.");
222: }
223: }
224:
225: /**
226: * Ensure that map.removeAttributes(remove) is equivalent to calling
227: * map.removeAttribute on remove's elements.
228: */
229: void _testRemoveAttributes(AttributeMap map, AttributeSet remove) {
230:
231: AttributeMap lhs = map.removeAttributes(remove);
232:
233: AttributeMap rhs = map;
234:
235: Enumeration iter = remove.elements();
236: while (iter.hasMoreElements()) {
237: Object attr = iter.nextElement();
238: rhs = rhs.removeAttribute(attr);
239: }
240:
241: if (!equalMaps(lhs, rhs)) {
242: errln("Maps are not equal.");
243: }
244: }
245:
246: /**
247: * Ensure that map.intersectWith(intersect) is equivalent to
248: * map.removeAttributes(map.keySet() - intersect);
249: */
250: void _testIntersectWith(AttributeMap map, AttributeSet intersect) {
251:
252: AttributeMap lhs = map.intersectWith(intersect);
253:
254: AttributeSet keySet = map.getKeySet();
255: AttributeSet removeSet = keySet.subtract(intersect);
256: AttributeMap rhs = map.removeAttributes(removeSet);
257:
258: if (!equalMaps(lhs, rhs)) {
259: map.intersectWith(intersect);
260: logln("intersect: " + intersect);
261: logln("keySet: " + keySet);
262: logln("removeSet: " + removeSet);
263: logln("map: " + map);
264: logln("lhs: " + lhs);
265: logln("rhs: " + rhs);
266: errln("Maps are not equal.");
267: }
268: }
269:
270: /**
271: * Ensure that:
272: * map, map.keySet(), and map.entrySet() are the same size;
273: * map.containsKey() is true for every key in keySet();
274: * map.containsValue() is true for every value in values;
275: * every entry key is in keySet, every entry value is in map.values();
276: * map.get() is consistent with entry's key, value;
277: * sum of hashcodes of entries equals map.hashCode().
278: */
279: void _testViews(AttributeMap map) {
280:
281: AttributeSet keySet = map.getKeySet();
282:
283: Enumeration keyIter = keySet.elements();
284: while (keyIter.hasMoreElements()) {
285: if (!map.containsKey(keyIter.nextElement())) {
286: errln("keySet contains key not in map");
287: }
288: }
289:
290: if (gJDK11) {
291: return;
292: }
293:
294: Collection values = map.values();
295: Set entrySet = map.entrySet();
296:
297: if (keySet.size() != map.size()
298: || entrySet.size() != map.size()) {
299: errln("Set sizes are inconsistent with map size.");
300: }
301:
302: int hashCode = 0;
303:
304: Iterator valueIter = values.iterator();
305: while (valueIter.hasNext()) {
306: if (!map.containsValue(valueIter.next())) {
307: errln("value set contains value not in map");
308: }
309: }
310:
311: Iterator entryIter = entrySet.iterator();
312: while (entryIter.hasNext()) {
313:
314: Entry entry = (Entry) entryIter.next();
315:
316: Object key = entry.getKey();
317: if (!keySet.contains(key)) {
318: errln("Entry key is not in key set.");
319: }
320:
321: Object value = map.get(entry.getKey());
322: if (!values.contains(value)) {
323: errln("Entry value is not in value set.");
324: }
325:
326: if (map.get(key) != value) {
327: errln("map.get did not return entry value.");
328: }
329:
330: hashCode += entry.hashCode();
331: }
332:
333: if (hashCode != map.hashCode()) {
334: errln("map hashcode is not sum of entry hashcodes.");
335: }
336: }
337:
338: /**
339: * Look for correct behavior in obvious cases.
340: */
341: void easyTests() {
342:
343: AttributeMap map = new AttributeMap();
344: if (!map.equals(AttributeMap.EMPTY_ATTRIBUTE_MAP)) {
345: errln("Default-constructed map is not equal to empty map.");
346: }
347:
348: map = map.addAttribute(TextAttribute.POSTURE,
349: TextAttribute.POSTURE_OBLIQUE);
350: Object otherMap = new AttributeMap(TextAttribute.POSTURE,
351: TextAttribute.POSTURE_OBLIQUE);
352: if (!map.equals(otherMap)) {
353: errln("Maps are inconsistent after map.add");
354: }
355:
356: otherMap = map.addAttributes(map);
357: if (!equalMaps(map, otherMap)) {
358: errln("Maps are inconsistent after addAttributes");
359: }
360:
361: map = map.addAttribute(TextAttribute.UNDERLINE,
362: TextAttribute.UNDERLINE_ON);
363:
364: if (map.size() != 2) {
365: errln("Map size is wrong. map=" + map);
366: }
367:
368: if (equalMaps(map, otherMap)) {
369: errln("Maps should not be equal");
370: }
371:
372: Object posture = new Float(0);
373: map = map.addAttribute(TextAttribute.POSTURE, posture);
374:
375: if (map.size() != 2) {
376: errln("Map size is wrong");
377: }
378:
379: if (!map.get(TextAttribute.POSTURE).equals(posture)) {
380: errln("Map element is wrong");
381: }
382:
383: map = map.removeAttribute(TextAttribute.UNDERLINE);
384:
385: if (map.size() != 1) {
386: errln("Map size is wrong");
387: }
388:
389: if (map.get(TextAttribute.UNDERLINE) != null) {
390: errln("Map should not have element");
391: }
392:
393: // map has POSTURE_REGULAR. If we addAttributes a map with
394: // POSTURE_ITALIC the new map should have POSTURE_ITALIC
395:
396: map = map.addAttributes(new AttributeMap(TextAttribute.POSTURE,
397: TextAttribute.POSTURE_OBLIQUE));
398: if (map.get(TextAttribute.POSTURE) != TextAttribute.POSTURE_OBLIQUE) {
399: errln("Map element is wrong");
400: }
401:
402: _testModifiers(map);
403: _testViews(map);
404:
405: Enumeration mapIter = maps.elements();
406: while (mapIter.hasMoreElements()) {
407: AttributeMap testMap = (AttributeMap) mapIter.nextElement();
408: Object newValue = new Object();
409: AttributeMap newMap = testMap.addAttribute(attributes[0],
410: newValue);
411: if (newMap.get(attributes[0]) != newValue) {
412: errln("Did not get expected value back. map=" + map);
413: }
414: }
415: }
416: }
|