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 17package com.google.common.collect; 18 19import static com.google.common.truth.Truth.assertThat; 20 21import com.google.common.annotations.GwtCompatible; 22 23/** 24 * Tests common methods in {@link ImmutableTable} 25 * 26 * @author Gregory Kick 27 */ 28@GwtCompatible(emulated = true) 29public class ImmutableTableTest extends AbstractTableReadTest { 30 @Override protected Table<String, Integer, Character> create(Object... data) { 31 ImmutableTable.Builder<String, Integer, Character> builder = 32 ImmutableTable.builder(); 33 for (int i = 0; i < data.length; i = i + 3) { 34 builder.put((String) data[i], (Integer) data[i + 1], 35 (Character) data[i + 2]); 36 } 37 return builder.build(); 38 } 39 40 public void testBuilder() { 41 ImmutableTable.Builder<Character, Integer, String> builder = 42 new ImmutableTable.Builder<Character, Integer, String>(); 43 assertEquals(ImmutableTable.of(), builder.build()); 44 assertEquals(ImmutableTable.of('a', 1, "foo"), builder 45 .put('a', 1, "foo") 46 .build()); 47 Table<Character, Integer, String> expectedTable = HashBasedTable.create(); 48 expectedTable.put('a', 1, "foo"); 49 expectedTable.put('b', 1, "bar"); 50 expectedTable.put('a', 2, "baz"); 51 Table<Character, Integer, String> otherTable = HashBasedTable.create(); 52 otherTable.put('b', 1, "bar"); 53 otherTable.put('a', 2, "baz"); 54 assertEquals(expectedTable, builder 55 .putAll(otherTable) 56 .build()); 57 } 58 59 public void testBuilder_withImmutableCell() { 60 ImmutableTable.Builder<Character, Integer, String> builder = 61 new ImmutableTable.Builder<Character, Integer, String>(); 62 assertEquals(ImmutableTable.of('a', 1, "foo"), builder 63 .put(Tables.immutableCell('a', 1, "foo")) 64 .build()); 65 } 66 67 public void testBuilder_withImmutableCellAndNullContents() { 68 ImmutableTable.Builder<Character, Integer, String> builder = 69 new ImmutableTable.Builder<Character, Integer, String>(); 70 try { 71 builder.put(Tables.immutableCell((Character) null, 1, "foo")); 72 fail(); 73 } catch (NullPointerException e) { 74 // success 75 } 76 try { 77 builder.put(Tables.immutableCell('a', (Integer) null, "foo")); 78 fail(); 79 } catch (NullPointerException e) { 80 // success 81 } 82 try { 83 builder.put(Tables.immutableCell('a', 1, (String) null)); 84 fail(); 85 } catch (NullPointerException e) { 86 // success 87 } 88 } 89 90 private static class StringHolder { 91 String string; 92 } 93 94 public void testBuilder_withMutableCell() { 95 ImmutableTable.Builder<Character, Integer, String> builder = 96 new ImmutableTable.Builder<Character, Integer, String>(); 97 98 final StringHolder holder = new StringHolder(); 99 holder.string = "foo"; 100 Table.Cell<Character, Integer, String> mutableCell = 101 new Tables.AbstractCell<Character, Integer, String>() { 102 @Override public Character getRowKey() { 103 return 'K'; 104 } 105 @Override public Integer getColumnKey() { 106 return 42; 107 } 108 @Override public String getValue() { 109 return holder.string; 110 } 111 }; 112 113 // Add the mutable cell to the builder 114 builder.put(mutableCell); 115 116 // Mutate the value 117 holder.string = "bar"; 118 119 // Make sure it uses the original value. 120 assertEquals(ImmutableTable.of('K', 42, "foo"), builder.build()); 121 } 122 123 public void testBuilder_noDuplicates() { 124 ImmutableTable.Builder<Character, Integer, String> builder = 125 new ImmutableTable.Builder<Character, Integer, String>() 126 .put('a', 1, "foo") 127 .put('a', 1, "bar"); 128 try { 129 builder.build(); 130 fail(); 131 } catch (IllegalArgumentException e) { 132 // success 133 } 134 } 135 136 public void testBuilder_noNulls() { 137 ImmutableTable.Builder<Character, Integer, String> builder = 138 new ImmutableTable.Builder<Character, Integer, String>(); 139 try { 140 builder.put(null, 1, "foo"); 141 fail(); 142 } catch (NullPointerException e) { 143 // success 144 } 145 try { 146 builder.put('a', null, "foo"); 147 fail(); 148 } catch (NullPointerException e) { 149 // success 150 } 151 try { 152 builder.put('a', 1, null); 153 fail(); 154 } catch (NullPointerException e) { 155 // success 156 } 157 } 158 159 private static <R, C, V> void validateTableCopies(Table<R, C, V> original) { 160 Table<R, C, V> copy = ImmutableTable.copyOf(original); 161 assertEquals(original, copy); 162 validateViewOrdering(original, copy); 163 164 Table<R, C, V> built 165 = ImmutableTable.<R, C, V>builder().putAll(original).build(); 166 assertEquals(original, built); 167 validateViewOrdering(original, built); 168 } 169 170 private static <R, C, V> void validateViewOrdering( 171 Table<R, C, V> original, Table<R, C, V> copy) { 172 assertTrue(Iterables.elementsEqual(original.cellSet(), copy.cellSet())); 173 assertTrue(Iterables.elementsEqual(original.rowKeySet(), copy.rowKeySet())); 174 assertTrue(Iterables.elementsEqual(original.values(), copy.values())); 175 } 176 177 public void testCopyOf() { 178 Table<Character, Integer, String> table = TreeBasedTable.create(); 179 validateTableCopies(table); 180 table.put('b', 2, "foo"); 181 validateTableCopies(table); 182 table.put('b', 1, "bar"); 183 table.put('a', 2, "baz"); 184 validateTableCopies(table); 185 // Even though rowKeySet, columnKeySet, and cellSet have the same 186 // iteration ordering, row has an inconsistent ordering. 187 assertThat(table.row('b').keySet()).has().exactly(1, 2).inOrder(); 188 assertThat(ImmutableTable.copyOf(table).row('b').keySet()) 189 .has().exactly(2, 1).inOrder(); 190 } 191 192 public void testCopyOfSparse() { 193 Table<Character, Integer, String> table = TreeBasedTable.create(); 194 table.put('x', 2, "foo"); 195 table.put('r', 1, "bar"); 196 table.put('c', 3, "baz"); 197 table.put('b', 7, "cat"); 198 table.put('e', 5, "dog"); 199 table.put('c', 0, "axe"); 200 table.put('e', 3, "tub"); 201 table.put('r', 4, "foo"); 202 table.put('x', 5, "bar"); 203 validateTableCopies(table); 204 } 205 206 public void testCopyOfDense() { 207 Table<Character, Integer, String> table = TreeBasedTable.create(); 208 table.put('c', 3, "foo"); 209 table.put('c', 2, "bar"); 210 table.put('c', 1, "baz"); 211 table.put('b', 3, "cat"); 212 table.put('b', 1, "dog"); 213 table.put('a', 3, "foo"); 214 table.put('a', 2, "bar"); 215 table.put('a', 1, "baz"); 216 validateTableCopies(table); 217 } 218 219 public void testBuilder_orderRowsAndColumnsBy_putAll() { 220 Table<Character, Integer, String> table = HashBasedTable.create(); 221 table.put('b', 2, "foo"); 222 table.put('b', 1, "bar"); 223 table.put('a', 2, "baz"); 224 ImmutableTable.Builder<Character, Integer, String> builder 225 = ImmutableTable.builder(); 226 Table<Character, Integer, String> copy 227 = builder.orderRowsBy(Ordering.natural()) 228 .orderColumnsBy(Ordering.natural()) 229 .putAll(table).build(); 230 assertThat(copy.rowKeySet()).has().exactly('a', 'b').inOrder(); 231 assertThat(copy.columnKeySet()).has().exactly(1, 2).inOrder(); 232 assertThat(copy.values()).has().exactly("baz", "bar", "foo").inOrder(); 233 assertThat(copy.row('b').keySet()).has().exactly(1, 2).inOrder(); 234 } 235 236 public void testBuilder_orderRowsAndColumnsBy_sparse() { 237 ImmutableTable.Builder<Character, Integer, String> builder 238 = ImmutableTable.builder(); 239 builder.orderRowsBy(Ordering.natural()); 240 builder.orderColumnsBy(Ordering.natural()); 241 builder.put('x', 2, "foo"); 242 builder.put('r', 1, "bar"); 243 builder.put('c', 3, "baz"); 244 builder.put('b', 7, "cat"); 245 builder.put('e', 5, "dog"); 246 builder.put('c', 0, "axe"); 247 builder.put('e', 3, "tub"); 248 builder.put('r', 4, "foo"); 249 builder.put('x', 5, "bar"); 250 Table<Character, Integer, String> table = builder.build(); 251 assertThat(table.rowKeySet()).has().exactly('b', 'c', 'e', 'r', 'x').inOrder(); 252 assertThat(table.columnKeySet()).has().exactly(0, 1, 2, 3, 4, 5, 7).inOrder(); 253 assertThat(table.values()).has().exactly("cat", "axe", "baz", "tub", 254 "dog", "bar", "foo", "foo", "bar").inOrder(); 255 assertThat(table.row('c').keySet()).has().exactly(0, 3).inOrder(); 256 assertThat(table.column(5).keySet()).has().exactly('e', 'x').inOrder(); 257 } 258 259 public void testBuilder_orderRowsAndColumnsBy_dense() { 260 ImmutableTable.Builder<Character, Integer, String> builder 261 = ImmutableTable.builder(); 262 builder.orderRowsBy(Ordering.natural()); 263 builder.orderColumnsBy(Ordering.natural()); 264 builder.put('c', 3, "foo"); 265 builder.put('c', 2, "bar"); 266 builder.put('c', 1, "baz"); 267 builder.put('b', 3, "cat"); 268 builder.put('b', 1, "dog"); 269 builder.put('a', 3, "foo"); 270 builder.put('a', 2, "bar"); 271 builder.put('a', 1, "baz"); 272 Table<Character, Integer, String> table = builder.build(); 273 assertThat(table.rowKeySet()).has().exactly('a', 'b', 'c').inOrder(); 274 assertThat(table.columnKeySet()).has().exactly(1, 2, 3).inOrder(); 275 assertThat(table.values()).has().exactly("baz", "bar", "foo", "dog", 276 "cat", "baz", "bar", "foo").inOrder(); 277 assertThat(table.row('c').keySet()).has().exactly(1, 2, 3).inOrder(); 278 assertThat(table.column(1).keySet()).has().exactly('a', 'b', 'c').inOrder(); 279 } 280 281 public void testBuilder_orderRowsBy_sparse() { 282 ImmutableTable.Builder<Character, Integer, String> builder 283 = ImmutableTable.builder(); 284 builder.orderRowsBy(Ordering.natural()); 285 builder.put('x', 2, "foo"); 286 builder.put('r', 1, "bar"); 287 builder.put('c', 3, "baz"); 288 builder.put('b', 7, "cat"); 289 builder.put('e', 5, "dog"); 290 builder.put('c', 0, "axe"); 291 builder.put('e', 3, "tub"); 292 builder.put('r', 4, "foo"); 293 builder.put('x', 5, "bar"); 294 Table<Character, Integer, String> table = builder.build(); 295 assertThat(table.rowKeySet()).has().exactly('b', 'c', 'e', 'r', 'x').inOrder(); 296 assertThat(table.column(5).keySet()).has().exactly('e', 'x').inOrder(); 297 } 298 299 public void testBuilder_orderRowsBy_dense() { 300 ImmutableTable.Builder<Character, Integer, String> builder 301 = ImmutableTable.builder(); 302 builder.orderRowsBy(Ordering.natural()); 303 builder.put('c', 3, "foo"); 304 builder.put('c', 2, "bar"); 305 builder.put('c', 1, "baz"); 306 builder.put('b', 3, "cat"); 307 builder.put('b', 1, "dog"); 308 builder.put('a', 3, "foo"); 309 builder.put('a', 2, "bar"); 310 builder.put('a', 1, "baz"); 311 Table<Character, Integer, String> table = builder.build(); 312 assertThat(table.rowKeySet()).has().exactly('a', 'b', 'c').inOrder(); 313 assertThat(table.column(1).keySet()).has().exactly('a', 'b', 'c').inOrder(); 314 } 315 316 public void testBuilder_orderColumnsBy_sparse() { 317 ImmutableTable.Builder<Character, Integer, String> builder 318 = ImmutableTable.builder(); 319 builder.orderColumnsBy(Ordering.natural()); 320 builder.put('x', 2, "foo"); 321 builder.put('r', 1, "bar"); 322 builder.put('c', 3, "baz"); 323 builder.put('b', 7, "cat"); 324 builder.put('e', 5, "dog"); 325 builder.put('c', 0, "axe"); 326 builder.put('e', 3, "tub"); 327 builder.put('r', 4, "foo"); 328 builder.put('x', 5, "bar"); 329 Table<Character, Integer, String> table = builder.build(); 330 assertThat(table.columnKeySet()).has().exactly(0, 1, 2, 3, 4, 5, 7).inOrder(); 331 assertThat(table.row('c').keySet()).has().exactly(0, 3).inOrder(); 332 } 333 334 public void testBuilder_orderColumnsBy_dense() { 335 ImmutableTable.Builder<Character, Integer, String> builder 336 = ImmutableTable.builder(); 337 builder.orderColumnsBy(Ordering.natural()); 338 builder.put('c', 3, "foo"); 339 builder.put('c', 2, "bar"); 340 builder.put('c', 1, "baz"); 341 builder.put('b', 3, "cat"); 342 builder.put('b', 1, "dog"); 343 builder.put('a', 3, "foo"); 344 builder.put('a', 2, "bar"); 345 builder.put('a', 1, "baz"); 346 Table<Character, Integer, String> table = builder.build(); 347 assertThat(table.columnKeySet()).has().exactly(1, 2, 3).inOrder(); 348 assertThat(table.row('c').keySet()).has().exactly(1, 2, 3).inOrder(); 349 } 350} 351 352