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

import "dart:collection";
import "package:expect/expect.dart";
import 'cast_helper.dart';

void main() {
  testDowncast();
  testUpcast();
}

void testDowncast() {
  var map = new Map.fromIterables(elements, elements);
  var dMap = Map.castFrom<C, C, D, D>(map);

  Expect.isTrue(dMap is Map<D, D>);

  Expect.equals(null, dMap[new C()]);
  Expect.throws(() => dMap[c]); // C is not D.
  Expect.isTrue(dMap.containsKey(c)); // containsKey should not be typed.
  Expect.equals(d, dMap[d]);
  Expect.throws(() => dMap[e]); // E is not D.
  Expect.isTrue(dMap.containsKey(null));
  Expect.equals(null, dMap[null]);

  Expect.equals(5, dMap.length);
  Expect.throws(() => dMap.remove(c)); // Removes key but fails to return value.
  Expect.equals(4, dMap.length);
  Expect.equals(null, dMap[c]);

  // Runtime errors when assigning or accessing a C.
  Expect.throws(() => dMap[c] = d);
  Expect.throws(() => dMap[d] = c);
  Expect.equals(4, dMap.length);

  // Test keys and values.
  Expect.isTrue(dMap.keys is Iterable<D>);
  Expect.isTrue(dMap.values is Iterable<D>);
  Expect.throws(() => dMap.keys.toList());
  Expect.throws(() => dMap.values.toList());
}

void testUpcast() {
  var map = new Map.fromIterables(elements, elements);
  var objectMap = Map.castFrom<C, C, Object, Object>(map);

  Expect.equals(5, objectMap.length);
  Expect.equals(c, objectMap[c]);
  Expect.isTrue(objectMap.containsKey(c));
  Expect.equals(c, objectMap.remove(c));
  Expect.equals(4, objectMap.length);

  // Test keys and values.
  Expect.isTrue(objectMap.keys is Iterable<Object>);
  Expect.isTrue(objectMap.values is Iterable<Object>);
  var expected = new List<Object>.from(elements);
  expected.remove(c);
  Expect.listEquals(expected, objectMap.keys.toList());
  Expect.listEquals(expected, objectMap.values.toList());
}
