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