| // 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()); | 
 | } |