|
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 file = require("sdk/io/file"); |
|
6 const { pathFor } = require("sdk/system"); |
|
7 const { Loader } = require("sdk/test/loader"); |
|
8 |
|
9 const STREAM_CLOSED_ERROR = new RegExp("The stream is closed and cannot be used."); |
|
10 |
|
11 // This should match the constant of the same name in text-streams.js. |
|
12 const BUFFER_BYTE_LEN = 0x8000; |
|
13 |
|
14 exports.testWriteRead = function (assert) { |
|
15 let fname = dataFileFilename(); |
|
16 |
|
17 // Write a small string less than the stream's buffer size... |
|
18 let str = "exports.testWriteRead data!"; |
|
19 let stream = file.open(fname, "w"); |
|
20 assert.ok(!stream.closed, "stream.closed after open should be false"); |
|
21 stream.write(str); |
|
22 stream.close(); |
|
23 assert.ok(stream.closed, "stream.closed after close should be true"); |
|
24 assert.throws(function () stream.close(), |
|
25 STREAM_CLOSED_ERROR, |
|
26 "stream.close after already closed should raise error"); |
|
27 assert.throws(function () stream.write("This shouldn't be written!"), |
|
28 STREAM_CLOSED_ERROR, |
|
29 "stream.write after close should raise error"); |
|
30 |
|
31 // ... and read it. |
|
32 stream = file.open(fname); |
|
33 assert.ok(!stream.closed, "stream.closed after open should be false"); |
|
34 assert.equal(stream.read(), str, |
|
35 "stream.read should return string written"); |
|
36 assert.equal(stream.read(), "", |
|
37 "stream.read at EOS should return empty string"); |
|
38 stream.close(); |
|
39 assert.ok(stream.closed, "stream.closed after close should be true"); |
|
40 assert.throws(function () stream.close(), |
|
41 STREAM_CLOSED_ERROR, |
|
42 "stream.close after already closed should raise error"); |
|
43 assert.throws(function () stream.read(), |
|
44 STREAM_CLOSED_ERROR, |
|
45 "stream.read after close should raise error"); |
|
46 |
|
47 // Write a big string many times the size of the stream's buffer and read it. |
|
48 // Since it comes after the previous test, this also ensures that the file is |
|
49 // truncated when it's opened for writing. |
|
50 str = ""; |
|
51 let bufLen = BUFFER_BYTE_LEN; |
|
52 let fileSize = bufLen * 10; |
|
53 for (let i = 0; i < fileSize; i++) |
|
54 str += i % 10; |
|
55 stream = file.open(fname, "w"); |
|
56 stream.write(str); |
|
57 stream.close(); |
|
58 stream = file.open(fname); |
|
59 assert.equal(stream.read(), str, |
|
60 "stream.read should return string written"); |
|
61 stream.close(); |
|
62 |
|
63 // The same, but write and read in chunks. |
|
64 stream = file.open(fname, "w"); |
|
65 let i = 0; |
|
66 while (i < str.length) { |
|
67 // Use a chunk length that spans buffers. |
|
68 let chunk = str.substr(i, bufLen + 1); |
|
69 stream.write(chunk); |
|
70 i += bufLen + 1; |
|
71 } |
|
72 stream.close(); |
|
73 stream = file.open(fname); |
|
74 let readStr = ""; |
|
75 bufLen = BUFFER_BYTE_LEN; |
|
76 let readLen = bufLen + 1; |
|
77 do { |
|
78 var frag = stream.read(readLen); |
|
79 readStr += frag; |
|
80 } while (frag); |
|
81 stream.close(); |
|
82 assert.equal(readStr, str, |
|
83 "stream.write and read in chunks should work as expected"); |
|
84 |
|
85 // Read the same file, passing in strange numbers of bytes to read. |
|
86 stream = file.open(fname); |
|
87 assert.equal(stream.read(fileSize * 100), str, |
|
88 "stream.read with big byte length should return string " + |
|
89 "written"); |
|
90 stream.close(); |
|
91 |
|
92 stream = file.open(fname); |
|
93 assert.equal(stream.read(0), "", |
|
94 "string.read with zero byte length should return empty " + |
|
95 "string"); |
|
96 stream.close(); |
|
97 |
|
98 stream = file.open(fname); |
|
99 assert.equal(stream.read(-1), "", |
|
100 "string.read with negative byte length should return " + |
|
101 "empty string"); |
|
102 stream.close(); |
|
103 |
|
104 file.remove(fname); |
|
105 }; |
|
106 |
|
107 exports.testWriteAsync = function (assert, done) { |
|
108 let fname = dataFileFilename(); |
|
109 let str = "exports.testWriteAsync data!"; |
|
110 let stream = file.open(fname, "w"); |
|
111 assert.ok(!stream.closed, "stream.closed after open should be false"); |
|
112 |
|
113 // Write. |
|
114 stream.writeAsync(str, function (err) { |
|
115 assert.equal(this, stream, "|this| should be the stream object"); |
|
116 assert.equal(err, undefined, |
|
117 "stream.writeAsync should not cause error"); |
|
118 assert.ok(stream.closed, "stream.closed after write should be true"); |
|
119 assert.throws(function () stream.close(), |
|
120 STREAM_CLOSED_ERROR, |
|
121 "stream.close after already closed should raise error"); |
|
122 assert.throws(function () stream.writeAsync("This shouldn't work!"), |
|
123 STREAM_CLOSED_ERROR, |
|
124 "stream.writeAsync after close should raise error"); |
|
125 |
|
126 // Read. |
|
127 stream = file.open(fname, "r"); |
|
128 assert.ok(!stream.closed, "stream.closed after open should be false"); |
|
129 let readStr = stream.read(); |
|
130 assert.equal(readStr, str, |
|
131 "string.read should yield string written"); |
|
132 stream.close(); |
|
133 file.remove(fname); |
|
134 done(); |
|
135 }); |
|
136 }; |
|
137 |
|
138 exports.testUnload = function (assert) { |
|
139 let loader = Loader(module); |
|
140 let file = loader.require("sdk/io/file"); |
|
141 |
|
142 let filename = dataFileFilename("temp"); |
|
143 let stream = file.open(filename, "w"); |
|
144 |
|
145 loader.unload(); |
|
146 assert.ok(stream.closed, "stream should be closed after module unload"); |
|
147 }; |
|
148 |
|
149 // Returns the name of a file that should be used to test writing and reading. |
|
150 function dataFileFilename() { |
|
151 return file.join(pathFor("ProfD"), "test-text-streams-data"); |
|
152 } |
|
153 |
|
154 require('sdk/test').run(exports); |