/*
* Copyright 2008 The Closure Compiler 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.javascript.jscomp.graph;
import static com.google.common.truth.Truth.assertThat;
import com.google.common.collect.ImmutableSet;
import junit.framework.TestCase;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
/**
* Unit test for the {@link StandardUnionFind} data structure.
*
*/
public final class StandardUnionFindTest extends TestCase {
private StandardUnionFind<String> union;
@Override protected void setUp() {
union = new StandardUnionFind<>();
}
public void testEmpty() {
assertThat(union.allEquivalenceClasses()).isEmpty();
}
public void testAdd() {
union.add("foo");
union.add("bar");
assertThat(null != union.find("foo")).isTrue();
assertThat(union.allEquivalenceClasses()).hasSize(2);
}
public void testUnion() {
union.union("A", "B");
union.union("C", "D");
assertThat(union.find("B")).isEqualTo(union.find("A"));
assertThat(union.find("D")).isEqualTo(union.find("C"));
assertThat(union.find("A").equals(union.find("D"))).isFalse();
}
public void testSetSize() {
union.union("A", "B");
union.union("B", "C");
union.union("D", "E");
union.union("F", "F");
assertThat(union.findAll("A")).hasSize(3);
assertThat(union.findAll("B")).hasSize(3);
assertThat(union.findAll("C")).hasSize(3);
assertThat(union.findAll("D")).hasSize(2);
assertThat(union.findAll("F")).hasSize(1);
}
public void testFind() {
union.add("A");
union.add("B");
assertThat(union.find("A")).isEqualTo("A");
assertThat(union.find("B")).isEqualTo("B");
union.union("A", "B");
assertThat(union.find("B")).isEqualTo(union.find("A"));
try {
union.find("Z");
fail("find() on unknown element should not be allowed.");
} catch (IllegalArgumentException expected) {
}
}
public void testAllEquivalenceClasses() {
union.union("A", "B");
union.union("A", "B");
union.union("B", "A");
union.union("B", "C");
union.union("D", "E");
union.union("F", "F");
Collection<Set<String>> classes = union.allEquivalenceClasses();
assertThat(classes).containsExactly(
ImmutableSet.of("A", "B", "C"), ImmutableSet.of("D", "E"), ImmutableSet.of("F"));
}
public void testFindAll() {
union.union("A", "B");
union.union("A", "B");
union.union("B", "A");
union.union("D", "E");
union.union("F", "F");
Set<String> aSet = union.findAll("A");
assertThat(aSet).containsExactly("A", "B");
union.union("B", "C");
assertThat(aSet).contains("C");
assertThat(aSet).hasSize(3);
try {
union.findAll("Z");
fail("findAll() on unknown element should not be allowed.");
} catch (IllegalArgumentException expected) {
}
}
public void testFindAllIterator() {
union.union("A", "B");
union.union("B", "C");
union.union("A", "B");
union.union("D", "E");
Set<String> aSet = union.findAll("A");
Iterator<String> aIter = aSet.iterator();
assertThat(aIter.hasNext()).isTrue();
assertThat(aIter.next()).isEqualTo("A");
assertThat(aIter.next()).isEqualTo("B");
assertThat(aIter.next()).isEqualTo("C");
assertThat(aIter.hasNext()).isFalse();
Set<String> dSet = union.findAll("D");
Iterator<String> dIter = dSet.iterator();
assertThat(dIter.hasNext()).isTrue();
assertThat(dIter.next()).isEqualTo("D");
assertThat(dIter.next()).isEqualTo("E");
assertThat(dIter.hasNext()).isFalse();
}
public void testFindAllSize() {
union.union("A", "B");
union.union("B", "C");
assertThat(union.findAll("A")).hasSize(3);
assertThat(union.findAll("B")).hasSize(3);
assertThat(union.findAll("C")).hasSize(3);
union.union("D", "E");
assertThat(union.findAll("C")).hasSize(3);
assertThat(union.findAll("D")).hasSize(2);
union.union("B", "E");
assertThat(union.findAll("C")).hasSize(5);
assertThat(union.findAll("D")).hasSize(5);
}
public void testElements() {
union.union("A", "B");
union.union("B", "C");
union.union("A", "B");
union.union("D", "E");
Set<String> elements = union.elements();
assertThat(elements).isEqualTo(ImmutableSet.of("A", "B", "C", "D", "E"));
assertThat(elements).doesNotContain("F");
}
public void testCopy() {
union.union("A", "B");
union.union("B", "Z");
union.union("X", "Y");
UnionFind<String> copy = new StandardUnionFind<>(union);
assertThat(copy.findAll("Z")).containsExactly("A", "B", "Z");
assertThat(copy.findAll("X")).containsExactly("X", "Y");
}
public void testChangesToCopyDontAffectOriginal() {
union.union("A", "B");
union.union("X", "Y");
union.union("A", "C");
UnionFind<String> copy = new StandardUnionFind<>(union);
copy.union("A", "D");
assertThat(copy.findAll("D")).containsExactly("A", "B", "C", "D");
assertThat(union.findAll("A")).containsExactly("A", "B", "C");
assertThat(copy.findAll("X")).containsExactly("X", "Y");
try {
union.findAll("D");
fail("D has been inserted to the original collection");
} catch (IllegalArgumentException e) {
// Expected.
}
}
public void testCheckEquivalent() {
union.union("A", "B");
union.add("C");
assertThat(union.areEquivalent("A", "B")).isTrue();
assertThat(union.areEquivalent("C", "A")).isFalse();
assertThat(union.areEquivalent("C", "B")).isFalse();
try {
union.areEquivalent("A", "F");
fail();
} catch (IllegalArgumentException e) {
// Expected.
}
}
}