Skip to content

Commit cfbfa4e

Browse files
committed
updates to Create methods
1 parent dde662d commit cfbfa4e

12 files changed

Lines changed: 168 additions & 22 deletions

File tree

cddjava/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
<artifactId>javafaker</artifactId>
5959
<version>1.0.2</version>
6060
</dependency>
61+
6162
</dependencies>
6263

6364
</project>

cddjava/src/main/java/org/offscale/Create.java

Lines changed: 94 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,14 @@ private class Schema {
3333
private String description;
3434
private String strictType;
3535

36+
public Schema() {
37+
this.type = "object";
38+
this.strictType = "Object";
39+
}
40+
3641
public Schema (final String type) {
3742
this.type = type;
43+
this.strictType = type;
3844
}
3945

4046
public Schema(String type, String strictType) {
@@ -68,7 +74,7 @@ public ImmutableMap<String, String> generateComponents() {
6874
HashMap<String, String> generatedComponents = new HashMap<>();
6975
JSONObject joSchemas = jo.getJSONObject("components").getJSONObject("schemas");
7076
List<String> schemas = Lists.newArrayList(joSchemas.keys());
71-
schemas.forEach((schema) -> generatedComponents.put(schema, generateComponent(joSchemas.getJSONObject(schema), schema).toString()));
77+
schemas.forEach((schema) -> generatedComponents.put(schema, generateComponent2(joSchemas.getJSONObject(schema), schema, null).get("type")));
7278
return ImmutableMap.copyOf(generatedComponents);
7379
}
7480

@@ -79,26 +85,67 @@ public ImmutableMap<String, String> generateComponents() {
7985
* @return a String containing the generated code for a component.
8086
*/
8187
private ClassOrInterfaceDeclaration generateComponent(JSONObject joComponent, String componentName) {
82-
JSONObject joProperties = joComponent.getJSONObject("properties");
83-
List<String> properties = Lists.newArrayList(joProperties.keys());
84-
ClassOrInterfaceDeclaration myComponent = new ClassOrInterfaceDeclaration();
85-
86-
myComponent.setName(componentName);
87-
properties.forEach((property) -> {
88-
Schema parameter = parseSchema(joProperties.getJSONObject(property));
89-
if (parameter.type.equals("Object")) {
90-
myComponent.addMember(generateComponent(joProperties.getJSONObject(property), Utils.capitalizeFirstLetter(property)));
91-
FieldDeclaration field = myComponent.addField(Utils.capitalizeFirstLetter(property), property);
92-
} else {
93-
FieldDeclaration field = myComponent.addField(parameter.type, property);
94-
field.setJavadocComment("Type of " + parameter.strictType);
88+
ClassOrInterfaceDeclaration myComponent = new ClassOrInterfaceDeclaration();
89+
myComponent.setName(componentName);
90+
if (joComponent.has("properties")) {
91+
JSONObject joProperties = joComponent.getJSONObject("properties");
92+
List<String> properties = Lists.newArrayList(joProperties.keys());
93+
properties.forEach((property) -> {
94+
Schema parameter = parseSchema(joProperties.getJSONObject(property));
95+
if (parameter.type.equals("Object")) {
96+
myComponent.addMember(generateComponent(joProperties.getJSONObject(property), Utils.capitalizeFirstLetter(property)));
97+
FieldDeclaration field = myComponent.addField(Utils.capitalizeFirstLetter(property), property);
98+
field.setJavadocComment("Type of " + parameter.strictType);
99+
} else {
100+
FieldDeclaration field = myComponent.addField(parameter.type, property);
101+
field.setJavadocComment("Type of " + parameter.strictType);
102+
}
103+
});
104+
// If there is no properties field, this should an array.
105+
} else {
106+
JSONObject joItems = joComponent.getJSONObject("items");
107+
Schema parameter = parseSchema(joItems);
108+
}
109+
return myComponent;
110+
}
111+
112+
private ImmutableMap<String, String> generateComponent2(JSONObject joComponent, String componentName, ClassOrInterfaceDeclaration parentClass) {
113+
Schema type = parseSchema(joComponent);
114+
if (type.type.equalsIgnoreCase("object")) {
115+
ClassOrInterfaceDeclaration newClass = new ClassOrInterfaceDeclaration();
116+
JSONObject joProperties = joComponent.getJSONObject("properties");
117+
List<String> properties = Lists.newArrayList(joProperties.keys());
118+
newClass.setName(Utils.capitalizeFirstLetter(componentName));
119+
properties.forEach(property -> {
120+
ImmutableMap<String, String> propertyType = generateComponent2(joProperties.getJSONObject(property), property, newClass);
121+
FieldDeclaration field = newClass.addField(propertyType.get("type"), property);
122+
field.setJavadocComment("Type of " + propertyType.get("strictType"));
123+
});
124+
if (parentClass == null) {
125+
return ImmutableMap.of("type", newClass.toString());
126+
}
127+
128+
parentClass.addMember(newClass);
129+
return ImmutableMap.of("type", newClass.getNameAsString(), "strictType", newClass.getNameAsString());
130+
} else if (type.type.equals("array")) {
131+
if (parentClass == null) {
132+
ClassOrInterfaceDeclaration newClass = new ClassOrInterfaceDeclaration();
133+
String arrayType = generateComponent2(joComponent.getJSONObject("items"), "ArrayType", newClass).get("type");
134+
newClass.setName(Utils.capitalizeFirstLetter(componentName));
135+
newClass.addField(arrayType + "[]", componentName + "Array");
136+
return ImmutableMap.of("type", newClass.toString());
95137
}
96-
});
97-
return myComponent;
138+
String arrayType = generateComponent2(joComponent.getJSONObject("items"), "ArrayType", parentClass).get("type");
139+
return ImmutableMap.of("type", arrayType + "[]", "strictType", arrayType + "[]");
140+
} else {
141+
return ImmutableMap.of("type", parseSchema(joComponent).type, "strictType", parseSchema(joComponent).strictType);
142+
}
98143
}
99144

100145
/**
101-
* @return Routes interface containing routes from OpenAPI Spec
146+
* @return Map with two key-value pairs: routes and tests.
147+
* routes is the code for the generated routes interface.
148+
* tests is the code for generated tests for all routes.
102149
*/
103150
public ImmutableMap<String, String> generateRoutesAndTests() {
104151
HashMap<String, String> routesAndTests = new HashMap<>();
@@ -125,10 +172,18 @@ public ImmutableMap<String, String> generateRoutesAndTests() {
125172
return ImmutableMap.copyOf(routesAndTests);
126173
}
127174

175+
/**
176+
* @return the base url for all http requests
177+
*/
128178
private String getBaseURL() {
129179
return this.jo.getJSONArray("servers").getJSONObject(0).getString("url");
130180
}
131181

182+
/**
183+
* Given a route, generates a test corresponding the route.
184+
* @param routesInterface
185+
* @param joRoute
186+
*/
132187
private void generateTest(ClassOrInterfaceDeclaration routesInterface, JSONObject joRoute) {
133188
String classType = generateRouteType(joRoute.getJSONObject("responses")).type;
134189
MethodDeclaration methodDeclaration = routesInterface.addMethod(joRoute.getString("operationId") + "Test");
@@ -165,6 +220,13 @@ private void generateTest(ClassOrInterfaceDeclaration routesInterface, JSONObjec
165220
methodDeclaration.setBody(methodBody);
166221
}
167222

223+
/**
224+
* Some parameter names are common such as firstname and can be
225+
* generated more precisely. This method handles parameters that
226+
* aren't common.
227+
* @param type of the parameter to generate mock data for
228+
* @return the mock data for the given parameter
229+
*/
168230
private String generateMockDataForUnrecognizedName(String type) {
169231
if (type.equals("String")) {
170232
return faker.food().fruit();
@@ -177,6 +239,10 @@ private String generateMockDataForUnrecognizedName(String type) {
177239
}
178240
}
179241

242+
/**
243+
* @param schema for which to generate the mock data
244+
* @return the mock data for the given schema.
245+
*/
180246
private String generateMockDataForType(Schema schema) {
181247
String parameter = schema.name + "=";
182248
switch (schema.name) {
@@ -191,11 +257,11 @@ private String generateMockDataForType(Schema schema) {
191257
}
192258

193259
/**
194-
*
260+
* generates the route code for a given route in the JSONObject.
195261
* @param routesInterface
196262
* @param joRoute
197263
* @param routeName
198-
* @param operation
264+
* @param operation such as GET or POST
199265
*/
200266
private MethodDeclaration generateRoute(ClassOrInterfaceDeclaration routesInterface, JSONObject joRoute, String routeName, String operation) {
201267
MethodDeclaration methodDeclaration = routesInterface.addMethod(joRoute.getString("operationId"))
@@ -260,6 +326,10 @@ private Schema parseSchema(JSONObject joSchema) {
260326
return new Schema(Utils.getOpenAPIToJavaTypes().get(joSchema.get("format")), joSchema.getString("format"));
261327
}
262328

329+
if (!joSchema.has("type")) {
330+
return new Schema();
331+
}
332+
263333
return new Schema(Utils.getOpenAPIToJavaTypes().get(joSchema.get("type")), joSchema.getString("type"));
264334
}
265335

@@ -298,6 +368,11 @@ private String generateJavadocForRoute(JSONObject joRoute, String routeName, Str
298368
return javaDocForRoute.toString();
299369
}
300370

371+
/**
372+
* @param joResponse
373+
* @param responseName
374+
* @return the javadoc return statement
375+
*/
301376
private String generateJavadocReturn(JSONObject joResponse, String responseName) {
302377
return joResponse.getString("description") + " (Status Code " + responseName + "), ";
303378
}

cddjava/src/main/java/org/offscale/Utils.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public static ImmutableMap<String, String> getOpenAPIToJavaTypes() {
2828
openAPIToJavaTypes.put("int32", "int");
2929
openAPIToJavaTypes.put("object", "Object");
3030
openAPIToJavaTypes.put("boolean", "boolean");
31+
openAPIToJavaTypes.put("array", "array");
3132

3233
return ImmutableMap.copyOf(openAPIToJavaTypes);
3334
}

cddjava/src/main/resources/OpenAPISpec1/componentCode1.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
class Pet {
22

3+
/**
4+
* Type of long[][][]
5+
*/
6+
long[][][] names;
7+
38
/**
49
* Type of integer
510
*/

cddjava/src/main/resources/OpenAPISpec1/componentCode3.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,15 @@ class Dog {
2020
String origin;
2121
}
2222

23+
/**
24+
* Type of First
25+
*/
2326
First first;
2427
}
2528

29+
/**
30+
* Type of Name
31+
*/
2632
Name name;
2733

2834
/**
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class Pets {
2+
3+
Pet[] PetsArray;
4+
}

cddjava/src/main/resources/OpenAPISpec1/openapi.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,22 @@ components:
9191
format: int64
9292
name:
9393
type: integer
94+
names:
95+
type: array
96+
items:
97+
type: array
98+
items:
99+
type: array
100+
items:
101+
type: integer
102+
format: int64
103+
94104
tag2:
95105
type: string
106+
Pets:
107+
type: array
108+
items:
109+
$ref: "#/components/schemas/Pet"
96110
Dog:
97111
properties:
98112
id:

cddjava/src/test/java/org/offscale/CreateTests.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import org.junit.Before;
1111
import org.junit.Test;
1212
import static org.junit.Assert.*;
13-
13+
import static org.hamcrest.CoreMatchers.*;
1414
import java.io.*;
1515
import java.net.URL;
1616
import java.nio.file.Files;
@@ -20,6 +20,7 @@ public class CreateTests {
2020
private Create create;
2121
private Create improperFormCreate;
2222
static private final String PET_COMPONENT_FILE_PATH = "src/main/resources/OpenAPISpec1/componentCode1.txt";
23+
static private final String PETS_COMPONENT_FILE_PATH = "src/main/resources/OpenAPISpec1/componentCode4.txt";
2324
static private final String DOG_COMPONENT_FILE_PATH = "src/main/resources/OpenAPISpec1/componentCode3.txt";
2425
static private final String ROUTES_FILE_PATH = "src/main/resources/OpenAPISpec1/routesCode.txt";
2526

@@ -32,10 +33,12 @@ public void init() {
3233
@Test
3334
public void generateComponentsSuccess() throws IOException {
3435
String petComponentCode = Files.readString(Path.of(PET_COMPONENT_FILE_PATH));
36+
String petsComponentCode = Files.readString(Path.of(PETS_COMPONENT_FILE_PATH));
3537
String dogComponentCode = Files.readString(Path.of(DOG_COMPONENT_FILE_PATH));
3638
ImmutableMap<String, String> generatedComponents = create.generateComponents();
37-
assertEquals(generatedComponents.size(), 3);
39+
assertEquals(generatedComponents.size(), 4);
3840
assertEquals(generatedComponents.get("Pet"), petComponentCode);
41+
assertEquals(generatedComponents.get("Pets"), petsComponentCode);
3942
assertEquals(generatedComponents.get("Dog"), dogComponentCode);
4043
}
4144

@@ -48,10 +51,18 @@ public void generateComponentsException() {
4851
public void generateRoutesSuccess() throws IOException {
4952
Path filePath = Path.of(ROUTES_FILE_PATH);
5053
String routesCode = Files.readString(filePath);
51-
System.out.println(create.generateRoutesAndTests().get("tests"));
5254
assertEquals(create.generateRoutesAndTests().get("routes"), routesCode);
5355
}
5456

57+
@Test
58+
public void generateTestsSuccess() throws IOException {
59+
String testClass = create.generateRoutesAndTests().get("tests");
60+
System.out.println(testClass);
61+
assertThat(testClass, containsString("createPetsTest()"));
62+
assertThat(testClass, containsString("listPetsTest()"));
63+
assertThat(testClass, containsString("showDogByIdTest()"));
64+
}
65+
5566
String run(String url, OkHttpClient client) throws IOException {
5667
Request request = new Request.Builder()
5768
.url(url)

cddjava/target/classes/OpenAPISpec1/componentCode1.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
class Pet {
22

3+
/**
4+
* Type of long[][][]
5+
*/
6+
long[][][] names;
7+
38
/**
49
* Type of integer
510
*/

cddjava/target/classes/OpenAPISpec1/componentCode3.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,15 @@ class Dog {
2020
String origin;
2121
}
2222

23+
/**
24+
* Type of First
25+
*/
2326
First first;
2427
}
2528

29+
/**
30+
* Type of Name
31+
*/
2632
Name name;
2733

2834
/**

0 commit comments

Comments
 (0)