| // 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<int, String> { |
| Iterable<int> 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<int> { |
| bool add(int value) => throw UnsupportedError("unsupported"); |
| bool contains(Object? value) => throw UnsupportedError("unsupported"); |
| Iterator<int> get iterator => <int>[].iterator; |
| int get length => 0; |
| int? lookup(Object? value) => throw UnsupportedError("unsupported"); |
| bool remove(Object? value) => throw UnsupportedError("unsupported"); |
| Set<int> 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<T>(dynamic value) { |
| Expect.equals(dynamic, T); |
| return value; |
| } |
| |
| T expectInt<T>(dynamic value) { |
| Expect.equals(int, T); |
| return value; |
| } |
| |
| T expectString<T>(dynamic value) { |
| Expect.equals(String, T); |
| return value; |
| } |
| |
| Iterable<T> expectIntIterable<T>(dynamic value) { |
| Expect.equals(int, T); |
| return value; |
| } |
| |
| Set<T> expectIntSet<T>() { |
| Expect.equals(int, T); |
| return Set(); |
| } |
| |
| Stream<T> expectIntStream<T>(dynamic elements) { |
| Expect.equals(int, T); |
| return Stream<T>.fromIterable(elements); |
| } |
| |
| Set<T> expectDynamicSet<T>() { |
| 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<int>` is a `List<num>` or |
| /// `List<dynamic>`. 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<T>(Object object) { |
| Expect.type<List>(object); |
| _expectTypeArguments(T.toString(), object); |
| } |
| |
| void expectSetOf<T>(Object object) { |
| Expect.type<Set>(object); |
| _expectTypeArguments(T.toString(), object); |
| } |
| |
| void expectMapOf<K, V>(Object object) { |
| Expect.type<Map>(object); |
| _expectTypeArguments("$K, $V", object); |
| } |