@@ -59,6 +59,68 @@ func TestValidateMicroflowBodyRejectsDuplicateCallOutputs(t *testing.T) {
5959 }
6060}
6161
62+ func TestValidateMicroflowBodyAllowsDuplicateOutputsInExclusiveBranches (t * testing.T ) {
63+ entityRef := ast.QualifiedName {Module : "Synthetic" , Name : "Item" }
64+ stmt := & ast.CreateMicroflowStmt {
65+ Body : []ast.MicroflowStatement {
66+ & ast.IfStmt {
67+ Condition : & ast.VariableExpr {Name : "UsePrimaryPath" },
68+ ThenBody : []ast.MicroflowStatement {
69+ & ast.CreateObjectStmt {Variable : "Result" , EntityType : entityRef },
70+ & ast.ReturnStmt {},
71+ },
72+ ElseBody : []ast.MicroflowStatement {
73+ & ast.RetrieveStmt {Variable : "Result" , Source : entityRef , Limit : "1" },
74+ & ast.ReturnStmt {},
75+ },
76+ },
77+ },
78+ }
79+
80+ errs := ValidateMicroflowBody (stmt )
81+ for _ , err := range errs {
82+ if strings .Contains (err , "duplicate variable name '$Result'" ) {
83+ t .Fatalf ("exclusive branches must not share duplicate-output scope: %#v" , errs )
84+ }
85+ }
86+ }
87+
88+ func TestValidateMicroflowBodyAllowsDuplicateOutputsInEnumCases (t * testing.T ) {
89+ entityRef := ast.QualifiedName {Module : "Synthetic" , Name : "Item" }
90+ stmt := & ast.CreateMicroflowStmt {
91+ Body : []ast.MicroflowStatement {
92+ & ast.EnumSplitStmt {
93+ Variable : "Route" ,
94+ Cases : []ast.EnumSplitCase {
95+ {
96+ Value : "First" ,
97+ Body : []ast.MicroflowStatement {
98+ & ast.CallJavaActionStmt {OutputVariable : "GeneratedID" , ActionName : ast.QualifiedName {Module : "Synthetic" , Name : "Generate" }},
99+ & ast.CreateObjectStmt {Variable : "Result" , EntityType : entityRef },
100+ & ast.ReturnStmt {},
101+ },
102+ },
103+ {
104+ Value : "Second" ,
105+ Body : []ast.MicroflowStatement {
106+ & ast.CallJavaActionStmt {OutputVariable : "GeneratedID" , ActionName : ast.QualifiedName {Module : "Synthetic" , Name : "Generate" }},
107+ & ast.CreateObjectStmt {Variable : "Result" , EntityType : entityRef },
108+ & ast.ReturnStmt {},
109+ },
110+ },
111+ },
112+ },
113+ },
114+ }
115+
116+ errs := strings .Join (ValidateMicroflowBody (stmt ), "\n " )
117+ for _ , name := range []string {"GeneratedID" , "Result" } {
118+ if strings .Contains (errs , "duplicate variable name '$" + name + "'" ) {
119+ t .Fatalf ("enum cases must not share duplicate-output scope: %s" , errs )
120+ }
121+ }
122+ }
123+
62124func TestFormatMicroflowActivitiesWarnsAboutDuplicateModelOutputs (t * testing.T ) {
63125 oc := & microflows.MicroflowObjectCollection {
64126 Objects : []microflows.MicroflowObject {
@@ -109,3 +171,71 @@ func TestFormatMicroflowActivitiesWarnsAboutDuplicateModelOutputs(t *testing.T)
109171 t .Fatalf ("describe output must not invent aliases:\n %s" , got )
110172 }
111173}
174+
175+ func TestFormatMicroflowActivitiesDoesNotWarnForExclusiveBranchOutputs (t * testing.T ) {
176+ oc := & microflows.MicroflowObjectCollection {
177+ Objects : []microflows.MicroflowObject {
178+ & microflows.StartEvent {
179+ BaseMicroflowObject : microflows.BaseMicroflowObject {
180+ BaseElement : model.BaseElement {ID : "start" },
181+ Position : model.Point {X : 0 , Y : 100 },
182+ },
183+ },
184+ & microflows.ExclusiveSplit {
185+ BaseMicroflowObject : microflows.BaseMicroflowObject {
186+ BaseElement : model.BaseElement {ID : "split" },
187+ Position : model.Point {X : 100 , Y : 100 },
188+ },
189+ SplitCondition : & microflows.ExpressionSplitCondition {Expression : "$UsePrimaryPath" },
190+ },
191+ & microflows.ActionActivity {
192+ BaseActivity : microflows.BaseActivity {
193+ BaseMicroflowObject : microflows.BaseMicroflowObject {
194+ BaseElement : model.BaseElement {ID : "then_create" },
195+ Position : model.Point {X : 200 , Y : 100 },
196+ },
197+ },
198+ Action : & microflows.CreateObjectAction {OutputVariable : "Result" , EntityQualifiedName : "Synthetic.Item" },
199+ },
200+ & microflows.ActionActivity {
201+ BaseActivity : microflows.BaseActivity {
202+ BaseMicroflowObject : microflows.BaseMicroflowObject {
203+ BaseElement : model.BaseElement {ID : "else_retrieve" },
204+ Position : model.Point {X : 200 , Y : 200 },
205+ },
206+ },
207+ Action : & microflows.RetrieveAction {
208+ OutputVariable : "Result" ,
209+ Source : & microflows.DatabaseRetrieveSource {
210+ EntityQualifiedName : "Synthetic.Item" ,
211+ },
212+ },
213+ },
214+ & microflows.EndEvent {
215+ BaseMicroflowObject : microflows.BaseMicroflowObject {
216+ BaseElement : model.BaseElement {ID : "then_end" },
217+ Position : model.Point {X : 300 , Y : 100 },
218+ },
219+ },
220+ & microflows.EndEvent {
221+ BaseMicroflowObject : microflows.BaseMicroflowObject {
222+ BaseElement : model.BaseElement {ID : "else_end" },
223+ Position : model.Point {X : 300 , Y : 200 },
224+ },
225+ },
226+ },
227+ Flows : []* microflows.SequenceFlow {
228+ {OriginID : "start" , DestinationID : "split" },
229+ {OriginID : "split" , DestinationID : "then_create" , CaseValue : & microflows.ExpressionCase {Expression : "true" }},
230+ {OriginID : "split" , DestinationID : "else_retrieve" , CaseValue : & microflows.ExpressionCase {Expression : "false" }},
231+ {OriginID : "then_create" , DestinationID : "then_end" },
232+ {OriginID : "else_retrieve" , DestinationID : "else_end" },
233+ },
234+ }
235+ lines := formatMicroflowActivities (& ExecContext {}, & microflows.Microflow {ObjectCollection : oc }, nil , nil )
236+ got := strings .Join (lines , "\n " )
237+
238+ if strings .Contains (got , "-- WARNING: duplicate output variable $Result" ) {
239+ t .Fatalf ("exclusive branch outputs must not be warned as linear duplicates:\n %s" , got )
240+ }
241+ }
0 commit comments