Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Unified Diff: tests/compiler/dart2js/lookup_map_test.dart

Issue 1310183014: Generalize lookup-maps to support other const keys (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tests/compiler/dart2js/lookup_map_test.dart
diff --git a/tests/compiler/dart2js/lookup_map_test.dart b/tests/compiler/dart2js/lookup_map_test.dart
index d73bc75ea7d1e467e78d21e712446140b62fd37f..a93e0a64a02d86388debdb93b1423ecd5939a2f4 100644
--- a/tests/compiler/dart2js/lookup_map_test.dart
+++ b/tests/compiler/dart2js/lookup_map_test.dart
@@ -8,10 +8,49 @@ import 'package:test/test.dart';
import 'compiler_helper.dart';
main() {
+ Map<String, String> testDeclarations = {
+ 'types': r'''
+ import 'package:lookup_map/lookup_map.dart';
+ class A {}
+ class B {}
+ class C {}
+ class D {}
+ class E {}''',
+
+ 'const keys': r'''
+ import 'package:lookup_map/lookup_map.dart';
+ class Key { final name; const Key(this.name); }
+ const A = const Key("A");
+ const B = const Key("B");
+ const C = const Key("C");
+ const D = const Key("D");
+ const E = const Key("E");''',
+
+ 'mixed keys': r'''
+ import 'package:lookup_map/lookup_map.dart';
+ class Key { final name; const Key(this.name); }
+ const A = const Key("A");
+ class B {}
+ const C = const Key("C");
+ class D {}
+ const E = const Key("E");''',
+ };
+
+ testDeclarations.forEach((name, declarations) {
+ group(name, () => _commonTests(declarations));
+ });
+ group('generic', _genericTests);
+ group('metadata', _metadataTests);
+ group('unsupported', _unsupportedKeysTests);
+}
+
+/// Common tests for both declarations that use Types or other const expressions
+/// as keys. The argument [declaration] should contain a declaration for
+/// constant keys named `A`, `B`, `C`, `D`, and `E`.
+_commonTests(String declarations) {
test('live entries are kept', () async {
- String generated = await compileAll(r"""
- import 'package:lookup_map/lookup_map.dart';
- class A{}
+ String generated = await compileAll("""
+ $declarations
const map = const LookupMap(const [
A, "the-text-for-A",
]);
@@ -21,9 +60,8 @@ main() {
});
test('live entries are kept - single-pair', () async {
- String generated = await compileAll(r"""
- import 'package:lookup_map/lookup_map.dart';
- class A{}
+ String generated = await compileAll("""
+ $declarations
const map = const LookupMap.pair(A, "the-text-for-A");
main() => print(map[A]);
""");
@@ -31,10 +69,8 @@ main() {
});
test('unused entries are removed', () async {
- String generated = await compileAll(r"""
- import 'package:lookup_map/lookup_map.dart';
- class A{}
- class B{}
+ String generated = await compileAll("""
+ $declarations
const map = const LookupMap(const [
A, "the-text-for-A",
B, "the-text-for-B",
@@ -45,10 +81,8 @@ main() {
});
test('unused entries are removed - nested maps', () async {
- String generated = await compileAll(r"""
- import 'package:lookup_map/lookup_map.dart';
- class A{}
- class B{}
+ String generated = await compileAll("""
+ $declarations
const map = const LookupMap(const [], const [
const LookupMap(const [
A, "the-text-for-A",
@@ -61,10 +95,8 @@ main() {
});
test('unused entries are removed - single-pair', () async {
- String generated = await compileAll(r"""
- import 'package:lookup_map/lookup_map.dart';
- class A{}
- class B{}
+ String generated = await compileAll("""
+ $declarations
const map = const LookupMap.pair(A, "the-text-for-A");
main() => print(map[A]);
""");
@@ -72,10 +104,9 @@ main() {
});
test('unused entries are removed - nested single-pair', () async {
- String generated = await compileAll(r"""
+ String generated = await compileAll("""
import 'package:lookup_map/lookup_map.dart';
- class A{}
- class B{}
+ $declarations
const map = const LookupMap(const [], const [
const LookupMap.pair(A, "the-text-for-A"),
const LookupMap.pair(B, "the-text-for-B"),
@@ -86,10 +117,8 @@ main() {
});
test('works if entries are declared separate from map', () async {
- String generated = await compileAll(r"""
- import 'package:lookup_map/lookup_map.dart';
- class A{}
- class B{}
+ String generated = await compileAll("""
+ $declarations
const entries = const [
A, "the-text-for-A",
B, "the-text-for-B",
@@ -101,10 +130,8 @@ main() {
});
test('escaping entries disable tree-shaking', () async {
- String generated = await compileAll(r"""
- import 'package:lookup_map/lookup_map.dart';
- class A{}
- class B{}
+ String generated = await compileAll("""
+ $declarations
const entries = const [
A, "the-text-for-A",
B, "the-text-for-B",
@@ -119,13 +146,8 @@ main() {
});
test('uses include recursively reachable data', () async {
- String generated = await compileAll(r"""
- import 'package:lookup_map/lookup_map.dart';
- class A{}
- class B{}
- class C{}
- class D{}
- class E{}
+ String generated = await compileAll("""
+ $declarations
const map = const LookupMap(const [
A, const ["the-text-for-A", B],
B, const ["the-text-for-B", C],
@@ -143,27 +165,62 @@ main() {
});
test('uses are found through newly discovered code', () async {
- String generated = await compileAll(r"""
- import 'package:lookup_map/lookup_map.dart';
- class A{ A(B x);}
- class B{}
- class C{}
- class D{}
- class E{}
- createA() => new A(map[B][1]());
- createB() => new B();
+ String generated = await compileAll("""
+ $declarations
+ f1() => map[B][1]();
+ f2() => E;
const map = const LookupMap(const [
- A, const ["the-text-for-A", createA],
- B, const ["the-text-for-B", createB],
+ A, const ["the-text-for-A", f1],
+ B, const ["the-text-for-B", f2],
C, const ["the-text-for-C"],
+ D, const ["the-text-for-D"],
+ E, const ["the-text-for-E"],
]);
main() => print(map[A][1]());
""");
expect(generated, contains("the-text-for-A"));
expect(generated, contains("the-text-for-B"));
expect(generated, isNot(contains("the-text-for-C")));
+ expect(generated, isNot(contains("the-text-for-C")));
+ expect(generated, contains("the-text-for-E"));
+ });
+
+ test('support subclassing LookupMap', () async {
+ String generated = await compileAll("""
+ $declarations
+ class S extends LookupMap {
+ const S(list) : super(list);
+ }
+ const map = const S(const [
+ A, "the-text-for-A",
+ B, "the-text-for-B",
+ ]);
+
+ main() => print(map[A]);
+ """);
+ expect(generated, contains("the-text-for-A"));
+ expect(generated, isNot(contains("the-text-for-B")));
});
+ test('constants keys are processed recursively', () async {
+ String generated = await compileAll("""
+ $declarations
+
+ const nested = const [ B ];
+ const map = const LookupMap(const [
+ A, "the-text-for-A",
+ B, "the-text-for-B",
+ ]);
+ main() => print(map[nested]);
+ """);
+ expect(generated, isNot(contains("the-text-for-A")));
+ expect(generated, contains("the-text-for-B"));
+ });
+}
+
+/// Tests specific to type keys, we ensure that generic type arguments are
+/// considered.
+_genericTests() {
test('generic type allocations are considered used', () async {
String generated = await compileAll(r"""
import 'package:lookup_map/lookup_map.dart';
@@ -193,6 +250,23 @@ main() {
expect(generated, isNot(contains("the-text-for-B")));
});
+ // regression test for a failure when looking up `dynamic` in a generic.
+ test('do not choke with dynamic type arguments', () async {
+ await compileAll(r"""
+ import 'package:lookup_map/lookup_map.dart';
+ class A{}
+ class M<T>{ get type => T; }
+ const map = const LookupMap(const [
+ A, "the-text-for-A",
+ ]);
+ main() => print(map[new M<dynamic>().type]);
+ """);
+ });
+}
+
+/// Sanity checks about metadata: it is ignored for codegen even though it is
+/// visited during resolution.
+_metadataTests() {
test('metadata is ignored', () async {
String generated = await compileAll(r"""
import 'package:lookup_map/lookup_map.dart';
@@ -225,37 +299,47 @@ main() {
""");
expect(generated, isNot(contains("the-text-for-A")));
});
+}
- // regression test for a failure when looking up `dynamic` in a generic.
- test('do not choke on dynamic types', () async {
- await compileAll(r"""
+_unsupportedKeysTests() {
+ test('primitive and string keys are always kept', () async {
+ String generated = await compileAll("""
import 'package:lookup_map/lookup_map.dart';
- class A{}
- class M<T>{ get type => T; }
+ const A = "A";
+ const B = "B";
const map = const LookupMap(const [
A, "the-text-for-A",
+ B, "the-text-for-B",
+ 3, "the-text-for-3",
+ 1.1, "the-text-for-1.1",
+ false, "the-text-for-false",
]);
- main() => print(map[new M<dynamic>().type]);
+ main() => print(map[A]);
""");
+ expect(generated, contains("the-text-for-A"));
+ expect(generated, contains("the-text-for-B"));
+ expect(generated, contains("the-text-for-3"));
+ expect(generated, contains("the-text-for-1.1"));
+ expect(generated, contains("the-text-for-false"));
});
-
- test('support subclassing LookupMap', () async {
- String generated = await compileAll(r"""
+ test('non-type const keys implementing equals are not removed', () async {
+ String generated = await compileAll("""
import 'package:lookup_map/lookup_map.dart';
- class A{}
- class B{}
- class S extends LookupMap {
- const S(list) : super(list);
+ class Key {
+ final name;
+ const Key(this.name);
+ int get hashCode => name.hashCode * 13;
+ operator ==(other) => other is Key && name == other.name;
}
- const map = const S(const [
+ const A = const Key("A");
+ const B = const Key("B");
+ const map = const LookupMap(const [
A, "the-text-for-A",
B, "the-text-for-B",
]);
-
main() => print(map[A]);
""");
- expect(generated, contains("the-text-for-A"));
- expect(generated, isNot(contains("the-text-for-B")));
+ expect(generated, contains("the-text-for-B"));
});
}

Powered by Google App Engine
This is Rietveld 408576698