Skip to content

Commit

Permalink
Merge pull request #964 from newmen/fix-required-or-optional
Browse files Browse the repository at this point in the history
Check schema required array before is required flag
  • Loading branch information
joelittlejohn authored Mar 27, 2019
2 parents 0b5b0e1 + 64b9e5c commit 8207053
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -118,16 +118,10 @@ public JDefinedClass apply(String nodeName, JsonNode node, JsonNode parent, JDef
return jclass;
}

private boolean isRequired(String nodeName, JsonNode node, Schema schema) {
if (node.has("required")) {
final JsonNode requiredNode = node.get("required");
return requiredNode.asBoolean();
}

JsonNode requiredArray = schema.getContent().get("required");

if (requiredArray != null) {
for (JsonNode requiredNode : requiredArray) {
private boolean hasEnumerated(Schema schema, String arrayFieldName, String nodeName) {
JsonNode array = schema.getContent().get(arrayFieldName);
if (array != null) {
for (JsonNode requiredNode : array) {
if (nodeName.equals(requiredNode.asText()))
return true;
}
Expand All @@ -136,22 +130,25 @@ private boolean isRequired(String nodeName, JsonNode node, Schema schema) {
return false;
}

private boolean useOptional(String nodeName, JsonNode node, Schema schema) {
if (node.has("javaOptional")) {
final JsonNode requiredNode = node.get("javaOptional");
private boolean hasFlag(JsonNode node, String fieldName) {
if (node.has(fieldName)) {
final JsonNode requiredNode = node.get(fieldName);
return requiredNode.asBoolean();
}

JsonNode javaOptionalArray = schema.getContent().get("javaOptional");
return false;
}

if (javaOptionalArray != null) {
for (JsonNode requiredNode : javaOptionalArray) {
if (nodeName.equals(requiredNode.asText()))
return true;
}
}
private boolean isDeclaredAs(String type, String nodeName, JsonNode node, Schema schema) {
return hasEnumerated(schema, type, nodeName) || hasFlag(node, type);
}

return false;
private boolean isRequired(String nodeName, JsonNode node, Schema schema) {
return isDeclaredAs("required", nodeName, node, schema);
}

private boolean useOptional(String nodeName, JsonNode node, Schema schema) {
return isDeclaredAs("javaOptional", nodeName, node, schema);
}

private void propertyAnnotations(String nodeName, JsonNode node, Schema schema, JDocCommentable generatedJavaConstruct) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/**
* Copyright © 2010-2017 Nokia
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.jsonschema2pojo.rules;

import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.Matchers.*;
import static org.mockito.Mockito.*;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.BooleanNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.sun.codemodel.JClassAlreadyExistsException;
import com.sun.codemodel.JCodeModel;
import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JType;
import org.jsonschema2pojo.GenerationConfig;
import org.jsonschema2pojo.NoopAnnotator;
import org.jsonschema2pojo.Schema;
import org.jsonschema2pojo.SchemaStore;
import org.junit.Before;
import org.junit.Test;

public class PropertyRuleTest {
private static final String TARGET_CLASS_NAME = PropertyRuleTest.class.getName() + ".DummyClass";

private static final String internalFieldName = "internalRequired";
private static final String targetFieldName = "requiredFoo";

private final GenerationConfig config = mock(GenerationConfig.class);
private final PropertyRule rule = new PropertyRule(new RuleFactory(config, new NoopAnnotator(), new SchemaStore()));

private ObjectMapper mapper;

@Before
public void setup() {
mapper = new ObjectMapper();

when(config.isIncludeGetters()).thenReturn(true);
when(config.isUseOptionalForGetters()).thenReturn(true);
}

private String getGeneratedMethodTypeName(JDefinedClass jclass) {
return jclass.getMethod("getRequiredFoo", new JType[] {}).type().name();
}

private Schema getMockedSchema(ObjectNode parentNode) {
Schema schema = mock(Schema.class);
when(schema.getContent()).thenReturn(parentNode);
when(schema.deriveChildSchema(any())).thenReturn(schema);
return schema;
}

private JDefinedClass applyRule(ObjectNode propertyNode, ObjectNode parentNode) throws JClassAlreadyExistsException {
JDefinedClass jclass = new JCodeModel()._class(TARGET_CLASS_NAME);
return rule.apply(targetFieldName, propertyNode, parentNode, jclass, getMockedSchema(parentNode));
}

@Test
public void applyRequiredByTopArray() throws JClassAlreadyExistsException {
ObjectNode propertyNode = mapper.createObjectNode();
propertyNode.set("required", mapper.createArrayNode().add(internalFieldName));
propertyNode.set("properties", mapper.createObjectNode().set(internalFieldName, mapper.createObjectNode()));

ObjectNode parentNode = mapper.createObjectNode();
parentNode.set("required", mapper.createArrayNode().add(targetFieldName));
parentNode.set("properties", mapper.createObjectNode().set(targetFieldName, propertyNode));

JDefinedClass jclass = applyRule(propertyNode, parentNode);

assertThat(jclass, notNullValue());
assertThat(getGeneratedMethodTypeName(jclass), is("RequiredFoo"));
}

@Test
public void applyNotRequiredByTopArray() throws JClassAlreadyExistsException {
ObjectNode propertyNode = mapper.createObjectNode();
propertyNode.set("required", mapper.createArrayNode().add(internalFieldName));
propertyNode.set("properties", mapper.createObjectNode().set(internalFieldName, mapper.createObjectNode()));

ObjectNode parentNode = mapper.createObjectNode();
parentNode.set("properties", mapper.createObjectNode().set(targetFieldName, propertyNode));

JDefinedClass jclass = applyRule(propertyNode, parentNode);

assertThat(jclass, notNullValue());
assertThat(getGeneratedMethodTypeName(jclass), is("Optional<RequiredFoo>"));
}

@Test
public void applyRequiredByFlag() throws JClassAlreadyExistsException {
ObjectNode propertyNode = mapper.createObjectNode();
propertyNode.set("required", BooleanNode.TRUE);
propertyNode.set("properties", mapper.createObjectNode().set(internalFieldName, mapper.createObjectNode()));

ObjectNode parentNode = mapper.createObjectNode();
parentNode.set("properties", mapper.createObjectNode().set(targetFieldName, propertyNode));

JDefinedClass jclass = applyRule(propertyNode, parentNode);

assertThat(jclass, notNullValue());
assertThat(getGeneratedMethodTypeName(jclass), is("RequiredFoo"));
}

@Test
public void applyNotRequiredByFlag() throws JClassAlreadyExistsException {
ObjectNode propertyNode = mapper.createObjectNode();
propertyNode.set("properties", mapper.createObjectNode().set(internalFieldName, mapper.createObjectNode()));

ObjectNode parentNode = mapper.createObjectNode();
parentNode.set("properties", mapper.createObjectNode().set(targetFieldName, propertyNode));

JDefinedClass jclass = applyRule(propertyNode, parentNode);

assertThat(jclass, notNullValue());
assertThat(getGeneratedMethodTypeName(jclass), is("Optional<RequiredFoo>"));
}
}

0 comments on commit 8207053

Please sign in to comment.