| Index: tests/html/binding_syntax_test.dart
|
| ===================================================================
|
| --- tests/html/binding_syntax_test.dart (revision 22591)
|
| +++ tests/html/binding_syntax_test.dart (working copy)
|
| @@ -5,6 +5,7 @@
|
| library binding_syntax_test;
|
|
|
| import 'dart:async';
|
| +import 'dart:collection';
|
| import 'dart:html';
|
| import 'package:mdv_observe/mdv_observe.dart';
|
| import 'package:unittest/html_config.dart';
|
| @@ -54,26 +55,95 @@
|
|
|
| var testSyntax = new TestBindingSyntax();
|
| TemplateElement.syntax['Test'] = testSyntax;
|
| + try {
|
| + var div = createTestHtml(
|
| + '<template bind syntax="Test">{{ foo }}' +
|
| + '<template bind>{{ foo }}</template></template>');
|
| + recursivelySetTemplateModel(div, model);
|
| + deliverChangeRecords();
|
| + expect(div.nodes.length, 4);
|
| + expect(div.nodes.last.text, 'bar');
|
| + expect(div.nodes[2].tagName, 'TEMPLATE');
|
| + expect(div.nodes[2].attributes['syntax'], 'Test');
|
|
|
| - var div = createTestHtml(
|
| - '<template bind syntax="Test">{{ foo }}' +
|
| - '<template bind>{{ foo }}</template></template>');
|
| - recursivelySetTemplateModel(div, model);
|
| - deliverChangeRecords();
|
| - expect(div.nodes.length, 4);
|
| - expect(div.nodes.last.text, 'bar');
|
| - expect(div.nodes[2].tagName, 'TEMPLATE');
|
| - expect(div.nodes[2].attributes['syntax'], 'Test');
|
| + expect(testSyntax.log, [
|
| + [model, '', 'bind', 'TEMPLATE'],
|
| + [model, 'foo', 'text', null],
|
| + [model, '', 'bind', 'TEMPLATE'],
|
| + [model, 'foo', 'text', null],
|
| + ]);
|
| + } finally {
|
| + TemplateElement.syntax.remove('Test');
|
| + }
|
| + });
|
|
|
| - expect(testSyntax.log, [
|
| - [model, 'foo', 'text', null],
|
| - [model, '', 'bind', 'TEMPLATE'],
|
| - [model, 'foo', 'text', null],
|
| - ]);
|
| + test('getInstanceModel', () {
|
| + var model = toObservable([{'foo': 1}, {'foo': 2}, {'foo': 3}]
|
| + .map(toSymbolMap));
|
|
|
| - TemplateElement.syntax.remove('Test');
|
| + var testSyntax = new TestModelSyntax();
|
| + testSyntax.altModels.addAll([{'foo': 'a'}, {'foo': 'b'}, {'foo': 'c'}]
|
| + .map(toSymbolMap));
|
| +
|
| + TemplateElement.syntax['Test'] = testSyntax;
|
| + try {
|
| +
|
| + var div = createTestHtml(
|
| + '<template repeat syntax="Test">' +
|
| + '{{ foo }}</template>');
|
| +
|
| + var template = div.nodes[0];
|
| + recursivelySetTemplateModel(div, model);
|
| + deliverChangeRecords();
|
| +
|
| + expect(div.nodes.length, 4);
|
| + expect(div.nodes[0].tagName, 'TEMPLATE');
|
| + expect(div.nodes[1].text, 'a');
|
| + expect(div.nodes[2].text, 'b');
|
| + expect(div.nodes[3].text, 'c');
|
| +
|
| + expect(testSyntax.log, [
|
| + [template, model[0]],
|
| + [template, model[1]],
|
| + [template, model[2]],
|
| + ]);
|
| +
|
| + } finally {
|
| + TemplateElement.syntax.remove('Test');
|
| + }
|
| });
|
|
|
| + // Note: this test was original, not a port of an existing test.
|
| + test('getInstanceFragment', () {
|
| + var model = toSymbolMap({'foo': 'bar'});
|
| +
|
| + var testSyntax = new WhitespaceRemover();
|
| + TemplateElement.syntax['Test'] = testSyntax;
|
| + try {
|
| + var div = createTestHtml(
|
| + '''<template bind syntax="Test">
|
| + {{ foo }}
|
| + <template bind>
|
| + {{ foo }}
|
| + </template>
|
| + </template>''');
|
| +
|
| + recursivelySetTemplateModel(div, model);
|
| + deliverChangeRecords();
|
| +
|
| + expect(testSyntax.trimmed, 2);
|
| + expect(testSyntax.removed, 1);
|
| +
|
| + expect(div.nodes.length, 4);
|
| + expect(div.nodes.last.text, 'bar');
|
| + expect(div.nodes[2].tagName, 'TEMPLATE');
|
| + expect(div.nodes[2].attributes['syntax'], 'Test');
|
| +
|
| + } finally {
|
| + TemplateElement.syntax.remove('Test');
|
| + }
|
| + });
|
| +
|
| test('Basic', () {
|
| var model = toSymbolMap({'foo': 2, 'bar': 4});
|
|
|
| @@ -115,6 +185,7 @@
|
| var test2Log = TemplateElement.syntax['Test2'].log;
|
|
|
| expect(testLog, [
|
| + [model, '', 'bind', 'TEMPLATE'],
|
| [model, 'foo', 'text', null],
|
| [model, '', 'bind', 'TEMPLATE']
|
| ]);
|
| @@ -126,6 +197,8 @@
|
| });
|
| }
|
|
|
| +// TODO(jmesserly): mocks would be cleaner here.
|
| +
|
| class TestBindingSyntax extends CustomBindingSyntax {
|
| var log = [];
|
|
|
| @@ -134,6 +207,49 @@
|
| }
|
| }
|
|
|
| +class TestModelSyntax extends CustomBindingSyntax {
|
| + var log = [];
|
| + var altModels = new ListQueue();
|
| +
|
| + getInstanceModel(template, model) {
|
| + log.add([template, model]);
|
| + return altModels.removeFirst();
|
| + }
|
| +}
|
| +
|
| +// Note: this isn't a very smart whitespace handler. A smarter one would only
|
| +// trim indentation, not all whitespace.
|
| +// See "trimOrCompact" in the web_ui Pub package.
|
| +class WhitespaceRemover extends CustomBindingSyntax {
|
| + int trimmed = 0;
|
| + int removed = 0;
|
| +
|
| + DocumentFragment getInstanceFragment(Element template) {
|
| + var instance = template.createInstance();
|
| + var walker = new TreeWalker(instance, NodeFilter.SHOW_TEXT);
|
| +
|
| + var toRemove = [];
|
| + while (walker.nextNode() != null) {
|
| + var node = walker.currentNode;
|
| + var text = node.text.replaceAll('\n', '').trim();
|
| + if (text.length != node.text.length) {
|
| + if (text.length == 0) {
|
| + toRemove.add(node);
|
| + } else {
|
| + trimmed++;
|
| + node.text = text;
|
| + }
|
| + }
|
| + }
|
| +
|
| + for (var node in toRemove) node.remove();
|
| + removed += toRemove.length;
|
| +
|
| + return instance;
|
| + }
|
| +}
|
| +
|
| +
|
| class TimesTwoSyntax extends CustomBindingSyntax {
|
| getBinding(model, path, name, node) {
|
| path = path.trim();
|
|
|