|  | // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file | 
|  | // for details. All rights reserved. Use of this source code is governed by a | 
|  | // BSD-style license that can be found in the LICENSE file. | 
|  |  | 
|  | library line_splitter_test; | 
|  |  | 
|  | import "package:expect/expect.dart"; | 
|  | import 'dart:async'; | 
|  | import 'dart:convert'; | 
|  | import 'dart:math' as MATH; | 
|  |  | 
|  | const lineTerminators = const ['\n', '\r', '\r\n']; | 
|  |  | 
|  | void main() { | 
|  | testSimpleConvert(); | 
|  | testSplit(); | 
|  | testSplitWithOffsets(); | 
|  | testManyLines(); | 
|  | testReadLine1(); | 
|  | testReadLine2(); | 
|  | testChunkedConversion(); | 
|  | } | 
|  |  | 
|  | void testManyLines() { | 
|  | int breakIndex = 0; | 
|  |  | 
|  | var inputs = const ['line1', 'line2', 'long line 3', ' line 4 ', 'l5']; | 
|  |  | 
|  | var buffer = inputs.fold(new StringBuffer(), (buff, e) { | 
|  | buff.write(e); | 
|  | buff.write(lineTerminators[breakIndex]); | 
|  |  | 
|  | breakIndex++; | 
|  | breakIndex = breakIndex % lineTerminators.length; | 
|  |  | 
|  | return buff; | 
|  | }); | 
|  |  | 
|  | var foo = _getLinesSliced(buffer.toString()); | 
|  | Expect.equals(inputs.join(), foo); | 
|  | } | 
|  |  | 
|  | String _getLinesSliced(String str) { | 
|  | late String lines; | 
|  | var stringSink = | 
|  | new StringConversionSink.withCallback((result) => lines = result); | 
|  | var sink = new LineSplitter().startChunkedConversion(stringSink); | 
|  |  | 
|  | const chunkSize = 3; | 
|  | var index = 0; | 
|  | while (index < str.length) { | 
|  | var end = MATH.min(str.length, index + chunkSize); | 
|  |  | 
|  | sink.addSlice(str, index, end, false); | 
|  | index += chunkSize; | 
|  | } | 
|  |  | 
|  | sink.close(); | 
|  | return lines; | 
|  | } | 
|  |  | 
|  | void testSimpleConvert() { | 
|  | var decoder = new LineSplitter(); | 
|  | for (var lf in lineTerminators) { | 
|  | var test = "line1${lf}line2${lf}line3"; | 
|  |  | 
|  | var result = decoder.convert(test); | 
|  |  | 
|  | Expect.listEquals(['line1', 'line2', 'line3'], result); | 
|  | } | 
|  |  | 
|  | var test = "Line1\nLine2\r\nLine3\rLine4\n\n\n\r\n\r\n\r\r"; | 
|  | var result = decoder.convert(test); | 
|  |  | 
|  | Expect.listEquals( | 
|  | ['Line1', 'Line2', 'Line3', 'Line4', '', '', '', '', '', ''], result); | 
|  | } | 
|  |  | 
|  | void testReadLine1() { | 
|  | var controller = new StreamController<List<int>>(sync: true); | 
|  | var stream = | 
|  | controller.stream.transform(utf8.decoder).transform(const LineSplitter()); | 
|  |  | 
|  | var stage = 0; | 
|  | var done = false; | 
|  |  | 
|  | void stringData(line) { | 
|  | Expect.equals(stage, 0); | 
|  | Expect.equals("Line", line); | 
|  | stage++; | 
|  | } | 
|  |  | 
|  | void streamClosed() { | 
|  | Expect.equals(1, stage); | 
|  | done = true; | 
|  | } | 
|  |  | 
|  | stream.listen(stringData, onDone: streamClosed); | 
|  |  | 
|  | // Note: codeUnits is fine. Text is ASCII. | 
|  | controller.add("Line".codeUnits); | 
|  | controller.close(); | 
|  | Expect.isTrue(done, 'should be done by now'); | 
|  | } | 
|  |  | 
|  | void testReadLine2() { | 
|  | var controller = new StreamController<List<int>>(sync: true); | 
|  |  | 
|  | var stream = | 
|  | controller.stream.transform(utf8.decoder).transform(const LineSplitter()); | 
|  |  | 
|  | var expectedLines = [ | 
|  | 'Line1', | 
|  | 'Line2', | 
|  | 'Line3', | 
|  | 'Line4', | 
|  | '', | 
|  | '', | 
|  | '', | 
|  | '', | 
|  | '', | 
|  | '', | 
|  | 'Line5', | 
|  | 'Line6' | 
|  | ]; | 
|  |  | 
|  | var index = 0; | 
|  |  | 
|  | stream.listen((line) { | 
|  | Expect.equals(expectedLines[index++], line); | 
|  | }); | 
|  |  | 
|  | // Note: codeUnits is fine. Text is ASCII. | 
|  | controller.add("Line1\nLine2\r\nLine3\rLi".codeUnits); | 
|  | controller.add("ne4\n".codeUnits); | 
|  | controller.add("\n\n\r\n\r\n\r\r".codeUnits); | 
|  | controller.add("Line5\r".codeUnits); | 
|  | controller.add("\nLine6\n".codeUnits); | 
|  | controller.close(); | 
|  | Expect.equals(expectedLines.length, index); | 
|  | } | 
|  |  | 
|  | void testSplit() { | 
|  | for (var lf in lineTerminators) { | 
|  | var test = "line1${lf}line2${lf}line3"; | 
|  | var result = LineSplitter.split(test).toList(); | 
|  | Expect.listEquals(['line1', 'line2', 'line3'], result); | 
|  | } | 
|  |  | 
|  | var test = "Line1\nLine2\r\nLine3\rLine4\n\n\n\r\n\r\n\r\r"; | 
|  | var result = LineSplitter.split(test).toList(); | 
|  |  | 
|  | Expect.listEquals( | 
|  | ['Line1', 'Line2', 'Line3', 'Line4', '', '', '', '', '', ''], result); | 
|  | } | 
|  |  | 
|  | void testSplitWithOffsets() { | 
|  | for (var lf in lineTerminators) { | 
|  | var test = "line1${lf}line2${lf}line3"; | 
|  | var i2 = 5 + lf.length; // index of "line2". | 
|  | Expect.equals(5 + lf.length, i2); | 
|  |  | 
|  | var result = LineSplitter.split(test, 4).toList(); | 
|  | Expect.listEquals(['1', 'line2', 'line3'], result); | 
|  |  | 
|  | result = LineSplitter.split(test, 5).toList(); | 
|  | Expect.listEquals(['', 'line2', 'line3'], result); | 
|  |  | 
|  | result = LineSplitter.split(test, i2).toList(); | 
|  | Expect.listEquals(['line2', 'line3'], result); | 
|  |  | 
|  | result = LineSplitter.split(test, 0, i2 + 2).toList(); | 
|  | Expect.listEquals(['line1', 'li'], result); | 
|  |  | 
|  | result = LineSplitter.split(test, i2, i2 + 5).toList(); | 
|  | Expect.listEquals(['line2'], result); | 
|  | } | 
|  |  | 
|  | var test = "Line1\nLine2\r\nLine3\rLine4\n\n\n\r\n\r\n\r\r"; | 
|  |  | 
|  | var result = LineSplitter.split(test).toList(); | 
|  |  | 
|  | Expect.listEquals( | 
|  | ['Line1', 'Line2', 'Line3', 'Line4', '', '', '', '', '', ''], result); | 
|  |  | 
|  | test = "a\n\nb\r\nc\n\rd\r\re\r\n\nf\r\n"; | 
|  | result = LineSplitter.split(test).toList(); | 
|  | Expect.listEquals(["a", "", "b", "c", "", "d", "", "e", "", "f"], result); | 
|  | } | 
|  |  | 
|  | void testChunkedConversion() { | 
|  | // Test any split of this complex string. | 
|  | var test = "a\n\nb\r\nc\n\rd\r\re\r\n\nf\rg\nh\r\n"; | 
|  | var result = ["a", "", "b", "c", "", "d", "", "e", "", "f", "g", "h"]; | 
|  | for (int i = 0; i < test.length; i++) { | 
|  | var output = []; | 
|  | var splitter = new LineSplitter(); | 
|  | var outSink = new ChunkedConversionSink<String>.withCallback(output.addAll); | 
|  | var sink = splitter.startChunkedConversion(outSink); | 
|  | sink.addSlice(test, 0, i, false); | 
|  | sink.addSlice(test, i, test.length, false); | 
|  | sink.close(); | 
|  | Expect.listEquals(result, output); | 
|  | } | 
|  |  | 
|  | // Test the string split into three parts in any way. | 
|  | for (int i = 0; i < test.length; i++) { | 
|  | for (int j = i; j < test.length; j++) { | 
|  | var output = []; | 
|  | var splitter = new LineSplitter(); | 
|  | var outSink = | 
|  | new ChunkedConversionSink<String>.withCallback(output.addAll); | 
|  | var sink = splitter.startChunkedConversion(outSink); | 
|  | sink.addSlice(test, 0, i, false); | 
|  | sink.addSlice(test, i, j, false); | 
|  | sink.addSlice(test, j, test.length, true); | 
|  | Expect.listEquals(result, output); | 
|  | } | 
|  | } | 
|  | } |