| 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, |
| 12 int chunkSize, |
| 13 StreamController<List<int>> controller) { |
| 14 if (chunkSize == -1) chunkSize = data.length; |
| 15 |
| 16 int written = 0; |
| 17 for (int pos = 0; pos < data.length; pos += chunkSize) { |
| 18 int remaining = data.length - pos; |
| 19 int writeLength = min(chunkSize, remaining); |
| 20 controller.add(data.sublist(pos, pos + writeLength)); |
| 21 written += writeLength; |
| 22 } |
| 23 controller.close(); |
| 24 } |
| 25 |
| 26 |
| 11 void _testParse(String message, | 27 void _testParse(String message, |
| 12 String boundary, | 28 String boundary, |
| 13 [List<Map> expectedHeaders, | 29 [List<Map> expectedHeaders, |
| 14 List expectedParts, | 30 List expectedParts, |
| 15 bool expectError = false]) { | 31 bool expectError = false]) { |
| 16 Future testWrite(List<int> data, [int chunkSize = -1]) { | 32 Future testWrite(List<int> data, [int chunkSize = -1]) { |
| 17 StreamController controller = new StreamController(sync: true); | 33 StreamController controller = new StreamController(sync: true); |
| 18 | 34 |
| 19 var stream = controller.stream.transform( | 35 var stream = controller.stream.transform( |
| 20 new MimeMultipartTransformer(boundary)); | 36 new MimeMultipartTransformer(boundary)); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 34 })); | 50 })); |
| 35 }, onError: (error) { | 51 }, onError: (error) { |
| 36 if (!expectError) throw error; | 52 if (!expectError) throw error; |
| 37 }, onDone: () { | 53 }, onDone: () { |
| 38 if (expectedParts != null) { | 54 if (expectedParts != null) { |
| 39 expect(i, equals(expectedParts.length)); | 55 expect(i, equals(expectedParts.length)); |
| 40 } | 56 } |
| 41 Future.wait(futures).then(completer.complete); | 57 Future.wait(futures).then(completer.complete); |
| 42 }); | 58 }); |
| 43 | 59 |
| 44 if (chunkSize == -1) chunkSize = data.length; | 60 _writeInChunks(data, chunkSize, controller); |
| 45 | |
| 46 int written = 0; | |
| 47 for (int pos = 0; pos < data.length; pos += chunkSize) { | |
| 48 int remaining = data.length - pos; | |
| 49 int writeLength = min(chunkSize, remaining); | |
| 50 controller.add(data.sublist(pos, pos + writeLength)); | |
| 51 written += writeLength; | |
| 52 } | |
| 53 controller.close(); | |
| 54 | 61 |
| 55 return completer.future; | 62 return completer.future; |
| 56 } | 63 } |
| 64 |
| 65 Future testFirstPartOnly(List<int> data, [int chunkSize = -1]) { |
| 66 var completer = new Completer(); |
| 67 var controller = new StreamController(sync: true); |
| 68 |
| 69 var stream = controller.stream.transform( |
| 70 new MimeMultipartTransformer(boundary)); |
| 71 |
| 72 var subscription; |
| 73 subscription = stream.first.then((multipart) { |
| 74 if (expectedHeaders != null) { |
| 75 expect(multipart.headers, equals(expectedHeaders[0])); |
| 76 } |
| 77 return (multipart.fold([], (b, d) => b..addAll(d)).then((data) { |
| 78 if (expectedParts != null && expectedParts[0] != null) { |
| 79 expect(data, equals(expectedParts[0].codeUnits)); |
| 80 } |
| 81 })); |
| 82 }).then((_) { |
| 83 completer.complete(); |
| 84 }); |
| 85 |
| 86 _writeInChunks(data, chunkSize, controller); |
| 87 |
| 88 return completer.future; |
| 89 } |
| 90 |
| 91 Future testCompletePartAfterCancel(List<int> data, |
| 92 int parts, |
| 93 [int chunkSize = -1]) { |
| 94 var completer = new Completer(); |
| 95 var controller = new StreamController(sync: true); |
| 96 var stream = controller.stream.transform( |
| 97 new MimeMultipartTransformer(boundary)); |
| 98 var subscription; |
| 99 int i = 0; |
| 100 var futures = []; |
| 101 subscription = stream.listen((multipart) { |
| 102 int partIndex = i; |
| 103 |
| 104 if (partIndex >= parts) { |
| 105 throw 'Expected no more parts, but got one.'; |
| 106 } |
| 107 |
| 108 if (expectedHeaders != null) { |
| 109 expect(multipart.headers, equals(expectedHeaders[partIndex])); |
| 110 } |
| 111 futures.add((multipart.fold([], (b, d) => b..addAll(d)).then((data) { |
| 112 if (expectedParts != null && expectedParts[partIndex] != null) { |
| 113 expect(data, equals(expectedParts[partIndex].codeUnits)); |
| 114 } |
| 115 }))); |
| 116 |
| 117 if (partIndex == (parts - 1)) { |
| 118 subscription.cancel(); |
| 119 Future.wait(futures).then(completer.complete); |
| 120 } |
| 121 i++; |
| 122 }); |
| 123 |
| 124 _writeInChunks(data, chunkSize, controller); |
| 125 |
| 126 return completer.future; |
| 127 } |
| 57 | 128 |
| 58 // Test parsing the data three times delivering the data in | 129 // Test parsing the data three times delivering the data in |
| 59 // different chunks. | 130 // different chunks. |
| 60 List<int> data = message.codeUnits; | 131 List<int> data = message.codeUnits; |
| 61 test('test', () { | 132 test('test', () { |
| 62 expect(Future.wait([ | 133 expect(Future.wait([ |
| 63 testWrite(data), | 134 testWrite(data), |
| 64 testWrite(data, 10), | 135 testWrite(data, 10), |
| 65 testWrite(data, 2), | 136 testWrite(data, 2), |
| 66 testWrite(data, 1)]), | 137 testWrite(data, 1), |
| 67 completes); | 138 ]), completes); |
| 68 }); | 139 }); |
| 140 |
| 141 if (expectedParts.length > 0) { |
| 142 test('test-first-part-only', () { |
| 143 expect(Future.wait([ |
| 144 testFirstPartOnly(data), |
| 145 testFirstPartOnly(data, 10), |
| 146 testFirstPartOnly(data, 2), |
| 147 testFirstPartOnly(data, 1), |
| 148 ]), completes); |
| 149 }); |
| 150 |
| 151 test('test-n-parts-only', () { |
| 152 int numPartsExpected = expectedParts.length - 1; |
| 153 if (numPartsExpected == 0) numPartsExpected = 1; |
| 154 |
| 155 expect(Future.wait([ |
| 156 testCompletePartAfterCancel(data, numPartsExpected), |
| 157 testCompletePartAfterCancel(data, numPartsExpected, 10), |
| 158 testCompletePartAfterCancel(data, numPartsExpected, 2), |
| 159 testCompletePartAfterCancel(data, numPartsExpected, 1), |
| 160 ]), completes); |
| 161 }); |
| 162 } |
| 69 } | 163 } |
| 70 | 164 |
| 71 void _testParseValid() { | 165 void _testParseValid() { |
| 72 // Empty message from Chrome form post. | 166 // Empty message from Chrome form post. |
| 73 var message = '------WebKitFormBoundaryU3FBruSkJKG0Yor1--\r\n'; | 167 var message = '------WebKitFormBoundaryU3FBruSkJKG0Yor1--\r\n'; |
| 74 _testParse(message, "----WebKitFormBoundaryU3FBruSkJKG0Yor1", [], []); | 168 _testParse(message, "----WebKitFormBoundaryU3FBruSkJKG0Yor1", [], []); |
| 75 | 169 |
| 76 // Sample from Wikipedia. | 170 // Sample from Wikipedia. |
| 77 message = """ | 171 message = """ |
| 78 This is a message with multiple parts in MIME format.\r | 172 This is a message with multiple parts in MIME format.\r |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 \r | 399 \r |
| 306 Body2\r | 400 Body2\r |
| 307 --xxx\r\n"""; | 401 --xxx\r\n"""; |
| 308 _testParse(message, "xxx", null, [null, null], true); | 402 _testParse(message, "xxx", null, [null, null], true); |
| 309 } | 403 } |
| 310 | 404 |
| 311 void main() { | 405 void main() { |
| 312 _testParseValid(); | 406 _testParseValid(); |
| 313 _testParseInvalid(); | 407 _testParseInvalid(); |
| 314 } | 408 } |
| OLD | NEW |