feat: add support for the safe navigation (aka Elvis) operator
fixes #791
This commit is contained in:
@ -151,7 +151,7 @@ export function main() {
|
||||
expect(executeWatch('const', '"a\n\nb"')).toEqual(['const=a\n\nb']);
|
||||
});
|
||||
|
||||
it('simple chained property access', () => {
|
||||
it('should support simple chained property access', () => {
|
||||
var address = new Address('Grenoble');
|
||||
var person = new Person('Victor', address);
|
||||
|
||||
@ -159,6 +159,18 @@ export function main() {
|
||||
.toEqual(['address.city=Grenoble']);
|
||||
});
|
||||
|
||||
it('should support the safe navigation operator', () => {
|
||||
var person = new Person('Victor', null);
|
||||
|
||||
expect(executeWatch('city', 'address?.city', person)).toEqual(['city=null']);
|
||||
expect(executeWatch('city', 'address?.toString()', person)).toEqual(['city=null']);
|
||||
|
||||
person.address = new Address('MTV');
|
||||
|
||||
expect(executeWatch('city', 'address?.city', person)).toEqual(['city=MTV']);
|
||||
expect(executeWatch('city', 'address?.toString()', person)).toEqual(['city=MTV']);
|
||||
});
|
||||
|
||||
it("should support method calls", () => {
|
||||
var person = new Person('Victor');
|
||||
expect(executeWatch('m', 'sayHi("Jim")', person)).toEqual(['m=Hi, Jim']);
|
||||
@ -976,7 +988,7 @@ class Address {
|
||||
city: string;
|
||||
constructor(city: string) { this.city = city; }
|
||||
|
||||
toString(): string { return this.city; }
|
||||
toString(): string { return isBlank(this.city) ? '-' : this.city }
|
||||
}
|
||||
|
||||
class Uninitialized {
|
||||
|
@ -126,14 +126,14 @@ export function main() {
|
||||
expectIdentifierToken(tokens[1], 8, 'b');
|
||||
});
|
||||
|
||||
it('should tokenize quoted string', function() {
|
||||
it('should tokenize quoted string', () => {
|
||||
var str = "['\\'', \"\\\"\"]";
|
||||
var tokens: List<Token> = lex(str);
|
||||
expectStringToken(tokens[1], 1, "'");
|
||||
expectStringToken(tokens[3], 7, '"');
|
||||
});
|
||||
|
||||
it('should tokenize escaped quoted string', function() {
|
||||
it('should tokenize escaped quoted string', () => {
|
||||
var str = '"\\"\\n\\f\\r\\t\\v\\u00A0"';
|
||||
var tokens: List<Token> = lex(str);
|
||||
expect(tokens.length).toEqual(1);
|
||||
@ -203,7 +203,7 @@ export function main() {
|
||||
});
|
||||
|
||||
// NOTE(deboer): NOT A LEXER TEST
|
||||
// it('should tokenize negative number', function() {
|
||||
// it('should tokenize negative number', () => {
|
||||
// var tokens:List<Token> = lex("-0.5");
|
||||
// expectNumberToken(tokens[0], 0, -0.5);
|
||||
// });
|
||||
@ -240,6 +240,11 @@ export function main() {
|
||||
expectOperatorToken(tokens[0], 0, '#');
|
||||
});
|
||||
|
||||
it('should tokenize ?. as operator', () => {
|
||||
var tokens: List<Token> = lex('?.');
|
||||
expectOperatorToken(tokens[0], 0, '?.');
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {ddescribe, describe, it, xit, iit, expect, beforeEach} from 'angular2/test_lib';
|
||||
import {ddescribe, describe, it, xit, iit, expect, beforeEach, IS_DARTIUM} from 'angular2/test_lib';
|
||||
import {BaseException, isBlank, isPresent} from 'angular2/src/facade/lang';
|
||||
import {reflector} from 'angular2/src/reflection/reflection';
|
||||
import {MapWrapper, ListWrapper} from 'angular2/src/facade/collection';
|
||||
@ -202,6 +202,33 @@ export function main() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('safe navigation operator', () => {
|
||||
it('should parse field access', () => {
|
||||
expectEval('a?.a', td(td(999))).toEqual(999);
|
||||
expectEval('a.a?.a', td(td(td(999)))).toEqual(999);
|
||||
});
|
||||
|
||||
it('should return null when accessing a field on null',
|
||||
() => { expect(() => { expectEval('null?.a', td()).toEqual(null); }).not.toThrow(); });
|
||||
|
||||
it('should have the same priority as .', () => {
|
||||
expect(() => { expectEval('null?.a.a', td()).toEqual(null); }).toThrowError();
|
||||
});
|
||||
|
||||
if (!IS_DARTIUM) {
|
||||
it('should return null when accessing a field on undefined', () => {
|
||||
expect(() => { expectEval('_undefined?.a', td()).toEqual(null); }).not.toThrow();
|
||||
});
|
||||
}
|
||||
|
||||
it('should evaluate method calls',
|
||||
() => { expectEval('a?.add(1,2)', td(td())).toEqual(3); });
|
||||
|
||||
it('should return null when accessing a method on null', () => {
|
||||
expect(() => { expectEval('null?.add(1, 2)', td()).toEqual(null); }).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe("method calls", () => {
|
||||
it("should evaluate method calls", () => {
|
||||
expectEval("fn()", td(0, 0, "constant")).toEqual("constant");
|
||||
|
Reference in New Issue
Block a user