// 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.

class ListTest {

  static testMain() {
    testList();
    testExpandableList();
  }

  static void expectValues(list, val1, val2, val3, val4) {
    Expect.equals(true, list.length == 4);
    Expect.equals(true, list.length == 4);
    Expect.equals(true, !list.isEmpty);
    Expect.equals(list[0], val1);
    Expect.equals(list[1], val2);
    Expect.equals(list[2], val3);
    Expect.equals(list[3], val4);
  }

  static void testClosures(List list) {
    testMap(val) {return val * 2 + 10; }
    List mapped = list.mappedBy(testMap).toList();
    Expect.equals(mapped.length, list.length);
    for (var i = 0; i < list.length; i++) {
      Expect.equals(mapped[i], list[i]*2 + 10);
    }

    testFilter(val) { return val == 3; }
    Iterable filtered = list.where(testFilter);
    Expect.equals(filtered.length, 1);

    testEvery(val) { return val != 11; }
    bool test = list.every(testEvery);
    Expect.equals(true, test);

    testSome(val) { return val == 1; }
    test = list.any(testSome);
    Expect.equals(true, test);

    testSomeFirst(val) { return val == 0; }
    test = list.any(testSomeFirst);
    Expect.equals(true, test);

    testSomeLast(val) { return val == (list.length - 1); }
    test = list.any(testSomeLast);
    Expect.equals(true, test);
  }

  static void testList() {
    List list = new List.fixedLength(4);
    Expect.equals(list.length, 4);
    list[0] = 4;
    expectValues(list, 4, null, null, null);
    String val = "fisk";
    list[1] = val;
    expectValues(list, 4, val, null, null);
    double d = 2.0;
    list[3] = d;
    expectValues(list, 4, val, null, d);

    for (int i = 0; i < list.length; i++) {
      list[i] = i;
    }

    for (int i = 0; i < 4; i++) {
      Expect.equals(i, list[i]);
      Expect.equals(i, list.indexOf(i));
      Expect.equals(i, list.lastIndexOf(i));
    }

    Expect.equals(-1, list.indexOf(100));
    Expect.equals(-1, list.lastIndexOf(100));
    list[2] = new Yes();
    Expect.equals(2, list.indexOf(100));
    Expect.equals(2, list.lastIndexOf(100));
    list[3] = new Yes();
    Expect.equals(2, list.indexOf(100));
    Expect.equals(3, list.lastIndexOf(100));
    list[2] = 2;
    Expect.equals(3, list.indexOf(100));
    Expect.equals(3, list.lastIndexOf(100));
    list[3] = 3;
    Expect.equals(-1, list.indexOf(100));
    Expect.equals(-1, list.lastIndexOf(100));

    testClosures(list);

    var exception = null;
    try {
      list.clear();
    } on UnsupportedError catch (e) {
      exception = e;
    }
    Expect.equals(true, exception != null);
  }

  static void testExpandableList() {
    List list = new List();
    Expect.equals(true, list.isEmpty);
    Expect.equals(list.length, 0);
    list.add(4);
    Expect.equals(1, list.length);
    Expect.equals(true, !list.isEmpty);
    Expect.equals(list.length, 1);
    Expect.equals(list.length, 1);
    Expect.equals(list.removeLast(), 4);

    for (int i = 0; i < 10; i++) {
      list.add(i);
    }

    Expect.equals(list.length, 10);
    for (int i = 0; i < 10; i++) {
      Expect.equals(i, list[i]);
      Expect.equals(i, list.indexOf(i));
      Expect.equals(i, list.lastIndexOf(i));
    }

    Expect.equals(-1, list.indexOf(100));
    Expect.equals(-1, list.lastIndexOf(100));
    list[2] = new Yes();
    Expect.equals(2, list.indexOf(100));
    Expect.equals(2, list.lastIndexOf(100));
    list[3] = new Yes();
    Expect.equals(2, list.indexOf(100));
    Expect.equals(3, list.lastIndexOf(100));
    list[2] = 2;
    Expect.equals(3, list.indexOf(100));
    Expect.equals(3, list.lastIndexOf(100));
    list[3] = 3;
    Expect.equals(-1, list.indexOf(100));
    Expect.equals(-1, list.lastIndexOf(100));

    testClosures(list);

    Expect.equals(list.removeLast(), 9);
    list.clear();
    Expect.equals(list.length, 0);
    Expect.equals(list.length, 0);
    Expect.equals(true, list.isEmpty);
  }
}

class Yes {
  operator ==(var other) => true;
}

main() {
  ListTest.testMain();
}
