Skip to content

Commit a07e7e0

Browse files
authored
Merge pull request #317 from hjotha/submit/writer-microflow-endevent-no-trailing-newline
fix(writer): drop synthetic trailing newline from EndEvent ReturnValue
2 parents 475e4f1 + d572e50 commit a07e7e0

3 files changed

Lines changed: 80 additions & 7 deletions

File tree

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
-- ============================================================================
2+
-- Bug #316: Synthetic trailing newline appended to EndEvent ReturnValue
3+
-- ============================================================================
4+
--
5+
-- Symptom (before fix):
6+
-- The microflow writer appended `"\n"` to every non-empty `ReturnValue`
7+
-- when serializing EndEvent objects. Pristine Studio Pro MPRs do not
8+
-- store that trailing newline, so any roundtrip through mxcli left a
9+
-- detectable BSON drift versus the original .mpr — visible in `mx check`
10+
-- diffs and in `mxcli diff-local` output even when no semantic change
11+
-- had been authored.
12+
--
13+
-- After fix:
14+
-- `writer_microflow.go` passes `ReturnValue` through directly. Empty
15+
-- return values stay empty; non-empty ones are written without an
16+
-- extra trailing newline.
17+
--
18+
-- Usage:
19+
-- mxcli exec mdl-examples/bug-tests/316-endevent-no-trailing-newline.mdl -p app.mpr
20+
-- mxcli -p app.mpr -c "describe microflow BugTest316.MF_ReturnExpr"
21+
-- The describe output must round-trip cleanly under describe → exec → describe
22+
-- and (when applied to a pristine Studio Pro project) `mx check` must
23+
-- not report any cosmetic diff in the EndEvent ReturnValue field.
24+
-- ============================================================================
25+
26+
create module BugTest316;
27+
28+
-- Microflow with a non-empty return value: the EndEvent's ReturnValue must
29+
-- not pick up a synthetic trailing newline on serialization.
30+
create microflow BugTest316.MF_ReturnExpr (
31+
$value: integer
32+
)
33+
returns boolean as $isPositive
34+
begin
35+
return $value > 0;
36+
end;
37+
/
38+
39+
-- Microflow with no return value (procedure): EndEvent ReturnValue stays empty.
40+
create microflow BugTest316.MF_NoReturn ()
41+
begin
42+
log info node 'BugTest316' 'side effect only';
43+
end;
44+
/

sdk/mpr/writer_microflow.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -466,13 +466,10 @@ func serializeMicroflowObject(obj microflows.MicroflowObject) bson.D {
466466
}
467467

468468
case *microflows.EndEvent:
469-
// Pristine EndEvents always carry `ReturnValue` (empty string for void
470-
// microflows; expression + "\n" when a value is returned). Omitting it
471-
// diverges from the pristine key set on Mx 9 roundtrips.
472-
returnValue := ""
473-
if o.ReturnValue != "" {
474-
returnValue = o.ReturnValue + "\n"
475-
}
469+
// Pristine Mx 9 EndEvents carry `ReturnValue` but not a synthetic trailing
470+
// line break. Adding one can make Studio Pro reject list-return EndEvents
471+
// with CE0117 even though mxcli's parser accepts the expression.
472+
returnValue := o.ReturnValue
476473
doc := bson.D{
477474
{Key: "$ID", Value: idToBsonBinary(string(o.ID))},
478475
{Key: "$Type", Value: "Microflows$EndEvent"},

sdk/mpr/writer_microflow_version_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,38 @@ func TestSerializeSequenceFlow_Mx10_UsesModernShape(t *testing.T) {
7979
}
8080
}
8181

82+
func TestSerializeEndEvent_EmptyReturnValueHasNoTrailingLineBreak(t *testing.T) {
83+
end := &microflows.EndEvent{
84+
BaseMicroflowObject: microflows.BaseMicroflowObject{
85+
BaseElement: model.BaseElement{ID: "end-empty"},
86+
Position: model.Point{X: 10, Y: 20},
87+
Size: model.Size{Width: 20, Height: 20},
88+
},
89+
ReturnValue: "empty",
90+
}
91+
92+
doc := serializeMicroflowObject(end)
93+
if got := bsonGetKey(doc, "ReturnValue"); got != "empty" {
94+
t.Fatalf("ReturnValue = %q, want %q", got, "empty")
95+
}
96+
}
97+
98+
func TestSerializeEndEvent_NonEmptyReturnValueHasNoSyntheticLineBreak(t *testing.T) {
99+
end := &microflows.EndEvent{
100+
BaseMicroflowObject: microflows.BaseMicroflowObject{
101+
BaseElement: model.BaseElement{ID: "end-result"},
102+
Position: model.Point{X: 10, Y: 20},
103+
Size: model.Size{Width: 20, Height: 20},
104+
},
105+
ReturnValue: "$Result",
106+
}
107+
108+
doc := serializeMicroflowObject(end)
109+
if got := bsonGetKey(doc, "ReturnValue"); got != "$Result" {
110+
t.Fatalf("ReturnValue = %q, want %q", got, "$Result")
111+
}
112+
}
113+
82114
func TestSerializeAnnotationFlow_VersionShapes(t *testing.T) {
83115
af := &microflows.AnnotationFlow{
84116
BaseElement: model.BaseElement{ID: "af-1"},

0 commit comments

Comments
 (0)