|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 const byteStreams = require("sdk/io/byte-streams"); |
|
6 const file = require("sdk/io/file"); |
|
7 const { pathFor } = require("sdk/system"); |
|
8 const { Loader } = require("sdk/test/loader"); |
|
9 |
|
10 const STREAM_CLOSED_ERROR = new RegExp("The stream is closed and cannot be used."); |
|
11 |
|
12 // This should match the constant of the same name in byte-streams.js. |
|
13 const BUFFER_BYTE_LEN = 0x8000; |
|
14 |
|
15 exports.testWriteRead = function (assert) { |
|
16 let fname = dataFileFilename(); |
|
17 |
|
18 // Write a small string less than the stream's buffer size... |
|
19 let str = "exports.testWriteRead data!"; |
|
20 let stream = open(assert, fname, true); |
|
21 assert.ok(!stream.closed, "stream.closed after open should be false"); |
|
22 stream.write(str); |
|
23 stream.close(); |
|
24 assert.ok(stream.closed, "Stream should be closed after stream.close"); |
|
25 assert.throws(function () stream.write("This shouldn't be written!"), |
|
26 STREAM_CLOSED_ERROR, |
|
27 "stream.write after close should raise error"); |
|
28 |
|
29 // ... and read it. |
|
30 stream = open(assert, fname); |
|
31 assert.equal(stream.read(), str, |
|
32 "stream.read should return string written"); |
|
33 assert.equal(stream.read(), "", |
|
34 "stream.read at EOS should return empty string"); |
|
35 stream.close(); |
|
36 assert.ok(stream.closed, "Stream should be closed after stream.close"); |
|
37 assert.throws(function () stream.read(), |
|
38 STREAM_CLOSED_ERROR, |
|
39 "stream.read after close should raise error"); |
|
40 |
|
41 file.remove(fname); |
|
42 }; |
|
43 |
|
44 // Write a big string many times the size of the stream's buffer and read it. |
|
45 exports.testWriteReadBig = function (assert) { |
|
46 let str = ""; |
|
47 let bufLen = BUFFER_BYTE_LEN; |
|
48 let fileSize = bufLen * 10; |
|
49 for (let i = 0; i < fileSize; i++) |
|
50 str += i % 10; |
|
51 let fname = dataFileFilename(); |
|
52 let stream = open(assert, fname, true); |
|
53 stream.write(str); |
|
54 stream.close(); |
|
55 stream = open(assert, fname); |
|
56 assert.equal(stream.read(), str, |
|
57 "stream.read should return string written"); |
|
58 stream.close(); |
|
59 file.remove(fname); |
|
60 }; |
|
61 |
|
62 // The same, but write and read in chunks. |
|
63 exports.testWriteReadChunks = function (assert) { |
|
64 let str = ""; |
|
65 let bufLen = BUFFER_BYTE_LEN; |
|
66 let fileSize = bufLen * 10; |
|
67 for (let i = 0; i < fileSize; i++) |
|
68 str += i % 10; |
|
69 let fname = dataFileFilename(); |
|
70 let stream = open(assert, fname, true); |
|
71 let i = 0; |
|
72 while (i < str.length) { |
|
73 // Use a chunk length that spans buffers. |
|
74 let chunk = str.substr(i, bufLen + 1); |
|
75 stream.write(chunk); |
|
76 i += bufLen + 1; |
|
77 } |
|
78 stream.close(); |
|
79 stream = open(assert, fname); |
|
80 let readStr = ""; |
|
81 bufLen = BUFFER_BYTE_LEN; |
|
82 let readLen = bufLen + 1; |
|
83 do { |
|
84 var frag = stream.read(readLen); |
|
85 readStr += frag; |
|
86 } while (frag); |
|
87 stream.close(); |
|
88 assert.equal(readStr, str, |
|
89 "stream.write and read in chunks should work as expected"); |
|
90 file.remove(fname); |
|
91 }; |
|
92 |
|
93 exports.testReadLengths = function (assert) { |
|
94 let fname = dataFileFilename(); |
|
95 let str = "exports.testReadLengths data!"; |
|
96 let stream = open(assert, fname, true); |
|
97 stream.write(str); |
|
98 stream.close(); |
|
99 |
|
100 stream = open(assert, fname); |
|
101 assert.equal(stream.read(str.length * 1000), str, |
|
102 "stream.read with big byte length should return string " + |
|
103 "written"); |
|
104 stream.close(); |
|
105 |
|
106 stream = open(assert, fname); |
|
107 assert.equal(stream.read(0), "", |
|
108 "string.read with zero byte length should return empty " + |
|
109 "string"); |
|
110 stream.close(); |
|
111 |
|
112 stream = open(assert, fname); |
|
113 assert.equal(stream.read(-1), "", |
|
114 "string.read with negative byte length should return " + |
|
115 "empty string"); |
|
116 stream.close(); |
|
117 |
|
118 file.remove(fname); |
|
119 }; |
|
120 |
|
121 exports.testTruncate = function (assert) { |
|
122 let fname = dataFileFilename(); |
|
123 let str = "exports.testReadLengths data!"; |
|
124 let stream = open(assert, fname, true); |
|
125 stream.write(str); |
|
126 stream.close(); |
|
127 |
|
128 stream = open(assert, fname); |
|
129 assert.equal(stream.read(), str, |
|
130 "stream.read should return string written"); |
|
131 stream.close(); |
|
132 |
|
133 stream = open(assert, fname, true); |
|
134 stream.close(); |
|
135 |
|
136 stream = open(assert, fname); |
|
137 assert.equal(stream.read(), "", |
|
138 "stream.read after truncate should be empty"); |
|
139 stream.close(); |
|
140 |
|
141 file.remove(fname); |
|
142 }; |
|
143 |
|
144 exports.testUnload = function (assert) { |
|
145 let loader = Loader(module); |
|
146 let file = loader.require("sdk/io/file"); |
|
147 |
|
148 let filename = dataFileFilename("temp-b"); |
|
149 let stream = file.open(filename, "wb"); |
|
150 |
|
151 loader.unload(); |
|
152 assert.ok(stream.closed, "Stream should be closed after module unload"); |
|
153 }; |
|
154 |
|
155 // Returns the name of a file that should be used to test writing and reading. |
|
156 function dataFileFilename() { |
|
157 return file.join(pathFor("ProfD"), "test-byte-streams-data"); |
|
158 } |
|
159 |
|
160 // Opens and returns the given file and ensures it's of the correct class. |
|
161 function open(assert, filename, forWriting) { |
|
162 let stream = file.open(filename, forWriting ? "wb" : "b"); |
|
163 let klass = forWriting ? "ByteWriter" : "ByteReader"; |
|
164 assert.ok(stream instanceof byteStreams[klass], |
|
165 "Opened stream should be a " + klass); |
|
166 return stream; |
|
167 } |
|
168 |
|
169 require('sdk/test').run(exports); |