Merge remote-tracking branch 'origin/master' into iterablex
diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index 439e796..bf6b38a 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml
@@ -8,3 +8,7 @@ interval: monthly labels: - autosubmit + groups: + github-actions: + patterns: + - "*"
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ac62fe0..e21d2e9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml
@@ -21,8 +21,8 @@ matrix: sdk: [dev] steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 + - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} - id: install @@ -48,8 +48,8 @@ os: [ubuntu-latest] sdk: [3.1.0, dev] steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 + - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} - id: install @@ -61,3 +61,6 @@ - name: Run Chrome tests run: dart test --platform chrome --test-randomize-ordering-seed=random if: always() && steps.install.outcome == 'success' + - name: Run Chrome tests - wasm + run: dart test --platform chrome --compiler dart2wasm + if: always() && steps.install.outcome == 'success' && matrix.sdk == 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f97cba..332686b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md
@@ -4,11 +4,16 @@ - Shuffle `IterableExtension.sample` results. - Fix `mergeSort` when the runtime iterable generic is a subtype of the static generic. +- `CanonicalizedMap`: added constructor `fromEntries`. +- Mark "mixin" classes as `mixin`. +- Deprecate `transitiveClosure`. Consider using `package:graphs`. - Remove `firstOrNull`, `lastOrNull`, `singleOrNull` and `elementAtOrNull()` from `IterableExtensions`. Since Dart 3.0, exact equivalents to these are available in Dart core, so 'package:collection' would only be shadowing these. +- Deprecate `whereNotNull()` from `IterableNullableExtension`. Use `nonNulls` + instead - this is an equivalent extension available in Dart core since + version 3.0. - Require Dart `^3.1.0` -- Mark "mixin" classes as `mixin`. ## 1.18.0
diff --git a/lib/algorithms.dart b/lib/algorithms.dart index 71a9f67..ac43242 100644 --- a/lib/algorithms.dart +++ b/lib/algorithms.dart
@@ -4,7 +4,7 @@ /// Import `collection.dart` instead. @Deprecated('Will be removed in collection 2.0.0.') -library dart.pkg.collection.algorithms; +library; export 'src/algorithms.dart' show binarySearch, insertionSort, lowerBound, mergeSort, reverse, shuffle;
diff --git a/lib/equality.dart b/lib/equality.dart index 021430b..5dc158c 100644 --- a/lib/equality.dart +++ b/lib/equality.dart
@@ -4,6 +4,6 @@ /// Import `collection.dart` instead. @Deprecated('Will be removed in collection 2.0.0.') -library dart.pkg.collection.equality; +library; export 'src/equality.dart';
diff --git a/lib/iterable_zip.dart b/lib/iterable_zip.dart index 1ef5595..bd0b1ef 100644 --- a/lib/iterable_zip.dart +++ b/lib/iterable_zip.dart
@@ -4,6 +4,6 @@ /// Import `collection.dart` instead. @Deprecated('Will be removed in collection 2.0.0.') -library dart.pkg.collection.iterable_zip; +library; export 'src/iterable_zip.dart';
diff --git a/lib/priority_queue.dart b/lib/priority_queue.dart index 9ed8be8..7505ce4 100644 --- a/lib/priority_queue.dart +++ b/lib/priority_queue.dart
@@ -4,6 +4,6 @@ /// Import `collection.dart` instead. @Deprecated('Will be removed in collection 2.0.0.') -library dart.pkg.collection.priority_queue; +library; export 'src/priority_queue.dart';
diff --git a/lib/src/algorithms.dart b/lib/src/algorithms.dart index f5ea8d3..bb5843c 100644 --- a/lib/src/algorithms.dart +++ b/lib/src/algorithms.dart
@@ -3,7 +3,7 @@ // BSD-style license that can be found in the LICENSE file. /// A selection of data manipulation algorithms. -library pkg.collection.algorithms; +library; import 'dart:math' show Random;
diff --git a/lib/src/canonicalized_map.dart b/lib/src/canonicalized_map.dart index 8490924..4103843 100644 --- a/lib/src/canonicalized_map.dart +++ b/lib/src/canonicalized_map.dart
@@ -46,6 +46,23 @@ addAll(other); } + /// Creates a canonicalized map that is initialized with the key/value pairs + /// of [entries]. + /// + /// The [canonicalize] function should return the canonical value for the + /// given key. Keys with the same canonical value are considered equivalent. + /// + /// The [isValidKey] function is called before calling [canonicalize] for + /// methods that take arbitrary objects. It can be used to filter out keys + /// that can't be canonicalized. + CanonicalizedMap.fromEntries( + Iterable<MapEntry<K, V>> entries, C Function(K key) canonicalize, + {bool Function(K key)? isValidKey}) + : _canonicalize = canonicalize, + _isValidKeyFn = isValidKey { + addEntries(entries); + } + CanonicalizedMap._( this._canonicalize, this._isValidKeyFn, Map<C, MapEntry<K, V>> base) { _base.addAll(base);
diff --git a/lib/src/functions.dart b/lib/src/functions.dart index 8f60b26..fb67c9f 100644 --- a/lib/src/functions.dart +++ b/lib/src/functions.dart
@@ -120,6 +120,7 @@ /// that vertex has no outgoing edges. This isn't checked, but if it's not /// satisfied, the function may crash or provide unexpected output. For example, /// `{"a": ["b"]}` is not valid, but `{"a": ["b"], "b": []}` is. +@Deprecated('This method will be removed. Consider using package:graphs.') Map<T, Set<T>> transitiveClosure<T>(Map<T, Iterable<T>> graph) { // This uses [Warshall's algorithm][], modified not to add a vertex from each // node to itself.
diff --git a/lib/src/iterable_extensions.dart b/lib/src/iterable_extensions.dart index 5def483..02d73a7 100644 --- a/lib/src/iterable_extensions.dart +++ b/lib/src/iterable_extensions.dart
@@ -572,6 +572,7 @@ /// of this iterable, in their original iteration order. /// /// For an `Iterable<X?>`, this method is equivalent to `.whereType<X>()`. + @Deprecated('Use .nonNulls instead.') Iterable<T> whereNotNull() sync* { for (var element in this) { if (element != null) yield element;
diff --git a/lib/wrappers.dart b/lib/wrappers.dart index d3a2ff6..be529ca 100644 --- a/lib/wrappers.dart +++ b/lib/wrappers.dart
@@ -4,7 +4,7 @@ /// Import `collection.dart` instead. @Deprecated('Will be removed in collection 2.0.0.') -library dart.pkg.collection.wrappers; +library; export 'src/canonicalized_map.dart'; export 'src/unmodifiable_wrappers.dart';
diff --git a/pubspec.yaml b/pubspec.yaml index 99e423f..d242250 100644 --- a/pubspec.yaml +++ b/pubspec.yaml
@@ -12,5 +12,5 @@ sdk: ^3.1.0 dev_dependencies: - dart_flutter_team_lints: ^2.0.0 + dart_flutter_team_lints: ^3.0.0 test: ^1.16.0
diff --git a/test/canonicalized_map_test.dart b/test/canonicalized_map_test.dart index 9ae4657..aadb734 100644 --- a/test/canonicalized_map_test.dart +++ b/test/canonicalized_map_test.dart
@@ -205,6 +205,24 @@ }); }); + group('CanonicalizedMap.fromEntries', () { + test('canonicalizes its keys', () { + var map = CanonicalizedMap.fromEntries( + {'1': 'value 1', '2': 'value 2', '3': 'value 3'}.entries, int.parse); + expect(map['01'], equals('value 1')); + expect(map['02'], equals('value 2')); + expect(map['03'], equals('value 3')); + }); + + test('uses the final value for collisions', () { + var map = CanonicalizedMap.fromEntries( + {'1': 'value 1', '01': 'value 2', '001': 'value 3'}.entries, + int.parse); + expect(map.length, equals(1)); + expect(map['0001'], equals('value 3')); + }); + }); + group('CanonicalizedMap.toMapOfCanonicalKeys', () { test('convert to a `Map<C,V>`', () { var map = CanonicalizedMap.from(
diff --git a/test/extensions_test.dart b/test/extensions_test.dart index e235f5e..30002fc 100644 --- a/test/extensions_test.dart +++ b/test/extensions_test.dart
@@ -836,17 +836,47 @@ group('of nullable', () { group('.whereNotNull', () { test('empty', () { - expect(iterable(<int?>[]).whereNotNull(), isEmpty); + expect( + iterable(<int?>[]) + .whereNotNull(), // ignore: deprecated_member_use_from_same_package + isEmpty); }); test('single', () { - expect(iterable(<int?>[null]).whereNotNull(), isEmpty); - expect(iterable(<int?>[1]).whereNotNull(), [1]); + expect( + iterable(<int?>[ + null + ]).whereNotNull(), // ignore: deprecated_member_use_from_same_package + isEmpty); + expect( + iterable(<int?>[ + 1 + ]).whereNotNull(), // ignore: deprecated_member_use_from_same_package + [1]); }); test('multiple', () { - expect(iterable(<int?>[1, 3, 5]).whereNotNull(), [1, 3, 5]); - expect(iterable(<int?>[null, null, null]).whereNotNull(), isEmpty); expect( - iterable(<int?>[1, null, 3, null, 5]).whereNotNull(), [1, 3, 5]); + iterable(<int?>[ + 1, + 3, + 5 + ]).whereNotNull(), // ignore: deprecated_member_use_from_same_package + [1, 3, 5]); + expect( + iterable(<int?>[ + null, + null, + null + ]).whereNotNull(), // ignore: deprecated_member_use_from_same_package + isEmpty); + expect( + iterable(<int?>[ + 1, + null, + 3, + null, + 5 + ]).whereNotNull(), // ignore: deprecated_member_use_from_same_package + [1, 3, 5]); }); }); });
diff --git a/test/functions_test.dart b/test/functions_test.dart index cc97327..f602303 100644 --- a/test/functions_test.dart +++ b/test/functions_test.dart
@@ -2,6 +2,8 @@ // 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. +// ignore_for_file: deprecated_member_use_from_same_package + import 'package:collection/collection.dart'; import 'package:test/test.dart'; @@ -9,7 +11,6 @@ group('mapMap()', () { test('with an empty map returns an empty map', () { expect( - // ignore: deprecated_member_use_from_same_package mapMap({}, key: expectAsync2((_, __) {}, count: 0), value: expectAsync2((_, __) {}, count: 0)), @@ -18,7 +19,6 @@ test('with no callbacks, returns a copy of the map', () { var map = {'foo': 1, 'bar': 2}; - // ignore: deprecated_member_use_from_same_package var result = mapMap<String, int, String, int>(map); expect(result, equals({'foo': 1, 'bar': 2})); @@ -29,7 +29,6 @@ test("maps the map's keys", () { expect( - // ignore: deprecated_member_use_from_same_package mapMap<String, int, dynamic, int>({'foo': 1, 'bar': 2}, key: (dynamic key, dynamic value) => key[value]), equals({'o': 1, 'r': 2})); @@ -37,7 +36,6 @@ test("maps the map's values", () { expect( - // ignore: deprecated_member_use_from_same_package mapMap<String, int, String, dynamic>({'foo': 1, 'bar': 2}, value: (dynamic key, dynamic value) => key[value]), equals({'foo': 'o', 'bar': 'r'})); @@ -45,7 +43,6 @@ test("maps both the map's keys and values", () { expect( - // ignore: deprecated_member_use_from_same_package mapMap({'foo': 1, 'bar': 2}, key: (dynamic key, dynamic value) => '$key$value', value: (dynamic key, dynamic value) => key[value]),