| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 // Copyright 2014 Google Inc. All Rights Reserved. | 
|  | 2 // | 
|  | 3 // Licensed under the Apache License, Version 2.0 (the 'License'); | 
|  | 4 // you may not use this file except in compliance with the License. | 
|  | 5 // You may obtain a copy of the License at | 
|  | 6 // | 
|  | 7 //     http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 8 // | 
|  | 9 // Unless required by applicable law or agreed to in writing, software | 
|  | 10 // distributed under the License is distributed on an 'AS IS' BASIS, | 
|  | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 12 // See the License for the specific language governing permissions and | 
|  | 13 // limitations under the License. | 
|  | 14 | 
|  | 15 library quiver.testing.util.equalstester; | 
|  | 16 | 
|  | 17 import 'package:quiver/testing/equality.dart'; | 
|  | 18 import 'package:test/test.dart'; | 
|  | 19 | 
|  | 20 main() { | 
|  | 21   group('expectEquals', () { | 
|  | 22     _ValidTestObject reference; | 
|  | 23     _ValidTestObject equalObject1; | 
|  | 24     _ValidTestObject equalObject2; | 
|  | 25     _ValidTestObject notEqualObject1; | 
|  | 26 | 
|  | 27     setUp(() { | 
|  | 28       reference = new _ValidTestObject(1, 2); | 
|  | 29       equalObject1 = new _ValidTestObject(1, 2); | 
|  | 30       equalObject2 = new _ValidTestObject(1, 2); | 
|  | 31       notEqualObject1 = new _ValidTestObject(0, 2); | 
|  | 32     }); | 
|  | 33 | 
|  | 34     test('Test null reference yields error', () { | 
|  | 35       try { | 
|  | 36         expect(null, areEqualityGroups); | 
|  | 37         fail('Should fail with null reference'); | 
|  | 38       } catch (e) { | 
|  | 39         expect(e.toString(), contains('Equality Group must not be null')); | 
|  | 40       } | 
|  | 41     }); | 
|  | 42 | 
|  | 43     test('Test null group name yields error', () { | 
|  | 44       try { | 
|  | 45         expect({'null': [reference], null: [reference]}, areEqualityGroups); | 
|  | 46         fail('Should fail with null group name'); | 
|  | 47       } catch (e) { | 
|  | 48         expect(e.toString(), contains('Group name must not be null')); | 
|  | 49       } | 
|  | 50     }); | 
|  | 51 | 
|  | 52     test('Test null group yields error', () { | 
|  | 53       try { | 
|  | 54         expect({'bad group': null}, areEqualityGroups); | 
|  | 55         fail('Should fail with null group'); | 
|  | 56       } catch (e) { | 
|  | 57         expect(e.toString(), contains('Group must not be null')); | 
|  | 58       } | 
|  | 59     }); | 
|  | 60 | 
|  | 61     test('Test after adding multiple instances at once with a null', () { | 
|  | 62       try { | 
|  | 63         expect( | 
|  | 64             {'bad group': [reference, equalObject1, null]}, areEqualityGroups); | 
|  | 65         fail('Should fail with null group'); | 
|  | 66       } catch (e) { | 
|  | 67         expect(e.toString(), contains("$reference [group 'bad group', item 1]" | 
|  | 68             " must be equal to null [group 'bad group', item 3]")); | 
|  | 69       } | 
|  | 70     }); | 
|  | 71 | 
|  | 72     test('Test adding non-equal objects only in single group.', () { | 
|  | 73       try { | 
|  | 74         expect( | 
|  | 75             {'not equal': [equalObject1, notEqualObject1]}, areEqualityGroups); | 
|  | 76         fail("Should get not equal to equal object error"); | 
|  | 77       } catch (e) { | 
|  | 78         expect(e.toString(), contains("$equalObject1 [group 'not equal', item" | 
|  | 79             " 1] must be equal to $notEqualObject1 [group 'not equal'" | 
|  | 80             ", item 2]")); | 
|  | 81       } | 
|  | 82     }); | 
|  | 83 | 
|  | 84     test('Test with no equals or not equals objects. This checks' | 
|  | 85         ' proper handling of null, incompatible class and reflexive tests', () { | 
|  | 86       expect({'single object': [reference]}, areEqualityGroups); | 
|  | 87     }); | 
|  | 88 | 
|  | 89     test('Test after populating equal objects. This checks proper' | 
|  | 90         ' handling of equality and verifies hashCode for valid objects', () { | 
|  | 91       expect({ | 
|  | 92         'all equal': [reference, equalObject1, equalObject2] | 
|  | 93       }, areEqualityGroups); | 
|  | 94     }); | 
|  | 95 | 
|  | 96     test('Test proper handling of case where an object is not equal to itself', | 
|  | 97         () { | 
|  | 98       Object obj = new _NonReflexiveObject(); | 
|  | 99       try { | 
|  | 100         expect({'non-reflexive': [obj]}, areEqualityGroups); | 
|  | 101         fail("Should get non-reflexive error"); | 
|  | 102       } catch (e) { | 
|  | 103         expect(e.toString(), contains("$obj must be equal to itself")); | 
|  | 104       } | 
|  | 105     }); | 
|  | 106 | 
|  | 107     test('Test proper handling of case where hashcode is not idempotent', () { | 
|  | 108       Object obj = new _InconsistentHashCodeObject(1, 2); | 
|  | 109       try { | 
|  | 110         expect({'non-reflexive': [obj]}, areEqualityGroups); | 
|  | 111         fail("Should get non-reflexive error"); | 
|  | 112       } catch (e) { | 
|  | 113         expect(e.toString(), contains( | 
|  | 114             "the implementation of hashCode of $obj must be idempotent")); | 
|  | 115       } | 
|  | 116     }); | 
|  | 117 | 
|  | 118     test('Test proper handling where an object incorrectly tests for an ' | 
|  | 119         'incompatible class', () { | 
|  | 120       Object obj = new _InvalidEqualsIncompatibleClassObject(); | 
|  | 121       try { | 
|  | 122         expect({'equals method broken': [obj]}, areEqualityGroups); | 
|  | 123         fail("Should get equal to incompatible class error"); | 
|  | 124       } catch (e) { | 
|  | 125         expect(e.toString(), contains("$obj must not be equal to an " | 
|  | 126             "arbitrary object of another class")); | 
|  | 127       } | 
|  | 128     }); | 
|  | 129 | 
|  | 130     test('Test proper handling where an object is not equal to one the user ' | 
|  | 131         'has said should be equal', () { | 
|  | 132       try { | 
|  | 133         expect({'non-equal': [reference, notEqualObject1]}, areEqualityGroups); | 
|  | 134         fail("Should get not equal to equal object error"); | 
|  | 135       } catch (e) { | 
|  | 136         expect( | 
|  | 137             e.toString(), contains("$reference [group 'non-equal', item 1]")); | 
|  | 138         expect(e.toString(), | 
|  | 139             contains("$notEqualObject1 [group 'non-equal', item 2]")); | 
|  | 140       } | 
|  | 141     }); | 
|  | 142 | 
|  | 143     test('Test for an invalid hashCode method, i.e., one that returns ' | 
|  | 144         'different value for objects that are equal according to the equals ' | 
|  | 145         'method', () { | 
|  | 146       Object a = new _InvalidHashCodeObject(1, 2); | 
|  | 147       Object b = new _InvalidHashCodeObject(1, 2); | 
|  | 148       try { | 
|  | 149         expect({'invalid hashcode': [a, b]}, areEqualityGroups); | 
|  | 150         fail("Should get invalid hashCode error"); | 
|  | 151       } catch (e) { | 
|  | 152         expect(e.toString(), contains("the hashCode (${a.hashCode}) of $a" | 
|  | 153             " [group 'invalid hashcode', item 1] must be equal to the" | 
|  | 154             " hashCode (${b.hashCode}) of $b")); | 
|  | 155       } | 
|  | 156     }); | 
|  | 157 | 
|  | 158     test('Symmetry Broken', () { | 
|  | 159       try { | 
|  | 160         expect({ | 
|  | 161           'broken symmetry': [named('foo')..addPeers(['bar']), named('bar')] | 
|  | 162         }, areEqualityGroups); | 
|  | 163         fail("should fail because symmetry is broken"); | 
|  | 164       } catch (e) { | 
|  | 165         expect(e.toString(), contains("bar [group 'broken symmetry', item 2] " | 
|  | 166             "must be equal to foo [group 'broken symmetry', item 1]")); | 
|  | 167       } | 
|  | 168     }); | 
|  | 169 | 
|  | 170     test('Transitivity Broken In EqualityGroup', () { | 
|  | 171       try { | 
|  | 172         expect({ | 
|  | 173           'transitivity broken': [ | 
|  | 174             named('foo')..addPeers(['bar', 'baz']), | 
|  | 175             named('bar')..addPeers(['foo']), | 
|  | 176             named('baz')..addPeers(['foo']) | 
|  | 177           ] | 
|  | 178         }, areEqualityGroups); | 
|  | 179         fail("should fail because transitivity is broken"); | 
|  | 180       } catch (e) { | 
|  | 181         expect(e.toString(), contains("bar [group 'transitivity broken', " | 
|  | 182             "item 2] must be equal to baz [group 'transitivity " | 
|  | 183             "broken', item 3]")); | 
|  | 184       } | 
|  | 185     }); | 
|  | 186 | 
|  | 187     test('Unequal Objects In EqualityGroup', () { | 
|  | 188       try { | 
|  | 189         expect({ | 
|  | 190           'unequal objects': [named('foo'), named('bar')] | 
|  | 191         }, areEqualityGroups); | 
|  | 192         fail('should fail because of unequal objects in the same equality ' | 
|  | 193             'group'); | 
|  | 194       } catch (e) { | 
|  | 195         expect(e.toString(), contains("foo [group 'unequal objects', item 1] " | 
|  | 196             "must be equal to bar [group 'unequal objects', item 2]")); | 
|  | 197       } | 
|  | 198     }); | 
|  | 199 | 
|  | 200     test('Transitivity Broken Across EqualityGroups', () { | 
|  | 201       try { | 
|  | 202         expect({ | 
|  | 203           'transitivity one': [ | 
|  | 204             named('foo')..addPeers(['bar']), | 
|  | 205             named('bar')..addPeers(['foo', 'x']) | 
|  | 206           ], | 
|  | 207           'transitivity two': [ | 
|  | 208             named('baz')..addPeers(['x']), | 
|  | 209             named('x')..addPeers(['baz', 'bar']) | 
|  | 210           ] | 
|  | 211         }, areEqualityGroups); | 
|  | 212         fail('should fail because transitivity is broken'); | 
|  | 213       } catch (e) { | 
|  | 214         expect(e.toString(), contains("bar [group 'transitivity one', item 2]" | 
|  | 215             " must not be equal to x [group 'transitivity two'," | 
|  | 216             " item 2]")); | 
|  | 217       } | 
|  | 218     }); | 
|  | 219 | 
|  | 220     test('EqualityGroups', () { | 
|  | 221       expect({ | 
|  | 222         'valid groups one': [ | 
|  | 223           named('foo').addPeers(['bar']), | 
|  | 224           named('bar').addPeers(['foo']) | 
|  | 225         ], | 
|  | 226         'valid groups two': [named('baz'), named('baz')] | 
|  | 227       }, areEqualityGroups); | 
|  | 228     }); | 
|  | 229   }); | 
|  | 230 } | 
|  | 231 | 
|  | 232 /// Test class that violates reflexitivity.  It is not equal to itself. | 
|  | 233 class _NonReflexiveObject { | 
|  | 234   @override | 
|  | 235   bool operator ==(Object o) => false; | 
|  | 236 | 
|  | 237   @override | 
|  | 238   int get hashCode => super.hashCode; | 
|  | 239 } | 
|  | 240 | 
|  | 241 /** | 
|  | 242  * Test class with valid equals and hashCode methods. Testers created | 
|  | 243  * with instances of this class should always pass. | 
|  | 244  */ | 
|  | 245 class _ValidTestObject { | 
|  | 246   int aspect1; | 
|  | 247   int aspect2; | 
|  | 248 | 
|  | 249   _ValidTestObject(this.aspect1, this.aspect2); | 
|  | 250 | 
|  | 251   @override | 
|  | 252   bool operator ==(Object o) { | 
|  | 253     if (!(o is _ValidTestObject)) { | 
|  | 254       return false; | 
|  | 255     } | 
|  | 256     _ValidTestObject other = o as _ValidTestObject; | 
|  | 257     if (aspect1 != other.aspect1) { | 
|  | 258       return false; | 
|  | 259     } | 
|  | 260     if (aspect2 != other.aspect2) { | 
|  | 261       return false; | 
|  | 262     } | 
|  | 263     return true; | 
|  | 264   } | 
|  | 265 | 
|  | 266   @override | 
|  | 267   int get hashCode { | 
|  | 268     int result = 17; | 
|  | 269     result = 37 * result + aspect1; | 
|  | 270     result = 37 * result + aspect2; | 
|  | 271     return result; | 
|  | 272   } | 
|  | 273 } | 
|  | 274 | 
|  | 275 ///Test class that returns true even if the test object is of the wrong class. | 
|  | 276 class _InvalidEqualsIncompatibleClassObject { | 
|  | 277   @override | 
|  | 278   bool operator ==(Object o) { | 
|  | 279     return true; | 
|  | 280   } | 
|  | 281 | 
|  | 282   @override | 
|  | 283   int get hashCode => 0; | 
|  | 284 } | 
|  | 285 | 
|  | 286 /// Test class with inconsistent hashCode method. | 
|  | 287 class _InconsistentHashCodeObject { | 
|  | 288   int _aspect1; | 
|  | 289   int _aspect2; | 
|  | 290   int _hashCode = 0; | 
|  | 291 | 
|  | 292   _InconsistentHashCodeObject(this._aspect1, this._aspect2); | 
|  | 293 | 
|  | 294   @override | 
|  | 295   int get hashCode => _hashCode++; | 
|  | 296 | 
|  | 297   @override | 
|  | 298   bool operator ==(Object o) { | 
|  | 299     if (!(o is _InconsistentHashCodeObject)) { | 
|  | 300       return false; | 
|  | 301     } | 
|  | 302     _InconsistentHashCodeObject other = o as _InconsistentHashCodeObject; | 
|  | 303     if (_aspect1 != other._aspect1) return false; | 
|  | 304     if (_aspect2 != other._aspect2) return false; | 
|  | 305     return true; | 
|  | 306   } | 
|  | 307 } | 
|  | 308 | 
|  | 309 /// Test class with invalid hashCode method. | 
|  | 310 class _InvalidHashCodeObject { | 
|  | 311   static int hashCodeSource = 0; | 
|  | 312   int _aspect1; | 
|  | 313   int _aspect2; | 
|  | 314   int _hashCode = hashCodeSource++; | 
|  | 315 | 
|  | 316   _InvalidHashCodeObject(this._aspect1, this._aspect2); | 
|  | 317 | 
|  | 318   @override | 
|  | 319   int get hashCode => _hashCode; | 
|  | 320 | 
|  | 321   @override | 
|  | 322   bool operator ==(Object o) { | 
|  | 323     if (!(o is _InvalidHashCodeObject)) { | 
|  | 324       return false; | 
|  | 325     } | 
|  | 326     _InvalidHashCodeObject other = o as _InvalidHashCodeObject; | 
|  | 327     if (_aspect1 != other._aspect1) return false; | 
|  | 328     if (_aspect2 != other._aspect2) return false; | 
|  | 329     return true; | 
|  | 330   } | 
|  | 331 } | 
|  | 332 | 
|  | 333 _NamedObject named(String name) => new _NamedObject(name); | 
|  | 334 | 
|  | 335 class _NamedObject { | 
|  | 336   final Set<String> peerNames = new Set(); | 
|  | 337   final String name; | 
|  | 338 | 
|  | 339   _NamedObject(this.name); | 
|  | 340 | 
|  | 341   void addPeers(List<String> names) { | 
|  | 342     peerNames.addAll(names); | 
|  | 343   } | 
|  | 344 | 
|  | 345   @override | 
|  | 346   bool operator ==(Object obj) { | 
|  | 347     if (obj is _NamedObject) { | 
|  | 348       _NamedObject that = obj; | 
|  | 349       return name == that.name || peerNames.contains(that.name); | 
|  | 350     } | 
|  | 351     return false; | 
|  | 352   } | 
|  | 353 | 
|  | 354   @override | 
|  | 355   int get hashCode => 0; | 
|  | 356 | 
|  | 357   @override String toString() => name; | 
|  | 358 } | 
| OLD | NEW | 
|---|