// Copyright (c) 2011, 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.
// Dart test program for testing arrays.

import "package:expect/expect.dart";

class A { }
class B { }

class ListTest {
  static void TestIterator() {
    List<int> a = new List<int>(10);
    int count = 0;

    // Basic iteration over ObjectList.
    for (int elem in a) {
      Expect.equals(null, elem);
      count++;
    }
    Expect.equals(10, count);

    // List length is 0.
    List<int> fa = new List<int>();
    count = 0;
    for (int elem in fa) {
      count++;
    }
    Expect.equals(0, count);

    // Iterate over ImmutableList.
    List<int> ca = const [0, 1, 2, 3, 4, 5];
    int sum = 0;
    for (int elem in ca) {
      sum += elem;
      fa.add(elem);
    }
    Expect.equals(15, sum);

    // Iterate over List.
    int sum2 = 0;
    for (int elem in fa) {
      sum2 += elem;
    }
    Expect.equals(sum, sum2);
  }

  static void testSublistTypeArguments() {
    final list1 = new List<A>(0).sublist(0);
    Expect.isTrue(list1 is List<A>);
    Expect.isTrue(list1 is! List<B>);

    final list2 = new List<A>(0).toList(growable: false);
    Expect.isTrue(list2 is List<A>);
    Expect.isTrue(list2 is! List<B>);
  }

  static void testMain() {
    int len = 10;
    List a = new List(len);
    Expect.equals(true, a is List);
    Expect.equals(len, a.length);
    a.forEach((element) { Expect.equals(null, element); });
    a[1] = 1;
    Expect.equals(1, a[1]);
    Expect.throws(() => a[len], (e) => e is RangeError);

    Expect.throws(() {
      List a = new List(4);
      a.setRange(1, 2, a, null);
    });

    Expect.throws(() {
      List a = new List(4);
      a.setRange(1, 2, const [1, 2, 3, 4], null);
    });

    Expect.throws(() {
      List a = new List(4);
      a.setRange(10, 11, a, 1);
    }, (e) => e is RangeError);

    a = new List(4);
    List b = new List(4);
    b.setRange(0, 4, a, 0);

    List<int> unsorted = [4, 3, 9, 12, -4, 9];
    int compare(a, b) {
      if (a < b) return -1;
      if (a > b) return 1;
      return 0;
    }
    unsorted.sort(compare);
    Expect.equals(6, unsorted.length);
    Expect.equals(-4, unsorted[0]);
    Expect.equals(12, unsorted[unsorted.length - 1]);
    int compare2(a, b) {
      if (a < b) return 1;
      if (a > b) return -1;
      return 0;
    }
    unsorted.sort(compare2);
    Expect.equals(12, unsorted[0]);
    Expect.equals(-4, unsorted[unsorted.length - 1]);
    Set<int> t = new Set<int>.from(unsorted);
    Expect.equals(true, t.contains(9));
    Expect.equals(true, t.contains(-4));
    Expect.equals(false, t.contains(-3));
    Expect.equals(6, unsorted.length);
    Expect.equals(5, t.length);
    TestIterator();
    int element = unsorted[2];
    Expect.equals(9, element);

    Expect.throws(() => unsorted[2.1],
                  (e) => e is ArgumentError || e is TypeError);

    Expect.throws(() => new List(-1));
    Expect.throws(() => new List(99999999999999999999999));

    List list = new List();
    // We cannot write just 'list.removeLast' due to issue 3769.
    Expect.throws(() => list.removeLast(),
                  (e) => e is RangeError);
    Expect.equals(0, list.length);
  }
}

main() {
  ListTest.testMain();
  ListTest.testSublistTypeArguments();
}
