| Index: test/codegen/corelib/iterable_reduce_test.dart | 
| diff --git a/test/codegen/corelib/iterable_reduce_test.dart b/test/codegen/corelib/iterable_reduce_test.dart | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..492ce9c6871937754d715094d977b0a5ebce43f2 | 
| --- /dev/null | 
| +++ b/test/codegen/corelib/iterable_reduce_test.dart | 
| @@ -0,0 +1,151 @@ | 
| +// Copyright (c) 2014, 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 'dart:collection'; | 
| +import 'dart:typed_data'; | 
| + | 
| +class MyList extends ListBase { | 
| +  List list; | 
| +  MyList(this.list); | 
| + | 
| +  get length => list.length; | 
| +  set length(val) { list.length = val; } | 
| + | 
| +  operator [](index) => list[index]; | 
| +  operator []=(index, val) => list[index] = val; | 
| +} | 
| + | 
| +id(x) => x; | 
| + | 
| +main() { | 
| +  // Test functionality. | 
| +  for (var iterable in [ | 
| +      const [1, 2, 3], | 
| +      [1, 2, 3], | 
| +      new List(3)..[0] = 1..[1] = 2..[2] = 3, | 
| +      {1: 1, 2: 2, 3: 3}.keys, | 
| +      {1: 1, 2: 2, 3: 3}.values, | 
| +      new Iterable.generate(3, (x) => x + 1), | 
| +      new List.generate(3, (x) => x + 1), | 
| +      [0, 1, 2, 3].where((x) => x > 0), | 
| +      [0, 1, 2].map((x) => x + 1), | 
| +      [[1, 2], [3]].expand(id), | 
| +      [3, 2, 1].reversed, | 
| +      [0, 1, 2, 3].skip(1), | 
| +      [1, 2, 3, 4].take(3), | 
| +      new Uint8List(3)..[0] = 1..[1] = 2..[2] = 3, | 
| +      (new HashMap()..[1] = 1..[2] = 2..[3] = 3).keys, | 
| +      (new HashMap()..[1] = 1..[2] = 2..[3] = 3).values, | 
| +      (new SplayTreeMap()..[1] = 0..[2] = 0..[3] = 0).keys, | 
| +      (new SplayTreeMap()..[0] = 1..[1] = 2..[2] = 3).values, | 
| +      new HashSet()..add(1)..add(2)..add(3), | 
| +      new LinkedHashSet()..add(1)..add(2)..add(3), | 
| +      new SplayTreeSet()..add(1)..add(2)..add(3), | 
| +      "\x01\x02\x03".codeUnits, | 
| +      "\x01\x02\x03".runes, | 
| +      new MyList([1, 2, 3]), | 
| +    ]) { | 
| +    int callCount = 0; | 
| +    var result = iterable.reduce((x, y) { callCount++;  return x + y; }); | 
| +    Expect.equals(6, result, "${iterable.runtimeType}"); | 
| +    Expect.equals(2, callCount); | 
| +  } | 
| + | 
| +  // Empty iterables not allowed. | 
| +  for (var iterable in [ | 
| +      const [], | 
| +      [], | 
| +      new List(0), | 
| +      {}.keys, | 
| +      {}.values, | 
| +      new Iterable.generate(0, (x) => x + 1), | 
| +      new List.generate(0, (x) => x + 1), | 
| +      [0, 1, 2, 3].where((x) => false), | 
| +      [].map((x) => x + 1), | 
| +      [[], []].expand(id), | 
| +      [].reversed, | 
| +      [0, 1, 2, 3].skip(4), | 
| +      [1, 2, 3, 4].take(0), | 
| +      new Uint8List(0), | 
| +      (new HashMap()).keys, | 
| +      (new HashMap()).values, | 
| +      (new SplayTreeMap()).keys, | 
| +      (new SplayTreeMap()).values, | 
| +      new HashSet(), | 
| +      new LinkedHashSet(), | 
| +      new SplayTreeSet(), | 
| +      "".codeUnits, | 
| +      "".runes, | 
| +      new MyList([]), | 
| +    ]) { | 
| +    Expect.throws(() { iterable.reduce((x, y) => throw "Unreachable"); }, | 
| +                  (e) => e is StateError); | 
| +  } | 
| + | 
| +  // Singleton iterables not calling reduce function. | 
| +  for (var iterable in [ | 
| +      const [1], | 
| +      [1], | 
| +      new List(1)..[0] = 1, | 
| +      {1: 1}.keys, | 
| +      {1: 1}.values, | 
| +      new Iterable.generate(1, (x) => x + 1), | 
| +      new List.generate(1, (x) => x + 1), | 
| +      [0, 1, 2, 3].where((x) => x == 1), | 
| +      [0].map((x) => x + 1), | 
| +      [[], [1]].expand(id), | 
| +      [1].reversed, | 
| +      [0, 1].skip(1), | 
| +      [1, 2, 3, 4].take(1), | 
| +      new Uint8List(1)..[0] = 1, | 
| +      (new HashMap()..[1] = 0).keys, | 
| +      (new HashMap()..[0] = 1).values, | 
| +      (new SplayTreeMap()..[1] = 0).keys, | 
| +      (new SplayTreeMap()..[0] = 1).values, | 
| +      new HashSet()..add(1), | 
| +      new LinkedHashSet()..add(1), | 
| +      new SplayTreeSet()..add(1), | 
| +      "\x01".codeUnits, | 
| +      "\x01".runes, | 
| +      new MyList([1]), | 
| +    ]) { | 
| +    Expect.equals(1, iterable.reduce((x, y) => throw "Unreachable")); | 
| +  } | 
| + | 
| +  // Concurrent modifications not allowed. | 
| +  testModification(base, modify, transform) { | 
| +    var iterable = transform(base); | 
| +    Expect.throws(() { | 
| +      iterable.reduce((x, y) { | 
| +        modify(base); | 
| +        return x + y; | 
| +      }); | 
| +    }, (e) => e is ConcurrentModificationError); | 
| +  } | 
| + | 
| +  void add4(collection) { collection.add(4); } | 
| +  void put4(map) { map[4] = 4; } | 
| + | 
| +  testModification([1, 2, 3], add4, id); | 
| +  testModification(new HashSet()..add(1)..add(2)..add(3), add4, id); | 
| +  testModification(new LinkedHashSet()..add(1)..add(2)..add(3), add4, id); | 
| +  testModification(new SplayTreeSet()..add(1)..add(2)..add(3), add4, id); | 
| +  testModification(new MyList([1, 2, 3]), add4, id); | 
| + | 
| +  testModification([0, 1, 2, 3], add4, (x) => x.where((x) => x > 0)); | 
| +  testModification([0, 1, 2], add4, (x) => x.map((x) => x + 1)); | 
| +  testModification([[1, 2], [3]], add4, (x) => x.expand((x) => x)); | 
| +  testModification([3, 2, 1], add4, (x) => x.reversed); | 
| +  testModification({1: 1, 2: 2, 3: 3}, put4, (x) => x.keys); | 
| +  testModification({1: 1, 2: 2, 3: 3}, put4, (x) => x.values); | 
| +  var hashMap = new HashMap()..[1] = 1..[2] = 2..[3] = 3; | 
| +  testModification(hashMap, put4, (x) => x.keys); | 
| +  hashMap = new HashMap()..[1] = 1..[2] = 2..[3] = 3; | 
| +  testModification(hashMap, put4, (x) => x.values); | 
| +  var splayMap = new SplayTreeMap()..[1] = 1..[2] = 2..[3] = 3; | 
| +  testModification(splayMap, put4, (x) => x.keys); | 
| +  splayMap = new SplayTreeMap()..[1] = 1..[2] = 2..[3] = 3; | 
| +  testModification(splayMap, put4, (x) => x.values); | 
| +} | 
|  |