Skip to content

Commit 6351f79

Browse files
committed
test(core/protocols): document testing
1 parent f504fc1 commit 6351f79

File tree

6 files changed

+467
-24
lines changed

6 files changed

+467
-24
lines changed

packages/core/src/submodules/protocols/json/JsonShapeDeserializer.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { NormalizedSchema, SCHEMA } from "@smithy/core/schema";
1+
import { determineTimestampFormat } from "@smithy/core/protocols";
2+
import { NormalizedSchema, SCHEMA, TypeRegistry } from "@smithy/core/schema";
23
import {
34
LazyJsonString,
45
NumericValue,
@@ -84,13 +85,8 @@ export class JsonShapeDeserializer extends SerdeContextConfig implements ShapeDe
8485
}
8586
}
8687

87-
if (ns.isTimestampSchema()) {
88-
const options = this.settings.timestampFormat;
89-
const format = options.useTrait
90-
? ns.getSchema() === SCHEMA.TIMESTAMP_DEFAULT
91-
? options.default
92-
: ns.getSchema() ?? options.default
93-
: options.default;
88+
if (ns.isTimestampSchema() && value != null) {
89+
const format = determineTimestampFormat(ns, this.settings);
9490
switch (format) {
9591
case SCHEMA.TIMESTAMP_DATE_TIME:
9692
return parseRfc3339DateTimeWithOffset(value);
@@ -126,6 +122,10 @@ export class JsonShapeDeserializer extends SerdeContextConfig implements ShapeDe
126122
}
127123
}
128124

125+
if (ns.isDocumentSchema()) {
126+
return structuredClone(value);
127+
}
128+
129129
// covers string, numeric, boolean, document, bigDecimal
130130
return value;
131131
}

packages/core/src/submodules/protocols/json/JsonShapeSerializer.ts

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import { determineTimestampFormat } from "@smithy/core/protocols";
12
import { NormalizedSchema, SCHEMA } from "@smithy/core/schema";
23
import { dateToUtcString, generateIdempotencyToken, LazyJsonString } from "@smithy/core/serde";
34
import { Schema, ShapeSerializer } from "@smithy/types";
5+
import { toBase64 } from "@smithy/util-base64";
46

57
import { SerdeContextConfig } from "../ConfigurableSerdeContext";
68
import { JsonSettings } from "./JsonCodec";
@@ -22,11 +24,25 @@ export class JsonShapeSerializer extends SerdeContextConfig implements ShapeSeri
2224
this.buffer = this._write(this.rootSchema, value);
2325
}
2426

27+
/**
28+
* @internal
29+
*/
30+
public writeDiscriminatedDocument(schema: Schema, value: unknown): void {
31+
this.write(schema, value);
32+
if (typeof this.buffer === "object") {
33+
this.buffer.__type = NormalizedSchema.of(schema).getName(true);
34+
}
35+
}
36+
2537
public flush(): string {
26-
if (this.rootSchema?.isStructSchema() || this.rootSchema?.isDocumentSchema()) {
38+
const { rootSchema } = this;
39+
this.rootSchema = undefined;
40+
41+
if (rootSchema?.isStructSchema() || rootSchema?.isDocumentSchema()) {
2742
const replacer = new JsonReplacer();
2843
return replacer.replaceInJson(JSON.stringify(this.buffer, replacer.createReplacer(), 0));
2944
}
45+
// non-struct root schema indicates a blob (base64 string) or plain string payload.
3046
return this.buffer;
3147
}
3248

@@ -73,23 +89,21 @@ export class JsonShapeSerializer extends SerdeContextConfig implements ShapeSeri
7389
return void 0;
7490
}
7591

76-
if (ns.isBlobSchema() && (value instanceof Uint8Array || typeof value === "string")) {
92+
if (
93+
(ns.isBlobSchema() && (value instanceof Uint8Array || typeof value === "string")) ||
94+
(ns.isDocumentSchema() && value instanceof Uint8Array)
95+
) {
7796
if (ns === this.rootSchema) {
7897
return value;
7998
}
8099
if (!this.serdeContext?.base64Encoder) {
81-
throw new Error("Missing base64Encoder in serdeContext");
100+
return toBase64(value);
82101
}
83102
return this.serdeContext?.base64Encoder(value);
84103
}
85104

86-
if (ns.isTimestampSchema() && value instanceof Date) {
87-
const options = this.settings.timestampFormat;
88-
const format = options.useTrait
89-
? ns.getSchema() === SCHEMA.TIMESTAMP_DEFAULT
90-
? options.default
91-
: ns.getSchema() ?? options.default
92-
: options.default;
105+
if ((ns.isTimestampSchema() || ns.isDocumentSchema()) && value instanceof Date) {
106+
const format = determineTimestampFormat(ns, this.settings);
93107
switch (format) {
94108
case SCHEMA.TIMESTAMP_DATE_TIME:
95109
return value.toISOString().replace(".000Z", "Z");
@@ -124,6 +138,10 @@ export class JsonShapeSerializer extends SerdeContextConfig implements ShapeSeri
124138
}
125139
}
126140

141+
if (ns.isDocumentSchema() && isObject) {
142+
return structuredClone(value);
143+
}
144+
127145
return value;
128146
}
129147
}
Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
{
2+
"serdeTests": [
3+
{
4+
"name": "default test case",
5+
"subject": "smithy.example#OmniWidget",
6+
"serialized": {
7+
"string": "hello"
8+
},
9+
"deserialized": {
10+
"string": "hello"
11+
},
12+
"codec": "json",
13+
"settings": {
14+
"jsonName": false
15+
}
16+
},
17+
{
18+
"name": "jsonName",
19+
"subject": "smithy.example#OmniWidget",
20+
"serialized": {
21+
"String": "hello"
22+
},
23+
"deserialized": {
24+
"string": "hello"
25+
},
26+
"codec": "json",
27+
"settings": {
28+
"jsonName": true
29+
}
30+
},
31+
{
32+
"name": "timestampFormat, with default epoch-seconds",
33+
"subject": "smithy.example#OmniWidget",
34+
"serialized": {
35+
"timestamp": 0,
36+
"timestampDateTime": "1970-01-01T00:00:00Z",
37+
"timestampHttpDate": "Thu, 01 Jan 1970 00:00:00 GMT",
38+
"timestampEpochSeconds": 0
39+
},
40+
"deserialized": {
41+
"timestamp": "1970-01-01T00:00:00Z",
42+
"timestampDateTime": "1970-01-01T00:00:00Z",
43+
"timestampHttpDate": "1970-01-01T00:00:00Z",
44+
"timestampEpochSeconds": "1970-01-01T00:00:00Z"
45+
},
46+
"codec": "json",
47+
"settings": {
48+
"timestampFormat": {
49+
"useTrait": true,
50+
"default": "epoch-seconds"
51+
}
52+
}
53+
},
54+
{
55+
"name": "ignoring timestampFormat, with default epoch-seconds",
56+
"subject": "smithy.example#OmniWidget",
57+
"serialized": {
58+
"timestamp": 0,
59+
"timestampDateTime": 0,
60+
"timestampHttpDate": 0,
61+
"timestampEpochSeconds": 0
62+
},
63+
"deserialized": {
64+
"timestamp": "1970-01-01T00:00:00Z",
65+
"timestampDateTime": "1970-01-01T00:00:00Z",
66+
"timestampHttpDate": "1970-01-01T00:00:00Z",
67+
"timestampEpochSeconds": "1970-01-01T00:00:00Z"
68+
},
69+
"codec": "json",
70+
"settings": {
71+
"timestampFormat": {
72+
"useTrait": false,
73+
"default": "epoch-seconds"
74+
}
75+
}
76+
},
77+
{
78+
"name": "default settings with populated members with initial values",
79+
"subject": "smithy.example#OmniWidget",
80+
"serialized": {
81+
"blob": "YWJjZA==",
82+
"boolean": false,
83+
"String": "",
84+
"byte": 0,
85+
"short": 0,
86+
"integer": 0,
87+
"long": 0,
88+
"float": 0,
89+
"double": 0,
90+
"bigInteger": 0,
91+
"bigDecimal": 0.0,
92+
"timestamp": 0,
93+
"timestampDateTime": "1970-01-01T00:00:00Z",
94+
"timestampHttpDate": "Thu, 01 Jan 1970 00:00:00 GMT",
95+
"timestampEpochSeconds": 0,
96+
"document": {},
97+
"enum": "A",
98+
"intEnum": 0,
99+
"list": [],
100+
"map": {},
101+
"structure": {}
102+
},
103+
"deserialized": {
104+
"blob": "YWJjZA==",
105+
"boolean": false,
106+
"string": "",
107+
"byte": 0,
108+
"short": 0,
109+
"integer": 0,
110+
"long": 0,
111+
"float": 0,
112+
"double": 0,
113+
"bigInteger": 0,
114+
"bigDecimal": 0.0,
115+
"timestamp": 0,
116+
"timestampDateTime": "1970-01-01T00:00:00Z",
117+
"timestampHttpDate": "Thu, 01 Jan 1970 00:00:00 GMT",
118+
"timestampEpochSeconds": 0,
119+
"document": {},
120+
"enum": "A",
121+
"intEnum": 0,
122+
"list": [],
123+
"map": {},
124+
"structure": {}
125+
},
126+
"codec": "json",
127+
"settings": {
128+
"defaultNamespace": "smithy.example",
129+
"jsonName": true,
130+
"timestampFormat": {
131+
"useTrait": true,
132+
"default": "epoch-seconds"
133+
}
134+
}
135+
},
136+
{
137+
"name": "default settings with populated members with filled values",
138+
"subject": "smithy.example#OmniWidget",
139+
"serialized": {
140+
"blob": "YWJjZA==",
141+
"boolean": true,
142+
"String": "abcd",
143+
"byte": -128,
144+
"short": -32768,
145+
"integer": -2147483648,
146+
"long": -9007199254740991,
147+
"float": -0.1,
148+
"double": -0.01,
149+
"bigInteger": -9007199254740991,
150+
"bigDecimal": -9007199254740991.123456789,
151+
"timestamp": 17514144000,
152+
"timestampDateTime": "2525-01-01T00:00:00Z",
153+
"timestampHttpDate": "Mon, 01 Jan 2525 00:00:00 GMT",
154+
"timestampEpochSeconds": 17514144000,
155+
"document": {
156+
"__type": "smithy.example#OmniWidget",
157+
"timestamp": 17514144000,
158+
"timestampDateTime": "2525-01-01T00:00:00Z",
159+
"timestampHttpDate": "Mon, 01 Jan 2525 00:00:00 GMT",
160+
"timestampEpochSeconds": 17514144000,
161+
"document": true
162+
},
163+
"enum": "B",
164+
"intEnum": 1,
165+
"list": [
166+
{
167+
"byte": -128
168+
},
169+
{
170+
"short": -32768
171+
}
172+
],
173+
"map": {
174+
"a": {
175+
"integer": -2147483648
176+
},
177+
"b": {
178+
"long": -9007199254740991
179+
}
180+
},
181+
"structure": {
182+
"list": [
183+
{
184+
"double": -0.01
185+
},
186+
{
187+
"float": -0.1
188+
}
189+
],
190+
"map": {
191+
"a": {
192+
"bigInteger": -9007199254740991
193+
},
194+
"b": {
195+
"bigDecimal": -9007199254740991.123456789
196+
}
197+
}
198+
}
199+
},
200+
"deserialized": {
201+
"blob": "YWJjZA==",
202+
"boolean": true,
203+
"string": "abcd",
204+
"byte": -128,
205+
"short": -32768,
206+
"integer": -2147483648,
207+
"long": -9007199254740991,
208+
"float": -0.1,
209+
"double": -0.01,
210+
"bigInteger": -9007199254740991,
211+
"bigDecimal": -9007199254740991.123456789,
212+
"timestamp": "2525-01-01T00:00:00Z",
213+
"timestampDateTime": "2525-01-01T00:00:00Z",
214+
"timestampHttpDate": "2525-01-01T00:00:00Z",
215+
"timestampEpochSeconds": "2525-01-01T00:00:00Z",
216+
"document": {
217+
"__type": "smithy.example#OmniWidget",
218+
"timestamp": "2525-01-01T00:00:00Z",
219+
"timestampDateTime": "2525-01-01T00:00:00Z",
220+
"timestampHttpDate": "2525-01-01T00:00:00Z",
221+
"timestampEpochSeconds": "2525-01-01T00:00:00Z",
222+
"document": true
223+
},
224+
"enum": "B",
225+
"intEnum": 1,
226+
"list": [
227+
{
228+
"byte": -128
229+
},
230+
{
231+
"short": -32768
232+
}
233+
],
234+
"map": {
235+
"a": {
236+
"integer": -2147483648
237+
},
238+
"b": {
239+
"long": -9007199254740991
240+
}
241+
},
242+
"structure": {
243+
"list": [
244+
{
245+
"double": -0.01
246+
},
247+
{
248+
"float": -0.1
249+
}
250+
],
251+
"map": {
252+
"a": {
253+
"bigInteger": -9007199254740991
254+
},
255+
"b": {
256+
"bigDecimal": -9007199254740991.123456789
257+
}
258+
}
259+
}
260+
},
261+
"codec": "json",
262+
"settings": {
263+
"defaultNamespace": "smithy.example",
264+
"jsonName": true,
265+
"timestampFormat": {
266+
"useTrait": true,
267+
"default": "epoch-seconds"
268+
}
269+
}
270+
}
271+
]
272+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import fs from "node:fs";
2+
import path from "node:path";
3+
import { describe, test as it } from "vitest";
4+
5+
import { jsonReviver } from "../json/jsonReviver";
6+
7+
const json = fs.readFileSync(path.join(__dirname, "./new-document-type-test-cases.json"), "utf-8");
8+
9+
export const testCases = JSON.parse(json, jsonReviver);
10+
11+
describe("placeholder", () => {
12+
it("", () => {});
13+
});

0 commit comments

Comments
 (0)