Skip to content

Commit

Permalink
Adding support for generic default types, 'default', 'const', 'exampl…
Browse files Browse the repository at this point in the history
…es' and 'enum'
  • Loading branch information
Leo Ring committed Feb 27, 2019
1 parent c90f0dd commit cd1a845
Show file tree
Hide file tree
Showing 7 changed files with 240 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ public JsonArray generate() {
if (maxItems == null) {
maxItems = 500;
}
maxItems = minItems + rnd.nextInt(maxItems-minItems);
if(maxItems > 1) {
maxItems = minItems + rnd.nextInt(maxItems - minItems);
}


//meant for JSON generator after all, not OutOfMemory generator :)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,14 @@

import io.apptik.json.JsonBoolean;
import io.apptik.json.JsonElement;
import io.apptik.json.JsonNumber;
import io.apptik.json.JsonString;
import io.apptik.json.generator.JsonGeneratorConfig;
import io.apptik.json.generator.JsonGenerator;
import io.apptik.json.schema.Schema;

import java.util.Random;

public class BooleanGenerator extends JsonGenerator {

public BooleanGenerator(Schema schema, JsonGeneratorConfig configuration) {
Expand All @@ -34,6 +38,38 @@ public BooleanGenerator(Schema schema, JsonGeneratorConfig configuration, String

@Override
public JsonElement generate() {
return new JsonBoolean(rnd.nextBoolean());
String defaultValue = schema.getDefault();

//Check for generic default types
if (schema.getDefaultBoolean() != null) {
return new JsonBoolean(schema.getDefaultBoolean());
}
if (schema.getConstBoolean() != null) {
return new JsonBoolean(schema.getConstBoolean());
}
if (schema.getExamples() != null && schema.getExamples().length() > 0) {
return checkIfDefaultIsABoolean(schema.getExamples().get(new Random().nextInt(schema.getExamples().length())).toString());
}
if (schema.getEnum() != null && schema.getEnum().length() > 0) {
return checkIfDefaultIsABoolean(schema.getEnum().get(new Random().nextInt(schema.getEnum().length() -1)).toString());
}

if (defaultValue != null && !defaultValue.isEmpty()) {
if(!defaultValue.equalsIgnoreCase("true") && !defaultValue.equalsIgnoreCase("false")) {
throw new RuntimeException("Default value: " + defaultValue + " of key: " + propertyName + ", is not a boolean type");
} else {
return (new JsonBoolean(Boolean.parseBoolean(defaultValue)));
}
} else {
return new JsonBoolean(rnd.nextBoolean());
}
}

private JsonBoolean checkIfDefaultIsABoolean(String defaultValue) {
if(!defaultValue.equalsIgnoreCase("true") && !defaultValue.equalsIgnoreCase("false")) {
throw new RuntimeException("Default value: " + defaultValue + " of key: " + propertyName + ", is not a boolean type");
} else {
return (new JsonBoolean(Boolean.parseBoolean(defaultValue)));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import io.apptik.json.generator.JsonGenerator;
import io.apptik.json.schema.Schema;

import java.util.Random;

public class IntegerGenerator extends JsonGenerator {
public IntegerGenerator(Schema schema, JsonGeneratorConfig configuration) {
super(schema, configuration);
Expand All @@ -35,6 +37,21 @@ public IntegerGenerator(Schema schema, JsonGeneratorConfig configuration, String
public JsonElement generate() {
int minValue = 0;
int maxValue = Integer.MAX_VALUE;

//Check for generic default types
if (schema.getDefaultInt() != null) {
return new JsonNumber(schema.getDefaultInt());
}
if (schema.getConstInt() != null) {
return new JsonNumber(schema.getConstInt());
}
if (schema.getExamples() != null && schema.getExamples().length() > 0) {
return checkIfDefaultIsAInteger(schema.getExamples().get(new Random().nextInt(schema.getExamples().length())).toString());
}
if (schema.getEnum() != null && schema.getEnum().length() > 0) {
return checkIfDefaultIsAInteger(schema.getEnum().get(new Random().nextInt(schema.getEnum().length() -1)).toString());
}

if(configuration!=null) {
if (configuration.globalIntegerMin!=null) minValue = configuration.globalIntegerMin;
if (configuration.globalIntegerMax!=null) maxValue = configuration.globalIntegerMax;
Expand All @@ -47,4 +64,12 @@ public JsonElement generate() {

return new JsonNumber(minValue + rnd.nextInt(maxValue-minValue));
}

private JsonNumber checkIfDefaultIsAInteger(String defaultValue) {
try {
return new JsonNumber(Integer.parseInt(defaultValue));
} catch (NumberFormatException ex) {
throw new RuntimeException("Default value: " + defaultValue + " of key: " + propertyName + ", is not a integer type");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@

import io.apptik.json.JsonElement;
import io.apptik.json.JsonNumber;
import io.apptik.json.JsonString;
import io.apptik.json.generator.JsonGenerator;
import io.apptik.json.generator.JsonGeneratorConfig;
import io.apptik.json.schema.Schema;

import java.util.Random;

public class NumberGenerator extends JsonGenerator {
public NumberGenerator(Schema schema, JsonGeneratorConfig configuration) {
super(schema, configuration);
Expand All @@ -36,6 +39,22 @@ public JsonElement generate() {

int minValue = 0;
int maxValue = Integer.MAX_VALUE;
String defaultValue = schema.getDefault();

//Check for generic default types
if (schema.getDefaultNumber() != null) {
return new JsonNumber(schema.getDefaultNumber());
}
if (schema.getConstNumber() != null) {
return new JsonNumber(schema.getConstNumber());
}
if (schema.getExamples() != null && schema.getExamples().length() > 0) {
return checkIfDefaultIsANumber(schema.getExamples().get(new Random().nextInt(schema.getExamples().length())).toString());
}
if (schema.getEnum() != null && schema.getEnum().length() > 0) {
return checkIfDefaultIsANumber(schema.getEnum().get(new Random().nextInt(schema.getEnum().length() -1)).toString());
}

if(configuration!=null) {
if (configuration.globalNumberMin!=null) minValue = configuration.globalNumberMin;
if (configuration.globalNumberMax!=null) maxValue = configuration.globalNumberMax;
Expand All @@ -48,4 +67,12 @@ public JsonElement generate() {

return new JsonNumber(minValue + rnd.nextInt(maxValue-minValue) + Math.abs(rnd.nextDouble()));
}

private JsonNumber checkIfDefaultIsANumber(String defaultValue) {
try {
return new JsonNumber(Double.parseDouble(defaultValue));
} catch (NumberFormatException ex) {
throw new RuntimeException("Default value: " + defaultValue + " of key: " + propertyName + ", is not a number type");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.Random;

import static io.apptik.json.generator.matcher.FormatMatchers.*;

Expand Down Expand Up @@ -77,13 +78,27 @@ public JsonElement generate() {
}
}
}

//Check for generic default types
if (schema.getDefault() != null && !schema.getDefault().isEmpty()) {
return new JsonString(schema.getDefault());
}
if (schema.getConst() != null && !schema.getConst().isEmpty()) {
return new JsonString(schema.getConst());
}
if (schema.getExamples() != null && schema.getExamples().length() > 0) {
return new JsonString(schema.getExamples().get(new Random().nextInt(schema.getExamples().length())).toString());
}
if (schema.getEnum() != null && schema.getEnum().length() > 0) {
return new JsonString(schema.getEnum().get(new Random().nextInt(schema.getEnum().length() -1)).toString());
}

if(configuration!=null) {
if (configuration.globalStringLengthMin!=null) minChars = configuration.globalStringLengthMin;
if (configuration.globalStringLengthMax!=null) maxChars = configuration.globalStringLengthMax;
if (propertyName != null ) {
if (configuration.stringLengthMin.get(propertyName)!=null) minChars = configuration.stringLengthMin.get(propertyName);
if (configuration.stringLengthMax.get(propertyName)!=null) maxChars = configuration.stringLengthMax.get(propertyName);

if (configuration.stringPredefinedValues.get(propertyName) != null) {
return new JsonString(configuration.stringPredefinedValues.get(propertyName).get(rnd.nextInt(configuration.stringPredefinedValues.get(propertyName).size())));
}
Expand All @@ -92,8 +107,9 @@ public JsonElement generate() {
}

String res = "";
int cnt = minChars + rnd.nextInt(maxChars-minChars);
for(int i=0;i<cnt;i++) res += (rnd.nextBoolean())? (char)(65 + rnd.nextInt(25)):(char)(97 + rnd.nextInt(25));
int cnt = minChars + rnd.nextInt(maxChars - minChars);
for (int i = 0; i < cnt; i++)
res += (rnd.nextBoolean()) ? (char) (65 + rnd.nextInt(25)) : (char) (97 + rnd.nextInt(25));
return new JsonString(res);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public void setUp() throws Exception {
"\"type\" : \"object\"," +
"\"properties\" : {" +
"\"one\" : {\"type\" : \"number\" } ," +
"\"two\" : {\"type\" : \"string\" }," +
"\"two\" : {\"type\" : \"string\" }," +
"\"three\" : " + "{" +
"\"type\" : \"object\"," +
"\"properties\" : {" +
Expand Down Expand Up @@ -76,7 +76,102 @@ public void testGenerate() throws Exception {
System.out.println(job.toString());

assertEquals(8, job.length());
}

@Test
public void testDefaults() throws Exception {
SchemaV4 defaultsSchema = new SchemaV4().wrap(JsonElement.readFrom(
"{\n" +
"\"type\" : \"object\"," +
"\"properties\" : {" +
"\"integerDefault\" : {\"type\" : \"integer\", \"default\": 1 } ," +
"\"integerConst\" : {\"type\" : \"integer\", \"const\": 2 }," +
"\"integerEnum\" : {\"type\" : \"integer\", \"enum\": [ 3, 4] }," +
"\"integerExamples\" : {\"type\" : \"integer\", \"examples\": [ 5, 6] }," +
"\"numberDefault\" : {\"type\" : \"number\", \"default\": 25.1 } ," +
"\"numberConst\" : {\"type\" : \"number\", \"const\": 25.2 }," +
"\"numberEnum\" : {\"type\" : \"number\", \"enum\": [ 25.3, 25.4 ] }," +
"\"numberExamples\" : {\"type\" : \"number\", \"examples\": [ 25.5, 25.6] }," +
"\"stringDefault\" : {\"type\" : \"string\", \"default\": \"someDefault\" }," +
"\"stringConst\" : {\"type\" : \"string\", \"const\": \"someConst\" }," +
"\"stringEnum\" : {\"type\" : \"string\", \"enum\": [\"someEnum\", \"someEnum2\"] }," +
"\"stringExamples\" : {\"type\" : \"string\", \"examples\": [\"someExample\", \"someExample2\"] }," +
"\"booleanDefault\" : {\"type\" : \"boolean\", \"default\": true }," +
"\"booleanConst\" : {\"type\" : \"boolean\", \"const\": false }," +
"\"booleanEnum\" : {\"type\" : \"boolean\", \"enum\": [ true, true] }," +
"\"booleanExamples\" : {\"type\" : \"boolean\", \"examples\": [ false, false] }," +
"\"arrayWithDefaults\" : {\"type\" : \"array\"," +
" \"items\" : { \"type\" : \"object\", " +
"\"properties\" : {" +
"\"integerDefault\" : {\"type\" : \"integer\", \"default\": 1 } ," +
"\"integerConst\" : {\"type\" : \"integer\", \"const\": 2 }," +
"\"integerEnum\" : {\"type\" : \"integer\", \"enum\": [ 3, 4] }," +
"\"integerExamples\" : {\"type\" : \"integer\", \"examples\": [ 5, 6] }," +
"\"numberDefault\" : {\"type\" : \"number\", \"default\": 25.1 } ," +
"\"numberConst\" : {\"type\" : \"number\", \"const\": 25.2 }," +
"\"numberEnum\" : {\"type\" : \"number\", \"enum\": [ 25.3, 25.4 ] }," +
"\"numberExamples\" : {\"type\" : \"number\", \"examples\": [ 25.5, 25.6] }," +
"\"stringDefault\" : {\"type\" : \"string\", \"default\": \"someDefault\" }," +
"\"stringConst\" : {\"type\" : \"string\", \"const\": \"someConst\" }," +
"\"stringEnum\" : {\"type\" : \"string\", \"enum\": [\"someEnum\", \"someEnum2\"] }," +
"\"stringExamples\" : {\"type\" : \"string\", \"examples\": [\"someExample\", \"someExample2\"] }," +
"\"booleanDefault\" : {\"type\" : \"boolean\", \"default\": true }," +
"\"booleanConst\" : {\"type\" : \"boolean\", \"const\": false }," +
"\"booleanEnum\" : {\"type\" : \"boolean\", \"enum\": [ true, true] }," +
"\"booleanExamples\" : {\"type\" : \"boolean\", \"examples\": [ false, false] }" +
"}" +
"}" +
"}" +
"}" +
"}").asJsonObject());

JsonObject job = new JsonGenerator(defaultsSchema, new JsonGeneratorConfig()).generate().asJsonObject();
System.out.println("Output is: " + job.toString());
assertEquals("someDefault", job.getString("stringDefault"));
assertEquals("someConst", job.getString("stringConst"));
assertTrue(job.getString("stringEnum").contains("someEnum") || job.getString("stringEnum").contains("someEnum2"));
assertTrue(job.getString("stringExamples").contains("someExample") || job.getString("stringExamples").contains("someExample2"));

assertTrue(1 == job.getInt("integerDefault"));
assertTrue(2 == job.getInt("integerConst"));
assertTrue(job.getInt("integerEnum") == 3|| job.getInt("integerEnum") == 4);
assertTrue(job.getInt("integerExamples") == 5 || job.getInt("integerExamples") == 6);

assertEquals(25.1, job.getDouble("numberDefault"));
assertEquals(25.2, job.getDouble("numberConst"));
assertTrue(job.getDouble("numberEnum") == 25.3|| job.getDouble("numberEnum") == 25.4);
assertTrue(job.getDouble("numberExamples") == 25.5 || job.getDouble("numberExamples") == 25.6);

assertTrue(true == job.getBoolean("booleanDefault"));
assertTrue(false == job.getBoolean("booleanConst"));
assertTrue(job.getBoolean("booleanEnum") == true);
assertTrue(job.getBoolean("booleanExamples") == false);

assertEquals("someDefault", job.getJsonArray("arrayWithDefaults").get(0).asJsonObject().getString("stringDefault"));
assertEquals("someConst", job.getJsonArray("arrayWithDefaults").get(0).asJsonObject().getString("stringConst"));
assertTrue(job.getJsonArray("arrayWithDefaults").get(0).asJsonObject().getString("stringEnum").contains("someEnum")
|| job.getJsonArray("arrayWithDefaults").get(0).asJsonObject().getString("stringEnum").contains("someEnum2"));
assertTrue(job.getJsonArray("arrayWithDefaults").get(0).asJsonObject().getString("stringExamples").contains("someExample")
|| job.getJsonArray("arrayWithDefaults").get(0).asJsonObject().getString("stringExamples").contains("someExample2"));

assertTrue(1 == job.getJsonArray("arrayWithDefaults").get(0).asJsonObject().getInt("integerDefault"));
assertTrue(2 == job.getJsonArray("arrayWithDefaults").get(0).asJsonObject().getInt("integerConst"));
assertTrue(job.getJsonArray("arrayWithDefaults").get(0).asJsonObject().getInt("integerEnum") == 3
|| job.getJsonArray("arrayWithDefaults").get(0).asJsonObject().getInt("integerEnum") == 4);
assertTrue(job.getJsonArray("arrayWithDefaults").get(0).asJsonObject().getInt("integerExamples") == 5
|| job.getJsonArray("arrayWithDefaults").get(0).asJsonObject().getInt("integerExamples") == 6);

assertEquals(25.1, job.getJsonArray("arrayWithDefaults").get(0).asJsonObject().getDouble("numberDefault"));
assertEquals(25.2, job.getJsonArray("arrayWithDefaults").get(0).asJsonObject().getDouble("numberConst"));
assertTrue(job.getJsonArray("arrayWithDefaults").get(0).asJsonObject().getDouble("numberEnum") == 25.3||
job.getJsonArray("arrayWithDefaults").get(0).asJsonObject().getDouble("numberEnum") == 25.4);
assertTrue(job.getJsonArray("arrayWithDefaults").get(0).asJsonObject().getDouble("numberExamples") == 25.5 ||
job.getJsonArray("arrayWithDefaults").get(0).asJsonObject().getDouble("numberExamples") == 25.6);

assertTrue(true == job.getJsonArray("arrayWithDefaults").get(0).asJsonObject().getBoolean("booleanDefault"));
assertTrue(false == job.getJsonArray("arrayWithDefaults").get(0).asJsonObject().getBoolean("booleanConst"));
assertTrue(job.getJsonArray("arrayWithDefaults").get(0).asJsonObject().getBoolean("booleanEnum") == true);
assertTrue(job.getJsonArray("arrayWithDefaults").get(0).asJsonObject().getBoolean("booleanExamples") == false);
}

@Test
Expand Down
34 changes: 33 additions & 1 deletion json-schema/src/main/java/io/apptik/json/schema/Schema.java
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,31 @@ public String getDescription() {
}

public String getDefault() {
return getJson().optString("default","");
return getJson().optString("default");
}

public Integer getDefaultInt() {
return getJson().optInt("default");
}

public Integer getConstInt() {
return getJson().optInt("const");
}

public Double getDefaultNumber() {
return getJson().optDouble("default");
}

public Double getConstNumber() {
return getJson().optDouble("const");
}

public Boolean getDefaultBoolean() {
return getJson().optBoolean("default");
}

public Boolean getConstBoolean() {
return getJson().optBoolean("const");
}

public Double getMultipleOf() {
Expand Down Expand Up @@ -375,6 +399,14 @@ public JsonObject getDependencies() {
return getJson().optJsonObject("dependencies");
}

public JsonArray getExamples() {
return getJson().optJsonArray("examples");
}

public String getConst() {
return getJson().optString("const");
}

public JsonArray getEnum() {
return getJson().optJsonArray("enum");
}
Expand Down

0 comments on commit cd1a845

Please sign in to comment.