Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1405)

Side by Side Diff: test/mime_multipart_transformer_test.dart

Issue 1315033002: pkg/mime: dartfmt most of the code (Closed) Base URL: https://github.com/dart-lang/mime.git@master
Patch Set: rebase Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lib/src/mime_type.dart ('k') | test/mime_type_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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:test/test.dart"; 8 import "package:test/test.dart";
9 import "package:mime/mime.dart"; 9 import "package:mime/mime.dart";
10 10
11 void _writeInChunks(List<int> data, 11 void _writeInChunks(
12 int chunkSize, 12 List<int> data, int chunkSize, StreamController<List<int>> controller) {
13 StreamController<List<int>> controller) {
14 if (chunkSize == -1) chunkSize = data.length; 13 if (chunkSize == -1) chunkSize = data.length;
15 14
16 int written = 0; 15 int written = 0;
17 for (int pos = 0; pos < data.length; pos += chunkSize) { 16 for (int pos = 0; pos < data.length; pos += chunkSize) {
18 int remaining = data.length - pos; 17 int remaining = data.length - pos;
19 int writeLength = min(chunkSize, remaining); 18 int writeLength = min(chunkSize, remaining);
20 controller.add(data.sublist(pos, pos + writeLength)); 19 controller.add(data.sublist(pos, pos + writeLength));
21 written += writeLength; 20 written += writeLength;
22 } 21 }
23 controller.close(); 22 controller.close();
24 } 23 }
25 24
25 enum TestMode { IMMEDIATE_LISTEN, DELAY_LISTEN, PAUSE_RESUME }
26 26
27 enum TestMode { 27 void _runParseTest(String message, String boundary, TestMode mode,
28 IMMEDIATE_LISTEN, 28 [List<Map> expectedHeaders, List expectedParts, bool expectError = false]) {
29 DELAY_LISTEN,
30 PAUSE_RESUME
31 }
32
33 void _runParseTest(String message,
34 String boundary,
35 TestMode mode,
36 [List<Map> expectedHeaders,
37 List expectedParts,
38 bool expectError = false]) {
39 Future testWrite(List<int> data, [int chunkSize = -1]) { 29 Future testWrite(List<int> data, [int chunkSize = -1]) {
40 StreamController controller = new StreamController(sync: true); 30 StreamController controller = new StreamController(sync: true);
41 31
42 var stream = controller.stream.transform( 32 var stream =
43 new MimeMultipartTransformer(boundary)); 33 controller.stream.transform(new MimeMultipartTransformer(boundary));
44 int i = 0; 34 int i = 0;
45 var completer = new Completer(); 35 var completer = new Completer();
46 var futures = []; 36 var futures = [];
47 stream.listen((multipart) { 37 stream.listen((multipart) {
48 int part = i++; 38 int part = i++;
49 if (expectedHeaders != null) { 39 if (expectedHeaders != null) {
50 expect(multipart.headers, equals(expectedHeaders[part])); 40 expect(multipart.headers, equals(expectedHeaders[part]));
51 } 41 }
52 switch (mode) { 42 switch (mode) {
53 case TestMode.IMMEDIATE_LISTEN: 43 case TestMode.IMMEDIATE_LISTEN:
54 futures.add(multipart.fold([], (buffer, data) => buffer..addAll(data)) 44 futures.add(multipart.fold([], (buffer, data) => buffer..addAll(data))
55 .then((data) { 45 .then((data) {
56 if (expectedParts[part] != null) { 46 if (expectedParts[part] != null) {
57 expect(data, equals(expectedParts[part].codeUnits)); 47 expect(data, equals(expectedParts[part].codeUnits));
58 } 48 }
59 })); 49 }));
60 break; 50 break;
61 51
62 case TestMode.DELAY_LISTEN: 52 case TestMode.DELAY_LISTEN:
63 futures.add(new Future(() { 53 futures.add(new Future(() {
64 return multipart.fold([], (buffer, data) => buffer..addAll(data)) 54 return multipart.fold([], (buffer, data) => buffer..addAll(data))
65 .then((data) { 55 .then((data) {
66 if (expectedParts[part] != null) { 56 if (expectedParts[part] != null) {
67 expect(data, equals(expectedParts[part].codeUnits)); 57 expect(data, equals(expectedParts[part].codeUnits));
68 } 58 }
69 }); 59 });
70 })); 60 }));
71 break; 61 break;
72 62
73 case TestMode.PAUSE_RESUME: 63 case TestMode.PAUSE_RESUME:
74 var completer = new Completer(); 64 var completer = new Completer();
75 futures.add(completer.future); 65 futures.add(completer.future);
76 var buffer = []; 66 var buffer = [];
77 var subscription; 67 var subscription;
78 subscription = multipart.listen( 68 subscription = multipart.listen((data) {
79 (data) { 69 buffer.addAll(data);
80 buffer.addAll(data); 70 subscription.pause();
81 subscription.pause(); 71 new Future(() => subscription.resume());
82 new Future(() => subscription.resume()); 72 }, onDone: () {
83 }, 73 if (expectedParts[part] != null) {
84 onDone: () { 74 expect(buffer, equals(expectedParts[part].codeUnits));
85 if (expectedParts[part] != null) { 75 }
86 expect(buffer, equals(expectedParts[part].codeUnits)); 76 completer.complete();
87 } 77 });
88 completer.complete();
89 });
90 break; 78 break;
91 } 79 }
92 }, onError: (error) { 80 }, onError: (error) {
93 if (!expectError) throw error; 81 if (!expectError) throw error;
94 }, onDone: () { 82 }, onDone: () {
95 if (expectedParts != null) { 83 if (expectedParts != null) {
96 expect(i, equals(expectedParts.length)); 84 expect(i, equals(expectedParts.length));
97 } 85 }
98 Future.wait(futures).then(completer.complete); 86 Future.wait(futures).then(completer.complete);
99 }); 87 });
100 88
101 _writeInChunks(data, chunkSize, controller); 89 _writeInChunks(data, chunkSize, controller);
102 90
103 return completer.future; 91 return completer.future;
104 } 92 }
105 93
106 Future testFirstPartOnly(List<int> data, [int chunkSize = -1]) { 94 Future testFirstPartOnly(List<int> data, [int chunkSize = -1]) {
107 var completer = new Completer(); 95 var completer = new Completer();
108 var controller = new StreamController(sync: true); 96 var controller = new StreamController(sync: true);
109 97
110 var stream = controller.stream.transform( 98 var stream =
111 new MimeMultipartTransformer(boundary)); 99 controller.stream.transform(new MimeMultipartTransformer(boundary));
112 100
113 var subscription; 101 var subscription;
114 subscription = stream.first.then((multipart) { 102 subscription = stream.first.then((multipart) {
115 if (expectedHeaders != null) { 103 if (expectedHeaders != null) {
116 expect(multipart.headers, equals(expectedHeaders[0])); 104 expect(multipart.headers, equals(expectedHeaders[0]));
117 } 105 }
118 return (multipart.fold([], (b, d) => b..addAll(d)).then((data) { 106 return (multipart.fold([], (b, d) => b..addAll(d)).then((data) {
119 if (expectedParts != null && expectedParts[0] != null) { 107 if (expectedParts != null && expectedParts[0] != null) {
120 expect(data, equals(expectedParts[0].codeUnits)); 108 expect(data, equals(expectedParts[0].codeUnits));
121 } 109 }
122 })); 110 }));
123 }).then((_) { 111 }).then((_) {
124 completer.complete(); 112 completer.complete();
125 }); 113 });
126 114
127 _writeInChunks(data, chunkSize, controller); 115 _writeInChunks(data, chunkSize, controller);
128 116
129 return completer.future; 117 return completer.future;
130 } 118 }
131 119
132 Future testCompletePartAfterCancel(List<int> data, 120 Future testCompletePartAfterCancel(List<int> data, int parts,
133 int parts, 121 [int chunkSize = -1]) {
134 [int chunkSize = -1]) {
135 var completer = new Completer(); 122 var completer = new Completer();
136 var controller = new StreamController(sync: true); 123 var controller = new StreamController(sync: true);
137 var stream = controller.stream.transform( 124 var stream =
138 new MimeMultipartTransformer(boundary)); 125 controller.stream.transform(new MimeMultipartTransformer(boundary));
139 var subscription; 126 var subscription;
140 int i = 0; 127 int i = 0;
141 var futures = []; 128 var futures = [];
142 subscription = stream.listen((multipart) { 129 subscription = stream.listen((multipart) {
143 int partIndex = i; 130 int partIndex = i;
144 131
145 if (partIndex >= parts) { 132 if (partIndex >= parts) {
146 throw 'Expected no more parts, but got one.'; 133 throw 'Expected no more parts, but got one.';
147 } 134 }
148 135
(...skipping 15 matching lines...) Expand all
164 151
165 _writeInChunks(data, chunkSize, controller); 152 _writeInChunks(data, chunkSize, controller);
166 153
167 return completer.future; 154 return completer.future;
168 } 155 }
169 156
170 // Test parsing the data three times delivering the data in 157 // Test parsing the data three times delivering the data in
171 // different chunks. 158 // different chunks.
172 List<int> data = message.codeUnits; 159 List<int> data = message.codeUnits;
173 test('test', () { 160 test('test', () {
174 expect(Future.wait([ 161 expect(
175 testWrite(data), 162 Future.wait([
176 testWrite(data, 10), 163 testWrite(data),
177 testWrite(data, 2), 164 testWrite(data, 10),
178 testWrite(data, 1), 165 testWrite(data, 2),
179 ]), completes); 166 testWrite(data, 1),
167 ]),
168 completes);
180 }); 169 });
181 170
182 if (expectedParts.length > 0) { 171 if (expectedParts.length > 0) {
183 test('test-first-part-only', () { 172 test('test-first-part-only', () {
184 expect(Future.wait([ 173 expect(
185 testFirstPartOnly(data), 174 Future.wait([
186 testFirstPartOnly(data, 10), 175 testFirstPartOnly(data),
187 testFirstPartOnly(data, 2), 176 testFirstPartOnly(data, 10),
188 testFirstPartOnly(data, 1), 177 testFirstPartOnly(data, 2),
189 ]), completes); 178 testFirstPartOnly(data, 1),
179 ]),
180 completes);
190 }); 181 });
191 182
192 test('test-n-parts-only', () { 183 test('test-n-parts-only', () {
193 int numPartsExpected = expectedParts.length - 1; 184 int numPartsExpected = expectedParts.length - 1;
194 if (numPartsExpected == 0) numPartsExpected = 1; 185 if (numPartsExpected == 0) numPartsExpected = 1;
195 186
196 expect(Future.wait([ 187 expect(
197 testCompletePartAfterCancel(data, numPartsExpected), 188 Future.wait([
198 testCompletePartAfterCancel(data, numPartsExpected, 10), 189 testCompletePartAfterCancel(data, numPartsExpected),
199 testCompletePartAfterCancel(data, numPartsExpected, 2), 190 testCompletePartAfterCancel(data, numPartsExpected, 10),
200 testCompletePartAfterCancel(data, numPartsExpected, 1), 191 testCompletePartAfterCancel(data, numPartsExpected, 2),
201 ]), completes); 192 testCompletePartAfterCancel(data, numPartsExpected, 1),
193 ]),
194 completes);
202 }); 195 });
203 } 196 }
204 } 197 }
205 198
206 void _testParse(String message, 199 void _testParse(String message, String boundary,
207 String boundary, 200 [List<Map> expectedHeaders, List expectedParts, bool expectError = false]) {
208 [List<Map> expectedHeaders, 201 _runParseTest(message, boundary, TestMode.IMMEDIATE_LISTEN, expectedHeaders,
209 List expectedParts, 202 expectedParts, expectError);
210 bool expectError = false]) { 203 _runParseTest(message, boundary, TestMode.DELAY_LISTEN, expectedHeaders,
211 _runParseTest( 204 expectedParts, expectError);
212 message, boundary, TestMode.IMMEDIATE_LISTEN, 205 _runParseTest(message, boundary, TestMode.PAUSE_RESUME, expectedHeaders,
213 expectedHeaders, expectedParts, expectError); 206 expectedParts, expectError);
214 _runParseTest(
215 message, boundary, TestMode.DELAY_LISTEN,
216 expectedHeaders, expectedParts, expectError);
217 _runParseTest(
218 message, boundary, TestMode.PAUSE_RESUME,
219 expectedHeaders, expectedParts, expectError);
220 } 207 }
221 208
222 void _testParseValid() { 209 void _testParseValid() {
223 // Empty message from Chrome form post. 210 // Empty message from Chrome form post.
224 var message = '------WebKitFormBoundaryU3FBruSkJKG0Yor1--\r\n'; 211 var message = '------WebKitFormBoundaryU3FBruSkJKG0Yor1--\r\n';
225 _testParse(message, "----WebKitFormBoundaryU3FBruSkJKG0Yor1", [], []); 212 _testParse(message, "----WebKitFormBoundaryU3FBruSkJKG0Yor1", [], []);
226 213
227 // Sample from Wikipedia. 214 // Sample from Wikipedia.
228 message = """ 215 message = """
229 This is a message with multiple parts in MIME format.\r 216 This is a message with multiple parts in MIME format.\r
230 --frontier\r 217 --frontier\r
231 Content-Type: text/plain\r 218 Content-Type: text/plain\r
232 \r 219 \r
233 This is the body of the message.\r 220 This is the body of the message.\r
234 --frontier\r 221 --frontier\r
235 Content-Type: application/octet-stream\r 222 Content-Type: application/octet-stream\r
236 Content-Transfer-Encoding: base64\r 223 Content-Transfer-Encoding: base64\r
237 \r 224 \r
238 PGh0bWw+CiAgPGhlYWQ+CiAgPC9oZWFkPgogIDxib2R5PgogICAgPHA+VGhpcyBpcyB0aGUg 225 PGh0bWw+CiAgPGhlYWQ+CiAgPC9oZWFkPgogIDxib2R5PgogICAgPHA+VGhpcyBpcyB0aGUg
239 Ym9keSBvZiB0aGUgbWVzc2FnZS48L3A+CiAgPC9ib2R5Pgo8L2h0bWw+Cg=\r 226 Ym9keSBvZiB0aGUgbWVzc2FnZS48L3A+CiAgPC9ib2R5Pgo8L2h0bWw+Cg=\r
240 --frontier--\r\n"""; 227 --frontier--\r\n""";
241 var headers1 = <String, String>{"content-type": "text/plain"}; 228 var headers1 = <String, String>{"content-type": "text/plain"};
242 var headers2 = <String, String>{"content-type": "application/octet-stream", 229 var headers2 = <String, String>{
243 "content-transfer-encoding": "base64"}; 230 "content-type": "application/octet-stream",
231 "content-transfer-encoding": "base64"
232 };
244 var body1 = "This is the body of the message."; 233 var body1 = "This is the body of the message.";
245 var body2 = """ 234 var body2 = """
246 PGh0bWw+CiAgPGhlYWQ+CiAgPC9oZWFkPgogIDxib2R5PgogICAgPHA+VGhpcyBpcyB0aGUg 235 PGh0bWw+CiAgPGhlYWQ+CiAgPC9oZWFkPgogIDxib2R5PgogICAgPHA+VGhpcyBpcyB0aGUg
247 Ym9keSBvZiB0aGUgbWVzc2FnZS48L3A+CiAgPC9ib2R5Pgo8L2h0bWw+Cg="""; 236 Ym9keSBvZiB0aGUgbWVzc2FnZS48L3A+CiAgPC9ib2R5Pgo8L2h0bWw+Cg=""";
248 _testParse(message, "frontier", [headers1, headers2], [body1, body2]); 237 _testParse(message, "frontier", [headers1, headers2], [body1, body2]);
249 238
250 // Sample from HTML 4.01 Specification. 239 // Sample from HTML 4.01 Specification.
251 message = """ 240 message = """
252 \r\n--AaB03x\r 241 \r\n--AaB03x\r
253 Content-Disposition: form-data; name=\"submit-name\"\r 242 Content-Disposition: form-data; name=\"submit-name\"\r
254 \r 243 \r
255 Larry\r 244 Larry\r
256 --AaB03x\r 245 --AaB03x\r
257 Content-Disposition: form-data; name=\"files\"; filename=\"file1.txt\"\r 246 Content-Disposition: form-data; name=\"files\"; filename=\"file1.txt\"\r
258 Content-Type: text/plain\r 247 Content-Type: text/plain\r
259 \r 248 \r
260 ... contents of file1.txt ...\r 249 ... contents of file1.txt ...\r
261 --AaB03x--\r\n"""; 250 --AaB03x--\r\n""";
262 headers1 = <String, String>{ 251 headers1 = <String, String>{
263 "content-disposition": "form-data; name=\"submit-name\""}; 252 "content-disposition": "form-data; name=\"submit-name\""
253 };
264 headers2 = <String, String>{ 254 headers2 = <String, String>{
265 "content-type": "text/plain", 255 "content-type": "text/plain",
266 "content-disposition": "form-data; name=\"files\"; filename=\"file1.txt\"" 256 "content-disposition": "form-data; name=\"files\"; filename=\"file1.txt\""
267 }; 257 };
268 body1 = "Larry"; 258 body1 = "Larry";
269 body2 = "... contents of file1.txt ..."; 259 body2 = "... contents of file1.txt ...";
270 _testParse(message, "AaB03x", [headers1, headers2], [body1, body2]); 260 _testParse(message, "AaB03x", [headers1, headers2], [body1, body2]);
271 261
272 // Longer form from submitting the following from Chrome. 262 // Longer form from submitting the following from Chrome.
273 // 263 //
274 // <html> 264 // <html>
275 // <body> 265 // <body>
276 // <FORM action="http://127.0.0.1:1234/" 266 // <FORM action="http://127.0.0.1:1234/"
(...skipping 22 matching lines...) Expand all
299 ------WebKitFormBoundaryQ3cgYAmGRF8yOeYB\r 289 ------WebKitFormBoundaryQ3cgYAmGRF8yOeYB\r
300 Content-Disposition: form-data; name=\"checkbox_input\"\r 290 Content-Disposition: form-data; name=\"checkbox_input\"\r
301 \r 291 \r
302 on\r 292 on\r
303 ------WebKitFormBoundaryQ3cgYAmGRF8yOeYB\r 293 ------WebKitFormBoundaryQ3cgYAmGRF8yOeYB\r
304 Content-Disposition: form-data; name=\"radio_input\"\r 294 Content-Disposition: form-data; name=\"radio_input\"\r
305 \r 295 \r
306 on\r 296 on\r
307 ------WebKitFormBoundaryQ3cgYAmGRF8yOeYB--\r\n"""; 297 ------WebKitFormBoundaryQ3cgYAmGRF8yOeYB--\r\n""";
308 headers1 = <String, String>{ 298 headers1 = <String, String>{
309 "content-disposition": "form-data; name=\"text_input\""}; 299 "content-disposition": "form-data; name=\"text_input\""
300 };
310 headers2 = <String, String>{ 301 headers2 = <String, String>{
311 "content-disposition": "form-data; name=\"password_input\""}; 302 "content-disposition": "form-data; name=\"password_input\""
303 };
312 var headers3 = <String, String>{ 304 var headers3 = <String, String>{
313 "content-disposition": "form-data; name=\"checkbox_input\""}; 305 "content-disposition": "form-data; name=\"checkbox_input\""
306 };
314 var headers4 = <String, String>{ 307 var headers4 = <String, String>{
315 "content-disposition": "form-data; name=\"radio_input\""}; 308 "content-disposition": "form-data; name=\"radio_input\""
309 };
316 body1 = "text"; 310 body1 = "text";
317 body2 = "password"; 311 body2 = "password";
318 var body3 = "on"; 312 var body3 = "on";
319 var body4 = "on"; 313 var body4 = "on";
320 _testParse(message, 314 _testParse(message, "----WebKitFormBoundaryQ3cgYAmGRF8yOeYB",
321 "----WebKitFormBoundaryQ3cgYAmGRF8yOeYB", 315 [headers1, headers2, headers3, headers4], [body1, body2, body3, body4]);
322 [headers1, headers2, headers3, headers4],
323 [body1, body2, body3, body4]);
324 316
325 // Same form from Firefox. 317 // Same form from Firefox.
326 message = """ 318 message = """
327 \r\n-----------------------------52284550912143824192005403738\r 319 \r\n-----------------------------52284550912143824192005403738\r
328 Content-Disposition: form-data; name=\"text_input\"\r 320 Content-Disposition: form-data; name=\"text_input\"\r
329 \r 321 \r
330 text\r 322 text\r
331 -----------------------------52284550912143824192005403738\r 323 -----------------------------52284550912143824192005403738\r
332 Content-Disposition: form-data; name=\"password_input\"\r 324 Content-Disposition: form-data; name=\"password_input\"\r
333 \r 325 \r
334 password\r 326 password\r
335 -----------------------------52284550912143824192005403738\r 327 -----------------------------52284550912143824192005403738\r
336 Content-Disposition: form-data; name=\"checkbox_input\"\r 328 Content-Disposition: form-data; name=\"checkbox_input\"\r
337 \r 329 \r
338 on\r 330 on\r
339 -----------------------------52284550912143824192005403738\r 331 -----------------------------52284550912143824192005403738\r
340 Content-Disposition: form-data; name=\"radio_input\"\r 332 Content-Disposition: form-data; name=\"radio_input\"\r
341 \r 333 \r
342 on\r 334 on\r
343 -----------------------------52284550912143824192005403738--\r\n"""; 335 -----------------------------52284550912143824192005403738--\r\n""";
344 _testParse(message, 336 _testParse(
345 "---------------------------52284550912143824192005403738", 337 message,
346 [headers1, headers2, headers3, headers4], 338 "---------------------------52284550912143824192005403738",
347 [body1, body2, body3, body4]); 339 [headers1, headers2, headers3, headers4],
340 [body1, body2, body3, body4]);
348 341
349 // And Internet Explorer 342 // And Internet Explorer
350 message = """ 343 message = """
351 \r\n-----------------------------7dc8f38c60326\r 344 \r\n-----------------------------7dc8f38c60326\r
352 Content-Disposition: form-data; name=\"text_input\"\r 345 Content-Disposition: form-data; name=\"text_input\"\r
353 \r 346 \r
354 text\r 347 text\r
355 -----------------------------7dc8f38c60326\r 348 -----------------------------7dc8f38c60326\r
356 Content-Disposition: form-data; name=\"password_input\"\r 349 Content-Disposition: form-data; name=\"password_input\"\r
357 \r 350 \r
358 password\r 351 password\r
359 -----------------------------7dc8f38c60326\r 352 -----------------------------7dc8f38c60326\r
360 Content-Disposition: form-data; name=\"checkbox_input\"\r 353 Content-Disposition: form-data; name=\"checkbox_input\"\r
361 \r 354 \r
362 on\r 355 on\r
363 -----------------------------7dc8f38c60326\r 356 -----------------------------7dc8f38c60326\r
364 Content-Disposition: form-data; name=\"radio_input\"\r 357 Content-Disposition: form-data; name=\"radio_input\"\r
365 \r 358 \r
366 on\r 359 on\r
367 -----------------------------7dc8f38c60326--\r\n"""; 360 -----------------------------7dc8f38c60326--\r\n""";
368 _testParse(message, 361 _testParse(message, "---------------------------7dc8f38c60326",
369 "---------------------------7dc8f38c60326", 362 [headers1, headers2, headers3, headers4], [body1, body2, body3, body4]);
370 [headers1, headers2, headers3, headers4],
371 [body1, body2, body3, body4]);
372 363
373 // Test boundary prefix inside prefix and content. 364 // Test boundary prefix inside prefix and content.
374 message = """ 365 message = """
375 -\r 366 -\r
376 --\r 367 --\r
377 --b\r 368 --b\r
378 --bo\r 369 --bo\r
379 --bou\r 370 --bou\r
380 --boun\r 371 --boun\r
381 --bound\r 372 --bound\r
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 \r 447 \r
457 Body2\r 448 Body2\r
458 --xxx\r\n"""; 449 --xxx\r\n""";
459 _testParse(message, "xxx", null, [null, null], true); 450 _testParse(message, "xxx", null, [null, null], true);
460 } 451 }
461 452
462 void main() { 453 void main() {
463 _testParseValid(); 454 _testParseValid();
464 _testParseInvalid(); 455 _testParseInvalid();
465 } 456 }
OLDNEW
« no previous file with comments | « lib/src/mime_type.dart ('k') | test/mime_type_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698