Skip to content

Commit d6fcb1d

Browse files
committed
Add missing test and rephrase errors
1 parent 840e8cf commit d6fcb1d

File tree

2 files changed

+71
-5
lines changed

2 files changed

+71
-5
lines changed

modules/protocol-tests/test/src/smithy4s/api/validation/AdtTraitValidatorSpec.scala

+58-3
Original file line numberDiff line numberDiff line change
@@ -167,14 +167,69 @@ object AdtTraitValidatorSpec extends FunSuite {
167167
.shape(struct)
168168
.severity(Severity.ERROR)
169169
.message(
170-
"This shape can only be referenced from one adt union, but it's referenced from test#MyUnion, test#MyUnionTwo"
170+
"This shape can only be referenced once and from one adt union, but it's referenced from test#MyUnion, test#MyUnionTwo"
171171
)
172172
.build()
173173
)
174174
expect(result == expected)
175175
}
176176

177-
// todo: test what happens if the shape is targeted by the same union twice (shouldn't be done)
177+
test(
178+
"AdtTrait - return error when structure is targeted by the same union twice"
179+
) {
180+
val unionShapeId = ShapeId.fromParts("test", "MyUnion")
181+
val adtTrait = new AdtTrait()
182+
val structMember = MemberShape
183+
.builder()
184+
.id("test#struct$testing")
185+
.target("smithy.api#String")
186+
.build()
187+
val struct =
188+
StructureShape
189+
.builder()
190+
.id("test#struct")
191+
.addMember(structMember)
192+
.build()
193+
194+
val unionMember = MemberShape
195+
.builder()
196+
.id(unionShapeId.withMember("unionMember"))
197+
.target(struct.getId)
198+
.build()
199+
200+
val unionMember2 = MemberShape
201+
.builder()
202+
.id(unionShapeId.withMember("unionMember2"))
203+
.target(struct.getId)
204+
.build()
205+
206+
val union =
207+
UnionShape
208+
.builder()
209+
.addTrait(adtTrait)
210+
.id(unionShapeId)
211+
.addMember(unionMember)
212+
.addMember(unionMember2)
213+
.build()
214+
215+
val model =
216+
Model.builder().addShapes(struct, union).build()
217+
218+
val result = validator.validate(model).asScala.toList
219+
220+
val expected = List(
221+
ValidationEvent
222+
.builder()
223+
.id("AdtTrait")
224+
.shape(struct)
225+
.severity(Severity.ERROR)
226+
.message(
227+
"This shape can only be referenced once and from one adt union, but it's referenced from test#MyUnion (2 times)"
228+
)
229+
.build()
230+
)
231+
expect(result == expected)
232+
}
178233

179234
test(
180235
"AdtTrait - return error when structure is targeted by a union and a structure"
@@ -228,7 +283,7 @@ object AdtTraitValidatorSpec extends FunSuite {
228283
.shape(struct)
229284
.severity(Severity.ERROR)
230285
.message(
231-
"This shape can only be referenced from one adt union, but it's referenced from test#MyStruct2, test#MyUnion"
286+
"This shape can only be referenced once and from one adt union, but it's referenced from test#MyStruct2, test#MyUnion"
232287
)
233288
.build()
234289
)

modules/protocol/src/smithy4s/meta/validation/AdtTraitValidator.java

+13-2
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,19 @@ public List<ValidationEvent> validate(Model model) {
6969
.entrySet().stream()
7070
.filter(entry -> entry.getValue().size() > 1)
7171
.map(targetWithDuplicateParents -> {
72-
String targets = targetWithDuplicateParents.getValue().stream().map(ref -> ref.from.getId().toString()).sorted().collect(Collectors.joining(", "));
73-
return error(targetWithDuplicateParents.getKey(), "This shape can only be referenced from one adt union, but it's referenced from " + targets);
72+
// String targets = targetWithDuplicateParents.getValue().stream().map(ref -> ref.from.getId().toString()).sorted().collect(Collectors.joining(", "));
73+
// for each unique "from" in parents, print the # of its occurrences
74+
String targets =
75+
targetWithDuplicateParents.getValue().stream()
76+
.collect(Collectors.groupingBy(ref -> ref.from))
77+
.entrySet().stream()
78+
.map(entry -> {
79+
String countSuffix = entry.getValue().size() == 1 ? "" : String.format(" (%d times)", entry.getValue().size());
80+
return entry.getKey().getId().toString() + countSuffix;
81+
})
82+
.sorted()
83+
.collect(Collectors.joining(", "));
84+
return error(targetWithDuplicateParents.getKey(), "This shape can only be referenced once and from one adt union, but it's referenced from " + targets);
7485
}).collect(Collectors.toList());
7586

7687
return Stream.concat(nonStructTargets, dupes.stream()).collect(Collectors.toList());

0 commit comments

Comments
 (0)