Skip to content

Commit 9019199

Browse files
committed
test(catalog): add unit tests for builder pure helper functions
Cover getMicroflowObjectType, getMicroflowActionType, getDataTypeName, countMicroflowActivities, calculateMcCabeComplexity, countNanoflowActivities, calculateNanoflowComplexity, extractLayoutRef, extractPageWidgets, extractWidgetsRecursive, extractSnippetWidgets, getBsonArrayElements, toBsonArray, extractString, extractBsonID, decodeBase64GUID, extractBinaryID, formatGUID, bytesToHex, entityAccessFromMemberRights, countWorkflowActivityTypes, countMenuItems, extractAttrName.
1 parent e765498 commit 9019199

6 files changed

Lines changed: 1135 additions & 0 deletions
Lines changed: 318 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,318 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
package catalog
4+
5+
import (
6+
"testing"
7+
8+
"github.com/mendixlabs/mxcli/sdk/microflows"
9+
)
10+
11+
func TestGetMicroflowObjectType(t *testing.T) {
12+
tests := []struct {
13+
name string
14+
obj microflows.MicroflowObject
15+
want string
16+
}{
17+
{"ActionActivity", &microflows.ActionActivity{}, "ActionActivity"},
18+
{"StartEvent", &microflows.StartEvent{}, "StartEvent"},
19+
{"EndEvent", &microflows.EndEvent{}, "EndEvent"},
20+
{"ExclusiveSplit", &microflows.ExclusiveSplit{}, "ExclusiveSplit"},
21+
{"InheritanceSplit", &microflows.InheritanceSplit{}, "InheritanceSplit"},
22+
{"ExclusiveMerge", &microflows.ExclusiveMerge{}, "ExclusiveMerge"},
23+
{"LoopedActivity", &microflows.LoopedActivity{}, "LoopedActivity"},
24+
{"Annotation", &microflows.Annotation{}, "Annotation"},
25+
{"BreakEvent", &microflows.BreakEvent{}, "BreakEvent"},
26+
{"ContinueEvent", &microflows.ContinueEvent{}, "ContinueEvent"},
27+
{"ErrorEvent", &microflows.ErrorEvent{}, "ErrorEvent"},
28+
}
29+
30+
for _, tt := range tests {
31+
t.Run(tt.name, func(t *testing.T) {
32+
if got := getMicroflowObjectType(tt.obj); got != tt.want {
33+
t.Errorf("getMicroflowObjectType() = %q, want %q", got, tt.want)
34+
}
35+
})
36+
}
37+
}
38+
39+
func TestGetMicroflowActionType(t *testing.T) {
40+
tests := []struct {
41+
name string
42+
action microflows.MicroflowAction
43+
want string
44+
}{
45+
{"CreateObjectAction", &microflows.CreateObjectAction{}, "CreateObjectAction"},
46+
{"ChangeObjectAction", &microflows.ChangeObjectAction{}, "ChangeObjectAction"},
47+
{"RetrieveAction", &microflows.RetrieveAction{}, "RetrieveAction"},
48+
{"MicroflowCallAction", &microflows.MicroflowCallAction{}, "MicroflowCallAction"},
49+
{"JavaActionCallAction", &microflows.JavaActionCallAction{}, "JavaActionCallAction"},
50+
{"ShowMessageAction", &microflows.ShowMessageAction{}, "ShowMessageAction"},
51+
{"LogMessageAction", &microflows.LogMessageAction{}, "LogMessageAction"},
52+
{"ValidationFeedbackAction", &microflows.ValidationFeedbackAction{}, "ValidationFeedbackAction"},
53+
{"ChangeVariableAction", &microflows.ChangeVariableAction{}, "ChangeVariableAction"},
54+
{"CreateVariableAction", &microflows.CreateVariableAction{}, "CreateVariableAction"},
55+
{"AggregateListAction", &microflows.AggregateListAction{}, "AggregateListAction"},
56+
{"ListOperationAction", &microflows.ListOperationAction{}, "ListOperationAction"},
57+
{"CastAction", &microflows.CastAction{}, "CastAction"},
58+
{"DownloadFileAction", &microflows.DownloadFileAction{}, "DownloadFileAction"},
59+
{"ClosePageAction", &microflows.ClosePageAction{}, "ClosePageAction"},
60+
{"ShowPageAction", &microflows.ShowPageAction{}, "ShowPageAction"},
61+
{"CallExternalAction", &microflows.CallExternalAction{}, "CallExternalAction"},
62+
{"unknown action falls to default", &microflows.UnknownAction{TypeName: "CustomThing"}, "MicroflowAction"},
63+
}
64+
65+
for _, tt := range tests {
66+
t.Run(tt.name, func(t *testing.T) {
67+
if got := getMicroflowActionType(tt.action); got != tt.want {
68+
t.Errorf("getMicroflowActionType() = %q, want %q", got, tt.want)
69+
}
70+
})
71+
}
72+
}
73+
74+
func TestGetDataTypeName(t *testing.T) {
75+
tests := []struct {
76+
name string
77+
dt microflows.DataType
78+
want string
79+
}{
80+
{"nil", nil, ""},
81+
{"Boolean", &microflows.BooleanType{}, "Boolean"},
82+
{"Integer", &microflows.IntegerType{}, "Integer"},
83+
{"Long", &microflows.LongType{}, "Long"},
84+
{"Decimal", &microflows.DecimalType{}, "Decimal"},
85+
{"String", &microflows.StringType{}, "String"},
86+
{"DateTime", &microflows.DateTimeType{}, "DateTime"},
87+
{"Date", &microflows.DateType{}, "Date"},
88+
{"Void", &microflows.VoidType{}, "Void"},
89+
{"Object with entity", &microflows.ObjectType{EntityQualifiedName: "Module.Entity"}, "Object:Module.Entity"},
90+
{"List with entity", &microflows.ListType{EntityQualifiedName: "Module.Entity"}, "List:Module.Entity"},
91+
{"Enumeration", &microflows.EnumerationType{EnumerationQualifiedName: "Module.Color"}, "Enumeration:Module.Color"},
92+
{"Binary falls to Unknown", &microflows.BinaryType{}, "Unknown"},
93+
}
94+
95+
for _, tt := range tests {
96+
t.Run(tt.name, func(t *testing.T) {
97+
if got := getDataTypeName(tt.dt); got != tt.want {
98+
t.Errorf("getDataTypeName() = %q, want %q", got, tt.want)
99+
}
100+
})
101+
}
102+
}
103+
104+
func TestCountMicroflowActivities(t *testing.T) {
105+
tests := []struct {
106+
name string
107+
mf *microflows.Microflow
108+
want int
109+
}{
110+
{
111+
name: "nil object collection",
112+
mf: &microflows.Microflow{},
113+
want: 0,
114+
},
115+
{
116+
name: "empty objects",
117+
mf: &microflows.Microflow{
118+
ObjectCollection: &microflows.MicroflowObjectCollection{},
119+
},
120+
want: 0,
121+
},
122+
{
123+
name: "excludes start/end/merge",
124+
mf: &microflows.Microflow{
125+
ObjectCollection: &microflows.MicroflowObjectCollection{
126+
Objects: []microflows.MicroflowObject{
127+
&microflows.StartEvent{},
128+
&microflows.ActionActivity{},
129+
&microflows.ExclusiveSplit{},
130+
&microflows.EndEvent{},
131+
&microflows.ExclusiveMerge{},
132+
},
133+
},
134+
},
135+
want: 2, // ActionActivity + ExclusiveSplit
136+
},
137+
{
138+
name: "counts loops and annotations",
139+
mf: &microflows.Microflow{
140+
ObjectCollection: &microflows.MicroflowObjectCollection{
141+
Objects: []microflows.MicroflowObject{
142+
&microflows.LoopedActivity{},
143+
&microflows.Annotation{},
144+
&microflows.ErrorEvent{},
145+
},
146+
},
147+
},
148+
want: 3,
149+
},
150+
}
151+
152+
for _, tt := range tests {
153+
t.Run(tt.name, func(t *testing.T) {
154+
if got := countMicroflowActivities(tt.mf); got != tt.want {
155+
t.Errorf("countMicroflowActivities() = %d, want %d", got, tt.want)
156+
}
157+
})
158+
}
159+
}
160+
161+
func TestCalculateMcCabeComplexity(t *testing.T) {
162+
tests := []struct {
163+
name string
164+
mf *microflows.Microflow
165+
want int
166+
}{
167+
{
168+
name: "nil object collection — base complexity",
169+
mf: &microflows.Microflow{},
170+
want: 1,
171+
},
172+
{
173+
name: "no decision points",
174+
mf: &microflows.Microflow{
175+
ObjectCollection: &microflows.MicroflowObjectCollection{
176+
Objects: []microflows.MicroflowObject{
177+
&microflows.StartEvent{},
178+
&microflows.ActionActivity{},
179+
&microflows.EndEvent{},
180+
},
181+
},
182+
},
183+
want: 1,
184+
},
185+
{
186+
name: "exclusive split adds 1",
187+
mf: &microflows.Microflow{
188+
ObjectCollection: &microflows.MicroflowObjectCollection{
189+
Objects: []microflows.MicroflowObject{
190+
&microflows.ExclusiveSplit{},
191+
},
192+
},
193+
},
194+
want: 2,
195+
},
196+
{
197+
name: "inheritance split adds 1",
198+
mf: &microflows.Microflow{
199+
ObjectCollection: &microflows.MicroflowObjectCollection{
200+
Objects: []microflows.MicroflowObject{
201+
&microflows.InheritanceSplit{},
202+
},
203+
},
204+
},
205+
want: 2,
206+
},
207+
{
208+
name: "loop adds 1 plus nested decisions",
209+
mf: &microflows.Microflow{
210+
ObjectCollection: &microflows.MicroflowObjectCollection{
211+
Objects: []microflows.MicroflowObject{
212+
&microflows.LoopedActivity{
213+
ObjectCollection: &microflows.MicroflowObjectCollection{
214+
Objects: []microflows.MicroflowObject{
215+
&microflows.ExclusiveSplit{},
216+
},
217+
},
218+
},
219+
},
220+
},
221+
},
222+
want: 3, // 1 base + 1 loop + 1 nested split
223+
},
224+
{
225+
name: "error event adds 1",
226+
mf: &microflows.Microflow{
227+
ObjectCollection: &microflows.MicroflowObjectCollection{
228+
Objects: []microflows.MicroflowObject{
229+
&microflows.ErrorEvent{},
230+
},
231+
},
232+
},
233+
want: 2,
234+
},
235+
{
236+
name: "complex flow",
237+
mf: &microflows.Microflow{
238+
ObjectCollection: &microflows.MicroflowObjectCollection{
239+
Objects: []microflows.MicroflowObject{
240+
&microflows.ExclusiveSplit{},
241+
&microflows.ExclusiveSplit{},
242+
&microflows.InheritanceSplit{},
243+
&microflows.LoopedActivity{},
244+
&microflows.ErrorEvent{},
245+
},
246+
},
247+
},
248+
want: 6, // 1 + 2 splits + 1 inheritance + 1 loop + 1 error
249+
},
250+
}
251+
252+
for _, tt := range tests {
253+
t.Run(tt.name, func(t *testing.T) {
254+
if got := calculateMcCabeComplexity(tt.mf); got != tt.want {
255+
t.Errorf("calculateMcCabeComplexity() = %d, want %d", got, tt.want)
256+
}
257+
})
258+
}
259+
}
260+
261+
func TestCountNanoflowActivities(t *testing.T) {
262+
tests := []struct {
263+
name string
264+
nf *microflows.Nanoflow
265+
want int
266+
}{
267+
{
268+
name: "nil object collection",
269+
nf: &microflows.Nanoflow{},
270+
want: 0,
271+
},
272+
{
273+
name: "excludes structural elements",
274+
nf: &microflows.Nanoflow{
275+
ObjectCollection: &microflows.MicroflowObjectCollection{
276+
Objects: []microflows.MicroflowObject{
277+
&microflows.StartEvent{},
278+
&microflows.ActionActivity{},
279+
&microflows.EndEvent{},
280+
&microflows.ExclusiveMerge{},
281+
},
282+
},
283+
},
284+
want: 1, // only ActionActivity
285+
},
286+
}
287+
288+
for _, tt := range tests {
289+
t.Run(tt.name, func(t *testing.T) {
290+
if got := countNanoflowActivities(tt.nf); got != tt.want {
291+
t.Errorf("countNanoflowActivities() = %d, want %d", got, tt.want)
292+
}
293+
})
294+
}
295+
}
296+
297+
func TestCalculateNanoflowComplexity(t *testing.T) {
298+
nf := &microflows.Nanoflow{
299+
ObjectCollection: &microflows.MicroflowObjectCollection{
300+
Objects: []microflows.MicroflowObject{
301+
&microflows.ExclusiveSplit{},
302+
&microflows.LoopedActivity{
303+
ObjectCollection: &microflows.MicroflowObjectCollection{
304+
Objects: []microflows.MicroflowObject{
305+
&microflows.InheritanceSplit{},
306+
},
307+
},
308+
},
309+
},
310+
},
311+
}
312+
313+
got := calculateNanoflowComplexity(nf)
314+
want := 4 // 1 base + 1 split + 1 loop + 1 nested inheritance
315+
if got != want {
316+
t.Errorf("calculateNanoflowComplexity() = %d, want %d", got, want)
317+
}
318+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
package catalog
4+
5+
import "testing"
6+
7+
func TestExtractAttrName(t *testing.T) {
8+
tests := []struct {
9+
name string
10+
input string
11+
want string
12+
}{
13+
{"three parts", "Module.Entity.Attribute", "Attribute"},
14+
{"four parts", "Module.Entity.Attribute.Sub", "Sub"},
15+
{"two parts", "Module.Entity", ""},
16+
{"single part", "Single", ""},
17+
{"empty string", "", ""},
18+
}
19+
20+
for _, tt := range tests {
21+
t.Run(tt.name, func(t *testing.T) {
22+
if got := extractAttrName(tt.input); got != tt.want {
23+
t.Errorf("extractAttrName(%q) = %q, want %q", tt.input, got, tt.want)
24+
}
25+
})
26+
}
27+
}

0 commit comments

Comments
 (0)