aboutsummaryrefslogtreecommitdiff
path: root/tools/addon-sdk-1.7/packages/api-utils/tests/test-byte-streams.js
blob: 5bd1e428dc1842268b1db057ba483e7df656540e (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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim:set ts=2 sw=2 sts=2 et filetype=javascript
 * 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 byteStreams = require("byte-streams");
const file = require("file");
const { pathFor } = require("api-utils/system");
const { Loader } = require("./helpers");

const STREAM_CLOSED_ERROR = "The stream is closed and cannot be used.";

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

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

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

  // ... and read it.
  stream = open(test, fname);
  test.assertEqual(stream.read(), str,
                   "stream.read should return string written");
  test.assertEqual(stream.read(), "",
                   "stream.read at EOS should return empty string");
  stream.close();
  test.assert(stream.closed, "Stream should be closed after stream.close");
  test.assertRaises(function () stream.read(),
                    STREAM_CLOSED_ERROR,
                    "stream.read after close should raise error");

  file.remove(fname);
};

// Write a big string many times the size of the stream's buffer and read it.
exports.testWriteReadBig = function (test) {
  let str = "";
  let bufLen = BUFFER_BYTE_LEN;
  let fileSize = bufLen * 10;
  for (let i = 0; i < fileSize; i++)
    str += i % 10;
  let fname = dataFileFilename();
  let stream = open(test, fname, true);
  stream.write(str);
  stream.close();
  stream = open(test, fname);
  test.assertEqual(stream.read(), str,
                   "stream.read should return string written");
  stream.close();
  file.remove(fname);
};

// The same, but write and read in chunks.
exports.testWriteReadChunks = function (test) {
  let str = "";
  let bufLen = BUFFER_BYTE_LEN;
  let fileSize = bufLen * 10;
  for (let i = 0; i < fileSize; i++)
    str += i % 10;
  let fname = dataFileFilename();
  let stream = open(test, fname, true);
  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 = open(test, fname);
  let readStr = "";
  bufLen = BUFFER_BYTE_LEN;
  let readLen = bufLen + 1;
  do {
    var frag = stream.read(readLen);
    readStr += frag;
  } while (frag);
  stream.close();
  test.assertEqual(readStr, str,
                   "stream.write and read in chunks should work as expected");
  file.remove(fname);
};

exports.testReadLengths = function (test) {
  let fname = dataFileFilename();
  let str = "exports.testReadLengths data!";
  let stream = open(test, fname, true);
  stream.write(str);
  stream.close();

  stream = open(test, fname);
  test.assertEqual(stream.read(str.length * 1000), str,
                   "stream.read with big byte length should return string " +
                   "written");
  stream.close();

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

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

  file.remove(fname);
};

exports.testTruncate = function (test) {
  let fname = dataFileFilename();
  let str = "exports.testReadLengths data!";
  let stream = open(test, fname, true);
  stream.write(str);
  stream.close();

  stream = open(test, fname);
  test.assertEqual(stream.read(), str,
                   "stream.read should return string written");
  stream.close();

  stream = open(test, fname, true);
  stream.close();

  stream = open(test, fname);
  test.assertEqual(stream.read(), "",
                   "stream.read after truncate should be empty");
  stream.close();

  file.remove(fname);
};

exports.testUnload = function (test) {
  let loader = Loader(module);
  let file = loader.require("file");

  let filename = dataFileFilename("temp-b");
  let stream = file.open(filename, "wb");

  loader.unload();
  test.assert(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-byte-streams-data");
}

// Opens and returns the given file and ensures it's of the correct class.
function open(test, filename, forWriting) {
  let stream = file.open(filename, forWriting ? "wb" : "b");
  let klass = forWriting ? "ByteWriter" : "ByteReader";
  test.assert(stream instanceof byteStreams[klass],
              "Opened stream should be a " + klass);
  return stream;
}