// Copyright (c) 2019, 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 'package:expect/expect.dart'; import 'helper_classes.dart'; // Typed as dynamic to also test spreading a value of type dynamic. final dynamic list = [1, 2, 3, 4]; final dynamic map = {1: 1, 2: 2, 3: 3, 4: 4}; final dynamic set = {1, 2, 3, 4}; void main() { testList(); testMap(); testSet(); testDuplicateKeys(); testKeyOrder(); } void testList() { // Only spread. Expect.listEquals(list, [...list]); // Spread at beginning. Expect.listEquals(list, [...[1, 2], 3, 4]); // Spread in middle. Expect.listEquals(list, [1, ...[2, 3], 4]); // Spread at end. Expect.listEquals(list, [1, 2, ...[3, 4]]); // Empty spreads. Expect.listEquals(list, [...[], 1, 2, ...[], 3, 4, ...[]]); // Multiple spreads. Expect.listEquals(list, [...[1], 2, ...[3, 4]]); // Nested spreads. Expect.listEquals(list, [...[...[1, 2], ...[3, 4]]]); // Null-aware. var list23 = [2, 3] as List?; var list4 = [4] as List?; Expect.listEquals(list, [1, ...?list23, ...?(null), ...?list4]); // Does not deep flatten. var innerList = [3]; Expect.listEquals( [1, 2, innerList, 4], [1, ...[2, innerList, 4]]); // Downcast element from dynamic. Expect.listEquals(list, [...[1, 2, 3, 4]]); } void testMap() { // Only spread. Expect.mapEquals(map, {...map}); // Spread at beginning. Expect.mapEquals(map, {...{1: 1, 2: 2}, 3: 3, 4: 4}); // Spread in middle. Expect.mapEquals(map, {1: 1, ...{2: 2, 3: 3}, 4: 4}); // Spread at end. Expect.mapEquals(map, {1: 1, 2: 2, ...{3: 3, 4: 4}}); // Empty spreads. Expect.mapEquals(map, { ...{}, 1: 1, 2: 2, ...{}, 3: 3, 4: 4, ...{} }); // Multiple spreads. Expect.mapEquals(map, {...{1: 1}, 2: 2, ...{3: 3, 4: 4}}); // Nested spreads. Expect.mapEquals(map, { ...{ ...{1: 1, 2: 2}, ...{3: 3, 4: 4} } }); // Null-aware. var map23 = {2: 2, 3: 3} as Map?; var map4 = {4: 4} as Map?; Expect.mapEquals(map, { 1: 1, ...?map23, ...?(null), ...?map4 }); // Does not deep flatten. var innerMap = {3: 3}; Expect.mapEquals({ 1: 1, 2: 2, 3: innerMap, 4: 4 }, { 1: 1, ...{ 2: 2, 3: innerMap, 4: 4 } }); // Downcast element from dynamic. Expect.mapEquals( map, {...{1: 1, 2: 2, 3: 3, 4: 4}}); } void testSet() { // Only spread. Expect.setEquals(set, {...set}); // Spread at beginning. Expect.setEquals(set, {...[1, 2], 3, 4}); // Spread in middle. Expect.setEquals(set, {1, ...[2, 3], 4}); // Spread at end. Expect.setEquals(set, {1, 2, ...[3, 4]}); // Empty spreads. Expect.setEquals(set, {...[], 1, 2, ...[], 3, 4, ...[]}); // Multiple spreads. Expect.setEquals(set, {...[1], 2, ...[3, 4]}); // Nested spreads. Expect.setEquals(set, {...{...[1, 2], ...[3, 4]}}); // Null-aware. var list23 = [2, 3] as List?; var list4 = [4] as List?; Expect.setEquals(set, {1, ...?list23, ...?(null), ...?list4}); // Does not deep flatten. var innerSet = {3}; Expect.setEquals({1, 2, innerSet, 4}, {1, ...[2, innerSet, 4]}); // Downcast element from dynamic. Expect.setEquals(set, {...[1, 2, 3, 4]}); } void testDuplicateKeys() { Expect.mapEquals(map, { 1: 1, 2: 2, ...{2: 2, 3: 3, 4: 4}, ...{3: 3}, 4: 4 }); Expect.setEquals(set, {1, 2, ...[1, 2, 3, 4], ...[2, 3], 4}); } void testKeyOrder() { // First equal key wins. var e1a = Equality(1, "a"); var e1b = Equality(1, "b"); var e2a = Equality(2, "a"); var e2b = Equality(2, "b"); var map = {e1a: 1, ...{e1b: 2, e2a: 3, e2b: 4}}; Expect.equals("1:a,2:a", map.keys.join(",")); var set = {e1a, ...[e1b, e2a, e2b]}; Expect.equals("1:a,2:a", set.join(",")); // All elements are evaluated, left to right. var transcript = []; T log(T value) { transcript.add(value.toString()); return value; } map = { log(e1a): log(1), ...{log(e1b): log(2), log(e2a): log(3), log(e2b): log(4)} }; Expect.equals("1:a,1,1:b,2,2:a,3,2:b,4", transcript.join(",")); transcript.clear(); set = {log(e1a), ...[log(e1b), log(e2a), log(e2b)]}; Expect.equals("1:a,1:b,2:a,2:b", transcript.join(",")); }