33import blue .language .Blue ;
44import blue .language .model .Node ;
55import blue .language .provider .BasicNodeProvider ;
6+ import java .util .*;
67import org .junit .jupiter .api .Test ;
78
89import static blue .language .utils .UncheckedObjectMapper .YAML_MAPPER ;
10+ import static blue .language .utils .Properties .DICTIONARY_TYPE_BLUE_ID ;
911import static org .junit .jupiter .api .Assertions .assertFalse ;
1012import 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