| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library map_test; | 5 library map_test; |
| 6 import "package:expect/expect.dart"; | 6 import "package:expect/expect.dart"; |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 void main() { | 9 void main() { |
| 10 test(new HashMap()); | 10 test(new HashMap()); |
| 11 test(new LinkedHashMap()); | 11 test(new LinkedHashMap()); |
| 12 test(new SplayTreeMap()); | 12 test(new SplayTreeMap()); |
| 13 test(new SplayTreeMap(Comparable.compare)); | 13 test(new SplayTreeMap(Comparable.compare)); |
| 14 test(new MapView(new HashMap())); |
| 15 test(new MapView(new SplayTreeMap())); |
| 16 test(new MapBaseMap()); |
| 14 testLinkedHashMap(); | 17 testLinkedHashMap(); |
| 15 testMapLiteral(); | 18 testMapLiteral(); |
| 16 testNullValue(); | 19 testNullValue(); |
| 17 testTypes(); | 20 testTypes(); |
| 18 | 21 |
| 19 testWeirdStringKeys(new Map()); | 22 testWeirdStringKeys(new Map()); |
| 20 testWeirdStringKeys(new Map<String, String>()); | 23 testWeirdStringKeys(new Map<String, String>()); |
| 21 testWeirdStringKeys(new HashMap()); | 24 testWeirdStringKeys(new HashMap()); |
| 22 testWeirdStringKeys(new HashMap<String, String>()); | 25 testWeirdStringKeys(new HashMap<String, String>()); |
| 23 testWeirdStringKeys(new LinkedHashMap()); | 26 testWeirdStringKeys(new LinkedHashMap()); |
| 24 testWeirdStringKeys(new LinkedHashMap<String, String>()); | 27 testWeirdStringKeys(new LinkedHashMap<String, String>()); |
| 25 testWeirdStringKeys(new SplayTreeMap()); | 28 testWeirdStringKeys(new SplayTreeMap()); |
| 26 testWeirdStringKeys(new SplayTreeMap<String, String>()); | 29 testWeirdStringKeys(new SplayTreeMap<String, String>()); |
| 30 testWeirdStringKeys(new MapBaseMap<String, String>()); |
| 27 | 31 |
| 28 testNumericKeys(new Map()); | 32 testNumericKeys(new Map()); |
| 29 testNumericKeys(new Map<num, String>()); | 33 testNumericKeys(new Map<num, String>()); |
| 30 testNumericKeys(new HashMap()); | 34 testNumericKeys(new HashMap()); |
| 31 testNumericKeys(new HashMap<num, String>()); | 35 testNumericKeys(new HashMap<num, String>()); |
| 32 testNumericKeys(new HashMap.identity()); | 36 testNumericKeys(new HashMap.identity()); |
| 33 testNumericKeys(new HashMap<num, String>.identity()); | 37 testNumericKeys(new HashMap<num, String>.identity()); |
| 34 testNumericKeys(new LinkedHashMap()); | 38 testNumericKeys(new LinkedHashMap()); |
| 35 testNumericKeys(new LinkedHashMap<num, String>()); | 39 testNumericKeys(new LinkedHashMap<num, String>()); |
| 36 testNumericKeys(new LinkedHashMap.identity()); | 40 testNumericKeys(new LinkedHashMap.identity()); |
| 37 testNumericKeys(new LinkedHashMap<num, String>.identity()); | 41 testNumericKeys(new LinkedHashMap<num, String>.identity()); |
| 42 testNumericKeys(new MapBaseMap<num, String>()); |
| 38 | 43 |
| 39 testNaNKeys(new Map()); | 44 testNaNKeys(new Map()); |
| 40 testNaNKeys(new Map<num, String>()); | 45 testNaNKeys(new Map<num, String>()); |
| 41 testNaNKeys(new HashMap()); | 46 testNaNKeys(new HashMap()); |
| 42 testNaNKeys(new HashMap<num, String>()); | 47 testNaNKeys(new HashMap<num, String>()); |
| 43 testNaNKeys(new LinkedHashMap()); | 48 testNaNKeys(new LinkedHashMap()); |
| 44 testNaNKeys(new LinkedHashMap<num, String>()); | 49 testNaNKeys(new LinkedHashMap<num, String>()); |
| 50 testNaNKeys(new MapBaseMap<num, String>()); |
| 45 // Identity maps fail the NaN-keys tests because the test assumes that | 51 // Identity maps fail the NaN-keys tests because the test assumes that |
| 46 // NaN is not equal to NaN. | 52 // NaN is not equal to NaN. |
| 47 | 53 |
| 48 testIdentityMap(new Map.identity()); | 54 testIdentityMap(new Map.identity()); |
| 49 testIdentityMap(new HashMap.identity()); | 55 testIdentityMap(new HashMap.identity()); |
| 50 testIdentityMap(new LinkedHashMap.identity()); | 56 testIdentityMap(new LinkedHashMap.identity()); |
| 51 testIdentityMap(new HashMap(equals: identical, | 57 testIdentityMap(new HashMap(equals: identical, |
| 52 hashCode: identityHashCode)); | 58 hashCode: identityHashCode)); |
| 53 testIdentityMap(new LinkedHashMap(equals: identical, | 59 testIdentityMap(new LinkedHashMap(equals: identical, |
| 54 hashCode: identityHashCode)); | 60 hashCode: identityHashCode)); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 82 testOtherKeys(new HashMap(equals: (int x, int y) => x == y, | 88 testOtherKeys(new HashMap(equals: (int x, int y) => x == y, |
| 83 hashCode: (int v) => v.hashCode, | 89 hashCode: (int v) => v.hashCode, |
| 84 isValidKey: (v) => v is int)); | 90 isValidKey: (v) => v is int)); |
| 85 testOtherKeys(new LinkedHashMap<int, int>()); | 91 testOtherKeys(new LinkedHashMap<int, int>()); |
| 86 testOtherKeys(new LinkedHashMap<int, int>.identity()); | 92 testOtherKeys(new LinkedHashMap<int, int>.identity()); |
| 87 testOtherKeys(new LinkedHashMap<int, int>(hashCode: (v) => v.hashCode, | 93 testOtherKeys(new LinkedHashMap<int, int>(hashCode: (v) => v.hashCode, |
| 88 isValidKey: (v) => v is int)); | 94 isValidKey: (v) => v is int)); |
| 89 testOtherKeys(new LinkedHashMap(equals: (int x, int y) => x == y, | 95 testOtherKeys(new LinkedHashMap(equals: (int x, int y) => x == y, |
| 90 hashCode: (int v) => v.hashCode, | 96 hashCode: (int v) => v.hashCode, |
| 91 isValidKey: (v) => v is int)); | 97 isValidKey: (v) => v is int)); |
| 98 testOtherKeys(new MapBaseMap<int, int>()); |
| 99 |
| 100 testUnmodifiableMap(new UnmodifiableMapView({1 : 37})); |
| 101 testUnmodifiableMap(new UnmodifiableMapBaseMap([1, 37])); |
| 102 testUnmodifiableMap(new MapBaseUnmodifiableMap([1, 37])); |
| 92 } | 103 } |
| 93 | 104 |
| 94 | 105 |
| 95 void test(Map map) { | 106 void test(Map map) { |
| 96 testDeletedElement(map); | 107 testDeletedElement(map); |
| 97 testMap(map, 1, 2, 3, 4, 5, 6, 7, 8); | 108 testMap(map, 1, 2, 3, 4, 5, 6, 7, 8); |
| 98 map.clear(); | 109 map.clear(); |
| 99 testMap(map, "value1", "value2", "value3", "value4", "value5", | 110 testMap(map, "value1", "value2", "value3", "value4", "value5", |
| 100 "value6", "value7", "value8"); | 111 "value6", "value7", "value8"); |
| 101 } | 112 } |
| (...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 697 Expect.isTrue(map.containsKey(c21)); | 708 Expect.isTrue(map.containsKey(c21)); |
| 698 Expect.isFalse(map.containsKey(c12)); | 709 Expect.isFalse(map.containsKey(c12)); |
| 699 Expect.isFalse(map.containsKey(c22)); | 710 Expect.isFalse(map.containsKey(c22)); |
| 700 Expect.equals(37, map[c11]); | 711 Expect.equals(37, map[c11]); |
| 701 Expect.equals(37, map[c21]); | 712 Expect.equals(37, map[c21]); |
| 702 | 713 |
| 703 Expect.equals(37, map.remove(c11)); | 714 Expect.equals(37, map.remove(c11)); |
| 704 testLength(0, map); | 715 testLength(0, map); |
| 705 } | 716 } |
| 706 | 717 |
| 718 void testUnmodifiableMap(Map map) { |
| 719 Expect.isTrue(map.containsKey(1)); |
| 720 testLength(1, map); |
| 721 Expect.equals(1, map.keys.first); |
| 722 Expect.equals(37, map.values.first); |
| 723 |
| 724 Expect.throws(map.clear); |
| 725 Expect.throws(() { map.remove(1); }); |
| 726 Expect.throws(() { map[2] = 42; }); |
| 727 Expect.throws(() { map.addAll({2 : 42}); }); |
| 728 } |
| 729 |
| 707 class Customer { | 730 class Customer { |
| 708 final int id; | 731 final int id; |
| 709 final int secondId; | 732 final int secondId; |
| 710 const Customer(this.id, this.secondId); | 733 const Customer(this.id, this.secondId); |
| 711 int get hashCode => id; | 734 int get hashCode => id; |
| 712 bool operator==(Object other) { | 735 bool operator==(Object other) { |
| 713 if (other is! Customer) return false; | 736 if (other is! Customer) return false; |
| 714 Customer otherCustomer = other; | 737 Customer otherCustomer = other; |
| 715 return id == otherCustomer.id; | 738 return id == otherCustomer.id; |
| 716 } | 739 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 742 Expect.isNull(map["not an int"]); | 765 Expect.isNull(map["not an int"]); |
| 743 Expect.isNull(map[1.5]); | 766 Expect.isNull(map[1.5]); |
| 744 } | 767 } |
| 745 | 768 |
| 746 class Mutable { | 769 class Mutable { |
| 747 int id; | 770 int id; |
| 748 Mutable(this.id); | 771 Mutable(this.id); |
| 749 int get hashCode => id; | 772 int get hashCode => id; |
| 750 bool operator==(other) => other is Mutable && other.id == id; | 773 bool operator==(other) => other is Mutable && other.id == id; |
| 751 } | 774 } |
| 775 |
| 776 |
| 777 // Slow implementation of Map based on MapBase. |
| 778 class MapBaseMap<K, V> extends MapBase<K, V> { |
| 779 final List _keys = <K>[]; |
| 780 final List _values = <V>[]; |
| 781 int _modCount = 0; |
| 782 |
| 783 V operator[](Object key) { |
| 784 int index = _keys.indexOf(key); |
| 785 if (index < 0) return null; |
| 786 return _values[index]; |
| 787 } |
| 788 |
| 789 Iterable<K> get keys => new TestKeyIterable<K>(this); |
| 790 |
| 791 void operator[]=(K key, V value) { |
| 792 int index = _keys.indexOf(key); |
| 793 if (index >= 0) { |
| 794 _values[index] = value; |
| 795 } else { |
| 796 _modCount++; |
| 797 _keys.add(key); |
| 798 _values.add(value); |
| 799 } |
| 800 } |
| 801 |
| 802 V remove(Object key) { |
| 803 int index = _keys.indexOf(key); |
| 804 if (index >= 0) { |
| 805 var result = _values[index]; |
| 806 key = _keys.removeLast(); |
| 807 var value = _values.removeLast(); |
| 808 if (index != _keys.length) { |
| 809 _keys[index] = key; |
| 810 _values[index] = value; |
| 811 } |
| 812 _modCount++; |
| 813 return result; |
| 814 } |
| 815 return null; |
| 816 } |
| 817 |
| 818 void clear() { |
| 819 // Clear cannot be based on remove, since remove won't remove keys that |
| 820 // are not equal to themselves. It will fail the testNaNKeys test. |
| 821 _keys.clear(); |
| 822 _values.clear(); |
| 823 _modCount++; |
| 824 } |
| 825 } |
| 826 |
| 827 class TestKeyIterable<K> extends IterableBase<K> { |
| 828 final _map; |
| 829 TestKeyIterable(this._map); |
| 830 int get length => _map._keys.length; |
| 831 Iterator<K> get iterator => new TestKeyIterator<K>(_map); |
| 832 } |
| 833 |
| 834 class TestKeyIterator<K> implements Iterator<K> { |
| 835 final _map; |
| 836 final int _modCount; |
| 837 int _index = 0; |
| 838 var _current; |
| 839 TestKeyIterator(map) : _map = map, _modCount = map._modCount; |
| 840 bool moveNext() { |
| 841 if (_modCount != _map._modCount) { |
| 842 throw new ConcurrentModificationError(_map); |
| 843 } |
| 844 if (_index == _map._keys.length) { |
| 845 _current = null; |
| 846 return false; |
| 847 } |
| 848 _current = _map._keys[_index++]; |
| 849 return true; |
| 850 } |
| 851 K get current => _current; |
| 852 } |
| 853 |
| 854 // Slow implementation of Map based on MapBase. |
| 855 class UnmodifiableMapBaseMap<K, V> extends UnmodifiableMapBase<K, V> { |
| 856 final List _keys = <K>[]; |
| 857 final List _values = <V>[]; |
| 858 UnmodifiableMapBaseMap(List pairs) { |
| 859 for (int i = 0; i < pairs.length; i += 2) { |
| 860 _keys.add(pairs[i]); |
| 861 _values.add(pairs[i + 1]); |
| 862 } |
| 863 } |
| 864 |
| 865 int get _modCount => 0; |
| 866 |
| 867 V operator[](K key) { |
| 868 int index = _keys.indexOf(key); |
| 869 if (index < 0) return null; |
| 870 return _values[index]; |
| 871 } |
| 872 |
| 873 Iterable<K> get keys => _keys.skip(0); |
| 874 } |
| 875 |
| 876 // Slow implementation of unmodifiable Map based on MapBase and |
| 877 // UnmodifiableMapMixin. |
| 878 class MapBaseUnmodifiableMap<K, V> extends MapBase<K, V> |
| 879 with UnmodifiableMapMixin<K, V> { |
| 880 final List _keys = <K>[]; |
| 881 final List _values = <V>[]; |
| 882 |
| 883 int get _modCount => 0; |
| 884 |
| 885 MapBaseUnmodifiableMap(List pairs) { |
| 886 for (int i = 0; i < pairs.length; i += 2) { |
| 887 _keys.add(pairs[i]); |
| 888 _values.add(pairs[i + 1]); |
| 889 } |
| 890 } |
| 891 |
| 892 V operator[](Object key) { |
| 893 int index = _keys.indexOf(key); |
| 894 if (index < 0) return null; |
| 895 return _values[index]; |
| 896 } |
| 897 |
| 898 Iterable<K> get keys => new TestKeyIterable<K>(this); |
| 899 } |
| OLD | NEW |