// 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 = 2.9

library map_test;

import "package:expect/expect.dart";
import 'dart:collection';
import 'dart:convert' show json;

Map<String, dynamic> newJsonMap() => json.decode('{}');
Map<String, dynamic> newJsonMapCustomReviver() =>
    json.decode('{}', reviver: (key, value) => value);

void main() {
  test(new HashMap());
  test(new LinkedHashMap());
  test(new SplayTreeMap());
  test(new SplayTreeMap(Comparable.compare));
  test(new MapView(new HashMap()));
  test(new MapView(new SplayTreeMap()));
  test(new MapBaseMap());
  test(new MapMixinMap());
  test(newJsonMap());
  test(newJsonMapCustomReviver());
  testLinkedHashMap();
  testMapLiteral();
  testNullValue();
  testTypes();
  testUnmodifiableMaps();

  testWeirdStringKeys(new Map());
  testWeirdStringKeys(new Map<String, String>());
  testWeirdStringKeys(new HashMap());
  testWeirdStringKeys(new HashMap<String, String>());
  testWeirdStringKeys(new LinkedHashMap());
  testWeirdStringKeys(new LinkedHashMap<String, String>());
  testWeirdStringKeys(new SplayTreeMap());
  testWeirdStringKeys(new SplayTreeMap<String, String>());
  testWeirdStringKeys(new MapBaseMap<String, String>());
  testWeirdStringKeys(new MapMixinMap<String, String>());
  testWeirdStringKeys(newJsonMap());
  testWeirdStringKeys(newJsonMapCustomReviver());

  testNumericKeys(new Map());
  testNumericKeys(new Map<num, String>());
  testNumericKeys(new HashMap());
  testNumericKeys(new HashMap<num, String>());
  testNumericKeys(new HashMap.identity());
  testNumericKeys(new HashMap<num, String>.identity());
  testNumericKeys(new LinkedHashMap());
  testNumericKeys(new LinkedHashMap<num, String>());
  testNumericKeys(new LinkedHashMap.identity());
  testNumericKeys(new LinkedHashMap<num, String>.identity());
  testNumericKeys(new MapBaseMap<num, String>());
  testNumericKeys(new MapMixinMap<num, String>());

  testNaNKeys(new Map());
  testNaNKeys(new Map<num, String>());
  testNaNKeys(new HashMap());
  testNaNKeys(new HashMap<num, String>());
  testNaNKeys(new LinkedHashMap());
  testNaNKeys(new LinkedHashMap<num, String>());
  testNaNKeys(new MapBaseMap<num, String>());
  testNaNKeys(new MapMixinMap<num, String>());
  // Identity maps fail the NaN-keys tests because the test assumes that
  // NaN is not equal to NaN.

  testIdentityMap(new Map.identity());
  testIdentityMap(new HashMap.identity());
  testIdentityMap(new LinkedHashMap.identity());
  testIdentityMap(new HashMap(equals: identical, hashCode: identityHashCode));
  testIdentityMap(
      new LinkedHashMap(equals: identical, hashCode: identityHashCode));
  testIdentityMap(new HashMap(
      equals: (x, y) => identical(x, y), hashCode: (x) => identityHashCode(x)));
  testIdentityMap(new LinkedHashMap(
      equals: (x, y) => identical(x, y), hashCode: (x) => identityHashCode(x)));

  testCustomMap(new HashMap(
      equals: myEquals,
      hashCode: myHashCode,
      isValidKey: (v) => v is Customer));
  testCustomMap(new LinkedHashMap(
      equals: myEquals,
      hashCode: myHashCode,
      isValidKey: (v) => v is Customer));
  testCustomMap(
      new HashMap<Customer, dynamic>(equals: myEquals, hashCode: myHashCode));

  testCustomMap(new LinkedHashMap<Customer, dynamic>(
      equals: myEquals, hashCode: myHashCode));

  testIterationOrder(new LinkedHashMap());
  testIterationOrder(new LinkedHashMap.identity());
  testIterationOrder(newJsonMap());
  testIterationOrder(newJsonMapCustomReviver());

  testOtherKeys(new SplayTreeMap<int, int>());
  testOtherKeys(
      new SplayTreeMap<int, int>((int a, int b) => a - b, (v) => v is int));
  testOtherKeys(new SplayTreeMap((int a, int b) => a - b, (v) => v is int));
  testOtherKeys(new HashMap<int, int>());
  testOtherKeys(new HashMap<int, int>.identity());
  testOtherKeys(new HashMap<int, int>(
      hashCode: (v) => v.hashCode, isValidKey: (v) => v is int));
  testOtherKeys(new HashMap(
      equals: (int x, int y) => x == y,
      hashCode: (int v) => v.hashCode,
      isValidKey: (v) => v is int));
  testOtherKeys(new LinkedHashMap<int, int>());
  testOtherKeys(new LinkedHashMap<int, int>.identity());
  testOtherKeys(new LinkedHashMap<int, int>(
      hashCode: (v) => v.hashCode, isValidKey: (v) => v is int));
  testOtherKeys(new LinkedHashMap(
      equals: (int x, int y) => x == y,
      hashCode: (int v) => v.hashCode,
      isValidKey: (v) => v is int));
  testOtherKeys(new MapBaseMap<int, int>());
  testOtherKeys(new MapMixinMap<int, int>());

  testUnmodifiableMap(const {1: 37});
  testUnmodifiableMap(new UnmodifiableMapView({1: 37}));
  testUnmodifiableMap(new UnmodifiableMapBaseMap([1, 37]));

  testTypeAnnotations(new HashMap());
  testTypeAnnotations(new LinkedHashMap());
  testTypeAnnotations(new HashMap(equals: identical));
  testTypeAnnotations(new LinkedHashMap(equals: identical));
  testTypeAnnotations(new HashMap(
      equals: (int a, int b) => a == b,
      hashCode: (int a) => a.hashCode,
      isValidKey: (a) => a is int));
  testTypeAnnotations(new LinkedHashMap(
      equals: (int a, int b) => a == b,
      hashCode: (int a) => a.hashCode,
      isValidKey: (a) => a is int));

  testFrom();
}

void test<K, V>(Map<K, V> map) {
  testDeletedElement(map);
  if (map is Map<int, dynamic>) {
    testMap(map, 1, 2, 3, 4, 5, 6, 7, 8);
  } else {
    map.clear();
    testMap(map, "value1", "value2", "value3", "value4", "value5", "value6",
        "value7", "value8");
  }
}

void testLinkedHashMap() {
  LinkedHashMap map = new LinkedHashMap();
  Expect.isFalse(map.containsKey(1));
  map[1] = 1;
  map[1] = 2;
  testLength(1, map);
}

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

  testLength(0, map);

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

  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]);
  testLength(2, map);
  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]);
  testLength(8, map);

  map.remove(key4);
  Expect.isFalse(map.containsKey(key4));
  testLength(7, map);

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

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

  Expect.isTrue(map.containsKey(key1));
  Expect.isTrue(map.containsValue(value1));

  // Test Map.forEach.
  Map otherMap = new Map<K, V>();
  void testForEachMap(key, value) {
    otherMap[key] = value;
  }

  map.forEach(testForEachMap);
  Expect.isTrue(otherMap.containsKey(key1));
  Expect.isTrue(otherMap.containsKey(key2));
  Expect.isTrue(otherMap.containsValue(value1));
  Expect.isTrue(otherMap.containsValue(value2));
  Expect.equals(2, otherMap.length);

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

  // Test Collection.keys.
  void testForEachKey(key) {
    otherMap[key] = null;
  }

  Iterable keys = map.keys;
  keys.forEach(testForEachKey);
  Expect.isTrue(otherMap.containsKey(key1));
  Expect.isTrue(otherMap.containsKey(key2));
  Expect.isFalse(otherMap.containsKey(value1));
  Expect.isFalse(otherMap.containsKey(value2));

  Expect.isTrue(otherMap.containsValue(null));
  Expect.isFalse(otherMap.containsValue(value1));
  Expect.isFalse(otherMap.containsValue(value2));
  Expect.equals(2, otherMap.length);
  otherMap.clear();
  Expect.equals(0, otherMap.length);

  // Test Collection.values.
  void testForEachValue(value) {
    if (value == value1) {
      otherMap[key1] = value;
    } else if (value == value2) {
      otherMap[key2] = value;
    } else {
      otherMap[key3] = null;
    }
  }

  Iterable values = map.values;
  values.forEach(testForEachValue);
  Expect.isTrue(otherMap.containsKey(key1));
  Expect.isTrue(otherMap.containsKey(key2));
  Expect.isFalse(otherMap.containsKey(value1));
  Expect.isFalse(otherMap.containsKey(value2));

  Expect.isTrue(otherMap.containsValue(value1));
  Expect.isTrue(otherMap.containsValue(value2));
  Expect.isFalse(otherMap.containsValue(value3));
  Expect.isFalse(otherMap.containsValue(key1));
  Expect.isFalse(otherMap.containsValue(null));
  Expect.equals(2, otherMap.length);
  otherMap.clear();
  Expect.equals(0, otherMap.length);

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

  // Test Map.addAll.
  map.clear();
  otherMap.clear();
  otherMap['99'] = 1;
  otherMap['50'] = 50;
  otherMap['1'] = 99;
  map.addAll(otherMap);
  Expect.equals(3, map.length);
  Expect.equals(1, map['99']);
  Expect.equals(50, map['50']);
  Expect.equals(99, map['1']);
  otherMap['50'] = 42;
  map.addAll(new HashMap<K, V>.from(otherMap));
  Expect.equals(3, map.length);
  Expect.equals(1, map['99']);
  Expect.equals(42, map['50']);
  Expect.equals(99, map['1']);
  otherMap['99'] = 7;
  map.addAll(new SplayTreeMap<K, V>.from(otherMap));
  Expect.equals(3, map.length);
  Expect.equals(7, map['99']);
  Expect.equals(42, map['50']);
  Expect.equals(99, map['1']);
  otherMap.remove('99');
  map['99'] = 0;
  map.addAll(otherMap);
  Expect.equals(3, map.length);
  Expect.equals(0, map['99']);
  Expect.equals(42, map['50']);
  Expect.equals(99, map['1']);
  map.clear();
  otherMap.clear();
  map.addAll(otherMap);
  Expect.equals(0, map.length);
}

void testDeletedElement(Map map) {
  map.clear();
  for (int i = 0; i < 100; i++) {
    map['1'] = 2;
    testLength(1, map);
    map.remove('1');
    testLength(0, map);
  }
  testLength(0, map);
}

void testMapLiteral() {
  Map m = {"a": 1, "b": 2, "c": 3};
  Expect.equals(3, m.length);
  int sum = 0;
  m.forEach((a, b) {
    sum += b;
  });
  Expect.equals(6, sum);

  List values = m.keys.toList();
  Expect.equals(3, values.length);
  String first = values[0];
  String second = values[1];
  String third = values[2];
  String all = "${first}${second}${third}";
  Expect.equals(3, all.length);
  Expect.isTrue(all.contains("a", 0));
  Expect.isTrue(all.contains("b", 0));
  Expect.isTrue(all.contains("c", 0));
}

void testNullValue() {
  Map m = {"a": 1, "b": null, "c": 3};

  Expect.equals(null, m["b"]);
  Expect.isTrue(m.containsKey("b"));
  Expect.equals(3, m.length);

  m["a"] = null;
  m["c"] = null;
  Expect.equals(null, m["a"]);
  Expect.isTrue(m.containsKey("a"));
  Expect.equals(null, m["c"]);
  Expect.isTrue(m.containsKey("c"));
  Expect.equals(3, m.length);

  m.remove("a");
  Expect.equals(2, m.length);
  Expect.equals(null, m["a"]);
  Expect.isFalse(m.containsKey("a"));
}

void testTypes() {
  testMap(Map<num, String> map) {
    Expect.isTrue(map is Map<num, String>);
    Expect.isTrue(map is! Map<String, dynamic>);
    Expect.isTrue(map is! Map<dynamic, int>);

    // Use with properly typed keys and values.
    map[42] = "text1";
    map[43] = "text2";
    map[42] = "text3";
    Expect.equals("text3", map.remove(42));
    Expect.equals(null, map[42]);
    map[42] = "text4";

    // Ensure that "containsKey", "containsValue" and "remove"
    // accepts any object.
    for (var object in [true, null, new Object()]) {
      Expect.isFalse(map.containsKey(object));
      Expect.isFalse(map.containsValue(object));
      Expect.isNull(map.remove(object));
      Expect.isNull(map[object]);
    }
  }

  testMap(new HashMap<int, String>());
  testMap(new LinkedHashMap<int, String>());
  testMap(new SplayTreeMap<int, String>());
  testMap(new SplayTreeMap<int, String>(Comparable.compare));
  testMap(new SplayTreeMap<int, String>((int a, int b) => a.compareTo(b)));
  testMap(new HashMap<num, String>());
  testMap(new LinkedHashMap<num, String>());
  testMap(new SplayTreeMap<num, String>());
  testMap(new SplayTreeMap<num, String>(Comparable.compare));
  testMap(new SplayTreeMap<num, String>((num a, num b) => a.compareTo(b)));
}

void testWeirdStringKeys(Map map) {
  // Test weird keys.
  var weirdKeys = const [
    'hasOwnProperty',
    'constructor',
    'toLocaleString',
    'propertyIsEnumerable',
    '__defineGetter__',
    '__defineSetter__',
    '__lookupGetter__',
    '__lookupSetter__',
    'isPrototypeOf',
    'toString',
    'valueOf',
    '__proto__',
    '__count__',
    '__parent__',
    ''
  ];
  Expect.isTrue(map.isEmpty);
  for (var key in weirdKeys) {
    Expect.isFalse(map.containsKey(key));
    Expect.equals(null, map[key]);
    var value = 'value:$key';
    map[key] = value;
    Expect.isTrue(map.containsKey(key));
    Expect.equals(value, map[key]);
    Expect.equals(value, map.remove(key));
    Expect.isFalse(map.containsKey(key));
    Expect.equals(null, map[key]);
  }
  Expect.isTrue(map.isEmpty);
}

void testNumericKeys(Map map) {
  var numericKeys = const [
    double.infinity,
    double.negativeInfinity,
    0,
    0.0,
    -0.0
  ];

  Expect.isTrue(map.isEmpty);
  for (var key in numericKeys) {
    Expect.isFalse(map.containsKey(key));
    Expect.equals(null, map[key]);
    var value = 'value:$key';
    map[key] = value;
    Expect.isTrue(map.containsKey(key));
    Expect.equals(value, map[key]);
    Expect.equals(value, map.remove(key));
    Expect.isFalse(map.containsKey(key));
    Expect.equals(null, map[key]);
  }
  Expect.isTrue(map.isEmpty);
}

void testNaNKeys(Map map) {
  Object nan = double.nan;
  // Skip this test on platforms that use native-JS NaN semantics for speed.
  if (!identical(nan, nan)) return;

  Expect.isTrue(map.isEmpty);
  // Test NaN.
  Expect.isFalse(map.containsKey(nan));
  Expect.equals(null, map[nan]);

  map[nan] = 'value:0';
  Expect.isFalse(map.containsKey(nan));
  Expect.equals(null, map[nan]);
  testLength(1, map);

  map[nan] = 'value:1';
  Expect.isFalse(map.containsKey(nan));
  Expect.equals(null, map[nan]);
  testLength(2, map);

  Expect.equals(null, map.remove(nan));
  testLength(2, map);

  var count = 0;
  map.forEach((key, value) {
    if (key.isNaN) count++;
  });
  Expect.equals(2, count);

  map.clear();
  Expect.isTrue(map.isEmpty);
}

void testLength(int length, Map map) {
  Expect.equals(length, map.length);
  Expect.equals(length, map.keys.length);
  Expect.equals(length, map.values.length);
  // Check being-empty.
  var ifEmpty = (length == 0) ? Expect.isTrue : Expect.isFalse;
  var ifNotEmpty = (length != 0) ? Expect.isTrue : Expect.isFalse;
  ifEmpty(map.isEmpty);
  ifNotEmpty(map.isNotEmpty);
  ifEmpty(map.keys.isEmpty);
  ifNotEmpty(map.keys.isNotEmpty);
  ifEmpty(map.values.isEmpty);
  ifNotEmpty(map.values.isNotEmpty);
  // Test key/value iterators match their isEmpty/isNotEmpty.
  ifNotEmpty(map.keys.iterator.moveNext());
  ifNotEmpty(map.values.iterator.moveNext());
  if (length == 0) {
    for (var k in map.keys) Expect.fail("contains key when iterating: $k");
    for (var v in map.values) Expect.fail("contains values when iterating: $v");
  }
}

testIdentityMap<K, V>(Map<K, V> typedMap) {
  Map map = typedMap;
  Expect.isTrue(map.isEmpty);

  var nan = double.nan;
  // TODO(11551): Remove guard when dart2js makes identical(NaN, NaN) true.
  if (identical(nan, nan)) {
    map[nan] = 42;
    testLength(1, map);
    Expect.isTrue(map.containsKey(nan));
    Expect.equals(42, map[nan]);
    map[nan] = 37;
    testLength(1, map);
    Expect.equals(37, map[nan]);
    Expect.equals(37, map.remove(nan));
    testLength(0, map);
  }

  Vampire v1 = const Vampire(1);
  Vampire v2 = const Vampire(2);
  Expect.isFalse(v1 == v1);
  Expect.isFalse(v2 == v2);
  Expect.isTrue(v2 == v1); // Snob!

  map[v1] = 1;
  map[v2] = 2;
  testLength(2, map);

  Expect.isTrue(map.containsKey(v1));
  Expect.isTrue(map.containsKey(v2));

  Expect.equals(1, map[v1]);
  Expect.equals(2, map[v2]);

  Expect.equals(1, map.remove(v1));
  testLength(1, map);
  Expect.isFalse(map.containsKey(v1));
  Expect.isTrue(map.containsKey(v2));

  Expect.isNull(map.remove(v1));
  Expect.equals(2, map.remove(v2));
  testLength(0, map);

  var eq01 = new Equalizer(0);
  var eq02 = new Equalizer(0);
  var eq11 = new Equalizer(1);
  var eq12 = new Equalizer(1);
  // Sanity.
  Expect.equals(eq01, eq02);
  Expect.equals(eq02, eq01);
  Expect.equals(eq11, eq12);
  Expect.equals(eq12, eq11);
  Expect.notEquals(eq01, eq11);
  Expect.notEquals(eq01, eq12);
  Expect.notEquals(eq02, eq11);
  Expect.notEquals(eq02, eq12);
  Expect.notEquals(eq11, eq01);
  Expect.notEquals(eq11, eq02);
  Expect.notEquals(eq12, eq01);
  Expect.notEquals(eq12, eq02);

  map[eq01] = 0;
  map[eq02] = 1;
  map[eq11] = 2;
  map[eq12] = 3;
  testLength(4, map);

  Expect.equals(0, map[eq01]);
  Expect.equals(1, map[eq02]);
  Expect.equals(2, map[eq11]);
  Expect.equals(3, map[eq12]);

  Expect.isTrue(map.containsKey(eq01));
  Expect.isTrue(map.containsKey(eq02));
  Expect.isTrue(map.containsKey(eq11));
  Expect.isTrue(map.containsKey(eq12));

  Expect.equals(1, map.remove(eq02));
  Expect.equals(3, map.remove(eq12));
  testLength(2, map);
  Expect.isTrue(map.containsKey(eq01));
  Expect.isFalse(map.containsKey(eq02));
  Expect.isTrue(map.containsKey(eq11));
  Expect.isFalse(map.containsKey(eq12));

  Expect.equals(0, map[eq01]);
  Expect.equals(null, map[eq02]);
  Expect.equals(2, map[eq11]);
  Expect.equals(null, map[eq12]);

  Expect.equals(0, map.remove(eq01));
  Expect.equals(2, map.remove(eq11));
  testLength(0, map);

  map[eq01] = 0;
  map[eq02] = 1;
  map[eq11] = 2;
  map[eq12] = 3;
  testLength(4, map);

  // Transfer to equality-based map will collapse elements.
  Map eqMap = new HashMap<K, V>();
  eqMap.addAll(map);
  testLength(2, eqMap);
  Expect.isTrue(eqMap.containsKey(eq01));
  Expect.isTrue(eqMap.containsKey(eq02));
  Expect.isTrue(eqMap.containsKey(eq11));
  Expect.isTrue(eqMap.containsKey(eq12));

  // Changing objects will not affect identity map.
  map.clear();
  var m1 = new Mutable(1);
  var m2 = new Mutable(2);
  var m3 = new Mutable(3);
  map[m1] = 1;
  map[m2] = 2;
  map[m3] = 3;
  Expect.equals(3, map.length);
  Expect.isTrue(map.containsKey(m1));
  Expect.isTrue(map.containsKey(m2));
  Expect.isTrue(map.containsKey(m3));
  Expect.notEquals(m1, m3);
  m3.id = 1;
  Expect.equals(m1, m3);
  // Even if keys are equal, they are still not identical.
  // Even if hashcode of m3 changed, it can still be found.
  Expect.equals(1, map[m1]);
  Expect.equals(3, map[m3]);
}

/** Class of objects that are equal if they hold the same id. */
class Equalizer {
  int id;
  Equalizer(this.id);
  int get hashCode => id;
  bool operator ==(Object other) => other is Equalizer && id == other.id;
}

/**
 * Objects that are not reflexive.
 *
 * They think they are better than their equals.
 */
class Vampire {
  final int generation;
  const Vampire(this.generation);

  int get hashCode => generation;

  // The double-fang operator falsely claims that a vampire is equal to
  // any of its sire's generation.
  bool operator ==(Object other) =>
      other is Vampire && generation - 1 == other.generation;
}

void testCustomMap<K, V>(Map<K, V> typedMap) {
  Map map = typedMap;
  testLength(0, map);
  var c11 = const Customer(1, 1);
  var c12 = const Customer(1, 2);
  var c21 = const Customer(2, 1);
  var c22 = const Customer(2, 2);
  // Sanity.
  Expect.equals(c11, c12);
  Expect.notEquals(c11, c21);
  Expect.notEquals(c11, c22);
  Expect.equals(c21, c22);
  Expect.notEquals(c21, c11);
  Expect.notEquals(c21, c12);

  Expect.isTrue(myEquals(c11, c21));
  Expect.isFalse(myEquals(c11, c12));
  Expect.isFalse(myEquals(c11, c22));
  Expect.isTrue(myEquals(c12, c22));
  Expect.isFalse(myEquals(c12, c11));
  Expect.isFalse(myEquals(c12, c21));

  map[c11] = 42;
  testLength(1, map);
  Expect.isTrue(map.containsKey(c11));
  Expect.isTrue(map.containsKey(c21));
  Expect.isFalse(map.containsKey(c12));
  Expect.isFalse(map.containsKey(c22));
  Expect.equals(42, map[c11]);
  Expect.equals(42, map[c21]);

  map[c21] = 37;
  testLength(1, map);
  Expect.isTrue(map.containsKey(c11));
  Expect.isTrue(map.containsKey(c21));
  Expect.isFalse(map.containsKey(c12));
  Expect.isFalse(map.containsKey(c22));
  Expect.equals(37, map[c11]);
  Expect.equals(37, map[c21]);

  map[c22] = 42;
  testLength(2, map);
  Expect.isTrue(map.containsKey(c11));
  Expect.isTrue(map.containsKey(c21));
  Expect.isTrue(map.containsKey(c12));
  Expect.isTrue(map.containsKey(c22));
  Expect.equals(37, map[c11]);
  Expect.equals(37, map[c21]);
  Expect.equals(42, map[c12]);
  Expect.equals(42, map[c22]);

  Expect.equals(42, map.remove(c12));
  testLength(1, map);
  Expect.isTrue(map.containsKey(c11));
  Expect.isTrue(map.containsKey(c21));
  Expect.isFalse(map.containsKey(c12));
  Expect.isFalse(map.containsKey(c22));
  Expect.equals(37, map[c11]);
  Expect.equals(37, map[c21]);

  Expect.equals(37, map.remove(c11));
  testLength(0, map);
}

void testUnmodifiableMap(Map map) {
  Expect.isTrue(map.containsKey(1));
  testLength(1, map);
  Expect.equals(1, map.keys.first);
  Expect.equals(37, map.values.first);

  Expect.throws(map.clear);
  Expect.throws(() {
    map.remove(1);
  });
  Expect.throws(() {
    map[2] = 42;
  });
  Expect.throws(() {
    map.addAll({2: 42});
  });
}

class Customer {
  final int id;
  final int secondId;
  const Customer(this.id, this.secondId);
  int get hashCode => id;
  bool operator ==(Object other) {
    if (other is! Customer) return false;
    Customer otherCustomer = other;
    return id == otherCustomer.id;
  }
}

int myHashCode(Customer c) => c.secondId;
bool myEquals(Customer a, Customer b) => a.secondId == b.secondId;

void testIterationOrder(Map map) {
  var order = ['0', '6', '4', '2', '7', '9', '7', '1', '2', '5', '3'];
  for (int i = 0; i < order.length; i++) map[order[i]] = i;
  Expect.listEquals(
      map.keys.toList(), ['0', '6', '4', '2', '7', '9', '1', '5', '3']);
  Expect.listEquals(map.values.toList(), [0, 1, 2, 8, 6, 5, 7, 9, 10]);
}

void testOtherKeys(Map<int, int> map) {
  // Test that non-int keys are allowed in containsKey/remove/lookup.
  // Custom hash sets and tree sets must be constructed so they don't
  // use the equality/comparator on incompatible objects.

  // This should not throw in either checked or unchecked mode.
  Expect.isFalse(map.containsKey("not an int"));
  Expect.isFalse(map.containsKey(1.5));
  Expect.isNull(map.remove("not an int"));
  Expect.isNull(map.remove(1.5));
  Expect.isNull(map["not an int"]);
  Expect.isNull(map[1.5]);
}

class Mutable {
  int id;
  Mutable(this.id);
  int get hashCode => id;
  bool operator ==(other) => other is Mutable && other.id == id;
}

// Slow implementation of Map based on MapBase.
abstract class MapBaseOperations<K, V> {
  final List _keys = <K>[];
  final List _values = <V>[];
  int _modCount = 0;

  V operator [](Object key) {
    int index = _keys.indexOf(key);
    if (index < 0) return null;
    return _values[index];
  }

  Iterable<K> get keys => new TestKeyIterable<K>(this);

  void operator []=(K key, V value) {
    int index = _keys.indexOf(key);
    if (index >= 0) {
      _values[index] = value;
    } else {
      _modCount++;
      _keys.add(key);
      _values.add(value);
    }
  }

  V remove(Object key) {
    int index = _keys.indexOf(key);
    if (index >= 0) {
      var result = _values[index];
      key = _keys.removeLast();
      var value = _values.removeLast();
      if (index != _keys.length) {
        _keys[index] = key;
        _values[index] = value;
      }
      _modCount++;
      return result;
    }
    return null;
  }

  void clear() {
    // Clear cannot be based on remove, since remove won't remove keys that
    // are not equal to themselves. It will fail the testNaNKeys test.
    _keys.clear();
    _values.clear();
    _modCount++;
  }
}

class MapBaseMap<K, V> = MapBase<K, V> with MapBaseOperations<K, V>;
class MapMixinMap<K, V> = MapBaseOperations<K, V> with MapMixin<K, V>;

class TestKeyIterable<K> extends IterableBase<K> {
  final _map;
  TestKeyIterable(this._map);
  int get length => _map._keys.length;
  Iterator<K> get iterator => new TestKeyIterator<K>(_map);
}

class TestKeyIterator<K> implements Iterator<K> {
  final _map;
  final int _modCount;
  int _index = 0;
  var _current;
  TestKeyIterator(map)
      : _map = map,
        _modCount = map._modCount;
  bool moveNext() {
    if (_modCount != _map._modCount) {
      throw new ConcurrentModificationError(_map);
    }
    if (_index == _map._keys.length) {
      _current = null;
      return false;
    }
    _current = _map._keys[_index++];
    return true;
  }

  K get current => _current;
}

// Slow implementation of Map based on MapBase.
class UnmodifiableMapBaseMap<K, V> extends UnmodifiableMapBase<K, V> {
  final List _keys = <K>[];
  final List _values = <V>[];
  UnmodifiableMapBaseMap(List pairs) {
    for (int i = 0; i < pairs.length; i += 2) {
      _keys.add(pairs[i]);
      _values.add(pairs[i + 1]);
    }
  }

  int get _modCount => 0;

  V operator [](Object key) {
    int index = _keys.indexOf(key);
    if (index < 0) return null;
    return _values[index];
  }

  Iterable<K> get keys => _keys.skip(0);
}

abstract class Super implements Comparable {}

abstract class Interface implements Comparable {}

class Sub extends Super implements Interface, Comparable {
  int compareTo(dynamic other) => 0;
  int get hashCode => 0;
  bool operator ==(other) => other is Sub;
}

expectMap(Map expect, Map actual) {
  Expect.equals(expect.length, actual.length, "length");
  for (var key in expect.keys) {
    Expect.isTrue(actual.containsKey(key), "containsKey $key");
    Expect.equals(expect[key], actual[key]);
  }
}

void testFrom() {
  // Check contents.
  for (var map in [
    {},
    {1: 1},
    {1: 2, 3: 4, 5: 6, 7: 8}
  ]) {
    expectMap(map, new Map.from(map));
    expectMap(map, new HashMap.from(map));
    expectMap(map, new LinkedHashMap.from(map));
    expectMap(map, new SplayTreeMap.from(map));
  }
  // Test type combinations allowed.
  Map<int, int> intMap = <int, int>{1: 2, 3: 4};
  Map<num, num> numMap = <num, num>{1: 2, 3: 4};
  expectMap(intMap, new Map<int, int>.from(numMap));
  expectMap(intMap, new Map<num, num>.from(intMap));
  expectMap(intMap, new HashMap<int, int>.from(numMap));
  expectMap(intMap, new HashMap<num, num>.from(intMap));
  expectMap(intMap, new LinkedHashMap<int, int>.from(numMap));
  expectMap(intMap, new LinkedHashMap<num, num>.from(intMap));
  expectMap(intMap, new SplayTreeMap<int, int>.from(numMap));
  expectMap(intMap, new SplayTreeMap<num, num>.from(intMap));

  var sub = new Sub();
  Map<Super, Super> superMap = <Super, Super>{sub: sub};
  Map<Interface, Interface> interfaceMap = <Interface, Interface>{sub: sub};
  expectMap(superMap, new Map<Super, Super>.from(interfaceMap));
  expectMap(superMap, new Map<Interface, Interface>.from(superMap));
  expectMap(superMap, new HashMap<Super, Super>.from(interfaceMap));
  expectMap(superMap, new HashMap<Interface, Interface>.from(superMap));
  expectMap(superMap, new LinkedHashMap<Super, Super>.from(interfaceMap));
  expectMap(superMap, new LinkedHashMap<Interface, Interface>.from(superMap));
  expectMap(superMap, new SplayTreeMap<Super, Super>.from(interfaceMap));
  expectMap(superMap, new SplayTreeMap<Interface, Interface>.from(superMap));
}

void testTypeAnnotations(Map<int, int> map) {
  map[0] = 100;
  map[999] = 101;
  map[0x800000000] = 102;
  map[0x20000000000000] = 103;
  Expect.isFalse(map.containsKey("not an it"));
  Expect.isNull(map.remove("not an it"));

  testLength(4, map);
  Expect.equals(101, map.remove(999));
  testLength(3, map);
  Expect.equals(102, map.remove(0x800000000));
  testLength(2, map);
  Expect.equals(103, map.remove(0x20000000000000));
  testLength(1, map);
}

void testUnmodifiableMaps() {
  void checkUnmodifiable(Map<int, int> map) {
    Expect.throws(() => map[0] = 0);
    Expect.throws(() => map.addAll({0: 0}));
    Expect.throws(() => map.addEntries({0: 0}.entries));
    Expect.throws(() => map.clear());
    Expect.throws(() => map.putIfAbsent(0, () => 0));
    Expect.throws(() => map.remove(0));
    Expect.throws(() => map.removeWhere((k, v) => true));
    Expect.throws(() => map.update(0, (v) => v, ifAbsent: () => 0));
    Expect.throws(() => map.updateAll((k, v) => v));
  }

  checkUnmodifiable(const {1: 1});
  checkUnmodifiable(Map.unmodifiable({1: 1}));
  checkUnmodifiable(UnmodifiableMapView({1: 1}));
  checkUnmodifiable(const MapView({1: 1}));
}
