Skip to content

Commit 9703ad5

Browse files
committed
Updated Tests
1 parent c9118f4 commit 9703ad5

18 files changed

+151
-89
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
language: java

pom.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,16 @@
8282

8383
<build>
8484
<plugins>
85+
<plugin>
86+
<groupId>org.apache.maven.plugins</groupId>
87+
<artifactId>maven-surefire-plugin</artifactId>
88+
<version>2.22.0</version>
89+
</plugin>
90+
<plugin>
91+
<groupId>org.apache.maven.plugins</groupId>
92+
<artifactId>maven-failsafe-plugin</artifactId>
93+
<version>2.22.0</version>
94+
</plugin>
8595
<plugin>
8696
<groupId>org.apache.maven.plugins</groupId>
8797
<artifactId>maven-source-plugin</artifactId>

src/main/java/dev/ditsche/validator/Validator.java

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package dev.ditsche.validator;
22

33
import dev.ditsche.validator.error.ErrorBag;
4+
import dev.ditsche.validator.error.FieldNotAccessibleException;
45
import dev.ditsche.validator.error.ValidationException;
56
import dev.ditsche.validator.rule.*;
7+
import dev.ditsche.validator.rule.builder.Builder;
68
import org.apache.commons.lang3.reflect.FieldUtils;
79

810
import java.lang.reflect.Field;
@@ -12,10 +14,8 @@
1214

1315
/**
1416
* Validates an object against a defined schema.
15-
*
16-
* @param <T> The type of the validated object.
1717
*/
18-
public class Validator<T> {
18+
public class Validator {
1919

2020
/**
2121
* The error bag for the
@@ -37,29 +37,49 @@ public class Validator<T> {
3737
/**
3838
* Create a new validator instance based on a given type.
3939
*/
40-
public Validator() {
40+
private Validator() {
4141
this.errorBag = new ErrorBag();
4242
this.ruleParser = new RuleParser();
4343
this.fields = new ArrayList<>();
4444
}
4545

46-
public Validator<T> add(Validatable validatable) {
46+
public static Validator fromRules(Builder ...builders) {
47+
Validator validator = new Validator();
48+
for(Builder builder : builders) {
49+
validator.add(builder);
50+
}
51+
return validator;
52+
}
53+
54+
public static Validator fromRules(Validatable ...rules) {
55+
Validator validator = new Validator();
56+
for(Validatable validatable : rules) {
57+
validator.add(validatable);
58+
}
59+
return validator;
60+
}
61+
62+
63+
64+
public Validator add(Builder builder) {
65+
return add(builder.build());
66+
}
67+
68+
public Validator add(Validatable validatable) {
4769
this.fields.add(validatable);
4870
return this;
4971
}
5072

51-
public T validate(T object) throws ValidationException, IllegalAccessException {
73+
public <T> T validate(T object) {
5274
return validate(object, false);
5375
}
5476

5577
/**
5678
* Validates an object against a schema and returns an error bag.
5779
*
5880
* @param object The object that need to be validated.
59-
* @throws ValidationException Thrown when at least one rule fails.
60-
* @throws IllegalAccessException Thrown when the field is not public.
6181
*/
62-
public T validate(T object, boolean abortEarly) throws ValidationException, IllegalAccessException {
82+
public <T> T validate(T object, boolean abortEarly) {
6383
errorBag.clear();
6484
List<Field> fieldSet = new ArrayList<>();
6585
for (Class<?> c = object.getClass(); c != null; c = c.getSuperclass())
@@ -68,38 +88,24 @@ public T validate(T object, boolean abortEarly) throws ValidationException, Ille
6888
fieldSet.addAll(Arrays.asList(fields));
6989
}
7090
for(Validatable validatable : this.fields) {
71-
Field field = fieldSet.stream().filter(f -> f.getName().equals(validatable.getField())).findFirst().orElse(null);
72-
if(field == null) continue;
73-
Object value = FieldUtils.readField(field, object, true);
74-
ValidationResult result = validatable.validate(value, abortEarly);
75-
if(result.isChanged())
76-
FieldUtils.writeField(field, object, value, true);
77-
errorBag.merge(result.getErrorBag());
91+
try {
92+
Field field = fieldSet.stream().filter(f -> f.getName().equals(validatable.getField())).findFirst().orElse(null);
93+
if(field == null) continue;
94+
Object value = FieldUtils.readField(field, object, true);
95+
ValidationResult result = validatable.validate(value, abortEarly);
96+
if(result.isChanged())
97+
FieldUtils.writeField(field, object, result.getValue(), true);
98+
errorBag.merge(result.getErrorBag());
99+
} catch (IllegalAccessException ex) {
100+
throw new FieldNotAccessibleException();
101+
}
78102
}
79103
if(!errorBag.isEmpty())
80104
throw new ValidationException(errorBag);
81105

82106
return object;
83107
}
84108

85-
/**
86-
* Uses reflection to invoke a getter of the validation target.
87-
* Falls back to the fields default getter. Will fail if the variable
88-
* is not publicly accessible.
89-
*
90-
* @param field The field name whose value should be received.
91-
* @param object The validation target object.
92-
* @return {@code null} if the field cannot be resolved, or the value.
93-
*/
94-
private Object getValue(Field field, Object object) throws IllegalAccessException {
95-
return FieldUtils.readField(field, object, true);
96-
}
97-
98-
private Object setValue(Field field, Object value, Object object) throws IllegalAccessException {
99-
FieldUtils.writeField(field, object, value, true);
100-
return object;
101-
}
102-
103109
/**
104110
* Registers a custom rule with an abbreviation.
105111
*

src/main/java/dev/ditsche/validator/rule/ValidationField.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,15 @@ public ValidationField(String field, Rule ...rules) {
5151
this.rules = Stream.of(rules).collect(Collectors.toList());
5252
}
5353

54+
public ValidationField(String field, List<Rule> rules) {
55+
if(field == null || field.trim().isEmpty())
56+
throw new IllegalArgumentException("Validation field requires a valid field name");
57+
if(rules == null)
58+
throw new IllegalArgumentException("Validation rules cannot be null");
59+
this.field = field;
60+
this.rules = rules;
61+
}
62+
5463
/**
5564
* Adds a rule to the field.
5665
* Replaces the rule if existing.

src/main/java/dev/ditsche/validator/rule/builder/NumberRuleBuilder.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import dev.ditsche.validator.rule.Rule;
44
import dev.ditsche.validator.rule.Validatable;
5+
import dev.ditsche.validator.rule.ValidationField;
56
import dev.ditsche.validator.rule.ruleset.*;
67

78
import java.util.LinkedList;
@@ -10,7 +11,7 @@
1011
/**
1112
* @author Tobias Dittmann
1213
*/
13-
class NumberRuleBuilder implements Builder {
14+
public class NumberRuleBuilder implements Builder {
1415

1516
private final String field;
1617

@@ -54,7 +55,7 @@ public NumberRuleBuilder custom(Rule rule) {
5455

5556
@Override
5657
public Validatable build() {
57-
return null;
58+
return new ValidationField(field, rules);
5859
}
5960

6061
}

src/main/java/dev/ditsche/validator/rule/builder/StringRuleBuilder.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
/**
1111
* @author Tobias Dittmann
1212
*/
13-
class StringRuleBuilder implements Builder {
13+
public class StringRuleBuilder implements Builder {
1414

1515
private final String field;
1616

@@ -82,13 +82,18 @@ public StringRuleBuilder defaultValue(String value) {
8282
return this;
8383
}
8484

85+
public StringRuleBuilder trim() {
86+
rules.add(new TrimRule());
87+
return this;
88+
}
89+
8590
public StringRuleBuilder custom(Rule rule) {
8691
rules.add(rule);
8792
return this;
8893
}
8994

9095
public ValidationField build() {
91-
return new ValidationField(field, (Rule[]) rules.toArray());
96+
return new ValidationField(field, rules);
9297
}
9398

9499
}

src/main/java/dev/ditsche/validator/rule/ruleset/EmailRule.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
*/
1515
public class EmailRule implements Rule {
1616

17-
private final String PATTERN = "^[A-Za-z0-9._%'-]+@[A-Za-z0-9.-]+\\\\.[a-zA-Z]{2,4}$";
17+
private final String PATTERN = "^[A-Za-z0-9._%'+-]+@[A-Za-z0-9.-]+.[a-zA-Z]{2,4}$";
1818

1919
@Override
2020
public RuleResult passes(Object value) {
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package dev.ditsche.validator.rule.ruleset;
2+
3+
import dev.ditsche.validator.rule.Rule;
4+
import dev.ditsche.validator.rule.RuleResult;
5+
6+
/**
7+
* @author Tobias Dittmann
8+
*/
9+
public class TrimRule implements Rule {
10+
11+
@Override
12+
public RuleResult passes(Object value) {
13+
14+
if(!(value instanceof String))
15+
return RuleResult.reject();
16+
17+
return RuleResult.resolve(((String) value).trim());
18+
}
19+
20+
@Override
21+
public String message(String field) {
22+
return String.format("The field \"%s\" needs to be a string to be able to trim it", field);
23+
}
24+
25+
}
Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
package dev.ditsche.validator.dto;
22

3+
import lombok.Data;
4+
35
/**
46
* @author Tobias Dittmann
57
*/
8+
@Data
69
public class TestEntity {
710
private String title;
11+
private String email;
12+
private String firstName;
13+
private int count;
814

9-
public TestEntity(String title) {
15+
public TestEntity(String title, String email, String firstName, int count) {
1016
this.title = title;
11-
}
12-
13-
public String getTitle() {
14-
return this.title;
17+
this.email = email;
18+
this.firstName = firstName;
19+
this.count = count;
1520
}
1621
}

src/test/java/dev/ditsche/validator/rule/RuleParserTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,16 @@ public class RuleParserTest {
1414
public void shouldParseRequiredRuleByString() {
1515
Rule rule = ruleParser.parse("required").orElse(null);
1616
assertThat(rule.getClass()).isEqualTo(RequiredRule.class);
17-
assertThat(rule.passes("abc")).isTrue();
17+
assertThat(rule.passes("abc").isPassed()).isTrue();
1818
}
1919

2020
@Test
2121
public void shouldParseMaxRuleByString() {
2222
Rule rule = ruleParser.parse("max:50").orElse(null);
2323
assertThat(rule.getClass()).isEqualTo(MaxRule.class);
2424

25-
assertThat(rule.passes(51)).isFalse();
26-
assertThat(rule.passes(49)).isTrue();
25+
assertThat(rule.passes(51).isPassed()).isFalse();
26+
assertThat(rule.passes(49).isPassed()).isTrue();
2727
}
2828

2929
}

0 commit comments

Comments
 (0)