Skip to content

Commit

Permalink
feat(java): java client cts APIC-467 (#626)
Browse files Browse the repository at this point in the history
fix(cts): add common client test (#646)
  • Loading branch information
millotp authored Jun 7, 2022
1 parent 19dc918 commit 6d579ae
Show file tree
Hide file tree
Showing 39 changed files with 361 additions and 632 deletions.
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ indent_size = 2

[*.{mustache,ts,yml}]
charset = utf-8

[*.mustache]
insert_final_newline = false
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ public Map<String, Object> postProcessAllModels(Map<String, Object> objs) {
protected Builder<String, Lambda> addMustacheLambdas() {
Builder<String, Lambda> lambdas = super.addMustacheLambdas();

lambdas.put("escapequotes", new EscapeQuotesLambda());
lambdas.put("escapeQuotes", new EscapeQuotesLambda());
lambdas.put("escapeSlash", new EscapeSlashLambda());
return lambdas;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.algolia.codegen.cts;

import com.samskivert.mustache.Mustache;
import com.samskivert.mustache.Template;
import java.io.IOException;
import java.io.Writer;

public class EscapeSlashLambda implements Mustache.Lambda {

@Override
public void execute(Template.Fragment fragment, Writer writer) throws IOException {
String text = fragment.execute();
writer.write(text.replace("\\", "\\\\"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,7 @@ class Step {

class Expected {

public String type;
public Object error;
public Match match;
public String testSubject;
}

class Match {

public String regexp;
public Map<String, Object> objectContaining;
public Object match;
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,10 @@ public void enhanceParameters(Map<String, Object> parameters, Map<String, Object
*/
public void enhanceParameters(Map<String, Object> parameters, Map<String, Object> bundle, CodegenOperation operation)
throws CTSException, JsonMappingException, JsonProcessingException {
if (parameters == null) {
return;
}
if (parameters.size() == 0) {
if (parameters != null && parameters.size() == 0) {
bundle.put("parameters", "{}");
return;
}
List<Map<String, Object>> parametersWithDataType = new ArrayList<>();
Map<String, Object> parametersWithDataTypeMap = new HashMap<>();

IJsonSchemaValidationProperties spec = null;
String paramName = null;
// special case if there is only bodyParam which is not an array
Expand All @@ -59,23 +53,28 @@ public void enhanceParameters(Map<String, Object> parameters, Map<String, Object
paramName = operation.bodyParam.paramName;
}

List<Map<String, Object>> parametersWithDataType = new ArrayList<>();
Map<String, Object> parametersWithDataTypeMap = new HashMap<>();

if (paramName == null) {
for (Entry<String, Object> param : parameters.entrySet()) {
CodegenParameter specParam = null;
if (operation != null) {
for (CodegenParameter sp : operation.allParams) {
if (sp.paramName.equals(param.getKey())) {
specParam = sp;
break;
if (parameters != null) {
for (Entry<String, Object> param : parameters.entrySet()) {
CodegenParameter specParam = null;
if (operation != null) {
for (CodegenParameter sp : operation.allParams) {
if (sp.paramName.equals(param.getKey())) {
specParam = sp;
break;
}
}
if (specParam == null) {
throw new CTSException("Parameter " + param.getKey() + " not found in the root parameter");
}
}
if (specParam == null) {
throw new CTSException("Parameter " + param.getKey() + " not found in the root parameter");
}
Map<String, Object> paramWithType = traverseParams(param.getKey(), param.getValue(), specParam, "", 0);
parametersWithDataType.add(paramWithType);
parametersWithDataTypeMap.put((String) paramWithType.get("key"), paramWithType);
}
Map<String, Object> paramWithType = traverseParams(param.getKey(), param.getValue(), specParam, "", 0);
parametersWithDataType.add(paramWithType);
parametersWithDataTypeMap.put((String) paramWithType.get("key"), paramWithType);
}
} else {
Map<String, Object> paramWithType = traverseParams(paramName, parameters, spec, "", 0);
Expand Down Expand Up @@ -134,7 +133,9 @@ private Map<String, Object> traverseParams(
testOutput.put("parent", parent);
testOutput.put("objectName", Utils.capitalize(baseType));

if (spec.getIsArray()) {
if (param == null) {
handleNull(testOutput);
} else if (spec.getIsArray()) {
handleArray(paramName, param, testOutput, spec, suffix);
} else if (isEnum(spec)) {
handleEnum(param, testOutput);
Expand Down Expand Up @@ -171,7 +172,9 @@ private Map<String, Object> traverseParams(String paramName, Object param, Strin
// cannot determine objectName with inference
// testOutput.put("objectName", Utils.capitalize(baseType));

if (param instanceof List) {
if (param == null) {
handleNull(testOutput);
} else if (param instanceof List) {
handleArray(paramName, param, testOutput, null, suffix);
} else if (param instanceof Map) {
handleObject(paramName, param, testOutput, suffix);
Expand All @@ -188,6 +191,7 @@ private Map<String, Object> createDefaultOutput() {
// context and run into a infinite loop
testOutput.put("isObject", false);
testOutput.put("isArray", false);
testOutput.put("isNull", false);
testOutput.put("isFreeFormObject", false);
testOutput.put("isAnyType", false);
testOutput.put("isString", false);
Expand All @@ -202,6 +206,10 @@ private Map<String, Object> createDefaultOutput() {
return testOutput;
}

private void handleNull(Map<String, Object> testOutput) {
testOutput.put("isNull", true);
}

private void handleArray(
String paramName,
Object param,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.algolia.codegen.Utils;
import com.algolia.codegen.exceptions.CTSException;
import io.swagger.v3.core.util.Json;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
Expand All @@ -12,29 +11,10 @@
import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.SupportingFile;

public class TestsClient implements TestsGenerator {

private final String language, client;
public class TestsClient extends TestsGenerator {

public TestsClient(String language, String client) {
this.language = language;
this.client = client;
}

private Map<String, ClientTestData[]> loadCTS() throws Exception {
if (!available()) {
throw new CTSException("Templates not found for client test", true);
}

File dir = new File("tests/CTS/client/" + client);
if (!dir.exists()) {
throw new CTSException("CTS not found at " + dir.getAbsolutePath(), true);
}
Map<String, ClientTestData[]> cts = new HashMap<>();
for (File f : dir.listFiles()) {
cts.put(f.getName().replace(".json", ""), Json.mapper().readValue(f, ClientTestData[].class));
}
return cts;
super(language, client);
}

@Override
Expand All @@ -58,7 +38,7 @@ public void addSupportingFiles(List<SupportingFile> supportingFiles, String outp
}

public void run(Map<String, CodegenModel> models, Map<String, CodegenOperation> operations, Map<String, Object> bundle) throws Exception {
Map<String, ClientTestData[]> cts = loadCTS();
Map<String, ClientTestData[]> cts = loadCTS("client", client, ClientTestData[].class);
ParametersWithDataType paramsType = new ParametersWithDataType(models, language);

List<Object> blocks = new ArrayList<>();
Expand Down Expand Up @@ -92,29 +72,33 @@ public void run(Map<String, CodegenModel> models, Map<String, CodegenOperation>
stepOut.put("path", step.path);
paramsType.enhanceParameters(step.parameters, stepOut, ope);

if (step.expected.testSubject == null) {
stepOut.put("testSubject", "result");
} else {
switch (step.expected.testSubject) {
if (step.expected.type != null) {
switch (step.expected.type) {
case "userAgent":
stepOut.put("testUserAgent", true);
break;
case "host":
stepOut.put("testHost", true);
break;
case "timeouts":
stepOut.put("testTimeouts", true);
break;
default:
stepOut.put("testSubject", step.expected.testSubject);
stepOut.put("testResult", true);
break;
}
}
if (step.expected.error != null) {
stepOut.put("isError", true);
stepOut.put("expectedError", step.expected.error);
} else if (step.expected.match != null) {
Map<String, Object> match = new HashMap<>();
match.put("regexp", step.expected.match.regexp);
if (step.expected.match.objectContaining != null) {
Map<String, Object> objectContaining = new HashMap<>();
paramsType.enhanceParameters(step.expected.match.objectContaining, objectContaining);
match.put("objectContaining", objectContaining);
if (step.expected.match instanceof Map) {
Map<String, Object> match = new HashMap<>();
paramsType.enhanceParameters((Map<String, Object>) step.expected.match, match);
stepOut.put("match", match);
} else {
stepOut.put("match", step.expected.match);
}
stepOut.put("match", match);
}
steps.add(stepOut);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,77 @@
package com.algolia.codegen.cts.tests;

import com.algolia.codegen.Utils;
import com.algolia.codegen.exceptions.CTSException;
import io.swagger.v3.core.util.Json;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.openapitools.codegen.CodegenModel;
import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.SupportingFile;

public interface TestsGenerator {
public boolean available();
public abstract class TestsGenerator {

public void addSupportingFiles(List<SupportingFile> supportingFiles, String outputFolder, String extension);
protected final String language, client;

public void run(Map<String, CodegenModel> models, Map<String, CodegenOperation> operations, Map<String, Object> bundle) throws Exception;
public TestsGenerator(String language, String client) {
this.language = language;
this.client = client;
}

public abstract boolean available();

public abstract void addSupportingFiles(List<SupportingFile> supportingFiles, String outputFolder, String extension);

public abstract void run(Map<String, CodegenModel> models, Map<String, CodegenOperation> operations, Map<String, Object> bundle)
throws Exception;

protected <T> Map<String, T> loadCTS(String path, String clientName, Class<T> jsonType) throws Exception {
if (!available()) {
throw new CTSException("Templates not found for " + path, true);
}

File dir = new File("tests/CTS/" + path + "/" + clientName);
File commonTestDir = new File("tests/CTS/" + path + "/common");
if (!dir.exists()) {
throw new CTSException("CTS not found at " + dir.getAbsolutePath(), true);
}
if (!commonTestDir.exists()) {
throw new CTSException("CTS not found at " + commonTestDir.getAbsolutePath(), true);
}
List<File> allTests = new ArrayList<>();
Collections.addAll(allTests, dir.listFiles());
Collections.addAll(allTests, commonTestDir.listFiles());

Map<String, T> cts = new TreeMap<>();

for (File f : allTests) {
String json = new String(Files.readAllBytes(Paths.get(f.getAbsolutePath())));
json = injectVariables(json);
cts.put(f.getName().replace(".json", ""), Json.mapper().readValue(json, jsonType));
}
return cts;
}

private String languageCased() {
switch (language) {
case "java":
return "Java";
case "javascript":
return "JavaScript";
case "php":
return "PHP";
default:
return language;
}
}

private String injectVariables(String json) {
return json.replace("${{languageCased}}", languageCased()).replace("${{clientPascalCase}}", Utils.capitalize(Utils.camelize(client)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,26 @@

import com.algolia.codegen.Utils;
import com.algolia.codegen.exceptions.CTSException;
import io.swagger.v3.core.util.Json;
import java.io.File;
import java.util.*;
import org.openapitools.codegen.CodegenModel;
import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.SupportingFile;

public class TestsRequest implements TestsGenerator {

private final String language, client;
public class TestsRequest extends TestsGenerator {

public TestsRequest(String language, String client) {
this.language = language;
this.client = client;
super(language, client);
}

private Map<String, Request[]> loadCTS() throws Exception {
Map<String, Request[]> cts = new TreeMap<>();
protected Map<String, Request[]> loadRequestCTS() throws Exception {
String clientName = client;
// This special case allow us to read the `search` CTS to generated the tests for the
// `algoliasearch-lite` client, which is only available in JavaScript
if (language.equals("javascript") && client.equals("algoliasearch-lite")) {
clientName = "search";
}

if (!available()) {
throw new CTSException("Templates not found for requests test", true);
}

File dir = new File("tests/CTS/methods/requests/" + clientName);
File commonTestDir = new File("tests/CTS/methods/requests/common");
if (!dir.exists()) {
throw new CTSException("CTS not found at " + dir.getAbsolutePath(), true);
}
if (!commonTestDir.exists()) {
throw new CTSException("CTS not found at " + commonTestDir.getAbsolutePath(), true);
}
for (File f : dir.listFiles()) {
cts.put(f.getName().replace(".json", ""), Json.mapper().readValue(f, Request[].class));
}
for (File f : commonTestDir.listFiles()) {
cts.put(f.getName().replace(".json", ""), Json.mapper().readValue(f, Request[].class));
}
return cts;
return super.loadCTS("methods/requests", clientName, Request[].class);
}

@Override
Expand All @@ -65,7 +41,7 @@ public void addSupportingFiles(List<SupportingFile> supportingFiles, String outp

@Override
public void run(Map<String, CodegenModel> models, Map<String, CodegenOperation> operations, Map<String, Object> bundle) throws Exception {
Map<String, Request[]> cts = loadCTS();
Map<String, Request[]> cts = loadRequestCTS();

List<Object> blocks = new ArrayList<>();
ParametersWithDataType paramsType = new ParametersWithDataType(models, language);
Expand Down
Loading

0 comments on commit 6d579ae

Please sign in to comment.