// Copyright (c) 2016, 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.

/// @assertion HashMap({bool equals(K key1, K key2), int hashCode(K key),
/// bool isValidKey(potentialKey) })
/// If [equals] is provided, it is used to compare the keys in the table with new
/// keys. Similar, if [hashCode] is provided, it is used to produce a hash
/// value for keys in order to place them in the hash table.
/// @description This test checks division-to-3-reminder hash code: in this case
/// there are only three hashes in the map: 0, 1 and 2.
/// @author iarkh@unipro.ru

import "../../../Utils/expect.dart";
import "dart:collection";

check(HashMap map, Map expected, List unexistent) {
  expected.forEach((key, value) {
    Expect.isTrue(map.containsKey(key));
    Expect.equals(value, map[key]);
  });
  for(int i = 0; i < unexistent.length; i++) {
    Expect.isFalse(map.containsKey(unexistent[i]));
    Expect.equals(null, map[unexistent[i]]);
  }
}

main() {
  HashMap map = new HashMap<int, int>(
      equals: (int key1, int key2) => key1 % 3 == key2 % 3,
      hashCode: (int e) => e % 3);

  map.putIfAbsent(0, () => 0);
  check(map, {0 : 0, 3 : 0, 6 : 0, 9 : 0}, [1, 2, 4, 5, 7, 8]);

  map.putIfAbsent(1, () => 1);
  check(map, {0 : 0, 1 : 1, 3 : 0, 4 : 1, 6 : 0, 7 : 1, 9 : 0}, [2, 5, 8]);

  map.putIfAbsent(2, () => 2);
  for (int i = 0; i <= 10; i++) {
    map.putIfAbsent(i, () => i);
    check(map,
        {0 : 0, 1 : 1, 2 : 2, 3 : 0, 4 : 1, 5 : 2, 6 : 0, 7 : 1, 8 : 2, 9 : 0},
        []);
  }

  map.putIfAbsent(2, () => 0);
  check(map,
      {0 : 0, 1 : 1, 2 : 2, 3 : 0, 4 : 1, 5 : 2, 6 : 0, 7 : 1, 8 : 2, 9 : 0},
      []);
}
