/** * Copyright 2011 meltmedia * * 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 org.xchain.framework.util; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import javax.xml.namespace.QName; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.junit.After; import org.junit.Before; import org.junit.Test; /** * @author Christian Trimble * @author Devon Tackett * @author Josh Kennedy */ public class DependencySorterTest { public static Logger log = LoggerFactory.getLogger(DependencySorterTest.class); public static QName LABEL_1 = new QName("http://www.xchain.org/test", "label1"); public static QName LABEL_2 = new QName("http://www.xchain.org/test", "label2"); public static QName LABEL_3 = new QName("http://www.xchain.org/test", "label3"); public static QName LABEL_4 = new QName("http://www.xchain.org/test", "label4"); public static QName LABEL_5 = new QName("http://www.xchain.org/test", "label5"); public static QName LABEL_6 = new QName("http://www.xchain.org/test", "label6"); @Before public void setUp() { } @After public void tearDown() { } @Test public void testNoEdges() throws Exception { DependencySorter<QName> sorter = new DependencySorter<QName>(new LexicographicQNameComparator()); sorter.add(LABEL_1); sorter.add(LABEL_2); sorter.add(LABEL_3); List<QName> sorted = sorter.sort(); // test the size. assertEquals("The sorted list has the wrong size.", 3, sorted.size()); // make sure that the list contains the 3 lables. assertTrue("The sorted list does not contain label 1.", sorted.contains(LABEL_1)); assertTrue("The sorted list does not contain label 2.", sorted.contains(LABEL_2)); assertTrue("The sorted list does not contain label 3.", sorted.contains(LABEL_3)); } @Test public void testTwoEdges() throws Exception { DependencySorter<QName> sorter = new DependencySorter<QName>(new LexicographicQNameComparator()); sorter.addDependency(LABEL_1, LABEL_2); sorter.addDependency(LABEL_2, LABEL_3); List<QName> sorted = sorter.sort(); // test the size. assertEquals("The sorted list has the wrong size.", 3, sorted.size()); // make sure that the list contains the 3 lables. Iterator<QName> iterator = sorted.iterator(); assertEquals("Label 1 should have been the first entry.", LABEL_1, iterator.next()); assertEquals("Label 2 should have been the second entry.", LABEL_2, iterator.next()); assertEquals("Label 3 should have been the third entry.", LABEL_3, iterator.next()); } @Test public void testTwoEdgesDefinedInReverse() throws Exception { DependencySorter<QName> sorter = new DependencySorter<QName>(new LexicographicQNameComparator()); sorter.addDependency(LABEL_2, LABEL_3); sorter.addDependency(LABEL_1, LABEL_2); List<QName> sorted = sorter.sort(); // test the size. assertEquals("The sorted list has the wrong size.", 3, sorted.size()); // make sure that the list contains the 3 lables. Iterator<QName> iterator = sorted.iterator(); assertEquals("Label 1 should have been the first entry.", LABEL_1, iterator.next()); assertEquals("Label 2 should have been the second entry.", LABEL_2, iterator.next()); assertEquals("Label 3 should have been the third entry.", LABEL_3, iterator.next()); } @Test public void testTwoLabelCycle() throws Exception { DependencySorter<QName> sorter = new DependencySorter<QName>(new LexicographicQNameComparator()); sorter.addDependency(LABEL_2, LABEL_1); sorter.addDependency(LABEL_1, LABEL_2); try { List<QName> sorted = sorter.sort(); fail("Dependency cycle not detected."); } catch( DependencyCycleException dce ) { // make sure that the cycle is in the exception. Map cycle = dce.getCycle(); assertTrue("Label 1 should have been in the cycle.", cycle.containsKey(LABEL_1)); assertTrue("Label 2 should have been in the cycle.", cycle.containsKey(LABEL_2)); Set label1DependencySet = (Set)cycle.get(LABEL_1); Set label2DependencySet = (Set)cycle.get(LABEL_2); assertEquals("Label 1 should have 1 dependency.", 1, label1DependencySet.size()); assertTrue("Label 1 should be dependent on label 2.", label1DependencySet.contains(LABEL_2)); assertEquals("Label 2 should have 1 dependency.", 1, label2DependencySet.size()); assertTrue("Label 2 should be dependent on label 1.", label2DependencySet.contains(LABEL_1)); } } @Test public void testThreeLabelCycle() throws Exception { DependencySorter<QName> sorter = new DependencySorter<QName>(new LexicographicQNameComparator()); sorter.addDependency(LABEL_1, LABEL_2); sorter.addDependency(LABEL_2, LABEL_3); sorter.addDependency(LABEL_3, LABEL_1); try { List<QName> sorted = sorter.sort(); fail("Dependency cycle not detected."); } catch( DependencyCycleException dce ) { // make sure that the cycle is in the exception. Map cycle = dce.getCycle(); assertTrue("Label 1 should have been in the cycle.", cycle.containsKey(LABEL_1)); assertTrue("Label 2 should have been in the cycle.", cycle.containsKey(LABEL_2)); assertTrue("Label 3 should have been in the cycle.", cycle.containsKey(LABEL_3)); Set label1DependencySet = (Set)cycle.get(LABEL_1); Set label2DependencySet = (Set)cycle.get(LABEL_2); Set label3DependencySet = (Set)cycle.get(LABEL_3); assertEquals("Label 1 should have 1 dependency.", 1, label1DependencySet.size()); assertTrue("Label 1 should be dependent on label 2.", label1DependencySet.contains(LABEL_2)); assertEquals("Label 2 should have 1 dependency.", 1, label2DependencySet.size()); assertTrue("Label 2 should be dependent on label 3.", label2DependencySet.contains(LABEL_3)); assertEquals("Label 3 should have 1 dependency.", 1, label3DependencySet.size()); assertTrue("Label 3 should be dependent on label 3.", label3DependencySet.contains(LABEL_1)); } } @Test public void testThreeLabelCycleWithOtherLabels() throws Exception { DependencySorter<QName> sorter = new DependencySorter<QName>(new LexicographicQNameComparator()); sorter.addDependency(LABEL_1, LABEL_2); sorter.addDependency(LABEL_2, LABEL_3); sorter.addDependency(LABEL_3, LABEL_1); sorter.addDependency(LABEL_3, LABEL_4); sorter.addDependency(LABEL_4, LABEL_5); sorter.addDependency(LABEL_6, LABEL_1); try { List<QName> sorted = sorter.sort(); fail("Dependency cycle not detected."); } catch( DependencyCycleException dce ) { // make sure that the cycle is in the exception. Map cycle = dce.getCycle(); assertTrue("Label 1 should have been in the cycle.", cycle.containsKey(LABEL_1)); assertTrue("Label 2 should have been in the cycle.", cycle.containsKey(LABEL_2)); assertTrue("Label 3 should have been in the cycle.", cycle.containsKey(LABEL_3)); Set label1DependencySet = (Set)cycle.get(LABEL_1); Set label2DependencySet = (Set)cycle.get(LABEL_2); Set label3DependencySet = (Set)cycle.get(LABEL_3); assertEquals("Label 1 should have 1 dependency.", 1, label1DependencySet.size()); assertTrue("Label 1 should be dependent on label 2.", label1DependencySet.contains(LABEL_2)); assertEquals("Label 2 should have 1 dependency.", 1, label2DependencySet.size()); assertTrue("Label 2 should be dependent on label 3.", label2DependencySet.contains(LABEL_3)); assertEquals("Label 3 should have 1 dependency.", 1, label3DependencySet.size()); assertTrue("Label 3 should be dependent on label 3.", label3DependencySet.contains(LABEL_1)); } } @Test public void testUndeterministicOrder() throws Exception { DependencySorter<QName> sorter = new DependencySorter<QName>(new LexicographicQNameComparator()); sorter.add(LABEL_5); sorter.add(LABEL_3); sorter.add(LABEL_1); sorter.add(LABEL_2); sorter.add(LABEL_6); sorter.add(LABEL_4); List<QName> sorted = sorter.sort(); // test the size. assertEquals("The sorted list has the wrong size.", 6, sorted.size()); // make sure that the list contains the 3 lables. assertEquals("The sorted list has label 1 out of order.", LABEL_1, sorted.get(0)); assertEquals("The sorted list has label 2 out of order.", LABEL_2, sorted.get(1)); assertEquals("The sorted list has label 3 out of order.", LABEL_3, sorted.get(2)); assertEquals("The sorted list has label 4 out of order.", LABEL_4, sorted.get(3)); assertEquals("The sorted list has label 5 out of order.", LABEL_5, sorted.get(4)); assertEquals("The sorted list has label 6 out of order.", LABEL_6, sorted.get(5)); } @Test public void testPartialUndeterministicOrder() throws Exception { DependencySorter<QName> sorter = new DependencySorter<QName>(new LexicographicQNameComparator()); // everyone depends on 3 sorter.addDependency(LABEL_3, LABEL_6); sorter.addDependency(LABEL_3, LABEL_1); sorter.addDependency(LABEL_3, LABEL_2); sorter.addDependency(LABEL_3, LABEL_5); sorter.addDependency(LABEL_3, LABEL_4); // 1 depends on 6 sorter.addDependency(LABEL_6, LABEL_1); // 4 depends on 2 sorter.addDependency(LABEL_2, LABEL_4); List<QName> sorted = sorter.sort(); // test the size. assertEquals("The sorted list has the wrong size.", 6, sorted.size()); // make sure that the list contains the 3 lables. assertEquals("The sorted list has label 3 out of order.", LABEL_3, sorted.get(0)); assertEquals("The sorted list has label 2 out of order.", LABEL_2, sorted.get(1)); assertEquals("The sorted list has label 5 out of order.", LABEL_5, sorted.get(2)); assertEquals("The sorted list has label 6 out of order.", LABEL_6, sorted.get(3)); assertEquals("The sorted list has label 1 out of order.", LABEL_1, sorted.get(4)); assertEquals("The sorted list has label 4 out of order.", LABEL_4, sorted.get(5)); } }