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 // Testing file input stream, VM-only, standalone test. | 4 // Testing file input stream, VM-only, standalone test. |
5 | 5 |
6 import "dart:io"; | 6 import "dart:io"; |
7 import "dart:isolate"; | 7 import "dart:isolate"; |
8 | 8 |
9 // Helper method to be able to run the test from the runtime | 9 // Helper method to be able to run the test from the runtime |
10 // directory, or the top directory. | 10 // directory, or the top directory. |
11 String getFilename(String path) => | 11 String getFilename(String path) => |
12 new File(path).existsSync() ? path : '../$path'; | 12 new File(path).existsSync() ? path : '../$path'; |
13 | 13 |
14 void testStringInputStreamSync() { | 14 void testStringLineTransformer() { |
15 String fileName = getFilename("tests/standalone/io/readuntil_test.dat"); | 15 String fileName = getFilename("tests/standalone/io/readuntil_test.dat"); |
16 // File contains "Hello Dart\nwassup!\n" | 16 // File contains "Hello Dart\nwassup!\n" |
17 File file = new File(fileName); | 17 File file = new File(fileName); |
18 int linesRead = 0; | 18 int linesRead = 0; |
19 StringInputStream x = new StringInputStream(file.openInputStream()); | 19 var lineStream = file.openRead() |
20 x.onLine = () { | 20 .transform(new StringDecoder()) |
21 String line = x.readLine(); | 21 .transform(new LineTransformer()); |
| 22 lineStream.listen((line) { |
22 linesRead++; | 23 linesRead++; |
23 if (linesRead == 1) { | 24 if (linesRead == 1) { |
24 Expect.equals("Hello Dart", line); | 25 Expect.equals("Hello Dart", line); |
25 } else if (linesRead == 2) { | 26 } else if (linesRead == 2) { |
26 Expect.equals("wassup!", line); | 27 Expect.equals("wassup!", line); |
27 } else { | 28 } else { |
28 Expect.fail("More or less than 2 lines read ($linesRead lines read)."); | 29 Expect.fail("More or less than 2 lines read ($linesRead lines read)."); |
29 } | 30 } |
30 }; | 31 }); |
31 } | 32 } |
32 | 33 |
33 void testInputStreamAsync() { | 34 |
| 35 void testOpenStreamAsync() { |
| 36 var keepAlive = new ReceivePort(); |
34 String fileName = getFilename("tests/standalone/io/readuntil_test.dat"); | 37 String fileName = getFilename("tests/standalone/io/readuntil_test.dat"); |
35 // File contains "Hello Dart\nwassup!\n" | 38 // File contains "Hello Dart\nwassup!\n" |
36 var expected = "Hello Dart\nwassup!\n".charCodes; | 39 var expected = "Hello Dart\nwassup!\n".charCodes; |
37 InputStream x = (new File(fileName)).openInputStream(); | |
38 var byteCount = 0; | 40 var byteCount = 0; |
39 x.onData = () { | 41 (new File(fileName)).openRead().listen( |
40 Expect.equals(expected[byteCount], x.read(1)[0]); | 42 (d) => byteCount += d.length, |
41 byteCount++; | 43 onDone: () { |
42 }; | 44 Expect.equals(expected.length, byteCount); |
43 x.onClosed = () { | 45 keepAlive.close(); |
44 Expect.equals(expected.length, byteCount); | 46 }); |
45 }; | |
46 } | 47 } |
47 | 48 |
48 void testStringInputStreamAsync(String name, int length) { | 49 |
| 50 // Create a file that is big enough that a file stream will |
| 51 // read it in multiple chunks. |
| 52 int writeLongFileSync(File file) { |
| 53 file.createSync(); |
| 54 StringBuffer buffer = new StringBuffer(); |
| 55 for (var i = 0; i < 10000; i++) { |
| 56 buffer.add("Hello, world"); |
| 57 } |
| 58 file.writeAsStringSync(buffer.toString()); |
| 59 var length = file.lengthSync(); |
| 60 Expect.equals(buffer.length, length); |
| 61 return length; |
| 62 } |
| 63 |
| 64 |
| 65 void testInputStreamTruncate() { |
| 66 var keepAlive = new ReceivePort(); |
| 67 var temp = new Directory('').createTempSync(); |
| 68 var file = new File('${temp.path}/input_stream_truncate.txt'); |
| 69 var originalLength = writeLongFileSync(file); |
| 70 // Start streaming the file. Pause after first chunk. Truncate |
| 71 // underlying file and check that the streaming stops with or |
| 72 // without getting all data. |
| 73 var streamedBytes = 0; |
| 74 var subscription; |
| 75 subscription = file.openRead().listen( |
| 76 (d) { |
| 77 if (streamedBytes == 0) { |
| 78 subscription.pause(); |
| 79 // Truncate the file by opening it for writing. |
| 80 file.open(FileMode.WRITE).then((opened) { |
| 81 opened.close().then((_) { |
| 82 Expect.equals(0, file.lengthSync()); |
| 83 subscription.resume(); |
| 84 }); |
| 85 }); |
| 86 } |
| 87 streamedBytes += d.length; |
| 88 }, |
| 89 onDone: () { |
| 90 Expect.isTrue(streamedBytes > 0 && streamedBytes <= originalLength); |
| 91 temp.delete(recursive: true).then((_) => keepAlive.close()); |
| 92 }, |
| 93 onError: (e) { |
| 94 Expect.fail("Unexpected error"); |
| 95 }); |
| 96 } |
| 97 |
| 98 |
| 99 void testInputStreamDelete() { |
| 100 var keepAlive = new ReceivePort(); |
| 101 var temp = new Directory('').createTempSync(); |
| 102 var file = new File('${temp.path}/input_stream_delete.txt'); |
| 103 var originalLength = writeLongFileSync(file); |
| 104 // Start streaming the file. Pause after first chunk. Truncate |
| 105 // underlying file and check that the streaming stops with or |
| 106 // without getting all data. |
| 107 var streamedBytes = 0; |
| 108 var subscription; |
| 109 subscription = file.openRead().listen( |
| 110 (d) { |
| 111 if (streamedBytes == 0) { |
| 112 subscription.pause(); |
| 113 // Delete the underlying file by opening it for writing. |
| 114 file.delete() |
| 115 .then((deleted) { |
| 116 Expect.isFalse(deleted.existsSync()); |
| 117 subscription.resume(); |
| 118 }) |
| 119 .catchError((e) { |
| 120 // On Windows, you cannot delete a file that is open |
| 121 // somewhere else. The stream has this file open |
| 122 // and therefore we get an error on deletion on Windows. |
| 123 Expect.equals('windows', Platform.operatingSystem); |
| 124 subscription.resume(); |
| 125 }); |
| 126 } |
| 127 streamedBytes += d.length; |
| 128 }, |
| 129 onDone: () { |
| 130 Expect.equals(originalLength, streamedBytes); |
| 131 temp.delete(recursive: true).then((_) => keepAlive.close()); |
| 132 }, |
| 133 onError: (e) { |
| 134 Expect.fail("Unexpected error"); |
| 135 }); |
| 136 } |
| 137 |
| 138 |
| 139 void testInputStreamAppend() { |
| 140 var keepAlive = new ReceivePort(); |
| 141 var temp = new Directory('').createTempSync(); |
| 142 var file = new File('${temp.path}/input_stream_append.txt'); |
| 143 var originalLength = writeLongFileSync(file); |
| 144 // Start streaming the file. Pause after first chunk. Append to |
| 145 // underlying file and check that the stream gets all the data. |
| 146 var streamedBytes = 0; |
| 147 var subscription; |
| 148 subscription = file.openRead().listen( |
| 149 (d) { |
| 150 if (streamedBytes == 0) { |
| 151 subscription.pause(); |
| 152 // Double the length of the underlying file. |
| 153 file.readAsBytes().then((bytes) { |
| 154 file.writeAsBytes(bytes, FileMode.APPEND).then((_) { |
| 155 Expect.equals(2 * originalLength, file.lengthSync()); |
| 156 subscription.resume(); |
| 157 }); |
| 158 }); |
| 159 } |
| 160 streamedBytes += d.length; |
| 161 }, |
| 162 onDone: () { |
| 163 Expect.equals(2 * originalLength, streamedBytes); |
| 164 temp.delete(recursive: true).then((_) => keepAlive.close()); |
| 165 }, |
| 166 onError: (e) { |
| 167 Expect.fail("Unexpected error"); |
| 168 }); |
| 169 } |
| 170 |
| 171 |
| 172 void testStringLineTransformerEnding(String name, int length) { |
49 String fileName = getFilename("tests/standalone/io/$name"); | 173 String fileName = getFilename("tests/standalone/io/$name"); |
50 // File contains 10 lines. | 174 // File contains 10 lines. |
51 File file = new File(fileName); | 175 File file = new File(fileName); |
52 Expect.equals(length, file.openSync().lengthSync()); | 176 Expect.equals(length, file.openSync().lengthSync()); |
53 StringInputStream x = new StringInputStream(file.openInputStream()); | 177 var lineStream = file.openRead() |
| 178 .transform(new StringDecoder()) |
| 179 .transform(new LineTransformer()); |
54 int lineCount = 0; | 180 int lineCount = 0; |
55 x.onLine = () { | 181 lineStream.listen( |
56 var line = x.readLine(); | 182 (line) { |
57 lineCount++; | 183 lineCount++; |
58 Expect.isTrue(lineCount <= 10); | 184 Expect.isTrue(lineCount <= 10); |
59 if (line[0] != "#") { | 185 if (line[0] != "#") { |
60 Expect.equals("Line $lineCount", line); | 186 Expect.equals("Line $lineCount", line); |
61 } | 187 } |
62 }; | 188 }, |
63 x.onClosed = () { | 189 onDone: () { |
64 Expect.equals(10, lineCount); | 190 Expect.equals(10, lineCount); |
65 }; | 191 }); |
66 } | |
67 | |
68 void testChunkedInputStream() { | |
69 // Force the test to timeout if it does not finish. | |
70 ReceivePort done = new ReceivePort(); | |
71 done.receive((message, replyTo) { done.close(); }); | |
72 | |
73 String fileName = getFilename("tests/standalone/io/readuntil_test.dat"); | |
74 // File contains 19 bytes ("Hello Dart\nwassup!") | |
75 File file = new File(fileName); | |
76 ChunkedInputStream x = new ChunkedInputStream(file.openInputStream()); | |
77 x.chunkSize = 9; | |
78 x.onData = () { | |
79 List<int> chunk = x.read(); | |
80 Expect.equals(9, chunk.length); | |
81 x.chunkSize = 5; | |
82 x.onData = () { | |
83 chunk = x.read(); | |
84 Expect.equals(5, chunk.length); | |
85 x.onData = () { | |
86 chunk = x.read(); | |
87 Expect.equals(5, chunk.length); | |
88 chunk = x.read(); | |
89 Expect.equals(null, chunk); | |
90 done.toSendPort().send(null); | |
91 }; | |
92 }; | |
93 }; | |
94 } | |
95 | |
96 void testUnreadyInputStream() { | |
97 String fileName = getFilename("tests/standalone/io/readuntil_test.dat"); | |
98 var expected = "Hello Dart\nwassup!\n".charCodes; | |
99 InputStream x = (new File(fileName)).openInputStream(); | |
100 List<int> buffer = new List<int>.fixedLength(100); | |
101 | |
102 x.onData = () { | |
103 Expect.fail("Input stream closed before opening called onData handler."); | |
104 }; | |
105 | |
106 x.onClosed = () { }; | |
107 | |
108 // Called before stream is ready. | |
109 int read = x.readInto(buffer); | |
110 Expect.equals(0, read); | |
111 | |
112 // Called before stream is ready. | |
113 x.close(); | |
114 } | 192 } |
115 | 193 |
116 | 194 |
117 main() { | 195 main() { |
118 testStringInputStreamSync(); | 196 testStringLineTransformer(); |
119 testInputStreamAsync(); | 197 testOpenStreamAsync(); |
| 198 testInputStreamTruncate(); |
| 199 testInputStreamDelete(); |
| 200 testInputStreamAppend(); |
120 // Check the length of these files as both are text files where one | 201 // Check the length of these files as both are text files where one |
121 // is without a terminating line separator which can easily be added | 202 // is without a terminating line separator which can easily be added |
122 // back if accidentally opened in a text editor. | 203 // back if accidentally opened in a text editor. |
123 testStringInputStreamAsync("readline_test1.dat", 111); | 204 testStringLineTransformerEnding("readline_test1.dat", 111); |
124 testStringInputStreamAsync("readline_test2.dat", 114); | 205 testStringLineTransformerEnding("readline_test2.dat", 114); |
125 testChunkedInputStream(); | |
126 testUnreadyInputStream(); | |
127 } | 206 } |
OLD | NEW |