diff --git a/test/parallel/test-repl-tab-complete.js b/test/parallel/test-repl-tab-complete.js index 6fe62f39fc91b6..1bf0c700eb2e54 100644 --- a/test/parallel/test-repl-tab-complete.js +++ b/test/parallel/test-repl-tab-complete.js @@ -2,8 +2,18 @@ var common = require('../common'); var assert = require('assert'); var util = require('util'); - var repl = require('repl'); +var referenceErrors = 0; +var completionCount = 0; + +function doNotCall() { + assert(false); +} + +process.on('exit', function() { + assert.strictEqual(referenceErrors, 6); + assert.strictEqual(completionCount, 12); +}); // A stream to push an array into a REPL function ArrayStream() { @@ -21,27 +31,37 @@ ArrayStream.prototype.resume = function() {}; ArrayStream.prototype.write = function() {}; var works = [['inner.one'], 'inner.o']; -var doesNotBreak = [[], 'inner.o']; - var putIn = new ArrayStream(); var testMe = repl.start('', putIn); +// Some errors are passed to the domain, but do not callback +testMe._domain.on('error', function(err) { + // Errors come from another context, so instanceof doesn't work + var str = err.toString(); + + if (/^ReferenceError:/.test(str)) + referenceErrors++; + else + assert(false); +}); + // Tab Complete will not break in an object literal putIn.run(['.clear']); putIn.run([ 'var inner = {', 'one:1' ]); -testMe.complete('inner.o', function(error, data) { - assert.deepEqual(data, doesNotBreak); -}); +testMe.complete('inner.o', doNotCall); + testMe.complete('console.lo', function(error, data) { + completionCount++; assert.deepEqual(data, [['console.log'], 'console.lo']); }); // Tab Complete will return globaly scoped variables putIn.run(['};']); testMe.complete('inner.o', function(error, data) { + completionCount++; assert.deepEqual(data, works); }); @@ -53,9 +73,7 @@ putIn.run([ '?', '{one: 1} : ' ]); -testMe.complete('inner.o', function(error, data) { - assert.deepEqual(data, doesNotBreak); -}); +testMe.complete('inner.o', doNotCall); putIn.run(['.clear']); @@ -65,15 +83,14 @@ putIn.run([ 'var inner = {one:1};' ]); testMe.complete('inner.o', function(error, data) { + completionCount++; assert.deepEqual(data, works); }); // When you close the function scope tab complete will not return the // locally scoped variable putIn.run(['};']); -testMe.complete('inner.o', function(error, data) { - assert.deepEqual(data, doesNotBreak); -}); +testMe.complete('inner.o', doNotCall); putIn.run(['.clear']); @@ -85,6 +102,7 @@ putIn.run([ '};' ]); testMe.complete('inner.o', function(error, data) { + completionCount++; assert.deepEqual(data, works); }); @@ -99,6 +117,7 @@ putIn.run([ '};' ]); testMe.complete('inner.o', function(error, data) { + completionCount++; assert.deepEqual(data, works); }); @@ -114,12 +133,12 @@ putIn.run([ '};' ]); testMe.complete('inner.o', function(error, data) { + completionCount++; assert.deepEqual(data, works); }); putIn.run(['.clear']); -// currently does not work, but should not break note the inner function // def has the params and { on a separate line putIn.run([ 'var top = function() {', @@ -129,9 +148,7 @@ putIn.run([ ' one:1', '};' ]); -testMe.complete('inner.o', function(error, data) { - assert.deepEqual(data, doesNotBreak); -}); +testMe.complete('inner.o', doNotCall); putIn.run(['.clear']); @@ -144,9 +161,7 @@ putIn.run([ ' one:1', '};' ]); -testMe.complete('inner.o', function(error, data) { - assert.deepEqual(data, doesNotBreak); -}); +testMe.complete('inner.o', doNotCall); putIn.run(['.clear']); @@ -160,9 +175,7 @@ putIn.run([ ' one:1', '};' ]); -testMe.complete('inner.o', function(error, data) { - assert.deepEqual(data, doesNotBreak); -}); +testMe.complete('inner.o', doNotCall); putIn.run(['.clear']); @@ -171,6 +184,7 @@ putIn.run([ 'var str = "test";' ]); testMe.complete('str.len', function(error, data) { + completionCount++; assert.deepEqual(data, [['str.length'], 'str.len']); }); @@ -182,6 +196,7 @@ var spaceTimeout = setTimeout(function() { }, 1000); testMe.complete(' ', function(error, data) { + completionCount++; assert.deepEqual(data, [[], undefined]); clearTimeout(spaceTimeout); }); @@ -189,6 +204,7 @@ testMe.complete(' ', function(error, data) { // tab completion should pick up the global "toString" object, and // any other properties up the "global" object's prototype chain testMe.complete('toSt', function(error, data) { + completionCount++; assert.deepEqual(data, [['toString'], 'toSt']); }); @@ -196,6 +212,7 @@ testMe.complete('toSt', function(error, data) { putIn.run(['.clear']); testMe.complete('require(\'', function(error, data) { + completionCount++; assert.strictEqual(error, null); repl._builtinLibs.forEach(function(lib) { assert.notStrictEqual(data[0].indexOf(lib), -1, lib + ' not found'); @@ -203,8 +220,16 @@ testMe.complete('require(\'', function(error, data) { }); testMe.complete('require(\'n', function(error, data) { + completionCount++; assert.strictEqual(error, null); - assert.deepEqual(data, [['net'], 'n']); + assert.strictEqual(data.length, 2); + assert.strictEqual(data[1], 'n'); + assert.notStrictEqual(data[0].indexOf('net'), -1); + // It's possible to pick up non-core modules too + data[0].forEach(function(completion) { + if (completion) + assert(/^n/.test(completion)); + }); }); // Make sure tab completion works on context properties @@ -214,5 +239,6 @@ putIn.run([ 'var custom = "test";' ]); testMe.complete('cus', function(error, data) { + completionCount++; assert.deepEqual(data, [['custom'], 'cus']); });