diff --git a/archunit/src/main/java/com/tngtech/archunit/library/plantuml/rules/PlantUmlComponent.java b/archunit/src/main/java/com/tngtech/archunit/library/plantuml/rules/PlantUmlComponent.java index 68fa280731..5c323c4aa6 100644 --- a/archunit/src/main/java/com/tngtech/archunit/library/plantuml/rules/PlantUmlComponent.java +++ b/archunit/src/main/java/com/tngtech/archunit/library/plantuml/rules/PlantUmlComponent.java @@ -91,7 +91,7 @@ public String toString() { "componentName=" + componentName + ", stereotypes=" + stereotypes + ", alias=" + alias + - ", dependencies=" + dependencies + + ", dependencies=" + dependencies.size() + '}'; } diff --git a/archunit/src/main/java/com/tngtech/archunit/library/plantuml/rules/PlantUmlPatterns.java b/archunit/src/main/java/com/tngtech/archunit/library/plantuml/rules/PlantUmlPatterns.java index a7ce0cfbca..6f29524fc1 100644 --- a/archunit/src/main/java/com/tngtech/archunit/library/plantuml/rules/PlantUmlPatterns.java +++ b/archunit/src/main/java/com/tngtech/archunit/library/plantuml/rules/PlantUmlPatterns.java @@ -36,6 +36,7 @@ class PlantUmlPatterns { private static final String OPTIONAL_COMPONENT_KEYWORD_FORMAT = "(?:component)?"; private static final String COMPONENT_NAME_GROUP_NAME = "componentName"; + private static final String LONG_COMPONENT_NAME_GROUP_NAME = "longComponentName"; private static final String COMPONENT_NAME_FORMAT = "\\[" + capture(anythingBut("\\[\\]"), COMPONENT_NAME_GROUP_NAME) + "]"; private static final String STEREOTYPE_FORMAT = "(?:<<" + capture(anythingBut("<>")) + ">>\\s*)"; @@ -46,9 +47,12 @@ class PlantUmlPatterns { private static final String COLOR_FORMAT = "\\s*(?:#" + anyOf("\\w|/\\\\-") + "+)?"; + private static final String COMPONENT_PACKAGE_IDENTIFIER = "(?:component|package)"; private static final Pattern PLANTUML_COMPONENT_PATTERN = Pattern.compile( - "^\\s*" + OPTIONAL_COMPONENT_KEYWORD_FORMAT - + "\\s*" + COMPONENT_NAME_FORMAT + "^\\s*" + + "(?:" + OPTIONAL_COMPONENT_KEYWORD_FORMAT + "\\s*" + COMPONENT_NAME_FORMAT + + "|" + COMPONENT_PACKAGE_IDENTIFIER + "\\s+\"" + + capture("[^\"]*", "longComponentName") + "\")" + "\\s*" + STEREOTYPE_FORMAT + "*" + ALIAS_FORMAT + COLOR_FORMAT @@ -105,7 +109,11 @@ static class PlantUmlComponentMatcher { } String matchComponentName() { - return componentMatcher.group(COMPONENT_NAME_GROUP_NAME); + String name = componentMatcher.group(COMPONENT_NAME_GROUP_NAME); + if (name == null) { + return componentMatcher.group(LONG_COMPONENT_NAME_GROUP_NAME); + } + return name; } Set matchStereoTypes() { diff --git a/archunit/src/test/java/com/tngtech/archunit/library/plantuml/rules/PlantUmlParserTest.java b/archunit/src/test/java/com/tngtech/archunit/library/plantuml/rules/PlantUmlParserTest.java index 873d8dde45..0a3e016d4d 100644 --- a/archunit/src/test/java/com/tngtech/archunit/library/plantuml/rules/PlantUmlParserTest.java +++ b/archunit/src/test/java/com/tngtech/archunit/library/plantuml/rules/PlantUmlParserTest.java @@ -34,6 +34,64 @@ public class PlantUmlParserTest { @Rule public final TemporaryFolder temporaryFolder = new TemporaryFolder(); + @Test + public void parses_long_syntax_from_file() { + PlantUmlDiagram diagram = parseFile("components-long-syntax.puml"); + + verifyComponentLayers(diagram); + verifyComponentAlias(diagram); + } + + @Test + public void parses_packages_from_file() { + PlantUmlDiagram diagram = parseFile("packages-long-syntax.puml"); + + verifyComponentLayers(diagram); + verifyComponentAlias(diagram); + } + + private void verifyComponentAlias(PlantUmlDiagram diagram) { + assertThat(diagram.getAllComponents()).hasSize(3) + .satisfiesExactlyInAnyOrder( + c -> assertThat(c.getAlias()).contains(new Alias("web")), + c -> assertThat(c.getAlias()).contains(new Alias("usecase")), + c -> assertThat(c.getAlias()).contains(new Alias("persistence"))); + } + + @Test + public void parses_components_from_file() { + PlantUmlDiagram diagram = parseFile("components-short-syntax.puml"); + + verifyComponentLayers(diagram); + assertThat(diagram.getAllComponents()).hasSize(3) + .allSatisfy(c -> assertThat(c.getAlias()).isEmpty()); + } + + private PlantUmlDiagram parseFile(final String fileName) { + return parser.parse(PlantUmlParserTest.class.getResource(fileName)); + } + + private void verifyComponentLayers(PlantUmlDiagram diagram) { + assertThat(diagram.getAllComponents()).hasSize(3) + .satisfiesExactlyInAnyOrder( + c -> { + assertThat(c.getComponentName()).isEqualTo(new ComponentName("Web API")); + assertThat(c.getDependencies()).hasSize(1); + assertThat(c.getStereotypes()).contains(new Stereotype("..web")); + }, + c -> { + assertThat(c.getComponentName()).isEqualTo(new ComponentName("Use Cases")); + assertThat(c.getDependencies()).hasSize(1); + assertThat(c.getStereotypes()).contains(new Stereotype("..usecase")); + }, + c -> { + assertThat(c.getComponentName()).isEqualTo(new ComponentName("Persistence")); + assertThat(c.getDependencies()).isEmpty(); + assertThat(c.getStereotypes()).contains(new Stereotype("..persistence")); + } + ); + } + @Test public void parses_correct_number_of_components() { PlantUmlDiagram diagram = createDiagram(TestDiagram.in(temporaryFolder) diff --git a/archunit/src/test/resources/com/tngtech/archunit/library/plantuml/rules/components-long-syntax.puml b/archunit/src/test/resources/com/tngtech/archunit/library/plantuml/rules/components-long-syntax.puml new file mode 100644 index 0000000000..10c29b3b0b --- /dev/null +++ b/archunit/src/test/resources/com/tngtech/archunit/library/plantuml/rules/components-long-syntax.puml @@ -0,0 +1,9 @@ +@startuml +component "Web API" <<..web>> as web +component "Use Cases" <<..usecase>> as usecase +component "Persistence" <<..persistence>> as persistence + +web --> usecase +usecase --> persistence + +@enduml diff --git a/archunit/src/test/resources/com/tngtech/archunit/library/plantuml/rules/components-short-syntax.puml b/archunit/src/test/resources/com/tngtech/archunit/library/plantuml/rules/components-short-syntax.puml new file mode 100644 index 0000000000..f6e9356fd6 --- /dev/null +++ b/archunit/src/test/resources/com/tngtech/archunit/library/plantuml/rules/components-short-syntax.puml @@ -0,0 +1,8 @@ +@startuml +[Web API] <<..web>> +[Use Cases] <<..usecase>> +[Persistence] <<..persistence>> + +[Web API] --> [Use Cases] +[Use Cases] --> [Persistence] +@enduml diff --git a/archunit/src/test/resources/com/tngtech/archunit/library/plantuml/rules/packages-long-syntax.puml b/archunit/src/test/resources/com/tngtech/archunit/library/plantuml/rules/packages-long-syntax.puml new file mode 100644 index 0000000000..7450bbae82 --- /dev/null +++ b/archunit/src/test/resources/com/tngtech/archunit/library/plantuml/rules/packages-long-syntax.puml @@ -0,0 +1,9 @@ +@startuml +package "Web API" <<..web>> as web +package "Use Cases" <<..usecase>> as usecase +package "Persistence" <<..persistence>> as persistence + +web --> usecase +usecase --> persistence + +@enduml