Skip to content

Commit a95b6d9

Browse files
Add test for list and map of enums
1 parent cffb077 commit a95b6d9

File tree

5 files changed

+112
-22
lines changed

5 files changed

+112
-22
lines changed

smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/StructuredMemberWriter.java

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -313,32 +313,41 @@ private void writeShapeValidator(TypeScriptWriter writer, Shape shape, Collectio
313313
"@aws-smithy/server-common");
314314
MemberShape collectionMemberShape = ((CollectionShape) shape).getMember();
315315
Shape collectionMemberTargetShape = model.expectShape(collectionMemberShape.getTarget());
316-
writer.openBlock("new __CompositeCollectionValidator<$T>(", "),",
317-
symbolProvider.toSymbol(collectionMemberTargetShape),
318-
() -> {
319-
writeCompositeValidator(writer, shape, constraintTraits);
320-
writeShapeValidator(writer,
321-
collectionMemberTargetShape,
322-
getConstraintTraits(collectionMemberShape));
323-
});
316+
if (collectionMemberTargetShape.hasTrait(EnumTrait.class)) {
317+
// While there is a concrete type for enums, any string can be provided, and so we need
318+
// to allow for that. The underlying validator will handle ensuring the values are correct.
319+
writer.writeInline("new __CompositeCollectionValidator<string>");
320+
} else {
321+
writer.writeInline("new __CompositeCollectionValidator<$T>",
322+
symbolProvider.toSymbol(collectionMemberTargetShape));
323+
}
324+
writer.openBlock("(", "),", () -> {
325+
writeCompositeValidator(writer, shape, constraintTraits);
326+
writeShapeValidator(writer, collectionMemberTargetShape, getConstraintTraits(collectionMemberShape));
327+
});
324328
} else if (shape.isMapShape()) {
325329
writer.addImport("CompositeMapValidator",
326330
"__CompositeMapValidator",
327331
"@aws-smithy/server-common");
328332
MapShape mapShape = (MapShape) shape;
329333
final MemberShape keyShape = mapShape.getKey();
330334
final MemberShape valueShape = mapShape.getValue();
331-
writer.openBlock("new __CompositeMapValidator<$T>(", "),",
332-
symbolProvider.toSymbol(model.expectShape(valueShape.getTarget())),
333-
() -> {
334-
writeCompositeValidator(writer, mapShape, constraintTraits);
335-
writeShapeValidator(writer,
336-
model.expectShape(keyShape.getTarget()),
337-
getConstraintTraits(keyShape));
338-
writeShapeValidator(writer,
339-
model.expectShape(valueShape.getTarget()),
340-
getConstraintTraits(valueShape));
341-
});
335+
if (valueShape.hasTrait(EnumTrait.class)) {
336+
// While there is a concrete type for enums, any string can be provided, and so we need
337+
// to allow for that. The underlying validator will handle ensuring the values are correct.
338+
writer.writeInline("new __CompositeMapValidator<string>");
339+
} else {
340+
writer.writeInline("new __CompositeMapValidator<$T>", symbolProvider.toSymbol(valueShape));
341+
}
342+
writer.openBlock("(", "),", () -> {
343+
writeCompositeValidator(writer, mapShape, constraintTraits);
344+
writeShapeValidator(writer,
345+
model.expectShape(keyShape.getTarget()),
346+
getConstraintTraits(keyShape));
347+
writeShapeValidator(writer,
348+
model.expectShape(valueShape.getTarget()),
349+
getConstraintTraits(valueShape));
350+
});
342351
} else if (shape instanceof SimpleShape) {
343352
writeCompositeValidator(writer, shape, constraintTraits);
344353
} else {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/.gradle

smithy-typescript-integ-tests/codegen/build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,16 @@ buildscript {
2323
dependencies {
2424
classpath 'software.amazon.smithy:smithy-typescript-codegen:0.3.0'
2525
classpath 'software.amazon.smithy:smithy-aws-typescript-codegen:0.3.0'
26-
classpath "software.amazon.smithy:smithy-model:1.5.1"
26+
classpath "software.amazon.smithy:smithy-model:1.7.2"
2727
}
2828
}
2929

3030
plugins {
31-
id 'software.amazon.smithy' version '0.5.2'
31+
id 'software.amazon.smithy' version '0.5.3'
3232
}
3333

3434
dependencies {
35-
implementation "software.amazon.smithy:smithy-aws-traits:1.5.1"
35+
implementation "software.amazon.smithy:smithy-aws-traits:1.7.2"
3636
}
3737

3838
repositories {

smithy-typescript-integ-tests/codegen/model/validation.smithy

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ operation Test {
1616

1717
structure TestInput {
1818
enum: Enum,
19+
enumList: ListOfEnums,
20+
enumMap: MapOfEnums,
1921
lengthTests: LengthTests,
2022
nestedTests: NestedUnionOne
2123
}
@@ -60,6 +62,15 @@ union NestedUnionThree {
6062
@enum([{"value" : "valueA"}, {"value": "valueB"}])
6163
string Enum
6264

65+
list ListOfEnums {
66+
member: Enum
67+
}
68+
69+
map MapOfEnums {
70+
key: String,
71+
value: Enum,
72+
}
73+
6374
@length(min: 2, max: 7)
6475
string MinMaxLengthString
6576

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
import { TestInput, Enum } from "@aws-smithy/typescript-integ-test-types";
17+
18+
describe("enum constraints", () => {
19+
const validEnum: Enum = "valueA";
20+
const invalidEnum: string = "invalidEnum";
21+
const expectedFailureBase = {
22+
constraintType: "enum",
23+
constraintValues: ["valueA", "valueB"],
24+
failureValue: invalidEnum,
25+
};
26+
it("handles bare enums", () => {
27+
expect(TestInput.validate({ enum: validEnum })).toEqual([]);
28+
expect(TestInput.validate({ enum: invalidEnum })).toEqual([
29+
{
30+
memberName: "enum",
31+
...expectedFailureBase,
32+
},
33+
]);
34+
});
35+
it("handles enum lists", () => {
36+
expect(TestInput.validate({ enumList: [validEnum] })).toEqual([]);
37+
expect(TestInput.validate({ enumList: [invalidEnum] })).toEqual([
38+
{
39+
memberName: "enumList",
40+
...expectedFailureBase,
41+
},
42+
]);
43+
expect(TestInput.validate({ enumList: [validEnum, invalidEnum] })).toEqual([
44+
{
45+
memberName: "enumList",
46+
...expectedFailureBase,
47+
},
48+
]);
49+
});
50+
it("handles enum maps", () => {
51+
expect(TestInput.validate({ enumMap: { valid: validEnum } })).toEqual([]);
52+
expect(TestInput.validate({ enumMap: { invalid: invalidEnum } })).toEqual([
53+
{
54+
memberName: "enumMap",
55+
...expectedFailureBase,
56+
},
57+
]);
58+
expect(
59+
TestInput.validate({
60+
enumMap: { valid: validEnum, invalid: invalidEnum },
61+
})
62+
).toEqual([
63+
{
64+
memberName: "enumMap",
65+
...expectedFailureBase,
66+
},
67+
]);
68+
});
69+
});

0 commit comments

Comments
 (0)