// 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 for linked hash-maps.

class LinkedHashMapTest {
  static void testMain() {
    Map map = new LinkedHashMap();
    map["a"] = 1;
    map["b"] = 2;
    map["c"] = 3;
    map["d"] = 4;
    map["e"] = 5;

    List<String> keys = new List<String>(5);
    List<int> values = new List<int>(5);

    int index;

    clear() {
      index = 0;
      for (int i = 0; i < keys.length; i++) {
        keys[i] = null;
        values[i] = null;
      }
    }

    verifyKeys(List<String> correctKeys) {
      for (int i = 0; i < correctKeys.length; i++) {
        Expect.equals(correctKeys[i], keys[i]);
      }
    }

    verifyValues(List<int> correctValues) {
      for (int i = 0; i < correctValues.length; i++) {
        Expect.equals(correctValues[i], values[i]);
      }
    }

    testForEachMap(Object key, Object value) {
      Expect.equals(map[key], value);
      keys[index] = key;
      values[index] = value;
      index++;
    }

    testForEachValue(Object v) {
      values[index++] = v;
    }

    testForEachKey(Object v) {
      keys[index++] = v;
    }

    final keysInOrder = const ["a", "b", "c", "d", "e"];
    final valuesInOrder = const [1, 2, 3, 4, 5];

    clear();
    map.forEach(testForEachMap);
    verifyKeys(keysInOrder);
    verifyValues(valuesInOrder);

    clear();
    map.keys.forEach(testForEachKey);
    verifyKeys(keysInOrder);

    clear();
    map.values.forEach(testForEachValue);
    verifyValues(valuesInOrder);

    // Remove and then insert.
    map.remove("b");
    map["b"] = 6;
    final keysAfterBMove = const ["a", "c", "d", "e", "b"];
    final valuesAfterBMove = const [1, 3, 4, 5, 6];


    clear();
    map.forEach(testForEachMap);
    verifyKeys(keysAfterBMove);
    verifyValues(valuesAfterBMove);

    clear();
    map.keys.forEach(testForEachKey);
    verifyKeys(keysAfterBMove);

    clear();
    map.values.forEach(testForEachValue);
    verifyValues(valuesAfterBMove);

    // Update.
    map["a"] = 0;
    final valuesAfterAUpdate = const [0, 3, 4, 5, 6];

    clear();
    map.forEach(testForEachMap);
    verifyKeys(keysAfterBMove);
    verifyValues(valuesAfterAUpdate);

    clear();
    map.keys.forEach(testForEachKey);
    verifyKeys(keysAfterBMove);

    clear();
    map.values.forEach(testForEachValue);
    verifyValues(valuesAfterAUpdate);
  }
}

main() {
  LinkedHashMapTest.testMain();
}
