// 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.
// A subtest of the larger MapTest. Will eliminate once the full
// test is running.

class MapTest {

  static void testDeletedElement(Map map) {
    map.clear();
    for (int i = 0; i < 100; i++) {
      map[1] = 2;
      Expect.equals(1, map.length);
      int x = map.remove(1);
      Expect.equals(2, x);
      Expect.equals(0, map.length);
    }
    Expect.equals(0, map.length);
    for (int i = 0; i < 100; i++) {
      map[i] = 2;
      Expect.equals(1, map.length);
      int x = map.remove(105);
      Expect.equals(null, x);
      Expect.equals(1, map.length);
      x = map.remove(i);
      Expect.equals(2, x);
      Expect.equals(0, map.length);
    }
    Expect.equals(0, map.length);
    map.remove(105);
  }

  static void test(Map map) {
    testDeletedElement(map);
    testMap(map, 1, 2, 3, 4, 5, 6, 7, 8);
    map.clear();
    testMap(map, "value1", "value2", "value3", "value4", "value5",
            "value6", "value7", "value8");
  }

  static void testMap(Map map, key1, key2, key3, key4, key5, key6, key7, key8) {
     int value1 = 10;
     int value2 = 20;
     int value3 = 30;
     int value4 = 40;
     int value5 = 50;
     int value6 = 60;
     int value7 = 70;
     int value8 = 80;

     Expect.equals(0, map.length);

     map[key1] = value1;
     Expect.equals(value1, map[key1]);
     map[key1] = value2;
     Expect.equals(false, map.containsKey(key2));
     Expect.equals(1, map.length);

     map[key1] = value1;
     Expect.equals(value1, map[key1]);
     // Add enough entries to make sure the table grows.
     map[key2] = value2;
     Expect.equals(value2, map[key2]);
     Expect.equals(2, map.length);
     map[key3] = value3;
     Expect.equals(value2, map[key2]);
     Expect.equals(value3, map[key3]);
     map[key4] = value4;
     Expect.equals(value3, map[key3]);
     Expect.equals(value4, map[key4]);
     map[key5] = value5;
     Expect.equals(value4, map[key4]);
     Expect.equals(value5, map[key5]);
     map[key6] = value6;
     Expect.equals(value5, map[key5]);
     Expect.equals(value6, map[key6]);
     map[key7] = value7;
     Expect.equals(value6, map[key6]);
     Expect.equals(value7, map[key7]);
     map[key8] = value8;
     Expect.equals(value1, map[key1]);
     Expect.equals(value2, map[key2]);
     Expect.equals(value3, map[key3]);
     Expect.equals(value4, map[key4]);
     Expect.equals(value5, map[key5]);
     Expect.equals(value6, map[key6]);
     Expect.equals(value7, map[key7]);
     Expect.equals(value8, map[key8]);
     Expect.equals(8, map.length);

     map.remove(key4);
     Expect.equals(false, map.containsKey(key4));
     Expect.equals(7, map.length);

     // Test clearing the table.
     map.clear();
     Expect.equals(0, map.length);
     Expect.equals(false, map.containsKey(key1));
     Expect.equals(false, map.containsKey(key2));
     Expect.equals(false, map.containsKey(key3));
     Expect.equals(false, map.containsKey(key4));
     Expect.equals(false, map.containsKey(key5));
     Expect.equals(false, map.containsKey(key6));
     Expect.equals(false, map.containsKey(key7));
     Expect.equals(false, map.containsKey(key8));

     // Test adding and removing again.
     map[key1] = value1;
     Expect.equals(value1, map[key1]);
     Expect.equals(1, map.length);
     map[key2] = value2;
     Expect.equals(value2, map[key2]);
     Expect.equals(2, map.length);
     map[key3] = value3;
     Expect.equals(value3, map[key3]);
     map.remove(key3);
     Expect.equals(2, map.length);
     map[key4] = value4;
     Expect.equals(value4, map[key4]);
     map.remove(key4);
     Expect.equals(2, map.length);
     map[key5] = value5;
     Expect.equals(value5, map[key5]);
     map.remove(key5);
     Expect.equals(2, map.length);
     map[key6] = value6;
     Expect.equals(value6, map[key6]);
     map.remove(key6);
     Expect.equals(2, map.length);
     map[key7] = value7;
     Expect.equals(value7, map[key7]);
     map.remove(key7);
     Expect.equals(2, map.length);
     map[key8] = value8;
     Expect.equals(value8, map[key8]);
     map.remove(key8);
     Expect.equals(2, map.length);

     Expect.equals(true, map.containsKey(key1));
     Expect.equals(true, map.containsValue(value1));

     // Test Map.forEach.
     Map other_map = new Map();
     void testForEachMap(key, value) {
       other_map[key] = value;
     }
     map.forEach(testForEachMap);
     Expect.equals(true, other_map.containsKey(key1));
     Expect.equals(true, other_map.containsKey(key2));
     Expect.equals(true, other_map.containsValue(value1));
     Expect.equals(true, other_map.containsValue(value2));
     Expect.equals(2, other_map.length);

     other_map.clear();
     Expect.equals(0, other_map.length);

     // Test Collection.keys.
     void testForEachCollection(value) {
       other_map[value] = value;
     }
     Iterable keys = map.keys;
     keys.forEach(testForEachCollection);
     Expect.equals(true, other_map.containsKey(key1));
     Expect.equals(true, other_map.containsKey(key2));
     Expect.equals(true, other_map.containsValue(key1));
     Expect.equals(true, other_map.containsValue(key2));
     Expect.equals(true, !other_map.containsKey(value1));
     Expect.equals(true, !other_map.containsKey(value2));
     Expect.equals(true, !other_map.containsValue(value1));
     Expect.equals(true, !other_map.containsValue(value2));
     Expect.equals(2, other_map.length);
     other_map.clear();
     Expect.equals(0, other_map.length);

     // Test Collection.values.
     Iterable values = map.values;
     values.forEach(testForEachCollection);
     Expect.equals(true, !other_map.containsKey(key1));
     Expect.equals(true, !other_map.containsKey(key2));
     Expect.equals(true, !other_map.containsValue(key1));
     Expect.equals(true, !other_map.containsValue(key2));
     Expect.equals(true, other_map.containsKey(value1));
     Expect.equals(true, other_map.containsKey(value2));
     Expect.equals(true, other_map.containsValue(value1));
     Expect.equals(true, other_map.containsValue(value2));
     Expect.equals(2, other_map.length);
     other_map.clear();
     Expect.equals(0, other_map.length);

     // Test Map.putIfAbsent.
     map.clear();
     Expect.equals(false, map.containsKey(key1));
     map.putIfAbsent(key1, () => 10);
     Expect.equals(true, map.containsKey(key1));
     Expect.equals(10, map[key1]);
     Expect.equals(10,
         map.putIfAbsent(key1, () => 11));
   }

  static testKeys(Map map) {
    map[1] = 101;
    map[2] = 102;
    Iterable k = map.keys;
    Expect.equals(2, k.length);
    Iterable v = map.values;
    Expect.equals(2, v.length);
    Expect.equals(true, map.containsValue(101));
    Expect.equals(true, map.containsValue(102));
    Expect.equals(false, map.containsValue(103));
  }

  static testMain() {
    test(new Map());
    testKeys(new Map());
  }
}


main() {
  MapTest.testMain();
}
