Skip to content

Commit b3fcedc

Browse files
committed
Add comprehensive tests for NodeTypeMatcher functionality
- Introduced multiple test cases to validate node type matching, including basic type value shapes, nested shapes, and list item type enforcement. - Enhanced coverage for implicit vs explicit list handling and dictionary value type enforcement. - Ensured that the tests accurately reflect the expected behavior of the Blue framework's type matching logic.
1 parent 74332fa commit b3fcedc

File tree

1 file changed

+283
-1
lines changed

1 file changed

+283
-1
lines changed

src/test/java/blue/language/utils/NodeTypeMatcherTest.java

Lines changed: 283 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
import blue.language.Blue;
44
import blue.language.model.Node;
55
import blue.language.provider.BasicNodeProvider;
6+
import java.util.*;
67
import org.junit.jupiter.api.Test;
78

89
import static blue.language.utils.UncheckedObjectMapper.YAML_MAPPER;
10+
import static blue.language.utils.Properties.DICTIONARY_TYPE_BLUE_ID;
911
import static org.junit.jupiter.api.Assertions.assertFalse;
1012
import static org.junit.jupiter.api.Assertions.assertTrue;
1113

@@ -83,4 +85,284 @@ public void testBasic() throws Exception {
8385

8486
}
8587

86-
}
88+
@Test
89+
public void testBasicTypeValueShapeNoConstraints() throws Exception {
90+
91+
BasicNodeProvider nodeProvider = new BasicNodeProvider();
92+
93+
String a = "name: A\n" +
94+
"value: AAA";
95+
96+
nodeProvider.addSingleDocs(a);
97+
98+
String b = "name: B\n" +
99+
"x:\n" +
100+
" type:\n" +
101+
" blueId: " + nodeProvider.getBlueIdByName("A");
102+
103+
nodeProvider.addSingleDocs(b);
104+
105+
String c = "name: C";
106+
nodeProvider.addSingleDocs(c);
107+
108+
String bId = nodeProvider.getBlueIdByName("B");
109+
String cId = nodeProvider.getBlueIdByName("C");
110+
111+
String bInst = "name: B Instance\n" +
112+
"type:\n" +
113+
" blueId: " + bId + "\n" +
114+
"x: AAA";
115+
nodeProvider.addSingleDocs(bInst);
116+
117+
String typeOK1 = "x:\n" +
118+
" type:\n" +
119+
" blueId: " + nodeProvider.getBlueIdByName("A");
120+
121+
String typeOK2 = "x: AAA";
122+
123+
String typeFailWrongType = "x:\n" +
124+
" type:\n" +
125+
" name: C";
126+
127+
String typeFailWrongBlue = "type:\n" +
128+
" blueId: " + cId + "\n" +
129+
"x: AAA";
130+
131+
String typeFailExtraProp = "type:\n" +
132+
" blueId: " + bId + "\n" +
133+
"x: AAA\n" +
134+
"y: d";
135+
136+
Blue blue = new Blue(nodeProvider);
137+
Node bInstNode = nodeProvider.getNodeByName("B Instance");
138+
139+
assertTrue(blue.nodeMatchesType(bInstNode, blue.yamlToNode(typeOK1)));
140+
assertTrue(blue.nodeMatchesType(bInstNode, blue.yamlToNode(typeOK2)));
141+
assertFalse(blue.nodeMatchesType(bInstNode, blue.yamlToNode(typeFailWrongType)));
142+
assertFalse(blue.nodeMatchesType(bInstNode, blue.yamlToNode(typeFailWrongBlue)));
143+
assertFalse(blue.nodeMatchesType(bInstNode, blue.yamlToNode(typeFailExtraProp)));
144+
}
145+
146+
@Test
147+
public void testNestedShapesListsAndProperties() throws Exception {
148+
BasicNodeProvider nodeProvider = new BasicNodeProvider();
149+
150+
String item = "name: Item\n" +
151+
"value: 1";
152+
153+
nodeProvider.addSingleDocs(item);
154+
String itemId = nodeProvider.getBlueIdByName("Item");
155+
156+
String item2 = "name: Item2\n" +
157+
"value: 2";
158+
nodeProvider.addSingleDocs(item2);
159+
String item2Id = nodeProvider.getBlueIdByName("Item2");
160+
161+
String listOwnerDoc = "name: ListOwner\n" +
162+
"items:\n" +
163+
" - blueId: " + itemId;
164+
nodeProvider.addSingleDocs(listOwnerDoc);
165+
166+
String container = "name: Container\n" +
167+
"list:\n" +
168+
" blueId: " + nodeProvider.getBlueIdByName("ListOwner");
169+
nodeProvider.addSingleDocs(container);
170+
171+
Blue blue = new Blue(nodeProvider);
172+
173+
Node containerInst = nodeProvider.getNodeByName("Container");
174+
175+
String okNestedShape = "list:\n" +
176+
" items:\n" +
177+
" - blueId: " + itemId;
178+
assertTrue(blue.nodeMatchesType(containerInst, blue.yamlToNode(okNestedShape)));
179+
180+
String failNestedValue = "list:\n" +
181+
" items:\n" +
182+
" - blueId: " + item2Id;
183+
assertFalse(blue.nodeMatchesType(containerInst, blue.yamlToNode(failNestedValue)));
184+
185+
String failExtra = "list:\n" +
186+
" items:\n" +
187+
" - value: 1\n" +
188+
" extra: something";
189+
assertFalse(blue.nodeMatchesType(containerInst, blue.yamlToNode(failExtra)));
190+
}
191+
192+
@Test
193+
public void testBlueIdExactMatchesWhenRequested() throws Exception {
194+
BasicNodeProvider nodeProvider = new BasicNodeProvider();
195+
196+
String alpha = "name: Alpha";
197+
String beta = "name: Beta";
198+
nodeProvider.addSingleDocs(alpha, beta);
199+
200+
String alphaId = nodeProvider.getBlueIdByName("Alpha");
201+
String betaId = nodeProvider.getBlueIdByName("Beta");
202+
203+
String container = "name: Holder\n" +
204+
"x:\n" +
205+
" blueId: " + alphaId;
206+
nodeProvider.addSingleDocs(container);
207+
208+
Blue blue = new Blue(nodeProvider);
209+
Node node = nodeProvider.getNodeByName("Holder");
210+
211+
String ok = "x:\n" +
212+
" blueId: " + alphaId;
213+
assertTrue(blue.nodeMatchesType(node, blue.yamlToNode(ok)));
214+
215+
String fail = "x:\n" +
216+
" blueId: " + betaId;
217+
assertFalse(blue.nodeMatchesType(node, blue.yamlToNode(fail)));
218+
}
219+
220+
@Test
221+
public void testListItemTypeEnforcesItemShape() throws Exception {
222+
BasicNodeProvider nodeProvider = new BasicNodeProvider();
223+
224+
String allowedItem = "name: Allowed Item\n" +
225+
"value: ok";
226+
String forbiddenItem = "name: Forbidden Item\n" +
227+
"value: not-ok";
228+
nodeProvider.addSingleDocs(allowedItem, forbiddenItem);
229+
230+
String allowedItemId = nodeProvider.getBlueIdByName("Allowed Item");
231+
String forbiddenItemId = nodeProvider.getBlueIdByName("Forbidden Item");
232+
233+
String listWithAllowed = "name: Allowed Container\n" +
234+
"itemsList:\n" +
235+
" type: List\n" +
236+
" items:\n" +
237+
" - blueId: " + allowedItemId + "\n";
238+
239+
String listWithForbidden = "name: Forbidden Container\n" +
240+
"itemsList:\n" +
241+
" type: List\n" +
242+
" items:\n" +
243+
" - blueId: " + forbiddenItemId + "\n";
244+
245+
nodeProvider.addSingleDocs(listWithAllowed, listWithForbidden);
246+
247+
Blue blue = new Blue(nodeProvider);
248+
249+
String targetTypeYaml = "itemsList:\n" +
250+
" type: List\n" +
251+
" itemType:\n" +
252+
" blueId: " + allowedItemId;
253+
254+
Node targetType = blue.yamlToNode(targetTypeYaml);
255+
256+
assertTrue(blue.nodeMatchesType(nodeProvider.getNodeByName("Allowed Container"), targetType));
257+
assertFalse(blue.nodeMatchesType(nodeProvider.getNodeByName("Forbidden Container"), targetType));
258+
}
259+
260+
@Test
261+
public void testImplicitListDictionaryStructuralMatching() throws Exception {
262+
BasicNodeProvider nodeProvider = new BasicNodeProvider();
263+
264+
String implicitListDoc = "name: ImplicitListNode\n" +
265+
"items:\n" +
266+
" - value: 1\n" +
267+
" - value: 2";
268+
nodeProvider.addSingleDocs(implicitListDoc);
269+
270+
String implicitDictDoc = "name: ImplicitDictNode\n" +
271+
"a:\n" +
272+
" value: 1\n" +
273+
"b:\n" +
274+
" value: 2";
275+
nodeProvider.addSingleDocs(implicitDictDoc);
276+
277+
Blue blue = new Blue(nodeProvider);
278+
279+
Node implicitListNode = nodeProvider.getNodeByName("ImplicitListNode");
280+
Node implicitDictNode = nodeProvider.getNodeByName("ImplicitDictNode");
281+
282+
String listTypeOnly = "type: List";
283+
String dictTypeOnly = "type: Dictionary";
284+
285+
assertTrue(blue.nodeMatchesType(implicitListNode, blue.yamlToNode(listTypeOnly)));
286+
assertTrue(blue.nodeMatchesType(implicitDictNode, blue.yamlToNode(dictTypeOnly)));
287+
288+
assertFalse(blue.nodeMatchesType(implicitListNode, blue.yamlToNode(dictTypeOnly)));
289+
assertFalse(blue.nodeMatchesType(implicitDictNode, blue.yamlToNode(listTypeOnly)));
290+
291+
String explicitTextButHasItems = "type: Text\n" +
292+
"items:\n" +
293+
" - value: 1";
294+
assertFalse(blue.nodeMatchesType(implicitListNode, blue.yamlToNode(explicitTextButHasItems)));
295+
}
296+
297+
@Test
298+
public void testEventPayloadsYamlImplicitVsExplicitList() throws Exception {
299+
BasicNodeProvider nodeProvider = new BasicNodeProvider();
300+
Blue blue = new Blue(nodeProvider);
301+
302+
String targetTypeYaml = "message:\n" +
303+
" request:\n" +
304+
" type: List";
305+
Node targetType = blue.yamlToNode(targetTypeYaml);
306+
307+
String explicitListEventYaml = "message:\n" +
308+
" request:\n" +
309+
" type: List\n" +
310+
" items:\n" +
311+
" - 1\n" +
312+
" - 2\n" +
313+
" - 3";
314+
Node explicitEventNode = blue.yamlToNode(explicitListEventYaml);
315+
assertTrue(blue.nodeMatchesType(explicitEventNode, targetType));
316+
317+
String implicitArrayEventYaml = "message:\n" +
318+
" request:\n" +
319+
" - 1\n" +
320+
" - 2\n" +
321+
" - 3";
322+
Node implicitEventNode = blue.yamlToNode(implicitArrayEventYaml);
323+
assertTrue(blue.nodeMatchesType(implicitEventNode, targetType));
324+
325+
String wrongShapeEventYaml = "message:\n" +
326+
" request:\n" +
327+
" a: 1\n" +
328+
" b: 2";
329+
Node wrongEventNode = blue.yamlToNode(wrongShapeEventYaml);
330+
assertFalse(blue.nodeMatchesType(wrongEventNode, targetType));
331+
}
332+
333+
@Test
334+
public void testDictionaryValueTypeEnforcesPropertyTypes() throws Exception {
335+
BasicNodeProvider nodeProvider = new BasicNodeProvider();
336+
337+
String activationState = "name: Activation State\n" +
338+
"value: active";
339+
String wrongState = "name: Wrong State\n" +
340+
"value: wrong";
341+
nodeProvider.addSingleDocs(activationState, wrongState);
342+
343+
String activationStateId = nodeProvider.getBlueIdByName("Activation State");
344+
String wrongStateId = nodeProvider.getBlueIdByName("Wrong State");
345+
346+
Blue blue = new Blue(nodeProvider);
347+
348+
String targetTypeYaml = "participantsState:\n" +
349+
" type: Dictionary\n" +
350+
" valueType:\n" +
351+
" blueId: " + activationStateId;
352+
Node targetType = blue.yamlToNode(targetTypeYaml);
353+
354+
java.util.function.Function<String, Node> createNodeWithValueBlueId = (valueBlueId) ->
355+
new Node().name("Container").properties("participantsState",
356+
new Node().type(new Node().blueId(DICTIONARY_TYPE_BLUE_ID))
357+
.properties("alice",
358+
new Node().blueId(valueBlueId).type(new Node().blueId(valueBlueId))
359+
)
360+
);
361+
362+
Node matchingNode = createNodeWithValueBlueId.apply(activationStateId);
363+
assertTrue(blue.nodeMatchesType(matchingNode, targetType));
364+
365+
Node mismatchedNode = createNodeWithValueBlueId.apply(wrongStateId);
366+
assertFalse(blue.nodeMatchesType(mismatchedNode, targetType));
367+
}
368+
}

0 commit comments

Comments
 (0)