OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 library tests.dart2js.lookup_map_test; |
| 6 |
| 7 import 'package:test/test.dart'; |
| 8 import 'compiler_helper.dart'; |
| 9 |
| 10 main() { |
| 11 test('live entries are kept', () async { |
| 12 String generated = await compileAll(r""" |
| 13 import 'package:lookup_map/lookup_map.dart'; |
| 14 class A{} |
| 15 const map = const LookupMap(const [ |
| 16 A, "the-text-for-A", |
| 17 ]); |
| 18 main() => print(map[A]); |
| 19 """); |
| 20 expect(generated, contains("the-text-for-A")); |
| 21 }); |
| 22 |
| 23 test('live entries are kept - single-pair', () async { |
| 24 String generated = await compileAll(r""" |
| 25 import 'package:lookup_map/lookup_map.dart'; |
| 26 class A{} |
| 27 const map = const LookupMap.pair(A, "the-text-for-A"); |
| 28 main() => print(map[A]); |
| 29 """); |
| 30 expect(generated, contains("the-text-for-A")); |
| 31 }); |
| 32 |
| 33 test('unused entries are removed', () async { |
| 34 String generated = await compileAll(r""" |
| 35 import 'package:lookup_map/lookup_map.dart'; |
| 36 class A{} |
| 37 class B{} |
| 38 const map = const LookupMap(const [ |
| 39 A, "the-text-for-A", |
| 40 B, "the-text-for-B", |
| 41 ]); |
| 42 main() => print(map[A]); |
| 43 """); |
| 44 expect(generated, isNot(contains("the-text-for-B"))); |
| 45 }); |
| 46 |
| 47 test('unused entries are removed - nested maps', () async { |
| 48 String generated = await compileAll(r""" |
| 49 import 'package:lookup_map/lookup_map.dart'; |
| 50 class A{} |
| 51 class B{} |
| 52 const map = const LookupMap(const [], const [ |
| 53 const LookupMap(const [ |
| 54 A, "the-text-for-A", |
| 55 B, "the-text-for-B", |
| 56 ]), |
| 57 ]); |
| 58 main() => print(map[A]); |
| 59 """); |
| 60 expect(generated, isNot(contains("the-text-for-B"))); |
| 61 }); |
| 62 |
| 63 test('unused entries are removed - single-pair', () async { |
| 64 String generated = await compileAll(r""" |
| 65 import 'package:lookup_map/lookup_map.dart'; |
| 66 class A{} |
| 67 class B{} |
| 68 const map = const LookupMap.pair(A, "the-text-for-A"); |
| 69 main() => print(map[A]); |
| 70 """); |
| 71 expect(generated, isNot(contains("the-text-for-B"))); |
| 72 }); |
| 73 |
| 74 test('unused entries are removed - nested single-pair', () async { |
| 75 String generated = await compileAll(r""" |
| 76 import 'package:lookup_map/lookup_map.dart'; |
| 77 class A{} |
| 78 class B{} |
| 79 const map = const LookupMap(const [], const [ |
| 80 const LookupMap.pair(A, "the-text-for-A"), |
| 81 const LookupMap.pair(B, "the-text-for-B"), |
| 82 ]); |
| 83 main() => print(map[A]); |
| 84 """); |
| 85 expect(generated, isNot(contains("the-text-for-B"))); |
| 86 }); |
| 87 |
| 88 test('works if entries are declared separate from map', () async { |
| 89 String generated = await compileAll(r""" |
| 90 import 'package:lookup_map/lookup_map.dart'; |
| 91 class A{} |
| 92 class B{} |
| 93 const entries = const [ |
| 94 A, "the-text-for-A", |
| 95 B, "the-text-for-B", |
| 96 ]; |
| 97 const map = const LookupMap(entries); |
| 98 main() => print(map[A]); |
| 99 """); |
| 100 expect(generated, isNot(contains("the-text-for-B"))); |
| 101 }); |
| 102 |
| 103 test('escaping entries disable tree-shaking', () async { |
| 104 String generated = await compileAll(r""" |
| 105 import 'package:lookup_map/lookup_map.dart'; |
| 106 class A{} |
| 107 class B{} |
| 108 const entries = const [ |
| 109 A, "the-text-for-A", |
| 110 B, "the-text-for-B", |
| 111 ]; |
| 112 const map = const LookupMap(entries); |
| 113 main() { |
| 114 entries.forEach(print); |
| 115 print(map[A]); |
| 116 } |
| 117 """); |
| 118 expect(generated, contains("the-text-for-B")); |
| 119 }); |
| 120 |
| 121 test('uses include recursively reachable data', () async { |
| 122 String generated = await compileAll(r""" |
| 123 import 'package:lookup_map/lookup_map.dart'; |
| 124 class A{} |
| 125 class B{} |
| 126 class C{} |
| 127 class D{} |
| 128 class E{} |
| 129 const map = const LookupMap(const [ |
| 130 A, const ["the-text-for-A", B], |
| 131 B, const ["the-text-for-B", C], |
| 132 C, const ["the-text-for-C"], |
| 133 D, const ["the-text-for-D", E], |
| 134 E, const ["the-text-for-E"], |
| 135 ]); |
| 136 main() => print(map[map[A][1]]); |
| 137 """); |
| 138 expect(generated, contains("the-text-for-A")); |
| 139 expect(generated, contains("the-text-for-B")); |
| 140 expect(generated, contains("the-text-for-C")); |
| 141 expect(generated, isNot(contains("the-text-for-D"))); |
| 142 expect(generated, isNot(contains("the-text-for-E"))); |
| 143 }); |
| 144 |
| 145 test('uses are found through newly discovered code', () async { |
| 146 String generated = await compileAll(r""" |
| 147 import 'package:lookup_map/lookup_map.dart'; |
| 148 class A{ A(B x);} |
| 149 class B{} |
| 150 class C{} |
| 151 class D{} |
| 152 class E{} |
| 153 createA() => new A(map[B][1]()); |
| 154 createB() => new B(); |
| 155 const map = const LookupMap(const [ |
| 156 A, const ["the-text-for-A", createA], |
| 157 B, const ["the-text-for-B", createB], |
| 158 C, const ["the-text-for-C"], |
| 159 ]); |
| 160 main() => print(map[A][1]()); |
| 161 """); |
| 162 expect(generated, contains("the-text-for-A")); |
| 163 expect(generated, contains("the-text-for-B")); |
| 164 expect(generated, isNot(contains("the-text-for-C"))); |
| 165 }); |
| 166 |
| 167 test('generic type allocations are considered used', () async { |
| 168 String generated = await compileAll(r""" |
| 169 import 'package:lookup_map/lookup_map.dart'; |
| 170 class A{} |
| 171 class M<T>{ get type => T; } |
| 172 const map = const LookupMap(const [ |
| 173 A, "the-text-for-A", |
| 174 ]); |
| 175 main() => print(map[new M<A>().type]); |
| 176 """); |
| 177 expect(generated, contains("the-text-for-A")); |
| 178 }); |
| 179 |
| 180 test('generics in type signatures are ignored', () async { |
| 181 String generated = await compileAll(r""" |
| 182 import 'package:lookup_map/lookup_map.dart'; |
| 183 class A{} |
| 184 class B{} |
| 185 class M<T>{ get type => T; } |
| 186 _factory(M<B> t) => t; |
| 187 const map = const LookupMap(const [ |
| 188 A, const ["the-text-for-A", _factory], |
| 189 B, "the-text-for-B", |
| 190 ]); |
| 191 main() => print(map[A]); |
| 192 """); |
| 193 expect(generated, isNot(contains("the-text-for-B"))); |
| 194 }); |
| 195 |
| 196 test('metadata is ignored', () async { |
| 197 String generated = await compileAll(r""" |
| 198 import 'package:lookup_map/lookup_map.dart'; |
| 199 class A{ const A(); } |
| 200 |
| 201 @A() |
| 202 class M {} |
| 203 const map = const LookupMap(const [ |
| 204 A, "the-text-for-A", |
| 205 ]); |
| 206 main() => print(map[M]); |
| 207 """); |
| 208 expect(generated, isNot(contains("the-text-for-A"))); |
| 209 }); |
| 210 |
| 211 test('shared constants used in metadata are ignored', () async { |
| 212 String generated = await compileAll(r""" |
| 213 import 'package:lookup_map/lookup_map.dart'; |
| 214 const annot = const B(foo: A); |
| 215 |
| 216 @B(foo: annot) |
| 217 class A{ const A(); } |
| 218 class B{ final Type foo; const B({this.foo}); } |
| 219 |
| 220 class M {} |
| 221 const map = const LookupMap(const [ |
| 222 A, const ["the-text-for-A", annot] |
| 223 ]); |
| 224 main() => print(map[M]); |
| 225 """); |
| 226 expect(generated, isNot(contains("the-text-for-A"))); |
| 227 }); |
| 228 |
| 229 // regression test for a failure when looking up `dynamic` in a generic. |
| 230 test('do not choke on dynamic types', () async { |
| 231 await compileAll(r""" |
| 232 import 'package:lookup_map/lookup_map.dart'; |
| 233 class A{} |
| 234 class M<T>{ get type => T; } |
| 235 const map = const LookupMap(const [ |
| 236 A, "the-text-for-A", |
| 237 ]); |
| 238 main() => print(map[new M<dynamic>().type]); |
| 239 """); |
| 240 }); |
| 241 |
| 242 |
| 243 test('support subclassing LookupMap', () async { |
| 244 String generated = await compileAll(r""" |
| 245 import 'package:lookup_map/lookup_map.dart'; |
| 246 class A{} |
| 247 class B{} |
| 248 class S extends LookupMap { |
| 249 const S(list) : super(list); |
| 250 } |
| 251 const map = const S(const [ |
| 252 A, "the-text-for-A", |
| 253 B, "the-text-for-B", |
| 254 ]); |
| 255 |
| 256 main() => print(map[A]); |
| 257 """); |
| 258 expect(generated, contains("the-text-for-A")); |
| 259 expect(generated, isNot(contains("the-text-for-B"))); |
| 260 }); |
| 261 } |
OLD | NEW |