fix(test_lib): support deep compare of objects with private/static fields
This commit is contained in:
		
							parent
							
								
									674848648a
								
							
						
					
					
						commit
						e163eb2a51
					
				| @ -8,6 +8,7 @@ import 'dart:async'; | ||||
| import 'package:angular2/src/reflection/reflection.dart'; | ||||
| import 'package:angular2/src/facade/dom.dart'; | ||||
| import 'package:angular2/src/reflection/reflection_capabilities.dart'; | ||||
| import 'package:collection/equality.dart'; | ||||
| 
 | ||||
| bool IS_DARTIUM = true; | ||||
| 
 | ||||
| @ -22,7 +23,9 @@ class Expect extends gns.Expect { | ||||
| 
 | ||||
|   NotExpect get not => new NotExpect(actual); | ||||
| 
 | ||||
|   void toEqual(expected) => toHaveSameProps(expected); | ||||
|   // TODO(tbosch) change back when https://github.com/vsavkin/guinness/issues/41 is fixed | ||||
|   // void toEqual(expected) => toHaveSameProps(expected); | ||||
|   void toEqual(expected) => _expect(actual, new FixedSamePropsMatcher(expected)); | ||||
|   void toThrowError([message=""]) => this.toThrowWith(message: message); | ||||
|   void toBePromise() => _expect(actual is Future, equals(true)); | ||||
|   void toImplement(expected) => toBeA(expected); | ||||
| @ -33,7 +36,10 @@ class Expect extends gns.Expect { | ||||
| class NotExpect extends gns.NotExpect { | ||||
|   NotExpect(actual) : super(actual); | ||||
| 
 | ||||
|   void toEqual(expected) => toHaveSameProps(expected); | ||||
|   // TODO(tbosch) change back when https://github.com/vsavkin/guinness/issues/41 is fixed | ||||
|   // void toEqual(expected) => toHaveSameProps(expected); | ||||
|   void toEqual(expected) => _expect(actual, isNot(new FixedSamePropsMatcher(expected))); | ||||
|   Function get _expect => gns.guinness.matchers.expect; | ||||
| } | ||||
| 
 | ||||
| beforeEach(fn) { | ||||
| @ -71,3 +77,63 @@ _handleAsync(fn) { | ||||
| 
 | ||||
|   return fn; | ||||
| } | ||||
| 
 | ||||
| // TODO(tbosch): remove when https://github.com/vsavkin/guinness/issues/41 | ||||
| // is fixed | ||||
| class FixedSamePropsMatcher extends Matcher { | ||||
|   final Object _expected; | ||||
| 
 | ||||
|   const FixedSamePropsMatcher(this._expected); | ||||
| 
 | ||||
|   bool matches(actual, Map matchState) { | ||||
|     return compare(toData(_expected), toData(actual)); | ||||
|   } | ||||
| 
 | ||||
|   Description describeMismatch(item, Description mismatchDescription, | ||||
|       Map matchState, bool verbose) => | ||||
|       mismatchDescription.add('is equal to ${toData(item)}. Expected: ${toData(_expected)}'); | ||||
| 
 | ||||
|   Description describe(Description description) => | ||||
|       description.add('has different properties'); | ||||
| 
 | ||||
|   toData(obj) => new _FixedObjToData().call(obj); | ||||
|   compare(d1, d2) => new DeepCollectionEquality().equals(d1, d2); | ||||
| } | ||||
| 
 | ||||
| // TODO(tbosch): remove when https://github.com/vsavkin/guinness/issues/41 | ||||
| // is fixed | ||||
| class _FixedObjToData { | ||||
|   final visitedObjects = new Set(); | ||||
| 
 | ||||
|   call(obj) { | ||||
|     if (visitedObjects.contains(obj)) return null; | ||||
|     visitedObjects.add(obj); | ||||
| 
 | ||||
|     if (obj is num || obj is String || obj is bool) return obj; | ||||
|     if (obj is Iterable) return obj.map(call).toList(); | ||||
|     if (obj is Map) return mapToData(obj); | ||||
|     return toDataUsingReflection(obj); | ||||
|   } | ||||
| 
 | ||||
|   mapToData(obj) { | ||||
|     var res = {}; | ||||
|     obj.forEach((k,v) { | ||||
|       res[call(k)] = call(v); | ||||
|     }); | ||||
|     return res; | ||||
|   } | ||||
| 
 | ||||
|   toDataUsingReflection(obj) { | ||||
|     final clazz = reflectClass(obj.runtimeType); | ||||
|     final instance = reflect(obj); | ||||
| 
 | ||||
|     return clazz.declarations.values.fold({}, (map, decl) { | ||||
|       if (decl is VariableMirror && !decl.isPrivate && !decl.isStatic) { | ||||
|         final field = instance.getField(decl.simpleName); | ||||
|         final name = MirrorSystem.getName(decl.simpleName); | ||||
|         map[name] = call(field.reflectee); | ||||
|       } | ||||
|       return map; | ||||
|     }); | ||||
|   } | ||||
| } | ||||
| @ -1,7 +1,7 @@ | ||||
| import {describe, it, iit, ddescribe, expect, tick, async, SpyObject, beforeEach, proxy} from 'angular2/test_lib'; | ||||
| import {MapWrapper, ListWrapper} from 'angular2/src/facade/collection'; | ||||
| import {PromiseWrapper} from 'angular2/src/facade/async'; | ||||
| import {IMPLEMENTS} from 'angular2/src/facade/lang'; | ||||
| import {IMPLEMENTS, Date, DateWrapper} from 'angular2/src/facade/lang'; | ||||
| 
 | ||||
| class TestObj { | ||||
|   prop; | ||||
| @ -26,6 +26,10 @@ export function main() { | ||||
|         expect(falseActual).not.toEqual(expected); | ||||
|       }); | ||||
| 
 | ||||
|       it('should structurally compare objects with private and static fields', () => { | ||||
|         expect(DateWrapper.fromMillis(1)).toEqual(DateWrapper.fromMillis(1)); | ||||
|       }); | ||||
| 
 | ||||
|       it('should work for arrays of string maps', () => { | ||||
|         expect([{'a':'b'}]).toEqual([{'a':'b'}]); | ||||
|       }); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user