Skip to content

Update protocol test request body comparison #268

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -278,53 +278,42 @@ private void writeRequestBodyAssertions(OperationShape operation, HttpRequestTes
writer.write("expect(r.body).toBeDefined();");

// Otherwise load a media type specific comparator and do a comparison.
String mediaType = testCase.getBodyMediaType().orElse(null);

// Fast check if we have an undescribed or plain text body.
if (mediaType == null || mediaType.equals("text/plain")) {
// Handle converting to the right comparison format for blob payloads.
HttpBindingIndex httpBindingIndex = HttpBindingIndex.of(model);
List<HttpBinding> payloadBindings = httpBindingIndex.getRequestBindings(operation, Location.PAYLOAD);
if (!payloadBindings.isEmpty() && hasBlobBinding(payloadBindings)) {
writer.write("expect(r.body).toMatchObject(Uint8Array.from($S, c => c.charCodeAt(0)));", body);
} else {
writer.write("expect(r.body).toBe($S);", body);
}
return;
}
registerBodyComparatorStub(mediaType);
String mediaType = testCase.getBodyMediaType().orElse("UNKNOWN");
String comparatorInvoke = registerBodyComparatorStub(mediaType);

// Handle escaping strings with quotes inside them.
writer.write("const bodyString = `$L`;", body.replace("\"", "\\\""));
writer.write("const unequalParts: any = compareEquivalentBodies(bodyString, r.body.toString());");
writer.write("const unequalParts: any = $L;", comparatorInvoke);
writer.write("expect(unequalParts).toBeUndefined();");
});
}

private boolean hasBlobBinding(List<HttpBinding> payloadBindings) {
// Can only have one payload binding at a time.
return model.expectShape(payloadBindings.get(0).getMember().getTarget()).isBlobShape();
}

private void registerBodyComparatorStub(String mediaType) {
private String registerBodyComparatorStub(String mediaType) {
// Load an additional stub to handle body comparisons for the
// set of bodyMediaType values we know of.
switch (mediaType) {
case "application/x-www-form-urlencoded":
additionalStubs.add("protocol-test-form-urlencoded-stub.ts");
break;
return "compareEquivalentFormUrlencodedBodies(bodyString, r.body.toString())";
case "application/json":
additionalStubs.add("protocol-test-json-stub.ts");
break;
return "compareEquivalentJsonBodies(bodyString, r.body.toString())";
case "application/xml":
writer.addDependency(TypeScriptDependency.XML_PARSER);
writer.addImport("parse", "xmlParse", "fast-xml-parser");
additionalStubs.add("protocol-test-xml-stub.ts");
break;
return "compareEquivalentXmlBodies(bodyString, r.body.toString())";
case "application/octet-stream":
additionalStubs.add("protocol-test-octet-stream-stub.ts");
return "compareEquivalentOctetStreamBodies(client.config, bodyString, r.body)";
case "text/plain":
additionalStubs.add("protocol-test-text-stub.ts");
return "compareEquivalentTextBodies(bodyString, r.body)";
default:
LOGGER.warning("Unable to compare bodies with unknown media type `" + mediaType
+ "`, defaulting to direct comparison.");
additionalStubs.add("protocol-test-unknown-type-stub.ts");
return "compareEquivalentUnknownTypeBodies(client.config, bodyString, r.body)";
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Returns a map of key names that were un-equal to value objects showing the
* discrepancies between the components.
*/
const compareEquivalentBodies = (expectedBody: string, generatedBody: string): Object => {
const compareEquivalentFormUrlencodedBodies = (expectedBody: string, generatedBody: string): Object => {
const fromEntries = (components: string[][]): { [key: string]: string } => {
const parts: { [key: string]: string } = {};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Returns a map of key names that were un-equal to value objects showing the
* discrepancies between the components.
*/
const compareEquivalentBodies = (expectedBody: string, generatedBody: string): Object => {
const compareEquivalentJsonBodies = (expectedBody: string, generatedBody: string): Object => {
const expectedParts = JSON.parse(expectedBody);
const generatedParts = JSON.parse(generatedBody);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Returns a map of key names that were un-equal to value objects showing the
* discrepancies between the components.
*/
const compareEquivalentOctetStreamBodies = (
config: any,
expectedBody: string,
generatedBody: Uint8Array
): Object => {
const expectedParts = {Value: expectedBody};
const generatedParts = {Value: config.utf8Encoder(generatedBody)};

return compareParts(expectedParts, generatedParts);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Returns a map of key names that were un-equal to value objects showing the
* discrepancies between the components.
*/
const compareEquivalentTextBodies = (expectedBody: string, generatedBody: string): Object => {
const expectedParts = {Value: expectedBody};
const generatedParts = {Value: generatedBody};

return compareParts(expectedParts, generatedParts);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@
* Returns a map of key names that were un-equal to value objects showing the
* discrepancies between the components.
*/
const compareEquivalentBodies = (expectedBody: string, generatedBody: string): Object => {
const compareEquivalentUnknownTypeBodies = (
config: any,
expectedBody: string,
generatedBody: string | Uint8Array
): Object => {
const expectedParts = {Value: expectedBody};
const generatedParts = {Value: generatedBody};
const generatedParts = {
Value: generatedBody instanceof Uint8Array ? config.utf8Encoder(generatedBody) : generatedBody
};

return compareParts(expectedParts, generatedParts);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Returns a map of key names that were un-equal to value objects showing the
* discrepancies between the components.
*/
const compareEquivalentBodies = (expectedBody: string, generatedBody: string): Object => {
const compareEquivalentXmlBodies = (expectedBody: string, generatedBody: string): Object => {
const decodeEscapedXml = (str: string) => {
return str
.replace(/&amp;/g, "&")
Expand Down