fix: find variable in parent scope (strict_variables)

This commit is contained in:
harttle
2016-11-08 21:01:25 +08:00
parent fd9fed154c
commit 295eee8134
5 changed files with 50 additions and 21 deletions
+12 -3
View File
@@ -1,7 +1,6 @@
const _ = require('./util/underscore.js'); const _ = require('./util/underscore.js');
const lexical = require('./lexical.js'); const lexical = require('./lexical.js');
const assert = require('./util/assert.js'); const assert = require('./util/assert.js');
const referenceError = /undefined variable|Cannot read property .* of undefined/;
var Scope = { var Scope = {
getAll: function() { getAll: function() {
@@ -16,13 +15,23 @@ var Scope = {
try { try {
return this.getPropertyByPath(this.scopes[i], str); return this.getPropertyByPath(this.scopes[i], str);
} catch (e) { } catch (e) {
if (!referenceError.test(e.message) || this.opts.strict_variables) { if (/undefined variable/.test(e.message)) {
continue;
}
if (/Cannot read property/.test(e.message)) {
if (this.opts.strict_variables) {
e.message += ': ' + str;
throw e;
} else {
continue;
}
} else {
e.message += ': ' + str; e.message += ': ' + str;
throw e; throw e;
} }
} }
} }
if(this.opts.strict_variables){ if (this.opts.strict_variables) {
throw new TypeError('undefined variable: ' + str); throw new TypeError('undefined variable: ' + str);
} }
}, },
+4
View File
@@ -14,7 +14,11 @@ TokenizationError.prototype.constructor = TokenizationError;
function ParseError(message, input, line, e) { function ParseError(message, input, line, e) {
if(Error.captureStackTrace){ if(Error.captureStackTrace){
Error.captureStackTrace(this, this.constructor); Error.captureStackTrace(this, this.constructor);
} else{
this.stack = "";
} }
this.stack += (this.stack ? "\nFrom " : "From ") + e.stack;
this.name = this.constructor.name; this.name = this.constructor.name;
this.originalError = e; this.originalError = e;
+28 -15
View File
@@ -71,21 +71,6 @@ describe('scope', function() {
}).to.throw(/unbalanced '/); }).to.throw(/unbalanced '/);
}); });
it('should throw undefined in strict mode', function() {
scope = Scope.factory(ctx, {
strict_variables: true
});
function fn() {
scope.get('notdefined');
}
expect(fn).to.throw(/undefined variable: notdefined/);
});
it('should get all properties when arguments empty', function() {
expect(scope.getAll()).deep.equal(ctx);
});
it('should access child property via dot syntax', function() { it('should access child property via dot syntax', function() {
expect(scope.get('bar.zoo')).to.equal('coo'); expect(scope.get('bar.zoo')).to.equal('coo');
expect(scope.get('bar.arr')).to.deep.equal(['a', 'b']); expect(scope.get('bar.arr')).to.deep.equal(['a', 'b']);
@@ -116,6 +101,34 @@ describe('scope', function() {
}); });
}); });
describe('strict_variables', function() {
var scope;
beforeEach(function(){
scope = Scope.factory(ctx, {
strict_variables: true
});
});
it('should throw undefined in strict mode', function() {
function fn() {
scope.get('notdefined');
}
expect(fn).to.throw(/undefined variable: notdefined/);
});
it('should find variable in parent scope', function() {
scope.set('foo', 'foo');
scope.push({
'bar': 'bar'
});
expect(scope.get('foo')).to.equal('foo');
});
});
describe('.getAll()', function() {
it('should get all properties when arguments empty', function() {
expect(scope.getAll()).deep.equal(ctx);
});
});
describe('.push()', function() { describe('.push()', function() {
it('should throw when trying to push non-object', function() { it('should throw when trying to push non-object', function() {
expect(function() { expect(function() {
+4 -2
View File
@@ -29,8 +29,10 @@ describe('tags/include', function() {
mock({ mock({
'/illegal.html': '{%include%}', '/illegal.html': '{%include%}',
}); });
return expect(liquid.renderFile('/illegal.html')).to. return liquid.renderFile('/illegal.html').catch(function(e){
be.rejectedWith(ParseError, /illegal token {%include%}/); expect(e.name).to.equal('ParseError');
expect(e.message).to.match(/illegal token {%include%}/);
});
}); });
it('should support include with relative path', function() { it('should support include with relative path', function() {
+2 -1
View File
@@ -66,7 +66,8 @@ describe('error', function() {
return engine.parseAndRender(src).catch(function(err) { return engine.parseAndRender(src).catch(function(err) {
expect(err.name).to.equal('ParseError'); expect(err.name).to.equal('ParseError');
expect(err.input).to.equal('{% -a %}'); expect(err.input).to.equal('{% -a %}');
expect(err.line).to.equal(3); expect(err.line).to.equal(3)
expect(err.stack).to.contain('From AssertionError: tag -a not found');
}); });
}); });
it('should throw correct error info for files', function() { it('should throw correct error info for files', function() {