Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(410)

Unified Diff: third_party/pkg/angular/test/core/parser/parser_spec.dart

Issue 257423008: Update all Angular libs (run update_all.sh). (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/pkg/angular/test/core/parser/parser_spec.dart
diff --git a/third_party/pkg/angular/test/core/parser/parser_spec.dart b/third_party/pkg/angular/test/core/parser/parser_spec.dart
index 6db4a5b3fc5977aac042de390b8843bea5b6dbfe..0957470a1c33b00849ccae23a74773c5fde68df4 100644
--- a/third_party/pkg/angular/test/core/parser/parser_spec.dart
+++ b/third_party/pkg/angular/test/core/parser/parser_spec.dart
@@ -10,6 +10,8 @@ class TestData {
set str(x) => _str = x;
method() => "testMethod";
+ sub1(a, {b: 0}) => a - b;
+ sub2({a: 0, b: 0}) => a - b;
}
class Ident {
@@ -47,18 +49,20 @@ main() {
describe('parse', () {
Map<String, dynamic> context;
Parser<Expression> parser;
- FilterMap filters;
- beforeEach(module((Module module) {
+ FormatterMap formatters;
+
+ beforeEachModule((Module module) {
module.type(IncrementFilter);
module.type(SubstringFilter);
- }));
- beforeEach(inject((Parser injectedParser, FilterMap injectedFilters) {
+ });
+
+ beforeEach((Parser injectedParser, FormatterMap injectedFilters) {
parser = injectedParser;
- filters = injectedFilters;
- }));
+ formatters = injectedFilters;
+ });
- eval(String text, [FilterMap f])
- => parser(text).eval(context, f == null ? filters : f);
+ eval(String text, [FormatterMap f]) =>
+ parser(text).eval(context, f == null ? formatters : f);
expectEval(String expr) => expect(() => eval(expr));
beforeEach((){ context = {}; });
@@ -154,9 +158,9 @@ main() {
describe('error handling', () {
Parser<Expression> parser;
- beforeEach(inject((Parser p) {
+ beforeEach((Parser p) {
parser = p;
- }));
+ });
// We only care about the error strings in the DynamicParser.
var errStr = (x) {
@@ -190,6 +194,10 @@ main() {
expectEval("4()").toThrow('4 is not a function');
});
+ it("should throw on an unexpected token", (){
+ expectEval("[1,2] trac")
+ .toThrow('Parser Error: \'trac\' is an unexpected token at column 7 in [[1,2] trac]');
+ });
it('should fail gracefully when invoking non-function', () {
expect(() {
@@ -274,7 +282,8 @@ main() {
context['map'] = {};
expect(eval('null')).toBe(null);
- expect(eval('map.null')).toBe(null);
+ expect(() => eval('map.null'))
+ .toThrow("Identifier 'null' is a reserved word.");
});
@@ -283,6 +292,20 @@ main() {
});
+ it('should eval binary operators with null as null', () {
+ expect(eval("null < 0")).toEqual(null);
+ expect(eval("null * 3")).toEqual(null);
+
+ // But + and - are special cases.
+ expect(eval("null + 6")).toEqual(6);
+ expect(eval("5 + null")).toEqual(5);
+ expect(eval("null - 4")).toEqual(-4);
+ expect(eval("3 - null")).toEqual(3);
+ expect(eval("null + null")).toEqual(0);
+ expect(eval("null - null")).toEqual(0);
+ });
+
+
it('should pass exceptions through getters', () {
expect(() {
parser('boo').eval(new ScopeWithErrors());
@@ -290,10 +313,13 @@ main() {
});
- it('should pass noSuchMethExceptions through getters', () {
+ it('should pass noSuchMethodExceptions through getters', () {
expect(() {
parser('getNoSuchMethod').eval(new ScopeWithErrors());
- }).toThrow("iDontExist");
+ }).toThrow("null");
+ // Dartium throws: The null object does not have a method 'iDontExist'
+ // Chrome throws: NullError: Cannot call "iDontExist$0" on null
+ // Firefox throws: NullError: null has no properties
});
@@ -310,6 +336,7 @@ main() {
}).toThrow("notAProperty");
});
+
it('should fail on private field access', () {
expect(parser('publicField').eval(new WithPrivateField())).toEqual(4);
// On Dartium, this fails with "NoSuchMethod: no instance getter"
@@ -319,6 +346,26 @@ main() {
parser('_privateField').eval(new WithPrivateField());
}).toThrow();
});
+
+
+ it('should only allow identifier or keyword as formatter names', () {
+ expect(() => parser('"Foo"|(')).toThrow('identifier or keyword');
+ expect(() => parser('"Foo"|1234')).toThrow('identifier or keyword');
+ expect(() => parser('"Foo"|"uppercase"')).toThrow('identifier or keyword');
+ });
+
+
+ it('should only allow identifier or keyword as member names', () {
+ expect(() => parser('x.(')).toThrow('identifier or keyword');
+ expect(() => parser('x. 1234')).toThrow('identifier or keyword');
+ expect(() => parser('x."foo"')).toThrow('identifier or keyword');
+ });
+
+
+ it('should only allow identifier, string, or keyword as object literal key', () {
+ expect(() => parser('{(:0}')).toThrow('expected identifier, keyword, or string');
+ expect(() => parser('{1234:0}')).toThrow('expected identifier, keyword, or string');
+ });
});
describe('setters', () {
@@ -397,8 +444,8 @@ main() {
});
});
- describe('reserved words', () {
- it('should support reserved words in member get access', () {
+ xdescribe('reserved words', () {
+ iit('should support reserved words in member get access', () {
for (String reserved in RESERVED_WORDS) {
expect(parser("o.$reserved").eval({ 'o': new Object() })).toEqual(null);
expect(parser("o.$reserved").eval({ 'o': { reserved: reserved }})).toEqual(reserved);
@@ -632,16 +679,15 @@ main() {
expect(eval("constN()")).toEqual(123);
});
+
it('should access a protected keyword on scope', () {
context['const'] = 3;
- expect(eval('const')).toEqual(3);
+ expect(eval('this["const"]')).toEqual(3);
});
- it('should evaluate function call with arguments', () {
- context["add"] = (a,b) {
- return a+b;
- };
+ it('should evaluate scope call with arguments', () {
+ context["add"] = (a,b) => a + b;
expect(eval("add(1,2)")).toEqual(3);
});
@@ -900,6 +946,7 @@ main() {
});
});
+
describe('assignable', () {
it('should expose assignment function', () {
var fn = parser('a');
@@ -910,6 +957,7 @@ main() {
});
});
+
describe('locals', () {
it('should expose local variables', () {
expect(parser('a').bind({'a': 6}, ScopeLocals.wrapper)({'a': 1})).toEqual(1);
@@ -925,10 +973,10 @@ main() {
});
- it('should work with scopes', inject((Scope scope) {
+ it('should work with scopes', (Scope scope) {
scope.context['a'] = {'b': 6};
expect(parser('a.b').bind(scope.context, ScopeLocals.wrapper)({'a': {'b':1}})).toEqual(1);
- }));
+ });
it('should expose assignment function', () {
var fn = parser('a.b');
@@ -942,51 +990,176 @@ main() {
});
- describe('filters', () {
- it('should call a filter', () {
- expect(eval("'Foo'|uppercase", filters)).toEqual("FOO");
- expect(eval("'fOo'|uppercase|lowercase", filters)).toEqual("foo");
+ describe('named arguments', () {
+ it('should be supported for scope calls', () {
+ var data = new TestData();
+ expect(parser("sub1(1)").eval(data)).toEqual(1);
+ expect(parser("sub1(3, b: 2)").eval(data)).toEqual(1);
+
+ expect(parser("sub2()").eval(data)).toEqual(0);
+ expect(parser("sub2(a: 3)").eval(data)).toEqual(3);
+ expect(parser("sub2(a: 3, b: 2)").eval(data)).toEqual(1);
+ expect(parser("sub2(b: 4)").eval(data)).toEqual(-4);
+ });
+
+
+ it('should be supported for scope calls (map)', () {
+ context["sub1"] = (a, {b: 0}) => a - b;
+ expect(eval("sub1(1)")).toEqual(1);
+ expect(eval("sub1(3, b: 2)")).toEqual(1);
+
+ context["sub2"] = ({a: 0, b: 0}) => a - b;
+ expect(eval("sub2()")).toEqual(0);
+ expect(eval("sub2(a: 3)")).toEqual(3);
+ expect(eval("sub2(a: 3, b: 2)")).toEqual(1);
+ expect(eval("sub2(b: 4)")).toEqual(-4);
+ });
+
+
+ it('should be supported for member calls', () {
+ context['o'] = new TestData();
+ expect(eval("o.sub1(1)")).toEqual(1);
+ expect(eval("o.sub1(3, b: 2)")).toEqual(1);
+
+ expect(eval("o.sub2()")).toEqual(0);
+ expect(eval("o.sub2(a: 3)")).toEqual(3);
+ expect(eval("o.sub2(a: 3, b: 2)")).toEqual(1);
+ expect(eval("o.sub2(b: 4)")).toEqual(-4);
+ });
+
+
+ it('should be supported for member calls (map)', () {
+ context['o'] = {
+ 'sub1': (a, {b: 0}) => a - b,
+ 'sub2': ({a: 0, b: 0}) => a - b
+ };
+ expect(eval("o.sub1(1)")).toEqual(1);
+ expect(eval("o.sub1(3, b: 2)")).toEqual(1);
+
+ expect(eval("o.sub2()")).toEqual(0);
+ expect(eval("o.sub2(a: 3)")).toEqual(3);
+ expect(eval("o.sub2(a: 3, b: 2)")).toEqual(1);
+ expect(eval("o.sub2(b: 4)")).toEqual(-4);
+ });
+
+
+ it('should be supported for function calls', () {
+ context["sub1"] = (a, {b: 0}) => a - b;
+ expect(eval("(sub1)(1)")).toEqual(1);
+ expect(eval("(sub1)(3, b: 2)")).toEqual(1);
+
+ context["sub2"] = ({a: 0, b: 0}) => a - b;
+ expect(eval("(sub2)()")).toEqual(0);
+ expect(eval("(sub2)(a: 3)")).toEqual(3);
+ expect(eval("(sub2)(a: 3, b: 2)")).toEqual(1);
+ expect(eval("(sub2)(b: 4)")).toEqual(-4);
+ });
+
+
+ it('should be an error to use the same name twice', () {
+ expect(() => parser('foo(a: 0, a: 1)')).toThrow("Duplicate argument named 'a' at column 11");
+ expect(() => parser('foo(a: 0, b: 1, a: 2)')).toThrow("Duplicate argument named 'a' at column 17");
+ expect(() => parser('foo(0, a: 1, a: 2)')).toThrow("Duplicate argument named 'a' at column 14");
+ expect(() => parser('foo(0, a: 1, b: 2, a: 3)')).toThrow("Duplicate argument named 'a' at column 20");
+ });
+
+
+ it('should be an error to use Dart reserved words as names', () {
+ expect(() => parser('foo(if: 0)')).toThrow("Cannot use Dart reserved word 'if' as named argument at column 5");
+ expect(() => parser('foo(a: 0, class: 0)')).toThrow("Cannot use Dart reserved word 'class' as named argument at column 11");
+ });
+
+
+ it('should pretty print scope calls correctly', () {
+ expect(parser('foo(a: 0)').toString()).toEqual('foo(a: 0)');
+ expect(parser('foo(a: 0, b: 1)').toString()).toEqual('foo(a: 0, b: 1)');
+ expect(parser('foo(b: 1, a: 0)').toString()).toEqual('foo(b: 1, a: 0)');
+
+ expect(parser('foo(0)').toString()).toEqual('foo(0)');
+ expect(parser('foo(0, a: 0)').toString()).toEqual('foo(0, a: 0)');
+ expect(parser('foo(0, a: 0, b: 1)').toString()).toEqual('foo(0, a: 0, b: 1)');
+ expect(parser('foo(0, b: 1, a: 0)').toString()).toEqual('foo(0, b: 1, a: 0)');
+ });
+
+
+ it('should pretty print member calls correctly', () {
+ expect(parser('o.foo(a: 0)').toString()).toEqual('o.foo(a: 0)');
+ expect(parser('o.foo(a: 0, b: 1)').toString()).toEqual('o.foo(a: 0, b: 1)');
+ expect(parser('o.foo(b: 1, a: 0)').toString()).toEqual('o.foo(b: 1, a: 0)');
+
+ expect(parser('o.foo(0)').toString()).toEqual('o.foo(0)');
+ expect(parser('o.foo(0, a: 0)').toString()).toEqual('o.foo(0, a: 0)');
+ expect(parser('o.foo(0, a: 0, b: 1)').toString()).toEqual('o.foo(0, a: 0, b: 1)');
+ expect(parser('o.foo(0, b: 1, a: 0)').toString()).toEqual('o.foo(0, b: 1, a: 0)');
+ });
+
+
+ it('should pretty print function calls correctly', () {
+ expect(parser('(foo)(a: 0)').toString()).toEqual('(foo)(a: 0)');
+ expect(parser('(foo)(a: 0, b: 1)').toString()).toEqual('(foo)(a: 0, b: 1)');
+ expect(parser('(foo)(b: 1, a: 0)').toString()).toEqual('(foo)(b: 1, a: 0)');
+
+ expect(parser('(foo)(0)').toString()).toEqual('(foo)(0)');
+ expect(parser('(foo)(0, a: 0)').toString()).toEqual('(foo)(0, a: 0)');
+ expect(parser('(foo)(0, a: 0, b: 1)').toString()).toEqual('(foo)(0, a: 0, b: 1)');
+ expect(parser('(foo)(0, b: 1, a: 0)').toString()).toEqual('(foo)(0, b: 1, a: 0)');
+ });
+ });
+
+
+ describe('formatters', () {
+ it('should call a formatter', () {
+ expect(eval("'Foo'|uppercase", formatters)).toEqual("FOO");
+ // Re-enable after static parser is removed
+ //expect(eval("'f' + ('o'|uppercase) + 'o'", formatters)).toEqual("fOo");
+ expect(eval("'fOo'|uppercase|lowercase", formatters)).toEqual("foo");
+ });
+
+ it('should call a formatter with arguments', () {
+ expect(eval("1|increment:2", formatters)).toEqual(3);
});
- it('should call a filter with arguments', () {
- expect(eval("1|increment:2", filters)).toEqual(3);
+ it('should evaluate grouped formatters', () {
+ context = {'name': 'MISKO'};
+ expect(eval('n = (name|lowercase)', formatters)).toEqual('misko');
+ expect(eval('n')).toEqual('misko');
});
- it('should parse filters', () {
+ it('should parse formatters', () {
expect(() {
eval("1|nonexistent");
- }).toThrow('No NgFilter: nonexistent found!');
+ }).toThrow('No Formatter: nonexistent found!');
expect(() {
- eval("1|nonexistent", filters);
- }).toThrow('No NgFilter: nonexistent found!');
+ eval("1|nonexistent", formatters);
+ }).toThrow('No Formatter: nonexistent found!');
context['offset'] = 3;
expect(eval("'abcd'|substring:1:offset")).toEqual("bc");
expect(eval("'abcd'|substring:1:3|uppercase")).toEqual("BC");
});
- it('should only use filters that are passed as an argument', inject((Injector injector) {
+ it('should only use formatters that are passed as an argument', (Injector injector) {
var expression = parser("'World'|hello");
expect(() {
- expression.eval({}, filters);
- }).toThrow('No NgFilter: hello found!');
+ expression.eval({}, formatters);
+ }).toThrow('No Formatter: hello found!');
var module = new Module()
..type(HelloFilter);
var childInjector = injector.createChild([module],
- forceNewInstances: [FilterMap]);
- var newFilters = childInjector.get(FilterMap);
+ forceNewInstances: [FormatterMap]);
+ var newFilters = childInjector.get(FormatterMap);
expect(expression.eval({}, newFilters)).toEqual('Hello, World!');
- }));
+ });
- it('should not allow filters in a chain', () {
+ it('should not allow formatters in a chain', () {
expect(() {
parser("1;'World'|hello");
- }).toThrow('cannot have a filter in a chain the end of the expression [1;\'World\'|hello]');
+ }).toThrow('Cannot have a formatter in a chain the end of the expression [1;\'World\'|hello]');
expect(() {
parser("'World'|hello;1");
- }).toThrow('cannot have a filter in a chain at column 15 in [\'World\'|hello;1]');
+ }).toThrow('Cannot have a formatter in a chain at column 15 in [\'World\'|hello;1]');
});
});
});
@@ -1024,19 +1197,19 @@ class ScopeWithErrors {
get getNoSuchMethod => null.iDontExist();
}
-@NgFilter(name:'increment')
+@Formatter(name:'increment')
class IncrementFilter {
call(a, b) => a + b;
}
-@NgFilter(name:'substring')
+@Formatter(name:'substring')
class SubstringFilter {
call(String str, startIndex, [endIndex]) {
return str.substring(startIndex, endIndex);
}
}
-@NgFilter(name:'hello')
+@Formatter(name:'hello')
class HelloFilter {
call(String str) {
return 'Hello, $str!';

Powered by Google App Engine
This is Rietveld 408576698