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 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