Skip to content

Commit

Permalink
Criteria. Some lambda expressions are working for ANY / NONE / ALL on…
Browse files Browse the repository at this point in the history
… collection
  • Loading branch information
asereda-gs committed May 23, 2019
1 parent fcdbd00 commit 1a25f5c
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 23 deletions.
Expand Up @@ -18,43 +18,57 @@ public CollectionCriteria(CriteriaContext<R> context, CriteriaCreator<S> inner,
}

public S all() {
throw new UnsupportedOperationException();
final UnaryOperator<Expression> expr = e -> Expressions.call(Operators.ALL, e);
return inner.create((CriteriaContext<S>) context.create(expr));
}

public R all(UnaryOperator<C> consumer) {
throw new UnsupportedOperationException();
final UnaryOperator<Expression> expr = e -> Expressions.call(Operators.ALL, toExpressionOperator(consumer).apply(e));
return context.create(expr);
}

public S none() {
throw new UnsupportedOperationException();
final UnaryOperator<Expression> expr = e -> Expressions.call(Operators.NONE, e);
return inner.create((CriteriaContext<S>) context.create(expr));
}

public R none(UnaryOperator<C> consumer) {
throw new UnsupportedOperationException();
final UnaryOperator<Expression> expr = e -> Expressions.call(Operators.NONE, toExpressionOperator(consumer).apply(e));
return context.create(expr);
}

public S any() {
throw new UnsupportedOperationException();
final UnaryOperator<Expression> expr = e -> Expressions.call(Operators.ANY, e);
return inner.create((CriteriaContext<S>) context.create(expr));
}

public R any(UnaryOperator<C> consumer) {
throw new UnsupportedOperationException();
final UnaryOperator<Expression> expr = e -> Expressions.call(Operators.ANY, toExpressionOperator(consumer).apply(e));
return context.create(expr);
}

public S at(int index) {
throw new UnsupportedOperationException();
}

public R isEmpty() {
throw new UnsupportedOperationException();
return context.create(e -> Expressions.call(Operators.EMPTY, e));
}

public R isNotEmpty() {
throw new UnsupportedOperationException();
return context.create(e -> Expressions.not(Expressions.call(Operators.EMPTY, e)));
}

public R hasSize(int size) {
throw new UnsupportedOperationException();
return context.create(e -> Expressions.call(Operators.SIZE, e, Expressions.literal(size)));
}

private UnaryOperator<Expression> toExpressionOperator(UnaryOperator<C> operator) {
return expression -> {
final C initial = context.withCreator(outer).create();
final C changed = operator.apply(initial);
return Expressions.extract(changed);
};
}

public static class Self extends CollectionCriteria<Self, Self, Self> {
Expand Down
Expand Up @@ -158,8 +158,12 @@ public static Expression dnf(Operator operator, Expression existing, Expression
return operator == Operators.AND ? conjunction.and(newExpression) : conjunction.or(newExpression);
}

public static Call call(final Operator operator, Expression ... operands) {
return call(operator, Arrays.asList(operands));
public static Call not(Call call) {
return Expressions.call(Operators.NOT, call);
}

public static Call call(final Operator operator, Expression ... operands) {
return call(operator, ImmutableList.copyOf(operands));
}

public static Call call(final Operator operator, final Iterable<? extends Expression> operands) {
Expand Down
Expand Up @@ -5,8 +5,14 @@ public enum Operators implements Operator {
EQUAL,
NOT_EQUAL,

// collection
IN,
NOT_IN,
ALL, // all elements match
NONE, // no elements match
ANY, // some elements match (at least one)
EMPTY, // means collection is empty
SIZE, // size of the collection

// boolean ops
AND,
Expand Down
@@ -0,0 +1,38 @@
package org.immutables.criteria;

import org.immutables.criteria.constraints.DebugExpressionVisitor;
import org.immutables.criteria.constraints.Expressional;
import org.junit.Assert;
import org.junit.Test;

import java.io.PrintWriter;
import java.io.StringWriter;

/**
* Tests that expression is built correctly by "serializing" it to string
*/
public class ExpressionAsStringTest {

@Test
public void string() {
PersonCriteria<PersonCriteria.Self> crit = PersonCriteria.create();

assertExpressional(crit.lastName.isPresent(), "call op=IS_PRESENT path=lastName");
assertExpressional(crit.lastName.isAbsent(), "call op=IS_ABSENT path=lastName");
assertExpressional(crit.lastName.value().isEqualTo("aaa"), "call op=EQUAL path=lastName literal=aaa");
assertExpressional(crit.lastName.value(f -> f.isEqualTo("bbb")), "call op=EQUAL path=lastName literal=bbb");
assertExpressional(crit.firstName.isIn("n1", "n2"), "call op=IN path=firstName literal=[n1, n2]");

assertExpressional(crit.firstName.isEqualTo("John").or().firstName.isEqualTo("Marry"),
"call op=OR\n" +
" call op=EQUAL path=firstName literal=John\n" +
" call op=EQUAL path=firstName literal=Marry");
}

private static void assertExpressional(Expressional<?> expressional, String expected) {
final StringWriter out = new StringWriter();
expressional.expression().accept(new DebugExpressionVisitor<>(new PrintWriter(out)));
Assert.assertEquals(out.toString().trim(), expected);
}

}
18 changes: 6 additions & 12 deletions criteria/common/test/org/immutables/criteria/PersonTest.java
@@ -1,7 +1,6 @@
package org.immutables.criteria;

import org.immutables.criteria.constraints.DebugExpressionVisitor;
import org.immutables.criteria.constraints.StringCriteria;
import org.junit.Ignore;
import org.junit.Test;

Expand Down Expand Up @@ -79,21 +78,16 @@ public void empty() {
public void collection() {
PersonCriteria.create()
.friends.any().nickName.isNotEmpty()
.aliases.none().contains("foo")
.or()//.or() should not work
.isMarried.isTrue()
.or()
.friends.all().nickName.isNotEmpty()
.friends.any().nickName.isEmpty()
.friends.none().nickName.hasSize(3)
.friends.all(f -> f.nickName.isEmpty().or().nickName.hasSize(2))
.friends.any(f -> f.nickName.isEmpty().or().nickName.hasSize(2))
.friends.none(f -> f.nickName.hasSize(3).nickName.startsWith("a"))
.aliases.none().contains("foo")
.or()
.lastName.value().isNotEmpty()
.lastName.value().hasSize(2)
.lastName.value(f -> f.startsWith("foo").endsWith("bar"))
.lastName.value(f -> f.startsWith("foo").or().endsWith("bar"))
.lastName.value(f -> f.isNotEmpty().isGreaterThan("aaa"))
.lastName.value(StringCriteria::isNotEmpty)
.firstName.hasSize(2)
.bestFriend.nickName.startsWith("foo");
.friends.none(f -> f.nickName.hasSize(3).nickName.startsWith("a"));
}

@Test
Expand Down

0 comments on commit 1a25f5c

Please sign in to comment.