/* * Copyright (C) 2009 The Guava Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.common.collect; import static com.google.common.collect.Tables.immutableCell; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.J2ktIncompatible; import com.google.common.base.Equivalence; import com.google.common.base.Function; import com.google.common.base.MoreObjects; import com.google.common.collect.Table.Cell; import com.google.common.testing.CollectorTester; import java.util.function.BiPredicate; import java.util.function.BinaryOperator; import java.util.stream.Collector; import java.util.stream.Stream; import junit.framework.TestCase; import org.checkerframework.checker.nullness.qual.Nullable; /** Unit tests for {@link TableCollectors}. */ @GwtCompatible(emulated = true) @ElementTypesAreNonnullByDefault public class TableCollectorsTest extends TestCase { public void testToImmutableTable() { Collector, ?, ImmutableTable> collector = TableCollectors.toImmutableTable(Cell::getRowKey, Cell::getColumnKey, Cell::getValue); BiPredicate, ImmutableTable> equivalence = pairwiseOnResultOf(ImmutableTable::cellSet); CollectorTester.of(collector, equivalence) .expectCollects( new ImmutableTable.Builder() .put("one", "uno", 1) .put("two", "dos", 2) .put("three", "tres", 3) .build(), immutableCell("one", "uno", 1), immutableCell("two", "dos", 2), immutableCell("three", "tres", 3)); } public void testToImmutableTableConflict() { Collector, ?, ImmutableTable> collector = TableCollectors.toImmutableTable(Cell::getRowKey, Cell::getColumnKey, Cell::getValue); try { Stream.of(immutableCell("one", "uno", 1), immutableCell("one", "uno", 2)).collect(collector); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException expected) { } } public void testToImmutableTableNullRowKey() { Collector, ?, ImmutableTable> collector = TableCollectors.toImmutableTable(t -> null, Cell::getColumnKey, Cell::getValue); try { Stream.of(immutableCell("one", "uno", 1)).collect(collector); fail("Expected NullPointerException"); } catch (NullPointerException expected) { } } public void testToImmutableTableNullColumnKey() { Collector, ?, ImmutableTable> collector = TableCollectors.toImmutableTable(Cell::getRowKey, t -> null, Cell::getValue); try { Stream.of(immutableCell("one", "uno", 1)).collect(collector); fail("Expected NullPointerException"); } catch (NullPointerException expected) { } } public void testToImmutableTableNullValue() { Collector, ?, ImmutableTable> collector = TableCollectors.toImmutableTable(Cell::getRowKey, Cell::getColumnKey, t -> null); try { Stream.of(immutableCell("one", "uno", 1)).collect(collector); fail("Expected NullPointerException"); } catch (NullPointerException expected) { } collector = TableCollectors.toImmutableTable(Cell::getRowKey, Cell::getColumnKey, Cell::getValue); try { Stream.of(immutableCell("one", "uno", 1), immutableCell("one", "uno", (Integer) null)) .collect(collector); fail("Expected NullPointerException"); } catch (NullPointerException expected) { } } public void testToImmutableTableMerging() { Collector, ?, ImmutableTable> collector = TableCollectors.toImmutableTable( Cell::getRowKey, Cell::getColumnKey, Cell::getValue, Integer::sum); BiPredicate, ImmutableTable> equivalence = pairwiseOnResultOf(ImmutableTable::cellSet); CollectorTester.of(collector, equivalence) .expectCollects( new ImmutableTable.Builder() .put("one", "uno", 1) .put("two", "dos", 6) .put("three", "tres", 3) .build(), immutableCell("one", "uno", 1), immutableCell("two", "dos", 2), immutableCell("three", "tres", 3), immutableCell("two", "dos", 4)); } public void testToImmutableTableMergingNullRowKey() { Collector, ?, ImmutableTable> collector = TableCollectors.toImmutableTable( t -> null, Cell::getColumnKey, Cell::getValue, Integer::sum); try { Stream.of(immutableCell("one", "uno", 1)).collect(collector); fail("Expected NullPointerException"); } catch (NullPointerException expected) { } } public void testToImmutableTableMergingNullColumnKey() { Collector, ?, ImmutableTable> collector = TableCollectors.toImmutableTable(Cell::getRowKey, t -> null, Cell::getValue, Integer::sum); try { Stream.of(immutableCell("one", "uno", 1)).collect(collector); fail("Expected NullPointerException"); } catch (NullPointerException expected) { } } public void testToImmutableTableMergingNullValue() { Collector, ?, ImmutableTable> collector = TableCollectors.toImmutableTable( Cell::getRowKey, Cell::getColumnKey, t -> null, Integer::sum); try { Stream.of(immutableCell("one", "uno", 1)).collect(collector); fail("Expected NullPointerException"); } catch (NullPointerException expected) { } collector = TableCollectors.toImmutableTable( Cell::getRowKey, Cell::getColumnKey, Cell::getValue, (i, j) -> MoreObjects.firstNonNull(i, 0) + MoreObjects.firstNonNull(j, 0)); try { Stream.of(immutableCell("one", "uno", 1), immutableCell("one", "uno", (Integer) null)) .collect(collector); fail("Expected NullPointerException"); } catch (NullPointerException expected) { } } public void testToImmutableTableMergingNullMerge() { Collector, ?, ImmutableTable> collector = TableCollectors.toImmutableTable( Cell::getRowKey, Cell::getColumnKey, Cell::getValue, (v1, v2) -> null); try { Stream.of(immutableCell("one", "uno", 1), immutableCell("one", "uno", 2)).collect(collector); fail("Expected NullPointerException"); } catch (NullPointerException expected) { } } public void testToTable() { Collector, ?, Table> collector = TableCollectors.toTable( Cell::getRowKey, Cell::getColumnKey, Cell::getValue, HashBasedTable::create); BiPredicate, Table> equivalence = pairwiseOnResultOf(Table::cellSet); CollectorTester.of(collector, equivalence) .expectCollects( new ImmutableTable.Builder() .put("one", "uno", 1) .put("two", "dos", 2) .put("three", "tres", 3) .build(), immutableCell("one", "uno", 1), immutableCell("two", "dos", 2), immutableCell("three", "tres", 3)); } public void testToTableNullMerge() { // TODO github.com/google/guava/issues/6824 - the null merge feature is not compatible with the // current nullness annotation of the mergeFunction parameter. Work around with casts. BinaryOperator<@Nullable Integer> mergeFunction = (v1, v2) -> null; Collector, ?, Table> collector = TableCollectors.toTable( Cell::getRowKey, Cell::getColumnKey, Cell::getValue, (BinaryOperator) mergeFunction, HashBasedTable::create); BiPredicate, Table> equivalence = pairwiseOnResultOf(Table::cellSet); CollectorTester.of(collector, equivalence) .expectCollects( ImmutableTable.of(), immutableCell("one", "uno", 1), immutableCell("one", "uno", 2)); } // https://youtrack.jetbrains.com/issue/KT-58242/. Crash when getValue result (null) is unboxed @J2ktIncompatible public void testToTableNullValues() { Collector, ?, Table> collector = TableCollectors.toTable( Cell::getRowKey, Cell::getColumnKey, Cell::getValue, () -> { Table table = ArrayTable.create(ImmutableList.of("one"), ImmutableList.of("uno")); return (Table) table; }); try { Cell cell = immutableCell("one", "uno", null); Stream.of((Cell) cell).collect(collector); fail("Expected NullPointerException"); } catch (NullPointerException expected) { } } public void testToTableConflict() { Collector, ?, Table> collector = TableCollectors.toTable( Cell::getRowKey, Cell::getColumnKey, Cell::getValue, HashBasedTable::create); try { Stream.of(immutableCell("one", "uno", 1), immutableCell("one", "uno", 2)).collect(collector); fail("Expected IllegalStateException"); } catch (IllegalStateException expected) { } } public void testToTableMerging() { Collector, ?, Table> collector = TableCollectors.toTable( Cell::getRowKey, Cell::getColumnKey, Cell::getValue, Integer::sum, HashBasedTable::create); BiPredicate, Table> equivalence = pairwiseOnResultOf(Table::cellSet); CollectorTester.of(collector, equivalence) .expectCollects( new ImmutableTable.Builder() .put("one", "uno", 1) .put("two", "dos", 6) .put("three", "tres", 3) .build(), immutableCell("one", "uno", 1), immutableCell("two", "dos", 2), immutableCell("three", "tres", 3), immutableCell("two", "dos", 4)); } // This function specifically returns a BiPredicate, because Guava7’s Equivalence class does not // actually implement BiPredicate, and CollectorTests expects a BiPredicate. static > BiPredicate pairwiseOnResultOf(Function arg) { Equivalence equivalence = Equivalence.equals().pairwise().onResultOf(arg); return equivalence::equivalent; } }