Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions lib/change_detection/dirty_checking_change_detector.dart
Original file line number Diff line number Diff line change
Expand Up @@ -451,9 +451,13 @@ class _MapChangeRecord<K, V> implements MapChangeRecord<K, V> {
if (oldSeqRecord != null && key == oldSeqRecord.key) {
newSeqRecord = oldSeqRecord;
if (!identical(value, oldSeqRecord._currentValue)) {
oldSeqRecord._previousValue = oldSeqRecord._currentValue;
var prev = oldSeqRecord._previousValue = oldSeqRecord._currentValue;
oldSeqRecord._currentValue = value;
_addToChanges(oldSeqRecord);
if (!((value is String && prev is String && value == prev) ||
(value is num && value.isNaN && prev is num && prev.isNaN))) {
// Check string by value rather than reference
_addToChanges(oldSeqRecord);
}
}
} else {
seqChanged = true;
Expand Down Expand Up @@ -793,11 +797,17 @@ class _CollectionChangeRecord<V> implements CollectionChangeRecord<V> {
*/
ItemRecord mismatch(ItemRecord record, item, int index) {
// Guard against bogus String changes
if (record != null && item is String && record.item is String &&
record.item == item) {
// this is false change in strings we need to recover, and pretend it is
// the same. We save the value so that next time identity will pass
return record..item = item;
if (record != null) {
if (item is String && record.item is String && record.item == item) {
// this is false change in strings we need to recover, and pretend it is
// the same. We save the value so that next time identity can pass
return record..item = item;
}

if (item is num && item.isNaN && record.item is num && record.item.isNaN){
// we need this for JavaScript since in JS NaN !== NaN.
return record;
}
}

// find the previous record so that we know where to insert after.
Expand Down
35 changes: 33 additions & 2 deletions test/change_detection/dirty_checking_change_detector_spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -245,14 +245,20 @@ main() => describe('DirtyCheckingChangeDetector', () {

it('should test string by value rather than by reference', () {
var list = ['a', 'boo'];
var record = detector.watch(list, null, 'handler');
detector.collectChanges();
detector..watch(list, null, null)..collectChanges();

list[1] = 'b' + 'oo';

expect(detector.collectChanges()).toEqual(null);
});

it('should ignore [NaN] != [NaN]', () {
var list = [double.NAN];
var record = detector..watch(list, null, null)..collectChanges();

expect(detector.collectChanges()).toEqual(null);
});

it('should remove and add same item', () {
var list = ['a', 'b', 'c'];
var record = detector.watch(list, null, 'handler');
Expand Down Expand Up @@ -389,6 +395,31 @@ main() => describe('DirtyCheckingChangeDetector', () {
changes: [],
removals: ['a[A -> null]', 'd[D -> null]']));
});

it('should test string keys by value rather than by reference', () {
var map = {'foo': 0};
detector..watch(map, null, null)..collectChanges();

map['f' + 'oo'] = 0;

expect(detector.collectChanges()).toEqual(null);
});

it('should test string values by value rather than by reference', () {
var map = {'foo': 'bar'};
detector..watch(map, null, null)..collectChanges();

map['foo'] = 'b' + 'ar';

expect(detector.collectChanges()).toEqual(null);
});

it('should not see a NaN value as a change', () {
var map = {'foo': double.NAN};
var record = detector..watch(map, null, null)..collectChanges();

expect(detector.collectChanges()).toEqual(null);
});
});

describe('DuplicateMap', () {
Expand Down