Skip to content

Commit 1abdc5a

Browse files
authored
Merge pull request #256 from retran/test/catalog-builder-coverage
test(catalog): add unit tests for builder pure helper functions
2 parents e765498 + 5bd8d68 commit 1abdc5a

6 files changed

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