LEFT | RIGHT |
(no file at all) | |
1 // © 2017 and later: Unicode, Inc. and others. | 1 // © 2017 and later: Unicode, Inc. and others. |
2 // License & terms of use: http://www.unicode.org/copyright.html#License | 2 // License & terms of use: http://www.unicode.org/copyright.html#License |
3 package com.ibm.icu.dev.test.number; | 3 package com.ibm.icu.dev.test.number; |
4 | 4 |
5 import static org.junit.Assert.assertEquals; | 5 import static org.junit.Assert.assertEquals; |
6 import static org.junit.Assert.assertFalse; | 6 import static org.junit.Assert.assertFalse; |
7 import static org.junit.Assert.assertNotEquals; | 7 import static org.junit.Assert.assertNotEquals; |
8 import static org.junit.Assert.assertTrue; | 8 import static org.junit.Assert.assertTrue; |
9 | 9 |
10 import java.text.FieldPosition; | 10 import java.text.FieldPosition; |
11 import java.text.Format.Field; | 11 import java.text.Format.Field; |
12 | 12 |
13 import org.junit.Test; | 13 import org.junit.Test; |
14 | 14 |
15 import com.ibm.icu.impl.number.NumberStringBuilder; | 15 import com.ibm.icu.impl.number.NumberStringBuilder; |
16 import com.ibm.icu.text.NumberFormat; | 16 import com.ibm.icu.text.NumberFormat; |
17 | 17 |
18 /** @author sffc */ | 18 /** @author sffc */ |
19 public class NumberStringBuilderTest { | 19 public class NumberStringBuilderTest { |
20 private static final String[] EXAMPLE_STRINGS = { | 20 private static final String[] EXAMPLE_STRINGS = { |
21 "", | 21 "", |
22 "xyz", | 22 "xyz", |
23 "The quick brown fox jumps over the lazy dog", | 23 "The quick brown fox jumps over the lazy dog", |
24 "😁", | 24 "😁", |
25 "mixed 😇 and ASCII", | 25 "mixed 😇 and ASCII", |
26 "with combining characters like 🇦🇧🇨🇩", | 26 "with combining characters like 🇦🇧🇨🇩", |
27 "A very very very very very very very very very very long string to force he
ap" | 27 "A very very very very very very very very very very long string to
force heap" }; |
28 }; | 28 |
29 | 29 @Test |
30 @Test | 30 public void testInsertAppendCharSequence() { |
31 public void testInsertAppendCharSequence() { | 31 |
32 | 32 StringBuilder sb1 = new StringBuilder(); |
33 StringBuilder sb1 = new StringBuilder(); | 33 NumberStringBuilder sb2 = new NumberStringBuilder(); |
34 NumberStringBuilder sb2 = new NumberStringBuilder(); | 34 for (String str : EXAMPLE_STRINGS) { |
35 for (String str : EXAMPLE_STRINGS) { | 35 NumberStringBuilder sb3 = new NumberStringBuilder(); |
36 NumberStringBuilder sb3 = new NumberStringBuilder(); | 36 sb1.append(str); |
37 sb1.append(str); | 37 sb2.append(str, null); |
38 sb2.append(str, null); | 38 sb3.append(str, null); |
39 sb3.append(str, null); | 39 assertCharSequenceEquals(sb1, sb2); |
40 assertCharSequenceEquals(sb1, sb2); | 40 assertCharSequenceEquals(sb3, str); |
41 assertCharSequenceEquals(sb3, str); | 41 |
42 | 42 StringBuilder sb4 = new StringBuilder(); |
43 StringBuilder sb4 = new StringBuilder(); | 43 NumberStringBuilder sb5 = new NumberStringBuilder(); |
44 NumberStringBuilder sb5 = new NumberStringBuilder(); | 44 sb4.append("😇"); |
45 sb4.append("😇"); | 45 sb4.append(str); |
46 sb4.append(str); | 46 sb4.append("xx"); |
47 sb4.append("xx"); | 47 sb5.append("😇xx", null); |
48 sb5.append("😇xx", null); | 48 sb5.insert(2, str, null); |
49 sb5.insert(2, str, null); | 49 assertCharSequenceEquals(sb4, sb5); |
50 assertCharSequenceEquals(sb4, sb5); | 50 |
51 | 51 int start = Math.min(1, str.length()); |
52 int start = Math.min(1, str.length()); | 52 int end = Math.min(10, str.length()); |
53 int end = Math.min(10, str.length()); | 53 sb4.insert(3, str, start, end); |
54 sb4.insert(3, str, start, end); | 54 sb5.insert(3, str, start, end, null); |
55 sb5.insert(3, str, start, end, null); | 55 assertCharSequenceEquals(sb4, sb5); |
56 assertCharSequenceEquals(sb4, sb5); | 56 |
57 | 57 sb4.append(str.toCharArray()); |
58 sb4.append(str.toCharArray()); | 58 sb5.append(str.toCharArray(), null); |
59 sb5.append(str.toCharArray(), null); | 59 assertCharSequenceEquals(sb4, sb5); |
60 assertCharSequenceEquals(sb4, sb5); | 60 |
61 | 61 sb4.insert(4, str.toCharArray()); |
62 sb4.insert(4, str.toCharArray()); | 62 sb5.insert(4, str.toCharArray(), null); |
63 sb5.insert(4, str.toCharArray(), null); | 63 assertCharSequenceEquals(sb4, sb5); |
64 assertCharSequenceEquals(sb4, sb5); | 64 |
65 | 65 sb4.append(sb4.toString()); |
66 sb4.append(sb4.toString()); | 66 sb5.append(new NumberStringBuilder(sb5)); |
67 sb5.append(new NumberStringBuilder(sb5)); | 67 assertCharSequenceEquals(sb4, sb5); |
68 assertCharSequenceEquals(sb4, sb5); | 68 } |
69 } | 69 } |
70 } | 70 |
71 | 71 @Test |
72 @Test | 72 public void testInsertAppendCodePoint() { |
73 public void testInsertAppendCodePoint() { | 73 int[] cases = { 0, 1, 60, 127, 128, 0x7fff, 0x8000, 0xffff, 0x10000, 0x1
f000, 0x10ffff }; |
74 int[] cases = {0, 1, 60, 127, 128, 0x7fff, 0x8000, 0xffff, 0x10000, 0x1f000,
0x10ffff}; | 74 |
75 | 75 StringBuilder sb1 = new StringBuilder(); |
76 StringBuilder sb1 = new StringBuilder(); | 76 NumberStringBuilder sb2 = new NumberStringBuilder(); |
77 NumberStringBuilder sb2 = new NumberStringBuilder(); | 77 for (int cas : cases) { |
78 for (int cas : cases) { | 78 NumberStringBuilder sb3 = new NumberStringBuilder(); |
79 NumberStringBuilder sb3 = new NumberStringBuilder(); | 79 sb1.appendCodePoint(cas); |
80 sb1.appendCodePoint(cas); | 80 sb2.appendCodePoint(cas, null); |
81 sb2.appendCodePoint(cas, null); | 81 sb3.appendCodePoint(cas, null); |
82 sb3.appendCodePoint(cas, null); | 82 assertCharSequenceEquals(sb1, sb2); |
83 assertCharSequenceEquals(sb1, sb2); | 83 assertEquals(Character.codePointAt(sb3, 0), cas); |
84 assertEquals(Character.codePointAt(sb3, 0), cas); | 84 |
85 | 85 StringBuilder sb4 = new StringBuilder(); |
86 StringBuilder sb4 = new StringBuilder(); | 86 NumberStringBuilder sb5 = new NumberStringBuilder(); |
87 NumberStringBuilder sb5 = new NumberStringBuilder(); | 87 sb4.append("😇"); |
88 sb4.append("😇"); | 88 sb4.appendCodePoint(cas); // Java StringBuilder has no insertCodePoi
nt() |
89 sb4.appendCodePoint(cas); // Java StringBuilder has no insertCodePoint() | 89 sb4.append("xx"); |
90 sb4.append("xx"); | 90 sb5.append("😇xx", null); |
91 sb5.append("😇xx", null); | 91 sb5.insertCodePoint(2, cas, null); |
92 sb5.insertCodePoint(2, cas, null); | 92 assertCharSequenceEquals(sb4, sb5); |
93 assertCharSequenceEquals(sb4, sb5); | 93 } |
94 } | 94 } |
95 } | 95 |
96 | 96 @Test |
97 @Test | 97 public void testCopy() { |
98 public void testCopy() { | 98 for (String str : EXAMPLE_STRINGS) { |
99 for (String str : EXAMPLE_STRINGS) { | 99 NumberStringBuilder sb1 = new NumberStringBuilder(); |
100 NumberStringBuilder sb1 = new NumberStringBuilder(); | 100 sb1.append(str, null); |
101 sb1.append(str, null); | 101 NumberStringBuilder sb2 = new NumberStringBuilder(sb1); |
102 NumberStringBuilder sb2 = new NumberStringBuilder(sb1); | 102 assertCharSequenceEquals(sb1, sb2); |
103 assertCharSequenceEquals(sb1, sb2); | 103 assertTrue(sb1.contentEquals(sb2)); |
104 assertTrue(sb1.contentEquals(sb2)); | 104 |
105 | 105 sb1.append("12345", null); |
106 sb1.append("12345", null); | 106 assertNotEquals(sb1.length(), sb2.length()); |
107 assertNotEquals(sb1.length(), sb2.length()); | 107 assertFalse(sb1.contentEquals(sb2)); |
108 assertFalse(sb1.contentEquals(sb2)); | 108 } |
109 } | 109 } |
110 } | 110 |
111 | 111 @Test |
112 @Test | 112 public void testFields() { |
113 public void testFields() { | 113 for (String str : EXAMPLE_STRINGS) { |
114 for (String str : EXAMPLE_STRINGS) { | 114 NumberStringBuilder sb = new NumberStringBuilder(); |
115 NumberStringBuilder sb = new NumberStringBuilder(); | 115 sb.append(str, null); |
116 sb.append(str, null); | 116 sb.append(str, NumberFormat.Field.CURRENCY); |
117 sb.append(str, NumberFormat.Field.CURRENCY); | 117 Field[] fields = sb.toFieldArray(); |
118 Field[] fields = sb.toFieldArray(); | 118 assertEquals(str.length() * 2, fields.length); |
119 assertEquals(str.length() * 2, fields.length); | 119 for (int i = 0; i < str.length(); i++) { |
120 for (int i = 0; i < str.length(); i++) { | 120 assertEquals(null, fields[i]); |
121 assertEquals(null, fields[i]); | 121 assertEquals(null, sb.fieldAt(i)); |
122 assertEquals(null, sb.fieldAt(i)); | 122 assertEquals(NumberFormat.Field.CURRENCY, fields[i + str.length(
)]); |
123 assertEquals(NumberFormat.Field.CURRENCY, fields[i + str.length()]); | 123 assertEquals(NumberFormat.Field.CURRENCY, sb.fieldAt(i + str.len
gth())); |
124 assertEquals(NumberFormat.Field.CURRENCY, sb.fieldAt(i + str.length())); | 124 } |
125 } | 125 |
126 | 126 // Very basic FieldPosition test. More robust tests happen in Number
FormatTest. |
127 // Very basic FieldPosition test. More robust tests happen in NumberFormat
Test. | 127 // Let NumberFormatTest also take care of AttributedCharacterIterato
r material. |
128 // Let NumberFormatTest also take care of AttributedCharacterIterator mate
rial. | 128 FieldPosition fp = new FieldPosition(NumberFormat.Field.CURRENCY); |
129 FieldPosition fp = new FieldPosition(NumberFormat.Field.CURRENCY); | 129 sb.populateFieldPosition(fp, 0); |
130 sb.populateFieldPosition(fp, 0); | 130 assertEquals(str.length(), fp.getBeginIndex()); |
131 assertEquals(str.length(), fp.getBeginIndex()); | 131 assertEquals(str.length() * 2, fp.getEndIndex()); |
132 assertEquals(str.length() * 2, fp.getEndIndex()); | 132 |
133 | 133 if (str.length() > 0) { |
134 if (str.length() > 0) { | 134 sb.insertCodePoint(2, 100, NumberFormat.Field.INTEGER); |
135 sb.insertCodePoint(2, 100, NumberFormat.Field.INTEGER); | 135 fields = sb.toFieldArray(); |
136 fields = sb.toFieldArray(); | 136 assertEquals(str.length() * 2 + 1, fields.length); |
137 assertEquals(str.length() * 2 + 1, fields.length); | 137 assertEquals(fields[2], NumberFormat.Field.INTEGER); |
138 assertEquals(fields[2], NumberFormat.Field.INTEGER); | 138 } |
139 } | 139 |
140 | 140 sb.append(new NumberStringBuilder(sb)); |
141 sb.append(new NumberStringBuilder(sb)); | 141 sb.append(sb.toCharArray(), sb.toFieldArray()); |
142 sb.append(sb.toCharArray(), sb.toFieldArray()); | 142 int numNull = 0; |
143 int numNull = 0; | 143 int numCurr = 0; |
144 int numCurr = 0; | 144 int numInt = 0; |
145 int numInt = 0; | 145 Field[] oldFields = fields; |
146 Field[] oldFields = fields; | 146 fields = sb.toFieldArray(); |
147 fields = sb.toFieldArray(); | 147 for (int i = 0; i < sb.length(); i++) { |
148 for (int i = 0; i < sb.length(); i++) { | 148 assertEquals(oldFields[i % oldFields.length], fields[i]); |
149 assertEquals(oldFields[i % oldFields.length], fields[i]); | 149 if (fields[i] == null) { |
150 if (fields[i] == null) { | 150 numNull++; |
151 numNull++; | 151 } else if (fields[i] == NumberFormat.Field.CURRENCY) { |
152 } else if (fields[i] == NumberFormat.Field.CURRENCY) { | 152 numCurr++; |
153 numCurr++; | 153 } else if (fields[i] == NumberFormat.Field.INTEGER) { |
154 } else if (fields[i] == NumberFormat.Field.INTEGER) { | 154 numInt++; |
155 numInt++; | 155 } else { |
156 } else { | 156 throw new AssertionError("Encountered unknown field in " + s
tr); |
157 throw new AssertionError("Encountered unknown field in " + str); | 157 } |
158 } | 158 } |
159 } | 159 assertEquals(str.length() * 4, numNull); |
160 assertEquals(str.length() * 4, numNull); | 160 assertEquals(numNull, numCurr); |
161 assertEquals(numNull, numCurr); | 161 assertEquals(str.length() > 0 ? 4 : 0, numInt); |
162 assertEquals(str.length() > 0 ? 4 : 0, numInt); | 162 |
163 | 163 NumberStringBuilder sb2 = new NumberStringBuilder(); |
164 NumberStringBuilder sb2 = new NumberStringBuilder(); | 164 sb2.append(sb); |
165 sb2.append(sb); | 165 assertTrue(sb.contentEquals(sb2)); |
166 assertTrue(sb.contentEquals(sb2)); | 166 assertTrue(sb.contentEquals(sb2.toCharArray(), sb2.toFieldArray())); |
167 assertTrue(sb.contentEquals(sb2.toCharArray(), sb2.toFieldArray())); | 167 |
168 | 168 sb2.insertCodePoint(0, 50, NumberFormat.Field.FRACTION); |
169 sb2.insertCodePoint(0, 50, NumberFormat.Field.FRACTION); | 169 assertTrue(!sb.contentEquals(sb2)); |
170 assertTrue(!sb.contentEquals(sb2)); | 170 assertTrue(!sb.contentEquals(sb2.toCharArray(), sb2.toFieldArray()))
; |
171 assertTrue(!sb.contentEquals(sb2.toCharArray(), sb2.toFieldArray())); | 171 } |
172 } | 172 } |
173 } | 173 |
174 | 174 @Test |
175 @Test | 175 public void testUnlimitedCapacity() { |
176 public void testUnlimitedCapacity() { | 176 NumberStringBuilder builder = new NumberStringBuilder(); |
177 NumberStringBuilder builder = new NumberStringBuilder(); | 177 // The builder should never fail upon repeated appends. |
178 // The builder should never fail upon repeated appends. | 178 for (int i = 0; i < 1000; i++) { |
179 for (int i = 0; i < 1000; i++) { | 179 assertEquals(builder.length(), i); |
180 assertEquals(builder.length(), i); | 180 builder.appendCodePoint('x', null); |
181 builder.appendCodePoint('x', null); | 181 assertEquals(builder.length(), i + 1); |
182 assertEquals(builder.length(), i + 1); | 182 } |
183 } | 183 } |
184 } | 184 |
185 | 185 @Test |
186 @Test | 186 public void testCodePoints() { |
187 public void testCodePoints() { | 187 NumberStringBuilder nsb = new NumberStringBuilder(); |
188 NumberStringBuilder nsb = new NumberStringBuilder(); | 188 assertEquals("First is -1 on empty string", -1, nsb.getFirstCodePoint())
; |
189 assertEquals("First is -1 on empty string", -1, nsb.getFirstCodePoint()); | 189 assertEquals("Last is -1 on empty string", -1, nsb.getLastCodePoint()); |
190 assertEquals("Last is -1 on empty string", -1, nsb.getLastCodePoint()); | 190 assertEquals("Length is 0 on empty string", 0, nsb.codePointCount()); |
191 assertEquals("Length is 0 on empty string", 0, nsb.codePointCount()); | 191 |
192 | 192 nsb.append("q", null); |
193 nsb.append("q", null); | 193 assertEquals("First is q", 'q', nsb.getFirstCodePoint()); |
194 assertEquals("First is q", 'q', nsb.getFirstCodePoint()); | 194 assertEquals("Last is q", 'q', nsb.getLastCodePoint()); |
195 assertEquals("Last is q", 'q', nsb.getLastCodePoint()); | 195 assertEquals("0th is q", 'q', nsb.codePointAt(0)); |
196 assertEquals("0th is q", 'q', nsb.codePointAt(0)); | 196 assertEquals("Before 1st is q", 'q', nsb.codePointBefore(1)); |
197 assertEquals("Before 1st is q", 'q', nsb.codePointBefore(1)); | 197 assertEquals("Code point count is 1", 1, nsb.codePointCount()); |
198 assertEquals("Code point count is 1", 1, nsb.codePointCount()); | 198 |
199 | 199 // 🚀 is two char16s |
200 // 🚀 is two char16s | 200 nsb.append("🚀", null); |
201 nsb.append("🚀", null); | 201 assertEquals("First is still q", 'q', nsb.getFirstCodePoint()); |
202 assertEquals("First is still q", 'q', nsb.getFirstCodePoint()); | 202 assertEquals("Last is space ship", 128640, nsb.getLastCodePoint()); |
203 assertEquals("Last is space ship", 128640, nsb.getLastCodePoint()); | 203 assertEquals("1st is space ship", 128640, nsb.codePointAt(1)); |
204 assertEquals("1st is space ship", 128640, nsb.codePointAt(1)); | 204 assertEquals("Before 1st is q", 'q', nsb.codePointBefore(1)); |
205 assertEquals("Before 1st is q", 'q', nsb.codePointBefore(1)); | 205 assertEquals("Before 3rd is space ship", 128640, nsb.codePointBefore(3))
; |
206 assertEquals("Before 3rd is space ship", 128640, nsb.codePointBefore(3)); | 206 assertEquals("Code point count is 2", 2, nsb.codePointCount()); |
207 assertEquals("Code point count is 2", 2, nsb.codePointCount()); | 207 } |
208 } | 208 |
209 | 209 private static void assertCharSequenceEquals(CharSequence a, CharSequence b)
{ |
210 private static void assertCharSequenceEquals(CharSequence a, CharSequence b) { | 210 assertEquals(a.toString(), b.toString()); |
211 assertEquals(a.toString(), b.toString()); | 211 |
212 | 212 assertEquals(a.length(), b.length()); |
213 assertEquals(a.length(), b.length()); | 213 for (int i = 0; i < a.length(); i++) { |
214 for (int i = 0; i < a.length(); i++) { | 214 assertEquals(a.charAt(i), b.charAt(i)); |
215 assertEquals(a.charAt(i), b.charAt(i)); | 215 } |
216 } | 216 |
217 | 217 int start = Math.min(2, a.length()); |
218 int start = Math.min(2, a.length()); | 218 int end = Math.min(12, a.length()); |
219 int end = Math.min(12, a.length()); | 219 if (start != end) { |
220 if (start != end) { | 220 assertCharSequenceEquals(a.subSequence(start, end), b.subSequence(st
art, end)); |
221 assertCharSequenceEquals(a.subSequence(start, end), b.subSequence(start, e
nd)); | 221 } |
222 } | 222 } |
223 } | |
224 } | 223 } |
LEFT | RIGHT |