11cb0ef41Sopenharmony_ci// Copyright Joyent, Inc. and other Node contributors. 21cb0ef41Sopenharmony_ci// 31cb0ef41Sopenharmony_ci// Permission is hereby granted, free of charge, to any person obtaining a 41cb0ef41Sopenharmony_ci// copy of this software and associated documentation files (the 51cb0ef41Sopenharmony_ci// "Software"), to deal in the Software without restriction, including 61cb0ef41Sopenharmony_ci// without limitation the rights to use, copy, modify, merge, publish, 71cb0ef41Sopenharmony_ci// distribute, sublicense, and/or sell copies of the Software, and to permit 81cb0ef41Sopenharmony_ci// persons to whom the Software is furnished to do so, subject to the 91cb0ef41Sopenharmony_ci// following conditions: 101cb0ef41Sopenharmony_ci// 111cb0ef41Sopenharmony_ci// The above copyright notice and this permission notice shall be included 121cb0ef41Sopenharmony_ci// in all copies or substantial portions of the Software. 131cb0ef41Sopenharmony_ci// 141cb0ef41Sopenharmony_ci// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 151cb0ef41Sopenharmony_ci// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 161cb0ef41Sopenharmony_ci// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 171cb0ef41Sopenharmony_ci// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 181cb0ef41Sopenharmony_ci// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 191cb0ef41Sopenharmony_ci// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 201cb0ef41Sopenharmony_ci// USE OR OTHER DEALINGS IN THE SOFTWARE. 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ci'use strict'; 231cb0ef41Sopenharmony_ciconst common = require('../common'); 241cb0ef41Sopenharmony_ciconst ArrayStream = require('../common/arraystream'); 251cb0ef41Sopenharmony_ciconst assert = require('assert'); 261cb0ef41Sopenharmony_ciconst join = require('path').join; 271cb0ef41Sopenharmony_ciconst fs = require('fs'); 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_ciconst tmpdir = require('../common/tmpdir'); 301cb0ef41Sopenharmony_citmpdir.refresh(); 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ciconst repl = require('repl'); 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ciconst works = [['inner.one'], 'inner.o']; 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_ciconst putIn = new ArrayStream(); 371cb0ef41Sopenharmony_ciconst testMe = repl.start('', putIn); 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ci// Some errors might be passed to the domain. 401cb0ef41Sopenharmony_citestMe._domain.on('error', function(reason) { 411cb0ef41Sopenharmony_ci const err = new Error('Test failed'); 421cb0ef41Sopenharmony_ci err.reason = reason; 431cb0ef41Sopenharmony_ci throw err; 441cb0ef41Sopenharmony_ci}); 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ciconst testFile = [ 471cb0ef41Sopenharmony_ci 'let inner = (function() {', 481cb0ef41Sopenharmony_ci ' return {one:1};', 491cb0ef41Sopenharmony_ci '})()', 501cb0ef41Sopenharmony_ci]; 511cb0ef41Sopenharmony_ciconst saveFileName = join(tmpdir.path, 'test.save.js'); 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ci// Add some data. 541cb0ef41Sopenharmony_ciputIn.run(testFile); 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ci// Save it to a file. 571cb0ef41Sopenharmony_ciputIn.run([`.save ${saveFileName}`]); 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ci// The file should have what I wrote. 601cb0ef41Sopenharmony_ciassert.strictEqual(fs.readFileSync(saveFileName, 'utf8'), 611cb0ef41Sopenharmony_ci testFile.join('\n')); 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_ci// Make sure that the REPL data is "correct". 641cb0ef41Sopenharmony_citestMe.complete('inner.o', common.mustSucceed((data) => { 651cb0ef41Sopenharmony_ci assert.deepStrictEqual(data, works); 661cb0ef41Sopenharmony_ci})); 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci// Clear the REPL. 691cb0ef41Sopenharmony_ciputIn.run(['.clear']); 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_ci// Load the file back in. 721cb0ef41Sopenharmony_ciputIn.run([`.load ${saveFileName}`]); 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_ci// Make sure that the REPL data is "correct". 751cb0ef41Sopenharmony_citestMe.complete('inner.o', common.mustSucceed((data) => { 761cb0ef41Sopenharmony_ci assert.deepStrictEqual(data, works); 771cb0ef41Sopenharmony_ci})); 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci// Clear the REPL. 801cb0ef41Sopenharmony_ciputIn.run(['.clear']); 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_cilet loadFile = join(tmpdir.path, 'file.does.not.exist'); 831cb0ef41Sopenharmony_ci 841cb0ef41Sopenharmony_ci// Should not break. 851cb0ef41Sopenharmony_ciputIn.write = common.mustCall(function(data) { 861cb0ef41Sopenharmony_ci // Make sure I get a failed to load message and not some crazy error. 871cb0ef41Sopenharmony_ci assert.strictEqual(data, `Failed to load: ${loadFile}\n`); 881cb0ef41Sopenharmony_ci // Eat me to avoid work. 891cb0ef41Sopenharmony_ci putIn.write = () => {}; 901cb0ef41Sopenharmony_ci}); 911cb0ef41Sopenharmony_ciputIn.run([`.load ${loadFile}`]); 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_ci// Throw error on loading directory. 941cb0ef41Sopenharmony_ciloadFile = tmpdir.path; 951cb0ef41Sopenharmony_ciputIn.write = common.mustCall(function(data) { 961cb0ef41Sopenharmony_ci assert.strictEqual(data, `Failed to load: ${loadFile} is not a valid file\n`); 971cb0ef41Sopenharmony_ci putIn.write = () => {}; 981cb0ef41Sopenharmony_ci}); 991cb0ef41Sopenharmony_ciputIn.run([`.load ${loadFile}`]); 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_ci// Clear the REPL. 1021cb0ef41Sopenharmony_ciputIn.run(['.clear']); 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci// NUL (\0) is disallowed in filenames in UNIX-like operating systems and 1051cb0ef41Sopenharmony_ci// Windows so we can use that to test failed saves. 1061cb0ef41Sopenharmony_ciconst invalidFileName = join(tmpdir.path, '\0\0\0\0\0'); 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_ci// Should not break. 1091cb0ef41Sopenharmony_ciputIn.write = common.mustCall(function(data) { 1101cb0ef41Sopenharmony_ci // Make sure I get a failed to save message and not some other error. 1111cb0ef41Sopenharmony_ci assert.strictEqual(data, `Failed to save: ${invalidFileName}\n`); 1121cb0ef41Sopenharmony_ci // Reset to no-op. 1131cb0ef41Sopenharmony_ci putIn.write = () => {}; 1141cb0ef41Sopenharmony_ci}); 1151cb0ef41Sopenharmony_ci 1161cb0ef41Sopenharmony_ci// Save it to a file. 1171cb0ef41Sopenharmony_ciputIn.run([`.save ${invalidFileName}`]); 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci{ 1201cb0ef41Sopenharmony_ci // Save .editor mode code. 1211cb0ef41Sopenharmony_ci const cmds = [ 1221cb0ef41Sopenharmony_ci 'function testSave() {', 1231cb0ef41Sopenharmony_ci 'return "saved";', 1241cb0ef41Sopenharmony_ci '}', 1251cb0ef41Sopenharmony_ci ]; 1261cb0ef41Sopenharmony_ci const putIn = new ArrayStream(); 1271cb0ef41Sopenharmony_ci const replServer = repl.start({ terminal: true, stream: putIn }); 1281cb0ef41Sopenharmony_ci 1291cb0ef41Sopenharmony_ci putIn.run(['.editor']); 1301cb0ef41Sopenharmony_ci putIn.run(cmds); 1311cb0ef41Sopenharmony_ci replServer.write('', { ctrl: true, name: 'd' }); 1321cb0ef41Sopenharmony_ci 1331cb0ef41Sopenharmony_ci putIn.run([`.save ${saveFileName}`]); 1341cb0ef41Sopenharmony_ci replServer.close(); 1351cb0ef41Sopenharmony_ci assert.strictEqual(fs.readFileSync(saveFileName, 'utf8'), 1361cb0ef41Sopenharmony_ci `${cmds.join('\n')}\n`); 1371cb0ef41Sopenharmony_ci} 138