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 com.google.common.annotations.GwtCompatible; 20import com.google.common.base.Function; 21import com.google.common.collect.Table.Cell; 22import com.google.common.collect.testing.MapInterfaceTest; 23import com.google.common.collect.testing.SampleElements; 24import com.google.common.collect.testing.TestSetGenerator; 25import com.google.common.collect.testing.features.CollectionFeature; 26import com.google.common.collect.testing.features.CollectionSize; 27import com.google.common.collect.testing.features.Feature; 28 29import junit.framework.TestCase; 30 31import java.util.List; 32import java.util.Map; 33import java.util.Set; 34import java.util.SortedMap; 35 36/** 37 * Collection tests for {@link Table} implementations. 38 * 39 * @author Jared Levy 40 * @author Louis Wasserman 41 */ 42@GwtCompatible(emulated = true) 43public class TableCollectionTest extends TestCase { 44 45 private static final Feature<?>[] COLLECTION_FEATURES = { 46 CollectionSize.ANY, 47 CollectionFeature.ALLOWS_NULL_QUERIES 48 }; 49 50 private static final Feature<?>[] COLLECTION_FEATURES_ORDER = { 51 CollectionSize.ANY, 52 CollectionFeature.KNOWN_ORDER, 53 CollectionFeature.ALLOWS_NULL_QUERIES 54 }; 55 56 private static final Feature<?>[] COLLECTION_FEATURES_REMOVE = { 57 CollectionSize.ANY, 58 CollectionFeature.SUPPORTS_REMOVE, 59 CollectionFeature.ALLOWS_NULL_QUERIES 60 }; 61 62 private static final Feature<?>[] COLLECTION_FEATURES_REMOVE_ORDER = { 63 CollectionSize.ANY, 64 CollectionFeature.KNOWN_ORDER, 65 CollectionFeature.SUPPORTS_REMOVE, 66 CollectionFeature.ALLOWS_NULL_QUERIES 67 }; 68 69 private static void populateForRowKeySet( 70 Table<String, Integer, Character> table, String[] elements) { 71 for (String row : elements) { 72 table.put(row, 1, 'a'); 73 table.put(row, 2, 'b'); 74 } 75 } 76 77 private static void populateForColumnKeySet( 78 Table<Integer, String, Character> table, String[] elements) { 79 for (String column : elements) { 80 table.put(1, column, 'a'); 81 table.put(2, column, 'b'); 82 } 83 } 84 85 private static void populateForValues( 86 Table<Integer, Character, String> table, String[] elements) { 87 for (int i = 0; i < elements.length; i++) { 88 table.put(i, 'a', elements[i]); 89 } 90 } 91 92 private static abstract class TestCellSetGenerator 93 implements TestSetGenerator<Cell<String, Integer, Character>> { 94 @Override 95 public SampleElements<Cell<String, Integer, Character>> samples() { 96 return new SampleElements<Cell<String, Integer, Character>>( 97 Tables.immutableCell("bar", 1, 'a'), 98 Tables.immutableCell("bar", 2, 'b'), 99 Tables.immutableCell("foo", 3, 'c'), 100 Tables.immutableCell("bar", 1, 'b'), 101 Tables.immutableCell("cat", 2, 'b')); 102 } 103 104 @Override 105 public Set<Cell<String, Integer, Character>> create( 106 Object... elements) { 107 Table<String, Integer, Character> table = createTable(); 108 for (Object element : elements) { 109 @SuppressWarnings("unchecked") 110 Cell<String, Integer, Character> cell 111 = (Cell<String, Integer, Character>) element; 112 table.put(cell.getRowKey(), cell.getColumnKey(), cell.getValue()); 113 } 114 return table.cellSet(); 115 } 116 117 abstract Table<String, Integer, Character> createTable(); 118 119 @Override 120 @SuppressWarnings("unchecked") 121 public Cell<String, Integer, Character>[] createArray(int length) { 122 return (Cell<String, Integer, Character>[]) new Cell<?, ?, ?>[length]; 123 } 124 125 @Override 126 public List<Cell<String, Integer, Character>> order( 127 List<Cell<String, Integer, Character>> insertionOrder) { 128 return insertionOrder; 129 } 130 } 131 132 private static abstract class MapTests 133 extends MapInterfaceTest<String, Integer> { 134 135 MapTests(boolean allowsNullValues, boolean supportsPut, boolean supportsRemove, 136 boolean supportsClear, boolean supportsIteratorRemove) { 137 super(false, allowsNullValues, supportsPut, supportsRemove, supportsClear, 138 supportsIteratorRemove); 139 } 140 141 @Override protected String getKeyNotInPopulatedMap() { 142 return "four"; 143 } 144 145 @Override protected Integer getValueNotInPopulatedMap() { 146 return 4; 147 } 148 } 149 150 private static abstract class RowTests extends MapTests { 151 RowTests(boolean allowsNullValues, boolean supportsPut, boolean supportsRemove, 152 boolean supportsClear, boolean supportsIteratorRemove) { 153 super(allowsNullValues, supportsPut, supportsRemove, supportsClear, 154 supportsIteratorRemove); 155 } 156 157 abstract Table<Character, String, Integer> makeTable(); 158 159 @Override protected Map<String, Integer> makeEmptyMap() { 160 return makeTable().row('a'); 161 } 162 163 @Override protected Map<String, Integer> makePopulatedMap() { 164 Table<Character, String, Integer> table = makeTable(); 165 table.put('a', "one", 1); 166 table.put('a', "two", 2); 167 table.put('a', "three", 3); 168 table.put('b', "four", 4); 169 return table.row('a'); 170 } 171 } 172 173 public static class HashRowTests extends RowTests { 174 public HashRowTests() { 175 super(false, true, true, true, true); 176 } 177 178 @Override Table<Character, String, Integer> makeTable() { 179 return HashBasedTable.create(); 180 } 181 } 182 183 public static class TreeRowTests extends RowTests { 184 public TreeRowTests() { 185 super(false, true, true, true, true); 186 } 187 188 @Override Table<Character, String, Integer> makeTable() { 189 return TreeBasedTable.create(); 190 } 191 } 192 193 public static class TransposeRowTests extends RowTests { 194 public TransposeRowTests() { 195 super(false, true, true, true, false); 196 } 197 198 @Override Table<Character, String, Integer> makeTable() { 199 Table<String, Character, Integer> original = TreeBasedTable.create(); 200 return Tables.transpose(original); 201 } 202 } 203 204 private static final Function<Integer, Integer> DIVIDE_BY_2 205 = new Function<Integer, Integer>() { 206 @Override public Integer apply(Integer input) { 207 return (input == null) ? null : input / 2; 208 } 209 }; 210 211 public static class TransformValueRowTests extends RowTests { 212 public TransformValueRowTests() { 213 super(false, false, true, true, true); 214 } 215 216 @Override Table<Character, String, Integer> makeTable() { 217 Table<Character, String, Integer> table = HashBasedTable.create(); 218 return Tables.transformValues(table, DIVIDE_BY_2); 219 } 220 221 @Override protected Map<String, Integer> makePopulatedMap() { 222 Table<Character, String, Integer> table = HashBasedTable.create(); 223 table.put('a', "one", 2); 224 table.put('a', "two", 4); 225 table.put('a', "three", 6); 226 table.put('b', "four", 8); 227 return Tables.transformValues(table, DIVIDE_BY_2).row('a'); 228 } 229 } 230 231 public static class UnmodifiableHashRowTests extends RowTests { 232 public UnmodifiableHashRowTests() { 233 super(false, false, false, false, false); 234 } 235 236 @Override Table<Character, String, Integer> makeTable() { 237 Table<Character, String, Integer> table = HashBasedTable.create(); 238 return Tables.unmodifiableTable(table); 239 } 240 241 @Override protected Map<String, Integer> makePopulatedMap() { 242 Table<Character, String, Integer> table = HashBasedTable.create(); 243 table.put('a', "one", 1); 244 table.put('a', "two", 2); 245 table.put('a', "three", 3); 246 table.put('b', "four", 4); 247 return Tables.unmodifiableTable(table).row('a'); 248 } 249 } 250 251 public static class UnmodifiableTreeRowTests extends RowTests { 252 public UnmodifiableTreeRowTests() { 253 super(false, false, false, false, false); 254 } 255 256 @Override Table<Character, String, Integer> makeTable() { 257 RowSortedTable<Character, String, Integer> table = TreeBasedTable.create(); 258 return Tables.unmodifiableRowSortedTable(table); 259 } 260 261 @Override protected Map<String, Integer> makePopulatedMap() { 262 RowSortedTable<Character, String, Integer> table = TreeBasedTable.create(); 263 table.put('a', "one", 1); 264 table.put('a', "two", 2); 265 table.put('a', "three", 3); 266 table.put('b', "four", 4); 267 return Tables.unmodifiableRowSortedTable(table).row('a'); 268 } 269 } 270 271 private static abstract class ColumnTests extends MapTests { 272 ColumnTests(boolean allowsNullValues, boolean supportsPut, boolean supportsRemove, 273 boolean supportsClear, boolean supportsIteratorRemove) { 274 super(allowsNullValues, supportsPut, supportsRemove, supportsClear, 275 supportsIteratorRemove); 276 } 277 278 abstract Table<String, Character, Integer> makeTable(); 279 280 @Override protected Map<String, Integer> makeEmptyMap() { 281 return makeTable().column('a'); 282 } 283 284 @Override protected Map<String, Integer> makePopulatedMap() { 285 Table<String, Character, Integer> table = makeTable(); 286 table.put("one", 'a', 1); 287 table.put("two", 'a', 2); 288 table.put("three", 'a', 3); 289 table.put("four", 'b', 4); 290 return table.column('a'); 291 } 292 } 293 294 public static class HashColumnTests extends ColumnTests { 295 public HashColumnTests() { 296 super(false, true, true, true, false); 297 } 298 299 @Override Table<String, Character, Integer> makeTable() { 300 return HashBasedTable.create(); 301 } 302 } 303 304 public static class TreeColumnTests extends ColumnTests { 305 public TreeColumnTests() { 306 super(false, true, true, true, false); 307 } 308 309 @Override Table<String, Character, Integer> makeTable() { 310 return TreeBasedTable.create(); 311 } 312 } 313 314 public static class TransposeColumnTests extends ColumnTests { 315 public TransposeColumnTests() { 316 super(false, true, true, true, true); 317 } 318 319 @Override Table<String, Character, Integer> makeTable() { 320 Table<Character, String, Integer> original = TreeBasedTable.create(); 321 return Tables.transpose(original); 322 } 323 } 324 325 public static class TransformValueColumnTests extends ColumnTests { 326 public TransformValueColumnTests() { 327 super(false, false, true, true, false); 328 } 329 330 @Override Table<String, Character, Integer> makeTable() { 331 Table<String, Character, Integer> table = HashBasedTable.create(); 332 return Tables.transformValues(table, DIVIDE_BY_2); 333 } 334 335 @Override protected Map<String, Integer> makePopulatedMap() { 336 Table<String, Character, Integer> table = HashBasedTable.create(); 337 table.put("one", 'a', 1); 338 table.put("two", 'a', 2); 339 table.put("three", 'a', 3); 340 table.put("four", 'b', 4); 341 return Tables.transformValues(table, DIVIDE_BY_2).column('a'); 342 } 343 } 344 345 public static class UnmodifiableHashColumnTests extends ColumnTests { 346 public UnmodifiableHashColumnTests() { 347 super(false, false, false, false, false); 348 } 349 350 @Override Table<String, Character, Integer> makeTable() { 351 Table<String, Character, Integer> table = HashBasedTable.create(); 352 return Tables.unmodifiableTable(table); 353 } 354 355 @Override protected Map<String, Integer> makePopulatedMap() { 356 Table<String, Character, Integer> table = HashBasedTable.create(); 357 table.put("one", 'a', 1); 358 table.put("two", 'a', 2); 359 table.put("three", 'a', 3); 360 table.put("four", 'b', 4); 361 return Tables.unmodifiableTable(table).column('a'); 362 } 363 } 364 365 public static class UnmodifiableTreeColumnTests extends ColumnTests { 366 public UnmodifiableTreeColumnTests() { 367 super(false, false, false, false, false); 368 } 369 370 @Override Table<String, Character, Integer> makeTable() { 371 RowSortedTable<String, Character, Integer> table = TreeBasedTable.create(); 372 return Tables.unmodifiableRowSortedTable(table); 373 } 374 375 @Override protected Map<String, Integer> makePopulatedMap() { 376 RowSortedTable<String, Character, Integer> table = TreeBasedTable.create(); 377 table.put("one", 'a', 1); 378 table.put("two", 'a', 2); 379 table.put("three", 'a', 3); 380 table.put("four", 'b', 4); 381 return Tables.unmodifiableRowSortedTable(table).column('a'); 382 } 383 } 384 385 private static abstract class MapMapTests 386 extends MapInterfaceTest<String, Map<Integer, Character>> { 387 388 MapMapTests(boolean allowsNullValues, boolean supportsRemove, 389 boolean supportsClear, boolean supportsIteratorRemove) { 390 super(false, allowsNullValues, false, supportsRemove, supportsClear, 391 supportsIteratorRemove); 392 } 393 394 @Override protected String getKeyNotInPopulatedMap() { 395 return "cat"; 396 } 397 398 @Override protected Map<Integer, Character> getValueNotInPopulatedMap() { 399 return ImmutableMap.of(); 400 } 401 402 /** 403 * The version of this test supplied by {@link MapInterfaceTest} fails for 404 * this particular map implementation, because {@code map.get()} returns a 405 * view collection that changes in the course of a call to {@code remove()}. 406 * Thus, the expectation doesn't hold that {@code map.remove(x)} returns the 407 * same value which {@code map.get(x)} did immediately beforehand. 408 */ 409 @Override public void testRemove() { 410 final Map<String, Map<Integer, Character>> map; 411 final String keyToRemove; 412 try { 413 map = makePopulatedMap(); 414 } catch (UnsupportedOperationException e) { 415 return; 416 } 417 keyToRemove = map.keySet().iterator().next(); 418 if (supportsRemove) { 419 int initialSize = map.size(); 420 map.get(keyToRemove); 421 map.remove(keyToRemove); 422 // This line doesn't hold - see the Javadoc comments above. 423 // assertEquals(expectedValue, oldValue); 424 assertFalse(map.containsKey(keyToRemove)); 425 assertEquals(initialSize - 1, map.size()); 426 } else { 427 try { 428 map.remove(keyToRemove); 429 fail("Expected UnsupportedOperationException."); 430 } catch (UnsupportedOperationException e) { 431 // Expected. 432 } 433 } 434 assertInvariants(map); 435 } 436 } 437 438 private static abstract class RowMapTests extends MapMapTests { 439 RowMapTests(boolean allowsNullValues, boolean supportsRemove, 440 boolean supportsClear, boolean supportsIteratorRemove) { 441 super(allowsNullValues, supportsRemove, supportsClear, 442 supportsIteratorRemove); 443 } 444 445 abstract Table<String, Integer, Character> makeTable(); 446 447 @Override protected Map<String, Map<Integer, Character>> 448 makePopulatedMap() { 449 Table<String, Integer, Character> table = makeTable(); 450 populateTable(table); 451 return table.rowMap(); 452 } 453 454 void populateTable(Table<String, Integer, Character> table) { 455 table.put("foo", 1, 'a'); 456 table.put("bar", 1, 'b'); 457 table.put("foo", 3, 'c'); 458 } 459 460 @Override protected Map<String, Map<Integer, Character>> makeEmptyMap() { 461 return makeTable().rowMap(); 462 } 463 } 464 465 public static class HashRowMapTests extends RowMapTests { 466 public HashRowMapTests() { 467 super(false, true, true, true); 468 } 469 470 @Override Table<String, Integer, Character> makeTable() { 471 return HashBasedTable.create(); 472 } 473 } 474 475 public static class TreeRowMapTests extends RowMapTests { 476 public TreeRowMapTests() { 477 super(false, true, true, true); 478 } 479 480 @Override Table<String, Integer, Character> makeTable() { 481 return TreeBasedTable.create(); 482 } 483 } 484 485 public static class TreeRowMapHeadMapTests extends RowMapTests { 486 public TreeRowMapHeadMapTests() { 487 super(false, true, true, true); 488 } 489 490 @Override TreeBasedTable<String, Integer, Character> makeTable() { 491 TreeBasedTable<String, Integer, Character> table = 492 TreeBasedTable.create(); 493 table.put("z", 1, 'a'); 494 return table; 495 } 496 497 @Override protected Map<String, Map<Integer, Character>> 498 makePopulatedMap() { 499 TreeBasedTable<String, Integer, Character> table = makeTable(); 500 populateTable(table); 501 return table.rowMap().headMap("x"); 502 } 503 504 @Override protected Map<String, Map<Integer, Character>> makeEmptyMap() { 505 return makeTable().rowMap().headMap("x"); 506 } 507 508 @Override protected String getKeyNotInPopulatedMap() { 509 return "z"; 510 } 511 } 512 513 public static class TreeRowMapTailMapTests extends RowMapTests { 514 public TreeRowMapTailMapTests() { 515 super(false, true, true, true); 516 } 517 518 @Override TreeBasedTable<String, Integer, Character> makeTable() { 519 TreeBasedTable<String, Integer, Character> table = 520 TreeBasedTable.create(); 521 table.put("a", 1, 'a'); 522 return table; 523 } 524 525 @Override protected Map<String, Map<Integer, Character>> 526 makePopulatedMap() { 527 TreeBasedTable<String, Integer, Character> table = makeTable(); 528 populateTable(table); 529 return table.rowMap().tailMap("b"); 530 } 531 532 @Override protected Map<String, Map<Integer, Character>> makeEmptyMap() { 533 return makeTable().rowMap().tailMap("b"); 534 } 535 536 @Override protected String getKeyNotInPopulatedMap() { 537 return "a"; 538 } 539 } 540 541 public static class TreeRowMapSubMapTests extends RowMapTests { 542 public TreeRowMapSubMapTests() { 543 super(false, true, true, true); 544 } 545 546 @Override TreeBasedTable<String, Integer, Character> makeTable() { 547 TreeBasedTable<String, Integer, Character> table = 548 TreeBasedTable.create(); 549 table.put("a", 1, 'a'); 550 table.put("z", 1, 'a'); 551 return table; 552 } 553 554 @Override protected Map<String, Map<Integer, Character>> 555 makePopulatedMap() { 556 TreeBasedTable<String, Integer, Character> table = makeTable(); 557 populateTable(table); 558 return table.rowMap().subMap("b", "x"); 559 } 560 561 @Override protected Map<String, Map<Integer, Character>> makeEmptyMap() { 562 return makeTable().rowMap().subMap("b", "x"); 563 } 564 565 @Override protected String getKeyNotInPopulatedMap() { 566 return "z"; 567 } 568 } 569 570 private static final Function<String, Character> FIRST_CHARACTER = 571 new Function<String, Character>() { 572 @Override 573 public Character apply(String input) { 574 return input == null ? null : input.charAt(0); 575 } 576 }; 577 578 public static class TransformValueRowMapTests extends RowMapTests { 579 public TransformValueRowMapTests() { 580 super(false, true, true, true); 581 } 582 583 @Override Table<String, Integer, Character> makeTable() { 584 Table<String, Integer, String> original = HashBasedTable.create(); 585 return Tables.transformValues(original, FIRST_CHARACTER); 586 } 587 588 @Override 589 protected Map<String, Map<Integer, Character>> makePopulatedMap() { 590 Table<String, Integer, String> table = HashBasedTable.create(); 591 table.put("foo", 1, "apple"); 592 table.put("bar", 1, "banana"); 593 table.put("foo", 3, "cat"); 594 return Tables.transformValues(table, FIRST_CHARACTER).rowMap(); 595 } 596 } 597 598 public static class UnmodifiableHashRowMapTests extends RowMapTests { 599 public UnmodifiableHashRowMapTests() { 600 super(false, false, false, false); 601 } 602 603 @Override Table<String, Integer, Character> makeTable() { 604 Table<String, Integer, Character> original = HashBasedTable.create(); 605 return Tables.unmodifiableTable(original); 606 } 607 608 @Override 609 protected Map<String, Map<Integer, Character>> makePopulatedMap() { 610 Table<String, Integer, Character> table = HashBasedTable.create(); 611 table.put("foo", 1, 'a'); 612 table.put("bar", 1, 'b'); 613 table.put("foo", 3, 'c'); 614 return Tables.unmodifiableTable(table).rowMap(); 615 } 616 } 617 618 public static class UnmodifiableTreeRowMapTests extends RowMapTests { 619 public UnmodifiableTreeRowMapTests() { 620 super(false, false, false, false); 621 } 622 623 @Override RowSortedTable<String, Integer, Character> makeTable() { 624 RowSortedTable<String, Integer, Character> original = TreeBasedTable.create(); 625 return Tables.unmodifiableRowSortedTable(original); 626 } 627 628 @Override 629 protected SortedMap<String, Map<Integer, Character>> makePopulatedMap() { 630 RowSortedTable<String, Integer, Character> table = TreeBasedTable.create(); 631 table.put("foo", 1, 'a'); 632 table.put("bar", 1, 'b'); 633 table.put("foo", 3, 'c'); 634 return Tables.unmodifiableRowSortedTable(table).rowMap(); 635 } 636 } 637 638 private static abstract class ColumnMapTests extends MapMapTests { 639 ColumnMapTests(boolean allowsNullValues, boolean supportsRemove, 640 boolean supportsClear, boolean supportsIteratorRemove) { 641 super(allowsNullValues, supportsRemove, supportsClear, 642 supportsIteratorRemove); 643 } 644 645 abstract Table<Integer, String, Character> makeTable(); 646 647 @Override protected Map<String, Map<Integer, Character>> 648 makePopulatedMap() { 649 Table<Integer, String, Character> table = makeTable(); 650 table.put(1, "foo", 'a'); 651 table.put(1, "bar", 'b'); 652 table.put(3, "foo", 'c'); 653 return table.columnMap(); 654 } 655 656 @Override protected Map<String, Map<Integer, Character>> makeEmptyMap() { 657 return makeTable().columnMap(); 658 } 659 } 660 661 public static class HashColumnMapTests extends ColumnMapTests { 662 public HashColumnMapTests() { 663 super(false, true, true, false); 664 } 665 666 @Override Table<Integer, String, Character> makeTable() { 667 return HashBasedTable.create(); 668 } 669 } 670 671 public static class TreeColumnMapTests extends ColumnMapTests { 672 public TreeColumnMapTests() { 673 super(false, true, true, false); 674 } 675 676 @Override Table<Integer, String, Character> makeTable() { 677 return TreeBasedTable.create(); 678 } 679 } 680 681 public static class TransformValueColumnMapTests extends ColumnMapTests { 682 public TransformValueColumnMapTests() { 683 super(false, true, true, false); 684 } 685 686 @Override Table<Integer, String, Character> makeTable() { 687 Table<Integer, String, String> original = HashBasedTable.create(); 688 return Tables.transformValues(original, FIRST_CHARACTER); 689 } 690 691 @Override 692 protected Map<String, Map<Integer, Character>> makePopulatedMap() { 693 Table<Integer, String, String> table = HashBasedTable.create(); 694 table.put(1, "foo", "apple"); 695 table.put(1, "bar", "banana"); 696 table.put(3, "foo", "cat"); 697 return Tables.transformValues(table, FIRST_CHARACTER).columnMap(); 698 } 699 } 700 701 public static class UnmodifiableHashColumnMapTests extends ColumnMapTests { 702 public UnmodifiableHashColumnMapTests() { 703 super(false, false, false, false); 704 } 705 706 @Override Table<Integer, String, Character> makeTable() { 707 Table<Integer, String, Character> original = HashBasedTable.create(); 708 return Tables.unmodifiableTable(original); 709 } 710 711 @Override 712 protected Map<String, Map<Integer, Character>> makePopulatedMap() { 713 Table<Integer, String, Character> table = HashBasedTable.create(); 714 table.put(1, "foo", 'a'); 715 table.put(1, "bar", 'b'); 716 table.put(3, "foo", 'c'); 717 return Tables.unmodifiableTable(table).columnMap(); 718 } 719 } 720 721 public static class UnmodifiableTreeColumnMapTests extends ColumnMapTests { 722 public UnmodifiableTreeColumnMapTests() { 723 super(false, false, false, false); 724 } 725 726 @Override Table<Integer, String, Character> makeTable() { 727 RowSortedTable<Integer, String, Character> original = TreeBasedTable.create(); 728 return Tables.unmodifiableRowSortedTable(original); 729 } 730 731 @Override 732 protected Map<String, Map<Integer, Character>> makePopulatedMap() { 733 RowSortedTable<Integer, String, Character> table = TreeBasedTable.create(); 734 table.put(1, "foo", 'a'); 735 table.put(1, "bar", 'b'); 736 table.put(3, "foo", 'c'); 737 return Tables.unmodifiableRowSortedTable(table).columnMap(); 738 } 739 } 740} 741 742