package com.blazebit.validation.constraint;
import static com.blazebit.validation.ConstraintValidatorUtils.containsViolation;
import static com.blazebit.validation.ConstraintValidatorUtils.getValidator;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Valid;
import javax.validation.Validator;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
import javax.validation.constraints.Size;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;
public class CheckEitherTest {
private Validator validator;
@Before
public void before() {
validator = getValidator();
}
@Test
public void testSimpleDefaultAndCompositeValidation() {
Set<ConstraintViolation<SimpleCar>> violations;
SimpleCar o;
o = new SimpleCarPopulateNone();
violations = validator.validate(o);
assertTrue(violations.size() == 2);
assertTrue(containsViolation(violations, "name"));
o = new SimpleCarPopulateFirst();
violations = validator.validate(o);
assertTrue(violations.size() == 3);
assertTrue(containsViolation(violations, "name"));
assertTrue(containsViolation(violations, "brand"));
o = new SimpleCarPopulateLast();
violations = validator.validate(o);
assertTrue(violations.size() == 3);
assertTrue(containsViolation(violations, "name"));
assertTrue(containsViolation(violations, "builder"));
o = new SimpleCarPopulateAll();
violations = validator.validate(o);
assertTrue(violations.size() == 4);
assertTrue(containsViolation(violations, "name"));
assertTrue(containsViolation(violations, "brand"));
assertTrue(containsViolation(violations, "builder"));
}
@Test
public void testSimpleCompositeValidation() {
Set<ConstraintViolation<SimpleCar>> violations;
SimpleCar o;
o = new SimpleCarPopulateNone();
o.name = "";
violations = validator.validate(o);
assertTrue(violations.size() == 1);
o = new SimpleCarPopulateFirst();
o.name = "";
violations = validator.validate(o);
assertTrue(violations.size() == 2);
assertTrue(containsViolation(violations, "brand"));
o = new SimpleCarPopulateLast();
o.name = "";
violations = validator.validate(o);
assertTrue(violations.size() == 2);
assertTrue(containsViolation(violations, "builder"));
o = new SimpleCarPopulateAll();
o.name = "";
violations = validator.validate(o);
assertTrue(violations.size() == 3);
assertTrue(containsViolation(violations, "brand"));
assertTrue(containsViolation(violations, "builder"));
o = new SimpleCarPopulateNone();
o.name = "";
o.brand = "";
o.builder = "";
violations = validator.validate(o);
assertTrue(violations.size() == 1);
o = new SimpleCarPopulateFirst();
o.name = "";
o.brand = "";
o.builder = "";
violations = validator.validate(o);
assertTrue(violations.size() == 2);
/* Builder must be null according to the validation rule */
assertTrue(containsViolation(violations, "builder"));
o = new SimpleCarPopulateLast();
o.name = "";
o.brand = "";
o.builder = "";
violations = validator.validate(o);
assertTrue(violations.size() == 2);
/* Brand must be null according to the validation rule */
assertTrue(containsViolation(violations, "brand"));
o = new SimpleCarPopulateAll();
o.name = "";
o.brand = "";
o.builder = "";
violations = validator.validate(o);
assertTrue(violations.size() == 3);
assertTrue(containsViolation(violations, "brand"));
assertTrue(containsViolation(violations, "builder"));
}
@Test
public void testSimpleSuccessfulValidation() {
Set<ConstraintViolation<SimpleCar>> violations;
SimpleCar o;
o = new SimpleCarPopulateNone();
o.name = "";
o.brand = "";
violations = validator.validate(o);
assertTrue(violations.isEmpty());
o = new SimpleCarPopulateFirst();
o.name = "";
o.brand = "";
violations = validator.validate(o);
assertTrue(violations.isEmpty());
o = new SimpleCarPopulateLast();
o.name = "";
o.brand = "";
violations = validator.validate(o);
assertTrue(violations.isEmpty());
o = new SimpleCarPopulateAll();
o.name = "";
o.brand = "";
violations = validator.validate(o);
assertTrue(violations.isEmpty());
o = new SimpleCarPopulateNone();
o.name = "";
o.builder = "";
violations = validator.validate(o);
assertTrue(violations.isEmpty());
o = new SimpleCarPopulateFirst();
o.name = "";
o.builder = "";
violations = validator.validate(o);
assertTrue(violations.isEmpty());
o = new SimpleCarPopulateLast();
o.name = "";
o.builder = "";
violations = validator.validate(o);
assertTrue(violations.isEmpty());
o = new SimpleCarPopulateAll();
o.name = "";
o.builder = "";
violations = validator.validate(o);
assertTrue(violations.isEmpty());
}
@Test
public void testComplexDefaultAndCompositeValidation() {
Set<ConstraintViolation<ComplexCar>> violations;
ComplexCar o;
o = new ComplexCarPopulateNone();
violations = validator.validate(o);
assertTrue(violations.size() == 2);
assertTrue(containsViolation(violations, "name"));
o = new ComplexCarPopulateFirst();
o.brand = new Brand();
violations = validator.validate(o);
assertTrue(violations.size() == 3);
assertTrue(containsViolation(violations, "name"));
assertTrue(containsViolation(violations, "brand.name"));
o = new ComplexCarPopulateLast();
o.builder = new Builder();
violations = validator.validate(o);
assertTrue(violations.size() == 3);
assertTrue(containsViolation(violations, "name"));
assertTrue(containsViolation(violations, "builder.name"));
/*
* This case is difficult, since contradicting constraint messages will
* also be included. Anyways we cover this case to clarify behavior.
*/
o = new ComplexCarPopulateAll();
o.brand = new Brand();
o.builder = new Builder();
violations = validator.validate(o);
assertTrue(violations.size() == 6);
assertTrue(containsViolation(violations, "name"));
/* Brand must be null according to the validation rule */
assertTrue(containsViolation(violations, "brand"));
assertTrue(containsViolation(violations, "brand.name"));
/* Builder must be null according to the validation rule */
assertTrue(containsViolation(violations, "builder"));
assertTrue(containsViolation(violations, "builder.name"));
}
@Test
public void testComplexCompositeValidation() {
Set<ConstraintViolation<ComplexCar>> violations;
ComplexCar o;
o = new ComplexCarPopulateNone();
o.name = "";
violations = validator.validate(o);
assertTrue(violations.size() == 1);
o = new ComplexCarPopulateFirst();
o.name = "";
o.brand = new Brand();
violations = validator.validate(o);
assertTrue(violations.size() == 2);
assertTrue(containsViolation(violations, "brand.name"));
o = new ComplexCarPopulateLast();
o.name = "";
o.builder = new Builder();
violations = validator.validate(o);
assertTrue(violations.size() == 2);
assertTrue(containsViolation(violations, "builder.name"));
o = new ComplexCarPopulateNone();
o.name = "";
o.brand = new Brand();
o.builder = new Builder();
violations = validator.validate(o);
assertTrue(violations.size() == 1);
o = new ComplexCarPopulateFirst();
o.name = "";
o.brand = new Brand();
o.builder = new Builder();
violations = validator.validate(o);
assertTrue(violations.size() == 3);
assertTrue(containsViolation(violations, "brand.name"));
assertTrue(containsViolation(violations, "builder"));
o = new ComplexCarPopulateLast();
o.name = "";
o.brand = new Brand();
o.builder = new Builder();
violations = validator.validate(o);
assertTrue(violations.size() == 3);
assertTrue(containsViolation(violations, "builder.name"));
assertTrue(containsViolation(violations, "brand"));
/*
* This case is difficult, since contradicting constraint messages will
* also be included. Anyways we cover this case to clarify behavior.
*/
o = new ComplexCarPopulateAll();
o.name = "";
o.brand = new Brand();
o.builder = new Builder();
violations = validator.validate(o);
assertTrue(violations.size() == 5);
/* Brand must be null according to the validation rule */
assertTrue(containsViolation(violations, "brand"));
assertTrue(containsViolation(violations, "brand.name"));
/* Builder must be null according to the validation rule */
assertTrue(containsViolation(violations, "builder"));
assertTrue(containsViolation(violations, "builder.name"));
/*
* This case is difficult, since contradicting constraint messages will
* also be included. Anyways we cover this case to clarify behavior.
*/
o = new ComplexCarPopulateAll();
o.name = "";
o.brand = new Brand();
o.brand.name = "A";
o.builder = new Builder();
o.builder.name = "A";
violations = validator.validate(o);
assertTrue(violations.size() == 3);
/* Brand must be null according to the validation rule */
assertTrue(containsViolation(violations, "brand"));
/* Builder must be null according to the validation rule */
assertTrue(containsViolation(violations, "builder"));
}
@Test
public void testComplexSuccessfulValidation() {
Set<ConstraintViolation<ComplexCar>> violations;
ComplexCar o;
o = new ComplexCarPopulateNone();
o.name = "";
o.brand = new Brand();
o.brand.name = "A";
violations = validator.validate(o);
assertTrue(violations.isEmpty());
o = new ComplexCarPopulateFirst();
o.name = "";
o.brand = new Brand();
o.brand.name = "A";
violations = validator.validate(o);
assertTrue(violations.isEmpty());
o = new ComplexCarPopulateLast();
o.name = "";
o.brand = new Brand();
o.brand.name = "A";
violations = validator.validate(o);
assertTrue(violations.isEmpty());
o = new ComplexCarPopulateAll();
o.name = "";
o.brand = new Brand();
o.brand.name = "A";
violations = validator.validate(o);
assertTrue(violations.isEmpty());
o = new ComplexCarPopulateNone();
o.name = "";
o.builder = new Builder();
o.builder.name = "A";
violations = validator.validate(o);
assertTrue(violations.isEmpty());
o = new ComplexCarPopulateFirst();
o.name = "";
o.builder = new Builder();
o.builder.name = "A";
violations = validator.validate(o);
assertTrue(violations.isEmpty());
o = new ComplexCarPopulateLast();
o.name = "";
o.builder = new Builder();
o.builder.name = "A";
violations = validator.validate(o);
assertTrue(violations.isEmpty());
o = new ComplexCarPopulateAll();
o.name = "";
o.builder = new Builder();
o.builder.name = "A";
violations = validator.validate(o);
assertTrue(violations.isEmpty());
}
class Car {
@NotNull
String name;
}
class SimpleCar extends Car {
@Null(groups = BuilderGroup.class)
@NotNull(groups = BrandGroup.class)
String brand;
@Null(groups = BrandGroup.class)
@NotNull(groups = BuilderGroup.class)
String builder;
}
@CheckEither(value = { BrandGroup.class, BuilderGroup.class }, message = "Either brand or builder have to be not null", mode = PopulationMode.NONE)
class SimpleCarPopulateNone extends SimpleCar {
}
@CheckEither(value = { BrandGroup.class, BuilderGroup.class }, message = "Either brand or builder have to be not null", mode = PopulationMode.FIRST)
class SimpleCarPopulateFirst extends SimpleCar {
}
@CheckEither(value = { BrandGroup.class, BuilderGroup.class }, message = "Either brand or builder have to be not null", mode = PopulationMode.LAST)
class SimpleCarPopulateLast extends SimpleCar {
}
@CheckEither(value = { BrandGroup.class, BuilderGroup.class }, message = "Either brand or builder have to be not null", mode = PopulationMode.ALL)
class SimpleCarPopulateAll extends SimpleCar {
}
class ComplexCar extends Car {
@Null(groups = BuilderGroup.class)
@NotNull(groups = BrandGroup.class)
@Valid
Brand brand;
@Null(groups = BrandGroup.class)
@NotNull(groups = BuilderGroup.class)
@Valid
Builder builder;
}
@CheckEither(value = { BrandGroup.class, BuilderGroup.class }, message = "Either brand or builder have to be not null", mode = PopulationMode.NONE)
class ComplexCarPopulateNone extends ComplexCar {
}
@CheckEither(value = { BrandGroup.class, BuilderGroup.class }, message = "Either brand or builder have to be not null", mode = PopulationMode.FIRST)
class ComplexCarPopulateFirst extends ComplexCar {
}
@CheckEither(value = { BrandGroup.class, BuilderGroup.class }, message = "Either brand or builder have to be not null", mode = PopulationMode.LAST)
class ComplexCarPopulateLast extends ComplexCar {
}
@CheckEither(value = { BrandGroup.class, BuilderGroup.class }, message = "Either brand or builder have to be not null", mode = PopulationMode.ALL)
class ComplexCarPopulateAll extends ComplexCar {
}
class Builder {
@NotNull(groups = BuilderGroup.class)
@Size(min = 1, groups = BuilderGroup.class)
String name;
}
class Brand {
@NotNull(groups = BrandGroup.class)
@Size(min = 1, groups = BrandGroup.class)
String name;
}
interface BrandGroup {
}
interface BuilderGroup {
}
}