// 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.
library linkedHashMap.test;
import 'dart:collection' show LinkedHashMap;

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>.fixedLength(5);
    List<int> values = new List<int>.fixedLength(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();
}
