1 /* 2 * Copyright (C) 2009 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.truth.Truth.assertThat; 20 import static java.util.Arrays.asList; 21 22 import com.google.common.annotations.GwtCompatible; 23 import com.google.common.annotations.GwtIncompatible; 24 import com.google.common.base.Objects; 25 import com.google.common.collect.Table.Cell; 26 import com.google.common.testing.EqualsTester; 27 import com.google.common.testing.NullPointerTester; 28 import com.google.common.testing.SerializableTester; 29 import java.util.Arrays; 30 import java.util.Map; 31 32 /** 33 * Test cases for {@link ArrayTable}. 34 * 35 * @author Jared Levy 36 */ 37 @GwtCompatible(emulated = true) 38 public class ArrayTableTest extends AbstractTableTest { 39 40 @Override create(Object... data)41 protected ArrayTable<String, Integer, Character> create(Object... data) { 42 // TODO: Specify different numbers of rows and columns, to detect problems 43 // that arise when the wrong size is used. 44 ArrayTable<String, Integer, Character> table = 45 ArrayTable.create(asList("foo", "bar", "cat"), asList(1, 2, 3)); 46 populate(table, data); 47 return table; 48 } 49 50 @Override assertSize(int expectedSize)51 protected void assertSize(int expectedSize) { 52 assertEquals(9, table.size()); 53 } 54 55 @Override supportsRemove()56 protected boolean supportsRemove() { 57 return false; 58 } 59 60 @Override supportsNullValues()61 protected boolean supportsNullValues() { 62 return true; 63 } 64 65 // Overriding tests of behavior that differs for ArrayTable. 66 67 @Override testContains()68 public void testContains() { 69 table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 70 assertTrue(table.contains("foo", 1)); 71 assertTrue(table.contains("bar", 1)); 72 assertTrue(table.contains("foo", 3)); 73 assertTrue(table.contains("foo", 2)); 74 assertTrue(table.contains("bar", 3)); 75 assertTrue(table.contains("cat", 1)); 76 assertFalse(table.contains("foo", -1)); 77 assertFalse(table.contains("bad", 1)); 78 assertFalse(table.contains("bad", -1)); 79 assertFalse(table.contains("foo", null)); 80 assertFalse(table.contains(null, 1)); 81 assertFalse(table.contains(null, null)); 82 } 83 84 @Override testContainsRow()85 public void testContainsRow() { 86 table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 87 assertTrue(table.containsRow("foo")); 88 assertTrue(table.containsRow("bar")); 89 assertTrue(table.containsRow("cat")); 90 assertFalse(table.containsRow("bad")); 91 assertFalse(table.containsRow(null)); 92 } 93 94 @Override testContainsColumn()95 public void testContainsColumn() { 96 table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 97 assertTrue(table.containsColumn(1)); 98 assertTrue(table.containsColumn(3)); 99 assertTrue(table.containsColumn(2)); 100 assertFalse(table.containsColumn(-1)); 101 assertFalse(table.containsColumn(null)); 102 } 103 104 @Override testContainsValue()105 public void testContainsValue() { 106 table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 107 assertTrue(table.containsValue('a')); 108 assertTrue(table.containsValue('b')); 109 assertTrue(table.containsValue('c')); 110 assertFalse(table.containsValue('x')); 111 assertTrue(table.containsValue(null)); 112 } 113 114 @Override testIsEmpty()115 public void testIsEmpty() { 116 assertFalse(table.isEmpty()); 117 table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 118 assertFalse(table.isEmpty()); 119 } 120 121 @Override testEquals()122 public void testEquals() { 123 table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 124 Table<String, Integer, Character> hashCopy = HashBasedTable.create(); 125 hashCopy.put("foo", 1, 'a'); 126 hashCopy.put("bar", 1, 'b'); 127 hashCopy.put("foo", 3, 'c'); 128 Table<String, Integer, Character> reordered = 129 create("foo", 3, 'c', "foo", 1, 'a', "bar", 1, 'b'); 130 Table<String, Integer, Character> smaller = create("foo", 1, 'a', "bar", 1, 'b'); 131 Table<String, Integer, Character> swapOuter = 132 create("bar", 1, 'a', "foo", 1, 'b', "bar", 3, 'c'); 133 Table<String, Integer, Character> swapValues = 134 create("foo", 1, 'c', "bar", 1, 'b', "foo", 3, 'a'); 135 136 new EqualsTester() 137 .addEqualityGroup(table, reordered) 138 .addEqualityGroup(hashCopy) 139 .addEqualityGroup(smaller) 140 .addEqualityGroup(swapOuter) 141 .addEqualityGroup(swapValues) 142 .testEquals(); 143 } 144 145 @Override testHashCode()146 public void testHashCode() { 147 table = ArrayTable.create(asList("foo", "bar"), asList(1, 3)); 148 table.put("foo", 1, 'a'); 149 table.put("bar", 1, 'b'); 150 table.put("foo", 3, 'c'); 151 int expected = 152 Objects.hashCode("foo", 1, 'a') 153 + Objects.hashCode("bar", 1, 'b') 154 + Objects.hashCode("foo", 3, 'c') 155 + Objects.hashCode("bar", 3, 0); 156 assertEquals(expected, table.hashCode()); 157 } 158 159 @Override testRow()160 public void testRow() { 161 table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 162 Map<Integer, Character> expected = Maps.newHashMap(); 163 expected.put(1, 'a'); 164 expected.put(3, 'c'); 165 expected.put(2, null); 166 assertEquals(expected, table.row("foo")); 167 } 168 169 @Override testColumn()170 public void testColumn() { 171 table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 172 Map<String, Character> expected = Maps.newHashMap(); 173 expected.put("foo", 'a'); 174 expected.put("bar", 'b'); 175 expected.put("cat", null); 176 assertEquals(expected, table.column(1)); 177 } 178 179 @Override testToStringSize1()180 public void testToStringSize1() { 181 table = ArrayTable.create(ImmutableList.of("foo"), ImmutableList.of(1)); 182 table.put("foo", 1, 'a'); 183 assertEquals("{foo={1=a}}", table.toString()); 184 } 185 testCreateDuplicateRows()186 public void testCreateDuplicateRows() { 187 try { 188 ArrayTable.create(asList("foo", "bar", "foo"), asList(1, 2, 3)); 189 fail(); 190 } catch (IllegalArgumentException expected) { 191 } 192 } 193 testCreateDuplicateColumns()194 public void testCreateDuplicateColumns() { 195 try { 196 ArrayTable.create(asList("foo", "bar"), asList(1, 2, 3, 2)); 197 fail(); 198 } catch (IllegalArgumentException expected) { 199 } 200 } 201 testCreateEmptyRows()202 public void testCreateEmptyRows() { 203 try { 204 ArrayTable.create(Arrays.<String>asList(), asList(1, 2, 3)); 205 fail(); 206 } catch (IllegalArgumentException expected) { 207 } 208 } 209 testCreateEmptyColumns()210 public void testCreateEmptyColumns() { 211 try { 212 ArrayTable.create(asList("foo", "bar"), Arrays.<Integer>asList()); 213 fail(); 214 } catch (IllegalArgumentException expected) { 215 } 216 } 217 testCreateEmptyRowsXColumns()218 public void testCreateEmptyRowsXColumns() { 219 ArrayTable<String, String, Character> table = 220 ArrayTable.create(Arrays.<String>asList(), Arrays.<String>asList()); 221 assertThat(table).isEmpty(); 222 assertThat(table).hasSize(0); 223 assertThat(table.columnKeyList()).isEmpty(); 224 assertThat(table.rowKeyList()).isEmpty(); 225 assertThat(table.columnKeySet()).isEmpty(); 226 assertThat(table.rowKeySet()).isEmpty(); 227 try { 228 table.at(0, 0); 229 fail(); 230 } catch (IndexOutOfBoundsException expected) { 231 } 232 } 233 234 @GwtIncompatible // toArray testEmptyToArry()235 public void testEmptyToArry() { 236 ArrayTable<String, String, Character> table = 237 ArrayTable.create(Arrays.<String>asList(), Arrays.<String>asList()); 238 assertThat(table.toArray(Character.class)).asList().isEmpty(); 239 } 240 testCreateCopyArrayTable()241 public void testCreateCopyArrayTable() { 242 Table<String, Integer, Character> original = 243 create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 244 Table<String, Integer, Character> copy = ArrayTable.create(original); 245 assertEquals(original, copy); 246 original.put("foo", 1, 'd'); 247 assertEquals((Character) 'd', original.get("foo", 1)); 248 assertEquals((Character) 'a', copy.get("foo", 1)); 249 assertEquals(copy.rowKeySet(), original.rowKeySet()); 250 assertEquals(copy.columnKeySet(), original.columnKeySet()); 251 } 252 testCreateCopyHashBasedTable()253 public void testCreateCopyHashBasedTable() { 254 Table<String, Integer, Character> original = HashBasedTable.create(); 255 original.put("foo", 1, 'a'); 256 original.put("bar", 1, 'b'); 257 original.put("foo", 3, 'c'); 258 Table<String, Integer, Character> copy = ArrayTable.create(original); 259 assertEquals(4, copy.size()); 260 assertEquals((Character) 'a', copy.get("foo", 1)); 261 assertEquals((Character) 'b', copy.get("bar", 1)); 262 assertEquals((Character) 'c', copy.get("foo", 3)); 263 assertNull(copy.get("bar", 3)); 264 original.put("foo", 1, 'd'); 265 assertEquals((Character) 'd', original.get("foo", 1)); 266 assertEquals((Character) 'a', copy.get("foo", 1)); 267 assertEquals(copy.rowKeySet(), ImmutableSet.of("foo", "bar")); 268 assertEquals(copy.columnKeySet(), ImmutableSet.of(1, 3)); 269 } 270 testCreateCopyEmptyTable()271 public void testCreateCopyEmptyTable() { 272 Table<String, Integer, Character> original = HashBasedTable.create(); 273 ArrayTable<String, Integer, Character> copy = ArrayTable.create(original); 274 assertThat(copy).isEqualTo(original); 275 assertThat(copy) 276 .isEqualTo(ArrayTable.create(Arrays.<String>asList(), Arrays.<Integer>asList())); 277 assertThat(copy).isEmpty(); 278 } 279 testCreateCopyEmptyArrayTable()280 public void testCreateCopyEmptyArrayTable() { 281 Table<String, Integer, Character> original = 282 ArrayTable.create(Arrays.<String>asList(), Arrays.<Integer>asList()); 283 ArrayTable<String, Integer, Character> copy = ArrayTable.create(original); 284 assertThat(copy).isEqualTo(original); 285 assertThat(copy).isEmpty(); 286 } 287 testSerialization()288 public void testSerialization() { 289 table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 290 SerializableTester.reserializeAndAssert(table); 291 } 292 293 @GwtIncompatible // reflection testNullPointerStatic()294 public void testNullPointerStatic() { 295 new NullPointerTester().testAllPublicStaticMethods(ArrayTable.class); 296 } 297 testToString_ordered()298 public void testToString_ordered() { 299 table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 300 assertEquals( 301 "{foo={1=a, 2=null, 3=c}, " 302 + "bar={1=b, 2=null, 3=null}, " 303 + "cat={1=null, 2=null, 3=null}}", 304 table.toString()); 305 assertEquals( 306 "{foo={1=a, 2=null, 3=c}, " 307 + "bar={1=b, 2=null, 3=null}, " 308 + "cat={1=null, 2=null, 3=null}}", 309 table.rowMap().toString()); 310 } 311 testCellSetToString_ordered()312 public void testCellSetToString_ordered() { 313 table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 314 assertEquals( 315 "[(foo,1)=a, (foo,2)=null, (foo,3)=c, " 316 + "(bar,1)=b, (bar,2)=null, (bar,3)=null, " 317 + "(cat,1)=null, (cat,2)=null, (cat,3)=null]", 318 table.cellSet().toString()); 319 } 320 testRowKeySetToString_ordered()321 public void testRowKeySetToString_ordered() { 322 table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 323 assertEquals("[foo, bar, cat]", table.rowKeySet().toString()); 324 } 325 testColumnKeySetToString_ordered()326 public void testColumnKeySetToString_ordered() { 327 table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 328 assertEquals("[1, 2, 3]", table.columnKeySet().toString()); 329 } 330 testValuesToString_ordered()331 public void testValuesToString_ordered() { 332 table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 333 assertEquals("[a, null, c, b, null, null, null, null, null]", table.values().toString()); 334 } 335 testRowKeyList()336 public void testRowKeyList() { 337 ArrayTable<String, Integer, Character> table = 338 create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 339 assertThat(table.rowKeyList()).containsExactly("foo", "bar", "cat").inOrder(); 340 } 341 testColumnKeyList()342 public void testColumnKeyList() { 343 ArrayTable<String, Integer, Character> table = 344 create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 345 assertThat(table.columnKeyList()).containsExactly(1, 2, 3).inOrder(); 346 } 347 testGetMissingKeys()348 public void testGetMissingKeys() { 349 table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 350 assertNull(table.get("dog", 1)); 351 assertNull(table.get("foo", 4)); 352 } 353 testAt()354 public void testAt() { 355 ArrayTable<String, Integer, Character> table = 356 create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 357 assertEquals((Character) 'b', table.at(1, 0)); 358 assertEquals((Character) 'c', table.at(0, 2)); 359 assertNull(table.at(1, 2)); 360 try { 361 table.at(1, 3); 362 fail(); 363 } catch (IndexOutOfBoundsException expected) { 364 } 365 try { 366 table.at(1, -1); 367 fail(); 368 } catch (IndexOutOfBoundsException expected) { 369 } 370 try { 371 table.at(3, 2); 372 fail(); 373 } catch (IndexOutOfBoundsException expected) { 374 } 375 try { 376 table.at(-1, 2); 377 fail(); 378 } catch (IndexOutOfBoundsException expected) { 379 } 380 } 381 testSet()382 public void testSet() { 383 ArrayTable<String, Integer, Character> table = 384 create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 385 assertEquals((Character) 'b', table.set(1, 0, 'd')); 386 assertEquals((Character) 'd', table.get("bar", 1)); 387 assertNull(table.set(2, 0, 'e')); 388 assertEquals((Character) 'e', table.get("cat", 1)); 389 assertEquals((Character) 'a', table.set(0, 0, null)); 390 assertNull(table.get("foo", 1)); 391 try { 392 table.set(1, 3, 'z'); 393 fail(); 394 } catch (IndexOutOfBoundsException expected) { 395 } 396 try { 397 table.set(1, -1, 'z'); 398 fail(); 399 } catch (IndexOutOfBoundsException expected) { 400 } 401 try { 402 table.set(3, 2, 'z'); 403 fail(); 404 } catch (IndexOutOfBoundsException expected) { 405 } 406 try { 407 table.set(-1, 2, 'z'); 408 fail(); 409 } catch (IndexOutOfBoundsException expected) { 410 } 411 assertFalse(table.containsValue('z')); 412 } 413 testEraseAll()414 public void testEraseAll() { 415 ArrayTable<String, Integer, Character> table = 416 create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 417 table.eraseAll(); 418 assertEquals(9, table.size()); 419 assertNull(table.get("bar", 1)); 420 assertTrue(table.containsRow("foo")); 421 assertFalse(table.containsValue('a')); 422 } 423 testPutIllegal()424 public void testPutIllegal() { 425 table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 426 try { 427 table.put("dog", 1, 'd'); 428 fail(); 429 } catch (IllegalArgumentException expected) { 430 assertThat(expected).hasMessageThat().isEqualTo("Row dog not in [foo, bar, cat]"); 431 } 432 try { 433 table.put("foo", 4, 'd'); 434 fail(); 435 } catch (IllegalArgumentException expected) { 436 assertThat(expected).hasMessageThat().isEqualTo("Column 4 not in [1, 2, 3]"); 437 } 438 assertFalse(table.containsValue('d')); 439 } 440 testErase()441 public void testErase() { 442 ArrayTable<String, Integer, Character> table = 443 create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 444 assertEquals((Character) 'b', table.erase("bar", 1)); 445 assertNull(table.get("bar", 1)); 446 assertEquals(9, table.size()); 447 assertNull(table.erase("bar", 1)); 448 assertNull(table.erase("foo", 2)); 449 assertNull(table.erase("dog", 1)); 450 assertNull(table.erase("bar", 5)); 451 assertNull(table.erase(null, 1)); 452 assertNull(table.erase("bar", null)); 453 } 454 455 @GwtIncompatible // ArrayTable.toArray(Class) testToArray()456 public void testToArray() { 457 ArrayTable<String, Integer, Character> table = 458 create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 459 Character[][] array = table.toArray(Character.class); 460 assertThat(array).hasLength(3); 461 assertThat(array[0]).asList().containsExactly('a', null, 'c').inOrder(); 462 assertThat(array[1]).asList().containsExactly('b', null, null).inOrder(); 463 assertThat(array[2]).asList().containsExactly(null, null, null).inOrder(); 464 table.set(0, 2, 'd'); 465 assertEquals((Character) 'c', array[0][2]); 466 array[0][2] = 'e'; 467 assertEquals((Character) 'd', table.at(0, 2)); 468 } 469 testCellReflectsChanges()470 public void testCellReflectsChanges() { 471 table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 472 Cell<String, Integer, Character> cell = table.cellSet().iterator().next(); 473 assertEquals(Tables.immutableCell("foo", 1, 'a'), cell); 474 assertEquals((Character) 'a', table.put("foo", 1, 'd')); 475 assertEquals(Tables.immutableCell("foo", 1, 'd'), cell); 476 } 477 testRowMissing()478 public void testRowMissing() { 479 table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 480 Map<Integer, Character> row = table.row("dog"); 481 assertTrue(row.isEmpty()); 482 try { 483 row.put(1, 'd'); 484 fail(); 485 } catch (UnsupportedOperationException expected) { 486 } 487 } 488 testColumnMissing()489 public void testColumnMissing() { 490 table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 491 Map<String, Character> column = table.column(4); 492 assertTrue(column.isEmpty()); 493 try { 494 column.put("foo", 'd'); 495 fail(); 496 } catch (UnsupportedOperationException expected) { 497 } 498 } 499 testRowPutIllegal()500 public void testRowPutIllegal() { 501 table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 502 Map<Integer, Character> map = table.row("foo"); 503 try { 504 map.put(4, 'd'); 505 fail(); 506 } catch (IllegalArgumentException expected) { 507 assertThat(expected).hasMessageThat().isEqualTo("Column 4 not in [1, 2, 3]"); 508 } 509 } 510 testColumnPutIllegal()511 public void testColumnPutIllegal() { 512 table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c'); 513 Map<String, Character> map = table.column(3); 514 try { 515 map.put("dog", 'd'); 516 fail(); 517 } catch (IllegalArgumentException expected) { 518 assertThat(expected).hasMessageThat().isEqualTo("Row dog not in [foo, bar, cat]"); 519 } 520 } 521 522 @GwtIncompatible // reflection testNulls()523 public void testNulls() { 524 new NullPointerTester().testAllPublicInstanceMethods(create()); 525 } 526 527 @GwtIncompatible // serialize testSerializable()528 public void testSerializable() { 529 SerializableTester.reserializeAndAssert(create()); 530 } 531 } 532