Skip to content

Commit

Permalink
structurizr-dsl: description and technology now work inside `!ele…
Browse files Browse the repository at this point in the history
…ments` blocks.
  • Loading branch information
simonbrowndotje committed Nov 30, 2024
1 parent d95879f commit b6fd8cd
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 0 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- structurizr-dsl: Adds support for `element!=` expressions.
- structurizr-dsl: `!elements` and `!relationships` now work inside deployment environment blocks.
- structurizr-dsl: `description` and `technology` now work inside `!elements` blocks.

## 3.1.0 (4th November 2024)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ Set<ModelItem> getModelItems() {
protected String[] getPermittedTokens() {
return new String[] {
StructurizrDslTokens.RELATIONSHIP_TOKEN,
StructurizrDslTokens.DESCRIPTION_TOKEN,
StructurizrDslTokens.TECHNOLOGY_TOKEN,
StructurizrDslTokens.TAG_TOKEN,
StructurizrDslTokens.TAGS_TOKEN,
StructurizrDslTokens.URL_TOKEN,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.structurizr.dsl;

import com.structurizr.model.*;

final class ElementsParser extends AbstractParser {

private final static int DESCRIPTION_INDEX = 1;
private final static int TECHNOLOGY_INDEX = 1;

void parseDescription(ElementsDslContext context, Tokens tokens) {
// description <description>
if (tokens.hasMoreThan(DESCRIPTION_INDEX)) {
throw new RuntimeException("Too many tokens, expected: description <description>");
}

if (!tokens.includes(DESCRIPTION_INDEX)) {
throw new RuntimeException("Expected: description <description>");
}

String description = tokens.get(DESCRIPTION_INDEX);
for (Element element : context.getElements()) {
element.setDescription(description);
}
}

void parseTechnology(ElementsDslContext context, Tokens tokens) {
// technology <technology>
if (tokens.hasMoreThan(TECHNOLOGY_INDEX)) {
throw new RuntimeException("Too many tokens, expected: technology <technology>");
}

if (!tokens.includes(TECHNOLOGY_INDEX)) {
throw new RuntimeException("Expected: technology <technology>");
}

String technology = tokens.get(TECHNOLOGY_INDEX);
for (Element element : context.getElements()) {
if (element instanceof Container) {
((Container)element).setTechnology(technology);
} else if (element instanceof Component) {
((Component)element).setTechnology(technology);
} else if (element instanceof DeploymentNode) {
((DeploymentNode)element).setTechnology(technology);
} else if (element instanceof InfrastructureNode) {
((InfrastructureNode)element).setTechnology(technology);
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,9 @@ void parse(List<String> lines, File dslFile, boolean fragment, boolean includeIn
} else if (DESCRIPTION_TOKEN.equalsIgnoreCase(firstToken) && inContext(ElementDslContext.class) && !isGroup(getContext())) {
new ModelItemParser().parseDescription(getContext(ElementDslContext.class), tokens);

} else if (DESCRIPTION_TOKEN.equalsIgnoreCase(firstToken) && inContext(ElementsDslContext.class)) {
new ElementsParser().parseDescription(getContext(ElementsDslContext.class), tokens);

} else if (TECHNOLOGY_TOKEN.equalsIgnoreCase(firstToken) && inContext(ContainerDslContext.class) && !getContext(ContainerDslContext.class).hasGroup()) {
new ContainerParser().parseTechnology(getContext(ContainerDslContext.class), tokens);

Expand All @@ -549,6 +552,9 @@ void parse(List<String> lines, File dslFile, boolean fragment, boolean includeIn
} else if (TECHNOLOGY_TOKEN.equalsIgnoreCase(firstToken) && inContext(InfrastructureNodeDslContext.class)) {
new InfrastructureNodeParser().parseTechnology(getContext(InfrastructureNodeDslContext.class), tokens);

} else if (TECHNOLOGY_TOKEN.equalsIgnoreCase(firstToken) && inContext(ElementsDslContext.class)) {
new ElementsParser().parseTechnology(getContext(ElementsDslContext.class), tokens);

} else if (INSTANCES_TOKEN.equalsIgnoreCase(firstToken) && inContext(DeploymentNodeDslContext.class)) {
new DeploymentNodeParser().parseInstances(getContext(DeploymentNodeDslContext.class), tokens);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.structurizr.dsl;

import com.structurizr.model.*;
import org.junit.jupiter.api.Test;

import java.util.Set;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;

class ElementsParserTests extends AbstractTests {

private final ElementsParser parser = new ElementsParser();

@Test
void test_parseTechnology_ThrowsAnException_WhenNoTechnologyIsSpecified() {
try {
parser.parseTechnology(null, tokens("technology"));
fail();
} catch (Exception e) {
assertEquals("Expected: technology <technology>", e.getMessage());
}
}

@Test
void test_parseTechnology() {
SoftwareSystem softwareSystem = model.addSoftwareSystem("Software System");
Container container = softwareSystem.addContainer("Container");
Component component = container.addComponent("Component");
DeploymentNode deploymentNode = model.addDeploymentNode("Deployment Node");
InfrastructureNode infrastructureNode = deploymentNode.addInfrastructureNode("Infrastructure Node");

ElementsDslContext context = new ElementsDslContext(null, Set.of(softwareSystem, container, component, deploymentNode, infrastructureNode));

parser.parseTechnology(context, tokens("technology", "Technology"));
assertEquals("Technology", container.getTechnology());
assertEquals("Technology", component.getTechnology());
assertEquals("Technology", deploymentNode.getTechnology());
assertEquals("Technology", infrastructureNode.getTechnology());
}

@Test
void test_parseDescription_ThrowsAnException_WhenNoDescriptionIsSpecified() {
try {
parser.parseDescription(null, tokens("description"));
fail();
} catch (Exception e) {
assertEquals("Expected: description <description>", e.getMessage());
}
}

@Test
void test_parseDescription() {
SoftwareSystem softwareSystem = model.addSoftwareSystem("Software System");
Container container = softwareSystem.addContainer("Container");
Component component = container.addComponent("Component");
DeploymentNode deploymentNode = model.addDeploymentNode("Deployment Node");
InfrastructureNode infrastructureNode = deploymentNode.addInfrastructureNode("Infrastructure Node");

ElementsDslContext context = new ElementsDslContext(null, Set.of(softwareSystem, container, component, deploymentNode, infrastructureNode));

parser.parseDescription(context, tokens("description", "Description"));
assertEquals("Description", softwareSystem.getDescription());
assertEquals("Description", container.getDescription());
assertEquals("Description", component.getDescription());
assertEquals("Description", deploymentNode.getDescription());
assertEquals("Description", infrastructureNode.getDescription());
}

}

0 comments on commit b6fd8cd

Please # to comment.