angular/angular.dart — pull request #806 by chirayuk (2014-03-27 22:26:59+00:00)
Title: Repro for bug in dirty_checking_change_detector with collections

Consider the case when one is watching an expression, say, `items`, that
happens to be a list. Now consider the case when one mutates that
list and also updates `items` to point to a different list. In this case, the reported changes should be between the earlier observed collection and the newly observed collection. However, the implementation first observes that the original list was mutated and then observes that the reference to the list was updated to a different list. The changes reported are now the differences between the mutated list and the new list which is incorrect.

To reproduce the bug, add this test to `test/change_detection/dirty_checking_change_detector_spec.dart`

```dart
iit('should handle changes to both the list reference and the previous list', () {
var items = context['a'] = [];
var watch = watchGrp.watch(parser('a', collection: true), (v, p) => logger(v));

// initial change for empty list creation.
watchGrp.detectChanges();
expect(logger[0], toEqualCollectionRecord(
collection: [], additions: [], moves: [], removals: []));
logger.clear();

context['a'] = items.toList(); // The reference is now set to a copy.
items.add(1); // The original list is mutated.

// Since context['a'] is still an empty list, we don't expect to see any
// changes. Due to the bug, we instead observe that this assert will
// pass but the one we want fails.
//
// // This incorrect expectation passes.
// expect(logger[0], toEqualCollectionRecord(
// collection: [], additions: [], moves: [],
// removals: ['1[0 -> null]']));
//
watchGrp.detectChanges();
expect(logger).toEqual([]);
logger.clear();
});
```