Skip to content

Commit

Permalink
added constraint on class api to ValidatorBuilder
Browse files Browse the repository at this point in the history
  • Loading branch information
ArielBerkovich committed Mar 31, 2024
1 parent f0ba625 commit b19615d
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 23 deletions.
73 changes: 50 additions & 23 deletions src/main/java/am/ik/yavi/builder/ValidatorBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,6 @@
*/
package am.ik.yavi.builder;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.Year;
import java.time.YearMonth;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Deque;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

import am.ik.yavi.constraint.BigDecimalConstraint;
import am.ik.yavi.constraint.BigIntegerConstraint;
import am.ik.yavi.constraint.BooleanConstraint;
Expand Down Expand Up @@ -111,6 +88,29 @@
import am.ik.yavi.meta.YearMonthConstraintMeta;
import am.ik.yavi.meta.ZonedDateTimeConstraintMeta;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.Year;
import java.time.YearMonth;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Deque;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

public class ValidatorBuilder<T> implements Cloneable {
private static final String DEFAULT_SEPARATOR = ".";

Expand Down Expand Up @@ -732,6 +732,33 @@ public ValidatorBuilder<T> _doubleArray(ToDoubleArray<T> f, String name,
return this.constraint(f, name, c, DoubleArrayConstraint::new);
}

/**
* @since 0.14.0
*/
public <C extends T> ValidatorBuilder<T> constraintOnClass(Class<C> clazz,
Validator<C> cValidator) {
Validator<T> TValidator = new ValidatorBuilder<T>()
.nest(clazz::cast, clazz.getName(), cValidator).build();

return constraintOnCondition(getClassConstraintCondition(clazz), TValidator);
}

/**
* @since 0.14.0
*/
public <C extends T> ValidatorBuilder<T> constraintOnClass(Class<C> clazz,
ValidatorBuilderConverter<C> converter) {
ValidatorBuilderConverter<T> tConverter = tValidatorBuilder -> tValidatorBuilder
.nest(clazz::cast, clazz.getName(), converter);

return constraintOnCondition(getClassConstraintCondition(clazz), tConverter);
}

private <C extends T> ConstraintCondition<T> getClassConstraintCondition(
Class<C> classCondition) {
return (t, c) -> classCondition.isInstance(t);
}

/**
* @since 0.11.0
*/
Expand Down
71 changes: 71 additions & 0 deletions src/test/java/am/ik/yavi/core/ConstraintOnClassTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package am.ik.yavi.core;

import am.ik.yavi.User;
import am.ik.yavi.builder.ValidatorBuilder;
import am.ik.yavi.constraint.CharSequenceConstraint;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.util.function.Function;
import java.util.stream.Stream;

import static com.google.common.truth.Truth.assertThat;

public class ConstraintOnClassTest {

@ParameterizedTest
@MethodSource("provideValidators")
void testConstraintOnConditionClass(Validator<User> validator) {
User validAdmin = new Admin("admin123", "admin@gmail", 27, "yavi123");
User invalidAdmin = new Admin("Niraz", "niraz@gmail", 23, "user");

assertThat(validator.validate(validAdmin).isValid()).isTrue();
assertThat(validator.validate(invalidAdmin).isValid()).isFalse();
}

@ParameterizedTest
@MethodSource("provideValidators")
void testConstraintOnNonConditionClass(Validator<User> validator) {
User validUser = new User("Rawad", "rawad@gmail", 25);
User invalidUser = new User("Almog", "almog@gmail", 19);

assertThat(validator.validate(validUser).isValid()).isTrue();
assertThat(validator.validate(invalidUser).isValid()).isFalse();
}

static Stream<Arguments> provideValidators() {
ValidatorBuilder<User> userValidatorBuilder = ValidatorBuilder.of(User.class)
.constraint(User::getAge, "age", c -> c.greaterThan(20));
Function<CharSequenceConstraint<Admin, String>, CharSequenceConstraint<Admin, String>> startsWithAdmin = (
CharSequenceConstraint<Admin, String> c) -> c.startsWith("yavi");

return Stream
.of(Arguments.of(new ValidatorBuilder<>(userValidatorBuilder)
.constraintOnClass(Admin.class,
ValidatorBuilder.of(Admin.class)
.constraint(Admin::getGroup, "group",
startsWithAdmin)
.build())
.build()), Arguments
.of(new ValidatorBuilder<>(userValidatorBuilder)
.constraintOnClass(Admin.class,
b -> b.constraint(Admin::getGroup,
"group", startsWithAdmin))
.build()));
}

private static class Admin extends User {
private String group;

public Admin(String name, String email, int age, String group) {
super(name, email, age);
this.group = group;
}

public String getGroup() {
return group;
}
}
}

0 comments on commit b19615d

Please sign in to comment.