// 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;
     }
     Collection 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.
     Collection 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;
    Collection k = map.keys;
    Expect.equals(2, k.length);
    Collection 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();
}
