From d84e3afc04afd946b5d93c0d3c1817f2706a0572 Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Tue, 20 Mar 2018 12:40:52 -0700 Subject: [PATCH] Add new Dart 2 Iterable and List methods (#422) Here we add implementations for some of Dart 2's new methods on Iterable and List: * new method `Iterable.followedBy` * new `orElse` named parameter on `Iterable.singleWhere` * new operator `List.+` * new method `List.indexWhere` * new method `List.lastIndexWhere` --- CHANGELOG.md | 7 ++++++ lib/src/collection/delegates/iterable.dart | 12 +++------- lib/src/collection/delegates/list.dart | 22 ++++------------- lib/src/collection/multimap.dart | 25 +++++++------------- test/collection/delegates/iterable_test.dart | 9 +++++++ test/collection/delegates/list_test.dart | 15 ++++++++++++ 6 files changed, 48 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1dfb927b..2b12dea6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +#### Master + + * New: DelegatingIterable now includes a real implementation of + `followedBy`, and accepts the `orElse` parameter on `singleWhere`. + * New: DelegatingList now includes real implementations of `operator +`, + `indexWhere`, and `lastIndexWhere`. + #### 0.28.0 - 2018-01-19 * BREAKING CHANGE: The signature of `MultiMap`'s `update` stub has changed diff --git a/lib/src/collection/delegates/iterable.dart b/lib/src/collection/delegates/iterable.dart index 5fc1e8b3..ab06e7f2 100644 --- a/lib/src/collection/delegates/iterable.dart +++ b/lib/src/collection/delegates/iterable.dart @@ -53,11 +53,7 @@ abstract class DelegatingIterable implements Iterable { delegate.fold(initialValue, combine); @override - // TODO: Dart 2.0 requires this method to be implemented. - // ignore: override_on_non_overriding_method - Iterable followedBy(Iterable other) { - throw new UnimplementedError("followedBy"); - } + Iterable followedBy(Iterable other) => delegate.followedBy(other); void forEach(void f(E element)) => delegate.forEach(f); @@ -89,10 +85,8 @@ abstract class DelegatingIterable implements Iterable { E get single => delegate.single; - E singleWhere(bool test(E element), {E orElse()}) { - if (orElse != null) throw new UnimplementedError("singleWhere:orElse"); - return delegate.singleWhere(test); - } + E singleWhere(bool test(E element), {E orElse()}) => + delegate.singleWhere(test, orElse: orElse); Iterable skip(int n) => delegate.skip(n); diff --git a/lib/src/collection/delegates/list.dart b/lib/src/collection/delegates/list.dart index 38fdae7c..87c8279f 100644 --- a/lib/src/collection/delegates/list.dart +++ b/lib/src/collection/delegates/list.dart @@ -35,11 +35,7 @@ abstract class DelegatingList extends DelegatingIterable } @override - // TODO: Dart 2.0 requires this method to be implemented. - // ignore: override_on_non_overriding_method - List operator +(List other) { - throw new UnimplementedError("+"); - } + List operator +(List other) => delegate + other; void add(E value) => delegate.add(value); @@ -79,11 +75,8 @@ abstract class DelegatingList extends DelegatingIterable int indexOf(E element, [int start = 0]) => delegate.indexOf(element, start); @override - // TODO: Dart 2.0 requires this method to be implemented. - // ignore: override_on_non_overriding_method - int indexWhere(bool test(E element), [int start = 0]) { - throw new UnimplementedError("indexWhere"); - } + int indexWhere(bool test(E element), [int start = 0]) => + delegate.indexWhere(test, start); void insert(int index, E element) => delegate.insert(index, element); @@ -91,8 +84,6 @@ abstract class DelegatingList extends DelegatingIterable delegate.insertAll(index, iterable); @override - // TODO: Dart 2.0 requires this method to be implemented. - // ignore: override_on_non_overriding_setter void set last(E element) { if (this.isEmpty) throw new RangeError.index(0, this); this[this.length - 1] = element; @@ -102,11 +93,8 @@ abstract class DelegatingList extends DelegatingIterable delegate.lastIndexOf(element, start); @override - // TODO: Dart 2.0 requires this method to be implemented. - // ignore: override_on_non_overriding_method - int lastIndexWhere(bool test(E element), [int start]) { - throw new UnimplementedError("lastIndexWhere"); - } + int lastIndexWhere(bool test(E element), [int start]) => + delegate.lastIndexWhere(test, start); void set length(int newLength) { delegate.length = newLength; diff --git a/lib/src/collection/multimap.dart b/lib/src/collection/multimap.dart index 9affd16e..80c59930 100644 --- a/lib/src/collection/multimap.dart +++ b/lib/src/collection/multimap.dart @@ -430,10 +430,9 @@ class _WrappedIterable> implements Iterable { } @override - // TODO: Dart 2.0 requires this method to be implemented. - // ignore: override_on_non_overriding_method Iterable followedBy(Iterable other) { - throw new UnimplementedError("followedBy"); + _syncDelegate(); + return _delegate.followedBy(other); } void forEach(void f(V element)) { @@ -499,9 +498,8 @@ class _WrappedIterable> implements Iterable { } V singleWhere(bool test(V element), {V orElse()}) { - if (orElse != null) throw new UnimplementedError("singleWhere:orElse"); _syncDelegate(); - return _delegate.singleWhere(test); + return _delegate.singleWhere(test, orElse: orElse); } Iterable skip(int n) { @@ -565,10 +563,9 @@ class _WrappedList extends _WrappedIterable> } @override - // TODO: Dart 2.0 requires this method to be implemented. - // ignore: override_on_non_overriding_method List operator +(List other) { - throw new UnimplementedError("+"); + _syncDelegate(); + return _delegate + other; } void add(V value) { @@ -627,10 +624,9 @@ class _WrappedList extends _WrappedIterable> } @override - // TODO: Dart 2.0 requires this method to be implemented. - // ignore: override_on_non_overriding_method int indexWhere(bool test(V element), [int start = 0]) { - throw new UnimplementedError("indexWhere"); + _syncDelegate(); + return _delegate.indexWhere(test, start); } void insert(int index, V element) { @@ -648,8 +644,6 @@ class _WrappedList extends _WrappedIterable> } @override - // TODO: Dart 2.0 requires this method to be implemented. - // ignore: override_on_non_overriding_setter void set last(V value) { if (this.isEmpty) throw new RangeError.index(0, this); this[this.length - 1] = value; @@ -661,10 +655,9 @@ class _WrappedList extends _WrappedIterable> } @override - // TODO: Dart 2.0 requires this method to be implemented. - // ignore: override_on_non_overriding_method int lastIndexWhere(bool test(V element), [int start]) { - throw new UnimplementedError("lastIndexWhere"); + _syncDelegate(); + return _delegate.lastIndexWhere(test, start); } void set length(int newLength) { diff --git a/test/collection/delegates/iterable_test.dart b/test/collection/delegates/iterable_test.dart index 883e6b91..95d49f42 100644 --- a/test/collection/delegates/iterable_test.dart +++ b/test/collection/delegates/iterable_test.dart @@ -87,6 +87,13 @@ void main() { expect(new MyIterable([]).isNotEmpty, isFalse); }); + test('followedBy', () { + expect(delegatingIterable.followedBy(['d', 'e']), + equals(['a', 'b', 'cc', 'd', 'e'])); + expect(delegatingIterable.followedBy(delegatingIterable), + equals(['a', 'b', 'cc', 'a', 'b', 'cc'])); + }); + test('forEach', () { final it = delegatingIterable.iterator; expect(it.current, isNull); @@ -138,6 +145,8 @@ void main() { expect(delegatingIterable.singleWhere((e) => e == 'b'), equals('b')); expect(() => delegatingIterable.singleWhere((e) => e == 'd'), throwsStateError); + expect(delegatingIterable.singleWhere((e) => e == 'd', orElse: () => 'X'), + equals('X')); }); test('skip', () { diff --git a/test/collection/delegates/list_test.dart b/test/collection/delegates/list_test.dart index 8727d406..487beb92 100644 --- a/test/collection/delegates/list_test.dart +++ b/test/collection/delegates/list_test.dart @@ -45,6 +45,11 @@ void main() { expect(delegatingList, equals(['d', 'b', 'cc'])); }); + test('+', () { + var sum = delegatingList + ['d', 'e']; + expect(sum, equals(['a', 'b', 'cc', 'd', 'e'])); + }); + test('add', () { delegatingList.add('d'); expect(delegatingList, equals(['a', 'b', 'cc', 'd'])); @@ -82,6 +87,11 @@ void main() { expect(delegatingList.indexOf('cc', 1), equals(2)); }); + test('indexWhere', () { + delegatingList.add('bb'); + expect(delegatingList.indexWhere((e) => e.length > 1), equals(2)); + }); + test('insert', () { delegatingList.insert(1, 'd'); expect(delegatingList, equals(['a', 'd', 'b', 'cc'])); @@ -98,6 +108,11 @@ void main() { expect(delegatingList.lastIndexOf('cc', 1), equals(-1)); }); + test('lastIndexWhere', () { + delegatingList.add('bb'); + expect(delegatingList.lastIndexWhere((e) => e.length > 1), equals(3)); + }); + test('set length', () { delegatingList.length = 2; expect(delegatingList, equals(['a', 'b']));