OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 import 'dart:async'; | 5 import 'dart:async'; |
6 import 'dart:math'; | 6 import 'dart:math'; |
7 | 7 |
8 import "package:unittest/unittest.dart"; | 8 import "package:unittest/unittest.dart"; |
9 import "package:mime/mime.dart"; | 9 import "package:mime/mime.dart"; |
10 | 10 |
11 void _writeInChunks(List<int> data, | 11 void _writeInChunks(List<int> data, |
12 int chunkSize, | 12 int chunkSize, |
13 StreamController<List<int>> controller) { | 13 StreamController<List<int>> controller) { |
14 if (chunkSize == -1) chunkSize = data.length; | 14 if (chunkSize == -1) chunkSize = data.length; |
15 | 15 |
16 int written = 0; | 16 int written = 0; |
17 for (int pos = 0; pos < data.length; pos += chunkSize) { | 17 for (int pos = 0; pos < data.length; pos += chunkSize) { |
18 int remaining = data.length - pos; | 18 int remaining = data.length - pos; |
19 int writeLength = min(chunkSize, remaining); | 19 int writeLength = min(chunkSize, remaining); |
20 controller.add(data.sublist(pos, pos + writeLength)); | 20 controller.add(data.sublist(pos, pos + writeLength)); |
21 written += writeLength; | 21 written += writeLength; |
22 } | 22 } |
23 controller.close(); | 23 controller.close(); |
24 } | 24 } |
25 | 25 |
26 | 26 |
27 void _testParse(String message, | 27 enum TestMode { |
28 String boundary, | 28 IMMEDIATE_LISTEN, |
29 [List<Map> expectedHeaders, | 29 DELAY_LISTEN, |
30 List expectedParts, | 30 PAUSE_RESUME |
31 bool expectError = false]) { | 31 } |
32 | |
33 void _runParseTest(String message, | |
34 String boundary, | |
35 TestMode mode, | |
36 [List<Map> expectedHeaders, | |
37 List expectedParts, | |
38 bool expectError = false]) { | |
32 Future testWrite(List<int> data, [int chunkSize = -1]) { | 39 Future testWrite(List<int> data, [int chunkSize = -1]) { |
33 StreamController controller = new StreamController(sync: true); | 40 StreamController controller = new StreamController(sync: true); |
34 | 41 |
35 var stream = controller.stream.transform( | 42 var stream = controller.stream.transform( |
36 new MimeMultipartTransformer(boundary)); | 43 new MimeMultipartTransformer(boundary)); |
37 int i = 0; | 44 int i = 0; |
38 var completer = new Completer(); | 45 var completer = new Completer(); |
39 var futures = []; | 46 var futures = []; |
40 stream.listen((multipart) { | 47 stream.listen((multipart) { |
41 int part = i++; | 48 int part = i++; |
42 if (expectedHeaders != null) { | 49 if (expectedHeaders != null) { |
43 expect(multipart.headers, equals(expectedHeaders[part])); | 50 expect(multipart.headers, equals(expectedHeaders[part])); |
44 } | 51 } |
45 futures.add(multipart.fold([], (buffer, data) => buffer..addAll(data)) | 52 switch (mode) { |
46 .then((data) { | 53 case TestMode.IMMEDIATE_LISTEN: |
47 if (expectedParts[part] != null) { | 54 futures.add(multipart.fold([], (buffer, data) => buffer..addAll(data)) |
48 expect(data, equals(expectedParts[part].codeUnits)); | 55 .then((data) { |
49 } | 56 if (expectedParts[part] != null) { |
50 })); | 57 expect(data, equals(expectedParts[part].codeUnits)); |
58 } | |
59 })); | |
60 break; | |
61 | |
62 case TestMode.DELAY_LISTEN: | |
63 var completer = new Completer(); | |
64 futures.add(completer.future); | |
65 new Future(() { | |
66 multipart.fold([], (buffer, data) => buffer..addAll(data)) | |
67 .then((data) { | |
68 if (expectedParts[part] != null) { | |
69 expect(data, equals(expectedParts[part].codeUnits)); | |
70 } | |
71 completer.complete(); | |
72 }); | |
73 }); | |
kustermann
2015/02/17 17:08:03
You don't need a completer here. Doing futures.add
Søren Gjesse
2015/02/18 07:27:18
Done.
| |
74 break; | |
75 | |
76 case TestMode.PAUSE_RESUME: | |
77 var completer = new Completer(); | |
78 futures.add(completer.future); | |
79 var buffer = []; | |
80 var subscription; | |
81 subscription = multipart.listen( | |
82 (data) { | |
83 buffer.addAll(data); | |
84 subscription.pause(); | |
85 new Future(() => subscription.resume()); | |
86 }, | |
87 onDone: () { | |
88 if (expectedParts[part] != null) { | |
89 expect(buffer, equals(expectedParts[part].codeUnits)); | |
90 } | |
91 completer.complete(); | |
92 }); | |
93 break; | |
94 } | |
51 }, onError: (error) { | 95 }, onError: (error) { |
52 if (!expectError) throw error; | 96 if (!expectError) throw error; |
53 }, onDone: () { | 97 }, onDone: () { |
54 if (expectedParts != null) { | 98 if (expectedParts != null) { |
55 expect(i, equals(expectedParts.length)); | 99 expect(i, equals(expectedParts.length)); |
56 } | 100 } |
57 Future.wait(futures).then(completer.complete); | 101 Future.wait(futures).then(completer.complete); |
58 }); | 102 }); |
59 | 103 |
60 _writeInChunks(data, chunkSize, controller); | 104 _writeInChunks(data, chunkSize, controller); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
155 expect(Future.wait([ | 199 expect(Future.wait([ |
156 testCompletePartAfterCancel(data, numPartsExpected), | 200 testCompletePartAfterCancel(data, numPartsExpected), |
157 testCompletePartAfterCancel(data, numPartsExpected, 10), | 201 testCompletePartAfterCancel(data, numPartsExpected, 10), |
158 testCompletePartAfterCancel(data, numPartsExpected, 2), | 202 testCompletePartAfterCancel(data, numPartsExpected, 2), |
159 testCompletePartAfterCancel(data, numPartsExpected, 1), | 203 testCompletePartAfterCancel(data, numPartsExpected, 1), |
160 ]), completes); | 204 ]), completes); |
161 }); | 205 }); |
162 } | 206 } |
163 } | 207 } |
164 | 208 |
209 void _testParse(String message, | |
210 String boundary, | |
211 [List<Map> expectedHeaders, | |
212 List expectedParts, | |
213 bool expectError = false]) { | |
214 _runParseTest( | |
215 message, boundary, TestMode.IMMEDIATE_LISTEN, | |
216 expectedHeaders, expectedParts, expectError); | |
217 _runParseTest( | |
218 message, boundary, TestMode.DELAY_LISTEN, | |
219 expectedHeaders, expectedParts, expectError); | |
220 _runParseTest( | |
221 message, boundary, TestMode.PAUSE_RESUME, | |
222 expectedHeaders, expectedParts, expectError); | |
223 } | |
224 | |
165 void _testParseValid() { | 225 void _testParseValid() { |
166 // Empty message from Chrome form post. | 226 // Empty message from Chrome form post. |
167 var message = '------WebKitFormBoundaryU3FBruSkJKG0Yor1--\r\n'; | 227 var message = '------WebKitFormBoundaryU3FBruSkJKG0Yor1--\r\n'; |
168 _testParse(message, "----WebKitFormBoundaryU3FBruSkJKG0Yor1", [], []); | 228 _testParse(message, "----WebKitFormBoundaryU3FBruSkJKG0Yor1", [], []); |
169 | 229 |
170 // Sample from Wikipedia. | 230 // Sample from Wikipedia. |
171 message = """ | 231 message = """ |
172 This is a message with multiple parts in MIME format.\r | 232 This is a message with multiple parts in MIME format.\r |
173 --frontier\r | 233 --frontier\r |
174 Content-Type: text/plain\r | 234 Content-Type: text/plain\r |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
399 \r | 459 \r |
400 Body2\r | 460 Body2\r |
401 --xxx\r\n"""; | 461 --xxx\r\n"""; |
402 _testParse(message, "xxx", null, [null, null], true); | 462 _testParse(message, "xxx", null, [null, null], true); |
403 } | 463 } |
404 | 464 |
405 void main() { | 465 void main() { |
406 _testParseValid(); | 466 _testParseValid(); |
407 _testParseInvalid(); | 467 _testParseInvalid(); |
408 } | 468 } |
OLD | NEW |