@@ -8,6 +8,7 @@ import 'dart:async';
88import 'package:angular2/src/reflection/reflection.dart' ;
99import 'package:angular2/src/facade/dom.dart' ;
1010import 'package:angular2/src/reflection/reflection_capabilities.dart' ;
11+ import 'package:collection/equality.dart' ;
1112
1213bool IS_DARTIUM = true ;
1314
@@ -22,7 +23,9 @@ class Expect extends gns.Expect {
2223
2324 NotExpect get not => new NotExpect (actual);
2425
25- void toEqual (expected) => toHaveSameProps (expected);
26+ // TODO(tbosch) change back when https://github.com/vsavkin/guinness/issues/41 is fixed
27+ // void toEqual(expected) => toHaveSameProps(expected);
28+ void toEqual (expected) => _expect (actual, new FixedSamePropsMatcher (expected));
2629 void toThrowError ([message= "" ]) => this .toThrowWith (message: message);
2730 void toBePromise () => _expect (actual is Future , equals (true ));
2831 void toImplement (expected) => toBeA (expected);
@@ -33,7 +36,10 @@ class Expect extends gns.Expect {
3336class NotExpect extends gns.NotExpect {
3437 NotExpect (actual) : super (actual);
3538
36- void toEqual (expected) => toHaveSameProps (expected);
39+ // TODO(tbosch) change back when https://github.com/vsavkin/guinness/issues/41 is fixed
40+ // void toEqual(expected) => toHaveSameProps(expected);
41+ void toEqual (expected) => _expect (actual, isNot (new FixedSamePropsMatcher (expected)));
42+ Function get _expect => gns.guinness.matchers.expect;
3743}
3844
3945beforeEach (fn) {
@@ -70,4 +76,64 @@ _handleAsync(fn) {
7076 }
7177
7278 return fn;
79+ }
80+
81+ // TODO(tbosch): remove when https://github.com/vsavkin/guinness/issues/41
82+ // is fixed
83+ class FixedSamePropsMatcher extends Matcher {
84+ final Object _expected;
85+
86+ const FixedSamePropsMatcher (this ._expected);
87+
88+ bool matches (actual, Map matchState) {
89+ return compare (toData (_expected), toData (actual));
90+ }
91+
92+ Description describeMismatch (item, Description mismatchDescription,
93+ Map matchState, bool verbose) =>
94+ mismatchDescription.add ('is equal to ${toData (item )}. Expected: ${toData (_expected )}' );
95+
96+ Description describe (Description description) =>
97+ description.add ('has different properties' );
98+
99+ toData (obj) => new _FixedObjToData ().call (obj);
100+ compare (d1, d2) => new DeepCollectionEquality ().equals (d1, d2);
101+ }
102+
103+ // TODO(tbosch): remove when https://github.com/vsavkin/guinness/issues/41
104+ // is fixed
105+ class _FixedObjToData {
106+ final visitedObjects = new Set ();
107+
108+ call (obj) {
109+ if (visitedObjects.contains (obj)) return null ;
110+ visitedObjects.add (obj);
111+
112+ if (obj is num || obj is String || obj is bool ) return obj;
113+ if (obj is Iterable ) return obj.map (call).toList ();
114+ if (obj is Map ) return mapToData (obj);
115+ return toDataUsingReflection (obj);
116+ }
117+
118+ mapToData (obj) {
119+ var res = {};
120+ obj.forEach ((k,v) {
121+ res[call (k)] = call (v);
122+ });
123+ return res;
124+ }
125+
126+ toDataUsingReflection (obj) {
127+ final clazz = reflectClass (obj.runtimeType);
128+ final instance = reflect (obj);
129+
130+ return clazz.declarations.values.fold ({}, (map, decl) {
131+ if (decl is VariableMirror && ! decl.isPrivate && ! decl.isStatic) {
132+ final field = instance.getField (decl.simpleName);
133+ final name = MirrorSystem .getName (decl.simpleName);
134+ map[name] = call (field.reflectee);
135+ }
136+ return map;
137+ });
138+ }
73139}
0 commit comments