Skip to content

Commit f2c677b

Browse files
Add YamlSetterConflictTest
1 parent c1cc5e7 commit f2c677b

File tree

6 files changed

+376
-2
lines changed

6 files changed

+376
-2
lines changed

annot/src/main/java/com/predic8/membrane/annot/yaml/BeanCacheObserver.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
/* Copyright 2025 predic8 GmbH, www.predic8.com
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License. */
14+
115
package com.predic8.membrane.annot.yaml;
216

317
import java.io.IOException;

annot/src/main/java/com/predic8/membrane/annot/yaml/YamlLoader.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
/* Copyright 2025 predic8 GmbH, www.predic8.com
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License. */
14+
115
package com.predic8.membrane.annot.yaml;
216

317
import org.jetbrains.annotations.NotNull;

annot/src/test/java/com/predic8/membrane/annot/YAMLParsingTest.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
/* Copyright 2025 predic8 GmbH, www.predic8.com
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License. */
14+
115
package com.predic8.membrane.annot;
216

317
import com.predic8.membrane.annot.util.CompilerHelper;
@@ -94,8 +108,7 @@ public class Child1Element {
94108
assertStructure(
95109
parseYAML(result, """
96110
demo:
97-
child:
98-
child1: {}
111+
child1: {}
99112
"""),
100113
clazz("DemoElement",
101114
property("child", clazz("Child1Element")))
Lines changed: 305 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,305 @@
1+
package com.predic8.membrane.annot;
2+
3+
import com.predic8.membrane.annot.util.CompilerHelper;
4+
import org.junit.jupiter.api.Test;
5+
6+
import static com.predic8.membrane.annot.SpringConfigurationXSDGeneratingAnnotationProcessorTest.MC_MAIN_DEMO;
7+
import static com.predic8.membrane.annot.util.CompilerHelper.*;
8+
import static java.util.List.of;
9+
import static org.junit.jupiter.api.Assertions.assertTrue;
10+
11+
public class YamlSetterConflictTest {
12+
13+
@Test
14+
public void sameConcreteChildOnTwoSetters() {
15+
var sources = splitSources(MC_MAIN_DEMO + """
16+
package com.predic8.membrane.demo;
17+
import com.predic8.membrane.annot.*;
18+
import java.util.List;
19+
20+
@MCElement(name="demo")
21+
public class DemoElement {
22+
@MCChildElement(order = 1)
23+
public void setB(List<B> s) {}
24+
25+
@MCChildElement(order = 2)
26+
public void setE(List<B> s) {}
27+
}
28+
---
29+
package com.predic8.membrane.demo;
30+
import com.predic8.membrane.annot.*;
31+
32+
@MCElement(name="b", topLevel = false, id = "b")
33+
public class B {
34+
}
35+
""");
36+
var result = CompilerHelper.compile(sources, false);
37+
38+
// assertCompilerResult(true, of(error("...")), result); TODO
39+
assertTrue(result.compilationSuccess());
40+
}
41+
42+
@Test
43+
public void sameChildNameFromDifferentAbstractHierarchies() {
44+
var sources = splitSources(MC_MAIN_DEMO + """
45+
package com.predic8.membrane.demo;
46+
import com.predic8.membrane.annot.*;
47+
import java.util.List;
48+
49+
@MCElement(name="a")
50+
public class A {
51+
@MCChildElement(order = 1)
52+
public void setB(List<AbstractC> s) {}
53+
54+
@MCChildElement(order = 2)
55+
public void setE(List<AbstractF> s) {}
56+
}
57+
---
58+
package com.predic8.membrane.demo;
59+
60+
public abstract class AbstractC {
61+
}
62+
---
63+
package com.predic8.membrane.demo;
64+
65+
public abstract class AbstractF {
66+
}
67+
---
68+
package com.predic8.membrane.demo.a;
69+
import com.predic8.membrane.annot.*;
70+
import com.predic8.membrane.demo.AbstractC;
71+
72+
@MCElement(name="d", topLevel = false, id = "d1")
73+
public class D extends AbstractC {
74+
}
75+
---
76+
package com.predic8.membrane.demo.b;
77+
import com.predic8.membrane.annot.*;
78+
import com.predic8.membrane.demo.AbstractF;
79+
80+
@MCElement(name="d", topLevel = false, id = "d2")
81+
public class D extends AbstractF {
82+
}
83+
""");
84+
var result = CompilerHelper.compile(sources, false);
85+
86+
// assertCompilerResult(false, of(error("...")), result); TODO
87+
assertTrue(result.compilationSuccess());
88+
}
89+
90+
@Test
91+
public void sameChildNameViaBaseAndConcreteSetter() {
92+
var sources = splitSources(MC_MAIN_DEMO + """
93+
package com.predic8.membrane.demo;
94+
import com.predic8.membrane.annot.*;
95+
import java.util.List;
96+
97+
@MCElement(name="demo")
98+
public class DemoElement {
99+
@MCChildElement(order = 1)
100+
public void setAbstract(List<AbstractChild> s) {}
101+
102+
@MCChildElement(order = 2)
103+
public void setConcrete(List<ConcreteChild> s) {}
104+
}
105+
---
106+
package com.predic8.membrane.demo;
107+
108+
public abstract class AbstractChild {
109+
}
110+
---
111+
package com.predic8.membrane.demo;
112+
import com.predic8.membrane.annot.*;
113+
114+
@MCElement(name="child", topLevel = false, id = "child")
115+
public class ConcreteChild extends AbstractChild {
116+
}
117+
""");
118+
var result = CompilerHelper.compile(sources, false);
119+
120+
// assertCompilerResult(false, of(error("Duplicate childElement 'child': child")), result); TODO
121+
assertTrue(result.compilationSuccess());
122+
}
123+
124+
@Test
125+
public void childNameNotUniqueAcrossPackages() {
126+
var sources = splitSources(MC_MAIN_DEMO + """
127+
package com.predic8.membrane.demo;
128+
import com.predic8.membrane.annot.*;
129+
130+
@MCElement(name="demo")
131+
public class DemoElement {
132+
@MCChildElement
133+
public void setChild(AbstractChildElement s) {}
134+
}
135+
---
136+
package com.predic8.membrane.demo;
137+
138+
public abstract class AbstractChildElement {
139+
}
140+
---
141+
package com.predic8.membrane.demo.a;
142+
import com.predic8.membrane.annot.*;
143+
import com.predic8.membrane.demo.AbstractChildElement;
144+
145+
@MCElement(name="child", topLevel = false, id = "child1")
146+
public class ChildA extends AbstractChildElement {
147+
}
148+
---
149+
package com.predic8.membrane.demo.b;
150+
import com.predic8.membrane.annot.*;
151+
import com.predic8.membrane.demo.AbstractChildElement;
152+
153+
@MCElement(name="child", topLevel = false, id = "child2")
154+
public class ChildB extends AbstractChildElement {
155+
}
156+
""");
157+
var result = CompilerHelper.compile(sources, false);
158+
159+
assertCompilerResult(false, of(error("Duplicate childElement 'child': child")), result);
160+
}
161+
162+
@Test
163+
public void sameConcreteChildOnTwoSetters_noList() {
164+
var sources = splitSources(MC_MAIN_DEMO + """
165+
package com.predic8.membrane.demo;
166+
import com.predic8.membrane.annot.*;
167+
168+
@MCElement(name="demo")
169+
public class DemoElement {
170+
@MCChildElement(order = 1)
171+
public void setB(B b) {}
172+
173+
@MCChildElement(order = 2)
174+
public void setE(B b) {}
175+
}
176+
---
177+
package com.predic8.membrane.demo;
178+
import com.predic8.membrane.annot.*;
179+
180+
@MCElement(name="b", topLevel = false, id = "b")
181+
public class B {
182+
}
183+
""");
184+
var result = CompilerHelper.compile(sources, false);
185+
186+
assertCompilerResult(false, of(error("Name clash: 'b' used by childElement 'b' & childElement 'e'")), result);
187+
}
188+
189+
@Test
190+
public void sameChildNameFromDifferentAbstractHierarchies_noList() {
191+
var sources = splitSources(MC_MAIN_DEMO + """
192+
package com.predic8.membrane.demo;
193+
import com.predic8.membrane.annot.*;
194+
195+
@MCElement(name="a")
196+
public class A {
197+
@MCChildElement(order = 1)
198+
public void setB(AbstractC c) {}
199+
200+
@MCChildElement(order = 2)
201+
public void setE(AbstractF f) {}
202+
}
203+
---
204+
package com.predic8.membrane.demo;
205+
206+
public abstract class AbstractC {
207+
}
208+
---
209+
package com.predic8.membrane.demo;
210+
211+
public abstract class AbstractF {
212+
}
213+
---
214+
package com.predic8.membrane.demo.a;
215+
import com.predic8.membrane.annot.*;
216+
import com.predic8.membrane.demo.AbstractC;
217+
218+
@MCElement(name="d", topLevel = false, id = "d1")
219+
public class DFromC extends AbstractC {
220+
}
221+
---
222+
package com.predic8.membrane.demo.b;
223+
import com.predic8.membrane.annot.*;
224+
import com.predic8.membrane.demo.AbstractF;
225+
226+
@MCElement(name="d", topLevel = false, id = "d2")
227+
public class DFromF extends AbstractF {
228+
}
229+
""");
230+
var result = CompilerHelper.compile(sources, false);
231+
232+
assertCompilerResult(false, of(error("Name clash: 'd' used by childElement 'b' & childElement 'e'")), result);
233+
}
234+
235+
@Test
236+
public void sameChildNameViaBaseAndConcreteSetter_noList() {
237+
var sources = splitSources(MC_MAIN_DEMO + """
238+
package com.predic8.membrane.demo;
239+
import com.predic8.membrane.annot.*;
240+
241+
@MCElement(name="demo")
242+
public class DemoElement {
243+
@MCChildElement(order = 1)
244+
public void setAbstract(AbstractChild c) {}
245+
246+
@MCChildElement(order = 2)
247+
public void setConcrete(ConcreteChild c) {}
248+
}
249+
---
250+
package com.predic8.membrane.demo;
251+
252+
public abstract class AbstractChild {
253+
}
254+
---
255+
package com.predic8.membrane.demo;
256+
import com.predic8.membrane.annot.*;
257+
258+
@MCElement(name="child", topLevel = false, id = "child")
259+
public class ConcreteChild extends AbstractChild {
260+
}
261+
""");
262+
var result = CompilerHelper.compile(sources, false);
263+
264+
assertCompilerResult(false, of(error("Name clash: 'child' used by childElement 'abstract' & childElement 'concrete'")), result);
265+
}
266+
267+
@Test
268+
public void childNameNotUniqueAcrossPackages_noList() {
269+
var sources = splitSources(MC_MAIN_DEMO + """
270+
package com.predic8.membrane.demo;
271+
import com.predic8.membrane.annot.*;
272+
273+
@MCElement(name="demo")
274+
public class DemoElement {
275+
@MCChildElement
276+
public void setChild(AbstractChildElement c) {}
277+
}
278+
---
279+
package com.predic8.membrane.demo;
280+
281+
public abstract class AbstractChildElement {
282+
}
283+
---
284+
package com.predic8.membrane.demo.a;
285+
import com.predic8.membrane.annot.*;
286+
import com.predic8.membrane.demo.AbstractChildElement;
287+
288+
@MCElement(name="child", topLevel = false, id = "child1")
289+
public class ChildA extends AbstractChildElement {
290+
}
291+
---
292+
package com.predic8.membrane.demo.b;
293+
import com.predic8.membrane.annot.*;
294+
import com.predic8.membrane.demo.AbstractChildElement;
295+
296+
@MCElement(name="child", topLevel = false, id = "child2")
297+
public class ChildB extends AbstractChildElement {
298+
}
299+
""");
300+
var result = CompilerHelper.compile(sources, false);
301+
302+
assertCompilerResult(false, of(error("Duplicate childElement 'child': child")), result);
303+
}
304+
305+
}

annot/src/test/java/com/predic8/membrane/annot/util/StructureAssertionUtil.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
/* Copyright 2025 predic8 GmbH, www.predic8.com
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License. */
14+
115
package com.predic8.membrane.annot.util;
216

317
import com.predic8.membrane.annot.yaml.BeanRegistry;

0 commit comments

Comments
 (0)