TableCollectionTest.java revision 7dd252788645e940eada959bdde927426e2531c9
1/* 2 * Copyright (C) 2008 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.google.common.collect; 18 19import static com.google.common.base.Preconditions.checkNotNull; 20import static com.google.common.collect.testing.testers.CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod; 21import static com.google.common.collect.testing.testers.CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod; 22 23import com.google.common.annotations.GwtCompatible; 24import com.google.common.annotations.GwtIncompatible; 25import com.google.common.base.Function; 26import com.google.common.base.Functions; 27import com.google.common.collect.Table.Cell; 28import com.google.common.collect.testing.CollectionTestSuiteBuilder; 29import com.google.common.collect.testing.MapInterfaceTest; 30import com.google.common.collect.testing.SampleElements; 31import com.google.common.collect.testing.SetTestSuiteBuilder; 32import com.google.common.collect.testing.TestSetGenerator; 33import com.google.common.collect.testing.TestStringCollectionGenerator; 34import com.google.common.collect.testing.TestStringSetGenerator; 35import com.google.common.collect.testing.features.CollectionFeature; 36import com.google.common.collect.testing.features.CollectionSize; 37import com.google.common.collect.testing.features.Feature; 38 39import java.util.Arrays; 40import java.util.Collection; 41import java.util.Collections; 42import java.util.List; 43import java.util.Map; 44import java.util.Set; 45import java.util.SortedMap; 46 47import junit.framework.Test; 48import junit.framework.TestCase; 49import junit.framework.TestSuite; 50 51/** 52 * Collection tests for {@link Table} implementations. 53 * 54 * @author Jared Levy 55 * @author Louis Wasserman 56 */ 57@GwtCompatible(emulated = true) 58public class TableCollectionTest extends TestCase { 59 60 private static final Feature<?>[] COLLECTION_FEATURES = { 61 CollectionSize.ANY, 62 CollectionFeature.ALLOWS_NULL_QUERIES 63 }; 64 65 private static final Feature<?>[] COLLECTION_FEATURES_ORDER = { 66 CollectionSize.ANY, 67 CollectionFeature.KNOWN_ORDER, 68 CollectionFeature.ALLOWS_NULL_QUERIES 69 }; 70 71 private static final Feature<?>[] COLLECTION_FEATURES_REMOVE = { 72 CollectionSize.ANY, 73 CollectionFeature.SUPPORTS_REMOVE, 74 CollectionFeature.ALLOWS_NULL_QUERIES 75 }; 76 77 private static final Feature<?>[] COLLECTION_FEATURES_REMOVE_ORDER = { 78 CollectionSize.ANY, 79 CollectionFeature.KNOWN_ORDER, 80 CollectionFeature.SUPPORTS_REMOVE, 81 CollectionFeature.ALLOWS_NULL_QUERIES 82 }; 83 84 @GwtIncompatible("suite") 85 public static Test suite() { 86 TestSuite suite = new TestSuite(); 87 suite.addTestSuite(ArrayRowTests.class); 88 suite.addTestSuite(HashRowTests.class); 89 suite.addTestSuite(TreeRowTests.class); 90 suite.addTestSuite(TransposeRowTests.class); 91 suite.addTestSuite(TransformValueRowTests.class); 92 suite.addTestSuite(UnmodifiableHashRowTests.class); 93 suite.addTestSuite(UnmodifiableTreeRowTests.class); 94 suite.addTestSuite(ArrayColumnTests.class); 95 suite.addTestSuite(HashColumnTests.class); 96 suite.addTestSuite(TreeColumnTests.class); 97 suite.addTestSuite(TransposeColumnTests.class); 98 suite.addTestSuite(TransformValueColumnTests.class); 99 suite.addTestSuite(UnmodifiableHashColumnTests.class); 100 suite.addTestSuite(UnmodifiableTreeColumnTests.class); 101 suite.addTestSuite(ArrayRowMapTests.class); 102 suite.addTestSuite(HashRowMapTests.class); 103 suite.addTestSuite(TreeRowMapTests.class); 104 suite.addTestSuite(TreeRowMapHeadMapTests.class); 105 suite.addTestSuite(TreeRowMapTailMapTests.class); 106 suite.addTestSuite(TreeRowMapSubMapTests.class); 107 suite.addTestSuite(TransformValueRowMapTests.class); 108 suite.addTestSuite(UnmodifiableHashRowMapTests.class); 109 suite.addTestSuite(UnmodifiableTreeRowMapTests.class); 110 suite.addTestSuite(ArrayColumnMapTests.class); 111 suite.addTestSuite(HashColumnMapTests.class); 112 suite.addTestSuite(TreeColumnMapTests.class); 113 suite.addTestSuite(TransformValueColumnMapTests.class); 114 suite.addTestSuite(UnmodifiableHashColumnMapTests.class); 115 suite.addTestSuite(UnmodifiableTreeColumnMapTests.class); 116 117 // Not testing rowKeySet() or columnKeySet() of Table.transformValues() 118 // since the transformation doesn't affect the row and column key sets. 119 120 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 121 @Override protected Set<String> create(String[] elements) { 122 Table<String, Integer, Character> table 123 = ArrayTable.create( 124 ImmutableList.copyOf(elements), ImmutableList.of(1, 2)); 125 populateForRowKeySet(table, elements); 126 return table.rowKeySet(); 127 } 128 }) 129 .named("ArrayTable.rowKeySet") 130 .withFeatures(CollectionSize.ONE, CollectionSize.SEVERAL, 131 CollectionFeature.KNOWN_ORDER, 132 CollectionFeature.REJECTS_DUPLICATES_AT_CREATION, 133 CollectionFeature.ALLOWS_NULL_QUERIES) 134 .createTestSuite()); 135 136 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 137 @Override protected Set<String> create(String[] elements) { 138 Table<String, Integer, Character> table = HashBasedTable.create(); 139 populateForRowKeySet(table, elements); 140 return table.rowKeySet(); 141 } 142 }) 143 .named("HashBasedTable.rowKeySet") 144 .withFeatures(COLLECTION_FEATURES_REMOVE) 145 .createTestSuite()); 146 147 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 148 @Override protected Set<String> create(String[] elements) { 149 Table<String, Integer, Character> table = TreeBasedTable.create(); 150 populateForRowKeySet(table, elements); 151 return table.rowKeySet(); 152 } 153 154 @Override public List<String> order(List<String> insertionOrder) { 155 Collections.sort(insertionOrder); 156 return insertionOrder; 157 } 158 }) 159 .named("TreeBasedTable.rowKeySet") 160 .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) 161 .createTestSuite()); 162 163 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 164 @Override protected Set<String> create(String[] elements) { 165 TreeBasedTable<String, Integer, Character> table 166 = TreeBasedTable.create(); 167 populateForRowKeySet(table, elements); 168 table.put("z", 1, 'a'); 169 return table.rowKeySet().headSet("x"); 170 } 171 172 @Override public List<String> order(List<String> insertionOrder) { 173 Collections.sort(insertionOrder); 174 return insertionOrder; 175 } 176 }) 177 .named("TreeBasedTable.rowKeySet.headSet") 178 .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) 179 .createTestSuite()); 180 181 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 182 @Override protected Set<String> create(String[] elements) { 183 TreeBasedTable<String, Integer, Character> table 184 = TreeBasedTable.create(); 185 populateForRowKeySet(table, elements); 186 table.put("\0", 1, 'a'); 187 return table.rowKeySet().tailSet("a"); 188 } 189 190 @Override public List<String> order(List<String> insertionOrder) { 191 Collections.sort(insertionOrder); 192 return insertionOrder; 193 } 194 }) 195 .named("TreeBasedTable.rowKeySet.tailSet") 196 .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) 197 .createTestSuite()); 198 199 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 200 @Override protected Set<String> create(String[] elements) { 201 TreeBasedTable<String, Integer, Character> table 202 = TreeBasedTable.create(); 203 populateForRowKeySet(table, elements); 204 table.put("\0", 1, 'a'); 205 table.put("z", 1, 'a'); 206 return table.rowKeySet().subSet("a", "x"); 207 } 208 209 @Override public List<String> order(List<String> insertionOrder) { 210 Collections.sort(insertionOrder); 211 return insertionOrder; 212 } 213 }) 214 .named("TreeBasedTable.rowKeySet.subSet") 215 .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) 216 .createTestSuite()); 217 218 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 219 @Override protected Set<String> create(String[] elements) { 220 Table<String, Integer, Character> table = HashBasedTable.create(); 221 populateForRowKeySet(table, elements); 222 return Tables.unmodifiableTable(table).rowKeySet(); 223 } 224 }) 225 .named("unmodifiableTable[HashBasedTable].rowKeySet") 226 .withFeatures(COLLECTION_FEATURES) 227 .createTestSuite()); 228 229 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 230 @Override protected Set<String> create(String[] elements) { 231 RowSortedTable<String, Integer, Character> table = TreeBasedTable.create(); 232 populateForRowKeySet(table, elements); 233 return Tables.unmodifiableRowSortedTable(table).rowKeySet(); 234 } 235 236 @Override public List<String> order(List<String> insertionOrder) { 237 Collections.sort(insertionOrder); 238 return insertionOrder; 239 } 240 }) 241 .named("unmodifiableRowSortedTable[TreeBasedTable].rowKeySet") 242 .withFeatures(COLLECTION_FEATURES_ORDER) 243 .createTestSuite()); 244 245 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 246 @Override protected Set<String> create(String[] elements) { 247 Table<Integer, String, Character> table 248 = ArrayTable.create( 249 ImmutableList.of(1, 2), ImmutableList.copyOf(elements)); 250 populateForColumnKeySet(table, elements); 251 return table.columnKeySet(); 252 } 253 }) 254 .named("ArrayTable.columnKeySet") 255 .withFeatures(CollectionSize.ONE, CollectionSize.SEVERAL, 256 CollectionFeature.KNOWN_ORDER, 257 CollectionFeature.REJECTS_DUPLICATES_AT_CREATION, 258 CollectionFeature.ALLOWS_NULL_QUERIES) 259 .createTestSuite()); 260 261 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 262 @Override protected Set<String> create(String[] elements) { 263 Table<Integer, String, Character> table = HashBasedTable.create(); 264 populateForColumnKeySet(table, elements); 265 return table.columnKeySet(); 266 } 267 }) 268 .named("HashBasedTable.columnKeySet") 269 .withFeatures(COLLECTION_FEATURES_REMOVE) 270 .suppressing(getIteratorUnknownOrderRemoveSupportedMethod()) 271 .createTestSuite()); 272 273 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 274 @Override protected Set<String> create(String[] elements) { 275 Table<Integer, String, Character> table = TreeBasedTable.create(); 276 populateForColumnKeySet(table, elements); 277 return table.columnKeySet(); 278 } 279 280 @Override public List<String> order(List<String> insertionOrder) { 281 Collections.sort(insertionOrder); 282 return insertionOrder; 283 } 284 }) 285 .named("TreeBasedTable.columnKeySet") 286 .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) 287 .suppressing(getIteratorKnownOrderRemoveSupportedMethod()) 288 .createTestSuite()); 289 290 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 291 @Override protected Set<String> create(String[] elements) { 292 Table<Integer, String, Character> table = HashBasedTable.create(); 293 populateForColumnKeySet(table, elements); 294 return Tables.unmodifiableTable(table).columnKeySet(); 295 } 296 }) 297 .named("unmodifiableTable[HashBasedTable].columnKeySet") 298 .withFeatures(COLLECTION_FEATURES) 299 .suppressing(getIteratorUnknownOrderRemoveSupportedMethod()) 300 .createTestSuite()); 301 302 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 303 @Override protected Set<String> create(String[] elements) { 304 RowSortedTable<Integer, String, Character> table = TreeBasedTable.create(); 305 populateForColumnKeySet(table, elements); 306 return Tables.unmodifiableRowSortedTable(table).columnKeySet(); 307 } 308 309 @Override public List<String> order(List<String> insertionOrder) { 310 Collections.sort(insertionOrder); 311 return insertionOrder; 312 } 313 }) 314 .named("unmodifiableRowSortedTable[TreeBasedTable].columnKeySet") 315 .withFeatures(COLLECTION_FEATURES_ORDER) 316 .suppressing(getIteratorKnownOrderRemoveSupportedMethod()) 317 .createTestSuite()); 318 319 suite.addTest(CollectionTestSuiteBuilder.using( 320 new TestStringCollectionGenerator() { 321 @Override protected Collection<String> create(String[] elements) { 322 List<Integer> rowKeys = Lists.newArrayList(); 323 for (int i = 0; i < elements.length; i++) { 324 rowKeys.add(i); 325 } 326 Table<Integer, Character, String> table 327 = ArrayTable.create(rowKeys, ImmutableList.of('a')); 328 populateForValues(table, elements); 329 return table.values(); 330 } 331 }) 332 .named("ArrayTable.values") 333 .withFeatures(CollectionSize.ONE, CollectionSize.SEVERAL, 334 CollectionFeature.ALLOWS_NULL_VALUES, 335 CollectionFeature.KNOWN_ORDER) 336 .createTestSuite()); 337 338 suite.addTest(CollectionTestSuiteBuilder.using( 339 new TestStringCollectionGenerator() { 340 @Override protected Collection<String> create(String[] elements) { 341 Table<Integer, Character, String> table = HashBasedTable.create(); 342 table.put(1, 'a', "foo"); 343 table.clear(); 344 populateForValues(table, elements); 345 return table.values(); 346 } 347 }) 348 .named("HashBasedTable.values") 349 .withFeatures(COLLECTION_FEATURES_REMOVE) 350 .createTestSuite()); 351 352 suite.addTest(CollectionTestSuiteBuilder.using( 353 new TestStringCollectionGenerator() { 354 @Override protected Collection<String> create(String[] elements) { 355 Table<Integer, Character, String> table = TreeBasedTable.create(); 356 table.put(1, 'a', "foo"); 357 table.clear(); 358 populateForValues(table, elements); 359 return table.values(); 360 } 361 }) 362 .named("TreeBasedTable.values") 363 .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) 364 .createTestSuite()); 365 366 final Function<String, String> removeFirstCharacter 367 = new Function<String, String>() { 368 @Override public String apply(String input) { 369 return input.substring(1); 370 } 371 }; 372 373 suite.addTest(CollectionTestSuiteBuilder.using( 374 new TestStringCollectionGenerator() { 375 @Override protected Collection<String> create(String[] elements) { 376 Table<Integer, Character, String> table = HashBasedTable.create(); 377 for (int i = 0; i < elements.length; i++) { 378 table.put(i, 'a', "x" + checkNotNull(elements[i])); 379 } 380 return Tables.transformValues(table, removeFirstCharacter).values(); 381 } 382 }) 383 .named("TransformValues.values") 384 .withFeatures(COLLECTION_FEATURES_REMOVE) 385 .createTestSuite()); 386 387 suite.addTest(CollectionTestSuiteBuilder.using( 388 new TestStringCollectionGenerator() { 389 @Override protected Collection<String> create(String[] elements) { 390 Table<Integer, Character, String> table = HashBasedTable.create(); 391 table.put(1, 'a', "foo"); 392 table.clear(); 393 populateForValues(table, elements); 394 return Tables.unmodifiableTable(table).values(); 395 } 396 }) 397 .named("unmodifiableTable[HashBasedTable].values") 398 .withFeatures(COLLECTION_FEATURES) 399 .createTestSuite()); 400 401 suite.addTest(CollectionTestSuiteBuilder.using( 402 new TestStringCollectionGenerator() { 403 @Override protected Collection<String> create(String[] elements) { 404 RowSortedTable<Integer, Character, String> table = TreeBasedTable.create(); 405 table.put(1, 'a', "foo"); 406 table.clear(); 407 populateForValues(table, elements); 408 return Tables.unmodifiableRowSortedTable(table).values(); 409 } 410 }) 411 .named("unmodifiableTable[TreeBasedTable].values") 412 .withFeatures(COLLECTION_FEATURES_ORDER) 413 .createTestSuite()); 414 415 suite.addTest(SetTestSuiteBuilder.using(new TestCellSetGenerator() { 416 @Override public SampleElements<Cell<String, Integer, Character>> 417 samples() { 418 return new SampleElements<Cell<String, Integer, Character>>( 419 Tables.immutableCell("bar", 1, 'a'), 420 Tables.immutableCell("bar", 2, 'b'), 421 Tables.immutableCell("bar", 3, (Character) null), 422 Tables.immutableCell("bar", 4, 'b'), 423 Tables.immutableCell("bar", 5, 'b')); 424 } 425 @Override public Set<Cell<String, Integer, Character>> create( 426 Object... elements) { 427 List<Integer> columnKeys = Lists.newArrayList(); 428 for (Object element : elements) { 429 @SuppressWarnings("unchecked") 430 Cell<String, Integer, Character> cell 431 = (Cell<String, Integer, Character>) element; 432 columnKeys.add(cell.getColumnKey()); 433 } 434 Table<String, Integer, Character> table 435 = ArrayTable.create(ImmutableList.of("bar"), columnKeys); 436 for (Object element : elements) { 437 @SuppressWarnings("unchecked") 438 Cell<String, Integer, Character> cell 439 = (Cell<String, Integer, Character>) element; 440 table.put(cell.getRowKey(), cell.getColumnKey(), cell.getValue()); 441 } 442 return table.cellSet(); 443 } 444 @Override Table<String, Integer, Character> createTable() { 445 throw new UnsupportedOperationException(); 446 } 447 }) 448 .named("ArrayTable.cellSet") 449 .withFeatures(CollectionSize.ONE, CollectionSize.SEVERAL, 450 CollectionFeature.KNOWN_ORDER, 451 CollectionFeature.REJECTS_DUPLICATES_AT_CREATION, 452 CollectionFeature.ALLOWS_NULL_QUERIES) 453 .createTestSuite()); 454 455 suite.addTest(SetTestSuiteBuilder.using(new TestCellSetGenerator() { 456 @Override Table<String, Integer, Character> createTable() { 457 return HashBasedTable.create(); 458 } 459 }) 460 .named("HashBasedTable.cellSet") 461 .withFeatures(CollectionSize.ANY, CollectionFeature.SUPPORTS_REMOVE, 462 CollectionFeature.ALLOWS_NULL_QUERIES) 463 .createTestSuite()); 464 465 suite.addTest(SetTestSuiteBuilder.using(new TestCellSetGenerator() { 466 @Override Table<String, Integer, Character> createTable() { 467 return TreeBasedTable.create(); 468 } 469 }) 470 .named("TreeBasedTable.cellSet") 471 .withFeatures(CollectionSize.ANY, CollectionFeature.SUPPORTS_REMOVE, 472 CollectionFeature.ALLOWS_NULL_QUERIES) 473 .createTestSuite()); 474 475 suite.addTest(SetTestSuiteBuilder.using(new TestCellSetGenerator() { 476 @Override Table<String, Integer, Character> createTable() { 477 Table<Integer, String, Character> original 478 = TreeBasedTable.create(); 479 return Tables.transpose(original); 480 } 481 }) 482 .named("TransposedTable.cellSet") 483 .withFeatures(CollectionSize.ANY, CollectionFeature.SUPPORTS_REMOVE, 484 CollectionFeature.ALLOWS_NULL_QUERIES) 485 .createTestSuite()); 486 487 suite.addTest(SetTestSuiteBuilder.using(new TestCellSetGenerator() { 488 @Override Table<String, Integer, Character> createTable() { 489 return HashBasedTable.create(); 490 } 491 @Override 492 public Set<Cell<String, Integer, Character>> create( 493 Object... elements) { 494 Table<String, Integer, Character> table = createTable(); 495 for (Object element : elements) { 496 @SuppressWarnings("unchecked") 497 Cell<String, Integer, Character> cell 498 = (Cell<String, Integer, Character>) element; 499 table.put(cell.getRowKey(), cell.getColumnKey(), cell.getValue()); 500 } 501 return Tables.transformValues(table, Functions.<Character>identity()).cellSet(); 502 } 503 }) 504 .named("TransformValues.cellSet") 505 .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_QUERIES, 506 CollectionFeature.SUPPORTS_REMOVE) 507 .createTestSuite()); 508 509 suite.addTest(SetTestSuiteBuilder.using(new TestCellSetGenerator() { 510 @Override Table<String, Integer, Character> createTable() { 511 return Tables.unmodifiableTable(HashBasedTable.<String, Integer, Character> create()); 512 } 513 @Override 514 public Set<Cell<String, Integer, Character>> create( 515 Object... elements) { 516 Table<String, Integer, Character> table = HashBasedTable.create(); 517 for (Object element : elements) { 518 @SuppressWarnings("unchecked") 519 Cell<String, Integer, Character> cell 520 = (Cell<String, Integer, Character>) element; 521 table.put(cell.getRowKey(), cell.getColumnKey(), cell.getValue()); 522 } 523 return Tables.unmodifiableTable(table).cellSet(); 524 } 525 }) 526 .named("unmodifiableTable[HashBasedTable].cellSet") 527 .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_QUERIES) 528 .createTestSuite()); 529 530 suite.addTest(SetTestSuiteBuilder.using(new TestCellSetGenerator() { 531 @Override RowSortedTable<String, Integer, Character> createTable() { 532 return Tables.unmodifiableRowSortedTable(TreeBasedTable 533 .<String, Integer, Character> create()); 534 } 535 @Override 536 public Set<Cell<String, Integer, Character>> create( 537 Object... elements) { 538 RowSortedTable<String, Integer, Character> table = TreeBasedTable.create(); 539 for (Object element : elements) { 540 @SuppressWarnings("unchecked") 541 Cell<String, Integer, Character> cell 542 = (Cell<String, Integer, Character>) element; 543 table.put(cell.getRowKey(), cell.getColumnKey(), cell.getValue()); 544 } 545 return Tables.unmodifiableRowSortedTable(table).cellSet(); 546 } 547 }) 548 .named("unmodifiableRowSortedTable[TreeBasedTable].cellSet") 549 .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_QUERIES) 550 .createTestSuite()); 551 552 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 553 @Override protected Set<String> create(String[] elements) { 554 Iterable<String> rowKeys = ImmutableSet.copyOf(elements); 555 Iterable<Integer> columnKeys = ImmutableList.of(1, 2, 3); 556 Table<String, Integer, Character> table 557 = ArrayTable.create(rowKeys, columnKeys); 558 populateForRowKeySet(table, elements); 559 return table.column(1).keySet(); 560 } 561 }) 562 .named("ArrayTable.column.keySet") 563 .withFeatures(CollectionSize.ONE, CollectionSize.SEVERAL, 564 CollectionFeature.KNOWN_ORDER, 565 CollectionFeature.ALLOWS_NULL_QUERIES) 566 .createTestSuite()); 567 568 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 569 @Override protected Set<String> create(String[] elements) { 570 Table<String, Integer, Character> table = HashBasedTable.create(); 571 populateForRowKeySet(table, elements); 572 return table.column(1).keySet(); 573 } 574 }) 575 .named("HashBasedTable.column.keySet") 576 .withFeatures(COLLECTION_FEATURES_REMOVE) 577 .suppressing(getIteratorUnknownOrderRemoveSupportedMethod()) 578 .createTestSuite()); 579 580 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 581 @Override protected Set<String> create(String[] elements) { 582 Table<String, Integer, Character> table = TreeBasedTable.create(); 583 populateForRowKeySet(table, elements); 584 return table.column(1).keySet(); 585 } 586 @Override public List<String> order(List<String> insertionOrder) { 587 Collections.sort(insertionOrder); 588 return insertionOrder; 589 } 590 }) 591 .named("TreeBasedTable.column.keySet") 592 .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) 593 .suppressing(getIteratorKnownOrderRemoveSupportedMethod()) 594 .createTestSuite()); 595 596 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 597 @Override protected Set<String> create(String[] elements) { 598 Table<String, Integer, Character> table = HashBasedTable.create(); 599 populateForRowKeySet(table, elements); 600 return Tables.transformValues(table, Functions.toStringFunction()).column(1).keySet(); 601 } 602 }) 603 .named("TransformValues.column.keySet") 604 .withFeatures(COLLECTION_FEATURES_REMOVE) 605 .suppressing(getIteratorUnknownOrderRemoveSupportedMethod()) 606 .createTestSuite()); 607 608 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 609 @Override protected Set<String> create(String[] elements) { 610 Table<String, Integer, Character> table = HashBasedTable.create(); 611 populateForRowKeySet(table, elements); 612 return Tables.unmodifiableTable(table).column(1).keySet(); 613 } 614 }) 615 .named("unmodifiableTable[HashBasedTable].column.keySet") 616 .withFeatures(COLLECTION_FEATURES) 617 .suppressing(getIteratorUnknownOrderRemoveSupportedMethod()) 618 .createTestSuite()); 619 620 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 621 @Override protected Set<String> create(String[] elements) { 622 RowSortedTable<String, Integer, Character> table = TreeBasedTable.create(); 623 populateForRowKeySet(table, elements); 624 return Tables.unmodifiableRowSortedTable(table).column(1).keySet(); 625 } 626 @Override public List<String> order(List<String> insertionOrder) { 627 Collections.sort(insertionOrder); 628 return insertionOrder; 629 } 630 }) 631 .named("unmodifiableRowSortedTable[TreeBasedTable].column.keySet") 632 .withFeatures(COLLECTION_FEATURES_ORDER) 633 .suppressing(getIteratorKnownOrderRemoveSupportedMethod()) 634 .createTestSuite()); 635 636 return suite; 637 } 638 639 private static void populateForRowKeySet( 640 Table<String, Integer, Character> table, String[] elements) { 641 for (String row : elements) { 642 table.put(row, 1, 'a'); 643 table.put(row, 2, 'b'); 644 } 645 } 646 647 private static void populateForColumnKeySet( 648 Table<Integer, String, Character> table, String[] elements) { 649 for (String column : elements) { 650 table.put(1, column, 'a'); 651 table.put(2, column, 'b'); 652 } 653 } 654 655 private static void populateForValues( 656 Table<Integer, Character, String> table, String[] elements) { 657 for (int i = 0; i < elements.length; i++) { 658 table.put(i, 'a', elements[i]); 659 } 660 } 661 662 private static abstract class TestCellSetGenerator 663 implements TestSetGenerator<Cell<String, Integer, Character>> { 664 @Override 665 public SampleElements<Cell<String, Integer, Character>> samples() { 666 return new SampleElements<Cell<String, Integer, Character>>( 667 Tables.immutableCell("bar", 1, 'a'), 668 Tables.immutableCell("bar", 2, 'b'), 669 Tables.immutableCell("foo", 3, 'c'), 670 Tables.immutableCell("bar", 1, 'b'), 671 Tables.immutableCell("cat", 2, 'b')); 672 } 673 674 @Override 675 public Set<Cell<String, Integer, Character>> create( 676 Object... elements) { 677 Table<String, Integer, Character> table = createTable(); 678 for (Object element : elements) { 679 @SuppressWarnings("unchecked") 680 Cell<String, Integer, Character> cell 681 = (Cell<String, Integer, Character>) element; 682 table.put(cell.getRowKey(), cell.getColumnKey(), cell.getValue()); 683 } 684 return table.cellSet(); 685 } 686 687 abstract Table<String, Integer, Character> createTable(); 688 689 @Override 690 @SuppressWarnings("unchecked") 691 public Cell<String, Integer, Character>[] createArray(int length) { 692 return (Cell<String, Integer, Character>[]) new Cell<?, ?, ?>[length]; 693 } 694 695 @Override 696 public List<Cell<String, Integer, Character>> order( 697 List<Cell<String, Integer, Character>> insertionOrder) { 698 return insertionOrder; 699 } 700 } 701 702 private static abstract class MapTests 703 extends MapInterfaceTest<String, Integer> { 704 705 MapTests(boolean allowsNullValues, boolean supportsPut, boolean supportsRemove, 706 boolean supportsClear, boolean supportsIteratorRemove) { 707 super(false, allowsNullValues, supportsPut, supportsRemove, supportsClear, 708 supportsIteratorRemove); 709 } 710 711 @Override protected String getKeyNotInPopulatedMap() { 712 return "four"; 713 } 714 715 @Override protected Integer getValueNotInPopulatedMap() { 716 return 4; 717 } 718 } 719 720 private static abstract class RowTests extends MapTests { 721 RowTests(boolean allowsNullValues, boolean supportsPut, boolean supportsRemove, 722 boolean supportsClear, boolean supportsIteratorRemove) { 723 super(allowsNullValues, supportsPut, supportsRemove, supportsClear, 724 supportsIteratorRemove); 725 } 726 727 abstract Table<Character, String, Integer> makeTable(); 728 729 @Override protected Map<String, Integer> makeEmptyMap() { 730 return makeTable().row('a'); 731 } 732 733 @Override protected Map<String, Integer> makePopulatedMap() { 734 Table<Character, String, Integer> table = makeTable(); 735 table.put('a', "one", 1); 736 table.put('a', "two", 2); 737 table.put('a', "three", 3); 738 table.put('b', "four", 4); 739 return table.row('a'); 740 } 741 } 742 743 @GwtIncompatible("TODO(hhchan): ArrayTable") 744 public static class ArrayRowTests extends RowTests { 745 public ArrayRowTests() { 746 super(true, true, false, false, false); 747 } 748 749 @Override protected String getKeyNotInPopulatedMap() { 750 throw new UnsupportedOperationException(); 751 } 752 753 @Override protected Map<String, Integer> makeEmptyMap() { 754 throw new UnsupportedOperationException(); 755 } 756 757 @Override protected Table<Character, String, Integer> makeTable() { 758 return ArrayTable.create(Arrays.asList('a', 'b', 'c'), 759 Arrays.asList("one", "two", "three", "four")); 760 } 761 } 762 763 public static class HashRowTests extends RowTests { 764 public HashRowTests() { 765 super(false, true, true, true, true); 766 } 767 768 @Override Table<Character, String, Integer> makeTable() { 769 return HashBasedTable.create(); 770 } 771 } 772 773 public static class TreeRowTests extends RowTests { 774 public TreeRowTests() { 775 super(false, true, true, true, true); 776 } 777 778 @Override Table<Character, String, Integer> makeTable() { 779 return TreeBasedTable.create(); 780 } 781 } 782 783 public static class TransposeRowTests extends RowTests { 784 public TransposeRowTests() { 785 super(false, true, true, true, false); 786 } 787 788 @Override Table<Character, String, Integer> makeTable() { 789 Table<String, Character, Integer> original = TreeBasedTable.create(); 790 return Tables.transpose(original); 791 } 792 } 793 794 private static final Function<Integer, Integer> DIVIDE_BY_2 795 = new Function<Integer, Integer>() { 796 @Override public Integer apply(Integer input) { 797 return (input == null) ? null : input / 2; 798 } 799 }; 800 801 public static class TransformValueRowTests extends RowTests { 802 public TransformValueRowTests() { 803 super(false, false, true, true, true); 804 } 805 806 @Override Table<Character, String, Integer> makeTable() { 807 Table<Character, String, Integer> table = HashBasedTable.create(); 808 return Tables.transformValues(table, DIVIDE_BY_2); 809 } 810 811 @Override protected Map<String, Integer> makePopulatedMap() { 812 Table<Character, String, Integer> table = HashBasedTable.create(); 813 table.put('a', "one", 2); 814 table.put('a', "two", 4); 815 table.put('a', "three", 6); 816 table.put('b', "four", 8); 817 return Tables.transformValues(table, DIVIDE_BY_2).row('a'); 818 } 819 } 820 821 public static class UnmodifiableHashRowTests extends RowTests { 822 public UnmodifiableHashRowTests() { 823 super(false, false, false, false, false); 824 } 825 826 @Override Table<Character, String, Integer> makeTable() { 827 Table<Character, String, Integer> table = HashBasedTable.create(); 828 return Tables.unmodifiableTable(table); 829 } 830 831 @Override protected Map<String, Integer> makePopulatedMap() { 832 Table<Character, String, Integer> table = HashBasedTable.create(); 833 table.put('a', "one", 1); 834 table.put('a', "two", 2); 835 table.put('a', "three", 3); 836 table.put('b', "four", 4); 837 return Tables.unmodifiableTable(table).row('a'); 838 } 839 } 840 841 public static class UnmodifiableTreeRowTests extends RowTests { 842 public UnmodifiableTreeRowTests() { 843 super(false, false, false, false, false); 844 } 845 846 @Override Table<Character, String, Integer> makeTable() { 847 RowSortedTable<Character, String, Integer> table = TreeBasedTable.create(); 848 return Tables.unmodifiableRowSortedTable(table); 849 } 850 851 @Override protected Map<String, Integer> makePopulatedMap() { 852 RowSortedTable<Character, String, Integer> table = TreeBasedTable.create(); 853 table.put('a', "one", 1); 854 table.put('a', "two", 2); 855 table.put('a', "three", 3); 856 table.put('b', "four", 4); 857 return Tables.unmodifiableRowSortedTable(table).row('a'); 858 } 859 } 860 861 private static abstract class ColumnTests extends MapTests { 862 ColumnTests(boolean allowsNullValues, boolean supportsPut, boolean supportsRemove, 863 boolean supportsClear, boolean supportsIteratorRemove) { 864 super(allowsNullValues, supportsPut, supportsRemove, supportsClear, 865 supportsIteratorRemove); 866 } 867 868 abstract Table<String, Character, Integer> makeTable(); 869 870 @Override protected Map<String, Integer> makeEmptyMap() { 871 return makeTable().column('a'); 872 } 873 874 @Override protected Map<String, Integer> makePopulatedMap() { 875 Table<String, Character, Integer> table = makeTable(); 876 table.put("one", 'a', 1); 877 table.put("two", 'a', 2); 878 table.put("three", 'a', 3); 879 table.put("four", 'b', 4); 880 return table.column('a'); 881 } 882 } 883 884 @GwtIncompatible("TODO(hhchan): ArrayTable") 885 public static class ArrayColumnTests extends ColumnTests { 886 public ArrayColumnTests() { 887 super(true, true, false, false, false); 888 } 889 890 @Override protected String getKeyNotInPopulatedMap() { 891 throw new UnsupportedOperationException(); 892 } 893 894 @Override protected Map<String, Integer> makeEmptyMap() { 895 throw new UnsupportedOperationException(); 896 } 897 898 @Override Table<String, Character, Integer> makeTable() { 899 return ArrayTable.create(Arrays.asList("one", "two", "three", "four"), 900 Arrays.asList('a', 'b', 'c')); 901 } 902 } 903 904 public static class HashColumnTests extends ColumnTests { 905 public HashColumnTests() { 906 super(false, true, true, true, false); 907 } 908 909 @Override Table<String, Character, Integer> makeTable() { 910 return HashBasedTable.create(); 911 } 912 } 913 914 public static class TreeColumnTests extends ColumnTests { 915 public TreeColumnTests() { 916 super(false, true, true, true, false); 917 } 918 919 @Override Table<String, Character, Integer> makeTable() { 920 return TreeBasedTable.create(); 921 } 922 } 923 924 public static class TransposeColumnTests extends ColumnTests { 925 public TransposeColumnTests() { 926 super(false, true, true, true, true); 927 } 928 929 @Override Table<String, Character, Integer> makeTable() { 930 Table<Character, String, Integer> original = TreeBasedTable.create(); 931 return Tables.transpose(original); 932 } 933 } 934 935 public static class TransformValueColumnTests extends ColumnTests { 936 public TransformValueColumnTests() { 937 super(false, false, true, true, false); 938 } 939 940 @Override Table<String, Character, Integer> makeTable() { 941 Table<String, Character, Integer> table = HashBasedTable.create(); 942 return Tables.transformValues(table, DIVIDE_BY_2); 943 } 944 945 @Override protected Map<String, Integer> makePopulatedMap() { 946 Table<String, Character, Integer> table = HashBasedTable.create(); 947 table.put("one", 'a', 1); 948 table.put("two", 'a', 2); 949 table.put("three", 'a', 3); 950 table.put("four", 'b', 4); 951 return Tables.transformValues(table, DIVIDE_BY_2).column('a'); 952 } 953 } 954 955 public static class UnmodifiableHashColumnTests extends ColumnTests { 956 public UnmodifiableHashColumnTests() { 957 super(false, false, false, false, false); 958 } 959 960 @Override Table<String, Character, Integer> makeTable() { 961 Table<String, Character, Integer> table = HashBasedTable.create(); 962 return Tables.unmodifiableTable(table); 963 } 964 965 @Override protected Map<String, Integer> makePopulatedMap() { 966 Table<String, Character, Integer> table = HashBasedTable.create(); 967 table.put("one", 'a', 1); 968 table.put("two", 'a', 2); 969 table.put("three", 'a', 3); 970 table.put("four", 'b', 4); 971 return Tables.unmodifiableTable(table).column('a'); 972 } 973 } 974 975 public static class UnmodifiableTreeColumnTests extends ColumnTests { 976 public UnmodifiableTreeColumnTests() { 977 super(false, false, false, false, false); 978 } 979 980 @Override Table<String, Character, Integer> makeTable() { 981 RowSortedTable<String, Character, Integer> table = TreeBasedTable.create(); 982 return Tables.unmodifiableRowSortedTable(table); 983 } 984 985 @Override protected Map<String, Integer> makePopulatedMap() { 986 RowSortedTable<String, Character, Integer> table = TreeBasedTable.create(); 987 table.put("one", 'a', 1); 988 table.put("two", 'a', 2); 989 table.put("three", 'a', 3); 990 table.put("four", 'b', 4); 991 return Tables.unmodifiableRowSortedTable(table).column('a'); 992 } 993 } 994 995 private static abstract class MapMapTests 996 extends MapInterfaceTest<String, Map<Integer, Character>> { 997 998 MapMapTests(boolean allowsNullValues, boolean supportsRemove, 999 boolean supportsClear, boolean supportsIteratorRemove) { 1000 super(false, allowsNullValues, false, supportsRemove, supportsClear, 1001 supportsIteratorRemove); 1002 } 1003 1004 @Override protected String getKeyNotInPopulatedMap() { 1005 return "cat"; 1006 } 1007 1008 @Override protected Map<Integer, Character> getValueNotInPopulatedMap() { 1009 return ImmutableMap.of(); 1010 } 1011 1012 /** 1013 * The version of this test supplied by {@link MapInterfaceTest} fails for 1014 * this particular map implementation, because {@code map.get()} returns a 1015 * view collection that changes in the course of a call to {@code remove()}. 1016 * Thus, the expectation doesn't hold that {@code map.remove(x)} returns the 1017 * same value which {@code map.get(x)} did immediately beforehand. 1018 */ 1019 @Override public void testRemove() { 1020 final Map<String, Map<Integer, Character>> map; 1021 final String keyToRemove; 1022 try { 1023 map = makePopulatedMap(); 1024 } catch (UnsupportedOperationException e) { 1025 return; 1026 } 1027 keyToRemove = map.keySet().iterator().next(); 1028 if (supportsRemove) { 1029 int initialSize = map.size(); 1030 map.get(keyToRemove); 1031 map.remove(keyToRemove); 1032 // This line doesn't hold - see the Javadoc comments above. 1033 // assertEquals(expectedValue, oldValue); 1034 assertFalse(map.containsKey(keyToRemove)); 1035 assertEquals(initialSize - 1, map.size()); 1036 } else { 1037 try { 1038 map.remove(keyToRemove); 1039 fail("Expected UnsupportedOperationException."); 1040 } catch (UnsupportedOperationException e) { 1041 // Expected. 1042 } 1043 } 1044 assertInvariants(map); 1045 } 1046 } 1047 1048 private static abstract class RowMapTests extends MapMapTests { 1049 RowMapTests(boolean allowsNullValues, boolean supportsRemove, 1050 boolean supportsClear, boolean supportsIteratorRemove) { 1051 super(allowsNullValues, supportsRemove, supportsClear, 1052 supportsIteratorRemove); 1053 } 1054 1055 abstract Table<String, Integer, Character> makeTable(); 1056 1057 @Override protected Map<String, Map<Integer, Character>> 1058 makePopulatedMap() { 1059 Table<String, Integer, Character> table = makeTable(); 1060 populateTable(table); 1061 return table.rowMap(); 1062 } 1063 1064 void populateTable(Table<String, Integer, Character> table) { 1065 table.put("foo", 1, 'a'); 1066 table.put("bar", 1, 'b'); 1067 table.put("foo", 3, 'c'); 1068 } 1069 1070 @Override protected Map<String, Map<Integer, Character>> makeEmptyMap() { 1071 return makeTable().rowMap(); 1072 } 1073 } 1074 1075 @GwtIncompatible("TODO(hhchan): ArrayTable") 1076 public static class ArrayRowMapTests extends RowMapTests { 1077 public ArrayRowMapTests() { 1078 super(true, false, false, false); 1079 } 1080 1081 @Override Table<String, Integer, Character> makeTable() { 1082 return ArrayTable.create(Arrays.asList("foo", "bar", "dog"), 1083 Arrays.asList(1, 2, 3)); 1084 } 1085 1086 @Override protected Map<String, Map<Integer, Character>> makeEmptyMap() { 1087 throw new UnsupportedOperationException(); 1088 } 1089 } 1090 1091 public static class HashRowMapTests extends RowMapTests { 1092 public HashRowMapTests() { 1093 super(false, true, true, true); 1094 } 1095 1096 @Override Table<String, Integer, Character> makeTable() { 1097 return HashBasedTable.create(); 1098 } 1099 } 1100 1101 public static class TreeRowMapTests extends RowMapTests { 1102 public TreeRowMapTests() { 1103 super(false, true, true, true); 1104 } 1105 1106 @Override Table<String, Integer, Character> makeTable() { 1107 return TreeBasedTable.create(); 1108 } 1109 } 1110 1111 public static class TreeRowMapHeadMapTests extends RowMapTests { 1112 public TreeRowMapHeadMapTests() { 1113 super(false, true, true, true); 1114 } 1115 1116 @Override TreeBasedTable<String, Integer, Character> makeTable() { 1117 TreeBasedTable<String, Integer, Character> table = 1118 TreeBasedTable.create(); 1119 table.put("z", 1, 'a'); 1120 return table; 1121 } 1122 1123 @Override protected Map<String, Map<Integer, Character>> 1124 makePopulatedMap() { 1125 TreeBasedTable<String, Integer, Character> table = makeTable(); 1126 populateTable(table); 1127 return table.rowMap().headMap("x"); 1128 } 1129 1130 @Override protected Map<String, Map<Integer, Character>> makeEmptyMap() { 1131 return makeTable().rowMap().headMap("x"); 1132 } 1133 1134 @Override protected String getKeyNotInPopulatedMap() { 1135 return "z"; 1136 } 1137 } 1138 1139 public static class TreeRowMapTailMapTests extends RowMapTests { 1140 public TreeRowMapTailMapTests() { 1141 super(false, true, true, true); 1142 } 1143 1144 @Override TreeBasedTable<String, Integer, Character> makeTable() { 1145 TreeBasedTable<String, Integer, Character> table = 1146 TreeBasedTable.create(); 1147 table.put("a", 1, 'a'); 1148 return table; 1149 } 1150 1151 @Override protected Map<String, Map<Integer, Character>> 1152 makePopulatedMap() { 1153 TreeBasedTable<String, Integer, Character> table = makeTable(); 1154 populateTable(table); 1155 return table.rowMap().tailMap("b"); 1156 } 1157 1158 @Override protected Map<String, Map<Integer, Character>> makeEmptyMap() { 1159 return makeTable().rowMap().tailMap("b"); 1160 } 1161 1162 @Override protected String getKeyNotInPopulatedMap() { 1163 return "a"; 1164 } 1165 } 1166 1167 public static class TreeRowMapSubMapTests extends RowMapTests { 1168 public TreeRowMapSubMapTests() { 1169 super(false, true, true, true); 1170 } 1171 1172 @Override TreeBasedTable<String, Integer, Character> makeTable() { 1173 TreeBasedTable<String, Integer, Character> table = 1174 TreeBasedTable.create(); 1175 table.put("a", 1, 'a'); 1176 table.put("z", 1, 'a'); 1177 return table; 1178 } 1179 1180 @Override protected Map<String, Map<Integer, Character>> 1181 makePopulatedMap() { 1182 TreeBasedTable<String, Integer, Character> table = makeTable(); 1183 populateTable(table); 1184 return table.rowMap().subMap("b", "x"); 1185 } 1186 1187 @Override protected Map<String, Map<Integer, Character>> makeEmptyMap() { 1188 return makeTable().rowMap().subMap("b", "x"); 1189 } 1190 1191 @Override protected String getKeyNotInPopulatedMap() { 1192 return "z"; 1193 } 1194 } 1195 1196 private static final Function<String, Character> FIRST_CHARACTER = 1197 new Function<String, Character>() { 1198 @Override 1199 public Character apply(String input) { 1200 return input == null ? null : input.charAt(0); 1201 } 1202 }; 1203 1204 public static class TransformValueRowMapTests extends RowMapTests { 1205 public TransformValueRowMapTests() { 1206 super(false, true, true, true); 1207 } 1208 1209 @Override Table<String, Integer, Character> makeTable() { 1210 Table<String, Integer, String> original = HashBasedTable.create(); 1211 return Tables.transformValues(original, FIRST_CHARACTER); 1212 } 1213 1214 @Override 1215 protected Map<String, Map<Integer, Character>> makePopulatedMap() { 1216 Table<String, Integer, String> table = HashBasedTable.create(); 1217 table.put("foo", 1, "apple"); 1218 table.put("bar", 1, "banana"); 1219 table.put("foo", 3, "cat"); 1220 return Tables.transformValues(table, FIRST_CHARACTER).rowMap(); 1221 } 1222 } 1223 1224 public static class UnmodifiableHashRowMapTests extends RowMapTests { 1225 public UnmodifiableHashRowMapTests() { 1226 super(false, false, false, false); 1227 } 1228 1229 @Override Table<String, Integer, Character> makeTable() { 1230 Table<String, Integer, Character> original = HashBasedTable.create(); 1231 return Tables.unmodifiableTable(original); 1232 } 1233 1234 @Override 1235 protected Map<String, Map<Integer, Character>> makePopulatedMap() { 1236 Table<String, Integer, Character> table = HashBasedTable.create(); 1237 table.put("foo", 1, 'a'); 1238 table.put("bar", 1, 'b'); 1239 table.put("foo", 3, 'c'); 1240 return Tables.unmodifiableTable(table).rowMap(); 1241 } 1242 } 1243 1244 public static class UnmodifiableTreeRowMapTests extends RowMapTests { 1245 public UnmodifiableTreeRowMapTests() { 1246 super(false, false, false, false); 1247 } 1248 1249 @Override RowSortedTable<String, Integer, Character> makeTable() { 1250 RowSortedTable<String, Integer, Character> original = TreeBasedTable.create(); 1251 return Tables.unmodifiableRowSortedTable(original); 1252 } 1253 1254 @Override 1255 protected SortedMap<String, Map<Integer, Character>> makePopulatedMap() { 1256 RowSortedTable<String, Integer, Character> table = TreeBasedTable.create(); 1257 table.put("foo", 1, 'a'); 1258 table.put("bar", 1, 'b'); 1259 table.put("foo", 3, 'c'); 1260 return Tables.unmodifiableRowSortedTable(table).rowMap(); 1261 } 1262 } 1263 1264 private static abstract class ColumnMapTests extends MapMapTests { 1265 ColumnMapTests(boolean allowsNullValues, boolean supportsRemove, 1266 boolean supportsClear, boolean supportsIteratorRemove) { 1267 super(allowsNullValues, supportsRemove, supportsClear, 1268 supportsIteratorRemove); 1269 } 1270 1271 abstract Table<Integer, String, Character> makeTable(); 1272 1273 @Override protected Map<String, Map<Integer, Character>> 1274 makePopulatedMap() { 1275 Table<Integer, String, Character> table = makeTable(); 1276 table.put(1, "foo", 'a'); 1277 table.put(1, "bar", 'b'); 1278 table.put(3, "foo", 'c'); 1279 return table.columnMap(); 1280 } 1281 1282 @Override protected Map<String, Map<Integer, Character>> makeEmptyMap() { 1283 return makeTable().columnMap(); 1284 } 1285 } 1286 1287 @GwtIncompatible("TODO(hhchan): ArrayTable") 1288 public static class ArrayColumnMapTests extends ColumnMapTests { 1289 public ArrayColumnMapTests() { 1290 super(true, false, false, false); 1291 } 1292 1293 @Override Table<Integer, String, Character> makeTable() { 1294 return ArrayTable.create(Arrays.asList(1, 2, 3), 1295 Arrays.asList("foo", "bar", "dog")); 1296 } 1297 1298 @Override protected Map<String, Map<Integer, Character>> makeEmptyMap() { 1299 throw new UnsupportedOperationException(); 1300 } 1301 } 1302 1303 public static class HashColumnMapTests extends ColumnMapTests { 1304 public HashColumnMapTests() { 1305 super(false, true, true, false); 1306 } 1307 1308 @Override Table<Integer, String, Character> makeTable() { 1309 return HashBasedTable.create(); 1310 } 1311 } 1312 1313 public static class TreeColumnMapTests extends ColumnMapTests { 1314 public TreeColumnMapTests() { 1315 super(false, true, true, false); 1316 } 1317 1318 @Override Table<Integer, String, Character> makeTable() { 1319 return TreeBasedTable.create(); 1320 } 1321 } 1322 1323 public static class TransformValueColumnMapTests extends ColumnMapTests { 1324 public TransformValueColumnMapTests() { 1325 super(false, true, true, false); 1326 } 1327 1328 @Override Table<Integer, String, Character> makeTable() { 1329 Table<Integer, String, String> original = HashBasedTable.create(); 1330 return Tables.transformValues(original, FIRST_CHARACTER); 1331 } 1332 1333 @Override 1334 protected Map<String, Map<Integer, Character>> makePopulatedMap() { 1335 Table<Integer, String, String> table = HashBasedTable.create(); 1336 table.put(1, "foo", "apple"); 1337 table.put(1, "bar", "banana"); 1338 table.put(3, "foo", "cat"); 1339 return Tables.transformValues(table, FIRST_CHARACTER).columnMap(); 1340 } 1341 } 1342 1343 public static class UnmodifiableHashColumnMapTests extends ColumnMapTests { 1344 public UnmodifiableHashColumnMapTests() { 1345 super(false, false, false, false); 1346 } 1347 1348 @Override Table<Integer, String, Character> makeTable() { 1349 Table<Integer, String, Character> original = HashBasedTable.create(); 1350 return Tables.unmodifiableTable(original); 1351 } 1352 1353 @Override 1354 protected Map<String, Map<Integer, Character>> makePopulatedMap() { 1355 Table<Integer, String, Character> table = HashBasedTable.create(); 1356 table.put(1, "foo", 'a'); 1357 table.put(1, "bar", 'b'); 1358 table.put(3, "foo", 'c'); 1359 return Tables.unmodifiableTable(table).columnMap(); 1360 } 1361 } 1362 1363 public static class UnmodifiableTreeColumnMapTests extends ColumnMapTests { 1364 public UnmodifiableTreeColumnMapTests() { 1365 super(false, false, false, false); 1366 } 1367 1368 @Override Table<Integer, String, Character> makeTable() { 1369 RowSortedTable<Integer, String, Character> original = TreeBasedTable.create(); 1370 return Tables.unmodifiableRowSortedTable(original); 1371 } 1372 1373 @Override 1374 protected Map<String, Map<Integer, Character>> makePopulatedMap() { 1375 RowSortedTable<Integer, String, Character> table = TreeBasedTable.create(); 1376 table.put(1, "foo", 'a'); 1377 table.put(1, "bar", 'b'); 1378 table.put(3, "foo", 'c'); 1379 return Tables.unmodifiableRowSortedTable(table).columnMap(); 1380 } 1381 } 1382} 1383