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