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

Required constraint should fail for empty groups #9

Merged
merged 6 commits into from
Mar 28, 2024
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
2 changes: 1 addition & 1 deletion .sdkmanrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Enable auto-env through the sdkman_auto_env config
# Add key=value pairs of SDKs to use below
java=11.0.15-tem
java=11.0.22-tem
4 changes: 4 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ Spotless comes with two Maven commands that you can run at any moment, preferabl

The remote build will check the code formatting, so the build will fail if the code isn't formatted correctly.

## Static Analysis
This project is configured to use [SonarCloud](https://sonarcloud.io) for static analysis. That analysis runs after every pull requst to the `main` branch and the results can be examined in the project [dashboard](https://sonarcloud.io/project/overview?id=sashirestela_slimvalidator).

It is highly recommended you install the free [SonarLint](https://sonarlint.io) extension in your favorite IDE, so you can analyze your code in advance before your pull request.

## Configure IDE (Optional)
You could set your favorite IDE to be aligned to the custom code format. See details below.
Expand Down
21 changes: 12 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Java lightweight validator.
## 💡 Description
SlimValidator is a Java library for providing object validation through annotations. It is inspired by the Java Bean Validation specification but is not a implementation at all.

For example, to validate the object of a class, we need to annotate its fields with constraints and then use the `Validator` class to evaluate all the constraints:
For example, to validate the object of a class, we need to annotate its fields with constraints and then use the `Validator` class to evaluate whether the object meets all the constraints:

```java
/* Classes definition with constraint annotations */
Expand Down Expand Up @@ -86,30 +86,33 @@ var validator = new Validator();
var violations = validator.validate(person);
violations.forEach(v -> System.out.println(v.getName() + " " + v.getMessage()));
```
As a result of the validation process, you will see the following messages in console:
As a result of the validation process, you will see the following messages in console, because the object does not meet several constraints:
```txt
id must not be null.
id must have a value.
income must be at least 2000.
hobbies size must be at least 3 at most 5.
address.apartment size must be at most 4.
address.city must not be null.
address.city must have a value.
reference type must be or String or Collection<String> (max 3 items).
```

## 🚩 Constraints

### @Required
- **Description**: Checks that a value is not null.
- **Description**: Checks that a value is not null. In case the value is a group (Collection, Map, Array) checks that it is not empty.
- **Applies to**: Fields of any type.
- **Parameters**:
- _(none)_.
- **Error messages**:
- If the value is null:
- _must not be null._
- **Example**:
- If the value is null or an empty group:
- _must have a value._
- **Examples**:
```java
@Required
private Long id;

@Required
private List<Adress> addresses;
```

### @Range
Expand All @@ -133,7 +136,7 @@ reference type must be or String or Collection<String> (max 3 items).

### @Size
- **Description**: Checks that a text's length or a group's size is within a closed range.
- **Applies to**: Fields of type: String, Collection, Map or Object array.
- **Applies to**: Fields of type: String, Collection, Map, Array.
- **Parameters**:
- _min_: The lowest value of the length or size. By default is 0.
- _max_: The greatest value of the length or size. By default is Integer.MAX_VALUE.
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>io.github.sashirestela</groupId>
<artifactId>slimvalidator</artifactId>
<version>1.0.0</version>
<version>1.1.0</version>
<packaging>jar</packaging>

<name>slimvalidator</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@
@Retention(RetentionPolicy.RUNTIME)
public @interface Required {

String message() default "must not be null.";
String message() default "must have a value.";

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,38 @@
import io.github.sashirestela.slimvalidator.ConstraintValidator;
import io.github.sashirestela.slimvalidator.constraints.Required;

import java.util.Collection;
import java.util.Map;

/**
* Checks that a value is not null. Applies to fields of any type.
*/
public class RequiredValidator implements ConstraintValidator<Required, Object> {

@Override
public boolean isValid(Object value) {
return (value != null);
if (value == null) {
return false;
} else {
var groupSize = getGroupSize(value);
if (groupSize == -1) {
return true;
} else {
return (groupSize > 0);
}
}
}

private int getGroupSize(Object value) {
if (value instanceof Collection) {
return ((Collection<?>) value).size();
} else if (value instanceof Map) {
return ((Map<?, ?>) value).size();
} else if (value.getClass().isArray()) {
return ((Object[]) value).length;
} else {
return -1;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ void shouldReturnViolationsWhenObjectDoesNotAccomplishConstraints() {
var actualViolationsMessage = exception.getMessage();
var expectedViolationMessage = ""
+ "name size must be at most 20.\n"
+ "email must not be null.\n"
+ "gender must not be null.\n"
+ "addresses.0.city must not be null.\n"
+ "addresses.0.coordinate.latitude must not be null.\n"
+ "email must have a value.\n"
+ "gender must have a value.\n"
+ "addresses.0.city must have a value.\n"
+ "addresses.0.coordinate.latitude must have a value.\n"
+ "reference type must be or String or Collection<String> (max 2 items) or Collection<Collection<String>> (max 2 items).\n"
+ "hobbies size must be at least 3.\n"
+ "relatives size must be at least 2.\n"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.github.sashirestela.slimvalidator.validators;

import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.assertEquals;

class RequiredValidatorTest {

@Test
void shouldReturnExpectedResultWhenEvaluatingDataPassed() {
Object[][] data = {
{ null, false },
{ "", true },
{ "Text", true },
{ List.of(), false },
{ List.of(1, 2), true },
{ Map.of(), false },
{ Map.of("key", "value"), true },
{ new Object[] {}, false },
{ new Object[] { 1, 2, 3 }, true }
};
for (Object[] value : data) {
var validator = new RequiredValidator();
var actualResult = validator.isValid(value[0]);
var expectedResult = (boolean) value[1];
assertEquals(expectedResult, actualResult);
}
}

}