diff options
author | Lance Ball <lball@redhat.com> | 2016-03-02 16:45:16 -0500 |
---|---|---|
committer | silverwind <me@silverwind.io> | 2016-03-18 21:03:40 +0100 |
commit | ad8257fa5b9795d3d79fa4a91d0f18c43f024ab3 (patch) | |
tree | b28a5a76c2c6ba7175b760e6720b7af2a26bd48d /test/parallel/test-repl-underscore.js | |
parent | c67937bebbb8b1de01e8fb878608b8ea5a34cba3 (diff) | |
download | android-node-v8-ad8257fa5b9795d3d79fa4a91d0f18c43f024ab3.tar.gz android-node-v8-ad8257fa5b9795d3d79fa4a91d0f18c43f024ab3.tar.bz2 android-node-v8-ad8257fa5b9795d3d79fa4a91d0f18c43f024ab3.zip |
repl: Assignment of _ allowed with warning
This commit addresses https://github.com/nodejs/node/issues/5431 by
changing the way that the repl handles assignment to the global _
variable.
Prior to this commit, node sets the result of the last expression
evaluated in the repl to `_`. This causes problems for users of
underscore, lodash and other packages where it is common to assign
`_` to the package, e.g. `_ = require('lodash');`.
Changes in this commit now result in the following behavior.
- If unassigned on the repl, `_` continues to refer to the last
evaluated expression.
- If assigned, the default behavior of assigning `_` to the last
evaluated expression is disabled, and `_` now references whatever
value was explicitly set. A warning is issued on the repl -
'expression assignment to _ now disabled'.
- If `_` is assigned multiple times, the warning is only displayed once.
- When `.clear` is executed in the repl, `_` continues to refer to its
most recent value, whatever that is (this is per existing behavior).
If `_` had been explicitly set prior to `.clear` it will not change
again with the evaluation of the next expression.
PR-URL: https://github.com/nodejs/node/pull/5535
Fixes: https://github.com/nodejs/node/issues/5431
Reviewed-By: Roman Reiss <me@silverwind.io>
Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'test/parallel/test-repl-underscore.js')
-rw-r--r-- | test/parallel/test-repl-underscore.js | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/test/parallel/test-repl-underscore.js b/test/parallel/test-repl-underscore.js new file mode 100644 index 0000000000..97fc508ad9 --- /dev/null +++ b/test/parallel/test-repl-underscore.js @@ -0,0 +1,156 @@ +'use strict'; + +require('../common'); +const assert = require('assert'); +const repl = require('repl'); +const stream = require('stream'); + +testSloppyMode(); +testStrictMode(); +testResetContext(); +testMagicMode(); + +function testSloppyMode() { + const r = initRepl(repl.REPL_MODE_SLOPPY); + + // cannot use `let` in sloppy mode + r.write(`_; // initial value undefined + var x = 10; // evaluates to undefined + _; // still undefined + y = 10; // evaluates to 10 + _; // 10 from last eval + _ = 20; // explicitly set to 20 + _; // 20 from user input + _ = 30; // make sure we can set it twice and no prompt + _; // 30 from user input + y = 40; // make sure eval doesn't change _ + _; // remains 30 from user input + `); + + assertOutput(r.output, [ + 'undefined', + 'undefined', + 'undefined', + '10', + '10', + 'Expression assignment to _ now disabled.', + '20', + '20', + '30', + '30', + '40', + '30' + ]); +} + +function testStrictMode() { + const r = initRepl(repl.REPL_MODE_STRICT); + + r.write(`_; // initial value undefined + var x = 10; // evaluates to undefined + _; // still undefined + let _ = 20; // use 'let' only in strict mode - evals to undefined + _; // 20 from user input + _ = 30; // make sure we can set it twice and no prompt + _; // 30 from user input + var y = 40; // make sure eval doesn't change _ + _; // remains 30 from user input + function f() { let _ = 50; } // undefined + f(); // undefined + _; // remains 30 from user input + `); + + assertOutput(r.output, [ + 'undefined', + 'undefined', + 'undefined', + 'undefined', + '20', + '30', + '30', + 'undefined', + '30', + 'undefined', + 'undefined', + '30' + ]); +} + +function testMagicMode() { + const r = initRepl(repl.REPL_MODE_MAGIC); + + r.write(`_; // initial value undefined + x = 10; // + _; // last eval - 10 + let _ = 20; // undefined + _; // 20 from user input + _ = 30; // make sure we can set it twice and no prompt + _; // 30 from user input + var y = 40; // make sure eval doesn't change _ + _; // remains 30 from user input + function f() { let _ = 50; return _; } // undefined + f(); // 50 + _; // remains 30 from user input + `); + + assertOutput(r.output, [ + 'undefined', + '10', + '10', + 'undefined', + '20', + '30', + '30', + 'undefined', + '30', + 'undefined', + '50', + '30' + ]); +} + +function testResetContext() { + const r = initRepl(repl.REPL_MODE_SLOPPY); + + r.write(`_ = 10; // explicitly set to 10 + _; // 10 from user input + .clear // Clearing context... + _; // remains 10 + x = 20; // but behavior reverts to last eval + _; // expect 20 + `); + + assertOutput(r.output, [ + 'Expression assignment to _ now disabled.', + '10', + '10', + 'Clearing context...', + '10', + '20', + '20' + ]); +} + +function initRepl(mode) { + const inputStream = new stream.PassThrough(); + const outputStream = new stream.PassThrough(); + outputStream.accum = ''; + + outputStream.on('data', (data) => { + outputStream.accum += data; + }); + + return repl.start({ + input: inputStream, + output: outputStream, + useColors: false, + terminal: false, + prompt: '', + replMode: mode + }); +} + +function assertOutput(output, expected) { + const lines = output.accum.trim().split('\n'); + assert.deepStrictEqual(lines, expected); +} |