// Copyright (c) 2019, 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. import 'dart:collection'; import 'package:expect/expect.dart'; class CustomMap with MapMixin { Iterable get keys => []; String operator [](Object key) => ""; operator []=(int key, String value) {} String remove(Object key) => throw UnsupportedError("unsupported"); void clear() => throw UnsupportedError("unsupported"); } class CustomSet extends SetBase { bool add(int value) => throw UnsupportedError("unsupported"); bool contains(Object value) => throw UnsupportedError("unsupported"); Iterator get iterator => [].iterator; int get length => 0; int lookup(Object value) => throw UnsupportedError("unsupported"); bool remove(Object value) => throw UnsupportedError("unsupported"); Set toSet() => this; } class Equality { final int id; final String name; const Equality(this.id, this.name); int get hashCode => id; bool operator ==(Object other) => other is Equality && id == other.id; String toString() => "$id:$name"; } T expectDynamic(dynamic value) { Expect.equals(dynamic, T); return value; } T expectInt(dynamic value) { Expect.equals(int, T); return value; } T expectString(dynamic value) { Expect.equals(String, T); return value; } Iterable expectIntIterable(dynamic value) { Expect.equals(int, T); return value; } Set expectIntSet() { Expect.equals(int, T); return Set(); } Stream expectIntStream(dynamic elements) { Expect.equals(int, T); return Stream.fromIterable(elements); } Set expectDynamicSet() { Expect.equals(dynamic, T); return Set(); } /// Hacky way of testing the inferred generic type arguments of [object]. /// /// [Expect.type()] only performs a subtype test, which means that it will /// return `true` when asked if a `List` is a `List` or /// `List`. For inference, we want to test the type more precisely. /// /// There isn't a good way to do that in tests yet so, for now, we just see if /// the runtime type contains the given type argument string. // TODO(rnystrom): Do something less horribly brittle. void _expectTypeArguments(String typeArguments, Object object) { var typeName = object.runtimeType.toString(); // If an implementation prints dynamic instantiations like a raw type, // handle that. if (!typeName.contains("<") && (typeArguments == "dynamic" || typeArguments == "dynamic, dynamic")) { return; } if (!typeName.contains("<$typeArguments>")) { Expect.fail("Object should have had generic type '<$typeArguments>', " "but was '$typeName'."); } } void expectListOf(Object object) { Expect.type(object); _expectTypeArguments(T.toString(), object); } void expectSetOf(Object object) { Expect.type(object); _expectTypeArguments(T.toString(), object); } void expectMapOf(Object object) { Expect.type(object); _expectTypeArguments("$K, $V", object); }