]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_2_1-src/src/com/ibm/richtext/test/unit/TestParagraphStyles.java
icu4jsrc
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / richtext / test / unit / TestParagraphStyles.java
1 /*\r
2  * (C) Copyright IBM Corp. 1998-2007.  All Rights Reserved.\r
3  *\r
4  * The program is provided "as is" without any warranty express or\r
5  * implied, including the warranty of non-infringement and the implied\r
6  * warranties of merchantibility and fitness for a particular purpose.\r
7  * IBM will not be liable for any damages suffered by you as a result\r
8  * of using the Program. In no event will IBM be liable for any\r
9  * special, indirect or consequential damages or lost profits even if\r
10  * IBM has been advised of the possibility of their occurrence. IBM\r
11  * will not be liable for any third party claims against you.\r
12  */\r
13 package com.ibm.richtext.test.unit;\r
14 \r
15 import com.ibm.icu.dev.test.TestFmwk;\r
16 \r
17 import com.ibm.richtext.styledtext.StyledText;\r
18 import com.ibm.richtext.styledtext.MConstText;\r
19 import com.ibm.richtext.styledtext.MText;\r
20 import com.ibm.richtext.textlayout.attributes.AttributeMap;\r
21 import com.ibm.richtext.styledtext.StyleModifier;\r
22 import java.util.Random;\r
23 \r
24 public final class TestParagraphStyles extends TestFmwk {\r
25 \r
26     static final String COPYRIGHT =\r
27                 "(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";\r
28                 \r
29     public static void main(String[] args) throws Exception {\r
30 \r
31         new TestParagraphStyles().run(args);\r
32     }\r
33 \r
34     private static final int RAND_SEED = 1234;\r
35     private static final int NUM_TESTS = 2500;\r
36 \r
37     private static final boolean isParagraphBreak(char c) {\r
38 \r
39         return c =='\u2029' || c == '\n';\r
40     }\r
41 \r
42     private static final Object KEY = "KEY";\r
43     private static final AttributeMap PLAIN = AttributeMap.EMPTY_ATTRIBUTE_MAP;\r
44     private static final AttributeMap A_STYLE = new AttributeMap(KEY, new Character('a'));\r
45     private static final StyleModifier A_MOD =\r
46                             StyleModifier.createReplaceModifier(A_STYLE);\r
47     private static final AttributeMap B_STYLE = new AttributeMap(KEY, new Character('b'));\r
48     private static final StyleModifier B_MOD =\r
49                             StyleModifier.createReplaceModifier(B_STYLE);\r
50     private static final AttributeMap C_STYLE = new AttributeMap(KEY, new Character('c'));\r
51     private static final StyleModifier C_MOD =\r
52                             StyleModifier.createReplaceModifier(C_STYLE);\r
53     private static final AttributeMap D_STYLE = new AttributeMap(KEY, new Character('d'));\r
54     private static final StyleModifier D_MOD =\r
55                             StyleModifier.createReplaceModifier(D_STYLE);\r
56     private static final AttributeMap E_STYLE = new AttributeMap(KEY, new Character('e'));\r
57     private static final StyleModifier E_MOD =\r
58                             StyleModifier.createReplaceModifier(E_STYLE);\r
59 \r
60     public void test() {\r
61 \r
62         easyTests();\r
63         randomTest();\r
64     }\r
65 \r
66     private void easyTests() {\r
67 \r
68         MText text = new StyledText("a\nb\nc\nd\n", PLAIN);\r
69         text.modifyParagraphStyles(0, text.length(), A_MOD);\r
70         verifyParagraphCount(text);\r
71 \r
72         MText src = new StyledText("XXX\nYYY", PLAIN);\r
73         src.modifyParagraphStyles(0, src.length(), B_MOD);\r
74         verifyParagraphCount(src);\r
75 \r
76         MText temp = text.extractWritable(0, text.length());\r
77         temp.append(src);\r
78         verifyParagraphCount(temp);\r
79         for (int i=0; i < text.length(); i++) {\r
80             if (!temp.paragraphStyleAt(i).equals(text.paragraphStyleAt(i))) {\r
81                 errln("Paragraph styles are wrong");\r
82             }\r
83         }\r
84         for (int i=0; i < src.length(); i++) {\r
85             if (!temp.paragraphStyleAt(i+text.length()).equals(src.paragraphStyleAt(i))) {\r
86                 errln("Paragraph styles are wrong");\r
87             }\r
88         }\r
89 \r
90         temp = text.extractWritable(0, text.length());\r
91         temp.replace(0, 1, src, 0, src.length());\r
92         verifyParagraphCount(temp);\r
93         if (temp.paragraphLimit(0) != 4) {\r
94             errln("Paragraph limit is wrong");\r
95         }\r
96         if (!temp.paragraphStyleAt(0).equals(B_STYLE)) {\r
97             errln("First style is wrong");\r
98         }\r
99         if (!temp.paragraphStyleAt(4).equals(A_STYLE)) {\r
100             errln("Style after insert is wrong");\r
101         }\r
102 \r
103         // test append\r
104         MConstText newSrc = src.extract(4, 7);\r
105         MText initC = new StyledText("cccccc", PLAIN);\r
106         initC.modifyParagraphStyles(0, initC.length(), C_MOD);\r
107         initC.append(newSrc);\r
108         // now initC should be one paragraph with style B\r
109         if (initC.paragraphLimit(0) != initC.length()) {\r
110             errln("Should only be one paragraph");\r
111         }\r
112         if (initC.paragraphStyleAt(0) != initC.paragraphStyleAt(initC.length())) {\r
113             errln("Two different paragraph styles");\r
114         }\r
115         if (!initC.paragraphStyleAt(initC.length()/2).equals(B_STYLE)) {\r
116             errln("Incorrect paragraph style");\r
117         }\r
118         \r
119         text = new StyledText("aaa\n", PLAIN);\r
120         text.modifyParagraphStyles(0, text.length(), A_MOD);\r
121         text.modifyParagraphStyles(text.length(), text.length(), B_MOD);\r
122         if (text.paragraphStyleAt(text.length()) != B_STYLE) {\r
123             errln("0-length paragraph at end has incorrect style");\r
124         }\r
125     }\r
126 \r
127     private static int randInt(Random rand, int limit) {\r
128 \r
129         return randInt(rand, 0, limit);\r
130     }\r
131 \r
132     private static int randInt(Random rand, int start, int limit) {\r
133 \r
134         if (start > limit) {\r
135             throw new IllegalArgumentException("Range is 0-length.");\r
136         }\r
137         else if (start == limit) {\r
138             return start;\r
139         }\r
140 \r
141         return start + (Math.abs(rand.nextInt())%(limit-start)) ;\r
142     }\r
143 \r
144     private void randomTest() {\r
145 \r
146         MText noParagraph = new StyledText("zzzz", PLAIN);\r
147         noParagraph.modifyParagraphStyles(0, noParagraph.length(), A_MOD);\r
148         MText twoParagraphs = new StyledText("aaa\nbbb", PLAIN);\r
149         twoParagraphs.modifyParagraphStyles(0, twoParagraphs.paragraphLimit(0), B_MOD);\r
150         MText threeParagraphs = new StyledText("cc\ndd\nee", PLAIN);\r
151         threeParagraphs.modifyParagraphStyles(0, 3, C_MOD);\r
152         threeParagraphs.modifyParagraphStyles(3, 6, D_MOD);\r
153         threeParagraphs.modifyParagraphStyles(6, 8, E_MOD);\r
154         MText trailingP1 = new StyledText("hhhh\n", PLAIN);\r
155         trailingP1.modifyParagraphStyles(0, trailingP1.paragraphLimit(0), C_MOD);\r
156         MText trailingP2 = new StyledText("iii\n", PLAIN);\r
157         trailingP2.modifyParagraphStyles(0, 0, D_MOD);\r
158         trailingP2.modifyParagraphStyles(trailingP2.length(), trailingP2.length(), B_MOD);\r
159 \r
160         if (!trailingP2.paragraphStyleAt(trailingP2.length()-1).equals(D_STYLE)) {\r
161             errln("Style incorrect in trailingP2");\r
162         }\r
163         if (!trailingP2.paragraphStyleAt(trailingP2.length()).equals(B_STYLE)) {\r
164             errln("Ending style incorrect in trailingP2");\r
165         }\r
166 \r
167         MConstText[] tests = { noParagraph, twoParagraphs,\r
168                                     threeParagraphs, trailingP1, trailingP2 };\r
169 \r
170         Random random = new Random(RAND_SEED);\r
171 \r
172         int stopAt = 465;\r
173         int i = 0;\r
174         try {\r
175             for (i=0; i < NUM_TESTS; i++) {\r
176 \r
177                 int srcIndex = randInt(random, tests.length);\r
178                 int targetIndex = randInt(random, tests.length);\r
179                 MText target = new StyledText(tests[targetIndex]);\r
180                 MConstText src = tests[srcIndex];\r
181 \r
182                 int srcStart = randInt(random, src.length());\r
183                 int srcLimit = randInt(random, srcStart, src.length());\r
184                 int start = randInt(random, target.length());\r
185                 int limit = randInt(random, start, target.length());\r
186 \r
187                 if (i == stopAt) {\r
188                     stopAt = i;\r
189                 }\r
190 \r
191                 insertAndCheck(src, srcStart, srcLimit, target, start, limit);\r
192             }\r
193         }\r
194         finally {\r
195             if (i < NUM_TESTS) {\r
196                 logln("iteration=" + i);\r
197             }\r
198         }\r
199     }\r
200 \r
201     private void insertAndCheck(MConstText src, int srcStart, int srcLimit,\r
202                                 MText target, int start, int limit) {\r
203 \r
204         // p-style after insertion\r
205         AttributeMap after;\r
206         if (limit == target.length() && srcLimit > srcStart) {\r
207             after = src.paragraphStyleAt(srcLimit);\r
208         }\r
209         else {\r
210             after = target.paragraphStyleAt(limit);\r
211         }\r
212 \r
213         AttributeMap before;\r
214         boolean srcHasPBreak = false;\r
215         for (int i=srcStart; i < srcLimit; i++) {\r
216             if (isParagraphBreak(src.at(i))) {\r
217                 srcHasPBreak = true;\r
218                 break;\r
219             }\r
220         }\r
221 \r
222         if (start > 0 && isParagraphBreak(target.at(start-1))) {\r
223             before = target.paragraphStyleAt(start-1);\r
224         }\r
225         else {\r
226             before = srcHasPBreak? src.paragraphStyleAt(srcStart) : after;\r
227         }\r
228         boolean stylePropogated = !before.equals(target.paragraphStyleAt(Math.max(0, start-1)));\r
229 \r
230 \r
231         target.resetDamagedRange();\r
232         target.replace(start, limit, src, srcStart, srcLimit);\r
233         final int damageLimit = (start==limit && srcStart==srcLimit)?\r
234                         Integer.MIN_VALUE : start + (srcLimit-srcStart);\r
235 \r
236         if (target.damagedRangeLimit() != damageLimit) {\r
237             logln("limit: " + damageLimit + ";  target.limit: " +\r
238                                 target.damagedRangeLimit());\r
239             errln("Damaged range limit is incorrect");\r
240         }\r
241 \r
242         final int damageStart = (damageLimit==Integer.MIN_VALUE)? Integer.MAX_VALUE :\r
243                 (stylePropogated? target.paragraphStart(Math.max(0, start-1)) : start);\r
244         if (target.damagedRangeStart() > damageStart) {\r
245             logln("start: " + damageStart + ";  target.start: " +\r
246                                 target.damagedRangeStart());\r
247             errln("Damaged range start is incorrect");\r
248         }\r
249 \r
250         verifyParagraphCount(target);\r
251 \r
252         // check endpoints\r
253         if (!before.equals(target.paragraphStyleAt(Math.max(start-1, 0)))) {\r
254             errln("Incorrect paragraph style before modified range");\r
255         }\r
256 \r
257         int lengthDelta = (srcLimit-srcStart) - (limit-start);\r
258         int indexAfterInsert = Math.min(target.length(), limit + lengthDelta);\r
259         if (!after.equals(target.paragraphStyleAt(indexAfterInsert))) {\r
260             errln("Incorrect paragraph style after modified range");\r
261         }\r
262 \r
263         if (srcHasPBreak) {\r
264             int startP = target.paragraphLimit(start);\r
265             int limitOfTest = target.paragraphStart(indexAfterInsert);\r
266 \r
267             int offset = start - srcStart;\r
268 \r
269             while (startP < limitOfTest) {\r
270                 int limitP = target.paragraphLimit(startP);\r
271                 if (src.paragraphLimit(startP-offset) + offset != limitP) {\r
272                     errln("paragraph limits are not consistent");\r
273                 }\r
274                 if (!src.paragraphStyleAt(startP-offset)\r
275                                     .equals(target.paragraphStyleAt(startP))) {\r
276                     errln("paragraph styles are not consistent");\r
277                 }\r
278                 startP = limitP;\r
279             }\r
280         }\r
281         else {\r
282             for (int i=start; i < start+(srcLimit-srcStart); i++) {\r
283                 if (!after.equals(target.paragraphStyleAt(i))) {\r
284                     errln("paragraph style changed unexpectedly");\r
285                 }\r
286             }\r
287         }\r
288     }\r
289 \r
290     private void verifyParagraphCount(MConstText text) {\r
291 \r
292         int pCount = 0;\r
293         int textLength = text.length();\r
294 \r
295         if (textLength == 0) {\r
296             pCount = 1;\r
297         }\r
298         else {\r
299             for (int s=0; s < textLength; s = text.paragraphLimit(s)) {\r
300                 pCount++;\r
301             }\r
302             if (isParagraphBreak(text.at(textLength-1))) {\r
303                 pCount++;\r
304             }\r
305         }\r
306 \r
307         int sepCount = 0;\r
308         for (int i=0; i < textLength; i++) {\r
309             if (isParagraphBreak(text.at(i))) {\r
310                 sepCount++;\r
311             }\r
312         }\r
313 \r
314         if (sepCount + 1 != pCount) {\r
315             logln("sepCount=" + sepCount + ";  pCount=" + pCount);\r
316             errln("Paragraph count is not consistent with characters");\r
317         }\r
318     }\r
319 \r
320 //    private void checkEndpoint(MConstText text) {\r
321 //\r
322 //        boolean emptyFinalParagraph;\r
323 //        int length = text.length();\r
324 //\r
325 //        if (length != 0) {\r
326 //            char ch = text.at(length-1);\r
327 //            emptyFinalParagraph = isParagraphBreak(ch);\r
328 //        }\r
329 //        else {\r
330 //            emptyFinalParagraph = true;\r
331 //        }\r
332 //\r
333 //        if ((text.paragraphStart(length) == length) != emptyFinalParagraph) {\r
334 //            errln("Final paragraph length is incorrect");\r
335 //        }\r
336 //    }\r
337 }