repl: add automatic loading of built-in libs
authorBrandon Benvie <brandon@bbenvie.com>
Sun, 25 Dec 2011 04:39:57 +0000 (23:39 -0500)
committerBen Noordhuis <info@bnoordhuis.nl>
Mon, 20 Feb 2012 12:56:27 +0000 (13:56 +0100)
lib/repl.js
test/simple/test-repl-autolibs.js [new file with mode: 0644]

index 70a5eba..7abf0a3 100644 (file)
@@ -67,6 +67,11 @@ module.paths = require('module')._nodeModulePaths(module.filename);
 // Can overridden with custom print functions, such as `probe` or `eyes.js`
 exports.writer = util.inspect;
 
+var builtinLibs = ['assert', 'buffer', 'child_process', 'cluster',
+  'crypto', 'dgram', 'dns', 'events', 'fs', 'http', 'https', 'net',
+  'os', 'path', 'punycode', 'querystring', 'readline', 'repl',
+  'string_decoder', 'tls', 'tty', 'url', 'util', 'vm', 'zlib'];
+
 
 function REPLServer(prompt, stream, eval, useGlobal, ignoreUndefined) {
   var self = this;
@@ -167,6 +172,21 @@ function REPLServer(prompt, stream, eval, useGlobal, ignoreUndefined) {
       }
     }
 
+    // Check if a builtin module name was used and then include it
+    // if there's no conflict.
+    if (~builtinLibs.indexOf(cmd)) {
+      var lib = require(cmd);
+      if (cmd in self.context && lib !== self.context[cmd]) {
+        self.outputStream.write('A different "' + cmd +
+                                '" already exists globally\n');
+      } else {
+        self.context._ = self.context[cmd] = lib;
+        self.outputStream.write(exports.writer(lib) + '\n');
+      }
+      self.displayPrompt();
+      return;
+    }
+
     if (!skipCatchall) {
       var evalCmd = self.bufferedCommand + cmd + '\n';
 
@@ -428,12 +448,6 @@ REPLServer.prototype.complete = function(line, callback) {
     }
 
     if (!subdir) {
-      // Kind of lame that this needs to be updated manually.
-      // Intentionally excluding moved modules: posix, utils.
-      var builtinLibs = ['assert', 'buffer', 'child_process', 'crypto', 'dgram',
-        'dns', 'events', 'file', 'freelist', 'fs', 'http', 'net', 'os', 'path',
-        'querystring', 'readline', 'repl', 'string_decoder', 'util', 'tcp',
-        'url'];
       completionGroups.push(builtinLibs);
     }
 
diff --git a/test/simple/test-repl-autolibs.js b/test/simple/test-repl-autolibs.js
new file mode 100644 (file)
index 0000000..56fbaa6
--- /dev/null
@@ -0,0 +1,71 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var assert = require('assert');
+var util = require('util');
+var repl = require('repl');
+
+// A stream to push an array into a REPL
+function ArrayStream() {
+  this.run = function (data) {
+    var self = this;
+    data.forEach(function (line) {
+      self.emit('data', line);
+    });
+  }
+}
+util.inherits(ArrayStream, require('stream').Stream);
+ArrayStream.prototype.readable = true;
+ArrayStream.prototype.writable = true;
+ArrayStream.prototype.resume = function () {};
+ArrayStream.prototype.write = function () {};
+
+var putIn = new ArrayStream;
+var testMe = repl.start('', putIn, null, true);
+
+test1();
+
+function test1(){
+  putIn.write = function (data) {
+    if (data.length) {
+      // inspect output matches repl output
+      assert.equal(data, util.inspect(require('fs'), null, null, false) + '\n');
+      // globally added lib matches required lib
+      assert.equal(global.fs, require('fs'));
+      test2();
+    }
+  };
+  putIn.run(['fs']);
+}
+
+function test2(){
+  putIn.write = function(data) {
+    if (data.length) {
+      // repl response error message
+      assert.equal(data.indexOf('A different'), 0);
+      // original value wasn't overwritten
+      assert.equal(val, global.url);
+    }
+  };
+  var val = {};
+  global.url = val;
+  putIn.run(['url']);
+}