Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tests and fixes for cascading array of pojo #114

Merged
merged 1 commit into from
Aug 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions blackbox-test/src/main/java/example/avaje/cascade/BShip.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package example.avaje.cascade;

import io.avaje.validation.constraints.NotBlank;
import io.avaje.validation.constraints.Valid;

import java.util.Set;

@Valid
public record BShip(
@NotBlank String name,
@Valid Set<ACrew> crew // cascade validation
) { }
11 changes: 11 additions & 0 deletions blackbox-test/src/main/java/example/avaje/cascade/CShip.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package example.avaje.cascade;

import io.avaje.validation.constraints.NotBlank;
import io.avaje.validation.constraints.Valid;

@Valid
public record CShip(
@NotBlank String name,
@Valid ACrew[] crew // cascade validation
) {
}
12 changes: 12 additions & 0 deletions blackbox-test/src/main/java/example/avaje/cascade/CShip2.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package example.avaje.cascade;

import io.avaje.validation.constraints.NotBlank;
import io.avaje.validation.constraints.NotEmpty;
import io.avaje.validation.constraints.Valid;

@Valid
public record CShip2(
@NotBlank String name,
@Valid @NotEmpty ACrew[] crew // cascade validation
) {
}
12 changes: 12 additions & 0 deletions blackbox-test/src/main/java/example/avaje/cascade/CShip3.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package example.avaje.cascade;

import io.avaje.validation.constraints.NotBlank;
import io.avaje.validation.constraints.NotEmpty;
import io.avaje.validation.constraints.Valid;

@Valid
public record CShip3(
@NotBlank String name,
@NotEmpty ACrew[] crew // NotEmpty with no cascade
) {
}
12 changes: 12 additions & 0 deletions blackbox-test/src/main/java/example/avaje/cascade/DShip.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package example.avaje.cascade;

import io.avaje.validation.constraints.NotBlank;
import io.avaje.validation.constraints.NotEmpty;
import io.avaje.validation.constraints.Valid;

@Valid
public record DShip(
@NotBlank String name,
@NotEmpty String[] crew // cascade validation
) {
}
91 changes: 91 additions & 0 deletions blackbox-test/src/test/java/example/avaje/cascade/AShipTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
Expand All @@ -22,6 +23,30 @@ void valid() {
validator.validate(ship);
}

@Test
void valid_usingSet() {
var ship = new BShip("lollyPop", Set.of(new ACrew("ok", null)));
validator.validate(ship);
}

@Test
void valid_usingArray() {
var ship = new CShip("lollyPop", new ACrew[]{new ACrew("ok", null)});
validator.validate(ship);
}

@Test
void valid_usingArray3() {
var ship = new CShip3("lollyPop", new ACrew[]{new ACrew("ok", null)});
validator.validate(ship);
}

@Test
void valid_usingScalarArray() {
var ship = new DShip("lollyPop", new String[]{"bob"});
validator.validate(ship);
}

@Test
void validAllowEmptyCollection() {
var ship = new AShip("lollyPop", List.of());
Expand Down Expand Up @@ -82,6 +107,72 @@ void invalidShip2_when_nullCollection_expect_InvalidEmptyCollection() {
assertThat(violations.get(1).message()).isEqualTo("must not be empty");
}

@Test
void arrayCascade() {
var ship = new CShip("", new ACrew[]{new ACrew("NotValid", null)});
List<ConstraintViolation> violations = violations(ship);

assertThat(violations).hasSize(2);
assertThat(violations.get(0).path()).isEqualTo("name");
assertThat(violations.get(0).message()).isEqualTo("must not be blank");
assertThat(violations.get(1).path()).isEqualTo("crew[0].name");
assertThat(violations.get(1).message()).isEqualTo("maximum length 4 exceeded");
}

@Test
void arrayNotCascade() {
var ship = new CShip3("", new ACrew[]{new ACrew("NotValid", null)});
List<ConstraintViolation> violations = violations(ship);

assertThat(violations).hasSize(1);
assertThat(violations.get(0).path()).isEqualTo("name");
assertThat(violations.get(0).message()).isEqualTo("must not be blank");
}

@Test
void arrayNotEmpty_when_empty() {
var ship = new CShip2("", new ACrew[]{});
List<ConstraintViolation> violations = violations(ship);

assertThat(violations).hasSize(2);
assertThat(violations.get(0).path()).isEqualTo("name");
assertThat(violations.get(0).message()).isEqualTo("must not be blank");
assertThat(violations.get(1).path()).isEqualTo("crew");
assertThat(violations.get(1).message()).isEqualTo("must not be empty");
}

@Test
void arrayNotEmpty_when_null() {
var ship = new CShip2("ok", null);
List<ConstraintViolation> violations = violations(ship);

assertThat(violations).hasSize(1);
assertThat(violations.get(0).path()).isEqualTo("crew");
assertThat(violations.get(0).message()).isEqualTo("must not be empty");
}

@Test
void arrayNotEmpty_when_scalarArrayEmpty() {
var ship = new DShip("", new String[]{});
List<ConstraintViolation> violations = violations(ship);

assertThat(violations).hasSize(2);
assertThat(violations.get(0).path()).isEqualTo("name");
assertThat(violations.get(0).message()).isEqualTo("must not be blank");
assertThat(violations.get(1).path()).isEqualTo("crew");
assertThat(violations.get(1).message()).isEqualTo("must not be empty");
}

@Test
void arrayNotEmpty_when_scalarNull() {
var ship = new DShip("ok", null);
List<ConstraintViolation> violations = violations(ship);

assertThat(violations).hasSize(1);
assertThat(violations.get(0).path()).isEqualTo("crew");
assertThat(violations.get(0).message()).isEqualTo("must not be empty");
}

List<ConstraintViolation> violations(Object any) {
return violations(any, Locale.ENGLISH);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import static io.avaje.validation.generator.ProcessingContext.isAssignable2Interface;

class AdapterHelper {
final class AdapterHelper {

private final Append writer;
private final ElementAnnotationContainer elementAnnotations;
Expand Down Expand Up @@ -67,9 +67,9 @@ void write() {
writer.eol().append("%s .mapValues()", indent);
writeTypeUse(genericType.secondParamType(), typeUse2, false);

} else if (genericType.topType().contains("[]") && hasValid) {
} else if (hasValid && genericType.topType().contains("[]")) {
writer.eol().append("%s .array()", indent);
writeTypeUse(genericType.firstParamType(), typeUse1);
writer.eol().append("%s .andThenMulti(ctx.adapter(%s.class))", indent, topType.shortNameMinusArray());

} else if (hasValid) {
if (!classLevel) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public String toString() {
}

void addImports(Set<String> importTypes) {
final String type = trimExtends();
final String type = trimExtends().replace("[]", "");
if (includeInImports(type)) {
importTypes.add(type);
}
Expand Down Expand Up @@ -97,10 +97,18 @@ void writeType(String prefix, StringBuilder sb) {
}
}

String shortNameMinusArray() {
return shortNameRaw().replace("[]", "");
}

String shortName() {
return shortNameRaw().replace("[]", "Array");
}

String shortNameRaw() {
final StringBuilder sb = new StringBuilder();
shortName(sb);
return sb.toString().replace("[]", "Array");
return sb.toString();
}

void shortName(StringBuilder sb) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ private void cascadeTypesInner() {
}

private boolean cascadeElement(TypeElement element) {
return element.getKind() != ElementKind.ENUM && !metaData.contains(adapterName(element));
return element != null && element.getKind() != ElementKind.ENUM && !metaData.contains(adapterName(element));
}

private String adapterName(TypeElement element) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ protected boolean validateAll(Iterable<Object> value, ValidationRequest req, Str

/** Execute validations for all items in the given array */
protected boolean validateArray(Object[] value, ValidationRequest req, String propertyName) {
if (value == null) {
if (value == null || multiAdapter == null) {
return true;
}
if (propertyName != null) {
Expand Down