463 lines
16 KiB
Java
463 lines
16 KiB
Java
/*
|
|
* Copyright (C) 2008 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.truth.Truth.assertThat;
|
|
|
|
import com.google.common.annotations.GwtCompatible;
|
|
import com.google.common.annotations.GwtIncompatible;
|
|
import com.google.common.collect.testing.SortedMapInterfaceTest;
|
|
import com.google.common.collect.testing.SortedMapTestSuiteBuilder;
|
|
import com.google.common.collect.testing.TestStringSortedMapGenerator;
|
|
import com.google.common.collect.testing.features.CollectionFeature;
|
|
import com.google.common.collect.testing.features.CollectionSize;
|
|
import com.google.common.collect.testing.features.MapFeature;
|
|
import com.google.common.testing.SerializableTester;
|
|
import java.util.Collections;
|
|
import java.util.Comparator;
|
|
import java.util.Map;
|
|
import java.util.Map.Entry;
|
|
import java.util.Set;
|
|
import java.util.SortedMap;
|
|
import junit.framework.Test;
|
|
import junit.framework.TestSuite;
|
|
|
|
/**
|
|
* Test cases for {@link TreeBasedTable}.
|
|
*
|
|
* @author Jared Levy
|
|
* @author Louis Wasserman
|
|
*/
|
|
@GwtCompatible(emulated = true)
|
|
public class TreeBasedTableTest extends AbstractTableTest {
|
|
@GwtIncompatible // suite
|
|
public static Test suite() {
|
|
TestSuite suite = new TestSuite();
|
|
suite.addTestSuite(TreeBasedTableTest.class);
|
|
suite.addTestSuite(TreeRowTest.class);
|
|
suite.addTest(
|
|
SortedMapTestSuiteBuilder.using(
|
|
new TestStringSortedMapGenerator() {
|
|
@Override
|
|
protected SortedMap<String, String> create(Entry<String, String>[] entries) {
|
|
TreeBasedTable<String, String, String> table = TreeBasedTable.create();
|
|
table.put("a", "b", "c");
|
|
table.put("c", "b", "a");
|
|
table.put("a", "a", "d");
|
|
for (Entry<String, String> entry : entries) {
|
|
table.put("b", entry.getKey(), entry.getValue());
|
|
}
|
|
return table.row("b");
|
|
}
|
|
})
|
|
.withFeatures(
|
|
MapFeature.GENERAL_PURPOSE,
|
|
CollectionFeature.SUPPORTS_ITERATOR_REMOVE,
|
|
CollectionSize.ANY)
|
|
.named("RowMapTestSuite")
|
|
.createTestSuite());
|
|
return suite;
|
|
}
|
|
|
|
public static class TreeRowTest extends SortedMapInterfaceTest<String, String> {
|
|
public TreeRowTest() {
|
|
super(false, false, true, true, true);
|
|
}
|
|
|
|
@Override
|
|
protected SortedMap<String, String> makeEmptyMap() {
|
|
TreeBasedTable<String, String, String> table = TreeBasedTable.create();
|
|
table.put("a", "b", "c");
|
|
table.put("c", "b", "a");
|
|
table.put("a", "a", "d");
|
|
return table.row("b");
|
|
}
|
|
|
|
@Override
|
|
protected SortedMap<String, String> makePopulatedMap() {
|
|
TreeBasedTable<String, String, String> table = TreeBasedTable.create();
|
|
table.put("a", "b", "c");
|
|
table.put("c", "b", "a");
|
|
table.put("b", "b", "x");
|
|
table.put("b", "c", "y");
|
|
table.put("b", "x", "n");
|
|
table.put("a", "a", "d");
|
|
return table.row("b");
|
|
}
|
|
|
|
@Override
|
|
protected String getKeyNotInPopulatedMap() {
|
|
return "q";
|
|
}
|
|
|
|
@Override
|
|
protected String getValueNotInPopulatedMap() {
|
|
return "p";
|
|
}
|
|
|
|
public void testClearSubMapOfRowMap() {
|
|
TreeBasedTable<String, String, String> table = TreeBasedTable.create();
|
|
table.put("a", "b", "c");
|
|
table.put("c", "b", "a");
|
|
table.put("b", "b", "x");
|
|
table.put("b", "c", "y");
|
|
table.put("b", "x", "n");
|
|
table.put("a", "a", "d");
|
|
table.row("b").subMap("c", "x").clear();
|
|
assertEquals(table.row("b"), ImmutableMap.of("b", "x", "x", "n"));
|
|
table.row("b").subMap("b", "y").clear();
|
|
assertEquals(table.row("b"), ImmutableMap.of());
|
|
assertFalse(table.backingMap.containsKey("b"));
|
|
}
|
|
}
|
|
|
|
private TreeBasedTable<String, Integer, Character> sortedTable;
|
|
|
|
protected TreeBasedTable<String, Integer, Character> create(
|
|
Comparator<? super String> rowComparator,
|
|
Comparator<? super Integer> columnComparator,
|
|
Object... data) {
|
|
TreeBasedTable<String, Integer, Character> table =
|
|
TreeBasedTable.create(rowComparator, columnComparator);
|
|
table.put("foo", 4, 'a');
|
|
table.put("cat", 1, 'b');
|
|
table.clear();
|
|
populate(table, data);
|
|
return table;
|
|
}
|
|
|
|
@Override
|
|
protected TreeBasedTable<String, Integer, Character> create(Object... data) {
|
|
TreeBasedTable<String, Integer, Character> table = TreeBasedTable.create();
|
|
table.put("foo", 4, 'a');
|
|
table.put("cat", 1, 'b');
|
|
table.clear();
|
|
populate(table, data);
|
|
return table;
|
|
}
|
|
|
|
public void testCreateExplicitComparators() {
|
|
table = TreeBasedTable.create(Collections.reverseOrder(), Ordering.usingToString());
|
|
table.put("foo", 3, 'a');
|
|
table.put("foo", 12, 'b');
|
|
table.put("bar", 5, 'c');
|
|
table.put("cat", 8, 'd');
|
|
assertThat(table.rowKeySet()).containsExactly("foo", "cat", "bar").inOrder();
|
|
assertThat(table.row("foo").keySet()).containsExactly(12, 3).inOrder();
|
|
}
|
|
|
|
public void testCreateCopy() {
|
|
TreeBasedTable<String, Integer, Character> original =
|
|
TreeBasedTable.create(Collections.reverseOrder(), Ordering.usingToString());
|
|
original.put("foo", 3, 'a');
|
|
original.put("foo", 12, 'b');
|
|
original.put("bar", 5, 'c');
|
|
original.put("cat", 8, 'd');
|
|
table = TreeBasedTable.create(original);
|
|
assertThat(table.rowKeySet()).containsExactly("foo", "cat", "bar").inOrder();
|
|
assertThat(table.row("foo").keySet()).containsExactly(12, 3).inOrder();
|
|
assertEquals(original, table);
|
|
}
|
|
|
|
@GwtIncompatible // SerializableTester
|
|
public void testSerialization() {
|
|
table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
|
|
SerializableTester.reserializeAndAssert(table);
|
|
}
|
|
|
|
public void testToString_ordered() {
|
|
table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
|
|
assertEquals("{bar={1=b}, foo={1=a, 3=c}}", table.toString());
|
|
assertEquals("{bar={1=b}, foo={1=a, 3=c}}", table.rowMap().toString());
|
|
}
|
|
|
|
public void testCellSetToString_ordered() {
|
|
table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
|
|
assertEquals("[(bar,1)=b, (foo,1)=a, (foo,3)=c]", table.cellSet().toString());
|
|
}
|
|
|
|
public void testRowKeySetToString_ordered() {
|
|
table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
|
|
assertEquals("[bar, foo]", table.rowKeySet().toString());
|
|
}
|
|
|
|
public void testValuesToString_ordered() {
|
|
table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
|
|
assertEquals("[b, a, c]", table.values().toString());
|
|
}
|
|
|
|
public void testRowComparator() {
|
|
sortedTable = TreeBasedTable.create();
|
|
assertSame(Ordering.natural(), sortedTable.rowComparator());
|
|
|
|
sortedTable = TreeBasedTable.create(Collections.reverseOrder(), Ordering.usingToString());
|
|
assertSame(Collections.reverseOrder(), sortedTable.rowComparator());
|
|
}
|
|
|
|
public void testColumnComparator() {
|
|
sortedTable = TreeBasedTable.create();
|
|
sortedTable.put("", 42, 'x');
|
|
assertSame(Ordering.natural(), sortedTable.columnComparator());
|
|
assertSame(
|
|
Ordering.natural(),
|
|
((SortedMap<Integer, Character>) sortedTable.rowMap().values().iterator().next())
|
|
.comparator());
|
|
|
|
sortedTable = TreeBasedTable.create(Collections.reverseOrder(), Ordering.usingToString());
|
|
sortedTable.put("", 42, 'x');
|
|
assertSame(Ordering.usingToString(), sortedTable.columnComparator());
|
|
assertSame(
|
|
Ordering.usingToString(),
|
|
((SortedMap<Integer, Character>) sortedTable.rowMap().values().iterator().next())
|
|
.comparator());
|
|
}
|
|
|
|
public void testRowKeySetComparator() {
|
|
sortedTable = TreeBasedTable.create();
|
|
assertSame(Ordering.natural(), sortedTable.rowKeySet().comparator());
|
|
|
|
sortedTable = TreeBasedTable.create(Collections.reverseOrder(), Ordering.usingToString());
|
|
assertSame(Collections.reverseOrder(), sortedTable.rowKeySet().comparator());
|
|
}
|
|
|
|
public void testRowKeySetFirst() {
|
|
sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
|
|
assertSame("bar", sortedTable.rowKeySet().first());
|
|
}
|
|
|
|
public void testRowKeySetLast() {
|
|
sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
|
|
assertSame("foo", sortedTable.rowKeySet().last());
|
|
}
|
|
|
|
public void testRowKeySetHeadSet() {
|
|
sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
|
|
Set<String> set = sortedTable.rowKeySet().headSet("cat");
|
|
assertEquals(Collections.singleton("bar"), set);
|
|
set.clear();
|
|
assertTrue(set.isEmpty());
|
|
assertEquals(Collections.singleton("foo"), sortedTable.rowKeySet());
|
|
}
|
|
|
|
public void testRowKeySetTailSet() {
|
|
sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
|
|
Set<String> set = sortedTable.rowKeySet().tailSet("cat");
|
|
assertEquals(Collections.singleton("foo"), set);
|
|
set.clear();
|
|
assertTrue(set.isEmpty());
|
|
assertEquals(Collections.singleton("bar"), sortedTable.rowKeySet());
|
|
}
|
|
|
|
public void testRowKeySetSubSet() {
|
|
sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c', "dog", 2, 'd');
|
|
Set<String> set = sortedTable.rowKeySet().subSet("cat", "egg");
|
|
assertEquals(Collections.singleton("dog"), set);
|
|
set.clear();
|
|
assertTrue(set.isEmpty());
|
|
assertEquals(ImmutableSet.of("bar", "foo"), sortedTable.rowKeySet());
|
|
}
|
|
|
|
public void testRowMapComparator() {
|
|
sortedTable = TreeBasedTable.create();
|
|
assertSame(Ordering.natural(), sortedTable.rowMap().comparator());
|
|
|
|
sortedTable = TreeBasedTable.create(Collections.reverseOrder(), Ordering.usingToString());
|
|
assertSame(Collections.reverseOrder(), sortedTable.rowMap().comparator());
|
|
}
|
|
|
|
public void testRowMapFirstKey() {
|
|
sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
|
|
assertSame("bar", sortedTable.rowMap().firstKey());
|
|
}
|
|
|
|
public void testRowMapLastKey() {
|
|
sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
|
|
assertSame("foo", sortedTable.rowMap().lastKey());
|
|
}
|
|
|
|
public void testRowKeyMapHeadMap() {
|
|
sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
|
|
Map<String, Map<Integer, Character>> map = sortedTable.rowMap().headMap("cat");
|
|
assertEquals(1, map.size());
|
|
assertEquals(ImmutableMap.of(1, 'b'), map.get("bar"));
|
|
map.clear();
|
|
assertTrue(map.isEmpty());
|
|
assertEquals(Collections.singleton("foo"), sortedTable.rowKeySet());
|
|
}
|
|
|
|
public void testRowKeyMapTailMap() {
|
|
sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
|
|
Map<String, Map<Integer, Character>> map = sortedTable.rowMap().tailMap("cat");
|
|
assertEquals(1, map.size());
|
|
assertEquals(ImmutableMap.of(1, 'a', 3, 'c'), map.get("foo"));
|
|
map.clear();
|
|
assertTrue(map.isEmpty());
|
|
assertEquals(Collections.singleton("bar"), sortedTable.rowKeySet());
|
|
}
|
|
|
|
public void testRowKeyMapSubMap() {
|
|
sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c', "dog", 2, 'd');
|
|
Map<String, Map<Integer, Character>> map = sortedTable.rowMap().subMap("cat", "egg");
|
|
assertEquals(ImmutableMap.of(2, 'd'), map.get("dog"));
|
|
map.clear();
|
|
assertTrue(map.isEmpty());
|
|
assertEquals(ImmutableSet.of("bar", "foo"), sortedTable.rowKeySet());
|
|
}
|
|
|
|
public void testRowMapValuesAreSorted() {
|
|
sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c', "dog", 2, 'd');
|
|
assertTrue(sortedTable.rowMap().get("foo") instanceof SortedMap);
|
|
}
|
|
|
|
public void testColumnKeySet_isSorted() {
|
|
table =
|
|
create(
|
|
"a", 2, 'X', "a", 2, 'X', "b", 3, 'X', "b", 2, 'X', "c", 10, 'X', "c", 10, 'X', "c", 20,
|
|
'X', "d", 15, 'X', "d", 20, 'X', "d", 1, 'X', "e", 5, 'X');
|
|
assertEquals("[1, 2, 3, 5, 10, 15, 20]", table.columnKeySet().toString());
|
|
}
|
|
|
|
public void testColumnKeySet_isSortedWithRealComparator() {
|
|
table =
|
|
create(
|
|
String.CASE_INSENSITIVE_ORDER,
|
|
Ordering.natural().reverse(),
|
|
"a",
|
|
2,
|
|
'X',
|
|
"a",
|
|
2,
|
|
'X',
|
|
"b",
|
|
3,
|
|
'X',
|
|
"b",
|
|
2,
|
|
'X',
|
|
"c",
|
|
10,
|
|
'X',
|
|
"c",
|
|
10,
|
|
'X',
|
|
"c",
|
|
20,
|
|
'X',
|
|
"d",
|
|
15,
|
|
'X',
|
|
"d",
|
|
20,
|
|
'X',
|
|
"d",
|
|
1,
|
|
'X',
|
|
"e",
|
|
5,
|
|
'X');
|
|
assertEquals("[20, 15, 10, 5, 3, 2, 1]", table.columnKeySet().toString());
|
|
}
|
|
|
|
public void testColumnKeySet_empty() {
|
|
table = create();
|
|
assertEquals("[]", table.columnKeySet().toString());
|
|
}
|
|
|
|
public void testColumnKeySet_oneRow() {
|
|
table = create("a", 2, 'X', "a", 1, 'X');
|
|
assertEquals("[1, 2]", table.columnKeySet().toString());
|
|
}
|
|
|
|
public void testColumnKeySet_oneColumn() {
|
|
table = create("a", 1, 'X', "b", 1, 'X');
|
|
assertEquals("[1]", table.columnKeySet().toString());
|
|
}
|
|
|
|
public void testColumnKeySet_oneEntry() {
|
|
table = create("a", 1, 'X');
|
|
assertEquals("[1]", table.columnKeySet().toString());
|
|
}
|
|
|
|
public void testRowEntrySetContains() {
|
|
table =
|
|
sortedTable =
|
|
create(
|
|
"a", 2, 'X', "a", 2, 'X', "b", 3, 'X', "b", 2, 'X', "c", 10, 'X', "c", 10, 'X', "c",
|
|
20, 'X', "d", 15, 'X', "d", 20, 'X', "d", 1, 'X', "e", 5, 'X');
|
|
SortedMap<Integer, Character> row = sortedTable.row("c");
|
|
Set<Entry<Integer, Character>> entrySet = row.entrySet();
|
|
assertTrue(entrySet.contains(Maps.immutableEntry(10, 'X')));
|
|
assertTrue(entrySet.contains(Maps.immutableEntry(20, 'X')));
|
|
assertFalse(entrySet.contains(Maps.immutableEntry(15, 'X')));
|
|
entrySet = row.tailMap(15).entrySet();
|
|
assertFalse(entrySet.contains(Maps.immutableEntry(10, 'X')));
|
|
assertTrue(entrySet.contains(Maps.immutableEntry(20, 'X')));
|
|
assertFalse(entrySet.contains(Maps.immutableEntry(15, 'X')));
|
|
}
|
|
|
|
public void testRowEntrySetRemove() {
|
|
table =
|
|
sortedTable =
|
|
create(
|
|
"a", 2, 'X', "a", 2, 'X', "b", 3, 'X', "b", 2, 'X', "c", 10, 'X', "c", 10, 'X', "c",
|
|
20, 'X', "d", 15, 'X', "d", 20, 'X', "d", 1, 'X', "e", 5, 'X');
|
|
SortedMap<Integer, Character> row = sortedTable.row("c");
|
|
Set<Entry<Integer, Character>> entrySet = row.tailMap(15).entrySet();
|
|
assertFalse(entrySet.remove(Maps.immutableEntry(10, 'X')));
|
|
assertTrue(entrySet.remove(Maps.immutableEntry(20, 'X')));
|
|
assertFalse(entrySet.remove(Maps.immutableEntry(15, 'X')));
|
|
entrySet = row.entrySet();
|
|
assertTrue(entrySet.remove(Maps.immutableEntry(10, 'X')));
|
|
assertFalse(entrySet.remove(Maps.immutableEntry(20, 'X')));
|
|
assertFalse(entrySet.remove(Maps.immutableEntry(15, 'X')));
|
|
}
|
|
|
|
public void testRowSize() {
|
|
table =
|
|
sortedTable =
|
|
create(
|
|
"a", 2, 'X', "a", 2, 'X', "b", 3, 'X', "b", 2, 'X', "c", 10, 'X', "c", 10, 'X', "c",
|
|
20, 'X', "d", 15, 'X', "d", 20, 'X', "d", 1, 'X', "e", 5, 'X');
|
|
SortedMap<Integer, Character> row = sortedTable.row("c");
|
|
assertEquals(2, row.size());
|
|
assertEquals(1, row.tailMap(15).size());
|
|
}
|
|
|
|
public void testSubRowClearAndPut() {
|
|
table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
|
|
SortedMap<Integer, Character> row = (SortedMap<Integer, Character>) table.row("foo");
|
|
SortedMap<Integer, Character> subRow = row.tailMap(2);
|
|
assertEquals(ImmutableMap.of(1, 'a', 3, 'c'), row);
|
|
assertEquals(ImmutableMap.of(3, 'c'), subRow);
|
|
table.remove("foo", 3);
|
|
assertEquals(ImmutableMap.of(1, 'a'), row);
|
|
assertEquals(ImmutableMap.of(), subRow);
|
|
table.remove("foo", 1);
|
|
assertEquals(ImmutableMap.of(), row);
|
|
assertEquals(ImmutableMap.of(), subRow);
|
|
table.put("foo", 2, 'b');
|
|
assertEquals(ImmutableMap.of(2, 'b'), row);
|
|
assertEquals(ImmutableMap.of(2, 'b'), subRow);
|
|
row.clear();
|
|
assertEquals(ImmutableMap.of(), row);
|
|
assertEquals(ImmutableMap.of(), subRow);
|
|
table.put("foo", 5, 'x');
|
|
assertEquals(ImmutableMap.of(5, 'x'), row);
|
|
assertEquals(ImmutableMap.of(5, 'x'), subRow);
|
|
}
|
|
}
|