Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 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 | 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 // Library tag to allow the test to run on Dartium. | 5 // Library tag to allow the test to run on Dartium. |
| 6 library base64_test; | 6 library base64_test; |
| 7 | 7 |
| 8 import 'dart:math'; | 8 import 'dart:math'; |
| 9 import 'dart:async'; | |
| 9 | 10 |
| 10 import "package:crypto/crypto.dart"; | 11 import "package:crypto/crypto.dart"; |
| 11 import "package:test/test.dart"; | 12 import "package:test/test.dart"; |
| 12 | 13 |
| 13 void main() { | 14 void main() { |
| 14 test('encoder', _testEncoder); | 15 test('encoder', _testEncoder); |
| 15 test('decoder', _testDecoder); | 16 test('decoder', _testDecoder); |
| 16 test('decoder for malformed input', _testDecoderForMalformedInput); | 17 test('decoder for malformed input', _testDecoderForMalformedInput); |
| 17 test('encode decode lists', _testEncodeDecodeLists); | 18 test('encode decode lists', _testEncodeDecodeLists); |
| 18 test('url safe encode-decode', _testUrlSafeEncodeDecode); | 19 test('url safe encode-decode', _testUrlSafeEncodeDecode); |
| 20 test('streaming encoder', _testStreamingEncoder); | |
| 21 test('streaming decoder', _testStreamingDecoder); | |
| 22 test('streaming decoder for malformed input', _testStreamingDecoderForMalforme dInput); | |
|
Søren Gjesse
2015/06/01 12:20:59
nit: Long line.
Alexander Ivanov
2015/06/03 09:19:47
Done.
| |
| 23 test('streaming encoder for different decompositions of a list of bytes', | |
| 24 _testStreamingEncoderForDecompositions); | |
| 25 test('streaming decoder for different decompositions of a string', | |
| 26 _testStreamingDecoderForDecompositions); | |
| 27 test('url safe streaming encoder/decoder', _testUrlSafeStreaming); | |
| 19 test('performance', _testPerformance); | 28 test('performance', _testPerformance); |
| 29 | |
| 30 | |
| 20 } | 31 } |
| 21 | 32 |
| 22 // Data from http://tools.ietf.org/html/rfc4648. | 33 // Data from http://tools.ietf.org/html/rfc4648. |
| 23 const _INPUTS = | 34 const _INPUTS = |
| 24 const [ '', 'f', 'fo', 'foo', 'foob', 'fooba', 'foobar']; | 35 const [ '', 'f', 'fo', 'foo', 'foob', 'fooba', 'foobar']; |
| 25 const _RESULTS = | 36 const _RESULTS = |
| 26 const [ '', 'Zg==', 'Zm8=', 'Zm9v', 'Zm9vYg==', 'Zm9vYmE=', 'Zm9vYmFy']; | 37 const [ '', 'Zg==', 'Zm8=', 'Zm9v', 'Zm9vYg==', 'Zm9vYmE=', 'Zm9vYmFy']; |
| 38 var _STREAMING_ENCODER_INPUT = | |
| 39 [[102, 102], [111, 102], | |
| 40 [111, 111, 102, 111, 111, 98, 102, 111, | |
| 41 111, 98, 97, 102, 111, 111, 98, 97, 114]]; | |
| 42 | |
| 43 const _STREAMING_ENCODED = 'ZmZvZm9vZm9vYmZvb2JhZm9vYmFy'; | |
| 44 const _STREAMING_DECODER_INPUT = | |
| 45 const ['YmFz', 'ZTY', '0I', 'GRlY29kZXI=']; | |
| 46 const _STREAMING_DECODED = | |
| 47 const [98, 97, 115, 101, 54, 52, 32, 100, 101, 99, 111, 100, 101, 114]; | |
| 48 const _STREAMING_DECODER_INPUT_FOR_ZEROES = | |
| 49 const ['AAAA', 'AAA=', 'AA==', '']; | |
| 50 var _STREAMING_DECODED_ZEROES = [0, 0, 0, 0, 0, 0]; | |
| 51 | |
| 52 var _DECOMPOSITIONS_FOR_DECODING = [ | |
| 53 ["A", "", "BCD"], ["A", "BCD", "", ""], ["A", "B", "", "", "CD", ""], | |
| 54 ["", "A", "BC", "", "D"], ["", "AB", "C", "", "", "D"], ["AB", "CD", ""], | |
| 55 ["", "ABC", "", "D"], ["", "ABC", "D", ""], ["", "", "ABCD", ""], | |
| 56 ["A", "B", "C", "D"], ["", "A", "B", "C", "D", ""], | |
| 57 ["", "A", "B", "", "", "C", "", "D", ""]]; | |
| 58 | |
| 59 const _DECOMPOSITION_DECODED = const [0, 16, 131]; | |
| 60 | |
| 61 var _DECOMPOSITIONS_FOR_ENCODING = [ | |
| 62 [[196, 16], [], [158], [196]], | |
| 63 [[196, 16], [158, 196], [], []], | |
| 64 [[196], [], [16], [], [], [158], [], [196]], | |
| 65 [[196], [], [16], [158, 196], [], []], | |
| 66 [[], [196], [], [], [16, 158], [], [196]], | |
| 67 [[], [196], [16, 158, 196], []], | |
| 68 [[196, 16, 158], [], [], [196]], | |
| 69 [[196, 16, 158], [], [196], []], | |
| 70 [[196, 16, 158, 196], [], [], []]]; | |
| 71 | |
| 72 const _DECOMPOSITION_ENCODED = 'xBCexA=='; | |
| 27 | 73 |
| 28 // Test data with only zeroes. | 74 // Test data with only zeroes. |
| 29 var inputsWithZeroes = [[0, 0, 0], [0, 0], [0], []]; | 75 var inputsWithZeroes = [[0, 0, 0], [0, 0], [0], []]; |
| 30 const _RESULTS_WITH_ZEROS = const ['AAAA', 'AAA=', 'AA==', '']; | 76 const _RESULTS_WITH_ZEROS = const ['AAAA', 'AAA=', 'AA==', '']; |
| 31 | 77 |
| 32 const _LONG_LINE = | 78 const _LONG_LINE = |
| 33 "Man is distinguished, not only by his reason, but by this singular " | 79 "Man is distinguished, not only by his reason, but by this singular " |
| 34 "passion from other animals, which is a lust of the mind, that by a " | 80 "passion from other animals, which is a lust of the mind, that by a " |
| 35 "perseverance of delight in the continued and indefatigable generation " | 81 "perseverance of delight in the continued and indefatigable generation " |
| 36 "of knowledge, exceeds the short vehemence of any carnal pleasure."; | 82 "of knowledge, exceeds the short vehemence of any carnal pleasure."; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 52 "x5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz" | 98 "x5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz" |
| 53 "IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlci" | 99 "IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlci" |
| 54 "BhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg" | 100 "BhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg" |
| 55 "dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcm" | 101 "dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcm" |
| 56 "FuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu" | 102 "FuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu" |
| 57 "dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYX" | 103 "dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYX" |
| 58 "Rpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo" | 104 "Rpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo" |
| 59 "ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm" | 105 "ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm" |
| 60 "5hbCBwbGVhc3VyZS4="; | 106 "5hbCBwbGVhc3VyZS4="; |
| 61 | 107 |
| 62 void _testEncoder() { | 108 void _testEncoder() { |
|
Søren Gjesse
2015/06/01 12:20:59
Please keep the tests using CryptoUtils as long as
Alexander Ivanov
2015/06/03 09:19:47
I've added tests confirming that the old API is wo
| |
| 63 for (var i = 0; i < _INPUTS.length; i++) { | 109 for (var i = 0; i < _INPUTS.length; i++) { |
| 64 expect(CryptoUtils.bytesToBase64(_INPUTS[i].codeUnits), _RESULTS[i]); | 110 expect(BASE64.encode(_INPUTS[i].codeUnits), _RESULTS[i]); |
| 65 } | 111 } |
| 66 for (var i = 0; i < inputsWithZeroes.length; i++) { | 112 for (var i = 0; i < inputsWithZeroes.length; i++) { |
| 67 expect(CryptoUtils.bytesToBase64(inputsWithZeroes[i]), | 113 expect(BASE64.encode(inputsWithZeroes[i]), |
| 68 _RESULTS_WITH_ZEROS[i]); | 114 _RESULTS_WITH_ZEROS[i]); |
| 69 } | 115 } |
| 70 expect( | 116 expect(BASE64.encode(_LONG_LINE.codeUnits, addLineSeparator : true), |
| 71 CryptoUtils.bytesToBase64(_LONG_LINE.codeUnits, addLineSeparator : true), | 117 _LONG_LINE_RESULT); |
| 72 _LONG_LINE_RESULT); | 118 expect(BASE64.encode(_LONG_LINE.codeUnits), |
| 73 expect(CryptoUtils.bytesToBase64(_LONG_LINE.codeUnits), | 119 _LONG_LINE_RESULT_NO_BREAK); |
| 74 _LONG_LINE_RESULT_NO_BREAK); | |
| 75 } | 120 } |
| 76 | 121 |
| 77 void _testDecoder() { | 122 void _testDecoder() { |
| 78 for (var i = 0; i < _RESULTS.length; i++) { | 123 for (var i = 0; i < _RESULTS.length; i++) { |
| 79 expect( | 124 expect( |
| 80 new String.fromCharCodes(CryptoUtils.base64StringToBytes(_RESULTS[i])), | 125 new String.fromCharCodes(BASE64.decode(_RESULTS[i])), |
| 81 _INPUTS[i]); | 126 _INPUTS[i]); |
| 82 } | 127 } |
| 128 | |
| 83 for (var i = 0; i < _RESULTS_WITH_ZEROS.length; i++) { | 129 for (var i = 0; i < _RESULTS_WITH_ZEROS.length; i++) { |
| 84 expect(CryptoUtils.base64StringToBytes(_RESULTS_WITH_ZEROS[i]), | 130 expect(BASE64.decode(_RESULTS_WITH_ZEROS[i]), |
| 85 inputsWithZeroes[i]); | 131 inputsWithZeroes[i]); |
| 86 } | 132 } |
| 87 var longLineDecoded = CryptoUtils.base64StringToBytes(_LONG_LINE_RESULT); | 133 |
| 134 var longLineDecoded = BASE64.decode(_LONG_LINE_RESULT); | |
| 88 expect(new String.fromCharCodes(longLineDecoded), _LONG_LINE); | 135 expect(new String.fromCharCodes(longLineDecoded), _LONG_LINE); |
| 89 var longLineResultNoBreak = | 136 |
| 90 CryptoUtils.base64StringToBytes(_LONG_LINE_RESULT); | 137 var longLineResultNoBreak = BASE64.decode(_LONG_LINE_RESULT); |
| 91 expect(new String.fromCharCodes(longLineResultNoBreak), _LONG_LINE); | 138 expect(new String.fromCharCodes(longLineResultNoBreak), _LONG_LINE); |
| 92 } | 139 } |
| 93 | 140 |
| 141 Future _testStreamingEncoder() async { | |
| 142 expect( | |
| 143 await new Stream.fromIterable(_STREAMING_ENCODER_INPUT) | |
| 144 .transform(BASE64.encoder) | |
| 145 .join(), | |
| 146 _STREAMING_ENCODED); | |
| 147 } | |
| 148 | |
| 149 Future _testStreamingDecoder() async { | |
| 150 expect( | |
| 151 await new Stream.fromIterable(_STREAMING_DECODER_INPUT) | |
| 152 .transform(BASE64.decoder) | |
| 153 .expand((l) => l) | |
| 154 .toList(), | |
| 155 _STREAMING_DECODED); | |
| 156 | |
| 157 expect( | |
| 158 await new Stream.fromIterable(_STREAMING_DECODER_INPUT_FOR_ZEROES) | |
| 159 .transform(BASE64.decoder) | |
| 160 .expand((l) => l) | |
| 161 .toList(), | |
| 162 _STREAMING_DECODED_ZEROES); | |
| 163 } | |
| 164 | |
| 165 Future _testStreamingDecoderForMalformedInput() async { | |
| 166 expect(new Stream.fromIterable(['ABz']) | |
| 167 .transform(BASE64.decoder) | |
| 168 .toList(), | |
| 169 throwsFormatException); | |
| 170 | |
| 171 expect(new Stream.fromIterable(['AB', 'Lx', 'z', 'xx']) | |
| 172 .transform(BASE64.decoder) | |
| 173 .toList(), | |
| 174 throwsFormatException); | |
| 175 } | |
| 176 | |
| 177 Future _testStreamingEncoderForDecompositions() async { | |
| 178 for(var decomposition in _DECOMPOSITIONS_FOR_ENCODING) { | |
| 179 expect( | |
| 180 await new Stream.fromIterable(decomposition) | |
| 181 .transform(BASE64.encoder) | |
| 182 .join(), | |
| 183 _DECOMPOSITION_ENCODED); | |
| 184 } | |
| 185 } | |
| 186 | |
| 187 Future _testStreamingDecoderForDecompositions() async { | |
| 188 for(var decomposition in _DECOMPOSITIONS_FOR_DECODING) { | |
| 189 expect( | |
| 190 await new Stream.fromIterable(decomposition) | |
| 191 .transform(BASE64.decoder) | |
| 192 .expand((x) => x) | |
| 193 .toList(), | |
| 194 _DECOMPOSITION_DECODED); | |
| 195 } | |
| 196 } | |
| 197 | |
| 94 void _testDecoderForMalformedInput() { | 198 void _testDecoderForMalformedInput() { |
| 95 expect(() { | 199 expect(() { |
| 96 CryptoUtils.base64StringToBytes('AB~'); | 200 BASE64.decode('AB~'); |
| 97 }, throwsFormatException); | 201 }, throwsFormatException); |
| 98 | 202 |
| 99 expect(() { | 203 expect(() { |
| 100 CryptoUtils.base64StringToBytes('A'); | 204 BASE64.decode('A'); |
| 101 }, throwsFormatException); | 205 }, throwsFormatException); |
| 102 } | 206 } |
| 103 | 207 |
| 208 Future _testUrlSafeStreaming() async { | |
| 209 String encUrlSafe = '-_A='; | |
| 210 List<List<int>> dec = [BASE64.decode('+/A=')]; | |
| 211 var streamedResult = await new Stream.fromIterable(dec) | |
| 212 .transform(new Base64Encoder(urlSafe: true)).join(); | |
| 213 | |
| 214 expect(streamedResult, encUrlSafe); | |
| 215 } | |
| 216 | |
| 104 void _testUrlSafeEncodeDecode() { | 217 void _testUrlSafeEncodeDecode() { |
| 105 List<int> decUrlSafe = CryptoUtils.base64StringToBytes('-_A='); | 218 List<int> decUrlSafe = BASE64.decode('-_A='); |
| 106 List<int> dec = CryptoUtils.base64StringToBytes('+/A='); | 219 List<int> dec = BASE64.decode('+/A='); |
| 107 expect(decUrlSafe, orderedEquals(dec)); | 220 expect(decUrlSafe, orderedEquals(dec)); |
| 108 expect(CryptoUtils.bytesToBase64(dec, urlSafe: true), '-_A='); | 221 expect(BASE64.encode(dec, urlSafe: true), '-_A='); |
|
Søren Gjesse
2015/06/01 12:20:59
I am not sure here. Related to the padding charact
Alexander Ivanov
2015/06/03 09:19:47
We add the option to encode the padding character
| |
| 109 expect(CryptoUtils.bytesToBase64(dec), '+/A='); | 222 expect(BASE64.encode(dec), '+/A='); |
| 110 } | 223 } |
| 111 | 224 |
| 112 void _testEncodeDecodeLists() { | 225 void _testEncodeDecodeLists() { |
| 113 for (int i = 0; i < 10; i++) { | 226 for (int i = 0; i < 10; i++) { |
| 114 for (int j = 0; j < 256 - i; j++) { | 227 for (int j = 0; j < 256 - i; j++) { |
| 115 List<int> x = new List<int>(i); | 228 List<int> x = new List<int>(i); |
| 116 for (int k = 0; k < i; k++) { | 229 for (int k = 0; k < i; k++) { |
| 117 x[k] = j; | 230 x[k] = j; |
| 118 } | 231 } |
| 119 var enc = CryptoUtils.bytesToBase64(x); | 232 var enc = BASE64.encode(x); |
| 120 var dec = CryptoUtils.base64StringToBytes(enc); | 233 var dec = BASE64.decode(enc); |
| 121 expect(dec, orderedEquals(x)); | 234 expect(dec, orderedEquals(x)); |
| 122 } | 235 } |
| 123 } | 236 } |
| 124 } | 237 } |
| 125 | 238 |
| 126 void _fillRandom(List<int> l) { | 239 void _fillRandom(List<int> l) { |
| 127 var random = new Random(0xBABE); | 240 var random = new Random(0xBABE); |
| 128 for (int j = 0; j < l.length; j++) { | 241 for (int j = 0; j < l.length; j++) { |
| 129 l[j] = random.nextInt(255); | 242 l[j] = random.nextInt(255); |
| 130 } | 243 } |
| 131 } | 244 } |
| 132 | 245 |
| 133 void _testPerformance() { | 246 void _testPerformance() { |
| 134 var l = new List<int>(1024); | 247 var l = new List<int>(1024); |
| 135 var iters = 5000; | 248 var iters = 5000; |
| 136 _fillRandom(l); | 249 _fillRandom(l); |
| 137 String enc; | 250 String enc; |
| 138 var w = new Stopwatch()..start(); | 251 var w = new Stopwatch()..start(); |
| 139 for( int i = 0; i < iters; ++i ) { | 252 for( int i = 0; i < iters; ++i ) { |
| 140 enc = CryptoUtils.bytesToBase64(l); | 253 enc = BASE64.encode(l); |
| 141 } | 254 } |
| 142 int ms = w.elapsedMilliseconds; | 255 int ms = w.elapsedMilliseconds; |
| 143 int perSec = (iters * l.length) * 1000 ~/ ms; | 256 int perSec = (iters * l.length) * 1000 ~/ ms; |
| 144 // print("Encode 1024 bytes for $iters times: $ms msec. $perSec b/s"); | 257 // print("Encode 1024 bytes for $iters times: $ms msec. $perSec b/s"); |
| 145 w..reset(); | 258 w..reset(); |
| 146 for( int i = 0; i < iters; ++i ) { | 259 for( int i = 0; i < iters; ++i ) { |
| 147 CryptoUtils.base64StringToBytes(enc); | 260 BASE64.decode(enc); |
| 148 } | 261 } |
| 149 ms = w.elapsedMilliseconds; | 262 ms = w.elapsedMilliseconds; |
| 150 perSec = (iters * l.length) * 1000 ~/ ms; | 263 perSec = (iters * l.length) * 1000 ~/ ms; |
| 151 // print('''Decode into ${l.length} bytes for $iters | 264 // ('''Decode into ${l.length} bytes for $iters |
| 152 // times: $ms msec. $perSec b/s'''); | 265 // times: $ms msec. $perSec b/s'''); |
| 153 } | 266 } |
| OLD | NEW |