Skip to content

Commit b4e0e18

Browse files
authored
Merge pull request #340 from hjotha/submit/builder-empty-change-refresh-in-client
fix: refresh empty change-object actions
2 parents d996121 + 8d5cc94 commit b4e0e18

3 files changed

Lines changed: 61 additions & 4 deletions

File tree

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
-- ============================================================================
2+
-- Bug #339: Empty change-object actions must refresh in client
3+
-- ============================================================================
4+
--
5+
-- Symptom (before fix):
6+
-- Rebuilding an empty change-object activity from MDL wrote a non-committing
7+
-- ChangeObjectAction with no member changes and RefreshInClient=false.
8+
-- Studio Pro / mx check rejected that activity with CE0032:
9+
-- "Change action has no items specified and does not commit the object."
10+
--
11+
-- After fix:
12+
-- `change $Object;` is serialized as a refresh-only change action by setting
13+
-- RefreshInClient=true. Although the CE0032 text mentions only items/commit,
14+
-- empirical mx check validation accepts refresh as the third valid escape.
15+
--
16+
-- Usage:
17+
-- mxcli exec mdl-examples/bug-tests/339-empty-change-refresh-in-client.mdl -p app.mpr
18+
-- mx check app.mpr
19+
-- Expected: 0 new CE0032 errors for BugTest339.MF_RefreshOnlyChange.
20+
-- ============================================================================
21+
22+
create module BugTest339;
23+
24+
create entity BugTest339.Item (
25+
Name: String(100)
26+
);
27+
28+
create microflow BugTest339.MF_RefreshOnlyChange ()
29+
begin
30+
$Item = create BugTest339.Item;
31+
change $Item;
32+
end;
33+
/

mdl/executor/bugfix_regression_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,27 @@ func TestCallMicroflowResultType_ResolvesSubsequentChangeMember(t *testing.T) {
675675
}
676676
}
677677

678+
func TestEmptyChangeObjectRefreshesInClient(t *testing.T) {
679+
fb := &flowBuilder{posX: 100, posY: 100, spacing: HorizontalSpacing}
680+
681+
id := fb.addChangeObjectAction(&ast.ChangeObjectStmt{Variable: "Object"})
682+
if id == "" || len(fb.objects) != 1 {
683+
t.Fatalf("expected one change object activity, got id=%q objects=%d", id, len(fb.objects))
684+
}
685+
686+
activity, ok := fb.objects[0].(*microflows.ActionActivity)
687+
if !ok {
688+
t.Fatalf("object type = %T, want *microflows.ActionActivity", fb.objects[0])
689+
}
690+
action, ok := activity.Action.(*microflows.ChangeObjectAction)
691+
if !ok {
692+
t.Fatalf("action type = %T, want *microflows.ChangeObjectAction", activity.Action)
693+
}
694+
if !action.RefreshInClient {
695+
t.Fatal("empty change object must refresh in client to remain valid without member changes or commit")
696+
}
697+
}
698+
678699
func TestCallMicroflowUnknownResultTypeStillDeclaresVariable(t *testing.T) {
679700
fb := &flowBuilder{
680701
varTypes: map[string]string{"Result": "Old.ModuleEntity"},

mdl/executor/cmd_microflows_builder_actions.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -240,10 +240,13 @@ func (fb *flowBuilder) addRollbackAction(s *ast.RollbackStmt) model.ID {
240240
// addChangeObjectAction creates a CHANGE statement.
241241
func (fb *flowBuilder) addChangeObjectAction(s *ast.ChangeObjectStmt) model.ID {
242242
action := &microflows.ChangeObjectAction{
243-
BaseElement: model.BaseElement{ID: model.ID(types.GenerateID())},
244-
ChangeVariable: s.Variable,
245-
Commit: microflows.CommitTypeNo,
246-
RefreshInClient: false,
243+
BaseElement: model.BaseElement{ID: model.ID(types.GenerateID())},
244+
ChangeVariable: s.Variable,
245+
Commit: microflows.CommitTypeNo,
246+
// Studio Pro rejects an empty non-committing change action unless it
247+
// refreshes in client. The CE0032 message mentions only items/commit,
248+
// but mx check accepts RefreshInClient=true as the third valid escape.
249+
RefreshInClient: len(s.Changes) == 0,
247250
}
248251

249252
// Look up entity type from variable scope

0 commit comments

Comments
 (0)