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