diff --git a/test/core/change_detection/binding_test.dart b/test/core/change_detection/binding_test.dart index defbb6492b..1468da5319 100644 --- a/test/core/change_detection/binding_test.dart +++ b/test/core/change_detection/binding_test.dart @@ -108,6 +108,10 @@ void main() { await new _GetValue().runTest(); }); + test('should support a function call', () async { + await new _GetValue().runTest(); + }); + test('should support assigning explicitly to null', () async { await new _GetValue().runTest(); }); @@ -510,6 +514,22 @@ class TestChainedPropertyAccess implements ValueTest { get expected => isTrue; } +@Component( + selector: 'test', + directives: const [ChildComponent], + template: r'''''', +) +class TestFunctionCall implements ValueTest { + @ViewChild(ChildComponent) + @override + ChildComponent child; + + get list => const ['foo', 'bar']; + + @override + get expected => isTrue; +} + @Component( selector: 'test', directives: const [ChildComponent], diff --git a/test/core/change_detection/container_test.dart b/test/core/change_detection/container_test.dart new file mode 100644 index 0000000000..a83d0999f5 --- /dev/null +++ b/test/core/change_detection/container_test.dart @@ -0,0 +1,136 @@ +@TestOn('browser') +import 'package:angular2/angular2.dart'; +import 'package:angular_test/angular_test.dart'; +import 'package:test/test.dart'; + +void main() { + tearDown(disposeAnyRunningTest); + + test('should *not* assign any values if the initial value is null', () async { + final fixture = await new NgTestBed().create(); + await fixture.update(expectAsync1((comp) { + expect(comp.child.updates, 0, reason: 'No changes should have happened'); + expect(comp.child.value, isNull); + })); + }); + + test('should propagate null if the initial value is non-null', () async { + final fixture = await new NgTestBed().create( + beforeChangeDetection: (comp) => comp.boundValue = 'Hello', + ); + await fixture.update(expectAsync1((comp) { + expect(comp.child.updates, 1, reason: 'One CD should have happened'); + expect(comp.child.value, 'Hello'); + comp.boundValue = null; + })); + await fixture.update(expectAsync1((comp) { + expect(comp.child.updates, 2, reason: 'Two CDs should have happened'); + expect(comp.child.value, isNull); + })); + }); + + test('should not recreate literal maps unless content changes', () async { + Map boundMap; + final fixture = await new NgTestBed().create( + beforeChangeDetection: (comp) { + comp.value = 'bar'; + }, + ); + await fixture.update(expectAsync1((comp) { + boundMap = comp.child.value; + expect(boundMap, {'key': 'bar'}); + })); + await fixture.update(expectAsync1((comp) { + expect(boundMap, same(comp.child.value), reason: 'Should be identical'); + comp.value = 'foo'; + })); + await fixture.update(expectAsync1((comp) { + expect(comp.child.value, {'key': 'foo'}); + })); + }); + + test('should not recreate literal lists unless content changes', () async { + List boundList; + final fixture = await new NgTestBed().create( + beforeChangeDetection: (comp) { + comp.value = 'bar'; + }, + ); + await fixture.update(expectAsync1((comp) { + boundList = comp.child.value; + expect(boundList, ['bar']); + })); + await fixture.update(expectAsync1((comp) { + expect(boundList, same(comp.child.value), reason: 'Should be identical'); + comp.value = 'foo'; + })); + await fixture.update(expectAsync1((comp) { + expect(comp.child.value, ['foo']); + })); + }); + + test('should support interpolation', () async { + final fixture = await new NgTestBed().create( + beforeChangeDetection: (comp) => comp.boundValue = 'Hello World', + ); + expect(fixture.text, 'Hello World'); + }); + + test('should output empty for null values in interpolation', () async { + final fixture = await new NgTestBed().create(); + expect(fixture.text, isEmpty); + }); +} + +@Component( + selector: 'child', + template: r'{{value}}', +) +class ChildComponent { + var _value; + var updates = 0; + + @Input() + set value(value) { + updates++; + _value = value; + } + + get value => _value; +} + +@Component( + selector: 'test', + directives: const [ChildComponent], + template: '', +) +class BoundValueTest { + var boundValue; + + @ViewChild(ChildComponent) + ChildComponent child; +} + +@Component( + selector: 'test', + directives: const [ChildComponent], + template: r'''''', +) +class BoundMapTest { + var value; + + @ViewChild(ChildComponent) + ChildComponent child; +} + +@Component( + selector: 'test', + directives: const [ChildComponent], + template: r'''''', +) +class BoundListTest { + var value; + + @ViewChild(ChildComponent) + ChildComponent child; +}