OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 import "package:expect/expect.dart"; | |
6 import "dart:typed_data"; | |
7 | |
8 main() { | |
9 iter(count, [values]) => values is List | |
10 ? new Iterable.generate(count, (x) => values[x]) | |
11 : new Iterable.generate(count, (x) => values); | |
12 test(expect, iter, [start = 0, end]) { | |
13 var actual = new String.fromCharCodes(iter, start, end); | |
14 Expect.equals(expect, actual); | |
15 } | |
16 | |
17 testThrows(iterable, [start = 0, end]) { | |
18 Expect.throws(() { | |
19 new String.fromCharCodes(iterable, start, end); | |
20 }); | |
21 } | |
22 | |
23 test("", iter(0)); | |
24 test("", []); | |
25 test("", const []); | |
26 test("", new List(0)); | |
27 test("", new Uint8List(0)); | |
28 test("", new Uint16List(0)); | |
29 test("", new Uint32List(0)); | |
30 test("", "".codeUnits); | |
31 | |
32 test("\x00", iter(1, 0)); | |
33 test("\x00", [0]); | |
34 test("\x00", const [0]); | |
35 test("\x00", new List(1)..[0] = 0); | |
36 test("\x00", new Uint8List(1)); | |
37 test("\x00", new Uint16List(1)); | |
38 test("\x00", new Uint32List(1)); | |
39 test("\x00", "\x00".codeUnits); | |
40 | |
41 test("\xff", iter(1, 255)); | |
42 test("\xFF", [255]); | |
43 test("\xFF", const [255]); | |
44 test("\xFF", new List(1)..[0] = 255); | |
45 test("\xFF", new Uint8List(1)..[0] = 255); | |
46 test("\xFF", new Uint16List(1)..[0] = 255); | |
47 test("\xFF", new Uint32List(1)..[0] = 255); | |
48 test("\xFF", "\xFF".codeUnits); | |
49 | |
50 test("\u0100", iter(1, 256)); | |
51 test("\u0100", [256]); | |
52 test("\u0100", const [256]); | |
53 test("\u0100", new List(1)..[0] = 256); | |
54 test("\u0100", new Uint16List(1)..[0] = 256); | |
55 test("\u0100", new Uint32List(1)..[0] = 256); | |
56 test("\u0100", "\u0100".codeUnits); | |
57 | |
58 test("\uffff", iter(1, 65535)); | |
59 test("\uffff", [65535]); | |
60 test("\uffff", const [65535]); | |
61 test("\uffff", new List(1)..[0] = 65535); | |
62 test("\uffff", new Uint16List(1)..[0] = 65535); | |
63 test("\uffff", new Uint32List(1)..[0] = 65535); | |
64 test("\uffff", "\uffff".codeUnits); | |
65 | |
66 test("\u{10000}", iter(1, 65536)); | |
67 test("\u{10000}", [65536]); | |
68 test("\u{10000}", const [65536]); | |
69 test("\u{10000}", new List(1)..[0] = 65536); | |
70 test("\u{10000}", new Uint32List(1)..[0] = 65536); | |
71 test("\u{10000}", "\u{10000}".codeUnits); | |
72 | |
73 test("\u{10FFFF}", iter(1, 0x10FFFF)); | |
74 test("\u{10FFFF}", [0x10FFFF]); | |
75 test("\u{10FFFF}", const [0x10FFFF]); | |
76 test("\u{10FFFF}", new List(1)..[0] = 0x10FFFF); | |
77 test("\u{10FFFF}", new Uint32List(1)..[0] = 0x10FFFF); | |
78 | |
79 test("\u{10ffff}", iter(2, [0xDBFF, 0xDFFF])); | |
80 test("\u{10ffff}", [0xDBFF, 0xDFFF]); | |
81 test("\u{10ffff}", const [0xDBFF, 0xDFFF]); | |
82 test( | |
83 "\u{10ffff}", | |
84 new List(2) | |
85 ..[0] = 0xDBFF | |
86 ..[1] = 0xDFFF); | |
87 test( | |
88 "\u{10ffff}", | |
89 new Uint16List(2) | |
90 ..[0] = 0xDBFF | |
91 ..[1] = 0xDFFF); | |
92 test( | |
93 "\u{10ffff}", | |
94 new Uint32List(2) | |
95 ..[0] = 0xDBFF | |
96 ..[1] = 0xDFFF); | |
97 test("\u{10FFFF}", "\u{10FFFF}".codeUnits); | |
98 | |
99 var leadSurrogate = "\u{10ffff}"[0]; | |
100 test(leadSurrogate, iter(1, 0xDBFF)); | |
101 test(leadSurrogate, [0xDBFF]); | |
102 test(leadSurrogate, const [0xDBFF]); | |
103 test(leadSurrogate, new List(1)..[0] = 0xDBFF); | |
104 test(leadSurrogate, new Uint16List(1)..[0] = 0xDBFF); | |
105 test(leadSurrogate, new Uint32List(1)..[0] = 0xDBFF); | |
106 test(leadSurrogate, leadSurrogate.codeUnits); | |
107 | |
108 var tailSurrogate = "\u{10ffff}"[1]; | |
109 test(tailSurrogate, iter(1, 0xDFFF)); | |
110 test(tailSurrogate, [0xDFFF]); | |
111 test(tailSurrogate, const [0xDFFF]); | |
112 test(tailSurrogate, new List(1)..[0] = 0xDFFF); | |
113 test(tailSurrogate, new Uint16List(1)..[0] = 0xDFFF); | |
114 test(tailSurrogate, new Uint32List(1)..[0] = 0xDFFF); | |
115 test(tailSurrogate, tailSurrogate.codeUnits); | |
116 | |
117 testThrows(null); | |
118 testThrows("not an iterable"); | |
119 testThrows(42); | |
120 testThrows([-1]); | |
121 testThrows(new List(1)..[0] = -1); | |
122 testThrows(const [-1]); | |
123 testThrows(new Int8List(1)..[0] = -1); | |
124 testThrows(new Int16List(1)..[0] = -1); | |
125 testThrows(new Int32List(1)..[0] = -1); | |
126 testThrows([0x110000]); | |
127 testThrows(new List(1)..[0] = 0x110000); | |
128 testThrows(const [0x110000]); | |
129 testThrows(new Int32List(1)..[0] = 0x110000); | |
130 | |
131 // Check start/end | |
132 var list = const [0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48]; | |
133 for (var iterable in [ | |
134 iter(list.length, list), | |
135 list.toList(growable: true), | |
136 list.toList(growable: false), | |
137 list, | |
138 new Uint8List(8)..setRange(0, 8, list), | |
139 new Uint16List(8)..setRange(0, 8, list), | |
140 new Uint32List(8)..setRange(0, 8, list), | |
141 "ABCDEFGH".codeUnits, | |
142 ]) { | |
143 test("ABCDEFGH", iterable); | |
144 // start varies, end is null. | |
145 test("ABCDEFGH", iterable, 0); | |
146 test("BCDEFGH", iterable, 1); | |
147 test("H", iterable, 7); | |
148 test("", iterable, 8); | |
149 // start = 0, end varies. | |
150 test("ABCDEFGH", iterable, 0); | |
151 test("A", iterable, 0, 1); | |
152 test("AB", iterable, 0, 2); | |
153 test("ABCDEFG", iterable, 0, 7); | |
154 test("ABCDEFGH", iterable, 0, 8); | |
155 test("", iterable, 0, 0); | |
156 // Both varying. | |
157 test("ABCDEFGH", iterable, 0, 8); | |
158 test("AB", iterable, 0, 2); | |
159 test("GH", iterable, 6, 8); | |
160 test("DE", iterable, 3, 5); | |
161 test("", iterable, 3, 3); | |
162 } | |
163 // Can split surrogates in input, but not a single big code point. | |
164 test(leadSurrogate, [0xDBFF, 0xDFFF], 0, 1); | |
165 test(tailSurrogate, [0xDBFF, 0xDFFF], 1); | |
166 test("\u{10FFFF}", [0x10FFFF], 0, 1); | |
167 | |
168 void testThrowsRange(iterable, [start = 0, end]) { | |
169 Expect.throws(() => new String.fromCharCodes(iterable, start, end), | |
170 (e) => e is RangeError); | |
171 } | |
172 | |
173 // Test varying slices of the code units of a string. | |
174 testSubstring(string) { | |
175 var codes = string.codeUnits; | |
176 int length = string.length; | |
177 for (var iterable in [ | |
178 iter(length, codes), | |
179 codes.toList(growable: true), | |
180 codes.toList(growable: false), | |
181 new Uint16List(length)..setRange(0, length, codes), | |
182 new Int32List(length)..setRange(0, length, codes), | |
183 new Uint32List(length)..setRange(0, length, codes), | |
184 codes, | |
185 ]) { | |
186 var newString = new String.fromCharCodes(iterable); | |
187 Expect.equals(string, newString); | |
188 for (int i = 0; i < length; i = i * 2 + 1) { | |
189 test(string.substring(i), iterable, i); | |
190 test(string.substring(0, i), iterable, 0, i); | |
191 for (int j = 0; i + j < length; j = j * 2 + 1) { | |
192 test(string.substring(i, i + j), iterable, i, i + j); | |
193 } | |
194 } | |
195 | |
196 testThrowsRange(iterable, -1); | |
197 testThrowsRange(iterable, 0, -1); | |
198 testThrowsRange(iterable, 2, 1); | |
199 testThrowsRange(iterable, 0, length + 1); | |
200 testThrowsRange(iterable, length + 1); | |
201 testThrowsRange(iterable, length + 1, length + 2); | |
202 } | |
203 } | |
204 | |
205 testSubstring(""); | |
206 testSubstring("ABCDEFGH"); | |
207 // length > 128 | |
208 testSubstring("ABCDEFGH" * 33); | |
209 testSubstring("\x00" * 357); | |
210 // length > 128 and non-ASCII. | |
211 testSubstring("\uFFFD\uFFFE\u{10000}\u{10ffff}c\x00" * 37); | |
212 | |
213 // Large List. | |
214 var megaList = ("abcde" * 200000).codeUnits.toList(); | |
215 test("abcde" * 199998, megaList, 5, 999995); | |
216 // Large Uint8List. | |
217 test("abcde" * 199998, new Uint8List.fromList(megaList), 5, 999995); | |
218 | |
219 const cLatin1 = const [0x00, 0xff]; | |
220 const cUtf16 = const [0x00, 0xffff, 0xdfff, 0xdbff, 0xdfff, 0xdbff]; | |
221 const cCodepoints = const [0x00, 0xffff, 0xdfff, 0x10ffff, 0xdbff]; | |
222 List gLatin1 = cLatin1.toList(growable: true); | |
223 List gUtf16 = cUtf16.toList(growable: true); | |
224 List gCodepoints = cCodepoints.toList(growable: true); | |
225 List fLatin1 = cLatin1.toList(growable: false); | |
226 List fUtf16 = cUtf16.toList(growable: false); | |
227 List fCodepoints = cCodepoints.toList(growable: false); | |
228 Uint8List bLatin1 = new Uint8List(2)..setRange(0, 2, cLatin1); | |
229 Uint16List wLatin1 = new Uint16List(2)..setRange(0, 2, cLatin1); | |
230 Uint16List wUtf16 = new Uint16List(6)..setRange(0, 6, cUtf16); | |
231 Uint32List lLatin1 = new Uint32List(2)..setRange(0, 2, cLatin1); | |
232 Uint32List lUtf16 = new Uint32List(6)..setRange(0, 6, cUtf16); | |
233 Uint32List lCodepoints = new Uint32List(5)..setRange(0, 5, cCodepoints); | |
234 Uint8List bvLatin1 = new Uint8List.view(bLatin1.buffer); | |
235 Uint16List wvLatin1 = new Uint16List.view(wLatin1.buffer); | |
236 Uint16List wvUtf16 = new Uint16List.view(wUtf16.buffer); | |
237 Uint32List lvLatin1 = new Uint32List.view(lLatin1.buffer); | |
238 Uint32List lvUtf16 = new Uint32List.view(lUtf16.buffer); | |
239 Uint32List lvCodepoints = new Uint32List.view(lCodepoints.buffer); | |
240 var buffer = new Uint8List(200).buffer; | |
241 Uint8List bbLatin1 = new Uint8List.view(buffer, 3, 2)..setAll(0, bLatin1); | |
242 Uint16List wbLatin1 = new Uint16List.view(buffer, 8, 2)..setAll(0, wLatin1); | |
243 Uint16List wbUtf16 = new Uint16List.view(buffer, 16, 6)..setAll(0, wUtf16); | |
244 Uint32List lbLatin1 = new Uint32List.view(buffer, 32, 2)..setAll(0, lLatin1); | |
245 Uint32List lbUtf16 = new Uint32List.view(buffer, 64, 6)..setAll(0, lUtf16); | |
246 Uint32List lbCodepoints = new Uint32List.view(buffer, 128, 5) | |
247 ..setAll(0, lCodepoints); | |
248 | |
249 String sLatin1 = "\x00\xff"; | |
250 String sUnicode = | |
251 "\x00\uffff$tailSurrogate$leadSurrogate$tailSurrogate$leadSurrogate"; | |
252 for (int i = 0; i < 2; i++) { | |
253 for (int j = i + 1; j < 2; j++) { | |
254 test(sLatin1.substring(i, j), cLatin1, i, j); | |
255 test(sLatin1.substring(i, j), gLatin1, i, j); | |
256 test(sLatin1.substring(i, j), fLatin1, i, j); | |
257 test(sLatin1.substring(i, j), bLatin1, i, j); | |
258 test(sLatin1.substring(i, j), wLatin1, i, j); | |
259 test(sLatin1.substring(i, j), lLatin1, i, j); | |
260 test(sLatin1.substring(i, j), bvLatin1, i, j); | |
261 test(sLatin1.substring(i, j), wvLatin1, i, j); | |
262 test(sLatin1.substring(i, j), lvLatin1, i, j); | |
263 test(sLatin1.substring(i, j), bbLatin1, i, j); | |
264 test(sLatin1.substring(i, j), wbLatin1, i, j); | |
265 test(sLatin1.substring(i, j), lbLatin1, i, j); | |
266 } | |
267 } | |
268 for (int i = 0; i < 6; i++) { | |
269 for (int j = i + 1; j < 6; j++) { | |
270 test(sUnicode.substring(i, j), cUtf16, i, j); | |
271 test(sUnicode.substring(i, j), gUtf16, i, j); | |
272 test(sUnicode.substring(i, j), fUtf16, i, j); | |
273 test(sUnicode.substring(i, j), wUtf16, i, j); | |
274 test(sUnicode.substring(i, j), lUtf16, i, j); | |
275 test(sUnicode.substring(i, j), wvUtf16, i, j); | |
276 test(sUnicode.substring(i, j), lvUtf16, i, j); | |
277 test(sUnicode.substring(i, j), wbUtf16, i, j); | |
278 test(sUnicode.substring(i, j), lbUtf16, i, j); | |
279 } | |
280 } | |
281 for (int i = 0; i < 5; i++) { | |
282 for (int j = i + 1; j < 5; j++) { | |
283 int stringEnd = j < 4 ? j : j + 1; | |
284 test(sUnicode.substring(i, stringEnd), cCodepoints, i, j); | |
285 test(sUnicode.substring(i, stringEnd), gCodepoints, i, j); | |
286 test(sUnicode.substring(i, stringEnd), fCodepoints, i, j); | |
287 test(sUnicode.substring(i, stringEnd), lCodepoints, i, j); | |
288 test(sUnicode.substring(i, stringEnd), lvCodepoints, i, j); | |
289 test(sUnicode.substring(i, stringEnd), lbCodepoints, i, j); | |
290 } | |
291 } | |
292 } | |
OLD | NEW |