| // Copyright (c) 2018, 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. |
| |
| // @dart = 2.9 |
| |
| import "dart:collection" show Queue; |
| import "dart:typed_data" show Int32List; |
| |
| import "package:expect/expect.dart"; |
| |
| // Tests behavior of result of an operation on a followedBy iterable. |
| test(List expects, Iterable iterable, [String name]) { |
| try { |
| Expect.isFalse(iterable is List, "$name is! List"); |
| Expect.isFalse(iterable is Set, "$name is! Set"); |
| Expect.isFalse(iterable is Queue, "$name is! Queue"); |
| if (expects.isNotEmpty) { |
| Expect.equals(expects.first, iterable.first, "$name: first"); |
| Expect.equals(expects.last, iterable.last, "$name: last"); |
| } else { |
| Expect.throwsStateError(() => iterable.first, "$name: first"); |
| Expect.throwsStateError(() => iterable.last, "$name: last"); |
| } |
| var it = iterable.iterator; |
| for (int index = 0; index < expects.length; index++) { |
| Expect.isTrue(it.moveNext(), "$name: has element $index"); |
| var expect = expects[index]; |
| Expect.equals(expect, it.current, "$name at $index"); |
| Expect.equals( |
| expect, iterable.elementAt(index), "$name: elementAt($index)"); |
| Expect.isTrue(iterable.contains(expect), "$name:contains $index"); |
| } |
| Expect.isFalse(it.moveNext(), |
| "$name: extra element at ${expects.length}: ${it.current}"); |
| } on Error { |
| print("Failed during: $name"); |
| rethrow; |
| } |
| } |
| |
| main() { |
| var conversions = <String, Iterable<int> Function(List<int>)>{ |
| "const": toConst, |
| "list": toList, |
| "unmod": toUnmodifiable, |
| "set": toSet, |
| "queue": toQueue, |
| "eff-len-iter": toELIter, |
| "non-eff-iter": toNEIter, |
| "typed": toTyped, |
| "keys": toKeys, |
| "values": toValues, |
| }; |
| for (var data in [ |
| const <int>[], |
| const <int>[1], |
| const <int>[1, 2, 3] |
| ]) { |
| conversions.forEach((name, c) { |
| test(data, c(data).whereType<int>(), "$name#${data.length}.wt<int>"); |
| test(data, c(data).whereType<num>(), "$name#${data.length}.wt<num>"); |
| test([], c(data).whereType<Null>(), "$name#${data.length}.wt<Null>"); |
| }); |
| } |
| |
| test([1, 0.1], ["a", 1, new Object(), 0.1, null].whereType<num>(), "mixed"); |
| |
| var o = new Object(); |
| var a = new A(); |
| var b = new B(); |
| var c = new C(); |
| var d = new D(); |
| var n = null; |
| test([o, a, b, c, d, n], [o, a, b, c, d, n].whereType<Object>(), "Object"); |
| test([a, b, c, d], [o, a, b, c, d, n].whereType<A>(), "A"); |
| test([b, d], [o, a, b, c, d, n].whereType<B>(), "B"); |
| test([c, d], [o, a, b, c, d, n].whereType<C>(), "C"); |
| test([d], [o, a, b, c, d, n].whereType<D>(), "D"); |
| test([n], [o, a, b, c, d, n].whereType<Null>(), "Null"); |
| |
| test([d], <B>[d].whereType<C>(), "Unrelated"); |
| } |
| |
| class A {} |
| |
| class B implements A {} |
| |
| class C implements A {} |
| |
| class D implements B, C {} |
| |
| List<int> toConst(List<int> elements) => elements; // Argument is const. |
| List<int> toList(List<int> elements) => elements.toList(); |
| List<int> toUnmodifiable(List<int> elements) => |
| new List<int>.unmodifiable(elements); |
| Set<int> toSet(List<int> elements) => elements.toSet(); |
| Queue<int> toQueue(List<int> elements) => new Queue<int>.from(elements); |
| // Creates an efficient-length iterable. |
| Iterable<int> toELIter(List<int> elements) => elements.map<int>((x) => x); |
| // Creates a non-efficient-length iterable. |
| Iterable<int> toNEIter(List<int> elements) => elements.where((x) => true); |
| List<int> toTyped(List<int> elements) => new Int32List.fromList(elements); |
| Iterable<int> toKeys(List<int> elements) => |
| new Map<int, int>.fromIterables(elements, elements).keys; |
| Iterable<int> toValues(List<int> elements) => |
| new Map<int, int>.fromIterables(elements, elements).values; |