refactor(view): separate context and locals

This commit is contained in:
vsavkin
2015-03-11 21:11:39 -07:00
parent 70c875ee14
commit a16954d3a5
30 changed files with 450 additions and 419 deletions

View File

@ -4,7 +4,7 @@ import {reflector} from 'angular2/src/reflection/reflection';
import {MapWrapper, ListWrapper} from 'angular2/src/facade/collection';
import {Parser} from 'angular2/src/change_detection/parser/parser';
import {Lexer} from 'angular2/src/change_detection/parser/lexer';
import {ContextWithVariableBindings} from 'angular2/src/change_detection/parser/context_with_variable_bindings';
import {Locals} from 'angular2/src/change_detection/parser/locals';
import {Pipe, LiteralPrimitive} from 'angular2/src/change_detection/parser/ast';
class TestData {
@ -55,21 +55,27 @@ export function main() {
return createParser().addPipes(ast, pipes);
}
function expectEval(text, passedInContext = null) {
var c = isBlank(passedInContext) ? td() : passedInContext;
return expect(parseAction(text).eval(c));
function emptyLocals() {
return new Locals(null, MapWrapper.create());
}
function expectEvalError(text, passedInContext = null) {
function expectEval(text, passedInContext = null, passedInLocals = null) {
var c = isBlank(passedInContext) ? td() : passedInContext;
return expect(() => parseAction(text).eval(c));
var l = isBlank(passedInLocals) ? emptyLocals() : passedInLocals;
return expect(parseAction(text).eval(c, l));
}
function expectEvalError(text, passedInContext = null, passedInLocals = null) {
var c = isBlank(passedInContext) ? td() : passedInContext;
var l = isBlank(passedInLocals) ? emptyLocals() : passedInLocals;
return expect(() => parseAction(text).eval(c, l));
}
function evalAsts(asts, passedInContext = null) {
var c = isBlank(passedInContext) ? td() : passedInContext;
var res = [];
for (var i=0; i<asts.length; i++) {
ListWrapper.push(res, asts[i].eval(c));
ListWrapper.push(res, asts[i].eval(c, emptyLocals()));
}
return res;
}
@ -188,23 +194,23 @@ export function main() {
expectEvalError('x."foo"').toThrowError(new RegExp('identifier or keyword'));
});
it("should read a field from ContextWithVariableBindings", () => {
var locals = new ContextWithVariableBindings(null,
MapWrapper.createFromPairs([["key", "value"]]));
expectEval("key", locals).toEqual("value");
it("should read a field from Locals", () => {
var locals = new Locals(null,
MapWrapper.createFromPairs([["key", "value"]]));
expectEval("key", null, locals).toEqual("value");
});
it("should handle nested ContextWithVariableBindings", () => {
var nested = new ContextWithVariableBindings(null,
MapWrapper.createFromPairs([["key", "value"]]));
var locals = new ContextWithVariableBindings(nested, MapWrapper.create());
expectEval("key", locals).toEqual("value");
it("should handle nested Locals", () => {
var nested = new Locals(null,
MapWrapper.createFromPairs([["key", "value"]]));
var locals = new Locals(nested, MapWrapper.create());
expectEval("key", null, locals).toEqual("value");
});
it("should fall back to a regular field read when ContextWithVariableBindings "+
"does not have the requested field", () => {
var locals = new ContextWithVariableBindings(td(999), MapWrapper.create());
expectEval("a", locals).toEqual(999);
it("should fall back to a regular field read when Locals "+
"does not have the requested field", () => {
var locals = new Locals(null, MapWrapper.create());
expectEval("a", td(999), locals).toEqual(999);
});
});
@ -216,25 +222,26 @@ export function main() {
expectEval("fn().add(1,2)", td(0, 0, td())).toEqual(3);
});
it('should throw when more than 10 arguments', () => {
expectEvalError("fn(1,2,3,4,5,6,7,8,9,10,11)").toThrowError(new RegExp('more than'));
});
it('should throw when no method', () => {
expectEvalError("blah()").toThrowError();
});
it('should evaluate a method from ContextWithVariableBindings', () => {
var context = new ContextWithVariableBindings(
td(0, 0, 'parent'),
it('should evaluate a method from Locals', () => {
var locals = new Locals(
null,
MapWrapper.createFromPairs([['fn', () => 'child']])
);
expectEval("fn()", context).toEqual('child');
expectEval("fn()", td(0, 0, 'parent'), locals).toEqual('child');
});
it('should fall back to the parent context when ContextWithVariableBindings does not ' +
'have the requested method', () => {
var context = new ContextWithVariableBindings(
td(0, 0, 'parent'),
MapWrapper.create()
);
expectEval("fn()", context).toEqual('parent');
it('should fall back to the parent context when Locals does not ' +
'have the requested method', () => {
var locals = new Locals(null, MapWrapper.create());
expectEval("fn()", td(0, 0, 'parent'), locals).toEqual('parent');
});
});
@ -314,14 +321,14 @@ export function main() {
it('should reassign when no variable binding with the given name', () => {
var context = td();
var locals = new ContextWithVariableBindings(context, MapWrapper.create());
expectEval('a = 200', locals).toEqual(200);
var locals = new Locals(null, MapWrapper.create());
expectEval('a = 200', context, locals).toEqual(200);
expect(context.a).toEqual(200);
});
it('should throw when reassigning a variable binding', () => {
var locals = new ContextWithVariableBindings(null, MapWrapper.createFromPairs([["key", "value"]]));
expectEvalError('key = 200', locals).toThrowError(new RegExp("Cannot reassign a variable binding"));
var locals = new Locals(null, MapWrapper.createFromPairs([["key", "value"]]));
expectEvalError('key = 200', null, locals).toThrowError(new RegExp("Cannot reassign a variable binding"));
});
});
@ -346,7 +353,7 @@ export function main() {
it('should pass exceptions', () => {
expect(() => {
parseAction('a()').eval(td(() => {throw new BaseException("boo to you")}));
parseAction('a()').eval(td(() => {throw new BaseException("boo to you")}), emptyLocals());
}).toThrowError('boo to you');
});
@ -579,9 +586,8 @@ export function main() {
describe('wrapLiteralPrimitive', () => {
it('should wrap a literal primitive', () => {
expect(createParser().wrapLiteralPrimitive("foo", null).eval(null)).toEqual("foo");
expect(createParser().wrapLiteralPrimitive("foo", null).eval(null, emptyLocals())).toEqual("foo");
});
});
});
}
}