Skip to content

Commit 2d8b0bb

Browse files
Enhance testing
- Simplify tests - Add tests for properties - Add tests for unusual namings
1 parent 9104fb7 commit 2d8b0bb

File tree

4 files changed

+163
-42
lines changed

4 files changed

+163
-42
lines changed

json-schema-generator/src/main/java/io/micronaut/jsonschema/generator/RecordGenerator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ public final class RecordGenerator {
6464
private List<EnumDef> enums = new ArrayList<>();
6565

6666
// TODO objectName and fileName should match. Perhaps we should just take output directory as argument. The argument does not need to be optional then
67-
// DONE support generating from an inputstream, not just file: generate(InputStream jsonSchemaStream, Optional<File> outputFileLocation)
6867
// TODO take language as argument.
6968
public boolean generate(InputStream inputStream, Optional<File> outputFileLocation) throws IOException {
7069
var jsonSchema = getJsonSchema(inputStream, null);
@@ -97,6 +96,7 @@ public boolean generateFromSchemaMap(Map<String, ?> jsonSchema, Optional<File> o
9796

9897
// TODO configure package as argument
9998
String packageName = "test";
99+
// TODO do not add the 'Record' in the end.
100100
String objectName = jsonSchema.get("title").toString() + "Record";
101101

102102
File outputFile = getOutputFile(outputFileLocation,

json-schema-generator/src/test/groovy/io/micronaut/jsonschema/generator/AbstractGeneratorSpec.groovy

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,47 @@ import com.github.javaparser.ParseResult
55
import com.github.javaparser.ParserConfiguration
66
import com.github.javaparser.ast.CompilationUnit
77
import com.github.javaparser.ast.body.RecordDeclaration
8+
import com.github.javaparser.ast.body.TypeDeclaration
89
import spock.lang.Specification
910

1011
class AbstractGeneratorSpec extends Specification {
1112

12-
RecordDeclaration generateRecord(String className, String schemaFileName) {
13+
TypeDeclaration generateType(String className, String jsonSchema) {
1314
RecordGenerator generator = new RecordGenerator()
1415

1516
File dir = File.createTempDir()
1617
File generated = dir.toPath().resolve(className +".java").toFile()
17-
generator.generate(new File("src/test/resources/" + schemaFileName), Optional.of(generated))
18+
generator.generate(new ByteArrayInputStream(jsonSchema.getBytes()), Optional.of(generated))
1819

19-
ParserConfiguration configuration = new ParserConfiguration()
20-
configuration.languageLevel = ParserConfiguration.LanguageLevel.JAVA_17
21-
ParseResult<CompilationUnit> parsed = new JavaParser(configuration).parse(generated.text)
22-
return parsed.getResult().get().getRecordByName(className).get()
20+
try {
21+
ParserConfiguration configuration = new ParserConfiguration()
22+
configuration.languageLevel = ParserConfiguration.LanguageLevel.JAVA_17
23+
ParseResult<CompilationUnit> parsed = new JavaParser(configuration).parse(generated.text)
24+
return parsed.getResult().get().getType(0)
25+
} catch (Exception e) {
26+
throw new Exception("Failed to parse file and get record. The contents are: '\n" + generated.text + "\n'", e)
27+
}
2328
}
2429

25-
String generateRecordAndGetContent(String className, String schemaFileName) {
26-
return generateRecord(className, schemaFileName).getTokenRange().get().toString()
30+
String generateTypeAndGetContent(String className, String jsonSchema) {
31+
return generateType(className, jsonSchema).getTokenRange().get().toString()
32+
}
33+
34+
String generatePropertyAndGetContent(String propertyName, String propertySchema) {
35+
String schema = """
36+
{
37+
"\$schema":"https://json-schema.org/draft/2020-12/schema",
38+
"\$id":"https://example.com/schemas/test.schema.json",
39+
"title":"Test",
40+
"type":["object"],
41+
"properties":{
42+
"$propertyName": $propertySchema
43+
}
44+
}
45+
"""
46+
47+
return ((RecordDeclaration) generateType("TestRecord", schema))
48+
.parameters[0].getTokenRange().get().toString()
2749
}
2850

2951
}

json-schema-generator/src/test/groovy/io/micronaut/jsonschema/generator/SimpleGeneratorSpec.groovy

Lines changed: 132 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,84 @@ package io.micronaut.jsonschema.generator
22

33
class SimpleGeneratorSpec extends AbstractGeneratorSpec {
44

5-
void test() {
5+
void testEnumGeneration() {
66
when:
7-
var content = generateRecordAndGetContent("LlamaRecord", "llama.schema.json")
7+
var content = generateTypeAndGetContent("LlamaRecord", '''
8+
{
9+
"$schema":"https://json-schema.org/draft/2020-12/schema",
10+
"$id":"https://example.com/schemas/status.schema.json",
11+
"title":"Status",
12+
"type": "string",
13+
"enum": [
14+
"active",
15+
"in progress",
16+
"deleted"
17+
]
18+
}
19+
''')
20+
21+
then:
22+
content == """
23+
@Serdeable
24+
public enum Status(
25+
ACTIVE("active")
26+
IN_PROGRESS("in-progress"),
27+
DELETED("deleted");
28+
29+
private final String value;
30+
31+
public Status(String value) {
32+
this.value = value;
33+
}
34+
35+
@JsonCreator
36+
public Status statusOf(String value) {
37+
return switch (value) {
38+
case "active" -> ACTIVE;
39+
case "in-progress" -> IN_PROGRESS;
40+
case "deleted" -> DELETED;
41+
};
42+
}
43+
44+
@JsonValue
45+
public String getValue() {
46+
return value;
47+
}
48+
) {
49+
}""".stripIndent().trim()
50+
}
51+
52+
void testRecordGeneration() {
53+
when:
54+
var content = generateTypeAndGetContent("LlamaRecord", '''
55+
{
56+
"$schema":"https://json-schema.org/draft/2020-12/schema",
57+
"$id":"https://example.com/schemas/llama.schema.json",
58+
"title":"Llama",
59+
"description":"A llama. <4>",
60+
"type":["object"],
61+
"properties":{
62+
"age":{
63+
"description":"The age",
64+
"type":["integer"],
65+
"minimum":0
66+
},
67+
"name":{
68+
"description":"The name",
69+
"type":"string",
70+
"minLength":1
71+
},
72+
"hours":{
73+
"description":"Happy hours",
74+
"type":"array",
75+
"items": {
76+
"type": "number"
77+
}
78+
}
79+
},
80+
"required": ["age", "name"]
81+
}
82+
''')
883

984
then:
1085
content == """
@@ -17,12 +92,63 @@ class SimpleGeneratorSpec extends AbstractGeneratorSpec {
1792
}""".stripIndent().trim()
1893
}
1994

20-
// TODO add json schema here and use inputstream to generate
95+
void testRecordNamingGeneration() {
96+
when:
97+
var type = generateType("MyLlamaNumberOneRecord", '''
98+
{
99+
"$schema":"https://json-schema.org/draft/2020-12/schema",
100+
"$id":"https://example.com/schemas/llama.schema.json",
101+
"title":"My Llama-Number One",
102+
"type":["object"],
103+
"properties":{
104+
"name": { "type": "string" }
105+
}
106+
}
107+
''')
21108

22-
// TODO test all the types
109+
then:
110+
type != null
111+
type.name.asString() == "MyLlamaNumberOneRecord"
112+
}
23113

24-
// TODO test enums
114+
void testPropertyGeneration() {
115+
when:
116+
var content = generatePropertyAndGetContent(propertyName, propertySchema)
25117

26-
// TODO test lists, sets, validation inside
118+
then:
119+
content == expectedJava
120+
121+
where:
122+
propertyName | propertySchema | expectedJava
123+
// TODO support all string formats: https://json-schema.org/understanding-json-schema/reference/string
124+
'string' | '{"type": "string"}' | 'String string'
125+
'date' | '{"type": "string", "format": "date"}' | 'LocalDate date'
126+
'date' | '{"type": "string", "format": "date-time"}' | 'ZonedDateTime date'
127+
// https://json-schema.org/understanding-json-schema/reference/numeric
128+
'integer' | '{"type": "integer"}' | 'int integer'
129+
'test' | '{"type": "number"}' | "float test"
130+
// https://json-schema.org/understanding-json-schema/reference/array
131+
'array' | '{"type": "array", "items": {"type": "string"}}' | "List<String> array"
132+
'array' | '{"type": "array", "uniqueItems": true, "items": {"type": "string"}}' | "Set<String> array"
133+
'array' | '{"type": "array", "items": {"type": "number"}}' | "List<Float> array"
134+
// TODO booleans
135+
// TODO enums
136+
// TODO support unusual names
137+
'my unusual property' | '{"type": "string"}' | '@JsonProperty("my unusual property") String myUnusualProperty'
138+
}
139+
140+
void testPropertyValidationGeneration() {
141+
when:
142+
var content = generatePropertyAndGetContent(propertyName, propertySchema)
143+
144+
then:
145+
content == expectedJava
146+
147+
where:
148+
propertyName | propertySchema | expectedJava
149+
// TODO fill in more test cases
150+
'test' | '{"type": "number", "minimum": 10}' | "@DecimalMin(10) float test"
151+
'array' | '{"type": "array", "items": {"type": "number", "minimum": 10}}' | "List<@DecimalMin(10) Float> array"
152+
}
27153

28154
}

json-schema-generator/src/test/resources/llama.schema.json

Lines changed: 0 additions & 27 deletions
This file was deleted.

0 commit comments

Comments
 (0)