• 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'use strict';
23const common = require('../common');
24const ArrayStream = require('../common/arraystream');
25const assert = require('assert');
26const join = require('path').join;
27const fs = require('fs');
28
29const tmpdir = require('../common/tmpdir');
30tmpdir.refresh();
31
32const repl = require('repl');
33
34const works = [['inner.one'], 'inner.o'];
35
36const putIn = new ArrayStream();
37const testMe = repl.start('', putIn);
38
39// Some errors might be passed to the domain.
40testMe._domain.on('error', function(reason) {
41  const err = new Error('Test failed');
42  err.reason = reason;
43  throw err;
44});
45
46const testFile = [
47  'let inner = (function() {',
48  '  return {one:1};',
49  '})()'
50];
51const saveFileName = join(tmpdir.path, 'test.save.js');
52
53// Add some data.
54putIn.run(testFile);
55
56// Save it to a file.
57putIn.run([`.save ${saveFileName}`]);
58
59// The file should have what I wrote.
60assert.strictEqual(fs.readFileSync(saveFileName, 'utf8'),
61                   testFile.join('\n'));
62
63// Make sure that the REPL data is "correct".
64testMe.complete('inner.o', common.mustCall(function(error, data) {
65  assert.ifError(error);
66  assert.deepStrictEqual(data, works);
67}));
68
69// Clear the REPL.
70putIn.run(['.clear']);
71
72// Load the file back in.
73putIn.run([`.load ${saveFileName}`]);
74
75// Make sure that the REPL data is "correct".
76testMe.complete('inner.o', common.mustCall(function(error, data) {
77  assert.ifError(error);
78  assert.deepStrictEqual(data, works);
79}));
80
81// Clear the REPL.
82putIn.run(['.clear']);
83
84let loadFile = join(tmpdir.path, 'file.does.not.exist');
85
86// Should not break.
87putIn.write = common.mustCall(function(data) {
88  // Make sure I get a failed to load message and not some crazy error.
89  assert.strictEqual(data, `Failed to load: ${loadFile}\n`);
90  // Eat me to avoid work.
91  putIn.write = () => {};
92});
93putIn.run([`.load ${loadFile}`]);
94
95// Throw error on loading directory.
96loadFile = tmpdir.path;
97putIn.write = common.mustCall(function(data) {
98  assert.strictEqual(data, `Failed to load: ${loadFile} is not a valid file\n`);
99  putIn.write = () => {};
100});
101putIn.run([`.load ${loadFile}`]);
102
103// Clear the REPL.
104putIn.run(['.clear']);
105
106// NUL (\0) is disallowed in filenames in UNIX-like operating systems and
107// Windows so we can use that to test failed saves.
108const invalidFileName = join(tmpdir.path, '\0\0\0\0\0');
109
110// Should not break.
111putIn.write = common.mustCall(function(data) {
112  // Make sure I get a failed to save message and not some other error.
113  assert.strictEqual(data, `Failed to save: ${invalidFileName}\n`);
114  // Reset to no-op.
115  putIn.write = () => {};
116});
117
118// Save it to a file.
119putIn.run([`.save ${invalidFileName}`]);
120
121{
122  // Save .editor mode code.
123  const cmds = [
124    'function testSave() {',
125    'return "saved";',
126    '}'
127  ];
128  const putIn = new ArrayStream();
129  const replServer = repl.start({ terminal: true, stream: putIn });
130
131  putIn.run(['.editor']);
132  putIn.run(cmds);
133  replServer.write('', { ctrl: true, name: 'd' });
134
135  putIn.run([`.save ${saveFileName}`]);
136  replServer.close();
137  assert.strictEqual(fs.readFileSync(saveFileName, 'utf8'),
138                     `${cmds.join('\n')}\n`);
139}
140