| // Copyright (c) 2020, 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. |
| |
| import "dart:collection"; |
| import "package:expect/expect.dart"; |
| import 'cast_helper.dart'; |
| |
| void main() { |
| testDowncastDirectAccess(); |
| testDowncastNoDirectAccess(); |
| testDowncastUntouchableElements(); |
| testUpcast(); |
| } |
| |
| void testDowncastDirectAccess() { |
| var iterable = new Iterable<C?>.generate(elements.length, (n) => elements[n]); |
| |
| // An iterable that (likely) can do direct access. |
| var dIterable = Iterable.castFrom<C?, D?>(iterable); |
| |
| Expect.throws(() => dIterable.first); |
| Expect.equals(d, dIterable.elementAt(1)); |
| Expect.throws(() => dIterable.elementAt(2)); // E is not D? |
| Expect.equals(f, dIterable.skip(3).first); // Skip does not access element. |
| Expect.equals(null, dIterable.skip(3).elementAt(1)); |
| |
| Expect.throws(() => dIterable.toList()); |
| } |
| |
| void testDowncastNoDirectAccess() { |
| var iterable = new Iterable<C?>.generate(elements.length, (n) => elements[n]); |
| |
| // An iterable that cannot do direct access. |
| var dIterable = Iterable.castFrom<C?, D?>(iterable.where((_) => true)); |
| |
| Expect.throws(() => dIterable.first); |
| Expect.equals(d, dIterable.elementAt(1)); |
| // E is not D?. |
| Expect.throws(() => dIterable.elementAt(2)); |
| Expect.equals(f, dIterable.skip(3).first); // Skip does not access element. |
| Expect.equals(null, dIterable.skip(3).elementAt(1)); |
| |
| Expect.throws(() => dIterable.toList()); |
| } |
| |
| void testDowncastUntouchableElements() { |
| // Iterable that definitely won't survive accessing element 3. |
| var iterable = new Iterable<C?>.generate( |
| elements.length, (n) => n == 3 ? throw "untouchable" : elements[n]); |
| var dIterable = Iterable.castFrom<C?, D?>(iterable); |
| |
| Expect.throws(() => dIterable.first); |
| Expect.equals(d, dIterable.elementAt(1)); |
| Expect.throws(() => dIterable.elementAt(3)); |
| // Skip does not access element. |
| Expect.equals(null, dIterable.skip(4).first); |
| Expect.equals(null, dIterable.skip(3).elementAt(1)); |
| |
| Expect.throws(() => dIterable.toList()); |
| } |
| |
| void testUpcast() { |
| var iterable = new Iterable<C?>.generate(elements.length, (n) => elements[n]); |
| |
| var objectIterable = Iterable.castFrom<C?, Object?>(iterable); |
| Expect.listEquals(elements, objectIterable.toList()); |
| } |