Merge pull request #108 from google/google
Integrate internal changes
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
deleted file mode 100644
index 0994653..0000000
--- a/.github/workflows/ci.yml
+++ /dev/null
@@ -1,37 +0,0 @@
-# This workflow uses actions that are not certified by GitHub.
-# They are provided by a third-party and are governed by
-# separate terms of service, privacy policy, and support
-# documentation.
-
-name: ci
-
-on:
- push:
- branches: [ master ]
- pull_request:
- branches: [ master ]
-
-jobs:
- analyze:
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v2
- - uses: dart-lang/setup-dart@v1.0
- with:
- sdk: dev
- - run: pub get
- - run: dart format --output=none --set-exit-if-changed .
- - run: dart analyze --fatal-infos
- test:
- runs-on: ubuntu-latest
- strategy:
- matrix:
- sdk: [2.12.0, stable, dev]
- steps:
- - uses: actions/checkout@v2
- - uses: dart-lang/setup-dart@v1.0
- with:
- sdk: ${{ matrix.sdk }}
- - run: pub get
- - run: pub run test -p vm,chrome
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index e43b40f..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,9 +0,0 @@
-# Files and directories created by pub
-.dart_tool/
-.packages
-.pub/
-packages
-pubspec.lock
-
-# Directory created by dartdoc
-doc/api/
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4ec2494..f1c8c44 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,7 @@
## 0.24.0-dev
* Migrate to [null safety](https://dart.dev/null-safety).
+* Update ObservableMap to notify observers about changes for all methods.
## 0.23.0
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
deleted file mode 100644
index 6f5e0ea..0000000
--- a/CONTRIBUTING.md
+++ /dev/null
@@ -1,33 +0,0 @@
-Want to contribute? Great! First, read this page (including the small print at
-the end).
-
-### Before you contribute
-Before we can use your code, you must sign the
-[Google Individual Contributor License Agreement](https://cla.developers.google.com/about/google-individual)
-(CLA), which you can do online. The CLA is necessary mainly because you own the
-copyright to your changes, even after your contribution becomes part of our
-codebase, so we need your permission to use and distribute your code. We also
-need to be sure of various other things—for instance that you'll tell us if you
-know that your code infringes on other people's patents. You don't have to sign
-the CLA until after you've submitted your code for review and a member has
-approved it, but you must do it before we can put your code into our codebase.
-
-Before you start working on a larger contribution, you should get in touch with
-us first through the issue tracker with your idea so that we can help out and
-possibly guide you. Coordinating up front makes it much easier to avoid
-frustration later on.
-
-### Code reviews
-All submissions, including submissions by project members, require review.
-
-### File headers
-All files in the project must start with the following header.
-
- // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
- // for details. All rights reserved. Use of this source code is governed by a
- // BSD-style license that can be found in the LICENSE file.
-
-### The small print
-Contributions made by corporations are covered by a different agreement than the
-one above, the
-[Software Grant and Corporate Contributor License Agreement](https://developers.google.com/open-source/cla/corporate).
diff --git a/lib/src/observable_list.dart b/lib/src/observable_list.dart
index c25534f..85c34ef 100644
--- a/lib/src/observable_list.dart
+++ b/lib/src/observable_list.dart
@@ -244,7 +244,6 @@
// We are modifying the length just below these checks. Without the checks
// Array.copy could throw an exception, leaving the list in a bad state
// (with a length that has been increased, but without a new element).
- if (index is! int) throw ArgumentError(index);
RangeError.checkValidIndex(index, this);
_list
// Increase the length by adding [element], in case [E] isn't nullable.
diff --git a/lib/src/observable_map.dart b/lib/src/observable_map.dart
index ec256f7..05f2a4f 100644
--- a/lib/src/observable_map.dart
+++ b/lib/src/observable_map.dart
@@ -190,7 +190,9 @@
@override
void addEntries(Iterable<MapEntry<K, V>> entries) {
- _map.addEntries(entries);
+ for (var entry in entries) {
+ this[entry.key] = entry.value;
+ }
}
@override
@@ -200,15 +202,21 @@
@override
V update(K key, V Function(V value) update, {V Function()? ifAbsent}) {
- return _map.update(key, update, ifAbsent: ifAbsent);
+ var value = containsKey(key) ? update(this[key] as V) : ifAbsent!();
+ return this[key] = value;
}
@override
- void updateAll(V Function(K key, V value) update) => _map.updateAll(update);
+ void updateAll(V Function(K key, V value) update) {
+ for (var key in keys) {
+ this[key] = update(key, this[key] as V);
+ }
+ }
@override
- void removeWhere(bool Function(K key, V value) test) =>
- _map.removeWhere(test);
+ void removeWhere(bool Function(K key, V value) test) {
+ keys.where((key) => test(key, this[key] as V)).toList().forEach(remove);
+ }
// Note: we don't really have a reasonable old/new value to use here.
// But this should fix "keys" and "values" in templates with minimal overhead.
diff --git a/test/change_notifier_test.dart b/test/change_notifier_test.dart
index b412742..a6d0385 100644
--- a/test/change_notifier_test.dart
+++ b/test/change_notifier_test.dart
@@ -56,7 +56,10 @@
test(
'delivers expectChangesed changes',
() => runTest<B>((cn) {
- cn..notifyChange(B(1))..notifyChange(B(2))..notifyChange(B(3));
+ cn
+ ..notifyChange(B(1))
+ ..notifyChange(B(2))
+ ..notifyChange(B(3));
}, (cr) {
expectChanges(cr, ChangeRecords<B>.wrap([B(1), B(2), B(3)]));
}));
diff --git a/test/observable_map_test.dart b/test/observable_map_test.dart
index 5743001..b980983 100644
--- a/test/observable_map_test.dart
+++ b/test/observable_map_test.dart
@@ -86,7 +86,7 @@
});
group('observe item', () {
- late ObservableMap map;
+ late ObservableMap<String, int?> map;
List<ChangeRecord>? changes;
setUp(() {
@@ -177,6 +177,48 @@
]);
});
});
+
+ test('change the item as part of addAll', () {
+ map.addAll({'b': 13, 'd': 4});
+ expect(map, {'a': 1, 'b': 13, 'c': 3, 'd': 4});
+ return Future(() {
+ expect(changes, [_changeKey('b', 2, 13)]);
+ });
+ });
+
+ test('change the item as part of addEntries', () {
+ map.addEntries(
+ [MapEntry<String, int>('b', 13), MapEntry<String, int>('d', 4)]);
+ expect(map, {'a': 1, 'b': 13, 'c': 3, 'd': 4});
+ return Future(() {
+ expect(changes, [_changeKey('b', 2, 13)]);
+ });
+ });
+
+ test('update the item', () {
+ map.update('b', (int? value) => value == null ? value : value + 1);
+ expect(map, {'a': 1, 'b': 3, 'c': 3});
+ return Future(() {
+ expect(changes, [_changeKey('b', 2, 3)]);
+ });
+ });
+
+ test('update all items', () {
+ map.updateAll(
+ (String key, int? value) => value == null ? value : value + 1);
+ expect(map, {'a': 2, 'b': 3, 'c': 4});
+ return Future(() {
+ expect(changes, [_changeKey('b', 2, 3)]);
+ });
+ });
+
+ test('remove the item as part of removeWhere', () {
+ map.removeWhere((key, value) => value != null && value > 1);
+ expect(map, {'a': 1});
+ return Future(() {
+ expect(changes, [_removeKey('b', 2)]);
+ });
+ });
});
test('toString', () {