Skip to content

Commit

Permalink
Improve support for bounded context canvases (#323)
Browse files Browse the repository at this point in the history
  • Loading branch information
boxleytw authored Nov 10, 2022
1 parent 4e3142f commit 0b248f2
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 29 deletions.
1 change: 1 addition & 0 deletions .java-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
11.0
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import org.contextmapper.dsl.contextMappingDSL.BoundedContext
import org.contextmapper.dsl.contextMappingDSL.BoundedContextType
import org.contextmapper.dsl.contextMappingDSL.ContextMappingDSLPackage
import org.contextmapper.dsl.contextMappingDSL.ContextMappingModel
import org.contextmapper.dsl.contextMappingDSL.Evolution
import org.contextmapper.dsl.contextMappingDSL.KnowledgeLevel
import org.eclipse.xtext.testing.InjectWith
import org.eclipse.xtext.testing.extensions.InjectionExtension
Expand Down Expand Up @@ -158,6 +159,38 @@ class BoundedContextDSLParsingTest {
assertEquals("Java / Spring Boot App", result.boundedContexts.get(0).implementationTechnology);
}

@Test
def void canDefineBusinessModel() {
// given
val String dslSnippet = '''
BoundedContext testContext {
businessModel = "ENGAGEMENT"
}
''';
// when
val ContextMappingModel result = parseHelper.parse(dslSnippet);
// then
assertThatNoParsingErrorsOccurred(result);
assertThatNoValidationErrorsOccurred(result);
assertEquals("ENGAGEMENT", result.boundedContexts.get(0).businessModel);
}

@Test
def void canDefineEvolution() {
// given
val String dslSnippet = '''
BoundedContext testContext {
evolution = CUSTOM_BUILT
}
''';
// when
val ContextMappingModel result = parseHelper.parse(dslSnippet);
// then
assertThatNoParsingErrorsOccurred(result);
assertThatNoValidationErrorsOccurred(result);
assertEquals(Evolution.CUSTOM_BUILT, result.boundedContexts.get(0).evolution);
}

@Test
def void canDefineTeamRealizesContext() {
// given
Expand All @@ -174,7 +207,7 @@ class BoundedContextDSLParsingTest {
// then
assertThatNoParsingErrorsOccurred(result);
assertThatNoValidationErrorsOccurred(result);

val BoundedContext team = result.boundedContexts.findFirst[it.type == BoundedContextType.TEAM];
assertEquals("ContextA", team.realizedBoundedContexts.get(0).name);
}
Expand All @@ -199,7 +232,7 @@ class BoundedContextDSLParsingTest {
// then
assertThatNoParsingErrorsOccurred(result);
assertThatNoValidationErrorsOccurred(result);

val BoundedContext team = result.boundedContexts.findFirst[it.type == BoundedContextType.TEAM];
val realizedBCNames = team.realizedBoundedContexts.stream.map[name].collect(Collectors.toList);
assertTrue(realizedBCNames.contains("ContextA"));
Expand All @@ -223,8 +256,8 @@ class BoundedContextDSLParsingTest {
assertThatNoParsingErrorsOccurred(result);
validationTestHelper.assertError(result, ContextMappingDSLPackage.Literals.BOUNDED_CONTEXT, "",
String.format(ONLY_TEAMS_CAN_REALIZE_OTHER_BOUNDED_CONTEXT, "NotATeam"));
}
}

@Test
def void canDefineAttributesWithoutEqualSign() {
// given
Expand All @@ -239,20 +272,20 @@ class BoundedContextDSLParsingTest {
''';
// when
val ContextMappingModel result = parseHelper.parse(dslSnippet);

// then
assertThatNoParsingErrorsOccurred(result);
assertThatNoValidationErrorsOccurred(result);
assertEquals("Java / Spring Boot App", result.boundedContexts.get(0).implementationTechnology);
assertEquals(KnowledgeLevel.META, result.boundedContexts.get(0).knowledgeLevel);
assertEquals("this is my vision", result.boundedContexts.get(0).domainVisionStatement);

val responsibilities = result.boundedContexts.get(0).responsibilities;
assertTrue(responsibilities.contains("a responsibility description..."));
assertTrue(responsibilities.contains("another responsibility"));
assertEquals(BoundedContextType.FEATURE, result.boundedContexts.get(0).type);
}

@Test
def void canRefineOtherBoundedContext() {
// given
Expand All @@ -262,11 +295,11 @@ class BoundedContextDSLParsingTest {
''';
// when
val ContextMappingModel result = parseHelper.parse(dslSnippet);

// then
assertThatNoParsingErrorsOccurred(result);
assertThatNoValidationErrorsOccurred(result);

val contextMapperContext = result.boundedContexts.get(1);
assertEquals("ContextMapper", contextMapperContext.name);
assertEquals("StrategicDDD", contextMapperContext.refinedBoundedContext.name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ ContextMappingModel:
(map = ContextMap)? &
(boundedContexts += BoundedContext)* &
(domains += Domain)* &
(userRequirements += UserRequirement)*
(userRequirements += UserRequirement)*
)
;

Expand All @@ -47,8 +47,8 @@ ContextMap:

BoundedContext:
(comment=ML_COMMENT | comment=SL_COMMENT)?
'BoundedContext' name=ID (('implements' (implementedDomainParts+=[DomainPart]) ("," implementedDomainParts+=[DomainPart])*)? &
('realizes' (realizedBoundedContexts+=[BoundedContext]) ("," realizedBoundedContexts+=[BoundedContext])*)? &
'BoundedContext' name=ID (('implements' (implementedDomainParts+=[DomainPart]) ("," implementedDomainParts+=[DomainPart])*)? &
('realizes' (realizedBoundedContexts+=[BoundedContext]) ("," realizedBoundedContexts+=[BoundedContext])*)? &
('refines' refinedBoundedContext=[BoundedContext])?
)
(
Expand All @@ -58,6 +58,8 @@ BoundedContext:
(('responsibilities' ('=')? responsibilities+=STRING) ("," responsibilities+=STRING)*)? &
('implementationTechnology' ('=')? implementationTechnology=STRING)? &
('knowledgeLevel' ('=')? knowledgeLevel=KnowledgeLevel)?)
('businessModel' ('=')? businessModel=STRING)? &
('evolution' ('=')? evolution=Evolution)? &
((application = Application)? &
(modules += SculptorModule)* &
(aggregates += Aggregate)*)
Expand Down Expand Up @@ -101,13 +103,13 @@ SymmetricRelationship:

Partnership:
(
(participant1 = [BoundedContext] '[''P'']' '<->' '[''P'']' participant2 = [BoundedContext]) |
('[''P'']' participant1 = [BoundedContext] '<->' '[''P'']' participant2 = [BoundedContext]) |
(participant1 = [BoundedContext] '[''P'']' '<->' '[''P'']' participant2 = [BoundedContext]) |
('[''P'']' participant1 = [BoundedContext] '<->' '[''P'']' participant2 = [BoundedContext]) |
(participant1 = [BoundedContext] '[''P'']' '<->' participant2 = [BoundedContext] '[''P'']') |
('[''P'']' participant1 = [BoundedContext] '<->' participant2 = [BoundedContext] '[''P'']') |
(participant1 = [BoundedContext] 'Partnership' participant2 = [BoundedContext])
)
(':' name=ID)?
(':' name=ID)?
(OPEN
('implementationTechnology' ('=')? implementationTechnology=STRING)?
CLOSE)?
Expand All @@ -122,17 +124,17 @@ SharedKernel:
(participant1 = [BoundedContext] 'Shared-Kernel' participant2 = [BoundedContext]) |
(participant1 = [BoundedContext] '<->' participant2 = [BoundedContext])
)
(':' name=ID)?
(':' name=ID)?
(OPEN
('implementationTechnology' ('=')? implementationTechnology=STRING)?
CLOSE)?
;

UpstreamDownstreamRelationship:
CustomerSupplierRelationship |
CustomerSupplierRelationship |
(
(
(upstream = [BoundedContext] (('[''U'']') | ('['('U'',')?(upstreamRoles+=UpstreamRole) ("," upstreamRoles+=UpstreamRole)*)']')? '->' (('[''D'']') | ('['('D'',')?(downstreamRoles+=DownstreamRole) ("," downstreamRoles+=DownstreamRole)*)']')? downstream = [BoundedContext]) |
(upstream = [BoundedContext] (('[''U'']') | ('['('U'',')?(upstreamRoles+=UpstreamRole) ("," upstreamRoles+=UpstreamRole)*)']')? '->' (('[''D'']') | ('['('D'',')?(downstreamRoles+=DownstreamRole) ("," downstreamRoles+=DownstreamRole)*)']')? downstream = [BoundedContext]) |
(downstream = [BoundedContext] (('[''D'']') | ('['('D'',')?(downstreamRoles+=DownstreamRole) ("," downstreamRoles+=DownstreamRole)*)']')? '<-' (('[''U'']') | ('['('U'',')?(upstreamRoles+=UpstreamRole) ("," upstreamRoles+=UpstreamRole)*)']')? upstream = [BoundedContext]) |
(upstream = [BoundedContext] ('['((upstreamRoles+=UpstreamRole) ("," upstreamRoles+=UpstreamRole)*)?']')?'Upstream-Downstream'('['((downstreamRoles+=DownstreamRole) ("," downstreamRoles+=DownstreamRole)*)?']')? downstream = [BoundedContext]) |
(downstream = [BoundedContext] ('['((downstreamRoles+=DownstreamRole) ("," downstreamRoles+=DownstreamRole)*)?']')?'Downstream-Upstream'('['((upstreamRoles+=UpstreamRole) ("," upstreamRoles+=UpstreamRole)*)?']')? upstream = [BoundedContext])
Expand Down Expand Up @@ -176,9 +178,9 @@ Aggregate :
(('userStories' ('=')? userRequirements += [UserStory]) ("," userRequirements += [UserStory])*) |
((('features' | 'userRequirements') ('=')? userRequirements += [UserRequirement]) ("," userRequirements += [UserRequirement])*)
)? &
('owner' ('=')? owner=[BoundedContext])? &
('owner' ('=')? owner=[BoundedContext])? &
('knowledgeLevel' ('=')? knowledgeLevel=KnowledgeLevel)? &
(('likelihoodForChange' | 'structuralVolatility') ('=')? likelihoodForChange=Volatility)? &
(('likelihoodForChange' | 'structuralVolatility') ('=')? likelihoodForChange=Volatility)? &
('contentVolatility' ('=')? contentVolatility=Volatility)? &
('availabilityCriticality' ('=')? availabilityCriticality=Criticality)? &
('consistencyCriticality' ('=')? consistencyCriticality=Criticality)? &
Expand All @@ -191,20 +193,23 @@ Aggregate :
(resources+=Resource) |
(consumers+=Consumer) |
(domainObjects+=SimpleDomainObject))*
CLOSE)?;
CLOSE)?
;

Application:
"Application" (name=ID)? (OPEN
((commands+=CommandEvent)* &
(events+=DomainEvent)* &
(services+=Service)* &
(flows+=Flow)*)
CLOSE)?;
CLOSE)?
;

Flow:
"Flow" name=ID (OPEN
"Flow" name=ID (OPEN
(steps+=FlowStep)*
CLOSE)?;
CLOSE)?
;

FlowStep:
DomainEventProductionStep | CommandInvokationStep
Expand Down Expand Up @@ -291,7 +296,7 @@ UserRequirement:
;

UseCase:
'UseCase' name=ID
'UseCase' name=ID
(OPEN
(('actor' ('=')? role=STRING)? &
('interactions' ('=')? features+=Feature ("," features+=Feature)*)? &
Expand Down Expand Up @@ -335,7 +340,8 @@ SculptorModule :
(consumers+=Consumer) |
(domainObjects+=SimpleDomainObject) |
(aggregates+=Aggregate))*
CLOSE)?;
CLOSE)?
;

enum UpstreamRole:
PUBLISHED_LANGUAGE = 'PL' | OPEN_HOST_SERVICE = 'OHS'
Expand Down Expand Up @@ -369,18 +375,22 @@ enum KnowledgeLevel :
META="META" | CONCRETE="CONCRETE"
;

enum Volatility :
enum Volatility :
UNDEFINED | NORMAL | RARELY | OFTEN
;

enum Criticality :
enum Criticality :
UNDEFINED | NORMAL | HIGH | LOW
;

enum Similarity :
enum Similarity :
UNDEFINED | NORMAL | HUGE | TINY
;

enum Evolution :
UNDEFINED | GENESIS | CUSTOM_BUILT | PRODUCT | COMMODITY
;

// define terminals
terminal OPEN: '{';
terminal CLOSE: '}';

0 comments on commit 0b248f2

Please sign in to comment.