feat(test_lib): add method to compare stringified DOM element

Closes #2106
This commit is contained in:
Marc Laval 2015-05-22 17:47:13 +02:00
parent fb42d5908e
commit c6335c128e
6 changed files with 88 additions and 25 deletions

View File

@ -172,8 +172,12 @@ class ListWrapper {
l.removeRange(from, to); l.removeRange(from, to);
return sub; return sub;
} }
static void sort(List l, compareFn(a, b)) { static void sort(List l, [compareFn(a, b) = null]) {
l.sort(compareFn); if (compareFn == null) {
l.sort();
} else {
l.sort(compareFn);
}
} }
// JS splice, slice, fill functions can take start < 0 which indicates a position relative to // JS splice, slice, fill functions can take start < 0 which indicates a position relative to

View File

@ -1,4 +1,4 @@
import {isJsObject, global} from 'angular2/src/facade/lang'; import {isJsObject, global, isPresent} from 'angular2/src/facade/lang';
export var List = global.Array; export var List = global.Array;
export var Map = global.Map; export var Map = global.Map;
@ -231,7 +231,13 @@ export class ListWrapper {
return l.slice(from, to === null ? undefined : to); return l.slice(from, to === null ? undefined : to);
} }
static splice<T>(l: List<T>, from: int, length: int): List<T> { return l.splice(from, length); } static splice<T>(l: List<T>, from: int, length: int): List<T> { return l.splice(from, length); }
static sort<T>(l: List<T>, compareFn: (a: T, b: T) => number) { l.sort(compareFn); } static sort<T>(l: List<T>, compareFn?: (a: T, b: T) => number) {
if (isPresent(compareFn)) {
l.sort(compareFn);
} else {
l.sort();
}
}
} }
export function isListLikeIterable(obj): boolean { export function isListLikeIterable(obj): boolean {

View File

@ -1,6 +1,6 @@
import {List, ListWrapper} from 'angular2/src/facade/collection'; import {List, ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
import {DOM} from 'angular2/src/dom/dom_adapter'; import {DOM} from 'angular2/src/dom/dom_adapter';
import {isPresent, RegExpWrapper, StringWrapper, RegExp} from 'angular2/src/facade/lang'; import {isPresent, isString, RegExpWrapper, StringWrapper, RegExp} from 'angular2/src/facade/lang';
import {resolveInternalDomView} from 'angular2/src/render/dom/view/view'; import {resolveInternalDomView} from 'angular2/src/render/dom/view/view';
export class Log { export class Log {
@ -59,3 +59,45 @@ export function normalizeCSS(css: string): string {
(match) => `[${match[1]}="${match[2]}"]`); (match) => `[${match[1]}="${match[2]}"]`);
return css; return css;
} }
var _singleTagWhitelist = ['br', 'hr', 'input'];
export function stringifyElement(el): string {
var result = '';
if (DOM.isElementNode(el)) {
var tagName = StringWrapper.toLowerCase(DOM.tagName(el));
// Opening tag
result += `<${tagName}`;
// Attributes in an ordered way
var attributeMap = DOM.attributeMap(el);
var keys = ListWrapper.create();
MapWrapper.forEach(attributeMap, (v, k) => { ListWrapper.push(keys, k); });
ListWrapper.sort(keys);
for (let i = 0; i < keys.length; i++) {
var key = keys[i];
var attValue = MapWrapper.get(attributeMap, key);
if (!isString(attValue)) {
result += ` ${key}`;
} else {
result += ` ${key}="${attValue}"`;
}
}
result += '>';
// Children
var children = DOM.childNodes(DOM.templateAwareRoot(el));
for (let j = 0; j < children.length; j++) {
result += stringifyElement(children[j]);
}
// Closing tag
if (!ListWrapper.contains(_singleTagWhitelist, tagName)) {
result += `</${tagName}>`;
}
} else {
result += DOM.getText(el);
}
return result;
}

View File

@ -13,7 +13,8 @@ import {
beforeEachBindings, beforeEachBindings,
it, it,
xit, xit,
containsRegexp containsRegexp,
stringifyElement
} from 'angular2/test_lib'; } from 'angular2/test_lib';
@ -724,9 +725,9 @@ export function main() {
var updateHost = injector.get(DirectiveUpdatingHostActions); var updateHost = injector.get(DirectiveUpdatingHostActions);
ObservableWrapper.subscribe(updateHost.setAttr, (_) => { ObservableWrapper.subscribe(updateHost.setAttr, (_) => {
expect(DOM.getOuterHTML(domElement)) expect(stringifyElement(domElement))
.toEqual( .toEqual(
'<div update-host-actions="" class="ng-binding" key="value"></div>'); '<div class="ng-binding" key="value" update-host-actions=""></div>');
async.done(); async.done();
}); });

View File

@ -1,4 +1,13 @@
import {describe, beforeEach, it, expect, iit, ddescribe, el} from 'angular2/test_lib'; import {
describe,
beforeEach,
it,
expect,
iit,
ddescribe,
el,
stringifyElement
} from 'angular2/test_lib';
import {MapWrapper} from 'angular2/src/facade/collection'; import {MapWrapper} from 'angular2/src/facade/collection';
import {ViewSplitter} from 'angular2/src/render/dom/compiler/view_splitter'; import {ViewSplitter} from 'angular2/src/render/dom/compiler/view_splitter';
@ -21,10 +30,10 @@ export function main() {
var rootElement = el('<div><template if="true">a</template></div>'); var rootElement = el('<div><template if="true">a</template></div>');
var results = createPipeline().process(rootElement); var results = createPipeline().process(rootElement);
expect(DOM.getOuterHTML(results[1].element)) expect(stringifyElement(results[1].element))
.toEqual('<template if="true" class="ng-binding"></template>'); .toEqual('<template class="ng-binding" if="true"></template>');
expect(results[1].isViewRoot).toBe(false); expect(results[1].isViewRoot).toBe(false);
expect(DOM.getOuterHTML(results[2].element)).toEqual('<template>a</template>'); expect(stringifyElement(results[2].element)).toEqual('<template>a</template>');
expect(results[2].isViewRoot).toBe(true); expect(results[2].isViewRoot).toBe(true);
}); });
@ -38,7 +47,7 @@ export function main() {
var rootElement = el('<div></div>'); var rootElement = el('<div></div>');
var results = createPipeline().process(rootElement); var results = createPipeline().process(rootElement);
expect(results.length).toBe(1); expect(results.length).toBe(1);
expect(DOM.getOuterHTML(rootElement)).toEqual('<div></div>'); expect(stringifyElement(rootElement)).toEqual('<div></div>');
}); });
it('should copy over the elementDescription', () => { it('should copy over the elementDescription', () => {
@ -60,7 +69,7 @@ export function main() {
expect(results[2].inheritedProtoView) expect(results[2].inheritedProtoView)
.toBe(results[1].inheritedElementBinder.nestedProtoView); .toBe(results[1].inheritedElementBinder.nestedProtoView);
expect(results[2].inheritedProtoView.type).toBe(ProtoViewDto.EMBEDDED_VIEW_TYPE); expect(results[2].inheritedProtoView.type).toBe(ProtoViewDto.EMBEDDED_VIEW_TYPE);
expect(DOM.getOuterHTML(results[2].inheritedProtoView.rootElement)) expect(stringifyElement(results[2].inheritedProtoView.rootElement))
.toEqual('<template>a</template>'); .toEqual('<template>a</template>');
}); });
@ -73,9 +82,9 @@ export function main() {
var originalChild = rootElement.childNodes[0]; var originalChild = rootElement.childNodes[0];
var results = createPipeline().process(rootElement); var results = createPipeline().process(rootElement);
expect(results[0].element).toBe(rootElement); expect(results[0].element).toBe(rootElement);
expect(DOM.getOuterHTML(results[0].element)) expect(stringifyElement(results[0].element))
.toEqual('<div><template class="ng-binding"></template></div>'); .toEqual('<div><template class="ng-binding"></template></div>');
expect(DOM.getOuterHTML(results[2].element)).toEqual('<span template=""></span>'); expect(stringifyElement(results[2].element)).toEqual('<span template=""></span>');
expect(results[2].element).toBe(originalChild); expect(results[2].element).toBe(originalChild);
}); });
@ -87,7 +96,7 @@ export function main() {
expect(results[0].element).toBe(rootElement); expect(results[0].element).toBe(rootElement);
expect(results[0].isViewRoot).toBe(true); expect(results[0].isViewRoot).toBe(true);
expect(results[2].isViewRoot).toBe(true); expect(results[2].isViewRoot).toBe(true);
expect(DOM.getOuterHTML(results[0].element)) expect(stringifyElement(results[0].element))
.toEqual('<template><template class="ng-binding"></template></template>'); .toEqual('<template><template class="ng-binding"></template></template>');
expect(results[2].element).toBe(originalChild); expect(results[2].element).toBe(originalChild);
}); });
@ -147,7 +156,7 @@ export function main() {
expect(results[2].inheritedProtoView).not.toBe(null); expect(results[2].inheritedProtoView).not.toBe(null);
expect(results[2].inheritedProtoView) expect(results[2].inheritedProtoView)
.toBe(results[1].inheritedElementBinder.nestedProtoView); .toBe(results[1].inheritedElementBinder.nestedProtoView);
expect(DOM.getOuterHTML(results[2].inheritedProtoView.rootElement)) expect(stringifyElement(results[2].inheritedProtoView.rootElement))
.toEqual('<span template=""></span>'); .toEqual('<span template=""></span>');
}); });
@ -160,9 +169,9 @@ export function main() {
var originalChild = rootElement.childNodes[0]; var originalChild = rootElement.childNodes[0];
var results = createPipeline().process(rootElement); var results = createPipeline().process(rootElement);
expect(results[0].element).toBe(rootElement); expect(results[0].element).toBe(rootElement);
expect(DOM.getOuterHTML(results[0].element)) expect(stringifyElement(results[0].element))
.toEqual('<div><template class="ng-binding" ng-if=""></template></div>'); .toEqual('<div><template class="ng-binding" ng-if=""></template></div>');
expect(DOM.getOuterHTML(results[2].element)).toEqual('<span *ng-if=""></span>'); expect(stringifyElement(results[2].element)).toEqual('<span *ng-if=""></span>');
expect(results[2].element).toBe(originalChild); expect(results[2].element).toBe(originalChild);
}); });
@ -180,7 +189,7 @@ export function main() {
expect(results[0].element).toBe(rootElement); expect(results[0].element).toBe(rootElement);
expect(results[0].isViewRoot).toBe(true); expect(results[0].isViewRoot).toBe(true);
expect(results[2].isViewRoot).toBe(true); expect(results[2].isViewRoot).toBe(true);
expect(DOM.getOuterHTML(results[0].element)) expect(stringifyElement(results[0].element))
.toEqual('<template><template class="ng-binding" foo=""></template></template>'); .toEqual('<template><template class="ng-binding" foo=""></template></template>');
expect(results[2].element).toBe(originalChild); expect(results[2].element).toBe(originalChild);
}); });
@ -233,7 +242,7 @@ export function main() {
expect(results[2].inheritedProtoView).not.toBe(null); expect(results[2].inheritedProtoView).not.toBe(null);
expect(results[2].inheritedProtoView) expect(results[2].inheritedProtoView)
.toBe(results[1].inheritedElementBinder.nestedProtoView); .toBe(results[1].inheritedElementBinder.nestedProtoView);
expect(DOM.getOuterHTML(results[2].inheritedProtoView.rootElement)) expect(stringifyElement(results[2].inheritedProtoView.rootElement))
.toEqual('<span *foo=""></span>'); .toEqual('<span *foo=""></span>');
}); });

View File

@ -7,7 +7,8 @@ import {
iit, iit,
SpyObject, SpyObject,
el, el,
proxy proxy,
stringifyElement
} from 'angular2/test_lib'; } from 'angular2/test_lib';
import {IMPLEMENTS, isBlank, isPresent} from 'angular2/src/facade/lang'; import {IMPLEMENTS, isBlank, isPresent} from 'angular2/src/facade/lang';
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection'; import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
@ -228,5 +229,5 @@ export function main() {
function toHtml(nodes) { function toHtml(nodes) {
if (isBlank(nodes)) return []; if (isBlank(nodes)) return [];
return ListWrapper.map(nodes, DOM.getOuterHTML); return ListWrapper.map(nodes, stringifyElement);
} }