Home | History | Annotate | Download | only in collect
      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 
     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 
     48   @Override protected void assertSize(int expectedSize) {
     49     assertEquals(9, table.size());
     50   }
     51 
     52   @Override protected boolean supportsRemove() {
     53     return false;
     54   }
     55 
     56   @Override protected boolean supportsNullValues() {
     57     return true;
     58   }
     59 
     60   // Overriding tests of behavior that differs for ArrayTable.
     61 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    185   public void testCreateEmptyRows() {
    186     try {
    187       ArrayTable.create(Arrays.<String>asList(), asList(1, 2, 3));
    188       fail();
    189     } catch (IllegalArgumentException expected) {}
    190   }
    191 
    192   public void testCreateEmptyColumns() {
    193     try {
    194       ArrayTable.create(asList("foo", "bar"), Arrays.<Integer>asList());
    195       fail();
    196     } catch (IllegalArgumentException expected) {}
    197   }
    198 
    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 
    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 
    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 
    237   public void testSerialization() {
    238     table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
    239     SerializableTester.reserializeAndAssert(table);
    240   }
    241 
    242   public void testNullPointerStatic() throws Exception {
    243     new NullPointerTester().testAllPublicStaticMethods(ArrayTable.class);
    244   }
    245 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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