| // Copyright (c) 2014, 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. |
| |
| // @dart = 2.9 |
| |
| import 'package:expect/expect.dart'; |
| |
| /// Returns its argument. |
| /// |
| /// Prevents static optimizations and inlining. |
| @pragma('vm:never-inline') |
| @pragma('dart2js:noInline') |
| dynamic getValueNonOptimized(dynamic x) { |
| // DateTime.now() cannot be predicted statically, never equal to 42. |
| if (DateTime.now().millisecondsSinceEpoch == 42) { |
| return getValueNonOptimized(2); |
| } |
| return x; |
| } |
| |
| main() { |
| // TODO(terry): Should check: |
| // - simple expressions are const e.g., 2 + 3, true && !false, etc. |
| // - const with final and/or static with same const attributes |
| // Additionally new class instances with a static const same identity |
| // - const for all types (int, num, double, String, boolean, and objects) |
| // - canonicalization - const created only once same identity e.g., |
| // |
| // getConstMap() => const [1, 2]; |
| // var a = getConstMap(); |
| // var b = getConstMap(); |
| // Expect.equals(a.hashCode, b.hashCode); |
| |
| // Make sure that const maps use the == operator and not object identity. The |
| // specification does not explicitly require it, otherwise ints and Strings |
| // wouldn't make much sense as keys. |
| final map = const {1: 42, 'foo': 499, 2: 'bar'}; |
| Expect.equals(42, map[getValueNonOptimized(1.0)]); |
| Expect.equals( |
| 499, map[getValueNonOptimized(new String.fromCharCodes('foo'.runes))]); |
| Expect.equals('bar', map[getValueNonOptimized(2)]); |
| |
| void testThrowsNoModification(void Function() f) { |
| Expect.throws(f, (e) { |
| return e is UnsupportedError; |
| }); |
| |
| Expect.equals(42, map[getValueNonOptimized(1.0)]); |
| Expect.equals( |
| 499, map[getValueNonOptimized(new String.fromCharCodes('foo'.runes))]); |
| Expect.equals('bar', map[getValueNonOptimized(2)]); |
| Expect.isNull(map[1024]); |
| } |
| |
| testThrowsNoModification(() { |
| map[1024] = 'something'; |
| }); |
| |
| testThrowsNoModification(() { |
| map.addAll({1024: 'something'}); |
| }); |
| |
| testThrowsNoModification(() { |
| map.putIfAbsent(1024, () => 'something'); |
| }); |
| |
| testThrowsNoModification(() { |
| map.putIfAbsent(1, () => 1024); |
| }); |
| |
| testThrowsNoModification(() { |
| map.clear(); |
| }); |
| |
| testThrowsNoModification(() { |
| map.remove(1024); |
| }); |
| |
| testThrowsNoModification(() { |
| map.remove(1); |
| }); |
| |
| testThrowsNoModification(() { |
| map.addEntries([MapEntry(1024, 'something')]); |
| }); |
| |
| testThrowsNoModification(() { |
| map.update(2, (Object value) => 42); |
| }); |
| |
| testThrowsNoModification(() { |
| map.updateAll((Object key, Object value) => '123'); |
| }); |
| |
| testThrowsNoModification(() { |
| map.removeWhere((Object key, Object value) => true); |
| }); |
| } |