// 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.acceptancetests.input; import static com.agical.bumblebee.junit4.Storage.store; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; import org.dtangler.core.configuration.Arguments; import org.dtangler.core.configuration.Group; import org.dtangler.core.configuration.ParserConstants; import org.dtangler.core.input.ArgumentBuilder; import org.dtangler.core.input.CommandLineParser; import org.junit.Test; public class ConfigurationParsingAcceptanceTest { /*!! #{set_header 'Run options: Configuration'} */ private final String cycleKey = CommandLineParser .getKeyString(ParserConstants.CYCLES_ALLOWED_KEY); private final String groupsKey = CommandLineParser .getKeyString(ParserConstants.GROUPS_KEY); private final String groupKey = CommandLineParser .getKeyString(ParserConstants.GROUP_KEY); private final String rulesKey = CommandLineParser .getKeyString(ParserConstants.RULES_KEY); @Test public void cyclesAreDisallowedByDefault() { /*! If the **=#{cycles}=** option is omitted, cycles are treated as errors. */ store("cycles", ParserConstants.CYCLES_ALLOWED_KEY); Arguments arguments = new ArgumentBuilder().build(new String[] {}); assertFalse("Cycles should be denied by default", arguments .getCyclesAllowed()); } @Test public void allowingCyclicDependencies() { /*! #{exclude} */ String allowed = cycleKey + ParserConstants.VALUE_TRUE; store("allowed", allowed); Arguments arguments = new ArgumentBuilder() .build(new String[] { allowed }); assertTrue(arguments.getCyclesAllowed()); } @Test public void disallowingCyclicDependencies() { /*! #{exclude} */ String disallowed = cycleKey + ParserConstants.VALUE_FALSE; store("disallowed", disallowed); Arguments arguments = new ArgumentBuilder() .build(new String[] { disallowed }); assertFalse(arguments.getCyclesAllowed()); } @Test public void specifyGroupsToSimplifyRules() { /*! Configuring dependency rules that apply to multiple items is easier when done with groups. You can also use asterisks (*) as wildcards when entering group members. Usage: >>>> #{groupsKey}\<group name\> #{contains} \<member name\> <<<< - You can enter *multiple members* to a group by separating them with commas. - You can enter *multiple groups* by separating them with semi-colons. For example: >>>> #{groupExample1} <<<< *Backward compatibility:* the older =#{group}= run option is interchangeable with =#{groups}=. */ String groupValue = "MyGroup " + ParserConstants.CONTAINS + " foo" + ParserConstants.SMALL_SEPARATOR + " bar" + ParserConstants.BIG_SEPARATOR + " PublicGroup " + ParserConstants.CONTAINS + " *public*"; String newGroup = groupsKey + groupValue; String oldGroup = groupKey + groupValue; store("groupsKey", groupsKey); store("group", ParserConstants.GROUP_KEY); store("groups", ParserConstants.GROUPS_KEY); store("contains", ParserConstants.CONTAINS); store("groupExample1", newGroup); Arguments newArguments = new ArgumentBuilder() .build(new String[] { newGroup }); Arguments oldArguments = new ArgumentBuilder() .build(new String[] { oldGroup }); Map<String, Group> parsedGroups = newArguments.getGroups(); assertEquals(oldArguments, newArguments); assertGroupByName(parsedGroups.get("MyGroup"), Arrays.asList("foo", "bar"), Collections.EMPTY_LIST); assertGroupByName(parsedGroups.get("PublicGroup"), Arrays .asList("*public*"), Collections.EMPTY_LIST); } @Test public void excludeItemsFromGroups() { /*! Items can be excluded from a group with the **=#{doesNotContain}=** option. For example: >>>> #{groupExample2} <<<< */ store("doesNotContain", ParserConstants.DOES_NOT_CONTAIN); String group = groupsKey + "Org " + ParserConstants.CONTAINS + " org.* " + ParserConstants.DOES_NOT_CONTAIN + " org.public.*" + ParserConstants.SMALL_SEPARATOR + "org.util.*"; store("groupExample2", group); Arguments arguments = new ArgumentBuilder() .build(new String[] { group }); assertGroupByName(arguments.getGroups().get("Org"), Arrays .asList("org.*"), Arrays.asList("org.public.*", "org.util.*")); } private void assertGroupByName(Group group, List<String> expectedIncl, List<String> expectedExcl) { assertNotNull(group); assertMembers(group.getGroupItems(), expectedIncl); assertMembers(group.getExcludedItems(), expectedExcl); } private void assertMembers(Set<String> actual, List<String> expected) { assertEquals(expected.size(), actual.size()); for (String member : actual) { assertTrue(expected.contains(member)); } } @Test public void forbiddenDependencies() { /*! Specifies what dependencies are *not allowed.* Usage: >>>> #{rulesKey}\<item name\> #{forbidden} \<item name\> <<<< - You can enter *multiple items* by separating them with commas (,). - You can enter *multiple rules* by separating them with semi-colons (;). For example: >>>> #{forbiddenDependenciesExample1} <<<< */ String rule = rulesKey + "y " + ParserConstants.CANNOT_DEPEND + " x" + ParserConstants.SMALL_SEPARATOR + " z" + ParserConstants.BIG_SEPARATOR + " b" + ParserConstants.SMALL_SEPARATOR + " c " + ParserConstants.CANNOT_DEPEND + " a"; store("forbidden", ParserConstants.CANNOT_DEPEND); store("rulesKey", rulesKey); store("forbiddenDependenciesExample1", rule); Arguments arguments = new ArgumentBuilder() .build(new String[] { rule }); assertRuleByName(arguments.getForbiddenDependencies().get("y"), Arrays .asList("x", "z")); assertRuleByName(arguments.getForbiddenDependencies().get("b"), Arrays .asList("a")); assertRuleByName(arguments.getForbiddenDependencies().get("c"), Arrays .asList("a")); } @Test public void allowedDependencies() { /*! Allowed dependencies provide a way to make exceptions to forbidden dependencies. Allowed dependencies **override** forbidden dependencies. Allowed dependencies are listed alongside forbidden dependencies in **=#{rules}=**, with the parameter **=#{can}=**. Consider the following example: >>>> #{groupExample3} #{ruleExample1} <<<< - A group that contains all items starting with 'org.domain.' is specified. - All dependencies between the items in the group are forbidden. - The '#{can}' rule overrides the '#{cannot}' rule and allows dependencies from org.domain.public.foo to org.domain.public.bar. */ String group = groupsKey + "Domain " + ParserConstants.CONTAINS + " org.domain.*"; String rule = rulesKey + "@Domain " + ParserConstants.CANNOT_DEPEND + " @Domain" + ParserConstants.BIG_SEPARATOR + " org.domain.public.foo " + ParserConstants.CAN_DEPEND + " org.domain.public.bar"; store("cannot", ParserConstants.CANNOT_DEPEND); store("can", ParserConstants.CAN_DEPEND); store("rules", ParserConstants.RULES_KEY); store("groupExample3", group); store("ruleExample1", rule); Arguments arguments = new ArgumentBuilder().build(new String[] { rule, group }); assertRuleByName(arguments.getAllowedDependencies().get( "org.domain.public.foo"), Arrays .asList("org.domain.public.bar")); assertRuleByName(arguments.getForbiddenDependencies().get("@Domain"), Arrays.asList("@Domain")); } private void assertRuleByName(Set<String> actual, List<String> expected) { assertNotNull(actual); assertEquals(expected.size(), actual.size()); for (String item : actual) { assertTrue(expected.contains(item)); } } }