| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2013, 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 // Tests of hash set behavior, with focus in iteration and concurrent | |
| 6 // modification errors. | |
| 7 | |
| 8 library hash_map2_test; | |
| 9 import 'dart:collection'; | |
| 10 | |
| 11 testSet(Set newSet(), Set newSetFrom(Set from)) { | |
| 12 Set gen(int from, int to) => | |
| 13 new Set.from(new Iterable.generate(to - from, (n) => n + from)); | |
| 14 | |
| 15 bool odd(int n) => (n & 1) == 1; | |
| 16 bool even(int n) => (n & 1) == 0; | |
| 17 | |
| 18 { // Test growing to largish capacity. | |
| 19 Set set = newSet(); | |
| 20 | |
| 21 for (int i = 0; i < 256; i++) { | |
| 22 set.add(i); | |
| 23 } | |
| 24 set.addAll(gen(256, 512)); | |
| 25 set.addAll(newSetFrom(gen(512, 1000))); | |
| 26 Expect.equals(1000, set.length); | |
| 27 | |
| 28 // Remove half. | |
| 29 for (int i = 0; i < 1000; i += 2) set.remove(i); | |
| 30 Expect.equals(500, set.length); | |
| 31 Expect.isFalse(set.any(even)); | |
| 32 Expect.isTrue(set.every(odd)); | |
| 33 | |
| 34 // Re-add all. | |
| 35 set.addAll(gen(0, 1000)); | |
| 36 Expect.equals(1000, set.length); | |
| 37 } | |
| 38 | |
| 39 { // Test having many deleted elements. | |
| 40 Set set = newSet(); | |
| 41 set.add(0); | |
| 42 for (int i = 0; i < 1000; i++) { | |
| 43 set.add(i + 1); | |
| 44 set.remove(i); | |
| 45 Expect.equals(1, set.length); | |
| 46 } | |
| 47 } | |
| 48 | |
| 49 { // Test having many elements with same hashCode | |
| 50 Set set = newSet(); | |
| 51 for (int i = 0; i < 1000; i++) { | |
| 52 set.add(new BadHashCode()); | |
| 53 } | |
| 54 Expect.equals(1000, set.length); | |
| 55 } | |
| 56 | |
| 57 { // Check concurrent modification | |
| 58 Set set = newSet()..add(0)..add(1); | |
| 59 | |
| 60 { // Test adding before a moveNext. | |
| 61 Iterator iter = set.iterator; | |
| 62 iter.moveNext(); | |
| 63 set.add(1); // Updating existing key isn't a modification. | |
| 64 iter.moveNext(); | |
| 65 set.add(2); | |
| 66 Expect.throws(iter.moveNext, (e) => e is Error); | |
| 67 } | |
| 68 | |
| 69 { // Test adding after last element. | |
| 70 Iterator iter = set.iterator; | |
| 71 Expect.equals(3, set.length); | |
| 72 iter.moveNext(); | |
| 73 iter.moveNext(); | |
| 74 iter.moveNext(); | |
| 75 set.add(3); | |
| 76 Expect.throws(iter.moveNext, (e) => e is Error); | |
| 77 } | |
| 78 | |
| 79 { // Test removing during iteration. | |
| 80 Iterator iter = set.iterator; | |
| 81 iter.moveNext(); | |
| 82 set.remove(1000); // Not a modification if it's not there. | |
| 83 iter.moveNext(); | |
| 84 int n = iter.current; | |
| 85 set.remove(n); | |
| 86 // Removing doesn't change current. | |
| 87 Expect.equals(n, iter.current); | |
| 88 Expect.throws(iter.moveNext, (e) => e is Error); | |
| 89 } | |
| 90 | |
| 91 { // Test removing after last element. | |
| 92 Iterator iter = set.iterator; | |
| 93 Expect.equals(3, set.length); | |
| 94 iter.moveNext(); | |
| 95 iter.moveNext(); | |
| 96 iter.moveNext(); | |
| 97 int n = iter.current; | |
| 98 set.remove(n); | |
| 99 // Removing doesn't change current. | |
| 100 Expect.equals(n, iter.current); | |
| 101 Expect.throws(iter.moveNext, (e) => e is Error); | |
| 102 } | |
| 103 | |
| 104 { // Test that updating value doesn't cause error. | |
| 105 Iterator iter = set.iterator; | |
| 106 Expect.equals(2, set.length); | |
| 107 iter.moveNext(); | |
| 108 int n = iter.current; | |
| 109 set.add(n); | |
| 110 iter.moveNext(); | |
| 111 Expect.isTrue(set.contains(iter.current)); | |
| 112 } | |
| 113 | |
| 114 { // Check adding many existing values isn't considered modification. | |
| 115 Set set2 = newSet(); | |
| 116 for (var value in set) { | |
| 117 set2.add(value); | |
| 118 } | |
| 119 Iterator iter = set.iterator; | |
| 120 set.addAll(set2); | |
| 121 // Shouldn't throw. | |
| 122 iter.moveNext(); | |
| 123 } | |
| 124 } | |
| 125 | |
| 126 { // Check that updating existing elements is not a modification. | |
| 127 // This must be the case even if the underlying data structure is | |
| 128 // nearly full. | |
| 129 for (int i = 1; i < 128; i++) { | |
| 130 // Create maps of different sizes, some of which should be | |
| 131 // at a limit of the underlying data structure. | |
| 132 Set set = newSetFrom(gen(0, i)); | |
| 133 Iterator iter = set.iterator; | |
| 134 for (int j = 0; j < i; j++) { | |
| 135 set.add(j); | |
| 136 } | |
| 137 iter.moveNext(); // Should not throw. | |
| 138 | |
| 139 for (int j = 1; j < i; j++) { | |
| 140 set.remove(j); | |
| 141 } | |
| 142 iter = set.iterator; | |
| 143 set.add(0); | |
| 144 iter.moveNext(); // Should not throw. | |
| 145 } | |
| 146 } | |
| 147 | |
| 148 { // Check that null can be in the set. | |
| 149 Set set = newSet(); | |
| 150 set.add(null); | |
| 151 Expect.equals(1, set.length); | |
| 152 Expect.isTrue(set.contains(null)); | |
| 153 Expect.isNull(set.first); | |
| 154 Expect.isNull(set.last); | |
| 155 set.add(null); | |
| 156 Expect.equals(1, set.length); | |
| 157 Expect.isTrue(set.contains(null)); | |
| 158 set.remove(null); | |
| 159 Expect.isTrue(set.isEmpty); | |
| 160 Expect.isFalse(set.contains(null)); | |
| 161 | |
| 162 // Created using Set.from. | |
| 163 set = newSetFrom([null]); | |
| 164 Expect.equals(1, set.length); | |
| 165 Expect.isTrue(set.contains(null)); | |
| 166 Expect.isNull(set.first); | |
| 167 Expect.isNull(set.last); | |
| 168 set.add(null); | |
| 169 Expect.equals(1, set.length); | |
| 170 Expect.isTrue(set.contains(null)); | |
| 171 set.remove(null); | |
| 172 Expect.isTrue(set.isEmpty); | |
| 173 Expect.isFalse(set.contains(null)); | |
| 174 | |
| 175 // Set that grows with null in it. | |
| 176 set = newSetFrom([1, 2, 3, null, 4, 5, 6]); | |
| 177 Expect.equals(7, set.length); | |
| 178 for (int i = 7; i < 128; i++) { | |
| 179 set.add(i); | |
| 180 } | |
| 181 Expect.equals(128, set.length); | |
| 182 Expect.isTrue(set.contains(null)); | |
| 183 set.add(null); | |
| 184 Expect.equals(128, set.length); | |
| 185 Expect.isTrue(set.contains(null)); | |
| 186 set.remove(null); | |
| 187 Expect.equals(127, set.length); | |
| 188 Expect.isFalse(set.contains(null)); | |
| 189 } | |
| 190 } | |
| 191 | |
| 192 void main() { | |
| 193 testSet(() => new HashSet(), (m) => new HashSet.from(m)); | |
| 194 testSet(() => new LinkedHashSet(), (m) => new LinkedHashSet.from(m)); | |
| 195 } | |
| 196 | |
| 197 | |
| 198 class BadHashCode { | |
| 199 static int idCounter = 0; | |
| 200 final int id; | |
| 201 BadHashCode() : id = idCounter++; | |
| 202 int get hashCode => 42; | |
| 203 // operator == is identity. | |
| 204 // Can't make a bad compareTo that isn't invalid. | |
| 205 int compareTo(BadHashCode other) => id - other.id; | |
| 206 } | |
| OLD | NEW |