|  | // 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. | 
|  |  | 
|  | // Requirements=nnbd-weak | 
|  |  | 
|  | import "dart:collection"; | 
|  | import "package:expect/expect.dart"; | 
|  | import 'cast_helper.dart'; | 
|  |  | 
|  | void main() { | 
|  | testIterable(); | 
|  | testList(); | 
|  | testMap(); | 
|  | testSet(); | 
|  | } | 
|  |  | 
|  | testIterable() { | 
|  | var iterable = new Iterable<C?>.generate(elements.length, (n) => elements[n]); | 
|  | // Downcast non-nullable. | 
|  |  | 
|  | // An iterable that (likely) can do direct access. | 
|  | var dIterableDirect = Iterable.castFrom<C?, D>(iterable); | 
|  | Expect.equals(d, dIterableDirect.elementAt(1)); | 
|  | Expect.equals(null, dIterableDirect.skip(3).elementAt(1)); | 
|  |  | 
|  | // An iterable that cannot do direct access. | 
|  | var dIterableNonDirect = | 
|  | Iterable.castFrom<C?, D>(iterable.where((_) => true)); | 
|  | Expect.equals(d, dIterableNonDirect.elementAt(1)); | 
|  | Expect.equals(null, dIterableNonDirect.skip(3).elementAt(1)); | 
|  |  | 
|  | // Iterable that definitely won't survive accessing element 3. | 
|  | var iterableLimited = new Iterable<C?>.generate( | 
|  | elements.length, (n) => n == 3 ? throw "untouchable" : elements[n]); | 
|  | var dIterableLimited = Iterable.castFrom<C?, D>(iterableLimited); | 
|  | Expect.equals(d, dIterableLimited.elementAt(1)); | 
|  | Expect.equals(null, dIterableLimited.skip(3).elementAt(1)); | 
|  |  | 
|  | // Upcast non-nullable. | 
|  | var objectIterable = Iterable.castFrom<C?, Object>(iterable); | 
|  | Expect.equals(null, objectIterable.skip(3).elementAt(1)); | 
|  | } | 
|  |  | 
|  | testList() { | 
|  | var list = new List<C?>.from(elements); | 
|  |  | 
|  | // Downcast non-nullable. | 
|  | var dList = List.castFrom<C?, D>(list); | 
|  | Expect.equals(d, dList[1]); | 
|  | Expect.equals(null, dList.last); | 
|  |  | 
|  | // Upcast non-nullable. | 
|  | var objectList = List.castFrom<C?, Object>(list); | 
|  | Expect.equals(null, objectList.last); | 
|  | } | 
|  |  | 
|  | testMap() { | 
|  | var map = new Map.fromIterables(elements, elements); | 
|  |  | 
|  | // Downcast non-nullable. | 
|  | var dMap = Map.castFrom<C?, C?, D, D>(map); | 
|  | Expect.equals(d, dMap[d]); | 
|  | Expect.isTrue(dMap.containsKey(null)); | 
|  | Expect.equals(null, dMap[null]); | 
|  |  | 
|  | // Test keys and values | 
|  | Expect.isTrue(dMap.keys is Iterable<D>); | 
|  | Expect.isTrue(dMap.values is Iterable<D>); | 
|  | Expect.throws(() => dMap.keys.toList()); | 
|  | Expect.throws(() => dMap.values.toList()); | 
|  |  | 
|  | // Upcast non-nullable. | 
|  | var objectMap = Map.castFrom<C?, C?, Object, Object>(map); | 
|  | Expect.isTrue(objectMap.containsKey(null)); | 
|  | Expect.equals(null, objectMap[null]); | 
|  |  | 
|  | // Test keys and values | 
|  | Expect.isTrue(objectMap.keys is Iterable<Object>); | 
|  | Expect.isTrue(objectMap.values is Iterable<Object>); | 
|  | var expectedValues = new List<Object>.from(elements); | 
|  | Expect.listEquals(expectedValues, objectMap.values.toList()); | 
|  | } | 
|  |  | 
|  | testSet() { | 
|  | var setEls = new Set<C?>.from(elements); | 
|  |  | 
|  | // Downcast non-nullable. | 
|  | var dSet = Set.castFrom<C?, D>(setEls); | 
|  | Expect.equals(d, dSet.elementAt(1)); | 
|  | Expect.equals(null, dSet.last); | 
|  |  | 
|  | // Upcast non-nullable. | 
|  | var objectSet = Set.castFrom<C?, Object>(setEls); | 
|  | Expect.equals(null, objectSet.last); | 
|  | } |