diff --git a/index.js b/index.js index 7620e5b..c934992 100644 --- a/index.js +++ b/index.js @@ -40,12 +40,30 @@ module.exports = function (ast, vars) { } else if (node.type === 'BinaryExpression' || node.type === 'LogicalExpression') { + var op = node.operator; + + if (op === '&&') { + var l = walk(node.left); + if (l === FAIL) return FAIL; + if (!l) return l; + var r = walk(node.right); + if (r === FAIL) return FAIL; + return r; + } + else if (op === '||') { + var l = walk(node.left); + if (l === FAIL) return FAIL; + if (l) return l; + var r = walk(node.right); + if (r === FAIL) return FAIL; + return r; + } + var l = walk(node.left); if (l === FAIL) return FAIL; var r = walk(node.right); if (r === FAIL) return FAIL; - var op = node.operator; if (op === '==') return l == r; if (op === '===') return l === r; if (op === '!=') return l != r; @@ -62,8 +80,6 @@ module.exports = function (ast, vars) { if (op === '|') return l | r; if (op === '&') return l & r; if (op === '^') return l ^ r; - if (op === '&&') return l && r; - if (op === '||') return l || r; return FAIL; } diff --git a/test/eval.js b/test/eval.js index 4055b35..87cb6d9 100644 --- a/test/eval.js +++ b/test/eval.js @@ -121,3 +121,29 @@ test('constructor at runtime only', function(t) { var res = evaluate(ast); t.equal(res, undefined); }); + +test('short circuit evaluation AND', function(t) { + t.plan(1); + + var variables = { + value: null + }; + var src = 'value && value.func()'; + var ast = parse(src).body[0].expression; + var res = evaluate(ast, variables); + t.equals(res, null); +}) + +test('short circuit evaluation OR', function(t) { + t.plan(1); + + var fnInvoked = false; + var variables = { + value: true, + fn: function() { fnInvoked = true} + }; + var src = 'value || fn()'; + var ast = parse(src).body[0].expression; + evaluate(ast, variables); + t.equals(fnInvoked, false); +}) \ No newline at end of file