feat(pipes): replaces iterable and key value diffing pipes with services
BREAKING CHANGE:
Directives that previously injected Pipes to get iterableDiff or keyvalueDiff, now should inject IterableDiffers and KeyValueDiffers.
This commit is contained in:
+96
-71
@@ -1,5 +1,8 @@
|
||||
import {describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/test_lib';
|
||||
import {IterableChanges} from 'angular2/src/change_detection/pipes/iterable_changes';
|
||||
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/test_lib';
|
||||
import {
|
||||
DefaultIterableDiffer,
|
||||
DefaultIterableDifferFactory
|
||||
} from 'angular2/src/change_detection/differs/default_iterable_differ';
|
||||
|
||||
import {NumberWrapper} from 'angular2/src/facade/lang';
|
||||
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
||||
@@ -9,36 +12,35 @@ import {iterableChangesAsString} from '../util';
|
||||
|
||||
// todo(vicb): UnmodifiableListView / frozen object when implemented
|
||||
export function main() {
|
||||
describe('collection_changes', function() {
|
||||
describe('CollectionChanges', function() {
|
||||
var changes;
|
||||
describe('iterable differ', function() {
|
||||
describe('DefaultIterableDiffer', function() {
|
||||
var differ;
|
||||
|
||||
beforeEach(() => { changes = new IterableChanges(); });
|
||||
|
||||
afterEach(() => { changes = null; });
|
||||
beforeEach(() => { differ = new DefaultIterableDiffer(); });
|
||||
|
||||
it('should support list and iterables', () => {
|
||||
expect(IterableChanges.supportsObj([])).toBeTruthy();
|
||||
expect(IterableChanges.supportsObj(new TestIterable())).toBeTruthy();
|
||||
expect(IterableChanges.supportsObj(new Map())).toBeFalsy();
|
||||
expect(IterableChanges.supportsObj(null)).toBeFalsy();
|
||||
var f = new DefaultIterableDifferFactory();
|
||||
expect(f.supports([])).toBeTruthy();
|
||||
expect(f.supports(new TestIterable())).toBeTruthy();
|
||||
expect(f.supports(new Map())).toBeFalsy();
|
||||
expect(f.supports(null)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should support iterables', () => {
|
||||
let l = new TestIterable();
|
||||
|
||||
changes.check(l);
|
||||
expect(changes.toString()).toEqual(iterableChangesAsString({collection: []}));
|
||||
differ.check(l);
|
||||
expect(differ.toString()).toEqual(iterableChangesAsString({collection: []}));
|
||||
|
||||
l.list = [1];
|
||||
changes.check(l);
|
||||
expect(changes.toString())
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(
|
||||
iterableChangesAsString({collection: ['1[null->0]'], additions: ['1[null->0]']}));
|
||||
|
||||
l.list = [2, 1];
|
||||
changes.check(l);
|
||||
expect(changes.toString())
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString({
|
||||
collection: ['2[null->0]', '1[0->1]'],
|
||||
previous: ['1[0->1]'],
|
||||
@@ -49,29 +51,29 @@ export function main() {
|
||||
|
||||
it('should detect additions', () => {
|
||||
let l = [];
|
||||
changes.check(l);
|
||||
expect(changes.toString()).toEqual(iterableChangesAsString({collection: []}));
|
||||
differ.check(l);
|
||||
expect(differ.toString()).toEqual(iterableChangesAsString({collection: []}));
|
||||
|
||||
l.push('a');
|
||||
changes.check(l);
|
||||
expect(changes.toString())
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(
|
||||
iterableChangesAsString({collection: ['a[null->0]'], additions: ['a[null->0]']}));
|
||||
|
||||
l.push('b');
|
||||
changes.check(l);
|
||||
expect(changes.toString())
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString(
|
||||
{collection: ['a', 'b[null->1]'], previous: ['a'], additions: ['b[null->1]']}));
|
||||
});
|
||||
|
||||
it('should support changing the reference', () => {
|
||||
let l = [0];
|
||||
changes.check(l);
|
||||
differ.check(l);
|
||||
|
||||
l = [1, 0];
|
||||
changes.check(l);
|
||||
expect(changes.toString())
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString({
|
||||
collection: ['1[null->0]', '0[0->1]'],
|
||||
previous: ['0[0->1]'],
|
||||
@@ -80,8 +82,8 @@ export function main() {
|
||||
}));
|
||||
|
||||
l = [2, 1, 0];
|
||||
changes.check(l);
|
||||
expect(changes.toString())
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString({
|
||||
collection: ['2[null->0]', '1[0->1]', '0[1->2]'],
|
||||
previous: ['1[0->1]', '0[1->2]'],
|
||||
@@ -92,13 +94,13 @@ export function main() {
|
||||
|
||||
it('should handle swapping element', () => {
|
||||
let l = [1, 2];
|
||||
changes.check(l);
|
||||
differ.check(l);
|
||||
|
||||
ListWrapper.clear(l);
|
||||
l.push(2);
|
||||
l.push(1);
|
||||
changes.check(l);
|
||||
expect(changes.toString())
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString({
|
||||
collection: ['2[1->0]', '1[0->1]'],
|
||||
previous: ['1[0->1]', '2[1->0]'],
|
||||
@@ -108,12 +110,12 @@ export function main() {
|
||||
|
||||
it('should handle swapping element', () => {
|
||||
let l = ['a', 'b', 'c'];
|
||||
changes.check(l);
|
||||
differ.check(l);
|
||||
|
||||
ListWrapper.removeAt(l, 1);
|
||||
ListWrapper.insert(l, 0, 'b');
|
||||
changes.check(l);
|
||||
expect(changes.toString())
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString({
|
||||
collection: ['b[1->0]', 'a[0->1]', 'c'],
|
||||
previous: ['a[0->1]', 'b[1->0]', 'c'],
|
||||
@@ -122,8 +124,8 @@ export function main() {
|
||||
|
||||
ListWrapper.removeAt(l, 1);
|
||||
l.push('a');
|
||||
changes.check(l);
|
||||
expect(changes.toString())
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString({
|
||||
collection: ['b', 'c[2->1]', 'a[1->2]'],
|
||||
previous: ['b', 'a[1->2]', 'c[2->1]'],
|
||||
@@ -133,24 +135,24 @@ export function main() {
|
||||
|
||||
it('should detect changes in list', () => {
|
||||
let l = [];
|
||||
changes.check(l);
|
||||
differ.check(l);
|
||||
|
||||
l.push('a');
|
||||
changes.check(l);
|
||||
expect(changes.toString())
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(
|
||||
iterableChangesAsString({collection: ['a[null->0]'], additions: ['a[null->0]']}));
|
||||
|
||||
l.push('b');
|
||||
changes.check(l);
|
||||
expect(changes.toString())
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString(
|
||||
{collection: ['a', 'b[null->1]'], previous: ['a'], additions: ['b[null->1]']}));
|
||||
|
||||
l.push('c');
|
||||
l.push('d');
|
||||
changes.check(l);
|
||||
expect(changes.toString())
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString({
|
||||
collection: ['a', 'b', 'c[null->2]', 'd[null->3]'],
|
||||
previous: ['a', 'b'],
|
||||
@@ -158,8 +160,8 @@ export function main() {
|
||||
}));
|
||||
|
||||
ListWrapper.removeAt(l, 2);
|
||||
changes.check(l);
|
||||
expect(changes.toString())
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString({
|
||||
collection: ['a', 'b', 'd[3->2]'],
|
||||
previous: ['a', 'b', 'c[2->null]', 'd[3->2]'],
|
||||
@@ -172,8 +174,8 @@ export function main() {
|
||||
l.push('c');
|
||||
l.push('b');
|
||||
l.push('a');
|
||||
changes.check(l);
|
||||
expect(changes.toString())
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString({
|
||||
collection: ['d[2->0]', 'c[null->1]', 'b[1->2]', 'a[0->3]'],
|
||||
previous: ['a[0->3]', 'b[1->2]', 'd[2->0]'],
|
||||
@@ -184,32 +186,32 @@ export function main() {
|
||||
|
||||
it('should test string by value rather than by reference (Dart)', () => {
|
||||
let l = ['a', 'boo'];
|
||||
changes.check(l);
|
||||
differ.check(l);
|
||||
|
||||
var b = 'b';
|
||||
var oo = 'oo';
|
||||
ListWrapper.set(l, 1, b + oo);
|
||||
changes.check(l);
|
||||
expect(changes.toString())
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString({collection: ['a', 'boo'], previous: ['a', 'boo']}));
|
||||
});
|
||||
|
||||
it('should ignore [NaN] != [NaN] (JS)', () => {
|
||||
let l = [NumberWrapper.NaN];
|
||||
changes.check(l);
|
||||
changes.check(l);
|
||||
expect(changes.toString())
|
||||
differ.check(l);
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString(
|
||||
{collection: [NumberWrapper.NaN], previous: [NumberWrapper.NaN]}));
|
||||
});
|
||||
|
||||
it('should detect [NaN] moves', () => {
|
||||
let l = [NumberWrapper.NaN, NumberWrapper.NaN];
|
||||
changes.check(l);
|
||||
differ.check(l);
|
||||
|
||||
ListWrapper.insert<any>(l, 0, 'foo');
|
||||
changes.check(l);
|
||||
expect(changes.toString())
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString({
|
||||
collection: ['foo[null->0]', 'NaN[0->1]', 'NaN[1->2]'],
|
||||
previous: ['NaN[0->1]', 'NaN[1->2]'],
|
||||
@@ -220,11 +222,11 @@ export function main() {
|
||||
|
||||
it('should remove and add same item', () => {
|
||||
let l = ['a', 'b', 'c'];
|
||||
changes.check(l);
|
||||
differ.check(l);
|
||||
|
||||
ListWrapper.removeAt(l, 1);
|
||||
changes.check(l);
|
||||
expect(changes.toString())
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString({
|
||||
collection: ['a', 'c[2->1]'],
|
||||
previous: ['a', 'b[1->null]', 'c[2->1]'],
|
||||
@@ -233,8 +235,8 @@ export function main() {
|
||||
}));
|
||||
|
||||
ListWrapper.insert(l, 1, 'b');
|
||||
changes.check(l);
|
||||
expect(changes.toString())
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString({
|
||||
collection: ['a', 'b[null->1]', 'c[1->2]'],
|
||||
previous: ['a', 'c[1->2]'],
|
||||
@@ -245,11 +247,11 @@ export function main() {
|
||||
|
||||
it('should support duplicates', () => {
|
||||
let l = ['a', 'a', 'a', 'b', 'b'];
|
||||
changes.check(l);
|
||||
differ.check(l);
|
||||
|
||||
ListWrapper.removeAt(l, 0);
|
||||
changes.check(l);
|
||||
expect(changes.toString())
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString({
|
||||
collection: ['a', 'a', 'b[3->2]', 'b[4->3]'],
|
||||
previous: ['a', 'a', 'a[2->null]', 'b[3->2]', 'b[4->3]'],
|
||||
@@ -260,11 +262,11 @@ export function main() {
|
||||
|
||||
it('should support insertions/moves', () => {
|
||||
let l = ['a', 'a', 'b', 'b'];
|
||||
changes.check(l);
|
||||
differ.check(l);
|
||||
|
||||
ListWrapper.insert(l, 0, 'b');
|
||||
changes.check(l);
|
||||
expect(changes.toString())
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString({
|
||||
collection: ['b[2->0]', 'a[0->1]', 'a[1->2]', 'b', 'b[null->4]'],
|
||||
previous: ['a[0->1]', 'a[1->2]', 'b[2->0]', 'b'],
|
||||
@@ -275,20 +277,43 @@ export function main() {
|
||||
|
||||
it('should not report unnecessary moves', () => {
|
||||
let l = ['a', 'b', 'c'];
|
||||
changes.check(l);
|
||||
differ.check(l);
|
||||
|
||||
ListWrapper.clear(l);
|
||||
l.push('b');
|
||||
l.push('a');
|
||||
l.push('c');
|
||||
changes.check(l);
|
||||
expect(changes.toString())
|
||||
differ.check(l);
|
||||
expect(differ.toString())
|
||||
.toEqual(iterableChangesAsString({
|
||||
collection: ['b[1->0]', 'a[0->1]', 'c'],
|
||||
previous: ['a[0->1]', 'b[1->0]', 'c'],
|
||||
moves: ['b[1->0]', 'a[0->1]']
|
||||
}));
|
||||
});
|
||||
|
||||
describe('diff', () => {
|
||||
it('should return self when there is a change',
|
||||
() => { expect(differ.diff(['a', 'b'])).toBe(differ); });
|
||||
|
||||
it('should return null when there is no change', () => {
|
||||
differ.diff(['a', 'b']);
|
||||
expect(differ.diff(['a', 'b'])).toEqual(null);
|
||||
});
|
||||
|
||||
it('should treat null as an empty list', () => {
|
||||
differ.diff(['a', 'b']);
|
||||
expect(differ.diff(null).toString())
|
||||
.toEqual(iterableChangesAsString({
|
||||
previous: ['a[0->null]', 'b[1->null]'],
|
||||
removals: ['a[0->null]', 'b[1->null]']
|
||||
}));
|
||||
});
|
||||
|
||||
it('should throw when given an invalid collection', () => {
|
||||
expect(() => differ.diff("invalid")).toThrowErrorWith("Error trying to diff 'invalid'");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
+78
-50
@@ -1,34 +1,37 @@
|
||||
import {describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/test_lib';
|
||||
import {KeyValueChanges} from 'angular2/src/change_detection/pipes/keyvalue_changes';
|
||||
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/test_lib';
|
||||
import {
|
||||
DefaultKeyValueDiffer,
|
||||
DefaultKeyValueDifferFactory
|
||||
} from 'angular2/src/change_detection/differs/default_keyvalue_differ';
|
||||
import {NumberWrapper, isJsObject} from 'angular2/src/facade/lang';
|
||||
import {MapWrapper} from 'angular2/src/facade/collection';
|
||||
import {kvChangesAsString} from '../util';
|
||||
|
||||
// todo(vicb): Update the code & tests for object equality
|
||||
export function main() {
|
||||
describe('keyvalue_changes', function() {
|
||||
describe('KeyValueChanges', function() {
|
||||
var changes;
|
||||
describe('keyvalue differ', function() {
|
||||
describe('DefaultKeyValueDiffer', function() {
|
||||
var differ;
|
||||
var m: Map<any, any>;
|
||||
|
||||
beforeEach(() => {
|
||||
changes = new KeyValueChanges();
|
||||
differ = new DefaultKeyValueDiffer();
|
||||
m = new Map();
|
||||
});
|
||||
|
||||
afterEach(() => { changes = null; });
|
||||
afterEach(() => { differ = null; });
|
||||
|
||||
it('should detect additions', () => {
|
||||
changes.check(m);
|
||||
differ.check(m);
|
||||
|
||||
m.set('a', 1);
|
||||
changes.check(m);
|
||||
expect(changes.toString())
|
||||
differ.check(m);
|
||||
expect(differ.toString())
|
||||
.toEqual(kvChangesAsString({map: ['a[null->1]'], additions: ['a[null->1]']}));
|
||||
|
||||
m.set('b', 2);
|
||||
changes.check(m);
|
||||
expect(changes.toString())
|
||||
differ.check(m);
|
||||
expect(differ.toString())
|
||||
.toEqual(kvChangesAsString(
|
||||
{map: ['a', 'b[null->2]'], previous: ['a'], additions: ['b[null->2]']}));
|
||||
});
|
||||
@@ -36,12 +39,12 @@ export function main() {
|
||||
it('should handle changing key/values correctly', () => {
|
||||
m.set(1, 10);
|
||||
m.set(2, 20);
|
||||
changes.check(m);
|
||||
differ.check(m);
|
||||
|
||||
m.set(2, 10);
|
||||
m.set(1, 20);
|
||||
changes.check(m);
|
||||
expect(changes.toString())
|
||||
differ.check(m);
|
||||
expect(differ.toString())
|
||||
.toEqual(kvChangesAsString({
|
||||
map: ['1[10->20]', '2[20->10]'],
|
||||
previous: ['1[10->20]', '2[20->10]'],
|
||||
@@ -53,12 +56,12 @@ export function main() {
|
||||
var previous, current;
|
||||
|
||||
m.set(1, 10);
|
||||
changes.check(m);
|
||||
differ.check(m);
|
||||
|
||||
m.set(1, 20);
|
||||
changes.check(m);
|
||||
differ.check(m);
|
||||
|
||||
changes.forEachChangedItem((record) => {
|
||||
differ.forEachChangedItem((record) => {
|
||||
previous = record.previousValue;
|
||||
current = record.currentValue;
|
||||
});
|
||||
@@ -68,23 +71,23 @@ export function main() {
|
||||
});
|
||||
|
||||
it('should do basic map watching', () => {
|
||||
changes.check(m);
|
||||
differ.check(m);
|
||||
|
||||
m.set('a', 'A');
|
||||
changes.check(m);
|
||||
expect(changes.toString())
|
||||
differ.check(m);
|
||||
expect(differ.toString())
|
||||
.toEqual(kvChangesAsString({map: ['a[null->A]'], additions: ['a[null->A]']}));
|
||||
|
||||
m.set('b', 'B');
|
||||
changes.check(m);
|
||||
expect(changes.toString())
|
||||
differ.check(m);
|
||||
expect(differ.toString())
|
||||
.toEqual(kvChangesAsString(
|
||||
{map: ['a', 'b[null->B]'], previous: ['a'], additions: ['b[null->B]']}));
|
||||
|
||||
m.set('b', 'BB');
|
||||
m.set('d', 'D');
|
||||
changes.check(m);
|
||||
expect(changes.toString())
|
||||
differ.check(m);
|
||||
expect(differ.toString())
|
||||
.toEqual(kvChangesAsString({
|
||||
map: ['a', 'b[B->BB]', 'd[null->D]'],
|
||||
previous: ['a', 'b[B->BB]'],
|
||||
@@ -93,21 +96,21 @@ export function main() {
|
||||
}));
|
||||
|
||||
MapWrapper.delete(m, 'b');
|
||||
changes.check(m);
|
||||
expect(changes.toString())
|
||||
differ.check(m);
|
||||
expect(differ.toString())
|
||||
.toEqual(kvChangesAsString(
|
||||
{map: ['a', 'd'], previous: ['a', 'b[BB->null]', 'd'], removals: ['b[BB->null]']}));
|
||||
|
||||
m.clear();
|
||||
changes.check(m);
|
||||
expect(changes.toString())
|
||||
differ.check(m);
|
||||
expect(differ.toString())
|
||||
.toEqual(kvChangesAsString(
|
||||
{previous: ['a[A->null]', 'd[D->null]'], removals: ['a[A->null]', 'd[D->null]']}));
|
||||
});
|
||||
|
||||
it('should test string by value rather than by reference (DART)', () => {
|
||||
m.set('foo', 'bar');
|
||||
changes.check(m);
|
||||
differ.check(m);
|
||||
|
||||
var f = 'f';
|
||||
var oo = 'oo';
|
||||
@@ -115,48 +118,49 @@ export function main() {
|
||||
var ar = 'ar';
|
||||
|
||||
m.set(f + oo, b + ar);
|
||||
changes.check(m);
|
||||
differ.check(m);
|
||||
|
||||
expect(changes.toString()).toEqual(kvChangesAsString({map: ['foo'], previous: ['foo']}));
|
||||
expect(differ.toString()).toEqual(kvChangesAsString({map: ['foo'], previous: ['foo']}));
|
||||
});
|
||||
|
||||
it('should not see a NaN value as a change (JS)', () => {
|
||||
m.set('foo', NumberWrapper.NaN);
|
||||
changes.check(m);
|
||||
differ.check(m);
|
||||
|
||||
changes.check(m);
|
||||
expect(changes.toString()).toEqual(kvChangesAsString({map: ['foo'], previous: ['foo']}));
|
||||
differ.check(m);
|
||||
expect(differ.toString()).toEqual(kvChangesAsString({map: ['foo'], previous: ['foo']}));
|
||||
});
|
||||
|
||||
// JS specific tests (JS Objects)
|
||||
if (isJsObject({})) {
|
||||
describe('JsObject changes', () => {
|
||||
it('should support JS Object', () => {
|
||||
expect(KeyValueChanges.supportsObj({})).toBeTruthy();
|
||||
expect(KeyValueChanges.supportsObj("not supported")).toBeFalsy();
|
||||
expect(KeyValueChanges.supportsObj(0)).toBeFalsy();
|
||||
expect(KeyValueChanges.supportsObj(null)).toBeFalsy();
|
||||
var f = new DefaultKeyValueDifferFactory();
|
||||
expect(f.supports({})).toBeTruthy();
|
||||
expect(f.supports("not supported")).toBeFalsy();
|
||||
expect(f.supports(0)).toBeFalsy();
|
||||
expect(f.supports(null)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should do basic object watching', () => {
|
||||
let m = {};
|
||||
changes.check(m);
|
||||
differ.check(m);
|
||||
|
||||
m['a'] = 'A';
|
||||
changes.check(m);
|
||||
expect(changes.toString())
|
||||
differ.check(m);
|
||||
expect(differ.toString())
|
||||
.toEqual(kvChangesAsString({map: ['a[null->A]'], additions: ['a[null->A]']}));
|
||||
|
||||
m['b'] = 'B';
|
||||
changes.check(m);
|
||||
expect(changes.toString())
|
||||
differ.check(m);
|
||||
expect(differ.toString())
|
||||
.toEqual(kvChangesAsString(
|
||||
{map: ['a', 'b[null->B]'], previous: ['a'], additions: ['b[null->B]']}));
|
||||
|
||||
m['b'] = 'BB';
|
||||
m['d'] = 'D';
|
||||
changes.check(m);
|
||||
expect(changes.toString())
|
||||
differ.check(m);
|
||||
expect(differ.toString())
|
||||
.toEqual(kvChangesAsString({
|
||||
map: ['a', 'b[B->BB]', 'd[null->D]'],
|
||||
previous: ['a', 'b[B->BB]'],
|
||||
@@ -167,8 +171,8 @@ export function main() {
|
||||
m = {};
|
||||
m['a'] = 'A';
|
||||
m['d'] = 'D';
|
||||
changes.check(m);
|
||||
expect(changes.toString())
|
||||
differ.check(m);
|
||||
expect(differ.toString())
|
||||
.toEqual(kvChangesAsString({
|
||||
map: ['a', 'd'],
|
||||
previous: ['a', 'b[BB->null]', 'd'],
|
||||
@@ -176,14 +180,38 @@ export function main() {
|
||||
}));
|
||||
|
||||
m = {};
|
||||
changes.check(m);
|
||||
expect(changes.toString())
|
||||
differ.check(m);
|
||||
expect(differ.toString())
|
||||
.toEqual(kvChangesAsString({
|
||||
previous: ['a[A->null]', 'd[D->null]'],
|
||||
removals: ['a[A->null]', 'd[D->null]']
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
describe('diff', () => {
|
||||
it('should return self when there is a change', () => {
|
||||
m.set('a', 'A');
|
||||
expect(differ.diff(m)).toBe(differ);
|
||||
});
|
||||
|
||||
it('should return null when there is no change', () => {
|
||||
m.set('a', 'A');
|
||||
differ.diff(m);
|
||||
expect(differ.diff(m)).toEqual(null);
|
||||
});
|
||||
|
||||
it('should treat null as an empty list', () => {
|
||||
m.set('a', 'A');
|
||||
differ.diff(m);
|
||||
expect(differ.diff(null).toString())
|
||||
.toEqual(kvChangesAsString({previous: ['a[A->null]'], removals: ['a[A->null]']}));
|
||||
});
|
||||
|
||||
it('should throw when given an invalid collection', () => {
|
||||
expect(() => differ.diff("invalid")).toThrowErrorWith("Error trying to diff 'invalid'");
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,70 @@
|
||||
import {
|
||||
ddescribe,
|
||||
describe,
|
||||
it,
|
||||
iit,
|
||||
xit,
|
||||
expect,
|
||||
beforeEach,
|
||||
afterEach,
|
||||
SpyIterableDifferFactory
|
||||
} from 'angular2/test_lib';
|
||||
import {IterableDiffers} from 'angular2/src/change_detection/differs/iterable_differs';
|
||||
import {Injector, bind} from 'angular2/di';
|
||||
|
||||
export function main() {
|
||||
describe('IterableDiffers', function() {
|
||||
var factory1;
|
||||
var factory2;
|
||||
var factory3;
|
||||
|
||||
beforeEach(() => {
|
||||
factory1 = new SpyIterableDifferFactory();
|
||||
factory2 = new SpyIterableDifferFactory();
|
||||
factory3 = new SpyIterableDifferFactory();
|
||||
});
|
||||
|
||||
it('should throw when no suitable implementation found', () => {
|
||||
var differs = new IterableDiffers([]);
|
||||
expect(() => differs.find("some object"))
|
||||
.toThrowErrorWith("Cannot find a differ supporting object 'some object'")
|
||||
});
|
||||
|
||||
it('should return the first suitable implementation', () => {
|
||||
factory1.spy("supports").andReturn(false);
|
||||
factory2.spy("supports").andReturn(true);
|
||||
factory3.spy("supports").andReturn(true);
|
||||
|
||||
var differs = IterableDiffers.create(<any>[factory1, factory2, factory3]);
|
||||
expect(differs.find("some object")).toBe(factory2);
|
||||
});
|
||||
|
||||
it('should copy over differs from the parent repo', () => {
|
||||
factory1.spy("supports").andReturn(true);
|
||||
factory2.spy("supports").andReturn(false);
|
||||
|
||||
var parent = IterableDiffers.create(<any>[factory1]);
|
||||
var child = IterableDiffers.create(<any>[factory2], parent);
|
||||
|
||||
expect(child.factories).toEqual([factory2, factory1]);
|
||||
});
|
||||
|
||||
describe(".extend()", () => {
|
||||
it('should throw if calling extend when creating root injector', () => {
|
||||
var injector = Injector.resolveAndCreate([IterableDiffers.extend([])]);
|
||||
|
||||
expect(() => injector.get(IterableDiffers))
|
||||
.toThrowErrorWith("Cannot extend IterableDiffers without a parent injector");
|
||||
});
|
||||
|
||||
it('should extend di-inherited diffesr', () => {
|
||||
var parent = new IterableDiffers([factory1]);
|
||||
var injector = Injector.resolveAndCreate([bind(IterableDiffers).toValue(parent)]);
|
||||
var childInjector = injector.resolveAndCreateChild([IterableDiffers.extend([factory2])]);
|
||||
|
||||
expect(injector.get(IterableDiffers).factories).toEqual([factory1]);
|
||||
expect(childInjector.get(IterableDiffers).factories).toEqual([factory2, factory1]);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import 'package:angular2/di.dart';
|
||||
import 'package:angular2/test_lib.dart';
|
||||
import 'package:observe/observe.dart';
|
||||
import 'package:angular2/src/directives/observable_list_diff.dart';
|
||||
import 'package:angular2/src/change_detection/pipes/iterable_changes.dart';
|
||||
import 'package:angular2/src/change_detection/differs/default_iterable_differ.dart';
|
||||
|
||||
class MockException implements Error {
|
||||
var message;
|
||||
@@ -269,14 +269,12 @@ class OnChangeComponent implements OnChange {
|
||||
changeDetection: ON_PUSH,
|
||||
properties: const ['list'],
|
||||
bindings: const [
|
||||
const Binding(Pipes,
|
||||
toValue: const Pipes(const {
|
||||
"iterableDiff": const [
|
||||
const Binding(IterableDiffers,
|
||||
toValue: const IterableDiffers(const [
|
||||
const ObservableListDiffFactory(),
|
||||
const IterableChangesFactory(),
|
||||
const NullPipeFactory()
|
||||
const DefaultIterableDifferFactory()
|
||||
]
|
||||
}))
|
||||
))
|
||||
])
|
||||
@View(
|
||||
template: '<span *ng-for="#item of list">{{item}}</span><directive-logging-checks></directive-logging-checks>',
|
||||
|
||||
@@ -6,64 +6,64 @@ import 'package:angular2/src/directives/observable_list_diff.dart';
|
||||
|
||||
main() {
|
||||
describe('ObservableListDiff', () {
|
||||
var pipeFactory, changeDetectorRef;
|
||||
var factory, changeDetectorRef;
|
||||
|
||||
beforeEach(() {
|
||||
pipeFactory = const ObservableListDiffFactory();
|
||||
factory = const ObservableListDiffFactory();
|
||||
changeDetectorRef = new SpyChangeDetectorRef();
|
||||
});
|
||||
|
||||
describe("supports", () {
|
||||
it("should be true for ObservableList", () {
|
||||
expect(pipeFactory.supports(new ObservableList())).toBe(true);
|
||||
expect(factory.supports(new ObservableList())).toBe(true);
|
||||
});
|
||||
|
||||
it("should be false otherwise", () {
|
||||
expect(pipeFactory.supports([1, 2, 3])).toBe(false);
|
||||
expect(factory.supports([1, 2, 3])).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
it("should return the wrapped value to trigger change detection on first invocation of transform",
|
||||
it("should return itself when called the first time",
|
||||
() {
|
||||
final pipe = pipeFactory.create(changeDetectorRef);
|
||||
final d = factory.create(changeDetectorRef);
|
||||
final c = new ObservableList.from([1, 2]);
|
||||
expect(pipe.transform(c, []).wrapped).toBe(pipe);
|
||||
expect(d.diff(c)).toBe(d);
|
||||
});
|
||||
|
||||
it("should return itself when no changes between the calls", () {
|
||||
final pipe = pipeFactory.create(changeDetectorRef);
|
||||
final d = factory.create(changeDetectorRef);
|
||||
|
||||
final c = new ObservableList.from([1, 2]);
|
||||
|
||||
pipe.transform(c, []);
|
||||
d.diff(c);
|
||||
|
||||
expect(pipe.transform(c, [])).toBe(pipe);
|
||||
expect(d.diff(c)).toBe(d);
|
||||
});
|
||||
|
||||
it("should return the wrapped value once a change has been trigger",
|
||||
it("should return the wrapped value once a change has been triggered",
|
||||
fakeAsync(() {
|
||||
final pipe = pipeFactory.create(changeDetectorRef);
|
||||
final d = factory.create(changeDetectorRef);
|
||||
|
||||
final c = new ObservableList.from([1, 2]);
|
||||
|
||||
pipe.transform(c, []);
|
||||
d.diff(c);
|
||||
|
||||
c.add(3);
|
||||
|
||||
// same value, because we have not detected the change yet
|
||||
expect(pipe.transform(c, [])).toBe(pipe);
|
||||
expect(d.diff(c)).toBe(d);
|
||||
|
||||
// now we detect the change
|
||||
flushMicrotasks();
|
||||
expect(pipe.transform(c, []).wrapped).toBe(pipe);
|
||||
expect(d.diff(c)).toBe(d);
|
||||
}));
|
||||
|
||||
it("should request a change detection check upon receiving a change",
|
||||
fakeAsync(() {
|
||||
final pipe = pipeFactory.create(changeDetectorRef);
|
||||
final d = factory.create(changeDetectorRef);
|
||||
|
||||
final c = new ObservableList.from([1, 2]);
|
||||
pipe.transform(c, []);
|
||||
d.diff(c);
|
||||
|
||||
c.add(3);
|
||||
flushMicrotasks();
|
||||
@@ -72,28 +72,28 @@ main() {
|
||||
}));
|
||||
|
||||
it("should return the wrapped value after changing a collection", () {
|
||||
final pipe = pipeFactory.create(changeDetectorRef);
|
||||
final d = factory.create(changeDetectorRef);
|
||||
|
||||
final c1 = new ObservableList.from([1, 2]);
|
||||
final c2 = new ObservableList.from([3, 4]);
|
||||
|
||||
expect(pipe.transform(c1, []).wrapped).toBe(pipe);
|
||||
expect(pipe.transform(c2, []).wrapped).toBe(pipe);
|
||||
expect(d.diff(c1)).toBe(d);
|
||||
expect(d.diff(c2)).toBe(d);
|
||||
});
|
||||
|
||||
it("should not unbsubscribe from the stream of chagnes after changing a collection",
|
||||
() {
|
||||
final pipe = pipeFactory.create(changeDetectorRef);
|
||||
final d = factory.create(changeDetectorRef);
|
||||
|
||||
final c1 = new ObservableList.from([1, 2]);
|
||||
expect(pipe.transform(c1, []).wrapped).toBe(pipe);
|
||||
expect(d.diff(c1)).toBe(d);
|
||||
|
||||
final c2 = new ObservableList.from([3, 4]);
|
||||
expect(pipe.transform(c2, []).wrapped).toBe(pipe);
|
||||
expect(d.diff(c2)).toBe(d);
|
||||
|
||||
// pushing into the first collection has no effect, and we do not see the change
|
||||
c1.add(3);
|
||||
expect(pipe.transform(c2, [])).toBe(pipe);
|
||||
expect(d.diff(c2)).toBe(d);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user