summaryrefslogtreecommitdiffstats
path: root/addon-sdk/source/test/test-text-streams.js
blob: c7691fd5471557474587a30935f7beee3a0e22e7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

const file = require("sdk/io/file");
const { pathFor } = require("sdk/system");
const { Loader } = require("sdk/test/loader");

const STREAM_CLOSED_ERROR = new RegExp("The stream is closed and cannot be used.");

// This should match the constant of the same name in text-streams.js.
const BUFFER_BYTE_LEN = 0x8000;

exports.testWriteRead = function (assert) {
  let fname = dataFileFilename();

  // Write a small string less than the stream's buffer size...
  let str = "exports.testWriteRead data!";
  let stream = file.open(fname, "w");
  assert.ok(!stream.closed, "stream.closed after open should be false");
  stream.write(str);
  stream.close();
  assert.ok(stream.closed, "stream.closed after close should be true");
  assert.throws(() => stream.close(),
                    STREAM_CLOSED_ERROR,
                    "stream.close after already closed should raise error");
  assert.throws(() => stream.write("This shouldn't be written!"),
                    STREAM_CLOSED_ERROR,
                    "stream.write after close should raise error");

  // ... and read it.
  stream = file.open(fname);
  assert.ok(!stream.closed, "stream.closed after open should be false");
  assert.equal(stream.read(), str,
                   "stream.read should return string written");
  assert.equal(stream.read(), "",
                   "stream.read at EOS should return empty string");
  stream.close();
  assert.ok(stream.closed, "stream.closed after close should be true");
  assert.throws(() => stream.close(),
                    STREAM_CLOSED_ERROR,
                    "stream.close after already closed should raise error");
  assert.throws(() => stream.read(),
                    STREAM_CLOSED_ERROR,
                    "stream.read after close should raise error");

  // Write a big string many times the size of the stream's buffer and read it.
  // Since it comes after the previous test, this also ensures that the file is
  // truncated when it's opened for writing.
  str = "";
  let bufLen = BUFFER_BYTE_LEN;
  let fileSize = bufLen * 10;
  for (let i = 0; i < fileSize; i++)
    str += i % 10;
  stream = file.open(fname, "w");
  stream.write(str);
  stream.close();
  stream = file.open(fname);
  assert.equal(stream.read(), str,
                   "stream.read should return string written");
  stream.close();

  // The same, but write and read in chunks.
  stream = file.open(fname, "w");
  let i = 0;
  while (i < str.length) {
    // Use a chunk length that spans buffers.
    let chunk = str.substr(i, bufLen + 1);
    stream.write(chunk);
    i += bufLen + 1;
  }
  stream.close();
  stream = file.open(fname);
  let readStr = "";
  bufLen = BUFFER_BYTE_LEN;
  let readLen = bufLen + 1;
  do {
    var frag = stream.read(readLen);
    readStr += frag;
  } while (frag);
  stream.close();
  assert.equal(readStr, str,
                   "stream.write and read in chunks should work as expected");

  // Read the same file, passing in strange numbers of bytes to read.
  stream = file.open(fname);
  assert.equal(stream.read(fileSize * 100), str,
                   "stream.read with big byte length should return string " +
                   "written");
  stream.close();

  stream = file.open(fname);
  assert.equal(stream.read(0), "",
                   "string.read with zero byte length should return empty " +
                   "string");
  stream.close();

  stream = file.open(fname);
  assert.equal(stream.read(-1), "",
                   "string.read with negative byte length should return " +
                   "empty string");
  stream.close();

  file.remove(fname);
};

exports.testWriteAsync = function (assert, done) {
  let fname = dataFileFilename();
  let str = "exports.testWriteAsync data!";
  let stream = file.open(fname, "w");
  assert.ok(!stream.closed, "stream.closed after open should be false");

  // Write.
  stream.writeAsync(str, function (err) {
    assert.equal(this, stream, "|this| should be the stream object");
    assert.equal(err, undefined,
                     "stream.writeAsync should not cause error");
    assert.ok(stream.closed, "stream.closed after write should be true");
    assert.throws(() => stream.close(),
                      STREAM_CLOSED_ERROR,
                      "stream.close after already closed should raise error");
    assert.throws(() => stream.writeAsync("This shouldn't work!"),
                      STREAM_CLOSED_ERROR,
                      "stream.writeAsync after close should raise error");

    // Read.
    stream = file.open(fname, "r");
    assert.ok(!stream.closed, "stream.closed after open should be false");
    let readStr = stream.read();
    assert.equal(readStr, str,
                     "string.read should yield string written");
    stream.close();
    file.remove(fname);
    done();
  });
};

exports.testUnload = function (assert) {
  let loader = Loader(module);
  let file = loader.require("sdk/io/file");

  let filename = dataFileFilename("temp");
  let stream = file.open(filename, "w");

  loader.unload();
  assert.ok(stream.closed, "stream should be closed after module unload");
};

// Returns the name of a file that should be used to test writing and reading.
function dataFileFilename() {
  return file.join(pathFor("ProfD"), "test-text-streams-data");
}

require('sdk/test').run(exports);