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

library map_unmodifiable_cast_test;

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

void main() {
  testNum(const {1: 37}, "const");
  testNum(const <num, num>{1: 37}.cast<int, int>(), "const.cast");
  testNum(const <num, num>{1: 37}.retype<int, int>(), "const.retype");

  testNum(new UnmodifiableMapView({1: 37}), "unmod");
  testNum(new UnmodifiableMapView<num, num>(<num, num>{1: 37}), "unmod.cast");
  testNum(new UnmodifiableMapView<num, num>(<int, int>{1: 37}), "unmod.retype");

  testNum(new UnmodifiableMapView<num, num>(<num, num>{1: 37}).cast<int, int>(),
      "unmodView<num>.cast<int>");
  testNum(new UnmodifiableMapView<num, num>(<int, int>{1: 37}).cast<int, int>(),
      "unmodView<int>.cast<int>");
  testNum(
      new UnmodifiableMapView<Object, Object>(<num, num>{1: 37})
          .cast<int, int>(),
      "unmodView<Object>(num).cast<int>");
  testNum(
      new UnmodifiableMapView<Object, Object>(<int, int>{1: 37})
          .cast<num, num>(),
      "unmodView<Object>(int).cast<num>");

  testNum(
      new UnmodifiableMapView<num, num>(<num, num>{1: 37}).retype<int, int>(),
      "unmodView<num>(num).retype<int>");
  testNum(
      new UnmodifiableMapView<num, num>(<int, int>{1: 37}).retype<int, int>(),
      "unmodView<num>(int).retype<int>");
  testNum(
      new UnmodifiableMapView<Object, Object>(<num, num>{1: 37})
          .retype<int, int>(),
      "unmodView<Object>(num).retype<int>");
  testNum(
      new UnmodifiableMapView<Object, Object>(<int, int>{1: 37})
          .retype<num, num>(),
      "unmodView<Object>(int).retype<num>");

  var m2 = new Map<num, num>.unmodifiable({1: 37});
  testNum(m2, "Map<num>.unmod");
  testNum(m2.cast<int, int>(), "Map<num>.unmod.cast<int>");

  Map<Symbol, dynamic> nsm = new NsmMap().foo(a: 0);
  test(nsm, #a, 0, "nsm");
  test(nsm.cast<Object, int>(), #a, 0, "nsm.cast");
  test(nsm.retype<Object, int>(), #a, 0, "nsm.retype");
}

void testNum(Map<Object, Object> map, String name) {
  test(map, 1, 37, name);
}

void test(
    Map<Object, Object> map, Object firstKey, Object firstValue, String name) {
  Expect.isTrue(map.containsKey(firstKey), "$name.containsKey");
  Expect.equals(1, map.length, "$name.length");
  Expect.equals(firstKey, map.keys.first, "$name.keys.first");
  Expect.equals(firstValue, map.values.first, "$name.values.first");

  Expect.throwsUnsupportedError(map.clear, "$name.clear");
  Expect.throwsUnsupportedError(() {
    map.remove(firstKey);
  }, "$name.remove");
  Expect.throwsUnsupportedError(() {
    map[null] = null;
  }, "$name[]=");
  Expect.throwsUnsupportedError(() {
    map.addAll(<Null, Null>{null: null});
  }, "$name.addAll");
}

class NsmMap {
  noSuchMethod(i) => i.namedArguments;
  foo({a, b, c, d});
}
