• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright Joyent, Inc. and other Node contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and associated documentation files (the
5// "Software"), to deal in the Software without restriction, including
6// without limitation the rights to use, copy, modify, merge, publish,
7// distribute, sublicense, and/or sell copies of the Software, and to permit
8// persons to whom the Software is furnished to do so, subject to the
9// following conditions:
10//
11// The above copyright notice and this permission notice shall be included
12// in all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20// USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22// Flags: --expose_externalize_string
23'use strict';
24const common = require('../common');
25const assert = require('assert');
26const path = require('path');
27const fs = require('fs');
28const tmpdir = require('../common/tmpdir');
29
30tmpdir.refresh();
31
32const fn = path.join(tmpdir.path, 'write.txt');
33const fn2 = path.join(tmpdir.path, 'write2.txt');
34const fn3 = path.join(tmpdir.path, 'write3.txt');
35const fn4 = path.join(tmpdir.path, 'write4.txt');
36const expected = 'ümlaut.';
37const constants = fs.constants;
38
39const { externalizeString, isOneByteString } = global;
40
41// Account for extra globals exposed by --expose_externalize_string.
42common.allowGlobals(externalizeString, isOneByteString, global.x);
43
44{
45  const expected = 'ümlaut sechzig';  // Must be a unique string.
46  externalizeString(expected);
47  assert.strictEqual(isOneByteString(expected), true);
48  const fd = fs.openSync(fn, 'w');
49  fs.writeSync(fd, expected, 0, 'latin1');
50  fs.closeSync(fd);
51  assert.strictEqual(fs.readFileSync(fn, 'latin1'), expected);
52}
53
54{
55  const expected = 'ümlaut neunzig';  // Must be a unique string.
56  externalizeString(expected);
57  assert.strictEqual(isOneByteString(expected), true);
58  const fd = fs.openSync(fn, 'w');
59  fs.writeSync(fd, expected, 0, 'utf8');
60  fs.closeSync(fd);
61  assert.strictEqual(fs.readFileSync(fn, 'utf8'), expected);
62}
63
64{
65  const expected = 'Zhōngwén 1';  // Must be a unique string.
66  externalizeString(expected);
67  assert.strictEqual(isOneByteString(expected), false);
68  const fd = fs.openSync(fn, 'w');
69  fs.writeSync(fd, expected, 0, 'ucs2');
70  fs.closeSync(fd);
71  assert.strictEqual(fs.readFileSync(fn, 'ucs2'), expected);
72}
73
74{
75  const expected = 'Zhōngwén 2';  // Must be a unique string.
76  externalizeString(expected);
77  assert.strictEqual(isOneByteString(expected), false);
78  const fd = fs.openSync(fn, 'w');
79  fs.writeSync(fd, expected, 0, 'utf8');
80  fs.closeSync(fd);
81  assert.strictEqual(fs.readFileSync(fn, 'utf8'), expected);
82}
83
84fs.open(fn, 'w', 0o644, common.mustSucceed((fd) => {
85  const done = common.mustSucceed((written) => {
86    assert.strictEqual(written, Buffer.byteLength(expected));
87    fs.closeSync(fd);
88    const found = fs.readFileSync(fn, 'utf8');
89    fs.unlinkSync(fn);
90    assert.strictEqual(found, expected);
91  });
92
93  const written = common.mustSucceed((written) => {
94    assert.strictEqual(written, 0);
95    fs.write(fd, expected, 0, 'utf8', done);
96  });
97
98  fs.write(fd, '', 0, 'utf8', written);
99}));
100
101const args = constants.O_CREAT | constants.O_WRONLY | constants.O_TRUNC;
102fs.open(fn2, args, 0o644, common.mustSucceed((fd) => {
103  const done = common.mustSucceed((written) => {
104    assert.strictEqual(written, Buffer.byteLength(expected));
105    fs.closeSync(fd);
106    const found = fs.readFileSync(fn2, 'utf8');
107    fs.unlinkSync(fn2);
108    assert.strictEqual(found, expected);
109  });
110
111  const written = common.mustSucceed((written) => {
112    assert.strictEqual(written, 0);
113    fs.write(fd, expected, 0, 'utf8', done);
114  });
115
116  fs.write(fd, '', 0, 'utf8', written);
117}));
118
119fs.open(fn3, 'w', 0o644, common.mustSucceed((fd) => {
120  const done = common.mustSucceed((written) => {
121    assert.strictEqual(written, Buffer.byteLength(expected));
122    fs.closeSync(fd);
123  });
124
125  fs.write(fd, expected, done);
126}));
127
128fs.open(fn4, 'w', 0o644, common.mustSucceed((fd) => {
129  const done = common.mustSucceed((written) => {
130    assert.strictEqual(written, Buffer.byteLength(expected));
131    fs.closeSync(fd);
132  });
133
134  const data = {
135    toString() { return expected; }
136  };
137  fs.write(fd, data, done);
138}));
139
140[false, 'test', {}, [], null, undefined].forEach((i) => {
141  assert.throws(
142    () => fs.write(i, common.mustNotCall()),
143    {
144      code: 'ERR_INVALID_ARG_TYPE',
145      name: 'TypeError'
146    }
147  );
148  assert.throws(
149    () => fs.writeSync(i),
150    {
151      code: 'ERR_INVALID_ARG_TYPE',
152      name: 'TypeError'
153    }
154  );
155});
156
157[
158  false, 5, {}, [], null, undefined,
159  new String('notPrimitive'),
160  { [Symbol.toPrimitive]: (hint) => 'amObject' },
161].forEach((data) => {
162  assert.throws(
163    () => fs.write(1, data, common.mustNotCall()),
164    {
165      code: 'ERR_INVALID_ARG_TYPE',
166      message: /"buffer"/
167    }
168  );
169  assert.throws(
170    () => fs.writeSync(1, data),
171    {
172      code: 'ERR_INVALID_ARG_TYPE',
173      message: /"buffer"/
174    }
175  );
176});
177