// This product is provided under the terms of EPL (Eclipse Public License) // version 1.0. // // The full license text can be read from: http://www.eclipse.org/org/documents/epl-v10.php package org.dtangler.core.ruleanalysis; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.dtangler.core.analysisresult.Violation; import org.dtangler.core.configuration.Group; import org.dtangler.core.dependencies.Dependable; import org.dtangler.core.dependencies.Dependencies; import org.dtangler.core.dependencies.Dependency; import org.dtangler.core.dependencies.TestDependable; import org.dtangler.core.dependencies.TestScope; import org.dtangler.core.ruleanalysis.Rule.Type; import org.junit.Test; public class ForbiddenDependencyFinderTest { private static final String item1Name = "item1"; private static final String item2Name = "item2"; private static final String item3Name = "item3"; private static final String item4Name = "item4"; private Dependable item1 = new TestDependable(item1Name); private Dependable item2 = new TestDependable(item2Name); private Dependable item3 = new TestDependable(item3Name); private Dependable item4 = new TestDependable(item4Name); private Dependable package1 = new TestDependable("eg.foo", TestScope.scope2); private Dependable package2 = new TestDependable("eg.bar", TestScope.scope2); private Dependable package3 = new TestDependable("eg.bay", TestScope.scope2); private Dependable fooClass1 = new TestDependable("eg.foo.Class1", TestScope.scope3); private Dependable fooClass2 = new TestDependable("eg.foo.Class2", TestScope.scope3); private Dependable barClass1 = new TestDependable("eg.bar.Class1", TestScope.scope3); private Dependable barClass2 = new TestDependable("eg.bar.Class2", TestScope.scope3); private Dependable barClass3 = new TestDependable("eg.bar.Class3", TestScope.scope3); private Dependable bayClass1 = new TestDependable("eg.bay.Class1", TestScope.scope3); private Dependable bayClass2 = new TestDependable("eg.bay.Class2", TestScope.scope3); @Test public void testNoRules() { Dependencies dependencies = new Dependencies(); dependencies.addDependencies(item1, createMap(item2, item3)); dependencies.addDependencies(item3, createMap(item4)); ForbiddenDependencyFinder analyzer = new ForbiddenDependencyFinder( Collections.EMPTY_LIST); analyzer.analyze(dependencies); Map<Dependency, Set<Violation>> result = analyzer.getViolations(); assertTrue(result.isEmpty()); } private Set<Violation> getAllViolations( Map<Dependency, Set<Violation>> violations) { Set<Violation> result = new HashSet(); for (Set<Violation> subSet : violations.values()) result.addAll(subSet); return result; } @Test public void testSpecificItemRule() { Dependencies dependencies = new Dependencies(); dependencies.addDependencies(item1, createMap(item2, item3)); dependencies.addDependencies(item3, createMap(item4)); Dependable item1Dep = new TestDependable(item1Name); Dependable item2Dep = new TestDependable(item2Name); Rule rule = createRule(Type.cannotDepend, new SingleRuleMember(item1Dep .getDisplayName()), new SingleRuleMember(item2Dep .getDisplayName())); ForbiddenDependencyFinder analyzer = new ForbiddenDependencyFinder( Arrays.asList(rule)); analyzer.analyze(dependencies); Set<Violation> result = getAllViolations(analyzer.getViolations()); assertEquals(1, result.size()); assertTrue(result.contains(new RuleViolation(new Dependency(item1Dep, item2Dep), rule))); } @Test public void testMultipleViolationsForSameDependency() { Dependencies dependencies = new Dependencies(); dependencies.addDependencies(item1, createMap(item2)); Dependable item1Dep = new TestDependable(item1Name); Dependable item2Dep = new TestDependable(item2Name); Rule rule1 = createRule(Type.cannotDepend, new SingleRuleMember( item1Dep.getDisplayName()), new GroupRuleMember(createGroup( "Group1", item2Name, item3Name, item4Name))); Rule rule2 = createRule(Type.cannotDepend, new SingleRuleMember( item1Dep.getDisplayName()), new SingleRuleMember(item2Dep .getDisplayName())); ForbiddenDependencyFinder analyzer = new ForbiddenDependencyFinder( Arrays.asList(rule1, rule2)); analyzer.analyze(dependencies); Set<Violation> result = getAllViolations(analyzer.getViolations()); assertEquals(2, result.size()); assertTrue(result.contains(new RuleViolation(new Dependency(item1Dep, item2Dep), rule1))); assertTrue(result.contains(new RuleViolation(new Dependency(item1Dep, item2Dep), rule2))); } @Test public void testAllowedDependencyOverWritesForbiddenDependency() { Dependencies dependencies = new Dependencies(); dependencies.addDependencies(item1, createMap(item2, item3, item4)); Dependable item1Dep = new TestDependable(item1Name); Rule rule1 = createRule(Type.cannotDepend, new SingleRuleMember( item1Dep.getDisplayName()), new GroupRuleMember(createGroup( "x", item2Name, item3Name, item4Name))); Rule rule2 = createRule(Type.canDepend, new SingleRuleMember(item1Dep .getDisplayName()), new GroupRuleMember(createGroup("x", item3Name))); ForbiddenDependencyFinder analyzer = new ForbiddenDependencyFinder( Arrays.asList(rule1, rule2)); analyzer.analyze(dependencies); Set<Violation> result = getAllViolations(analyzer.getViolations()); assertEquals(2, result.size()); assertTrue(result.contains(new RuleViolation(new Dependency(item1Dep, new TestDependable(item2Name)), rule1))); assertTrue(result.contains(new RuleViolation(new Dependency(item1Dep, new TestDependable(item4Name)), rule1))); } @Test public void testRightSideWildCard() { Dependencies dependencies = new Dependencies(); Dependable foo = new TestDependable("eg.foo"); Dependable bar1 = new TestDependable("eg.bar.c1"); Dependable bar2 = new TestDependable("eg.bar.c2"); dependencies.addDependencies(foo, createMap(bar1, bar2)); Dependable fooDep = new TestDependable("eg.foo"); Rule rule = createRule(Type.cannotDepend, new SingleRuleMember(fooDep .getDisplayName()), new GroupRuleMember(createGroup("bar", "eg.bar.*"))); ForbiddenDependencyFinder analyzer = new ForbiddenDependencyFinder( Arrays.asList(rule)); analyzer.analyze(dependencies); Set<Violation> result = getAllViolations(analyzer.getViolations()); assertEquals(2, result.size()); assertTrue(result.contains(new RuleViolation(new Dependency(fooDep, new TestDependable("eg.bar.c1")), rule))); assertTrue(result.contains(new RuleViolation(new Dependency(fooDep, new TestDependable("eg.bar.c2")), rule))); } @Test public void testGroupOnBothSides() { Dependencies dependencies = new Dependencies(); Dependable foo = new TestDependable("foo"); Dependable bar = new TestDependable("bar"); dependencies.addDependencies(foo, createMap(item1, item2, item3)); dependencies.addDependencies(bar, createMap(item2)); Rule rule = createRule(Type.cannotDepend, new GroupRuleMember( createGroup("Group1", "foo", "bar")), new GroupRuleMember( createGroup("Group2", "item1", "item2"))); ForbiddenDependencyFinder analyzer = new ForbiddenDependencyFinder( Arrays.asList(rule)); analyzer.analyze(dependencies); Set<Violation> result = getAllViolations(analyzer.getViolations()); Dependable fooDep = new TestDependable("foo"); Dependable barDep = new TestDependable("bar"); assertEquals(3, result.size()); assertTrue(result.contains(new RuleViolation(new Dependency(fooDep, new TestDependable("item1")), rule))); assertTrue(result.contains(new RuleViolation(new Dependency(fooDep, new TestDependable("item2")), rule))); assertTrue(result.contains(new RuleViolation(new Dependency(barDep, new TestDependable("item2")), rule))); } @Test public void testGroupWithWildCardsOnBothSides() { Dependencies dependencies = new Dependencies(); Dependable foo1 = new TestDependable("foo.c1"); Dependable foo2 = new TestDependable("foo.c2"); Dependable bar1 = new TestDependable("bar.c1"); dependencies.addDependencies(foo1, createMap(item1, item2)); dependencies.addDependencies(foo2, createMap(item2)); dependencies.addDependencies(bar1, createMap(item2)); Rule rule = createRule(Type.cannotDepend, new GroupRuleMember( createGroup("foo", "foo*")), new GroupRuleMember(createGroup( "item", "item*"))); ForbiddenDependencyFinder analyzer = new ForbiddenDependencyFinder( Arrays.asList(rule)); analyzer.analyze(dependencies); Set<Violation> result = getAllViolations(analyzer.getViolations()); Dependable foo1Dep = new TestDependable("foo.c1"); Dependable foo2Dep = new TestDependable("foo.c2"); assertEquals(3, result.size()); assertTrue(result.contains(new RuleViolation(new Dependency(foo1Dep, new TestDependable("item1")), rule))); assertTrue(result.contains(new RuleViolation(new Dependency(foo1Dep, new TestDependable("item2")), rule))); assertTrue(result.contains(new RuleViolation(new Dependency(foo2Dep, new TestDependable("item2")), rule))); } @Test public void testDenyAll() { Dependencies dependencies = new Dependencies(); Dependable foo = new TestDependable("foo"); Dependable bar = new TestDependable("bar"); Dependable bay = new TestDependable("bay"); dependencies.addDependencies(foo, createMap(item1, item2)); dependencies.addDependencies(bar, createMap(item1, item2)); dependencies.addDependencies(bay, createMap(item1, item2)); Rule rule = createRule(Type.cannotDepend, new GroupRuleMember( createGroup("all", "*")), new GroupRuleMember(createGroup( "all", "*"))); ForbiddenDependencyFinder analyzer = new ForbiddenDependencyFinder( Arrays.asList(rule)); analyzer.analyze(dependencies); Set<Violation> result = getAllViolations(analyzer.getViolations()); assertEquals(6, result.size()); } @Test public void testDenyAllAndAllowSome() { Dependencies dependencies = new Dependencies(); Dependable foo = new TestDependable("foo"); Dependable bar = new TestDependable("bar"); Dependable bay = new TestDependable("bay"); dependencies.addDependencies(foo, createMap(item1, item2)); dependencies.addDependencies(bar, createMap(item1, item2)); dependencies.addDependencies(bay, createMap(item1, item2)); Rule rule1 = createRule(Type.cannotDepend, new GroupRuleMember( createGroup("all", "*")), new GroupRuleMember(createGroup( "all", "*"))); Rule rule2 = createRule(Type.canDepend, new GroupRuleMember( createGroup("bar", "bar")), new GroupRuleMember(createGroup( "all", "*"))); ForbiddenDependencyFinder analyzer = new ForbiddenDependencyFinder( Arrays.asList(rule1, rule2)); analyzer.analyze(dependencies); Set<Violation> result = getAllViolations(analyzer.getViolations()); assertEquals(4, result.size()); } private Dependencies createDependencies() { Dependencies dependencies = new Dependencies(); dependencies.addChild(package1, fooClass1); dependencies.addChild(package1, fooClass2); dependencies.addChild(package2, barClass1); dependencies.addChild(package2, barClass2); dependencies.addChild(package2, barClass3); dependencies.addChild(package3, bayClass1); dependencies.addChild(package3, bayClass2); return dependencies; } @Test public void testPackageRuleAffectsClassScope() { Dependencies dependencies = createDependencies(); dependencies.addDependencies(package1, createMap(package2)); dependencies.addDependencies(fooClass1, createMap(barClass1)); Rule packageLevelRule = createRule(Rule.Type.cannotDepend, new SingleRuleMember("eg.foo"), new SingleRuleMember("eg.bar")); ForbiddenDependencyFinder analyzer = new ForbiddenDependencyFinder( Arrays.asList(packageLevelRule)); analyzer.analyze(dependencies); Set<Violation> results = getAllViolations(analyzer.getViolations()); assertEquals(2, results.size()); assertTrue(results.contains(new RuleViolation(new Dependency(package1, package2), packageLevelRule))); assertTrue(results.contains(new RuleViolation(new Dependency(fooClass1, barClass1), packageLevelRule))); } @Test public void testAllowedDependencyOverwritesForbiddenDependencyWithGroups() { Dependencies dependencies = createDependencies(); dependencies.addDependencies(package1, createMap(package2, package3)); dependencies.addDependencies(package2, createMap(package3)); dependencies .addDependencies(fooClass1, createMap(barClass1, bayClass2)); dependencies.addDependencies(barClass1, createMap(barClass2)); dependencies.addDependencies(barClass3, createMap(bayClass2)); GroupRuleMember groupAll = new GroupRuleMember(createGroup("all", "*")); GroupRuleMember groupPart = new GroupRuleMember(createGroup("part", "*eg.ba*")); Rule rule1 = createRule(Type.cannotDepend, groupAll, groupPart); Rule rule2 = createRule(Type.canDepend, groupPart, groupPart); ForbiddenDependencyFinder analyzer = new ForbiddenDependencyFinder( Arrays.asList(rule1, rule2)); analyzer.analyze(dependencies); Set<Violation> result = getAllViolations(analyzer.getViolations()); assertEquals(4, result.size()); } @Test public void testFindOnlyForbiddenDependencies() { Dependencies dependencies = createDependencies(); setDependencies(dependencies); Rule packageLevelRule = createRule(Rule.Type.cannotDepend, new SingleRuleMember("eg.foo"), new SingleRuleMember("eg.bar")); Rule allowedRule = createRule(Rule.Type.canDepend, new SingleRuleMember("eg.foo.Class1"), new SingleRuleMember( "eg.bar.Class1")); ForbiddenDependencyFinder analyzer = new ForbiddenDependencyFinder( Arrays.asList(packageLevelRule, allowedRule)); analyzer.analyze(dependencies); Set<Violation> results = getAllViolations(analyzer.getViolations()); assertEquals(2, results.size()); assertTrue(results.contains(new RuleViolation(new Dependency(package1, package2), packageLevelRule))); assertTrue(results.contains(new RuleViolation(new Dependency(fooClass2, barClass1), packageLevelRule))); } private void setDependencies(Dependencies dependencies) { dependencies.addDependencies(package1, createMap(package2)); dependencies .addDependencies(fooClass1, createMap(fooClass2, barClass1)); dependencies.addDependencies(fooClass2, createMap(barClass1)); dependencies.addDependencies(barClass2, createMap(barClass1)); } private Group createGroup(String name, String... items) { return new Group(name, new HashSet(Arrays.asList(items))); } private Map<Dependable, Integer> createMap(Dependable... items) { Map<Dependable, Integer> result = new HashMap(); for (Dependable item : items) { result.put(item, 1); } return result; } private Rule createRule(Type type, RuleMember leftSide, RuleMember... rightSideMembers) { return new Rule(type, leftSide, new HashSet(Arrays .asList(rightSideMembers))); } }