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

#10 - Added support of typed conjunction to predicate composition #13

Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@
public interface RichPredicate<T> extends Predicate<T> {

<R> WhereObject<T, R> and(Function<T, R> mapper);

RichPredicateConjunction<T> and();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.github.avegera.predicate4j.api;

import java.util.List;
import java.util.function.Function;

public interface RichPredicateConjunction<T> {

WhereBoolean<T> booleanValue(Function<T, Boolean> mapper);

<R> WhereList<T, R> list(Function<T, List<R>> mapper);

WhereString<T> string(Function<T, String> mapper);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package io.github.avegera.predicate4j.impl;

import io.github.avegera.predicate4j.api.*;

import java.util.List;
import java.util.function.Function;

public class RichPredicateConjunctionImpl<T> implements RichPredicateConjunction<T> {

private final RichPredicate<T> previousPredicate;

public RichPredicateConjunctionImpl(RichPredicate<T> previousPredicate) {
this.previousPredicate = previousPredicate;
}

@Override
public WhereBoolean<T> booleanValue(Function<T, Boolean> mapper) {
return new WhereBooleanImpl<>(mapper, previousPredicate);
}

@Override
public <R> WhereList<T, R> list(Function<T, List<R>> mapper) {
return new WhereListImpl<>(mapper, previousPredicate);
}

@Override
public WhereString<T> string(Function<T, String> mapper) {
return new WhereStringImpl<>(mapper, previousPredicate);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.github.avegera.predicate4j.impl;

import io.github.avegera.predicate4j.api.RichPredicateConjunction;
import io.github.avegera.predicate4j.api.RichPredicate;
import io.github.avegera.predicate4j.api.WhereObject;

Expand All @@ -23,4 +24,9 @@ public boolean test(T object) {
public <R2> WhereObject<T, R2> and(Function<T, R2> andMapper) {
return new WhereObjectImpl<>(andMapper, this);
}

@Override
public RichPredicateConjunction<T> and() {
return new RichPredicateConjunctionImpl<>(this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ public WhereBooleanImpl(Function<T, Boolean> mapper) {
super(mapper);
}

public WhereBooleanImpl(Function<T, Boolean> mapper, RichPredicate<T> previousPredicate) {
super(mapper, previousPredicate);
}

@Override
public RichPredicate<T> isTrue() {
return getPredicate(Predicates.isTrue());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ public WhereListImpl(Function<T, List<R>> mapper) {
super(mapper);
}

public WhereListImpl(Function<T, List<R>> mapper, RichPredicate<T> previousPredicate) {
super(mapper, previousPredicate);
}

@Override
public RichPredicate<T> isEmpty() {
return getPredicate(Predicates.isEmpty());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ public WhereStringImpl(Function<T, String> mapper) {
super(mapper);
}

public WhereStringImpl(Function<T, String> mapper, RichPredicate<T> previousPredicate) {
super(mapper, previousPredicate);
}

@Override
public RichPredicate<T> isEmpty() {
return getPredicate(Predicates.isEmptyString());
Expand Down
57 changes: 28 additions & 29 deletions src/test/java/io/github/avegera/predicate4j/WhereTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1899,7 +1899,7 @@ class ReturnTrueWhen {
@Test
@DisplayName("all two predicates are true")
void allPredicatesAreTrue() {
Address address = new Address("USA", null, null);
Address address = new Address("USA", null);
assertThat(predicateConjunction).accepts(address);
}
}
Expand All @@ -1917,21 +1917,21 @@ void objectIsNull() {
@Test
@DisplayName("first predicate is false")
void firstPredicateIsFalse() {
Address address = new Address("Ireland", null, null);
Address address = new Address("Ireland", null);
assertThat(predicateConjunction).rejects(address);
}

@Test
@DisplayName("second predicate is false")
void secondPredicateIsFalse() {
Address address = new Address("USA", null, 123);
Address address = new Address("USA", 123);
assertThat(predicateConjunction).rejects(address);
}

@Test
@DisplayName("both predicates are false")
void bothPredicatesAreFalse() {
Address address = new Address("Ireland", null, 123);
Address address = new Address("Ireland", 123);
assertThat(predicateConjunction).rejects(address);
}
}
Expand All @@ -1942,7 +1942,7 @@ void bothPredicatesAreFalse() {
class ThreePredicates {

private final Predicate<Address> predicateConjunction = where(Address::country).notNull()
.and(Address::value).notEqualTo("testValue")
.and().string(Address::state).startsWith("some")
.and(Address::zipCode).isInstanceOf(Integer.class);

@Nested
Expand All @@ -1952,7 +1952,7 @@ class ReturnTrueWhen {
@Test
@DisplayName("all predicates are true")
void allPredicatesAreTrue() {
Address address = new Address("USA", "someValue", 123);
Address address = new Address("USA", "someState", 123);
assertThat(predicateConjunction).accepts(address);
}
}
Expand All @@ -1977,28 +1977,28 @@ void firstPredicateIsFalse() {
@Test
@DisplayName("second predicate is false")
void secondPredicateIsFalse() {
Address address = new Address("USA", "testValue", 123);
Address address = new Address("USA", "testState", 123);
assertThat(predicateConjunction).rejects(address);
}

@Test
@DisplayName("third predicate is false")
void thirdPredicateIsFalse() {
Address address = new Address("USA", "someValue", null);
Address address = new Address("USA", "someState", null);
assertThat(predicateConjunction).rejects(address);
}

@Test
@DisplayName("two predicates are false")
void twoPredicatesAreFalse() {
Address address = new Address(null, "testValue", 123);
Address address = new Address(null, "testState", 123);
assertThat(predicateConjunction).rejects(address);
}

@Test
@DisplayName("all predicates are false")
void allPredicatesAreFalse() {
Address address = new Address(null, "testValue", null);
Address address = new Address(null, "testState", null);
assertThat(predicateConjunction).rejects(address);
}
}
Expand All @@ -2008,13 +2008,13 @@ void allPredicatesAreFalse() {
@DisplayName("7 predicates")
class SevenPredicates {

private final Predicate<Address> predicateConjunction = where(Address::country).notNull()
.and(Address::zipCode).notNull()
.and(Address::value).notNull()
.and(Address::country).notEqualTo("USA")
.and(Address::country).notEqualTo("Canada")
.and(Address::value).isEqualTo("testValue")
.and(Address::zipCode).isEqualTo(123);
private final Predicate<Address> predicateConjunction = where(Address::country).isEqualTo("USA")
.and(Address::state).notNull()
.and().string(Address::street).notStartsWith("str.")
.and().string(Address::building).notEqualTo("xyz")
.and(Address::zipCode).isEqualTo(123)
.and().list(Address::tenants).contains("Tenant1")
.and().booleanValue(Address::active).isTrue();

@Nested
@DisplayName("returns true when")
Expand All @@ -2023,8 +2023,7 @@ class ReturnTrueWhen {
@Test
@DisplayName("all predicates are true")
void mappedValueIsFalse() {
Address address = new Address("notCanadaAndUSA", "testValue", 123);
assertThat(predicateConjunction).accepts(address);
assertThat(predicateConjunction).accepts(new Address("USA", "testValue", "someStreet", "abc", 123, asList("Tenant1", "Tenant2"), true));
}
}

Expand All @@ -2041,70 +2040,70 @@ void objectIsNull() {
@Test
@DisplayName("first predicate is false")
void firstPredicateIsFalse() {
Address address = new Address(null, "testValue", 123);
Address address = new Address("Canada", "testValue", "someStreet", "abc", 123, asList("Tenant1", "Tenant2"), true);
assertThat(predicateConjunction).rejects(address);
}

@Test
@DisplayName("second predicate is false")
void secondPredicateIsFalse() {
Address address = new Address("notCanadaAndUSA", null, 123);
Address address = new Address("USA", null, "someStreet", "abc", 123, asList("Tenant1", "Tenant2"), true);
assertThat(predicateConjunction).rejects(address);
}

@Test
@DisplayName("third predicate is false")
void thirdPredicateIsFalse() {
Address address = new Address("notCanadaAndUSA", "testValue", null);
Address address = new Address("USA", "testValue", "str. Some Street", "abc", 123, asList("Tenant1", "Tenant2"), true);
assertThat(predicateConjunction).rejects(address);
}

@Test
@DisplayName("fourth predicate is false")
void fourthPredicateIsFalse() {
Address address = new Address("USA", "testValue", 123);
Address address = new Address("USA", "testValue", "someStreet", "xyz", 123, asList("Tenant1", "Tenant2"), true);
assertThat(predicateConjunction).rejects(address);
}

@Test
@DisplayName("fifth predicate is false")
void fifthPredicateIsFalse() {
Address address = new Address("Canada", "testValue", 123);
Address address = new Address("USA", "testValue", "someStreet", "abc", 456, asList("Tenant1", "Tenant2"), true);
assertThat(predicateConjunction).rejects(address);
}

@Test
@DisplayName("sixth predicate is false")
void sixthPredicateIsFalse() {
Address address = new Address("notCanadaAndUSA", "anotherValue", 123);
Address address = new Address("USA", "testValue", "someStreet", "abc", 123, asList("Tenant2", "Tenant3", "Tenant4"), true);
assertThat(predicateConjunction).rejects(address);
}

@Test
@DisplayName("seventh predicate is false")
void seventhPredicateIsFalse() {
Address address = new Address("notCanadaAndUSA", "testValue", 456);
Address address = new Address("USA", "testValue", "someStreet", "abc", 123, asList("Tenant1", "Tenant2"), false);
assertThat(predicateConjunction).rejects(address);
}

@Test
@DisplayName("three predicates are false")
void threePredicatesAreFalse() {
Address address = new Address("USA", "anotherValue", 456);
Address address = new Address("USA", "testValue", "str. Some Street", "xyz", null, asList("Tenant1", "Tenant2"), true);
assertThat(predicateConjunction).rejects(address);
}

@Test
@DisplayName("four predicates are false")
void fourPredicatesAreFalse() {
Address address = new Address("USA", "anotherValue", null);
Address address = new Address("Canada", null, "someStreet", "abc", 123, asList("Tenant2", "Tenant3"), false);
assertThat(predicateConjunction).rejects(address);
}

@Test
@DisplayName("all predicates are false")
void allPredicatesAreFalse() {
Address address = new Address(null, null, null);
Address address = new Address("USA", "testValue", "someStreet", "abc", 123, asList("Tenant1", "Tenant2"), null);
assertThat(predicateConjunction).rejects(address);
}
}
Expand Down
57 changes: 50 additions & 7 deletions src/test/java/io/github/avegera/predicate4j/test/Address.java
Original file line number Diff line number Diff line change
@@ -1,32 +1,75 @@
package io.github.avegera.predicate4j.test;

import java.util.List;

public class Address {

private final String country;
private final String value;
private final String state;
private final String street;
private final String building;
private final Integer zipCode;
private final Boolean active;
private final List<String> tenants;

public Address(String country, Integer zipCode) {
this(country, null, null, null, zipCode, null, null);
}

public Address(String country, String value, Integer zipCode) {
public Address(String country, String state, Integer zipCode) {
this(country, state, null, null, zipCode, null, null);
}

public Address(String country, String state, String street, String building, Integer zipCode, List<String> tenants, Boolean active) {
this.country = country;
this.value = value;
this.street = street;
this.state = state;
this.building = building;
this.zipCode = zipCode;
this.tenants = tenants;
this.active = active;
}

public String country() {
return country;
}

public String value() {
return value;
public String state() {
return state;
}

public String street() {
return street;
}

public String building() {
return building;
}

public Integer zipCode() {
return zipCode;
}

public Boolean active() {
return active;
}

public List<String> tenants() {
return tenants;
}

@Override
public String toString() {
return String.format("Address(country=%s, value=%s, zipCode=%s)", getValue(country), getValue(value), getValue(zipCode));
return String.format(
"Address(country=%s, state=%s, street=%s, building=%s, zipCode=%s, active=%s, tenants=%s)",
getValue(country),
getValue(state),
getValue(street),
getValue(building),
getValue(zipCode),
getValue(active),
getValue(tenants)
);
}

private String getValue(Object object) {
Expand All @@ -35,4 +78,4 @@ private String getValue(Object object) {
}
return object instanceof String ? "\"" + object + "\"" : object.toString();
}
}
}