Index: pkg/template_binding/test/template_binding_test.dart |
diff --git a/pkg/template_binding/test/template_binding_test.dart b/pkg/template_binding/test/template_binding_test.dart |
index 7639d760f15063ea48f11e75125743a8a794b9ef..c2ac5a959303de8c13a974f6ac00612cb0837628 100644 |
--- a/pkg/template_binding/test/template_binding_test.dart |
+++ b/pkg/template_binding/test/template_binding_test.dart |
@@ -5,7 +5,6 @@ |
library template_binding.test.template_binding_test; |
import 'dart:async'; |
-import 'dart:collection'; |
import 'dart:html'; |
import 'dart:math' as math; |
import 'package:observe/observe.dart'; |
@@ -18,13 +17,13 @@ import 'binding_syntax.dart' show syntaxTests; |
import 'utils.dart'; |
// Note: this file ported from |
-// https://github.com/Polymer/TemplateBinding/blob/ed3266266e751b5ab1f75f8e0509d0d5f0ef35d8/tests/tests.js |
+// https://github.com/Polymer/TemplateBinding/blob/fcb7a502794f19544f2d4b77c96eebb70830591d/tests/tests.js |
// TODO(jmesserly): submit a small cleanup patch to original. I fixed some |
// cases where "div" and "t" were unintentionally using the JS global scope; |
// look for "assertNodesAre". |
-main() { |
+main() => dirtyCheckZone().run(() { |
useHtmlConfiguration(); |
// Load MutationObserver polyfill in case IE needs it. |
@@ -46,7 +45,7 @@ main() { |
expect(MutationObserver.supported, true, reason: 'polyfill was loaded.'); |
}); |
- group('Template Instantiation', templateInstantiationTests); |
+ group('Template', templateInstantiationTests); |
group('Binding Delegate API', () { |
group('with Observable', () { |
@@ -59,7 +58,7 @@ main() { |
}); |
group('Compat', compatTests); |
-} |
+}); |
var expando = new Expando('test'); |
void addExpandos(node) { |
@@ -78,237 +77,710 @@ void checkExpandos(node) { |
} |
templateInstantiationTests() { |
+ // Dart note: renamed some of these tests to have unique names |
- observeTest('Template', () { |
+ test('Bind (simple)', () { |
var div = createTestHtml('<template bind={{}}>text</template>'); |
templateBind(div.firstChild).model = {}; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 2); |
- expect(div.nodes.last.text, 'text'); |
+ return new Future(() { |
+ expect(div.nodes.length, 2); |
+ expect(div.nodes.last.text, 'text'); |
- templateBind(div.firstChild).model = null; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 1); |
+ // Dart note: null is used instead of undefined to clear the template. |
+ templateBind(div.firstChild).model = null; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 1); |
+ templateBind(div.firstChild).model = 123; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.nodes.last.text, 'text'); |
+ }); |
+ }); |
+ |
+ test('oneTime-Bind', () { |
+ var div = createTestHtml('<template bind="[[ bound ]]">text</template>'); |
+ var model = toObservable({'bound': 1}); |
+ templateBind(div.firstChild).model = model; |
+ return new Future(() { |
+ expect(div.nodes.length, 2); |
+ expect(div.nodes.last.text, 'text'); |
+ |
+ model['bound'] = false; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.nodes.last.text, 'text'); |
+ }); |
}); |
- observeTest('Template bind, no parent', () { |
+ test('Bind - no parent', () { |
var div = createTestHtml('<template bind>text</template>'); |
var template = div.firstChild; |
template.remove(); |
templateBind(template).model = {}; |
- performMicrotaskCheckpoint(); |
- expect(template.nodes.length, 0); |
- expect(template.nextNode, null); |
+ return new Future(() { |
+ expect(template.nodes.length, 0); |
+ expect(template.nextNode, null); |
+ }); |
}); |
- observeTest('Template bind, no defaultView', () { |
+ test('Bind - no defaultView', () { |
var div = createTestHtml('<template bind>text</template>'); |
var template = div.firstChild; |
var doc = document.implementation.createHtmlDocument(''); |
doc.adoptNode(div); |
recursivelySetTemplateModel(template, {}); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 1); |
+ return new Future(() => expect(div.nodes.length, 1)); |
}); |
- observeTest('Template-Empty Bind', () { |
+ test('Empty Bind', () { |
var div = createTestHtml('<template bind>text</template>'); |
var template = div.firstChild; |
templateBind(template).model = {}; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 2); |
- expect(div.nodes.last.text, 'text'); |
+ return new Future(() { |
+ expect(div.nodes.length, 2); |
+ expect(div.nodes.last.text, 'text'); |
+ }); |
}); |
- observeTest('Template Bind If', () { |
- var div = createTestHtml('<template bind if="{{ foo }}">text</template>'); |
- // Note: changed this value from 0->null because zero is not falsey in Dart. |
+ test('Bind If', () { |
+ var div = createTestHtml( |
+ '<template bind="{{ bound }}" if="{{ predicate }}">' |
+ 'value:{{ value }}' |
+ '</template>'); |
+ // Dart note: predicate changed from 0->null because 0 isn't falsey in Dart. |
// See https://code.google.com/p/dart/issues/detail?id=11956 |
- var m = toObservable({ 'foo': null }); |
+ // Changed bound from null->1 since null is equivalent to JS undefined, |
+ // and would cause the template to not be expanded. |
+ var m = toObservable({ 'predicate': null, 'bound': 1 }); |
var template = div.firstChild; |
templateBind(template).model = m; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 1); |
+ return new Future(() { |
+ expect(div.nodes.length, 1); |
- m['foo'] = 1; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 2); |
- expect(div.lastChild.text, 'text'); |
+ m['predicate'] = 1; |
- templateBind(template).model = null; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 1); |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.lastChild.text, 'value:'); |
+ |
+ m['bound'] = toObservable({ 'value': 2 }); |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.lastChild.text, 'value:2'); |
+ |
+ m['bound']['value'] = 3; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.lastChild.text, 'value:3'); |
+ |
+ templateBind(template).model = null; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 1); |
+ }); |
+ }); |
+ |
+ test('Bind oneTime-If - predicate false', () { |
+ var div = createTestHtml( |
+ '<template bind="{{ bound }}" if="[[ predicate ]]">' |
+ 'value:{{ value }}' |
+ '</template>'); |
+ // Dart note: predicate changed from 0->null because 0 isn't falsey in Dart. |
+ // See https://code.google.com/p/dart/issues/detail?id=11956 |
+ // Changed bound from null->1 since null is equivalent to JS undefined, |
+ // and would cause the template to not be expanded. |
+ var m = toObservable({ 'predicate': null, 'bound': 1 }); |
+ var template = div.firstChild; |
+ templateBind(template).model = m; |
+ |
+ return new Future(() { |
+ expect(div.nodes.length, 1); |
+ |
+ m['predicate'] = 1; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 1); |
+ |
+ m['bound'] = toObservable({ 'value': 2 }); |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 1); |
+ |
+ m['bound']['value'] = 3; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 1); |
+ |
+ templateBind(template).model = null; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 1); |
+ }); |
+ }); |
+ |
+ test('Bind oneTime-If - predicate true', () { |
+ var div = createTestHtml( |
+ '<template bind="{{ bound }}" if="[[ predicate ]]">' |
+ 'value:{{ value }}' |
+ '</template>'); |
+ |
+ // Dart note: changed bound from null->1 since null is equivalent to JS |
+ // undefined, and would cause the template to not be expanded. |
+ var m = toObservable({ 'predicate': 1, 'bound': 1 }); |
+ var template = div.firstChild; |
+ templateBind(template).model = m; |
+ |
+ return new Future(() { |
+ expect(div.nodes.length, 2); |
+ expect(div.lastChild.text, 'value:'); |
+ |
+ m['bound'] = toObservable({ 'value': 2 }); |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.lastChild.text, 'value:2'); |
+ |
+ m['bound']['value'] = 3; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.lastChild.text, 'value:3'); |
+ |
+ m['predicate'] = null; // will have no effect |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.lastChild.text, 'value:3'); |
+ |
+ templateBind(template).model = null; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 1); |
+ }); |
+ }); |
+ |
+ test('oneTime-Bind If', () { |
+ var div = createTestHtml( |
+ '<template bind="[[ bound ]]" if="{{ predicate }}">' |
+ 'value:{{ value }}' |
+ '</template>'); |
+ |
+ var m = toObservable({'predicate': null, 'bound': {'value': 2}}); |
+ var template = div.firstChild; |
+ templateBind(template).model = m; |
+ |
+ return new Future(() { |
+ expect(div.nodes.length, 1); |
+ |
+ m['predicate'] = 1; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.lastChild.text, 'value:2'); |
+ |
+ m['bound']['value'] = 3; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.lastChild.text, 'value:3'); |
+ |
+ m['bound'] = toObservable({'value': 4 }); |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.lastChild.text, 'value:3'); |
+ |
+ templateBind(template).model = null; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 1); |
+ }); |
+ }); |
+ |
+ test('oneTime-Bind oneTime-If', () { |
+ var div = createTestHtml( |
+ '<template bind="[[ bound ]]" if="[[ predicate ]]">' |
+ 'value:{{ value }}' |
+ '</template>'); |
+ |
+ var m = toObservable({'predicate': 1, 'bound': {'value': 2}}); |
+ var template = div.firstChild; |
+ templateBind(template).model = m; |
+ |
+ return new Future(() { |
+ expect(div.nodes.length, 2); |
+ expect(div.lastChild.text, 'value:2'); |
+ |
+ m['bound']['value'] = 3; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.lastChild.text, 'value:3'); |
+ |
+ m['bound'] = toObservable({'value': 4 }); |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.lastChild.text, 'value:3'); |
+ |
+ m['predicate'] = false; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.lastChild.text, 'value:3'); |
+ |
+ templateBind(template).model = null; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 1); |
+ }); |
}); |
- observeTest('Template Bind If, 2', () { |
+ test('Bind If, 2', () { |
var div = createTestHtml( |
'<template bind="{{ foo }}" if="{{ bar }}">{{ bat }}</template>'); |
var m = toObservable({ 'bar': null, 'foo': { 'bat': 'baz' } }); |
recursivelySetTemplateModel(div, m); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 1); |
+ return new Future(() { |
+ expect(div.nodes.length, 1); |
- m['bar'] = 1; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 2); |
- expect(div.lastChild.text, 'baz'); |
+ m['bar'] = 1; |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.lastChild.text, 'baz'); |
+ }); |
}); |
- observeTest('Template If', () { |
+ test('If', () { |
var div = createTestHtml('<template if="{{ foo }}">{{ value }}</template>'); |
- // Note: changed this value from 0->null because zero is not falsey in |
- // Dart. See https://code.google.com/p/dart/issues/detail?id=11956 |
+ // Dart note: foo changed from 0->null because 0 isn't falsey in Dart. |
+ // See https://code.google.com/p/dart/issues/detail?id=11956 |
var m = toObservable({ 'foo': null, 'value': 'foo' }); |
var template = div.firstChild; |
templateBind(template).model = m; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 1); |
+ return new Future(() { |
+ expect(div.nodes.length, 1); |
- m['foo'] = 1; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 2); |
- expect(div.lastChild.text, 'foo'); |
+ m['foo'] = 1; |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.lastChild.text, 'foo'); |
- templateBind(template).model = null; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 1); |
+ templateBind(template).model = null; |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 1); |
+ }); |
}); |
- observeTest('Template Empty-If', () { |
+ test('Empty-If', () { |
var div = createTestHtml('<template if>{{ value }}</template>'); |
var m = toObservable({ 'value': 'foo' }); |
recursivelySetTemplateModel(div, null); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 1); |
+ return new Future(() { |
+ expect(div.nodes.length, 1); |
+ |
+ recursivelySetTemplateModel(div, m); |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.lastChild.text, 'foo'); |
+ }); |
+ }); |
+ |
+ test('OneTime - simple text', () { |
+ var div = createTestHtml('<template bind>[[ value ]]</template>'); |
+ var m = toObservable({ 'value': 'foo' }); |
+ recursivelySetTemplateModel(div, m); |
+ return new Future(() { |
+ expect(div.nodes.length, 2); |
+ expect(div.lastChild.text, 'foo'); |
+ |
+ m['value'] = 'bar'; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ // unchanged. |
+ expect(div.lastChild.text, 'foo'); |
+ }); |
+ }); |
+ |
+ test('OneTime - compound text', () { |
+ var div = createTestHtml( |
+ '<template bind>[[ foo ]] bar [[ baz ]]</template>'); |
+ var m = toObservable({ 'foo': 'FOO', 'baz': 'BAZ' }); |
+ recursivelySetTemplateModel(div, m); |
+ return new Future(() { |
+ expect(div.nodes.length, 2); |
+ expect(div.lastChild.text, 'FOO bar BAZ'); |
+ m['foo'] = 'FI'; |
+ m['baz'] = 'BA'; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ // unchanged. |
+ expect(div.nodes.length, 2); |
+ expect(div.lastChild.text, 'FOO bar BAZ'); |
+ }); |
+ }); |
+ |
+ test('OneTime/Dynamic Mixed - compound text', () { |
+ var div = createTestHtml( |
+ '<template bind>[[ foo ]] bar {{ baz }}</template>'); |
+ var m = toObservable({ 'foo': 'FOO', 'baz': 'BAZ' }); |
+ recursivelySetTemplateModel(div, m); |
+ return new Future(() { |
+ expect(div.nodes.length, 2); |
+ expect(div.lastChild.text, 'FOO bar BAZ'); |
+ |
+ m['foo'] = 'FI'; |
+ m['baz'] = 'BA'; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ // unchanged [[ foo ]]. |
+ expect(div.nodes.length, 2); |
+ expect(div.lastChild.text, 'FOO bar BA'); |
+ }); |
+ }); |
+ |
+ test('OneTime - simple attribute', () { |
+ var div = createTestHtml( |
+ '<template bind><div foo="[[ value ]]"></div></template>'); |
+ var m = toObservable({ 'value': 'foo' }); |
+ recursivelySetTemplateModel(div, m); |
+ return new Future(() { |
+ expect(div.nodes.length, 2); |
+ expect(div.lastChild.attributes['foo'], 'foo'); |
+ |
+ m['value'] = 'bar'; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ // unchanged. |
+ expect(div.nodes.length, 2); |
+ expect(div.lastChild.attributes['foo'], 'foo'); |
+ }); |
+ }); |
+ |
+ test('OneTime - compound attribute', () { |
+ var div = createTestHtml( |
+ '<template bind>' |
+ '<div foo="[[ value ]]:[[ otherValue ]]"></div>' |
+ '</template>'); |
+ var m = toObservable({ 'value': 'foo', 'otherValue': 'bar' }); |
+ recursivelySetTemplateModel(div, m); |
+ return new Future(() { |
+ expect(div.nodes.length, 2); |
+ expect(div.lastChild.attributes['foo'], 'foo:bar'); |
+ |
+ m['value'] = 'baz'; |
+ m['otherValue'] = 'bot'; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ // unchanged. |
+ expect(div.lastChild.attributes['foo'], 'foo:bar'); |
+ }); |
+ }); |
+ |
+ test('OneTime/Dynamic mixed - compound attribute', () { |
+ var div = createTestHtml( |
+ '<template bind>' |
+ '<div foo="{{ value }}:[[ otherValue ]]"></div>' |
+ '</template>'); |
+ var m = toObservable({ 'value': 'foo', 'otherValue': 'bar' }); |
recursivelySetTemplateModel(div, m); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 2); |
- expect(div.lastChild.text, 'foo'); |
+ return new Future(() { |
+ expect(div.nodes.length, 2); |
+ expect(div.lastChild.attributes['foo'], 'foo:bar'); |
+ |
+ m['value'] = 'baz'; |
+ m['otherValue'] = 'bot'; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ // unchanged [[ otherValue ]]. |
+ expect(div.lastChild.attributes['foo'], 'baz:bar'); |
+ }); |
}); |
- observeTest('Template Repeat If', () { |
+ test('Repeat If', () { |
var div = createTestHtml( |
- '<template repeat="{{ foo }}" if="{{ bar }}">{{ }}</template>'); |
- // Note: changed this value from 0->null because zero is not falsey in Dart. |
+ '<template repeat="{{ items }}" if="{{ predicate }}">{{}}</template>'); |
+ // Dart note: predicate changed from 0->null because 0 isn't falsey in Dart. |
// See https://code.google.com/p/dart/issues/detail?id=11956 |
- var m = toObservable({ 'bar': null, 'foo': [1, 2, 3] }); |
+ var m = toObservable({ 'predicate': null, 'items': [1] }); |
var template = div.firstChild; |
templateBind(template).model = m; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 1); |
+ return new Future(() { |
+ expect(div.nodes.length, 1); |
- m['bar'] = 1; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 4); |
- expect(div.nodes[1].text, '1'); |
- expect(div.nodes[2].text, '2'); |
- expect(div.nodes[3].text, '3'); |
+ m['predicate'] = 1; |
- templateBind(template).model = null; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 1); |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.nodes[1].text, '1'); |
+ |
+ m['items']..add(2)..add(3); |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 4); |
+ expect(div.nodes[1].text, '1'); |
+ expect(div.nodes[2].text, '2'); |
+ expect(div.nodes[3].text, '3'); |
+ |
+ m['items'] = [4]; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.nodes[1].text, '4'); |
+ |
+ templateBind(template).model = null; |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 1); |
+ }); |
+ }); |
+ |
+ test('Repeat oneTime-If (predicate false)', () { |
+ var div = createTestHtml( |
+ '<template repeat="{{ items }}" if="[[ predicate ]]">{{}}</template>'); |
+ // Dart note: predicate changed from 0->null because 0 isn't falsey in Dart. |
+ // See https://code.google.com/p/dart/issues/detail?id=11956 |
+ var m = toObservable({ 'predicate': null, 'items': [1] }); |
+ var template = div.firstChild; |
+ templateBind(template).model = m; |
+ return new Future(() { |
+ expect(div.nodes.length, 1); |
+ |
+ m['predicate'] = 1; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 1, reason: 'unchanged'); |
+ |
+ m['items']..add(2)..add(3); |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 1, reason: 'unchanged'); |
+ |
+ m['items'] = [4]; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 1, reason: 'unchanged'); |
+ |
+ templateBind(template).model = null; |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 1); |
+ }); |
}); |
- observeTest('TextTemplateWithNullStringBinding', () { |
+ test('Repeat oneTime-If (predicate true)', () { |
+ var div = createTestHtml( |
+ '<template repeat="{{ items }}" if="[[ predicate ]]">{{}}</template>'); |
+ |
+ var m = toObservable({ 'predicate': true, 'items': [1] }); |
+ var template = div.firstChild; |
+ templateBind(template).model = m; |
+ return new Future(() { |
+ expect(div.nodes.length, 2); |
+ expect(div.nodes[1].text, '1'); |
+ |
+ m['items']..add(2)..add(3); |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 4); |
+ expect(div.nodes[1].text, '1'); |
+ expect(div.nodes[2].text, '2'); |
+ expect(div.nodes[3].text, '3'); |
+ |
+ m['items'] = [4]; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.nodes[1].text, '4'); |
+ |
+ m['predicate'] = false; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2, reason: 'unchanged'); |
+ expect(div.nodes[1].text, '4', reason: 'unchanged'); |
+ |
+ templateBind(template).model = null; |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 1); |
+ }); |
+ }); |
+ |
+ test('oneTime-Repeat If', () { |
+ var div = createTestHtml( |
+ '<template repeat="[[ items ]]" if="{{ predicate }}">{{}}</template>'); |
+ |
+ var m = toObservable({ 'predicate': false, 'items': [1] }); |
+ var template = div.firstChild; |
+ templateBind(template).model = m; |
+ return new Future(() { |
+ expect(div.nodes.length, 1); |
+ |
+ m['predicate'] = true; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.nodes[1].text, '1'); |
+ |
+ m['items']..add(2)..add(3); |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.nodes[1].text, '1'); |
+ |
+ m['items'] = [4]; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.nodes[1].text, '1'); |
+ |
+ templateBind(template).model = null; |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 1); |
+ }); |
+ }); |
+ |
+ test('oneTime-Repeat oneTime-If', () { |
+ var div = createTestHtml( |
+ '<template repeat="[[ items ]]" if="[[ predicate ]]">{{}}</template>'); |
+ |
+ var m = toObservable({ 'predicate': true, 'items': [1] }); |
+ var template = div.firstChild; |
+ templateBind(template).model = m; |
+ return new Future(() { |
+ expect(div.nodes.length, 2); |
+ expect(div.nodes[1].text, '1'); |
+ |
+ m['items']..add(2)..add(3); |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.nodes[1].text, '1'); |
+ |
+ m['items'] = [4]; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.nodes[1].text, '1'); |
+ |
+ m['predicate'] = false; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.nodes[1].text, '1'); |
+ |
+ templateBind(template).model = null; |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 1); |
+ }); |
+ }); |
+ |
+ test('TextTemplateWithNullStringBinding', () { |
var div = createTestHtml('<template bind={{}}>a{{b}}c</template>'); |
var model = toObservable({'b': 'B'}); |
recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 2); |
- expect(div.nodes.last.text, 'aBc'); |
+ return new Future(() { |
+ expect(div.nodes.length, 2); |
+ expect(div.nodes.last.text, 'aBc'); |
- model['b'] = 'b'; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.last.text, 'abc'); |
+ model['b'] = 'b'; |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.last.text, 'abc'); |
- model['b'] = null; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.last.text, 'ac'); |
+ model['b'] = null; |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.last.text, 'ac'); |
- model = null; |
- performMicrotaskCheckpoint(); |
- // setting model isn't observable. |
- expect(div.nodes.last.text, 'ac'); |
+ model = null; |
+ }).then(endOfMicrotask).then((_) { |
+ // setting model isn't bindable. |
+ expect(div.nodes.last.text, 'ac'); |
+ }); |
}); |
- observeTest('TextTemplateWithBindingPath', () { |
+ test('TextTemplateWithBindingPath', () { |
var div = createTestHtml( |
'<template bind="{{ data }}">a{{b}}c</template>'); |
var model = toObservable({ 'data': {'b': 'B'} }); |
var template = div.firstChild; |
templateBind(template).model = model; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 2); |
- expect(div.nodes.last.text, 'aBc'); |
+ return new Future(() { |
+ expect(div.nodes.length, 2); |
+ expect(div.nodes.last.text, 'aBc'); |
- model['data']['b'] = 'b'; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.last.text, 'abc'); |
+ model['data']['b'] = 'b'; |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.last.text, 'abc'); |
- model['data'] = toObservable({'b': 'X'}); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.last.text, 'aXc'); |
+ model['data'] = toObservable({'b': 'X'}); |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.last.text, 'aXc'); |
- // Dart note: changed from `null` since our null means don't render a model. |
- model['data'] = toObservable({}); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.last.text, 'ac'); |
+ // Dart note: changed from `null` since our null means don't render a model. |
+ model['data'] = toObservable({}); |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.last.text, 'ac'); |
- model['data'] = null; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 1); |
+ model['data'] = null; |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 1); |
+ }); |
}); |
- observeTest('TextTemplateWithBindingAndConditional', () { |
+ test('TextTemplateWithBindingAndConditional', () { |
var div = createTestHtml( |
'<template bind="{{}}" if="{{ d }}">a{{b}}c</template>'); |
var model = toObservable({'b': 'B', 'd': 1}); |
recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 2); |
- expect(div.nodes.last.text, 'aBc'); |
+ return new Future(() { |
+ expect(div.nodes.length, 2); |
+ expect(div.nodes.last.text, 'aBc'); |
- model['b'] = 'b'; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.last.text, 'abc'); |
+ model['b'] = 'b'; |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.last.text, 'abc'); |
- // TODO(jmesserly): MDV set this to empty string and relies on JS conversion |
- // rules. Is that intended? |
- // See https://github.com/toolkitchen/mdv/issues/59 |
- model['d'] = null; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 1); |
+ // TODO(jmesserly): MDV set this to empty string and relies on JS conversion |
+ // rules. Is that intended? |
+ // See https://github.com/Polymer/TemplateBinding/issues/59 |
+ model['d'] = null; |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 1); |
- model['d'] = 'here'; |
- model['b'] = 'd'; |
+ model['d'] = 'here'; |
+ model['b'] = 'd'; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 2); |
- expect(div.nodes.last.text, 'adc'); |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.nodes.last.text, 'adc'); |
+ }); |
}); |
- observeTest('TemplateWithTextBinding2', () { |
+ test('TemplateWithTextBinding2', () { |
var div = createTestHtml( |
'<template bind="{{ b }}">a{{value}}c</template>'); |
expect(div.nodes.length, 1); |
var model = toObservable({'b': {'value': 'B'}}); |
recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 2); |
- expect(div.nodes.last.text, 'aBc'); |
+ return new Future(() { |
+ expect(div.nodes.length, 2); |
+ expect(div.nodes.last.text, 'aBc'); |
- model['b'] = toObservable({'value': 'b'}); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.last.text, 'abc'); |
+ model['b'] = toObservable({'value': 'b'}); |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.last.text, 'abc'); |
+ }); |
}); |
- observeTest('TemplateWithAttributeBinding', () { |
+ test('TemplateWithAttributeBinding', () { |
var div = createTestHtml( |
'<template bind="{{}}">' |
'<div foo="a{{b}}c"></div>' |
@@ -316,20 +788,21 @@ templateInstantiationTests() { |
var model = toObservable({'b': 'B'}); |
recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 2); |
- expect(div.nodes.last.attributes['foo'], 'aBc'); |
+ return new Future(() { |
+ expect(div.nodes.length, 2); |
+ expect(div.nodes.last.attributes['foo'], 'aBc'); |
- model['b'] = 'b'; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.last.attributes['foo'], 'abc'); |
+ model['b'] = 'b'; |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.last.attributes['foo'], 'abc'); |
- model['b'] = 'X'; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.last.attributes['foo'], 'aXc'); |
+ model['b'] = 'X'; |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.last.attributes['foo'], 'aXc'); |
+ }); |
}); |
- observeTest('TemplateWithConditionalBinding', () { |
+ test('TemplateWithConditionalBinding', () { |
var div = createTestHtml( |
'<template bind="{{}}">' |
'<div foo?="{{b}}"></div>' |
@@ -337,40 +810,91 @@ templateInstantiationTests() { |
var model = toObservable({'b': 'b'}); |
recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 2); |
- expect(div.nodes.last.attributes['foo'], ''); |
- expect(div.nodes.last.attributes, isNot(contains('foo?'))); |
+ return new Future(() { |
+ expect(div.nodes.length, 2); |
+ expect(div.nodes.last.attributes['foo'], ''); |
+ expect(div.nodes.last.attributes, isNot(contains('foo?'))); |
- model['b'] = null; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.last.attributes, isNot(contains('foo'))); |
+ model['b'] = null; |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.last.attributes, isNot(contains('foo'))); |
+ }); |
}); |
- observeTest('Repeat', () { |
+ test('Repeat', () { |
var div = createTestHtml( |
- '<template repeat="{{}}"">text</template>'); |
+ '<template repeat="{{ array }}">{{}},</template>'); |
+ |
+ var model = toObservable({'array': [0, 1, 2]}); |
+ var template = templateBind(div.firstChild); |
+ template.model = model; |
+ |
+ return new Future(() { |
+ expect(div.nodes.length, 4); |
+ expect(div.text, '0,1,2,'); |
+ |
+ model['array'].length = 1; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
+ expect(div.text, '0,'); |
+ |
+ model['array'].addAll([3, 4]); |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 4); |
+ expect(div.text, '0,3,4,'); |
+ |
+ model['array'].removeRange(1, 2); |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 3); |
+ expect(div.text, '0,4,'); |
+ |
+ model['array'].addAll([5, 6]); |
+ model['array'] = toObservable(['x', 'y']); |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 3); |
+ expect(div.text, 'x,y,'); |
+ |
+ template.model = null; |
+ |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 1); |
+ expect(div.text, ''); |
+ }); |
+ }); |
+ |
+ test('Repeat - oneTime', () { |
+ var div = createTestHtml('<template repeat="[[]]">text</template>'); |
var model = toObservable([0, 1, 2]); |
- recursivelySetTemplateModel(div, model); |
+ var template = templateBind(div.firstChild); |
+ template.model = model; |
+ |
+ return new Future(() { |
+ expect(div.nodes.length, 4); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 4); |
+ model.length = 1; |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 4); |
- model.length = 1; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 2); |
+ model.addAll([3, 4]); |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 4); |
- model.addAll(toObservable([3, 4])); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 4); |
+ model.removeRange(1, 2); |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 4); |
- model.removeRange(1, 2); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 3); |
+ template.model = null; |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 1); |
+ }); |
}); |
- observeTest('Repeat - Reuse Instances', () { |
+ test('Repeat - Reuse Instances', () { |
var div = createTestHtml('<template repeat>{{ val }}</template>'); |
var model = toObservable([ |
@@ -381,157 +905,164 @@ templateInstantiationTests() { |
{'val': 1} |
]); |
recursivelySetTemplateModel(div, model); |
- |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 6); |
var template = div.firstChild; |
- addExpandos(template.nextNode); |
- checkExpandos(template.nextNode); |
+ return new Future(() { |
+ expect(div.nodes.length, 6); |
- model.sort((a, b) => a['val'] - b['val']); |
- performMicrotaskCheckpoint(); |
- checkExpandos(template.nextNode); |
+ addExpandos(template.nextNode); |
+ checkExpandos(template.nextNode); |
- model = toObservable(model.reversed); |
- recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
- checkExpandos(template.nextNode); |
+ model.sort((a, b) => a['val'] - b['val']); |
+ }).then(endOfMicrotask).then((_) { |
+ checkExpandos(template.nextNode); |
- for (var item in model) { |
- item['val'] += 1; |
- } |
+ model = toObservable(model.reversed); |
+ recursivelySetTemplateModel(div, model); |
+ }).then(endOfMicrotask).then((_) { |
+ checkExpandos(template.nextNode); |
+ |
+ for (var item in model) { |
+ item['val'] += 1; |
+ } |
- performMicrotaskCheckpoint(); |
- expect(div.nodes[1].text, "11"); |
- expect(div.nodes[2].text, "9"); |
- expect(div.nodes[3].text, "6"); |
- expect(div.nodes[4].text, "3"); |
- expect(div.nodes[5].text, "2"); |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes[1].text, "11"); |
+ expect(div.nodes[2].text, "9"); |
+ expect(div.nodes[3].text, "6"); |
+ expect(div.nodes[4].text, "3"); |
+ expect(div.nodes[5].text, "2"); |
+ }); |
}); |
- observeTest('Bind - Reuse Instance', () { |
+ test('Bind - Reuse Instance', () { |
var div = createTestHtml( |
'<template bind="{{ foo }}">{{ bar }}</template>'); |
var model = toObservable({ 'foo': { 'bar': 5 }}); |
recursivelySetTemplateModel(div, model); |
- |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 2); |
var template = div.firstChild; |
- addExpandos(template.nextNode); |
- checkExpandos(template.nextNode); |
+ return new Future(() { |
+ expect(div.nodes.length, 2); |
- model = toObservable({'foo': model['foo']}); |
- recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
- checkExpandos(template.nextNode); |
+ addExpandos(template.nextNode); |
+ checkExpandos(template.nextNode); |
+ |
+ model = toObservable({'foo': model['foo']}); |
+ recursivelySetTemplateModel(div, model); |
+ }).then(endOfMicrotask).then((_) { |
+ checkExpandos(template.nextNode); |
+ }); |
}); |
- observeTest('Repeat-Empty', () { |
+ test('Repeat-Empty', () { |
var div = createTestHtml( |
'<template repeat>text</template>'); |
var model = toObservable([0, 1, 2]); |
recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 4); |
+ return new Future(() { |
+ expect(div.nodes.length, 4); |
- model.length = 1; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 2); |
+ model.length = 1; |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 2); |
- model.addAll(toObservable([3, 4])); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 4); |
+ model.addAll(toObservable([3, 4])); |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 4); |
- model.removeRange(1, 2); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 3); |
+ model.removeRange(1, 2); |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 3); |
+ }); |
}); |
- observeTest('Removal from iteration needs to unbind', () { |
+ test('Removal from iteration needs to unbind', () { |
var div = createTestHtml( |
'<template repeat="{{}}"><a>{{v}}</a></template>'); |
var model = toObservable([{'v': 0}, {'v': 1}, {'v': 2}, {'v': 3}, |
{'v': 4}]); |
recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
- var nodes = div.nodes.skip(1).toList(); |
- var vs = model.toList(); |
+ var nodes, vs; |
+ return new Future(() { |
- for (var i = 0; i < 5; i++) { |
- expect(nodes[i].text, '$i'); |
- } |
+ nodes = div.nodes.skip(1).toList(); |
+ vs = model.toList(); |
- model.length = 3; |
- performMicrotaskCheckpoint(); |
- for (var i = 0; i < 5; i++) { |
- expect(nodes[i].text, '$i'); |
- } |
+ for (var i = 0; i < 5; i++) { |
+ expect(nodes[i].text, '$i'); |
+ } |
- vs[3]['v'] = 33; |
- vs[4]['v'] = 44; |
- performMicrotaskCheckpoint(); |
- for (var i = 0; i < 5; i++) { |
- expect(nodes[i].text, '$i'); |
- } |
+ model.length = 3; |
+ }).then(endOfMicrotask).then((_) { |
+ for (var i = 0; i < 5; i++) { |
+ expect(nodes[i].text, '$i'); |
+ } |
+ |
+ vs[3]['v'] = 33; |
+ vs[4]['v'] = 44; |
+ }).then(endOfMicrotask).then((_) { |
+ for (var i = 0; i < 5; i++) { |
+ expect(nodes[i].text, '$i'); |
+ } |
+ }); |
}); |
- observeTest('DOM Stability on Iteration', () { |
+ test('DOM Stability on Iteration', () { |
var div = createTestHtml( |
'<template repeat="{{}}">{{}}</template>'); |
var model = toObservable([1, 2, 3, 4, 5]); |
recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
- |
- // Note: the node at index 0 is the <template>. |
- var nodes = div.nodes.toList(); |
- expect(nodes.length, 6, reason: 'list has 5 items'); |
+ var nodes; |
+ return new Future(() { |
+ // Note: the node at index 0 is the <template>. |
+ nodes = div.nodes.toList(); |
+ expect(nodes.length, 6, reason: 'list has 5 items'); |
- model.removeAt(0); |
- model.removeLast(); |
+ model.removeAt(0); |
+ model.removeLast(); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 4, reason: 'list has 3 items'); |
- expect(identical(div.nodes[1], nodes[2]), true, reason: '2 not removed'); |
- expect(identical(div.nodes[2], nodes[3]), true, reason: '3 not removed'); |
- expect(identical(div.nodes[3], nodes[4]), true, reason: '4 not removed'); |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 4, reason: 'list has 3 items'); |
+ expect(identical(div.nodes[1], nodes[2]), true, reason: '2 not removed'); |
+ expect(identical(div.nodes[2], nodes[3]), true, reason: '3 not removed'); |
+ expect(identical(div.nodes[3], nodes[4]), true, reason: '4 not removed'); |
- model.insert(0, 5); |
- model[2] = 6; |
- model.add(7); |
+ model.insert(0, 5); |
+ model[2] = 6; |
+ model.add(7); |
- performMicrotaskCheckpoint(); |
+ }).then(endOfMicrotask).then((_) { |
- expect(div.nodes.length, 6, reason: 'list has 5 items'); |
- expect(nodes.contains(div.nodes[1]), false, reason: '5 is a new node'); |
- expect(identical(div.nodes[2], nodes[2]), true); |
- expect(nodes.contains(div.nodes[3]), false, reason: '6 is a new node'); |
- expect(identical(div.nodes[4], nodes[4]), true); |
- expect(nodes.contains(div.nodes[5]), false, reason: '7 is a new node'); |
+ expect(div.nodes.length, 6, reason: 'list has 5 items'); |
+ expect(nodes.contains(div.nodes[1]), false, reason: '5 is a new node'); |
+ expect(identical(div.nodes[2], nodes[2]), true); |
+ expect(nodes.contains(div.nodes[3]), false, reason: '6 is a new node'); |
+ expect(identical(div.nodes[4], nodes[4]), true); |
+ expect(nodes.contains(div.nodes[5]), false, reason: '7 is a new node'); |
- nodes = div.nodes.toList(); |
+ nodes = div.nodes.toList(); |
- model.insert(2, 8); |
+ model.insert(2, 8); |
- performMicrotaskCheckpoint(); |
+ }).then(endOfMicrotask).then((_) { |
- expect(div.nodes.length, 7, reason: 'list has 6 items'); |
- expect(identical(div.nodes[1], nodes[1]), true); |
- expect(identical(div.nodes[2], nodes[2]), true); |
- expect(nodes.contains(div.nodes[3]), false, reason: '8 is a new node'); |
- expect(identical(div.nodes[4], nodes[3]), true); |
- expect(identical(div.nodes[5], nodes[4]), true); |
- expect(identical(div.nodes[6], nodes[5]), true); |
+ expect(div.nodes.length, 7, reason: 'list has 6 items'); |
+ expect(identical(div.nodes[1], nodes[1]), true); |
+ expect(identical(div.nodes[2], nodes[2]), true); |
+ expect(nodes.contains(div.nodes[3]), false, reason: '8 is a new node'); |
+ expect(identical(div.nodes[4], nodes[3]), true); |
+ expect(identical(div.nodes[5], nodes[4]), true); |
+ expect(identical(div.nodes[6], nodes[5]), true); |
+ }); |
}); |
- observeTest('Repeat2', () { |
+ test('Repeat2', () { |
var div = createTestHtml( |
'<template repeat="{{}}">{{value}}</template>'); |
expect(div.nodes.length, 1); |
@@ -543,28 +1074,29 @@ templateInstantiationTests() { |
]); |
recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 4); |
- expect(div.nodes[1].text, '0'); |
- expect(div.nodes[2].text, '1'); |
- expect(div.nodes[3].text, '2'); |
- |
- model[1]['value'] = 'One'; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 4); |
- expect(div.nodes[1].text, '0'); |
- expect(div.nodes[2].text, 'One'); |
- expect(div.nodes[3].text, '2'); |
- |
- model.replaceRange(0, 1, toObservable([{'value': 'Zero'}])); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 4); |
- expect(div.nodes[1].text, 'Zero'); |
- expect(div.nodes[2].text, 'One'); |
- expect(div.nodes[3].text, '2'); |
+ return new Future(() { |
+ expect(div.nodes.length, 4); |
+ expect(div.nodes[1].text, '0'); |
+ expect(div.nodes[2].text, '1'); |
+ expect(div.nodes[3].text, '2'); |
+ |
+ model[1]['value'] = 'One'; |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 4); |
+ expect(div.nodes[1].text, '0'); |
+ expect(div.nodes[2].text, 'One'); |
+ expect(div.nodes[3].text, '2'); |
+ |
+ model.replaceRange(0, 1, toObservable([{'value': 'Zero'}])); |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 4); |
+ expect(div.nodes[1].text, 'Zero'); |
+ expect(div.nodes[2].text, 'One'); |
+ expect(div.nodes[3].text, '2'); |
+ }); |
}); |
- observeTest('TemplateWithInputValue', () { |
+ test('TemplateWithInputValue', () { |
var div = createTestHtml( |
'<template bind="{{}}">' |
'<input value="{{x}}">' |
@@ -572,25 +1104,26 @@ templateInstantiationTests() { |
var model = toObservable({'x': 'hi'}); |
recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 2); |
- expect(div.nodes.last.value, 'hi'); |
+ return new Future(() { |
+ expect(div.nodes.length, 2); |
+ expect(div.nodes.last.value, 'hi'); |
- model['x'] = 'bye'; |
- expect(div.nodes.last.value, 'hi'); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.last.value, 'bye'); |
+ model['x'] = 'bye'; |
+ expect(div.nodes.last.value, 'hi'); |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.last.value, 'bye'); |
- div.nodes.last.value = 'hello'; |
- dispatchEvent('input', div.nodes.last); |
- expect(model['x'], 'hello'); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.last.value, 'hello'); |
+ div.nodes.last.value = 'hello'; |
+ dispatchEvent('input', div.nodes.last); |
+ expect(model['x'], 'hello'); |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.last.value, 'hello'); |
+ }); |
}); |
////////////////////////////////////////////////////////////////////////////// |
- observeTest('Decorated', () { |
+ test('Decorated', () { |
var div = createTestHtml( |
'<template bind="{{ XX }}" id="t1">' |
'<p>Crew member: {{name}}, Job title: {{title}}</p>' |
@@ -604,24 +1137,24 @@ templateInstantiationTests() { |
}); |
recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
+ return new Future(() { |
+ var t1 = document.getElementById('t1'); |
+ var instance = t1.nextElementSibling; |
+ expect(instance.text, 'Crew member: Leela, Job title: Captain'); |
- var t1 = document.getElementById('t1'); |
- var instance = t1.nextElementSibling; |
- expect(instance.text, 'Crew member: Leela, Job title: Captain'); |
+ var t2 = document.getElementById('t2'); |
+ instance = t2.nextElementSibling; |
+ expect(instance.text, 'Crew member: Fry, Job title: Delivery boy'); |
- var t2 = document.getElementById('t2'); |
- instance = t2.nextElementSibling; |
- expect(instance.text, 'Crew member: Fry, Job title: Delivery boy'); |
+ expect(div.children.length, 4); |
+ expect(div.nodes.length, 4); |
- expect(div.children.length, 4); |
- expect(div.nodes.length, 4); |
- |
- expect(div.nodes[1].tagName, 'P'); |
- expect(div.nodes[3].tagName, 'P'); |
+ expect(div.nodes[1].tagName, 'P'); |
+ expect(div.nodes[3].tagName, 'P'); |
+ }); |
}); |
- observeTest('DefaultStyles', () { |
+ test('DefaultStyles', () { |
var t = new Element.tag('template'); |
TemplateBindExtension.decorate(t); |
@@ -632,40 +1165,24 @@ templateInstantiationTests() { |
}); |
- observeTest('Bind', () { |
+ test('Bind', () { |
var div = createTestHtml('<template bind="{{}}">Hi {{ name }}</template>'); |
var model = toObservable({'name': 'Leela'}); |
recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes[1].text, 'Hi Leela'); |
- }); |
- |
- observeTest('BindImperative', () { |
- var div = createTestHtml( |
- '<template>' |
- 'Hi {{ name }}' |
- '</template>'); |
- var t = div.nodes.first; |
- |
- var model = toObservable({'name': 'Leela'}); |
- nodeBind(t).bind('bind', model, ''); |
- |
- performMicrotaskCheckpoint(); |
- expect(div.nodes[1].text, 'Hi Leela'); |
+ return new Future(() => expect(div.nodes[1].text, 'Hi Leela')); |
}); |
- observeTest('BindPlaceHolderHasNewLine', () { |
+ test('BindPlaceHolderHasNewLine', () { |
var div = createTestHtml( |
'<template bind="{{}}">Hi {{\nname\n}}</template>'); |
var model = toObservable({'name': 'Leela'}); |
recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes[1].text, 'Hi Leela'); |
+ return new Future(() => expect(div.nodes[1].text, 'Hi Leela')); |
}); |
- observeTest('BindWithRef', () { |
+ test('BindWithRef', () { |
var id = 't${new math.Random().nextInt(100)}'; |
var div = createTestHtml( |
'<template id="$id">' |
@@ -681,11 +1198,35 @@ templateInstantiationTests() { |
var model = toObservable({'name': 'Fry'}); |
recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
- expect(t2.nextNode.text, 'Hi Fry'); |
+ return new Future(() => expect(t2.nextNode.text, 'Hi Fry')); |
+ }); |
+ |
+ |
+ test('Update Ref', () { |
+ var div = createTestHtml( |
+ '<template id=A>Hi, {{}}</template>' |
+ '<template id=B>Hola, {{}}</template>' |
+ '<template ref=A repeat></template>'); |
+ |
+ var model = new ObservableList.from(['Fry']); |
+ recursivelySetTemplateModel(div, model); |
+ |
+ return new Future(() { |
+ expect(div.nodes.length, 4); |
+ expect('Hi, Fry', div.nodes[3].text); |
+ |
+ div.nodes[2].attributes['ref'] = 'B'; |
+ model.add('Leela'); |
+ |
+ }).then(endOfMicrotask).then((x) { |
+ expect(div.nodes.length, 5); |
+ |
+ expect('Hi, Fry', div.nodes[3].text); |
+ expect('Hola, Leela', div.nodes[4].text); |
+ }); |
}); |
- observeTest('BindWithDynamicRef', () { |
+ test('BindWithDynamicRef', () { |
var id = 't${new math.Random().nextInt(100)}'; |
var div = createTestHtml( |
'<template id="$id">' |
@@ -698,33 +1239,7 @@ templateInstantiationTests() { |
var model = toObservable({'name': 'Fry', 'id': id }); |
recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
- expect(t2.nextNode.text, 'Hi Fry'); |
- }); |
- |
- observeTest('BindChanged', () { |
- var model = toObservable({ |
- 'XX': {'name': 'Leela', 'title': 'Captain'}, |
- 'XY': {'name': 'Fry', 'title': 'Delivery boy'}, |
- 'XZ': {'name': 'Zoidberg', 'title': 'Doctor'} |
- }); |
- |
- var div = createTestHtml( |
- '<template bind="{{ XX }}">Hi {{ name }}</template>'); |
- |
- recursivelySetTemplateModel(div, model); |
- |
- var t = div.nodes.first; |
- performMicrotaskCheckpoint(); |
- |
- expect(div.nodes.length, 2); |
- expect(t.nextNode.text, 'Hi Leela'); |
- |
- nodeBind(t).bind('bind', model, 'XZ'); |
- performMicrotaskCheckpoint(); |
- |
- expect(div.nodes.length, 2); |
- expect(t.nextNode.text, 'Hi Zoidberg'); |
+ return new Future(() => expect(t2.nextNode.text, 'Hi Fry')); |
}); |
assertNodesAre(div, [arguments]) { |
@@ -737,7 +1252,7 @@ templateInstantiationTests() { |
} |
} |
- observeTest('Repeat3', () { |
+ test('Repeat3', () { |
var div = createTestHtml( |
'<template repeat="{{ contacts }}">Hi {{ name }}</template>'); |
var t = div.nodes.first; |
@@ -751,44 +1266,45 @@ templateInstantiationTests() { |
}); |
recursivelySetTemplateModel(div, m); |
- performMicrotaskCheckpoint(); |
+ return new Future(() { |
- assertNodesAre(div, ['Hi Raf', 'Hi Arv', 'Hi Neal']); |
+ assertNodesAre(div, ['Hi Raf', 'Hi Arv', 'Hi Neal']); |
- m['contacts'].add(toObservable({'name': 'Alex'})); |
- performMicrotaskCheckpoint(); |
- assertNodesAre(div, ['Hi Raf', 'Hi Arv', 'Hi Neal', 'Hi Alex']); |
+ m['contacts'].add(toObservable({'name': 'Alex'})); |
+ }).then(endOfMicrotask).then((_) { |
+ assertNodesAre(div, ['Hi Raf', 'Hi Arv', 'Hi Neal', 'Hi Alex']); |
- m['contacts'].replaceRange(0, 2, |
- toObservable([{'name': 'Rafael'}, {'name': 'Erik'}])); |
- performMicrotaskCheckpoint(); |
- assertNodesAre(div, ['Hi Rafael', 'Hi Erik', 'Hi Neal', 'Hi Alex']); |
+ m['contacts'].replaceRange(0, 2, |
+ toObservable([{'name': 'Rafael'}, {'name': 'Erik'}])); |
+ }).then(endOfMicrotask).then((_) { |
+ assertNodesAre(div, ['Hi Rafael', 'Hi Erik', 'Hi Neal', 'Hi Alex']); |
- m['contacts'].removeRange(1, 3); |
- performMicrotaskCheckpoint(); |
- assertNodesAre(div, ['Hi Rafael', 'Hi Alex']); |
+ m['contacts'].removeRange(1, 3); |
+ }).then(endOfMicrotask).then((_) { |
+ assertNodesAre(div, ['Hi Rafael', 'Hi Alex']); |
- m['contacts'].insertAll(1, |
- toObservable([{'name': 'Erik'}, {'name': 'Dimitri'}])); |
- performMicrotaskCheckpoint(); |
- assertNodesAre(div, ['Hi Rafael', 'Hi Erik', 'Hi Dimitri', 'Hi Alex']); |
+ m['contacts'].insertAll(1, |
+ toObservable([{'name': 'Erik'}, {'name': 'Dimitri'}])); |
+ }).then(endOfMicrotask).then((_) { |
+ assertNodesAre(div, ['Hi Rafael', 'Hi Erik', 'Hi Dimitri', 'Hi Alex']); |
- m['contacts'].replaceRange(0, 1, |
- toObservable([{'name': 'Tab'}, {'name': 'Neal'}])); |
- performMicrotaskCheckpoint(); |
- assertNodesAre(div, ['Hi Tab', 'Hi Neal', 'Hi Erik', 'Hi Dimitri', |
- 'Hi Alex']); |
+ m['contacts'].replaceRange(0, 1, |
+ toObservable([{'name': 'Tab'}, {'name': 'Neal'}])); |
+ }).then(endOfMicrotask).then((_) { |
+ assertNodesAre(div, ['Hi Tab', 'Hi Neal', 'Hi Erik', 'Hi Dimitri', |
+ 'Hi Alex']); |
- m['contacts'] = toObservable([{'name': 'Alex'}]); |
- performMicrotaskCheckpoint(); |
- assertNodesAre(div, ['Hi Alex']); |
+ m['contacts'] = toObservable([{'name': 'Alex'}]); |
+ }).then(endOfMicrotask).then((_) { |
+ assertNodesAre(div, ['Hi Alex']); |
- m['contacts'].length = 0; |
- performMicrotaskCheckpoint(); |
- assertNodesAre(div, []); |
+ m['contacts'].length = 0; |
+ }).then(endOfMicrotask).then((_) { |
+ assertNodesAre(div, []); |
+ }); |
}); |
- observeTest('RepeatModelSet', () { |
+ test('RepeatModelSet', () { |
var div = createTestHtml( |
'<template repeat="{{ contacts }}">' |
'Hi {{ name }}' |
@@ -801,14 +1317,13 @@ templateInstantiationTests() { |
] |
}); |
recursivelySetTemplateModel(div, m); |
- |
- performMicrotaskCheckpoint(); |
- var t = div.nodes.first; |
- |
- assertNodesAre(div, ['Hi Raf', 'Hi Arv', 'Hi Neal']); |
+ return new Future(() { |
+ var t = div.nodes.first; |
+ assertNodesAre(div, ['Hi Raf', 'Hi Arv', 'Hi Neal']); |
+ }); |
}); |
- observeTest('RepeatEmptyPath', () { |
+ test('RepeatEmptyPath', () { |
var div = createTestHtml( |
'<template repeat="{{}}">Hi {{ name }}</template>'); |
var t = div.nodes.first; |
@@ -819,39 +1334,39 @@ templateInstantiationTests() { |
{'name': 'Neal'} |
]); |
recursivelySetTemplateModel(div, m); |
+ return new Future(() { |
- performMicrotaskCheckpoint(); |
+ assertNodesAre(div, ['Hi Raf', 'Hi Arv', 'Hi Neal']); |
- assertNodesAre(div, ['Hi Raf', 'Hi Arv', 'Hi Neal']); |
+ m.add(toObservable({'name': 'Alex'})); |
+ }).then(endOfMicrotask).then((_) { |
+ assertNodesAre(div, ['Hi Raf', 'Hi Arv', 'Hi Neal', 'Hi Alex']); |
- m.add(toObservable({'name': 'Alex'})); |
- performMicrotaskCheckpoint(); |
- assertNodesAre(div, ['Hi Raf', 'Hi Arv', 'Hi Neal', 'Hi Alex']); |
+ m.replaceRange(0, 2, toObservable([{'name': 'Rafael'}, {'name': 'Erik'}])); |
+ }).then(endOfMicrotask).then((_) { |
+ assertNodesAre(div, ['Hi Rafael', 'Hi Erik', 'Hi Neal', 'Hi Alex']); |
- m.replaceRange(0, 2, toObservable([{'name': 'Rafael'}, {'name': 'Erik'}])); |
- performMicrotaskCheckpoint(); |
- assertNodesAre(div, ['Hi Rafael', 'Hi Erik', 'Hi Neal', 'Hi Alex']); |
+ m.removeRange(1, 3); |
+ }).then(endOfMicrotask).then((_) { |
+ assertNodesAre(div, ['Hi Rafael', 'Hi Alex']); |
- m.removeRange(1, 3); |
- performMicrotaskCheckpoint(); |
- assertNodesAre(div, ['Hi Rafael', 'Hi Alex']); |
+ m.insertAll(1, toObservable([{'name': 'Erik'}, {'name': 'Dimitri'}])); |
+ }).then(endOfMicrotask).then((_) { |
+ assertNodesAre(div, ['Hi Rafael', 'Hi Erik', 'Hi Dimitri', 'Hi Alex']); |
- m.insertAll(1, toObservable([{'name': 'Erik'}, {'name': 'Dimitri'}])); |
- performMicrotaskCheckpoint(); |
- assertNodesAre(div, ['Hi Rafael', 'Hi Erik', 'Hi Dimitri', 'Hi Alex']); |
+ m.replaceRange(0, 1, toObservable([{'name': 'Tab'}, {'name': 'Neal'}])); |
+ }).then(endOfMicrotask).then((_) { |
+ assertNodesAre(div, ['Hi Tab', 'Hi Neal', 'Hi Erik', 'Hi Dimitri', |
+ 'Hi Alex']); |
- m.replaceRange(0, 1, toObservable([{'name': 'Tab'}, {'name': 'Neal'}])); |
- performMicrotaskCheckpoint(); |
- assertNodesAre(div, ['Hi Tab', 'Hi Neal', 'Hi Erik', 'Hi Dimitri', |
- 'Hi Alex']); |
- |
- m.length = 0; |
- m.add(toObservable({'name': 'Alex'})); |
- performMicrotaskCheckpoint(); |
- assertNodesAre(div, ['Hi Alex']); |
+ m.length = 0; |
+ m.add(toObservable({'name': 'Alex'})); |
+ }).then(endOfMicrotask).then((_) { |
+ assertNodesAre(div, ['Hi Alex']); |
+ }); |
}); |
- observeTest('RepeatNullModel', () { |
+ test('RepeatNullModel', () { |
var div = createTestHtml( |
'<template repeat="{{}}">Hi {{ name }}</template>'); |
var t = div.nodes.first; |
@@ -864,12 +1379,10 @@ templateInstantiationTests() { |
t.attributes['iterate'] = ''; |
m = toObservable({}); |
recursivelySetTemplateModel(div, m); |
- |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 1); |
+ return new Future(() => expect(div.nodes.length, 1)); |
}); |
- observeTest('RepeatReuse', () { |
+ test('RepeatReuse', () { |
var div = createTestHtml( |
'<template repeat="{{}}">Hi {{ name }}</template>'); |
var t = div.nodes.first; |
@@ -880,60 +1393,61 @@ templateInstantiationTests() { |
{'name': 'Neal'} |
]); |
recursivelySetTemplateModel(div, m); |
- performMicrotaskCheckpoint(); |
- |
- assertNodesAre(div, ['Hi Raf', 'Hi Arv', 'Hi Neal']); |
- var node1 = div.nodes[1]; |
- var node2 = div.nodes[2]; |
- var node3 = div.nodes[3]; |
- |
- m.replaceRange(1, 2, toObservable([{'name': 'Erik'}])); |
- performMicrotaskCheckpoint(); |
- assertNodesAre(div, ['Hi Raf', 'Hi Erik', 'Hi Neal']); |
- expect(div.nodes[1], node1, |
- reason: 'model[0] did not change so the node should not have changed'); |
- expect(div.nodes[2], isNot(equals(node2)), |
- reason: 'Should not reuse when replacing'); |
- expect(div.nodes[3], node3, |
- reason: 'model[2] did not change so the node should not have changed'); |
- |
- node2 = div.nodes[2]; |
- m.insert(0, toObservable({'name': 'Alex'})); |
- performMicrotaskCheckpoint(); |
- assertNodesAre(div, ['Hi Alex', 'Hi Raf', 'Hi Erik', 'Hi Neal']); |
- }); |
- |
- observeTest('TwoLevelsDeepBug', () { |
+ |
+ var node1, node2, node3; |
+ return new Future(() { |
+ assertNodesAre(div, ['Hi Raf', 'Hi Arv', 'Hi Neal']); |
+ node1 = div.nodes[1]; |
+ node2 = div.nodes[2]; |
+ node3 = div.nodes[3]; |
+ |
+ m.replaceRange(1, 2, toObservable([{'name': 'Erik'}])); |
+ }).then(endOfMicrotask).then((_) { |
+ assertNodesAre(div, ['Hi Raf', 'Hi Erik', 'Hi Neal']); |
+ expect(div.nodes[1], node1, |
+ reason: 'model[0] did not change so the node should not have changed'); |
+ expect(div.nodes[2], isNot(equals(node2)), |
+ reason: 'Should not reuse when replacing'); |
+ expect(div.nodes[3], node3, |
+ reason: 'model[2] did not change so the node should not have changed'); |
+ |
+ node2 = div.nodes[2]; |
+ m.insert(0, toObservable({'name': 'Alex'})); |
+ }).then(endOfMicrotask).then((_) { |
+ assertNodesAre(div, ['Hi Alex', 'Hi Raf', 'Hi Erik', 'Hi Neal']); |
+ }); |
+ }); |
+ |
+ test('TwoLevelsDeepBug', () { |
var div = createTestHtml( |
'<template bind="{{}}"><span><span>{{ foo }}</span></span></template>'); |
var model = toObservable({'foo': 'bar'}); |
recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
- |
- expect(div.nodes[1].nodes[0].nodes[0].text, 'bar'); |
+ return new Future(() { |
+ expect(div.nodes[1].nodes[0].nodes[0].text, 'bar'); |
+ }); |
}); |
- observeTest('Checked', () { |
+ test('Checked', () { |
var div = createTestHtml( |
- '<template>' |
+ '<template bind>' |
'<input type="checkbox" checked="{{a}}">' |
'</template>'); |
var t = div.nodes.first; |
- var m = toObservable({ |
- 'a': true |
- }); |
- nodeBind(t).bind('bind', m, ''); |
- performMicrotaskCheckpoint(); |
+ templateBind(t).model = toObservable({'a': true }); |
- var instanceInput = t.nextNode; |
- expect(instanceInput.checked, true); |
+ return new Future(() { |
- instanceInput.click(); |
- expect(instanceInput.checked, false); |
+ var instanceInput = t.nextNode; |
+ expect(instanceInput.checked, true); |
- instanceInput.click(); |
- expect(instanceInput.checked, true); |
+ instanceInput.click(); |
+ expect(instanceInput.checked, false); |
+ |
+ instanceInput.click(); |
+ expect(instanceInput.checked, true); |
+ }); |
}); |
nestedHelper(s, start) { |
@@ -947,40 +1461,37 @@ templateInstantiationTests() { |
}); |
recursivelySetTemplateModel(div, m); |
- performMicrotaskCheckpoint(); |
+ return new Future(() { |
- var i = start; |
- expect(div.nodes[i++].text, '1'); |
- expect(div.nodes[i++].tagName, 'TEMPLATE'); |
- expect(div.nodes[i++].text, '2'); |
+ var i = start; |
+ expect(div.nodes[i++].text, '1'); |
+ expect(div.nodes[i++].tagName, 'TEMPLATE'); |
+ expect(div.nodes[i++].text, '2'); |
- m['a']['b'] = 11; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes[start].text, '11'); |
+ m['a']['b'] = 11; |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes[start].text, '11'); |
- m['a']['c'] = toObservable({'d': 22}); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes[start + 2].text, '22'); |
+ m['a']['c'] = toObservable({'d': 22}); |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes[start + 2].text, '22'); |
+ }); |
} |
- observeTest('Nested', () { |
- nestedHelper( |
- '<template bind="{{a}}">' |
- '{{b}}' |
- '<template bind="{{c}}">' |
- '{{d}}' |
- '</template>' |
- '</template>', 1); |
- }); |
+ test('Nested', () => nestedHelper( |
+ '<template bind="{{a}}">' |
+ '{{b}}' |
+ '<template bind="{{c}}">' |
+ '{{d}}' |
+ '</template>' |
+ '</template>', 1)); |
- observeTest('NestedWithRef', () { |
- nestedHelper( |
+ test('NestedWithRef', () => nestedHelper( |
'<template id="inner">{{d}}</template>' |
'<template id="outer" bind="{{a}}">' |
'{{b}}' |
'<template ref="inner" bind="{{c}}"></template>' |
- '</template>', 2); |
- }); |
+ '</template>', 2)); |
nestedIterateInstantiateHelper(s, start) { |
var div = createTestHtml(s); |
@@ -999,46 +1510,43 @@ templateInstantiationTests() { |
}); |
recursivelySetTemplateModel(div, m); |
- performMicrotaskCheckpoint(); |
- |
- var i = start; |
- expect(div.nodes[i++].text, '1'); |
- expect(div.nodes[i++].tagName, 'TEMPLATE'); |
- expect(div.nodes[i++].text, '11'); |
- expect(div.nodes[i++].text, '2'); |
- expect(div.nodes[i++].tagName, 'TEMPLATE'); |
- expect(div.nodes[i++].text, '22'); |
+ return new Future(() { |
+ |
+ var i = start; |
+ expect(div.nodes[i++].text, '1'); |
+ expect(div.nodes[i++].tagName, 'TEMPLATE'); |
+ expect(div.nodes[i++].text, '11'); |
+ expect(div.nodes[i++].text, '2'); |
+ expect(div.nodes[i++].tagName, 'TEMPLATE'); |
+ expect(div.nodes[i++].text, '22'); |
+ |
+ m['a'][1] = toObservable({ |
+ 'b': 3, |
+ 'c': {'d': 33} |
+ }); |
- m['a'][1] = toObservable({ |
- 'b': 3, |
- 'c': {'d': 33} |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes[start + 3].text, '3'); |
+ expect(div.nodes[start + 5].text, '33'); |
}); |
- |
- performMicrotaskCheckpoint(); |
- expect(div.nodes[start + 3].text, '3'); |
- expect(div.nodes[start + 5].text, '33'); |
} |
- observeTest('NestedRepeatBind', () { |
- nestedIterateInstantiateHelper( |
- '<template repeat="{{a}}">' |
- '{{b}}' |
- '<template bind="{{c}}">' |
- '{{d}}' |
- '</template>' |
- '</template>', 1); |
- }); |
- |
- observeTest('NestedRepeatBindWithRef', () { |
- nestedIterateInstantiateHelper( |
- '<template id="inner">' |
+ test('NestedRepeatBind', () => nestedIterateInstantiateHelper( |
+ '<template repeat="{{a}}">' |
+ '{{b}}' |
+ '<template bind="{{c}}">' |
'{{d}}' |
'</template>' |
- '<template repeat="{{a}}">' |
- '{{b}}' |
- '<template ref="inner" bind="{{c}}"></template>' |
- '</template>', 2); |
- }); |
+ '</template>', 1)); |
+ |
+ test('NestedRepeatBindWithRef', () => nestedIterateInstantiateHelper( |
+ '<template id="inner">' |
+ '{{d}}' |
+ '</template>' |
+ '<template repeat="{{a}}">' |
+ '{{b}}' |
+ '<template ref="inner" bind="{{c}}"></template>' |
+ '</template>', 2)); |
nestedIterateIterateHelper(s, start) { |
var div = createTestHtml(s); |
@@ -1057,53 +1565,50 @@ templateInstantiationTests() { |
}); |
recursivelySetTemplateModel(div, m); |
- performMicrotaskCheckpoint(); |
- |
- var i = start; |
- expect(div.nodes[i++].text, '1'); |
- expect(div.nodes[i++].tagName, 'TEMPLATE'); |
- expect(div.nodes[i++].text, '11'); |
- expect(div.nodes[i++].text, '12'); |
- expect(div.nodes[i++].text, '2'); |
- expect(div.nodes[i++].tagName, 'TEMPLATE'); |
- expect(div.nodes[i++].text, '21'); |
- expect(div.nodes[i++].text, '22'); |
- |
- m['a'][1] = toObservable({ |
- 'b': 3, |
- 'c': [{'d': 31}, {'d': 32}, {'d': 33}] |
- }); |
- |
- i = start + 4; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes[start + 4].text, '3'); |
- expect(div.nodes[start + 6].text, '31'); |
- expect(div.nodes[start + 7].text, '32'); |
- expect(div.nodes[start + 8].text, '33'); |
- } |
+ return new Future(() { |
+ |
+ var i = start; |
+ expect(div.nodes[i++].text, '1'); |
+ expect(div.nodes[i++].tagName, 'TEMPLATE'); |
+ expect(div.nodes[i++].text, '11'); |
+ expect(div.nodes[i++].text, '12'); |
+ expect(div.nodes[i++].text, '2'); |
+ expect(div.nodes[i++].tagName, 'TEMPLATE'); |
+ expect(div.nodes[i++].text, '21'); |
+ expect(div.nodes[i++].text, '22'); |
+ |
+ m['a'][1] = toObservable({ |
+ 'b': 3, |
+ 'c': [{'d': 31}, {'d': 32}, {'d': 33}] |
+ }); |
- observeTest('NestedRepeatBind', () { |
- nestedIterateIterateHelper( |
- '<template repeat="{{a}}">' |
- '{{b}}' |
- '<template repeat="{{c}}">' |
- '{{d}}' |
- '</template>' |
- '</template>', 1); |
- }); |
+ i = start + 4; |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes[start + 4].text, '3'); |
+ expect(div.nodes[start + 6].text, '31'); |
+ expect(div.nodes[start + 7].text, '32'); |
+ expect(div.nodes[start + 8].text, '33'); |
+ }); |
+ } |
- observeTest('NestedRepeatRepeatWithRef', () { |
- nestedIterateIterateHelper( |
- '<template id="inner">' |
+ test('NestedRepeatBind', () => nestedIterateIterateHelper( |
+ '<template repeat="{{a}}">' |
+ '{{b}}' |
+ '<template repeat="{{c}}">' |
'{{d}}' |
'</template>' |
- '<template repeat="{{a}}">' |
- '{{b}}' |
- '<template ref="inner" repeat="{{c}}"></template>' |
- '</template>', 2); |
- }); |
- |
- observeTest('NestedRepeatSelfRef', () { |
+ '</template>', 1)); |
+ |
+ test('NestedRepeatRepeatWithRef', () => nestedIterateIterateHelper( |
+ '<template id="inner">' |
+ '{{d}}' |
+ '</template>' |
+ '<template repeat="{{a}}">' |
+ '{{b}}' |
+ '<template ref="inner" repeat="{{c}}"></template>' |
+ '</template>', 2)); |
+ |
+ test('NestedRepeatSelfRef', () { |
var div = createTestHtml( |
'<template id="t" repeat="{{}}">' |
'{{name}}' |
@@ -1135,26 +1640,27 @@ templateInstantiationTests() { |
]); |
recursivelySetTemplateModel(div, m); |
- performMicrotaskCheckpoint(); |
- var i = 1; |
- expect(div.nodes[i++].text, 'Item 1'); |
- expect(div.nodes[i++].tagName, 'TEMPLATE'); |
- expect(div.nodes[i++].text, 'Item 1.1'); |
- expect(div.nodes[i++].tagName, 'TEMPLATE'); |
- expect(div.nodes[i++].text, 'Item 1.1.1'); |
- expect(div.nodes[i++].tagName, 'TEMPLATE'); |
- expect(div.nodes[i++].text, 'Item 1.2'); |
- expect(div.nodes[i++].tagName, 'TEMPLATE'); |
- expect(div.nodes[i++].text, 'Item 2'); |
- |
- m[0] = toObservable({'name': 'Item 1 changed'}); |
- |
- i = 1; |
- performMicrotaskCheckpoint(); |
- expect(div.nodes[i++].text, 'Item 1 changed'); |
- expect(div.nodes[i++].tagName, 'TEMPLATE'); |
- expect(div.nodes[i++].text, 'Item 2'); |
+ int i = 1; |
+ return new Future(() { |
+ expect(div.nodes[i++].text, 'Item 1'); |
+ expect(div.nodes[i++].tagName, 'TEMPLATE'); |
+ expect(div.nodes[i++].text, 'Item 1.1'); |
+ expect(div.nodes[i++].tagName, 'TEMPLATE'); |
+ expect(div.nodes[i++].text, 'Item 1.1.1'); |
+ expect(div.nodes[i++].tagName, 'TEMPLATE'); |
+ expect(div.nodes[i++].text, 'Item 1.2'); |
+ expect(div.nodes[i++].tagName, 'TEMPLATE'); |
+ expect(div.nodes[i++].text, 'Item 2'); |
+ |
+ m[0] = toObservable({'name': 'Item 1 changed'}); |
+ |
+ i = 1; |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes[i++].text, 'Item 1 changed'); |
+ expect(div.nodes[i++].tagName, 'TEMPLATE'); |
+ expect(div.nodes[i++].text, 'Item 2'); |
+ }); |
}); |
// Note: we don't need a zone for this test, and we don't want to alter timing |
@@ -1211,8 +1717,8 @@ templateInstantiationTests() { |
return completer.future; |
}); |
- observeTest('NestedIterateTableMixedSemanticNative', () { |
- if (!parserHasNativeTemplate) return; |
+ test('NestedIterateTableMixedSemanticNative', () { |
+ if (!parserHasNativeTemplate) return null; |
var div = createTestHtml( |
'<table><tbody>' |
@@ -1229,30 +1735,30 @@ templateInstantiationTests() { |
]); |
recursivelySetTemplateModel(div, m); |
- performMicrotaskCheckpoint(); |
- |
- var tbody = div.nodes[0].nodes[0]; |
+ return new Future(() { |
+ var tbody = div.nodes[0].nodes[0]; |
- // 1 for the <tr template>, 2 * (1 tr) |
- expect(tbody.nodes.length, 3); |
+ // 1 for the <tr template>, 2 * (1 tr) |
+ expect(tbody.nodes.length, 3); |
- // 1 for the <td template>, 2 * (1 td) |
- expect(tbody.nodes[1].nodes.length, 3); |
+ // 1 for the <td template>, 2 * (1 td) |
+ expect(tbody.nodes[1].nodes.length, 3); |
- expect(tbody.nodes[1].nodes[1].text, '0'); |
- expect(tbody.nodes[1].nodes[2].text, '1'); |
+ expect(tbody.nodes[1].nodes[1].text, '0'); |
+ expect(tbody.nodes[1].nodes[2].text, '1'); |
- // 1 for the <td template>, 2 * (1 td) |
- expect(tbody.nodes[2].nodes.length, 3); |
- expect(tbody.nodes[2].nodes[1].text, '2'); |
- expect(tbody.nodes[2].nodes[2].text, '3'); |
+ // 1 for the <td template>, 2 * (1 td) |
+ expect(tbody.nodes[2].nodes.length, 3); |
+ expect(tbody.nodes[2].nodes[1].text, '2'); |
+ expect(tbody.nodes[2].nodes[2].text, '3'); |
- // Asset the 'class' binding is retained on the semantic template (just |
- // check the last one). |
- expect(tbody.nodes[2].nodes[2].attributes["class"], '3'); |
+ // Asset the 'class' binding is retained on the semantic template (just |
+ // check the last one). |
+ expect(tbody.nodes[2].nodes[2].attributes["class"], '3'); |
+ }); |
}); |
- observeTest('NestedIterateTable', () { |
+ test('NestedIterateTable', () { |
var div = createTestHtml( |
'<table><tbody>' |
'<tr template repeat="{{}}">' |
@@ -1266,30 +1772,31 @@ templateInstantiationTests() { |
]); |
recursivelySetTemplateModel(div, m); |
- performMicrotaskCheckpoint(); |
+ return new Future(() { |
- var i = 1; |
- var tbody = div.nodes[0].nodes[0]; |
+ var i = 1; |
+ var tbody = div.nodes[0].nodes[0]; |
- // 1 for the <tr template>, 2 * (1 tr) |
- expect(tbody.nodes.length, 3); |
+ // 1 for the <tr template>, 2 * (1 tr) |
+ expect(tbody.nodes.length, 3); |
- // 1 for the <td template>, 2 * (1 td) |
- expect(tbody.nodes[1].nodes.length, 3); |
- expect(tbody.nodes[1].nodes[1].text, '0'); |
- expect(tbody.nodes[1].nodes[2].text, '1'); |
+ // 1 for the <td template>, 2 * (1 td) |
+ expect(tbody.nodes[1].nodes.length, 3); |
+ expect(tbody.nodes[1].nodes[1].text, '0'); |
+ expect(tbody.nodes[1].nodes[2].text, '1'); |
- // 1 for the <td template>, 2 * (1 td) |
- expect(tbody.nodes[2].nodes.length, 3); |
- expect(tbody.nodes[2].nodes[1].text, '2'); |
- expect(tbody.nodes[2].nodes[2].text, '3'); |
+ // 1 for the <td template>, 2 * (1 td) |
+ expect(tbody.nodes[2].nodes.length, 3); |
+ expect(tbody.nodes[2].nodes[1].text, '2'); |
+ expect(tbody.nodes[2].nodes[2].text, '3'); |
- // Asset the 'class' binding is retained on the semantic template (just |
- // check the last one). |
- expect(tbody.nodes[2].nodes[2].attributes['class'], '3'); |
+ // Asset the 'class' binding is retained on the semantic template (just |
+ // check the last one). |
+ expect(tbody.nodes[2].nodes[2].attributes['class'], '3'); |
+ }); |
}); |
- observeTest('NestedRepeatDeletionOfMultipleSubTemplates', () { |
+ test('NestedRepeatDeletionOfMultipleSubTemplates', () { |
var div = createTestHtml( |
'<ul>' |
'<template repeat="{{}}" id=t1>' |
@@ -1313,13 +1820,10 @@ templateInstantiationTests() { |
]); |
recursivelySetTemplateModel(div, m); |
- |
- performMicrotaskCheckpoint(); |
- m.removeAt(0); |
- performMicrotaskCheckpoint(); |
+ return new Future(() => m.removeAt(0)); |
}); |
- observeTest('DeepNested', () { |
+ test('DeepNested', () { |
var div = createTestHtml( |
'<template bind="{{a}}">' |
'<p>' |
@@ -1337,34 +1841,36 @@ templateInstantiationTests() { |
} |
}); |
recursivelySetTemplateModel(div, m); |
- performMicrotaskCheckpoint(); |
- |
- expect(div.nodes[1].tagName, 'P'); |
- expect(div.nodes[1].nodes.first.tagName, 'TEMPLATE'); |
- expect(div.nodes[1].nodes[1].text, '42'); |
+ return new Future(() { |
+ expect(div.nodes[1].tagName, 'P'); |
+ expect(div.nodes[1].nodes.first.tagName, 'TEMPLATE'); |
+ expect(div.nodes[1].nodes[1].text, '42'); |
+ }); |
}); |
- observeTest('TemplateContentRemoved', () { |
+ test('TemplateContentRemoved', () { |
var div = createTestHtml('<template bind="{{}}">{{ }}</template>'); |
var model = 42; |
recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes[1].text, '42'); |
- expect(div.nodes[0].text, ''); |
+ return new Future(() { |
+ expect(div.nodes[1].text, '42'); |
+ expect(div.nodes[0].text, ''); |
+ }); |
}); |
- observeTest('TemplateContentRemovedEmptyArray', () { |
+ test('TemplateContentRemovedEmptyArray', () { |
var div = createTestHtml('<template iterate>Remove me</template>'); |
var model = toObservable([]); |
recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 1); |
- expect(div.nodes[0].text, ''); |
+ return new Future(() { |
+ expect(div.nodes.length, 1); |
+ expect(div.nodes[0].text, ''); |
+ }); |
}); |
- observeTest('TemplateContentRemovedNested', () { |
+ test('TemplateContentRemovedNested', () { |
var div = createTestHtml( |
'<template bind="{{}}">' |
'{{ a }}' |
@@ -1378,35 +1884,36 @@ templateInstantiationTests() { |
'b': 2 |
}); |
recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
- |
- expect(div.nodes[0].text, ''); |
- expect(div.nodes[1].text, '1'); |
- expect(div.nodes[2].text, ''); |
- expect(div.nodes[3].text, '2'); |
+ return new Future(() { |
+ expect(div.nodes[0].text, ''); |
+ expect(div.nodes[1].text, '1'); |
+ expect(div.nodes[2].text, ''); |
+ expect(div.nodes[3].text, '2'); |
+ }); |
}); |
- observeTest('BindWithUndefinedModel', () { |
+ test('BindWithUndefinedModel', () { |
var div = createTestHtml( |
'<template bind="{{}}" if="{{}}">{{ a }}</template>'); |
var model = toObservable({'a': 42}); |
recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes[1].text, '42'); |
- |
- model = null; |
- recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 1); |
- |
- model = toObservable({'a': 42}); |
- recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes[1].text, '42'); |
+ return new Future(() { |
+ expect(div.nodes[1].text, '42'); |
+ |
+ model = null; |
+ recursivelySetTemplateModel(div, model); |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 1); |
+ |
+ model = toObservable({'a': 42}); |
+ recursivelySetTemplateModel(div, model); |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes[1].text, '42'); |
+ }); |
}); |
- observeTest('BindNested', () { |
+ test('BindNested', () { |
var div = createTestHtml( |
'<template bind="{{}}">' |
'Name: {{ name }}' |
@@ -1425,24 +1932,24 @@ templateInstantiationTests() { |
} |
}); |
recursivelySetTemplateModel(div, m); |
- performMicrotaskCheckpoint(); |
- |
- expect(div.nodes.length, 5); |
- expect(div.nodes[1].text, 'Name: Hermes'); |
- expect(div.nodes[3].text, 'Wife: LaBarbara'); |
- |
- m['child'] = toObservable({'name': 'Dwight'}); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 6); |
- expect(div.nodes[5].text, 'Child: Dwight'); |
- |
- m.remove('wife'); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 5); |
- expect(div.nodes[4].text, 'Child: Dwight'); |
+ return new Future(() { |
+ expect(div.nodes.length, 5); |
+ expect(div.nodes[1].text, 'Name: Hermes'); |
+ expect(div.nodes[3].text, 'Wife: LaBarbara'); |
+ |
+ m['child'] = toObservable({'name': 'Dwight'}); |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 6); |
+ expect(div.nodes[5].text, 'Child: Dwight'); |
+ |
+ m.remove('wife'); |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 5); |
+ expect(div.nodes[4].text, 'Child: Dwight'); |
+ }); |
}); |
- observeTest('BindRecursive', () { |
+ test('BindRecursive', () { |
var div = createTestHtml( |
'<template bind="{{}}" if="{{}}" id="t">' |
'Name: {{ name }}' |
@@ -1456,24 +1963,24 @@ templateInstantiationTests() { |
} |
}); |
recursivelySetTemplateModel(div, m); |
- performMicrotaskCheckpoint(); |
- |
- expect(div.nodes.length, 5); |
- expect(div.nodes[1].text, 'Name: Fry'); |
- expect(div.nodes[3].text, 'Name: Bender'); |
- |
- m['friend']['friend'] = toObservable({'name': 'Leela'}); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 7); |
- expect(div.nodes[5].text, 'Name: Leela'); |
- |
- m['friend'] = toObservable({'name': 'Leela'}); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 5); |
- expect(div.nodes[3].text, 'Name: Leela'); |
+ return new Future(() { |
+ expect(div.nodes.length, 5); |
+ expect(div.nodes[1].text, 'Name: Fry'); |
+ expect(div.nodes[3].text, 'Name: Bender'); |
+ |
+ m['friend']['friend'] = toObservable({'name': 'Leela'}); |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 7); |
+ expect(div.nodes[5].text, 'Name: Leela'); |
+ |
+ m['friend'] = toObservable({'name': 'Leela'}); |
+ }).then(endOfMicrotask).then((_) { |
+ expect(div.nodes.length, 5); |
+ expect(div.nodes[3].text, 'Name: Leela'); |
+ }); |
}); |
- observeTest('Template - Self is terminator', () { |
+ test('Template - Self is terminator', () { |
var div = createTestHtml( |
'<template repeat>{{ foo }}' |
'<template bind></template>' |
@@ -1481,37 +1988,38 @@ templateInstantiationTests() { |
var m = toObservable([{ 'foo': 'bar' }]); |
recursivelySetTemplateModel(div, m); |
- performMicrotaskCheckpoint(); |
+ return new Future(() { |
- m.add(toObservable({ 'foo': 'baz' })); |
- recursivelySetTemplateModel(div, m); |
- performMicrotaskCheckpoint(); |
+ m.add(toObservable({ 'foo': 'baz' })); |
+ recursivelySetTemplateModel(div, m); |
+ }).then(endOfMicrotask).then((_) { |
- expect(div.nodes.length, 5); |
- expect(div.nodes[1].text, 'bar'); |
- expect(div.nodes[3].text, 'baz'); |
+ expect(div.nodes.length, 5); |
+ expect(div.nodes[1].text, 'bar'); |
+ expect(div.nodes[3].text, 'baz'); |
+ }); |
}); |
- observeTest('Template - Same Contents, Different Array has no effect', () { |
- if (!MutationObserver.supported) return; |
+ test('Template - Same Contents, Different Array has no effect', () { |
+ if (!MutationObserver.supported) return null; |
var div = createTestHtml('<template repeat>{{ foo }}</template>'); |
var m = toObservable([{ 'foo': 'bar' }, { 'foo': 'bat'}]); |
recursivelySetTemplateModel(div, m); |
- performMicrotaskCheckpoint(); |
- |
- var observer = new MutationObserver((records, _) {}); |
- observer.observe(div, childList: true); |
- |
- var template = div.firstChild; |
- nodeBind(template).bind('repeat', toObservable(m.toList()), ''); |
- performMicrotaskCheckpoint(); |
- var records = observer.takeRecords(); |
- expect(records.length, 0); |
+ var observer = new MutationObserver((x, y) {}); |
+ return new Future(() { |
+ observer.observe(div, childList: true); |
+ |
+ var template = div.firstChild; |
+ templateBind(template).model = new ObservableList.from(m); |
+ }).then(endOfMicrotask).then((_) { |
+ var records = observer.takeRecords(); |
+ expect(records.length, 0); |
+ }); |
}); |
- observeTest('RecursiveRef', () { |
+ test('RecursiveRef', () { |
var div = createTestHtml( |
'<template bind>' |
'<template id=src>{{ foo }}</template>' |
@@ -1520,54 +2028,13 @@ templateInstantiationTests() { |
var m = toObservable({'foo': 'bar'}); |
recursivelySetTemplateModel(div, m); |
- performMicrotaskCheckpoint(); |
- |
- expect(div.nodes.length, 4); |
- expect(div.nodes[3].text, 'bar'); |
- }); |
- |
- observeTest('ChangeFromBindToRepeat', () { |
- var div = createTestHtml( |
- '<template bind="{{a}}">' |
- '{{ length }}' |
- '</template>'); |
- var template = div.nodes.first; |
- |
- // Note: this test data is a little different from the JS version, because |
- // we allow binding to the "length" field of the Map in preference to |
- // binding keys. |
- var m = toObservable({ |
- 'a': [ |
- [], |
- { 'b': [1,2,3,4] }, |
- // Note: this will use the Map "length" property, not the "length" key. |
- {'length': 42, 'c': 123} |
- ] |
+ return new Future(() { |
+ expect(div.nodes.length, 4); |
+ expect(div.nodes[3].text, 'bar'); |
}); |
- recursivelySetTemplateModel(div, m); |
- performMicrotaskCheckpoint(); |
- |
- expect(div.nodes.length, 2); |
- expect(div.nodes[1].text, '3'); |
- |
- nodeBind(template) |
- ..unbind('bind') |
- ..bind('repeat', m, 'a'); |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 4); |
- expect(div.nodes[1].text, '0'); |
- expect(div.nodes[2].text, '1'); |
- expect(div.nodes[3].text, '2'); |
- |
- nodeBind(template).unbind('repeat'); |
- nodeBind(template).bind('bind', m, 'a.1.b'); |
- |
- performMicrotaskCheckpoint(); |
- expect(div.nodes.length, 2); |
- expect(div.nodes[1].text, '4'); |
}); |
- observeTest('ChangeRefId', () { |
+ test('ChangeRefId', () { |
var div = createTestHtml( |
'<template id="a">a:{{ }}</template>' |
'<template id="b">b:{{ }}</template>' |
@@ -1576,22 +2043,22 @@ templateInstantiationTests() { |
'</template>'); |
var model = toObservable([]); |
recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
- |
- expect(div.nodes.length, 3); |
+ return new Future(() { |
+ expect(div.nodes.length, 3); |
- document.getElementById('a').id = 'old-a'; |
- document.getElementById('b').id = 'a'; |
+ document.getElementById('a').id = 'old-a'; |
+ document.getElementById('b').id = 'a'; |
- model..add(1)..add(2); |
- performMicrotaskCheckpoint(); |
+ model..add(1)..add(2); |
+ }).then(endOfMicrotask).then((_) { |
- expect(div.nodes.length, 7); |
- expect(div.nodes[4].text, 'b:1'); |
- expect(div.nodes[6].text, 'b:2'); |
+ expect(div.nodes.length, 7); |
+ expect(div.nodes[4].text, 'b:1'); |
+ expect(div.nodes[6].text, 'b:2'); |
+ }); |
}); |
- observeTest('Content', () { |
+ test('Content', () { |
var div = createTestHtml( |
'<template><a></a></template>' |
'<template><b></b></template>'); |
@@ -1620,7 +2087,7 @@ templateInstantiationTests() { |
expect(contentB.nodes.first.tagName, 'B'); |
}); |
- observeTest('NestedContent', () { |
+ test('NestedContent', () { |
var div = createTestHtml( |
'<template>' |
'<template></template>' |
@@ -1634,46 +2101,44 @@ templateInstantiationTests() { |
templateBind(templateA).content.ownerDocument); |
}); |
- observeTest('BindShadowDOM', () { |
- if (ShadowRoot.supported) { |
- var root = createShadowTestHtml( |
- '<template bind="{{}}">Hi {{ name }}</template>'); |
- var model = toObservable({'name': 'Leela'}); |
- recursivelySetTemplateModel(root, model); |
- performMicrotaskCheckpoint(); |
- expect(root.nodes[1].text, 'Hi Leela'); |
- } |
+ test('BindShadowDOM', () { |
+ if (!ShadowRoot.supported) return null; |
+ |
+ var root = createShadowTestHtml( |
+ '<template bind="{{}}">Hi {{ name }}</template>'); |
+ var model = toObservable({'name': 'Leela'}); |
+ recursivelySetTemplateModel(root, model); |
+ return new Future(() => expect(root.nodes[1].text, 'Hi Leela')); |
}); |
// Dart note: this test seems gone from JS. Keeping for posterity sake. |
- observeTest('BindShadowDOM createInstance', () { |
- if (ShadowRoot.supported) { |
- var model = toObservable({'name': 'Leela'}); |
- var template = new Element.html('<template>Hi {{ name }}</template>'); |
- var root = createShadowTestHtml(''); |
- root.nodes.add(templateBind(template).createInstance(model)); |
- |
- performMicrotaskCheckpoint(); |
+ test('BindShadowDOM createInstance', () { |
+ if (!ShadowRoot.supported) return null; |
+ |
+ var model = toObservable({'name': 'Leela'}); |
+ var template = new Element.html('<template>Hi {{ name }}</template>'); |
+ var root = createShadowTestHtml(''); |
+ root.nodes.add(templateBind(template).createInstance(model)); |
+ |
+ return new Future(() { |
expect(root.text, 'Hi Leela'); |
model['name'] = 'Fry'; |
- performMicrotaskCheckpoint(); |
+ }).then(endOfMicrotask).then((_) { |
expect(root.text, 'Hi Fry'); |
- } |
+ }); |
}); |
- observeTest('BindShadowDOM Template Ref', () { |
- if (ShadowRoot.supported) { |
- var root = createShadowTestHtml( |
- '<template id=foo>Hi</template><template bind ref=foo></template>'); |
- recursivelySetTemplateModel(root, toObservable({})); |
- performMicrotaskCheckpoint(); |
- expect(root.nodes.length, 3); |
- } |
+ test('BindShadowDOM Template Ref', () { |
+ if (!ShadowRoot.supported) return null; |
+ var root = createShadowTestHtml( |
+ '<template id=foo>Hi</template><template bind ref=foo></template>'); |
+ recursivelySetTemplateModel(root, toObservable({})); |
+ return new Future(() => expect(root.nodes.length, 3)); |
}); |
- // https://github.com/toolkitchen/mdv/issues/8 |
- observeTest('UnbindingInNestedBind', () { |
+ // https://github.com/Polymer/TemplateBinding/issues/8 |
+ test('UnbindingInNestedBind', () { |
var div = createTestHtml( |
'<template bind="{{outer}}" if="{{outer}}" syntax="testHelper">' |
'<template bind="{{inner}}" if="{{inner}}">' |
@@ -1682,44 +2147,38 @@ templateInstantiationTests() { |
'</template>'); |
var syntax = new UnbindingInNestedBindSyntax(); |
- var model = toObservable({ |
- 'outer': { |
- 'inner': { |
- 'age': 42 |
- } |
- } |
- }); |
+ var model = toObservable({'outer': {'inner': {'age': 42}}}); |
recursivelySetTemplateModel(div, model, syntax); |
- performMicrotaskCheckpoint(); |
- expect(syntax.count, 1); |
+ return new Future(() { |
+ expect(syntax.count, 1); |
- var inner = model['outer']['inner']; |
- model['outer'] = null; |
+ var inner = model['outer']['inner']; |
+ model['outer'] = null; |
- performMicrotaskCheckpoint(); |
- expect(syntax.count, 1); |
+ }).then(endOfMicrotask).then((_) { |
+ expect(syntax.count, 1); |
- model['outer'] = toObservable({'inner': {'age': 2}}); |
- syntax.expectedAge = 2; |
+ model['outer'] = toObservable({'inner': {'age': 2}}); |
+ syntax.expectedAge = 2; |
- performMicrotaskCheckpoint(); |
- expect(syntax.count, 2); |
+ }).then(endOfMicrotask).then((_) { |
+ expect(syntax.count, 2); |
+ }); |
}); |
// https://github.com/toolkitchen/mdv/issues/8 |
- observeTest('DontCreateInstancesForAbandonedIterators', () { |
+ test('DontCreateInstancesForAbandonedIterators', () { |
var div = createTestHtml( |
'<template bind="{{}} {{}}">' |
- '<template bind="{{}}">Foo' |
- '</template>' |
+ '<template bind="{{}}">Foo</template>' |
'</template>'); |
recursivelySetTemplateModel(div, null); |
- performMicrotaskCheckpoint(); |
+ return nextMicrotask; |
}); |
- observeTest('CreateInstance', () { |
+ test('CreateInstance', () { |
var div = createTestHtml( |
'<template bind="{{a}}">' |
'<template bind="{{b}}">' |
@@ -1735,11 +2194,35 @@ templateInstantiationTests() { |
templateBind(instance.nodes.first).ref); |
host.append(instance); |
- performMicrotaskCheckpoint(); |
- expect(host.firstChild.nextNode.text, 'bar:replaced'); |
+ return new Future(() { |
+ expect(host.firstChild.nextNode.text, 'bar:replaced'); |
+ }); |
+ }); |
+ |
+ test('Repeat - svg', () { |
+ var div = createTestHtml( |
+ '<svg width="400" height="110">' |
+ '<template repeat>' |
+ '<rect width="{{ width }}" height="{{ height }}" />' |
+ '</template>' |
+ '</svg>'); |
+ |
+ var model = toObservable([{ 'width': 10, 'height': 11 }, |
+ { 'width': 20, 'height': 21 }]); |
+ var svg = div.firstChild; |
+ var template = svg.firstChild; |
+ templateBind(template).model = model; |
+ |
+ return new Future(() { |
+ expect(svg.nodes.length, 3); |
+ expect(svg.nodes[1].attributes['width'], '10'); |
+ expect(svg.nodes[1].attributes['height'], '11'); |
+ expect(svg.nodes[2].attributes['width'], '20'); |
+ expect(svg.nodes[2].attributes['height'], '21'); |
+ }); |
}); |
- observeTest('Bootstrap', () { |
+ test('Bootstrap', () { |
var div = new DivElement(); |
div.innerHtml = |
'<template>' |
@@ -1773,7 +2256,7 @@ templateInstantiationTests() { |
expect(template3.content.nodes.first.text, 'Hello'); |
}); |
- observeTest('issue-285', () { |
+ test('issue-285', () { |
var div = createTestHtml( |
'<template>' |
'<template bind if="{{show}}">' |
@@ -1793,19 +2276,20 @@ templateInstantiationTests() { |
div.append(templateBind(template).createInstance(model, |
new Issue285Syntax())); |
- performMicrotaskCheckpoint(); |
- expect(template.nextNode.nextNode.nextNode.text, '2'); |
- model['show'] = false; |
- performMicrotaskCheckpoint(); |
- model['show'] = true; |
- performMicrotaskCheckpoint(); |
- expect(template.nextNode.nextNode.nextNode.text, '2'); |
+ return new Future(() { |
+ expect(template.nextNode.nextNode.nextNode.text, '2'); |
+ model['show'] = false; |
+ }).then(endOfMicrotask).then((_) { |
+ model['show'] = true; |
+ }).then(endOfMicrotask).then((_) { |
+ expect(template.nextNode.nextNode.nextNode.text, '2'); |
+ }); |
}); |
- observeTest('issue-141', () { |
+ test('issue-141', () { |
var div = createTestHtml( |
- '<template bind>' + |
- '<div foo="{{foo1}} {{foo2}}" bar="{{bar}}"></div>' + |
+ '<template bind>' |
+ '<div foo="{{foo1}} {{foo2}}" bar="{{bar}}"></div>' |
'</template>'); |
var model = toObservable({ |
@@ -1815,14 +2299,40 @@ templateInstantiationTests() { |
}); |
recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
+ return new Future(() { |
+ expect(div.lastChild.attributes['bar'], 'barValue'); |
+ }); |
+ }); |
+ |
+ test('issue-18', () { |
+ var delegate = new Issue18Syntax(); |
+ |
+ var div = createTestHtml( |
+ '<template bind>' |
+ '<div class="foo: {{ bar }}"></div>' |
+ '</template>'); |
- expect(div.lastChild.attributes['bar'], 'barValue'); |
+ var model = toObservable({'bar': 2}); |
+ |
+ recursivelySetTemplateModel(div, model, delegate); |
+ |
+ return new Future(() { |
+ expect(div.lastChild.attributes['class'], 'foo: 2'); |
+ }); |
+ }); |
+ |
+ test('issue-152', () { |
+ var div = createTestHtml('<template ref=notThere></template>'); |
+ var template = div.firstChild; |
+ |
+ // if a ref cannot be located, a template will continue to use itself |
+ // as the source of template instances. |
+ expect(template, templateBind(template).ref); |
}); |
} |
compatTests() { |
- observeTest('underbar bindings', () { |
+ test('underbar bindings', () { |
var div = createTestHtml( |
'<template bind>' |
'<div _style="color: {{ color }};"></div>' |
@@ -1839,19 +2349,19 @@ compatTests() { |
}); |
recursivelySetTemplateModel(div, model); |
- performMicrotaskCheckpoint(); |
+ return new Future(() { |
+ var subDiv = div.firstChild.nextNode; |
+ expect(subDiv.attributes['style'], 'color: red;'); |
- var subDiv = div.firstChild.nextNode; |
- expect(subDiv.attributes['style'], 'color: red;'); |
+ var img = subDiv.nextNode; |
+ expect(img.attributes['src'], 'pic.jpg'); |
- var img = subDiv.nextNode; |
- expect(img.attributes['src'], 'pic.jpg'); |
+ var a = img.nextNode; |
+ expect(a.attributes['href'], 'link.html'); |
- var a = img.nextNode; |
- expect(a.attributes['href'], 'link.html'); |
- |
- var input = a.nextNode; |
- expect(input.value, '4'); |
+ var input = a.nextNode; |
+ expect(input.value, '4'); |
+ }); |
}); |
} |
@@ -1864,7 +2374,7 @@ class Issue285Syntax extends BindingDelegate { |
class TestBindingSyntax extends BindingDelegate { |
prepareBinding(String path, name, node) { |
if (path.trim() == 'replaceme') { |
- return (x, y) => new ObservableBox('replaced'); |
+ return (m, n, oneTime) => new PathObserver('replaced', ''); |
} |
return null; |
} |
@@ -1877,10 +2387,18 @@ class UnbindingInNestedBindSyntax extends BindingDelegate { |
prepareBinding(path, name, node) { |
if (name != 'text' || path != 'age') return null; |
- return (model, node) { |
+ return (model, _, oneTime) { |
expect(model['age'], expectedAge); |
count++; |
- return model; |
+ return new PathObserver(model, path); |
}; |
} |
} |
+ |
+class Issue18Syntax extends BindingDelegate { |
+ prepareBinding(path, name, node) { |
+ if (name != 'class') return null; |
+ |
+ return (model, _, oneTime) => new PathObserver(model, path); |
+ } |
+} |