Refactor tests, move some internal expression tests to ebean-core

This commit is contained in:
Rob Bygrave
2022-03-27 19:55:34 +13:00
parent 28088a5e54
commit e3e5414157
37 changed files with 221 additions and 97 deletions
@@ -0,0 +1,114 @@
package io.ebeaninternal.server.expression;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.LinkedHashMap;
import java.util.Map;
public class AllEqualsExpressionTest extends BaseExpressionTest {
@Test
public void isSameByPlan_when_same() {
same(exp("a", 10), exp("a", 10));
}
@Test
public void isSameByBind_when_sameMultiple() {
Assertions.assertThat(exp("a", 10, "b", "23").isSameByBind(exp("a", 10, "b", "23"))).isTrue();
}
@Test
public void isSameByPlan_when_diffBindValue() {
same(exp("a", 10), exp("a", 20));
}
@Test
public void isSameByPlan_when_multiple() {
same(exp("a", 10, "b", 20, "c", 30), exp("a", 10, "b", 20, "c", 30));
}
@Test
public void isSameByPlan_when_less() {
different(exp("a", 10, "b", 20, "c", 30), exp("a", 10, "b", 20));
}
@Test
public void isSameByPlan_when_more() {
different(exp("a", 10, "b", 20), exp("a", 10, "b", 20, "c", 30));
}
@Test
public void isSameByPlan_when_diffProperty_diff() {
different(exp("a", 10), exp("b", 10));
}
@Test
public void isSameByPlan_when_diffType_diff() {
different(exp("a", 10), new NoopExpression());
}
@Test
public void isSameByPlan_when_diffBindByNull_last() {
different(exp("a", 10), exp("a", null));
}
@Test
public void isSameByPlan_when_diffBindByNull_first() {
different(exp("a", null), exp("a", 10));
}
@Test
public void isSameByPlan_when_differentExpressionType() {
different(exp("a", null), new NoopExpression());
}
@Test
public void isSameByBind_when_diffBindByNull_last() {
Assertions.assertThat(exp("a", 10).isSameByBind(exp("a", null))).isFalse();
}
@Test
public void isSameByBind_when_diffBindByNull_first() {
Assertions.assertThat(exp("a", null).isSameByBind(exp("a", 10))).isFalse();
}
private AllEqualsExpression exp(Map<String, Object> propMap) {
return new AllEqualsExpression(propMap);
}
AllEqualsExpression exp(String key0, Object val1) {
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
map.put(key0, val1);
return exp(map);
}
AllEqualsExpression exp(String key0, Object val1, String key2, Object val2) {
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
map.put(key0, val1);
map.put(key2, val2);
return exp(map);
}
AllEqualsExpression exp(String key0, Object val1, String key2, Object val2, String key3, Object val3) {
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
map.put(key0, val1);
map.put(key2, val2);
map.put(key3, val3);
return exp(map);
}
}
@@ -0,0 +1,94 @@
package io.ebeaninternal.server.expression;
import io.ebean.EbeanServer;
import io.ebean.Query;
import io.ebean.Transaction;
import io.ebean.event.BeanQueryRequest;
import io.ebeaninternal.api.SpiExpression;
import io.ebeaninternal.server.deploy.BaseTest;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import org.tests.model.basic.Customer;
import org.tests.model.basic.Order;
import static org.assertj.core.api.Assertions.assertThat;
public abstract class BaseExpressionTest extends BaseTest {
protected DefaultExpressionRequest newExpressionRequest() {
BeanDescriptor<Order> desc = getBeanDescriptor(Order.class);
return new DefaultExpressionRequest(desc);
}
protected String hash(SpiExpression expression) {
StringBuilder sb = new StringBuilder();
if (expression != null) {
expression.queryPlanHash(sb);
}
return sb.toString();
}
protected void same(SpiExpression one, SpiExpression two) {
assertThat(hash(one)).isEqualTo(hash(two));
}
protected void different(SpiExpression one, SpiExpression two) {
assertThat(hash(one)).isNotEqualTo(hash(two));
}
/**
* Request with Multi-Value support.
*/
protected InExpressionTest.TDQueryRequest<Customer> multi() {
return MULTI_VALUE;
}
/**
* Request with NO Multi-Value support.
*/
protected InExpressionTest.TDQueryRequest<Customer> noMulti() {
return NO_MULTI_VALUE;
}
private static final TDQueryRequest<Customer> MULTI_VALUE = new TDQueryRequest<>(true);
private static final TDQueryRequest<Customer> NO_MULTI_VALUE = new TDQueryRequest<>(false);
static class TDQueryRequest<T> implements BeanQueryRequest<T> {
final boolean supported;
TDQueryRequest(boolean supported) {
this.supported = supported;
}
@Override
public EbeanServer getEbeanServer() {
return null;
}
@Override
public Transaction transaction() {
return null;
}
@Override
public Query<T> query() {
return null;
}
@Override
public boolean isPadInExpression() {
return supported;
}
@Override
public boolean isMultiValueIdSupported() {
return supported;
}
@Override
public boolean isMultiValueSupported(Class<?> valueType) {
return supported;
}
}
}
@@ -0,0 +1,69 @@
package io.ebeaninternal.server.expression;
import io.ebeaninternal.api.SpiExpression;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class BetweenExpressionTest extends BaseExpressionTest {
@Test
public void addSql() {
DefaultExpressionRequest expReq = newExpressionRequest();
BetweenExpression exp = new BetweenExpression("startDate", 1, 2);
exp.addSql(expReq);
assertThat(expReq.getSql()).isEqualTo("startDate between ? and ?");
}
@Test
public void copyForPlanKey_isSameInstance() {
BetweenExpression exp = new BetweenExpression("startDate", 1, 2);
SpiExpression other = exp.copyForPlanKey();
assertThat(exp).isSameAs(other);
}
@Test
public void isSameByPlan_when_properties_match() {
BetweenExpression exp0 = new BetweenExpression("startDate", 1, 2);
BetweenExpression exp1 = new BetweenExpression("startDate", 3, 4);
same(exp0, exp1);
same(exp1, exp0);
}
@Test
public void isSameByPlan_when_properties_do_not_match() {
BetweenExpression exp0 = new BetweenExpression("startDate", 1, 2);
BetweenExpression exp1 = new BetweenExpression("endDate", 1, 2);
different(exp0, exp1);
different(exp1, exp0);
}
@Test
public void isSameByBind_when_values_do_not_match() {
BetweenExpression exp0 = new BetweenExpression("startDate", 1, 2);
BetweenExpression exp1 = new BetweenExpression("startDate", 1, 3);
assertThat(exp0.isSameByBind(exp1)).isFalse();
assertThat(exp1.isSameByBind(exp0)).isFalse();
}
@Test
public void isSameByBind_when_values_match() {
BetweenExpression exp0 = new BetweenExpression("startDate", 1, 2);
BetweenExpression exp1 = new BetweenExpression("startDate", 1, 2);
assertThat(exp0.isSameByBind(exp1)).isTrue();
assertThat(exp1.isSameByBind(exp0)).isTrue();
}
}
@@ -0,0 +1,51 @@
package io.ebeaninternal.server.expression;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class BetweenPropertyExpressionTest extends BaseExpressionTest {
private BetweenPropertyExpression exp(String lowProperty, String highProperty, Object value) {
return new BetweenPropertyExpression(lowProperty, highProperty, value);
}
@Test
public void sqlExpression() {
TDSpiExpressionRequest request = new TDSpiExpressionRequest(null);
exp("a", "b", 10).addSql(request);
Assertions.assertThat(request.getSql()).isEqualTo(" ? between a and b");
}
@Test
public void isSameByPlan_when_same() {
same(exp("a", "b", 10), exp("a", "b", 10));
}
@Test
public void isSameByPlan_when_diffValue() {
same(exp("a", "b", 10), exp("a", "b", 20));
}
@Test
public void isSameByPlan_when_diffProperty() {
different(exp("a", "b", 10), exp("a", "c", 10));
}
@Test
public void isSameByPlan_when_diffExpressionType() {
different(exp("a", "b", 10), new NoopExpression());
}
@Test
public void isSameByBind_when_same() {
assertThat(exp("a", "b", 10).isSameByBind(exp("a", "b", 10))).isTrue();
}
@Test
public void isSameByBind_when_diff() {
assertThat(exp("a", "b", 10).isSameByBind(exp("a", "b", 20))).isFalse();
}
}
@@ -0,0 +1,50 @@
package io.ebeaninternal.server.expression;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class CaseInsensitiveEqualExpressionTest extends BaseExpressionTest {
CaseInsensitiveEqualExpression exp(String propName, String value) {
return new CaseInsensitiveEqualExpression(propName, value, false);
}
@Test
public void isSameByPlan_when_same() {
same(exp("a", "10"), exp("a", "10"));
}
@Test
public void isSameByPlan_when_diffBind_same() {
same(exp("a", "10"), exp("a", "20"));
}
@Test
public void isSameByPlan_when_diffProperty_diff() {
different(exp("a", "10"), exp("b", "10"));
}
@Test
public void isSameByPlan_when_diffType_diff() {
different(exp("a", "10"), new NoopExpression());
}
@Test
public void isSameByBind_when_sameBindValues() {
assertThat(exp("a", "10").isSameByBind(exp("b", "10"))).isTrue();
}
@Test
public void isSameByBind_when_diffBindValues() {
assertThat(exp("a", "10").isSameByBind(exp("b", "20"))).isFalse();
}
}
@@ -0,0 +1,104 @@
package io.ebeaninternal.server.expression;
import io.ebean.LikeType;
import io.ebean.bean.EntityBean;
import io.ebean.event.BeanQueryRequest;
import io.ebeaninternal.api.ManyWhereJoins;
import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.server.core.OrmQueryRequest;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.tests.model.basic.Address;
import org.tests.model.basic.Customer;
public class DefaultExampleExpressionTest extends BaseExpressionTest {
Customer customer() {
Address address = new Address();
address.setCity("billingAddress.city");
Customer customer = new Customer();
customer.setName("name");
customer.setBillingAddress(address);
return customer;
}
DefaultExampleExpression exp() {
Customer customer = customer();
return new DefaultExampleExpression((EntityBean) customer, false, LikeType.EQUAL_TO);
}
DefaultExampleExpression expExtra() {
Customer customer = customer();
customer.setSmallnote("smallNote");
return new DefaultExampleExpression((EntityBean) customer, false, LikeType.EQUAL_TO);
}
DefaultExampleExpression expDiffName() {
Customer customer = customer();
customer.setName("otherName");
return new DefaultExampleExpression((EntityBean) customer, false, LikeType.EQUAL_TO);
}
BeanDescriptor<Customer> customerBeanDescriptor() {
return getBeanDescriptor(Customer.class);
}
DefaultExampleExpression prepare(DefaultExampleExpression expr) {
SpiQuery<Customer> query = (SpiQuery<Customer>) spiEbeanServer().find(Customer.class);
BeanQueryRequest<?> request = create(query);
expr.containsMany(customerBeanDescriptor(), new ManyWhereJoins());
expr.prepareExpression(request);
return expr;
}
@Test
public void test() {
DefaultExampleExpression expr = exp();
prepare(expr);
StringBuilder builder = new StringBuilder();
expr.queryPlanHash(builder);
TDSpiExpressionRequest req = new TDSpiExpressionRequest(customerBeanDescriptor());
expr.addBindValues(req);
Assertions.assertThat(req.bindValues).contains("name", "billingAddress.city");
}
private <T> OrmQueryRequest<T> create(SpiQuery<T> query) {
return new OrmQueryRequest<>(null, null, query, null);
}
@Test
public void isSameByPlan_whenSame() {
same(prepare(exp()), prepare(exp()));
}
@Test
public void isSameByPlan_when_diffBindValue_stillSame() {
same(prepare(exp()), prepare(expDiffName()));
}
@Test
public void isSameByPlan_when_extraExpression_then_different() {
different(prepare(exp()), prepare(expExtra()));
}
@Test
public void isSameByPlan_when_lessExpression_then_different() {
different(prepare(expExtra()), prepare(exp()));
}
}
@@ -0,0 +1,93 @@
package io.ebeaninternal.server.expression;
import io.ebean.Expression;
import io.ebeaninternal.api.SpiExpression;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class DefaultExpressionFactoryTest {
private String toQueryPlanHash(Expression expression) {
StringBuilder sb = new StringBuilder();
((SpiExpression) expression).queryPlanHash(sb);
return sb.toString();
}
@Test
public void testLowerILike() {
DefaultExpressionFactory factory = new DefaultExpressionFactory(false, false);
Expression expression = factory.ilike("name", "foo");
assertThat(expression).isInstanceOf(LikeExpression.class);
}
@Test
public void testNativeILike() {
DefaultExpressionFactory factory = new DefaultExpressionFactory(false, true);
Expression expression = factory.ilike("name", "foo");
assertThat(expression).isInstanceOf(NativeILikeExpression.class);
}
@Test
public void testEq() {
DefaultExpressionFactory factory = new DefaultExpressionFactory(false, false);
Expression expression = factory.eq("name", null);
assertThat(expression).isInstanceOf(NullExpression.class);
assertThat(toQueryPlanHash(expression)).isEqualTo("Null[name]");
}
@Test
public void testNe() {
DefaultExpressionFactory factory = new DefaultExpressionFactory(false, false);
Expression expression = factory.ne("name", null);
assertThat(expression).isInstanceOf(NullExpression.class);
assertThat(toQueryPlanHash(expression)).isEqualTo("NotNull[name]");
}
@Test
public void testIeq() {
DefaultExpressionFactory factory = new DefaultExpressionFactory(false, false);
Expression expression = factory.ieq("name", null);
assertThat(expression).isInstanceOf(NullExpression.class);
assertThat(toQueryPlanHash(expression)).isEqualTo("Null[name]");
}
@Test
public void testIne() {
DefaultExpressionFactory factory = new DefaultExpressionFactory(false, false);
Expression expression = factory.ine("name", null);
assertThat(expression).isInstanceOf(NullExpression.class);
assertThat(toQueryPlanHash(expression)).isEqualTo("NotNull[name]");
}
@Test
public void testEq_with_equalsWithNullAsNoop() {
DefaultExpressionFactory factory = new DefaultExpressionFactory(true, false);
Expression expression = factory.eq("name", null);
assertThat(expression).isInstanceOf(NoopExpression.class);
}
@Test
public void testNe_with_equalsWithNullAsNoop() {
DefaultExpressionFactory factory = new DefaultExpressionFactory(true, false);
Expression expression = factory.ne("name", null);
assertThat(expression).isInstanceOf(NoopExpression.class);
}
@Test
public void testIeq_with_equalsWithNullAsNoop() {
DefaultExpressionFactory factory = new DefaultExpressionFactory(true, false);
Expression expression = factory.ieq("name", null);
assertThat(expression).isInstanceOf(NoopExpression.class);
}
}
@@ -0,0 +1,98 @@
package io.ebeaninternal.server.expression;
import io.ebean.ExpressionList;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class DefaultExpressionListTest extends BaseExpressionTest {
DefaultExpressionList<?> exp() {
return new DefaultExpressionList<>(null, new DefaultExpressionFactory(true, true), null);
}
private <T> DefaultExpressionList<T> spi(ExpressionList<T> list) {
return (DefaultExpressionList<T>) list;
}
@Test
public void isSameByPlan_when_same() {
same(spi(exp().eq("a", 10).eq("b", 20))
,spi(exp().eq("a", 10).eq("b", 20)));
}
@Test
public void isSameByPlan_when_diffExpressionType() {
different(spi(exp().eq("a", 10).eq("b", 20))
,new NoopExpression());
}
@Test
public void isSameByPlan_when_less() {
different(spi(exp().eq("a", 10).eq("b", 20))
,spi(exp().eq("a", 10)));
}
@Test
public void isSameByPlan_when_lessEmptyLast() {
different(spi(exp().eq("a", 10).eq("b", 20))
,spi(exp()));
}
@Test
public void isSameByPlan_when_lessEmptyFirst() {
different(spi(exp())
,spi(exp().eq("a", 10)));
}
@Test
public void isSameByPlan_when_more() {
different(spi(exp().eq("a", 10).eq("b", 20))
,spi(exp().eq("a", 10).eq("b", 20).eq("c", 30)));
}
@Test
public void isSameByPlan_when_diffProperties() {
different(spi(exp().eq("a", 10).eq("b", 20))
,spi(exp().eq("c", 10).eq("b", 20)));
}
@Test
public void isSameByBind_when_same() {
assertThat(spi(exp().eq("a", 10).eq("b", 20))
.isSameByBind(spi(exp().eq("a", 10).eq("b", 20)))).isTrue();
}
@Test
public void isSameByBind_when_diffValues() {
assertThat(spi(exp().eq("a", 10).eq("b", 20))
.isSameByBind(spi(exp().eq("a", 10).eq("b", 30)))).isFalse();
}
@Test
public void isSameByBind_when_less() {
assertThat(spi(exp().eq("a", 10))
.isSameByBind(spi(exp().eq("a", 10).eq("b", 20)))).isFalse();
}
@Test
public void isSameByBind_when_more() {
assertThat(spi(exp().eq("a", 10))
.isSameByBind(spi(exp().eq("a", 10).eq("b", 20)))).isFalse();
}
}
@@ -0,0 +1,82 @@
package io.ebeaninternal.server.expression;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import static org.assertj.core.api.Assertions.assertThat;
public class ExistsQueryExpressionTest extends BaseExpressionTest {
private ExistsQueryExpression exp(boolean not, String sql, Object... bindValues) {
return new ExistsQueryExpression(not, sql, Arrays.asList(bindValues));
}
@Test
public void isSameByPlan_when_same() {
same(exp(true, "a", 10), exp(true, "a", 10));
}
@Test
public void isSameByPlan_when_diffBind_same() {
same(exp(true, "a", 10), exp(true, "a", 20));
}
@Test
public void isSameByPlan_when_diffNot() {
different(exp(true, "a", 10), exp(false, "a", 10));
}
@Test
public void isSameByPlan_when_diffSql() {
different(exp(true, "a", 10), exp(true, "b", 10));
}
@Test
public void isSameByBind_when_sameBindValues() {
same(exp(true, "a", 10), exp(true, "a", 10));
}
@Test
public void isSameByBind_when_sameMultipleBindValues() {
same(exp(true, "a", 10, "ABC", 20), exp(true, "a", 10, "ABC", 20));
}
@Test
public void isSameByBind_when_diffMultipleBindValues() {
assertThat(exp(true, "a", 10, "ABC", 20).isSameByBind(exp(true, "a", 10, "ABC", 21))).isFalse();
}
@Test
public void isSameByBind_when_diffMultipleBindValuesByOrder() {
assertThat(exp(true, "a", 10, "ABC", 20).isSameByBind(exp(true, "a", 10, 20, "ABC"))).isFalse();
}
@Test
public void isSameByBind_when_diffBindValues() {
assertThat(exp(true, "a", 10).isSameByBind(exp(true, "a", 20))).isFalse();
}
@Test
public void isSameByBind_when_lessBindValues() {
assertThat(exp(true, "a", 10, 20).isSameByBind(exp(true, "a", 20))).isFalse();
}
@Test
public void isSameByBind_when_moreBindValues() {
assertThat(exp(true, "a", 10).isSameByBind(exp(true, "a", 10, 20))).isFalse();
}
}
@@ -0,0 +1,39 @@
package io.ebeaninternal.server.expression;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class IdExpressionTest extends BaseExpressionTest {
private IdExpression exp(Object value) {
return new IdExpression(value);
}
@Test
public void isSameByPlan_when_same() {
same(exp(10), exp(10));
}
@Test
public void isSameByPlan_when_diffBind_same() {
same(exp(10), exp(20));
}
@Test
public void isSameByBind_when_sameBindValues() {
assertThat(exp(10).isSameByBind(exp(10))).isTrue();
}
@Test
public void isSameByBind_when_diffBindValues() {
assertThat(exp(10).isSameByBind(exp(20))).isFalse();
assertThat(exp(10).isSameByBind(exp("junk"))).isFalse();
}
}
@@ -0,0 +1,65 @@
package io.ebeaninternal.server.expression;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import static org.assertj.core.api.Assertions.assertThat;
public class IdInExpressionTest extends BaseExpressionTest {
private IdInExpression exp(Object... values) {
return new IdInExpression(Arrays.asList(values));
}
@Test
public void isSameByPlan_when_same() {
same(exp(10), exp(10));
}
@Test
public void isSameByPlan_when_diffBind_same() {
same(exp(10), exp(20));
}
@Test
public void isSameByPlan_when_diffBindCount_notPrepared() {
different(exp(10), exp(10, 20));
}
@Test
public void isSameByBind_when_sameBindValues() {
assertThat(exp(10).isSameByBind(exp(10))).isTrue();
}
@Test
public void isSameByBind_when_mulitpleSameBindValues() {
assertThat(exp(10, "ABC", 20).isSameByBind(exp(10, "ABC", 20))).isTrue();
}
@Test
public void isSameByBind_when_diffBindValues() {
assertThat(exp(10).isSameByBind(exp("junk"))).isFalse();
}
@Test
public void isSameByBind_when_lessBindValues() {
assertThat(exp(10, "ABC", 20).isSameByBind(exp(10, "ABC"))).isFalse();
}
@Test
public void isSameByBind_when_moreBindValues() {
assertThat(exp(10, "ABC").isSameByBind(exp(10, "ABC", 30))).isFalse();
}
}
@@ -0,0 +1,185 @@
package io.ebeaninternal.server.expression;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class InExpressionTest extends BaseExpressionTest {
@Test
public void queryPlanHash_given_diffEmpty_should_differentPlanHash() {
List<Integer> emptyValues = values();
InExpression ex1 = new InExpression("foo", emptyValues, false, true);
InExpression ex2 = new InExpression("foo", emptyValues, false);
InExpression ex3 = new InExpression("foo", emptyValues, false, true);
InExpression ex4 = new InExpression("foo", null, false, true);
ex1.prepareExpression(multi());
ex2.prepareExpression(multi());
different(ex1, ex2);
same(ex1, ex3); // same empty
same(ex1, ex4); // same null
}
@Test
public void queryPlanHash_given_diffPropertyName_should_differentPlanHash() {
List<Integer> values = values(42, 92);
InExpression ex1 = new InExpression("foo", values, false);
InExpression ex2 = new InExpression("bar", values, false);
ex1.prepareExpression(multi());
ex2.prepareExpression(multi());
different(ex1, ex2);
}
@Test
public void queryPlanHash_given_diffBindCount_should_differentPlanHash() {
List<Integer> values1 = values(42, 92);
List<Integer> values2 = values(42, 92, 82);
InExpression ex1 = new InExpression("foo", values1, false);
InExpression ex2 = new InExpression("foo", values2, false);
ex1.prepareExpression(noMulti());
ex2.prepareExpression(noMulti());
different(ex1, ex2);
}
@Test
public void queryPlanHash_given_diffBindCount_withMultiSupport_samePlanHash() {
List<Integer> values1 = values(42, 92);
List<Integer> values2 = values(42, 92, 82);
InExpression ex1 = new InExpression("foo", values1, false);
InExpression ex2 = new InExpression("foo", values2, false);
ex1.prepareExpression(multi());
ex2.prepareExpression(multi());
same(ex1, ex2);
}
@Test
public void queryPlanHash_given_diffNotFlag_should_differentPlanHash() {
List<Integer> values = values(42, 92);
InExpression ex1 = new InExpression("foo", values, true);
InExpression ex2 = new InExpression("foo", values, false);
ex1.prepareExpression(multi());
ex2.prepareExpression(multi());
different(ex1, ex2);
}
@Test
public void queryPlanHash_given_sameNotFlag_should_samePlanHash() {
List<Integer> values = values(42, 92);
InExpression ex1 = new InExpression("foo", values, true);
InExpression ex2 = new InExpression("foo", values, true);
ex1.prepareExpression(multi());
ex2.prepareExpression(multi());
same(ex1, ex2);
}
private List<Integer> values(int... vals) {
ArrayList<Integer> list = new ArrayList<>();
for (int val : vals) {
list.add(val);
}
return list;
}
private InExpression exp(String propName, boolean not, Object... values) {
InExpression ex = new InExpression(propName, Arrays.asList(values), not);
ex.prepareExpression(multi());
return ex;
}
private InExpression expNoMulti(String propName, boolean not, Object... values) {
InExpression ex = new InExpression(propName, Arrays.asList(values), not);
ex.prepareExpression(noMulti());
return ex;
}
@Test
public void isSameByPlan_when_same() {
same(exp("a", false, 10), exp("a", false, 10));
}
@Test
public void isSameByPlan_when_diffPropertyName() {
different(exp("a", false, 10), exp("b", false, 10));
}
@Test
public void isSameByPlan_when_diffNot() {
different(exp("a", false, 10), exp("a", true, 10));
}
@Test
public void isSameByPlan_when_diffBind_same() {
same(exp("a", false, 10), exp("a", false, 10, 20));
different(expNoMulti("a", false, 10), expNoMulti("a", false, 10, 20));
}
@Test
public void isSameByPlan_when_diffBindCount() {
same(exp("a", false, 10), exp("a", false, 10, 20));
different(expNoMulti("a", false, 10), expNoMulti("a", false, 10, 20));
}
@Test
public void isSameByBind_when_sameBindValues() {
assertThat(exp("a", false, 10).isSameByBind(exp("a", false, 10))).isTrue();
}
@Test
public void isSameByBind_when_sameMultipleBindValues() {
assertThat(exp("a", false, 10, "ABC", 20).isSameByBind(exp("a", false, 10, "ABC", 20))).isTrue();
}
@Test
public void isSameByBind_when_diffBindValues() {
assertThat(exp("a", false, 10).isSameByBind(exp("a", false, "foo"))).isFalse();
}
@Test
public void isSameByBind_when_lessBindValues() {
assertThat(exp("a", false, 10, "ABC", 20).isSameByBind(exp("a", false, 10, "ABC"))).isFalse();
}
@Test
public void isSameByBind_when_moreBindValues() {
assertThat(exp("a", false, 10, "ABC").isSameByBind(exp("a", false, 10, "ABC", 30))).isFalse();
}
}
@@ -0,0 +1,92 @@
package io.ebeaninternal.server.expression;
import io.ebean.Pairs;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class InPairsExpressionTest extends BaseExpressionTest {
private Pairs pairs() {
return pairs("sku", "code");
}
private Pairs pairs(String property0, String property1) {
Pairs pairs = new Pairs(property0, property1)
.add("2", 1000)
.add("2", 1001)
.add("3", 1000);
return pairs;
}
@Test
public void same_samePlan_sameBind() throws Exception {
InPairsExpression e0 = new InPairsExpression(pairs(), false);
InPairsExpression e1 = new InPairsExpression(pairs(), false);
same(e0, e1);
assertTrue(e0.isSameByBind(e1));
}
@Test
public void same_samePlan_diffBind() throws Exception {
InPairsExpression e0 = new InPairsExpression(pairs(), false);
InPairsExpression e1 = new InPairsExpression(pairs().add("4", 1000), false);
e0.prepareExpression(multi());
e1.prepareExpression(multi());
// when multi() ... same as bind count not important
same(e0, e1);
assertFalse(e0.isSameByBind(e1));
}
@Test
public void same_noMulti_diffPlan() throws Exception {
InPairsExpression e0 = new InPairsExpression(pairs(), false);
InPairsExpression e1 = new InPairsExpression(pairs().add("4", 1000), false);
e0.prepareExpression(noMulti());
e1.prepareExpression(noMulti());
// when noMulti() ... bind count different so different plan
different(e0, e1);
}
@Test
public void diffProperty0_diff() throws Exception {
InPairsExpression e0 = new InPairsExpression(pairs(), false);
InPairsExpression e1 = new InPairsExpression(pairs("k", "code"), false);
different(e0, e1);
}
@Test
public void diffProperty1_diff() throws Exception {
InPairsExpression e0 = new InPairsExpression(pairs(), false);
InPairsExpression e1 = new InPairsExpression(pairs("sku", "c"), false);
different(e0, e1);
}
@Test
public void diffSeparator_diff() throws Exception {
InPairsExpression e0 = new InPairsExpression(pairs(), false);
InPairsExpression e1 = new InPairsExpression(pairs().concatSeparator(":"), false);
different(e0, e1);
}
@Test
public void diffSuffix_diff() throws Exception {
InPairsExpression e0 = new InPairsExpression(pairs(), false);
InPairsExpression e1 = new InPairsExpression(pairs().concatSuffix(":"), false);
different(e0, e1);
}
}
@@ -0,0 +1,87 @@
package io.ebeaninternal.server.expression;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import static org.assertj.core.api.Assertions.assertThat;
public class InQueryExpressionTest extends BaseExpressionTest {
private InQueryExpression exp(String propertyName, boolean not, String sql, Object... bindValues) {
return new InQueryExpression(propertyName, not, sql, Arrays.asList(bindValues));
}
@Test
public void isSameByPlan_when_same() {
same(exp("name", true, "sql", 10), exp("name", true, "sql", 10));
}
@Test
public void isSameByPlan_when_diffBind_same() {
same(exp("name", true, "sql", 10), exp("name", true, "sql", 20));
}
@Test
public void isSameByPlan_when_diffNPropertyName() {
different(exp("name", true, "sql", 10), exp("nameDiff", true, "sql", 10));
}
@Test
public void isSameByPlan_when_diffNot() {
different(exp("name", true, "sql", 10), exp("name", false, "sql", 10));
}
@Test
public void isSameByPlan_when_diffSql() {
different(exp("name", true, "sql", 10), exp("name", true, "sqlDiff", 10));
}
@Test
public void isSameByBind_when_sameBindValues() {
assertThat(exp("name", true, "sql", 10).isSameByBind(exp("name", true, "sql", 10))).isTrue();
}
@Test
public void isSameByBind_when_sameMultipleBindValues() {
assertThat(exp("name", true, "sql", 10, "ABC", 20).isSameByBind(exp("name", true, "sql", 10, "ABC", 20))).isTrue();
}
@Test
public void isSameByBind_when_diffMultipleBindValues() {
assertThat(exp("name", true, "sql", 10, "ABC", 20).isSameByBind(exp("name", true, "sql", 10, "ABC", 21))).isFalse();
}
@Test
public void isSameByBind_when_diffMultipleBindValuesByOrder() {
assertThat(exp("name", true, "sql", 10, "ABC", 20).isSameByBind(exp("name", true, "sql", 10, 20, "ABC"))).isFalse();
}
@Test
public void isSameByBind_when_diffBindValues() {
assertThat(exp("name", true, "sql", 10).isSameByBind(exp("name", true, "sql", 20))).isFalse();
}
@Test
public void isSameByBind_when_lessBindValues() {
assertThat(exp("name", true, "sql", 10, 20).isSameByBind(exp("name", true, "sql", 20))).isFalse();
}
@Test
public void isSameByBind_when_moreBindValues() {
assertThat(exp("name", true, "sql", 10).isSameByBind(exp("name", true, "sql", 10, 20))).isFalse();
}
}
@@ -0,0 +1,69 @@
package io.ebeaninternal.server.expression;
import io.ebeaninternal.api.SpiExpression;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class InRangeExpressionTest extends BaseExpressionTest {
@Test
public void addSql() {
DefaultExpressionRequest expReq = newExpressionRequest();
InRangeExpression exp = new InRangeExpression("startDate", 1, 2);
exp.addSql(expReq);
assertThat(expReq.getSql()).isEqualTo("(startDate >= ? and startDate < ?)");
}
@Test
public void copyForPlanKey_isSameInstance() {
InRangeExpression exp = new InRangeExpression("startDate", 1, 2);
SpiExpression other = exp.copyForPlanKey();
assertThat(exp).isSameAs(other);
}
@Test
public void isSameByPlan_when_properties_match() {
InRangeExpression exp0 = new InRangeExpression("startDate", 1, 2);
InRangeExpression exp1 = new InRangeExpression("startDate", 3, 4);
same(exp0, exp1);
same(exp1, exp0);
}
@Test
public void isSameByPlan_when_properties_do_not_match() {
InRangeExpression exp0 = new InRangeExpression("startDate", 1, 2);
InRangeExpression exp1 = new InRangeExpression("endDate", 1, 2);
different(exp0, exp1);
different(exp1, exp0);
}
@Test
public void isSameByBind_when_values_do_not_match() {
InRangeExpression exp0 = new InRangeExpression("startDate", 1, 2);
InRangeExpression exp1 = new InRangeExpression("startDate", 1, 3);
assertThat(exp0.isSameByBind(exp1)).isFalse();
assertThat(exp1.isSameByBind(exp0)).isFalse();
}
@Test
public void isSameByBind_when_values_match() {
InRangeExpression exp0 = new InRangeExpression("startDate", 1, 2);
InRangeExpression exp1 = new InRangeExpression("startDate", 1, 2);
assertThat(exp0.isSameByBind(exp1)).isTrue();
assertThat(exp1.isSameByBind(exp0)).isTrue();
}
}
@@ -0,0 +1,79 @@
package io.ebeaninternal.server.expression;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class JsonPathExpressionTest extends BaseExpressionTest {
private JsonPathExpression exp(String propertyName, String path, Op operator, Object value) {
return new JsonPathExpression(propertyName, path, operator, value);
}
@Test
public void isSameByPlan_when_same() {
same(exp("a", "path", Op.EQ, 10), exp("a", "path", Op.EQ, 10));
}
@Test
public void isSameByPlan_when_diffBind_same() {
same(exp("a", "path", Op.EQ, 10), exp("a", "path", Op.EQ, 20));
}
@Test
public void isSameByPlan_when_diffPath() {
different(exp("a", "path", Op.EQ, 10), exp("a", "pathDiff", Op.EQ, 10));
}
@Test
public void isSameByPlan_when_diffProperty_diff() {
different(exp("a", "path", Op.EQ, 10), exp("b", "path", Op.EQ, 10));
}
@Test
public void isSameByPlan_when_diffOperator_diff() {
different(exp("a", "path", Op.EQ, 10), exp("a", "path", Op.LT, 10));
}
@Test
public void isSameByPlan_when_diffType_diff() {
different(exp("a", "path", Op.EQ, 10), new NoopExpression());
}
@Test
public void isSameByBind_when_sameBindValues() {
assertThat(exp("a", "path", Op.EQ, 10).isSameByBind(exp("a", "path", Op.LT, 10))).isTrue();
}
@Test
public void isSameByBind_when_sameNullBindValues() {
assertThat(exp("a", "path", Op.EQ, null).isSameByBind(exp("a", "path", Op.LT, null))).isTrue();
}
@Test
public void isSameByBind_when_diffBindValues() {
assertThat(exp("a", "path", Op.EQ, 10).isSameByBind(exp("a", "path", Op.EQ, "junk"))).isFalse();
}
@Test
public void isSameByBind_when_diffFirstNullBindValues() {
assertThat(exp("a", "path", Op.EQ, null).isSameByBind(exp("a", "path", Op.LT, 10))).isFalse();
}
@Test
public void isSameByBind_when_diffLastNullBindValues() {
assertThat(exp("a", "path", Op.EQ, 10).isSameByBind(exp("a", "path", Op.LT, null))).isFalse();
}
}
@@ -0,0 +1,59 @@
package io.ebeaninternal.server.expression;
import io.ebean.Expr;
import io.ebean.Expression;
import io.ebean.Junction;
import org.junit.jupiter.api.Test;
public class JunctionExpressionTest extends BaseExpressionTest {
Expression eq(String propName, int value) {
return Expr.eq(propName, value);
}
DefaultExpressionList<?> exp(Expression... expressions) {
DefaultExpressionList<Object> list = new DefaultExpressionList<>(null, new DefaultExpressionFactory(true, false), null);
for (Expression ex : expressions) {
list.add(ex);
}
return list;
}
<T> JunctionExpression<T> and(DefaultExpressionList<T> list) {
return new JunctionExpression<>(Junction.Type.AND, list);
}
<T> JunctionExpression<T> or(DefaultExpressionList<T> list) {
return new JunctionExpression<>(Junction.Type.OR, list);
}
@Test
public void isSameByPlan_when_same() {
same(and(exp(eq("a", 10), eq("b", 10))),
and(exp(eq("a", 10), eq("b", 10))));
}
@Test
public void copyForPlanKey_isSameByPlan_when_same() {
same(and(exp(eq("a", 10), eq("b", 10)).copyForPlanKey()),
and(exp(eq("a", 10), eq("b", 10))));
}
@Test
public void copyForPlanKey_isSameByPlan_when_diff() {
different(and(exp(eq("a", 10), eq("b", 10)).copyForPlanKey()),
and(exp(eq("a", 10), eq("c", 10))));
}
@Test
public void isSameByPlan_when_diffType() {
different(and(exp(eq("a", 10), eq("b", 10))),
or(exp(eq("a", 10), eq("b", 10))));
}
}
@@ -0,0 +1,64 @@
package io.ebeaninternal.server.expression;
import io.ebean.LikeType;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class LikeExpressionTest extends BaseExpressionTest {
private LikeExpression exp(String propertyName, String value, boolean caseInsensitive, LikeType type) {
return new LikeExpression(propertyName, value, caseInsensitive, type);
}
@Test
public void isSameByPlan_when_same() {
same(exp("a", "rob", true, LikeType.STARTS_WITH)
, exp("a", "rob", true, LikeType.STARTS_WITH));
}
@Test
public void isSameByPlan_when_diffBind_then_stillSame() {
same(exp("a", "rob", true, LikeType.STARTS_WITH)
, exp("a", "bor", true, LikeType.STARTS_WITH));
}
@Test
public void isSameByPlan_when_diffCaseInsensitive() {
different(exp("a", "rob", true, LikeType.STARTS_WITH)
, exp("a", "rob", false, LikeType.STARTS_WITH));
}
@Test
public void isSameByPlan_when_diffLikeType() {
different(exp("a", "rob", true, LikeType.STARTS_WITH)
, exp("a", "rob", true, LikeType.ENDS_WITH));
}
@Test
public void isSameByPlan_when_diffProperty() {
different(exp("a", "rob", true, LikeType.STARTS_WITH)
, exp("b", "rob", true, LikeType.STARTS_WITH));
}
@Test
public void isSameByBind_when_sameBindValues() {
assertThat(exp("a", "rob", true, LikeType.STARTS_WITH)
.isSameByBind(exp("a", "rob", true, LikeType.STARTS_WITH))).isTrue();
}
@Test
public void isSameByBind_when_diffBindValues() {
assertThat(exp("a", "rob", true, LikeType.STARTS_WITH)
.isSameByBind(exp("a", "bor", true, LikeType.STARTS_WITH))).isFalse();
}
}
@@ -0,0 +1,140 @@
package io.ebeaninternal.server.expression;
import io.ebean.Expr;
import io.ebean.Expression;
import org.junit.jupiter.api.Test;
import org.tests.model.basic.Order;
import static org.assertj.core.api.Assertions.assertThat;
public class LogicExpressionTest extends BaseExpressionTest {
private Expression eq(String propName, int value) {
return Expr.eq(propName, value);
}
private LogicExpression and(Expression a, Expression b) {
return new LogicExpression.And(a, b);
}
private LogicExpression or(Expression a, Expression b) {
return new LogicExpression.Or(a, b);
}
@Test
public void addSql() {
DefaultExpressionRequest expReq = newExpressionRequest();
LogicExpression and = and(eq("a", 10), eq("b", 10));
and.addSql(expReq);
assertThat(expReq.getSql()).isEqualTo("(a = ? and b = ?)");
}
@Test
public void isSameByPlan_when_same() {
same(and(eq("a", 10), eq("b", 10))
, and(eq("a", 10), eq("b", 10)));
}
@Test
public void isSameByPlan_when_diffBind_then_stillSame() {
same(and(eq("a", 10), eq("b", 10))
, and(eq("a", 20), eq("b", 20)));
}
@Test
public void isSameByPlan_when_diffExp1_then_diff() {
different(and(eq("a", 10), eq("b", 10))
, and(eq("c", 10), eq("b", 10)));
}
@Test
public void isSameByPlan_when_diffExp2_then_diff() {
different(and(eq("a", 10), eq("b", 10))
, and(eq("a", 10), eq("c", 10)));
}
@Test
public void isSameByPlan_when_diffType_then_diff() {
different(or(eq("a", 10), eq("b", 10))
, and(eq("a", 10), eq("c", 10)));
}
@Test
public void isSameByPlan_when_diffExpressionType() {
different(or(eq("a", 10), eq("b", 10))
, new NoopExpression());
}
@Test
public void isSameByBind_when_sameBindValues() {
assertThat(and(eq("a", 10), eq("b", 10))
.isSameByBind(and(eq("a", 10), eq("c", 10)))).isTrue();
}
@Test
public void isSameByBind_when_diffBindValues() {
assertThat(and(eq("a", 10), eq("b", 10))
.isSameByBind(and(eq("a", 10), eq("c", 20)))).isFalse();
}
@Test
public void nestedPath_when_notNested() {
LogicExpression and = and(eq("orderDate", 10), eq("shipDate", 10));
and.nestedPath(getBeanDescriptor(Order.class));
assertThat(and.expOne).isInstanceOf(SimpleExpression.class);
assertThat(and.expTwo).isInstanceOf(SimpleExpression.class);
}
@Test
public void nestedPath_when_nestedSame() {
LogicExpression and = and(eq("details.orderQty", 10), eq("details.unitPrice", 10));
String path = and.nestedPath(getBeanDescriptor(Order.class));
assertThat(path).isEqualTo("details");
assertThat(and.expOne).isInstanceOf(SimpleExpression.class);
assertThat(and.expTwo).isInstanceOf(SimpleExpression.class);
}
@Test
public void nestedPath_when_nestedDifferent() {
LogicExpression and = and(eq("details.orderQty", 10), eq("shipments.shipTime", 10));
String path = and.nestedPath(getBeanDescriptor(Order.class));
assertThat(path).isNull();
assertThat(and.expOne).isInstanceOf(NestedPathWrapperExpression.class);
assertThat(((NestedPathWrapperExpression) and.expOne).nestedPath).isEqualTo("details");
assertThat(and.expTwo).isInstanceOf(NestedPathWrapperExpression.class);
assertThat(((NestedPathWrapperExpression) and.expTwo).nestedPath).isEqualTo("shipments");
}
@Test
public void nestedPath_when_oneNested() {
LogicExpression and = and(eq("details.orderQty", 10), eq("orderDate", 10));
String path = and.nestedPath(getBeanDescriptor(Order.class));
assertThat(path).isNull();
assertThat(and.expOne).isInstanceOf(NestedPathWrapperExpression.class);
assertThat(((NestedPathWrapperExpression) and.expOne).nestedPath).isEqualTo("details");
assertThat(and.expTwo).isInstanceOf(SimpleExpression.class);
}
}
@@ -0,0 +1,65 @@
package io.ebeaninternal.server.expression;
import io.ebean.DB;
import io.ebean.Query;
import org.junit.jupiter.api.Test;
import org.tests.model.basic.Customer;
import static org.assertj.core.api.Assertions.assertThat;
public class NoopExpressionTest extends BaseExpressionTest {
@Test
public void test() {
initTables();
Query<Customer> query = DB.find(Customer.class)
.select("id")
.where().add(NoopExpression.INSTANCE)
.query();
query.findList();
String generatedSql = query.getGeneratedSql();
assertThat(generatedSql).contains("select t0.id from o_customer t0 where 1=1");
}
@Test
public void test_withPreAndPost() {
initTables();
Query<Customer> query = DB.find(Customer.class)
.select("id")
.where().eq("name", null)
.add(NoopExpression.INSTANCE)
.ne("status", null)
.query();
query.findList();
String generatedSql = query.getGeneratedSql();
assertThat(generatedSql).contains("select t0.id from o_customer t0 where t0.name is null and 1=1 and t0.status is not null");
}
@Test
public void isSameByPlan_when_same() {
same(new NoopExpression(), new NoopExpression());
}
@Test
public void isSameByPlan_when_diffExpressionType() {
different(new NoopExpression(), null);
}
@Test
public void isSameByBind_when_same() {
assertThat(new NoopExpression().isSameByBind(new NoopExpression())).isTrue();
}
@Test
public void isSameByBind_when_diffExpressionType() {
assertThat(new NoopExpression().isSameByBind(null)).isTrue();
}
}
@@ -0,0 +1,54 @@
package io.ebeaninternal.server.expression;
import io.ebean.Expression;
import org.junit.jupiter.api.Test;
import static io.ebean.Expr.eq;
import static org.assertj.core.api.Assertions.assertThat;
public class NotExpressionTest extends BaseExpressionTest {
NotExpression not(Expression expression) {
return new NotExpression(expression);
}
@Test
public void isSameByPlan_when_same() {
same(not(eq("a", 10)), not(eq("a", 10)));
}
@Test
public void isSameByPlan_when_sameByPlan() {
same(not(eq("a", 10)), not(eq("a", 20)));
}
@Test
public void isSameByPlan_when_different() {
different(not(eq("a", 10)), not(eq("b", 10)));
}
@Test
public void isSameByPlan_when_differentExpressionType() {
different(not(eq("a", 10)), new NoopExpression());
}
@Test
public void isSameByBind_when_same() {
assertThat(not(eq("a", 10))
.isSameByBind(not(eq("b", 10)))).isTrue();
}
@Test
public void isSameByBind_when_different() {
assertThat(not(eq("a", 10))
.isSameByBind(not(eq("a", 20)))).isFalse();
}
}
@@ -0,0 +1,95 @@
package io.ebeaninternal.server.expression;
import io.ebeaninternal.api.ManyWhereJoins;
import io.ebeaninternal.api.SpiExpression;
import org.junit.jupiter.api.Test;
import org.tests.model.basic.Order;
import static org.assertj.core.api.Assertions.assertThat;
public class NullExpressionTest extends BaseExpressionTest {
private NullExpression nullExp(String propertyName, boolean notNull) {
NullExpression expr = new NullExpression(propertyName, notNull);
expr.containsMany(getBeanDescriptor(Order.class), new ManyWhereJoins());
return expr;
}
@Test
public void addSql_when_notNull() throws Exception {
DefaultExpressionRequest expReq = newExpressionRequest();
nullExp("id", true).addSql(expReq);
assertThat(expReq.getSql()).isEqualTo("id is not null");
}
@Test
public void addSql_when_null() throws Exception {
DefaultExpressionRequest expReq = newExpressionRequest();
nullExp("id", false).addSql(expReq);
assertThat(expReq.getSql()).isEqualTo("id is null");
}
@Test
public void addSql_when_notNull_and_assocOne() throws Exception {
DefaultExpressionRequest expReq = newExpressionRequest();
nullExp("customer", true).addSql(expReq);
assertThat(expReq.getSql()).isEqualTo("customer.id is not null");
}
@Test
public void addSql_when_null_and_assocOne() throws Exception {
DefaultExpressionRequest expReq = newExpressionRequest();
nullExp("customer", false).addSql(expReq);
assertThat(expReq.getSql()).isEqualTo("customer.id is null");
}
@Test
public void copyForPlanKey_isSameInstance() throws Exception {
NullExpression exp = nullExp("customer.name", false);
SpiExpression other = exp.copyForPlanKey();
assertThat(exp).isSameAs(other);
}
@Test
public void isSameByBind_true() throws Exception {
assertThat(nullExp("customer.name", false)
.isSameByBind(nullExp("customer.name", false))).isTrue();
}
@Test
public void isSameByPlan_true() throws Exception {
same(nullExp("customer.name", false),
nullExp("customer.name", false));
}
@Test
public void isSameByPlan_false_when_notNullDiff() throws Exception {
different(new NullExpression("customer.name", false),
new NullExpression("customer.name", true));
}
@Test
public void isSameByPlan_false_when_propertyNameDiff() throws Exception {
different(new NullExpression("customer.startDate", true),
new NullExpression("customer.name", true));
}
}
@@ -0,0 +1,148 @@
package io.ebeaninternal.server.expression;
import io.ebean.DB;
import io.ebean.ExpressionList;
import io.ebeaninternal.api.SpiExpression;
import io.ebeaninternal.server.deploy.BaseTest;
import org.junit.jupiter.api.Test;
import org.tests.model.basic.Order;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
public class PrepareDocNestedTest extends BaseTest {
@Test
public void prepare() throws Exception {
ExpressionList<Order> where = DB.find(Order.class)
.where()
.gt("details.orderQty", 1)
.query().where();
DefaultExpressionList<?> exp = (DefaultExpressionList<?>) where;
PrepareDocNested.prepare(exp, getBeanDescriptor(Order.class));
List<SpiExpression> underlyingList = exp.getUnderlyingList();
assertEquals(underlyingList.size(), 1);
assertEquals(exp.allDocNestedPath, "details");
}
@Test
public void prepare_when_multipleOfSamePath() throws Exception {
ExpressionList<Order> where = DB.find(Order.class)
.where()
.gt("details.orderQty", 1)
.gt("details.unitPrice", 1)
.query().where();
DefaultExpressionList<?> exp = (DefaultExpressionList<?>) where;
PrepareDocNested.prepare(exp, getBeanDescriptor(Order.class));
List<SpiExpression> underlyingList = exp.getUnderlyingList();
assertEquals(underlyingList.size(), 2);
assertEquals(exp.allDocNestedPath, "details");
}
@Test
public void prepare_when_mixed() throws Exception {
ExpressionList<Order> where = DB.find(Order.class)
.where()
.gt("customer.id", 1)
.gt("details.orderQty", 1)
.gt("details.unitPrice", 1)
.query().where();
DefaultExpressionList<?> exp = (DefaultExpressionList<?>) where;
PrepareDocNested.prepare(exp, getBeanDescriptor(Order.class));
List<SpiExpression> underlyingList = exp.getUnderlyingList();
assertEquals(underlyingList.size(), 2);
assertNull(exp.allDocNestedPath);
DefaultExpressionList<?> second = (DefaultExpressionList<?>) underlyingList.get(1);
assertEquals(second.allDocNestedPath, "details");
}
@Test
public void prepare_when_nestedJunction() throws Exception {
ExpressionList<Order> where = DB.find(Order.class)
.where()
.not()
.gt("customer.id", 1)
.gt("details.orderQty", 1)
.gt("details.unitPrice", 1)
.query().where();
DefaultExpressionList<?> exp = (DefaultExpressionList<?>) where;
PrepareDocNested.prepare(exp, getBeanDescriptor(Order.class));
List<SpiExpression> underlyingList = exp.getUnderlyingList();
assertEquals(underlyingList.size(), 1);
assertNull(exp.allDocNestedPath);
JunctionExpression<?> junction = (JunctionExpression<?>) underlyingList.get(0);
List<SpiExpression> junctionUnderlying = junction.exprList.getUnderlyingList();
JunctionExpression<?> nestedNestedPath = (JunctionExpression<?>) junctionUnderlying.get(1);
assertEquals(nestedNestedPath.exprList.allDocNestedPath, "details");
}
@Test
public void prepare_when_nestedMultiple() throws Exception {
ExpressionList<Order> where = DB.find(Order.class)
.where()
.isNotNull("shipments.shipTime")
.gt("details.orderQty", 1)
.gt("details.unitPrice", 1)
.query().where();
DefaultExpressionList<?> exp = (DefaultExpressionList<?>) where;
PrepareDocNested.prepare(exp, getBeanDescriptor(Order.class));
List<SpiExpression> underlyingList = exp.getUnderlyingList();
assertEquals(underlyingList.size(), 2);
assertNull(exp.allDocNestedPath);
DefaultExpressionList<?> shipExpr = (DefaultExpressionList<?>) underlyingList.get(0);
assertEquals(shipExpr.allDocNestedPath, "shipments");
DefaultExpressionList<?> detailsExpr = (DefaultExpressionList<?>) underlyingList.get(1);
assertEquals(detailsExpr.allDocNestedPath, "details");
}
@Test
public void prepare_when_manyMixed() throws Exception {
ExpressionList<Order> where = DB.find(Order.class)
.where()
.gt("customer.id", 1) // 0
.isNotNull("shipments.shipTime") // shipments 0
.isNotNull("status") // 1
.gt("details.orderQty", 1) // details 0
.isNotNull("orderDate") // 2
.gt("details.unitPrice", 1) // details 1
.query().where();
DefaultExpressionList<?> exp = (DefaultExpressionList<?>) where;
PrepareDocNested.prepare(exp, getBeanDescriptor(Order.class));
List<SpiExpression> underlyingList = exp.getUnderlyingList();
assertEquals(underlyingList.size(), 5);
assertNull(exp.allDocNestedPath);
DefaultExpressionList<?> shipExpr = (DefaultExpressionList<?>) underlyingList.get(3);
assertEquals(shipExpr.allDocNestedPath, "shipments");
DefaultExpressionList<?> detailsExpr = (DefaultExpressionList<?>) underlyingList.get(4);
assertEquals(detailsExpr.allDocNestedPath, "details");
}
}
@@ -0,0 +1,90 @@
package io.ebeaninternal.server.expression;
import org.junit.jupiter.api.Test;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
public class RawExpressionBuilderTest {
@Test
public void buildSingle_noop() {
RawExpression exp = RawExpressionBuilder.buildSingle("foo = ?", 42);
assertThat(exp.sql).isEqualTo("foo = ?");
}
@Test
public void buildSingle_noExpand() {
RawExpression exp = RawExpressionBuilder.buildSingle("foo = ?", asList(42, 43));
assertThat(exp.sql).isEqualTo("foo = ?");
}
@Test
public void buildSingle_expand() {
RawExpression exp = RawExpressionBuilder.buildSingle("foo in (?1)", asList(42, 43));
assertThat(exp.sql).isEqualTo("foo in (?,?)");
assertThat(exp.values).contains(42, 43);
}
@Test
public void buildSingle_expand_more() {
RawExpression exp = RawExpressionBuilder.buildSingle("foo in (?1)", asList(42, 43, 44, 45));
assertThat(exp.sql).isEqualTo("foo in (?,?,?,?)");
assertThat(exp.values).contains(42, 43, 44, 45);
}
@Test
public void buildSingle_expand_single() {
RawExpression exp = RawExpressionBuilder.buildSingle("foo in (?1)", asList(42));
assertThat(exp.sql).isEqualTo("foo in (?)");
assertThat(exp.values).contains(42);
}
@Test
public void build_noop() {
RawExpression exp = RawExpressionBuilder.build("foo = ?", asArray(42));
assertThat(exp.sql).isEqualTo("foo = ?");
}
@Test
public void build_noExpand() {
RawExpression exp = RawExpressionBuilder.buildSingle("foo = ? and bar = any(?)", asArray(44, asList(42, 43)));
assertThat(exp.sql).isEqualTo("foo = ? and bar = any(?)");
}
@Test
public void build_expand() {
RawExpression exp = RawExpressionBuilder.build("foo in (?) and bar in (?2)", asArray(44, asList(42, 43)));
assertThat(exp.sql).isEqualTo("foo in (?) and bar in (?,?)");
assertThat(exp.values).contains(44, 42, 43);
}
@Test
public void build_expand2() {
RawExpression exp = RawExpressionBuilder.build("foo in (?) and bar in (?2) (?3)", asArray(44, asList(42, 43), asList(91, 92, 93)));
assertThat(exp.sql).isEqualTo("foo in (?) and bar in (?,?) (?,?,?)");
assertThat(exp.values).containsExactly(44, 42, 43, 91, 92, 93);
}
@Test
public void build_expand3() {
RawExpression exp = RawExpressionBuilder.build("foo in (?) and bar in (?2) (?3) and ?", asArray(44, asList(42, 43), asList(91, 92, 93), 87));
assertThat(exp.sql).isEqualTo("foo in (?) and bar in (?,?) (?,?,?) and ?");
assertThat(exp.values).containsExactly(44, 42, 43, 91, 92, 93, 87);
}
private Object[] asArray(Object... values) {
return values;
}
}
@@ -0,0 +1,77 @@
package io.ebeaninternal.server.expression;
import io.ebeaninternal.api.BindValuesKey;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class RawExpressionTest extends BaseExpressionTest {
private RawExpression exp(String sql, Object... values) {
return new RawExpression(sql, values);
}
@Test
public void isSameByPlan_when_same() {
same(exp("a", 10), exp("a", 10));
}
@Test
public void isSameByPlan_when_diffBindValues() {
same(exp("a", 10), exp("a", 20));
}
@Test
public void isSameByPlan_when_diffSql() {
different(exp("a", 10), exp("b", 10));
}
@Test
public void isSameByBind_when_same() {
assertThat(exp("a", 10).isSameByBind(exp("a", 10))).isTrue();
}
@Test
public void isSameByBind_when_diffBindValues() {
assertThat(exp("a", 10).isSameByBind(exp("a", 20))).isFalse();
}
@Test
public void isSameByBind_when_moreBindValues() {
assertThat(exp("a", 10).isSameByBind(exp("a", 10, 20))).isFalse();
}
@Test
public void isSameByBind_when_lessBindValues() {
assertThat(exp("a", 10, 20).isSameByBind(exp("a", 10))).isFalse();
}
@Test
public void queryBindHash_when_sameBindValues() {
assert_queryBindHash_isSame(exp("a", 10), exp("a", 10));
}
@Test
public void queryBindHash_when_diffBindValues() {
assert_queryBindHash_isDifferent(exp("a", 10), exp("a", 20));
}
@Test
public void queryBindHash_when_diffBindValues2() {
assert_queryBindHash_isDifferent(exp("a", 10), exp("a", 10, 11));
}
public void assert_queryBindHash_isDifferent(RawExpression exp0, RawExpression exp1) {
assertThat(bindKey(exp0)).isNotEqualTo(bindKey(exp1));
}
public void assert_queryBindHash_isSame(RawExpression exp0, RawExpression exp1) {
assertThat(bindKey(exp0)).isEqualTo(bindKey(exp1));
}
private BindValuesKey bindKey(RawExpression query) {
BindValuesKey bindValuesKey = new BindValuesKey();
query.queryBindKey(bindValuesKey);
return bindValuesKey;
}
}
@@ -0,0 +1,30 @@
package io.ebeaninternal.server.expression;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class SameTest {
@Test
public void sameByNull() throws Exception {
Assertions.assertThat(Same.sameByNull("a", "a")).isTrue();
assertThat(Same.sameByNull("a", "b")).isTrue();
assertThat(Same.sameByNull(null, null)).isTrue();
assertThat(Same.sameByNull("a", null)).isFalse();
assertThat(Same.sameByNull(null, "a")).isFalse();
}
@Test
public void sameByValue() throws Exception {
assertThat(Same.sameByValue("a", "a")).isTrue();
assertThat(Same.sameByValue("a", "b")).isFalse();
assertThat(Same.sameByValue(null, null)).isTrue();
assertThat(Same.sameByValue("a", null)).isFalse();
assertThat(Same.sameByValue(null, "a")).isFalse();
}
}
@@ -0,0 +1,56 @@
package io.ebeaninternal.server.expression;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class SimpleExpressionTest extends BaseExpressionTest {
private SimpleExpression exp(String propertyName, Op operator, Object value) {
return new SimpleExpression(propertyName, operator, value);
}
@Test
public void isSameByPlan_when_same() {
same(exp("a", Op.EQ, 10), exp("a", Op.EQ, 10));
}
@Test
public void isSameByPlan_when_diffBind_same() {
same(exp("a", Op.EQ, 10), exp("a", Op.EQ, 20));
}
@Test
public void isSameByPlan_when_diffProperty_diff() {
different(exp("a", Op.EQ, 10), exp("b", Op.EQ, 10));
}
@Test
public void isSameByPlan_when_diffOperator_diff() {
different(exp("a", Op.EQ, 10), exp("a", Op.LT, 10));
}
@Test
public void isSameByPlan_when_diffType_diff() {
different(exp("a", Op.EQ, 10), new NoopExpression());
}
@Test
public void isSameByBind_when_sameBindValues() {
assertThat(exp("a", Op.EQ, 10).isSameByBind(exp("a", Op.LT, 10))).isTrue();
}
@Test
public void isSameByBind_when_diffBindValues() {
assertThat(exp("a", Op.EQ, 10).isSameByBind(exp("a", Op.EQ, "junk"))).isFalse();
}
}
@@ -0,0 +1,91 @@
package io.ebeaninternal.server.expression;
import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.server.core.SpiOrmQueryRequest;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.expression.platform.DbExpressionHandler;
import java.util.ArrayList;
import java.util.List;
/**
* Test double for testing with SpiExpressionRequest.
*/
public class TDSpiExpressionRequest implements SpiExpressionRequest {
List<Object> bindValues = new ArrayList<>();
final BeanDescriptor<?> descriptor;
StringBuilder sql = new StringBuilder();
public TDSpiExpressionRequest(BeanDescriptor<?> descriptor) {
this.descriptor = descriptor;
}
@Override
public DbExpressionHandler getDbPlatformHandler() {
return null;
}
@Override
public String parseDeploy(String logicalProp) {
return null;
}
@Override
public BeanDescriptor<?> getBeanDescriptor() {
return descriptor;
}
@Override
public SpiOrmQueryRequest<?> getQueryRequest() {
return null;
}
@Override
public SpiExpressionRequest append(String sqlExpression) {
sql.append(sqlExpression);
return this;
}
@Override
public void addBindEncryptKey(Object encryptKey) {
}
@Override
public void addBindValue(Object bindValue) {
bindValues.add(bindValue);
}
@Override
public String getSql() {
return sql.toString();
}
@Override
public ArrayList<Object> getBindValues() {
return null;
}
@Override
public int nextParameter() {
return 0;
}
@Override
public void appendLike(boolean rawLikeExpression) {
}
@Override
public String escapeLikeString(String value) {
return value;
}
@Override
public void appendInExpression(boolean not, List<Object> bindValues) {
}
}
@@ -0,0 +1,122 @@
package io.ebeaninternal.server.querydefn;
import io.ebean.*;
import io.ebeaninternal.api.BindValuesKey;
import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.server.core.DefaultServer;
import io.ebeaninternal.server.core.OrmQueryRequest;
import io.ebeaninternal.server.core.OrmQueryRequestTestHelper;
import io.ebeaninternal.server.deploy.BaseTest;
import io.ebeaninternal.server.expression.BaseExpressionTest;
import org.junit.jupiter.api.Test;
import org.tests.model.basic.Customer;
import org.tests.model.basic.Order;
import static org.assertj.core.api.Assertions.assertThat;
public class DefaultOrmQueryTest extends BaseExpressionTest {
@Test
public void when_forUpdate_then_excludeFromBeanCache() {
DefaultOrmQuery<Customer> q1 = (DefaultOrmQuery<Customer>) DB.find(Customer.class)
.forUpdate().where().eq("id", 42).query();
assertThat(q1.getUseBeanCache()).isSameAs(CacheMode.OFF);
}
@Test
public void checkForId_when_eqId_then_translatedTo_setId() {
DefaultOrmQuery<Order> q1 = (DefaultOrmQuery<Order>) DB.find(Order.class).where().eq("id", 42).query();
assertThat(q1.getWhereExpressions()).isNotNull();
assertThat(q1.getId()).isNull();
assertThat(q1.isFindById()).isTrue();
assertThat(q1.getId()).isEqualTo(42);
assertThat(q1.getWhereExpressions()).isNull();
}
@Test
public void checkForId_when_idEq_ok() {
DefaultOrmQuery<Order> q1 = (DefaultOrmQuery<Order>) DB.find(Order.class).where().idEq(42).query();
assertThat(q1.getId()).isEqualTo(42);
assertThat(q1.isFindById()).isTrue();
assertThat(q1.getId()).isEqualTo(42);
}
@Test
public void checkForId_when_setId_ok() {
DefaultOrmQuery<Order> q1 = (DefaultOrmQuery<Order>) DB.find(Order.class).setId(42);
assertThat(q1.getId()).isEqualTo(42);
assertThat(q1.isFindById()).isTrue();
assertThat(q1.getId()).isEqualTo(42);
}
@Test
public void when_addWhere_then_planChanges() {
DefaultOrmQuery<Order> q1 = (DefaultOrmQuery<Order>) DB.find(Order.class).where().in("name", "a", "b", "c").query();
DefaultOrmQuery<Order> q2 = (DefaultOrmQuery<Order>) DB.find(Order.class).where().in("id", 2, 2, 3).query();
prepare(q1, q2);
assertThat(q1.createQueryPlanKey()).isNotEqualTo(q2.createQueryPlanKey());
assertThat(bindKey(q1)).isNotEqualTo(bindKey(q2));
}
@Test
public void when_sameWhereWithDiffBindValues_then_planSame_bindDiff() {
DefaultOrmQuery<Order> q1 = (DefaultOrmQuery<Order>) DB.find(Order.class).where().in("id", 1, 2, 3).query();
DefaultOrmQuery<Order> q2 = (DefaultOrmQuery<Order>) DB.find(Order.class).where().in("id", 2, 2, 3).query();
prepare(q1, q2);
assertThat(q1.createQueryPlanKey()).isEqualTo(q2.createQueryPlanKey());
assertThat(bindKey(q1)).isNotEqualTo(bindKey(q2));
}
@Test
public void when_sameWhereAndBindValues_then_planSameAndBind() {
DefaultOrmQuery<Order> q1 = (DefaultOrmQuery<Order>) DB.find(Order.class).where().in("id", 1, 2, 3).query();
DefaultOrmQuery<Order> q2 = (DefaultOrmQuery<Order>) DB.find(Order.class).where().in("id", 1, 2, 3).query();
prepare(q1, q2);
assertThat(q1.createQueryPlanKey()).isEqualTo(q2.createQueryPlanKey());
assertThat(bindKey(q1)).isEqualTo(bindKey(q2));
}
@Test
public void when_diffFirstMaxRows_then_differentPlan() {
DefaultOrmQuery<Order> query1 = (DefaultOrmQuery<Order>) DB.find(Order.class)
.setFirstRow(0)
.setMaxRows(31);
DefaultOrmQuery<Order> query2 = (DefaultOrmQuery<Order>) DB.find(Order.class)
.setFirstRow(1)
.setMaxRows(0);
prepare(query1, query2);
assertThat(query1.createQueryPlanKey()).isNotEqualTo(query2.createQueryPlanKey());
}
private <T> void prepare(DefaultOrmQuery<T> q1, DefaultOrmQuery<T> q2) {
OrmQueryRequest<T> r1 = OrmQueryRequestTestHelper.queryRequest(q1);
q1.prepare(r1);
OrmQueryRequest<T> r2 = OrmQueryRequestTestHelper.queryRequest(q2);
q2.prepare(r2);
}
private BindValuesKey bindKey(DefaultOrmQuery<Order> query) {
BindValuesKey key = new BindValuesKey();
query.queryBindKey(key);
return key;
}
}
@@ -0,0 +1,258 @@
package io.ebeaninternal.server.querydefn;
import io.ebeaninternal.server.deploy.BaseTest;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import org.junit.jupiter.api.Test;
import org.tests.model.basic.Order;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;
public class OrmQueryDetailTest extends BaseTest {
OrmQueryDetail parse(String query) {
return new OrmQueryDetailParser(query).parse();
}
@Test
public void isEmpty_when_empty() {
OrmQueryDetail detail = new OrmQueryDetail();
assertThat(detail.isEmpty()).isTrue();
}
@Test
public void isEmpty_when_hasFetch_expect_false() {
OrmQueryDetail detail = new OrmQueryDetail();
detail.fetch("customer", null, null);
assertThat(detail.isEmpty()).isFalse();
}
@Test
public void isEmpty_when_hasSelect_expect_false() {
OrmQueryDetail detail = new OrmQueryDetail();
detail.select("name");
assertThat(detail.isEmpty()).isFalse();
}
@Test
public void isAutoTuneEqual_when_fetchOrderIsDifferent_then_stillEqual() {
OrmQueryDetail detail1 = parse("select (id,name) fetch customer (name) fetch details (code)");
OrmQueryDetail detail2 = parse("select (id,name) fetch details (code) fetch customer (name)");
assertTrue(detail1.isAutoTuneEqual(detail2));
}
@Test
public void isAutoTuneEqual_when_different_select() {
OrmQueryDetail detail1 = parse("select (id,name) fetch customer (name) fetch details (code)");
OrmQueryDetail detail2 = parse("select (id) fetch details (code) fetch customer (name)");
assertFalse(detail1.isAutoTuneEqual(detail2));
}
@Test
public void isAutoTuneEqual_when_different_selectInFetch() {
OrmQueryDetail detail1 = parse("select (id,name) fetch customer (name) fetch details (code)");
OrmQueryDetail detail2 = parse("select (id,name) fetch customer (id,name) fetch details (code)");
assertFalse(detail1.isAutoTuneEqual(detail2));
}
@Test
public void isAutoTuneEqual_when_different_additionalFetch() {
OrmQueryDetail detail1 = parse("select (id,name) fetch customer (name) fetch details (code)");
OrmQueryDetail detail2 = parse("select (id,name) fetch customer (name) fetch details (code) fetch customer.contacts");
assertFalse(detail1.isAutoTuneEqual(detail2));
}
@Test
public void isAutoTuneEqual_when_different_removedFetch() {
OrmQueryDetail detail1 = parse("select (id,name) fetch customer (name) fetch details (code) fetch customer.contacts");
OrmQueryDetail detail2 = parse("select (id,name) fetch customer (name) fetch details (code)");
assertFalse(detail1.isAutoTuneEqual(detail2));
assertFalse(detail2.isAutoTuneEqual(detail1));
}
@Test
public void isAutoTuneEqual_when_different_removedFetchProperty() {
OrmQueryDetail detail1 = parse("select (id,name) fetch customer (name)");
OrmQueryDetail detail2 = parse("select (id,name) fetch customer ");
assertFalse(detail1.isAutoTuneEqual(detail2));
assertFalse(detail2.isAutoTuneEqual(detail1));
}
@Test
public void isAutoTuneEqual_when_different_path() {
OrmQueryDetail detail1 = parse("select (id,name) fetch customer (name)");
OrmQueryDetail detail2 = parse("select (id,name) fetch details (id) ");
assertFalse(detail1.isAutoTuneEqual(detail2));
assertFalse(detail2.isAutoTuneEqual(detail1));
}
@Test
public void select_whenMultiple() throws Exception {
OrmQueryDetail other = new OrmQueryDetail();
other.select("id,name");
OrmQueryProperties root = other.getChunk(null, false);
assertNull(root.getPath());
assertThat(root.getIncluded()).containsExactly("id", "name");
}
@Test
public void select_whenOne() throws Exception {
OrmQueryDetail other = new OrmQueryDetail();
other.select("name");
OrmQueryProperties root = other.getChunk(null, false);
assertNull(root.getPath());
assertThat(root.getIncluded()).containsExactly("name");
}
@Test
public void getFetchPaths_when_noFetches_then_expect_empty() {
assertThat(new OrmQueryDetail().getFetchPaths()).isEmpty();
OrmQueryDetail detail = new OrmQueryDetail();
detail.select("foo");
assertThat(detail.getFetchPaths()).isEmpty();
}
@Test
public void getFetchPaths_when_oneFetch() {
OrmQueryDetail detail = new OrmQueryDetail();
detail.select("foo");
detail.fetch("customer", null, null);
assertThat(detail.getFetchPaths()).containsExactly("customer");
}
@Test
public void getFetchPaths_when_multipleFetch_expect_preserveOrder() {
OrmQueryDetail detail = new OrmQueryDetail();
detail.select("foo");
detail.fetch("customer", null, null);
detail.fetch("details", null, null);
assertThat(detail.getFetchPaths()).containsExactly("customer", "details");
}
@Test
public void getFetchPaths_when_multipleFetch_expect_preserveOrder_v2() {
OrmQueryDetail detail = new OrmQueryDetail();
detail.select("foo");
detail.fetch("details", null, null);
detail.fetch("customer", null, null);
detail.fetch("details.product", null, null);
assertThat(detail.getFetchPaths()).containsExactly("details", "customer", "details.product");
}
@Test
public void markQueryJoins_when_allowOne_expect_stillFetchJoin() {
OrmQueryDetail detail = new OrmQueryDetail();
detail.fetch("details", null, null);
detail.markQueryJoins(orderDesc(), null, true, true);
assertThat(detail.getChunk("details", false).isQueryFetch()).isFalse();
}
@Test
public void markQueryJoins_when_allowNone_expect_queryJoin() {
OrmQueryDetail detail = new OrmQueryDetail();
detail.fetch("details", null, null);
detail.markQueryJoins(orderDesc(), null, false, true);
assertThat(detail.getChunk("details", false).isQueryFetch()).isTrue();
}
@Test
public void markQueryJoins_when_allowOneButSecond_expect_queryJoin() {
OrmQueryDetail detail = new OrmQueryDetail();
detail.fetch("details", null, null);
detail.fetch("customer.contacts", null, null);
detail.markQueryJoins(orderDesc(), null, true, true);
assertThat(detail.getChunk("details", false).isQueryFetch()).isFalse();
assertThat(detail.getChunk("customer.contacts", false).isQueryFetch()).isTrue();
}
@Test
public void markQueryJoins_when_allowNone_expect_bothQueryJoin() {
OrmQueryDetail detail = new OrmQueryDetail();
detail.fetch("details", null, null);
detail.fetch("customer.contacts", null, null);
detail.markQueryJoins(orderDesc(), null, false, true);
assertThat(detail.getChunk("details", false).isQueryFetch()).isTrue();
assertThat(detail.getChunk("customer.contacts", false).isQueryFetch()).isTrue();
}
@Test
public void sortFetchPaths_when_missingParent_expect_addsMissing() {
OrmQueryDetail detail = new OrmQueryDetail();
detail.fetch("customer.contacts", null, null);
detail.sortFetchPaths(orderDesc());
assertThat(detail.getFetchPaths()).containsExactly("customer", "customer.contacts");
assertThat(detail.getChunk("customer", false).getIncluded()).containsExactly("id");
}
@Test
public void sortFetchPaths_when_outOfOrder_expect_correctOrder() {
OrmQueryDetail detail = new OrmQueryDetail();
detail.fetch("customer.contacts", "email", null);
detail.fetch("customer", "name", null);
detail.sortFetchPaths(orderDesc());
assertThat(detail.getFetchPaths()).containsExactly("customer", "customer.contacts");
assertThat(detail.getChunk("customer", false).getIncluded()).containsExactly("name");
}
@Test
public void sortFetchPaths_when_empty_expect_stillEmpty() {
OrmQueryDetail detail = new OrmQueryDetail();
detail.sortFetchPaths(orderDesc());
assertThat(detail.getFetchPaths()).isEmpty();
}
BeanDescriptor<Order> orderDesc() {
return getBeanDescriptor(Order.class);
}
}
@@ -0,0 +1,350 @@
package io.ebeaninternal.server.querydefn;
import io.ebean.ExpressionList;
import io.ebean.Query;
import io.ebeaninternal.api.CQueryPlanKey;
import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.server.deploy.BaseTest;
import io.ebeaninternal.server.deploy.TableJoin;
import io.ebeaninternal.server.deploy.meta.DeployTableJoin;
import io.ebeaninternal.server.deploy.meta.DeployTableJoinColumn;
import org.junit.jupiter.api.Test;
import org.tests.model.basic.Customer;
import java.sql.Timestamp;
import static org.assertj.core.api.Assertions.assertThat;
public class OrmQueryPlanKeyTest extends BaseTest {
@SuppressWarnings({"unchecked", "rawtypes"})
private DefaultOrmQuery<Customer> query() {
return (DefaultOrmQuery) server().find(Customer.class);
}
@Test
public void equals_when_defaults() {
assertSame(query().createQueryPlanKey(), query().createQueryPlanKey());
}
@Test
public void equals_when_diffTableJoinNull() {
DefaultOrmQuery<Customer> q1 = query();
q1.setM2MIncludeJoin(tableJoin("table", "id", "customer_id"));
assertDifferent(q1, query());
}
@Test
public void equals_when_diffTableJoin() {
DefaultOrmQuery<Customer> q1 = query();
q1.setM2MIncludeJoin(tableJoin("one", "cid", "customer_id"));
DefaultOrmQuery<Customer> q2 = query();
q2.setM2MIncludeJoin(tableJoin("two", "cid", "customer_id"));
assertDifferent(q1, q2);
}
@Test
public void equals_when_sameTableJoin() {
DefaultOrmQuery<Customer> q1 = query();
q1.setM2MIncludeJoin(tableJoin("one", "id", "cust_id"));
DefaultOrmQuery<Customer> q2 = query();
q2.setM2MIncludeJoin(tableJoin("one", "id", "cust_id"));
assertSame(q1, q2);
}
private TableJoin tableJoin(String table, String col1, String col2) {
DeployTableJoin deploy = new DeployTableJoin();
deploy.setTable(table);
deploy.addJoinColumn(new DeployTableJoinColumn(col1, col2));
return new TableJoin(deploy);
}
@Test
public void equals_when_diffQueryType() {
DefaultOrmQuery<Customer> q1 = query();
q1.setType(SpiQuery.Type.BEAN);
DefaultOrmQuery<Customer> q2 = query();
q2.setType(SpiQuery.Type.LIST);
assertDifferent(q1, q2);
}
@Test
public void equals_when_firstRowsDifferent() {
CQueryPlanKey key1 = planKey(query().setFirstRow(10));
CQueryPlanKey key2 = planKey(query());
assertDifferent(key1, key2);
key1 = planKey(query().setFirstRow(10));
key2 = planKey(query().setFirstRow(9));
assertDifferent(key1, key2);
key1 = planKey(query());
key2 = planKey(query().setFirstRow(9));
assertDifferent(key1, key2);
}
@Test
public void equals_when_maxRowsDifferent() {
CQueryPlanKey key1 = planKey(query().setMaxRows(10));
CQueryPlanKey key2 = planKey(query());
assertDifferent(key1, key2);
key1 = planKey(query().setMaxRows(10));
key2 = planKey(query().setMaxRows(9));
assertDifferent(key1, key2);
key1 = planKey(query());
key2 = planKey(query().setMaxRows(9));
assertDifferent(key1, key2);
}
@Test
public void equals_when_firstRowsMaxRowsSame() {
CQueryPlanKey key1 = planKey(query().setMaxRows(10).setFirstRow(20));
CQueryPlanKey key2 = planKey(query().setFirstRow(20).setMaxRows(10));
assertSame(key1, key2);
}
@Test
public void equals_when_diffDisableLazyLoading() {
assertDifferent(query().setDisableLazyLoading(true), query());
}
@Test
public void equals_when_diffOrderByNull() {
CQueryPlanKey key1 = planKey(query().order("id"));
CQueryPlanKey key2 = planKey(query());
assertDifferent(key1, key2);
key1 = planKey(query().order().asc("id"));
key2 = planKey(query());
assertDifferent(key1, key2);
}
@Test
public void equals_when_orderBySame() {
CQueryPlanKey key1 = planKey(query().order("id, name"));
CQueryPlanKey key2 = planKey(query().order("id, name"));
assertSame(key1, key2);
}
@Test
public void equals_when_diffDistinct() {
CQueryPlanKey key1 = planKey(query().setDistinct(true));
CQueryPlanKey key2 = planKey(query());
assertDifferent(key1, key2);
}
@Test
public void equals_when_sameDistinct() {
CQueryPlanKey key1 = planKey(query().setDistinct(true));
CQueryPlanKey key2 = planKey(query().setDistinct(true));
assertSame(key1, key2);
}
@Test
public void equals_when_useDocStore() {
CQueryPlanKey key1 = planKey(query().setUseDocStore(true));
CQueryPlanKey key2 = planKey(query());
assertDifferent(key1, key2);
}
@Test
public void equals_when_diffMapKey() {
CQueryPlanKey key1 = planKey(query().setMapKey("name"));
CQueryPlanKey key2 = planKey(query());
assertDifferent(key1, key2);
CQueryPlanKey key3 = planKey(query().setMapKey("email"));
assertDifferent(key1, key3);
CQueryPlanKey key4 = planKey(query().setMapKey("name"));
assertSame(key1, key4);
}
@Test
public void equals_when_diffIdNull() {
CQueryPlanKey key1 = planKey(query().setId(42));
CQueryPlanKey key2 = planKey(query());
assertDifferent(key1, key2);
}
@Test
public void equals_when_idBothGiven() {
CQueryPlanKey key1 = planKey(query().setId(42));
CQueryPlanKey key2 = planKey(query().setId(23));
assertSame(key1, key2);
}
@Test
public void equals_when_diffTemporalMode() {
CQueryPlanKey key1 = planKey(query());
CQueryPlanKey key2 = planKey(query().asDraft());
assertDifferent(key1, key2);
CQueryPlanKey key3 = planKey(query().asOf(new Timestamp(System.currentTimeMillis())));
assertDifferent(key1, key3);
CQueryPlanKey key4 = planKey(query().setIncludeSoftDeletes());
assertDifferent(key1, key4);
}
@Test
public void equals_when_diffForUpdate() {
CQueryPlanKey key1 = planKey(query().forUpdate());
CQueryPlanKey key2 = planKey(query());
assertDifferent(key1, key2);
CQueryPlanKey key3 = planKey(query().forUpdateNoWait());
assertDifferent(key1, key3);
CQueryPlanKey key4 = planKey(query().forUpdateSkipLocked());
assertDifferent(key1, key4);
CQueryPlanKey key5 = planKey(query().forUpdate());
assertSame(key1, key5);
}
@Test
public void equals_when_diffRootAliasNull() {
CQueryPlanKey key1 = planKey(query().alias("alias"));
CQueryPlanKey key2 = planKey(query());
assertDifferent(key1, key2);
CQueryPlanKey key3 = planKey(query().alias("diff"));
assertDifferent(key1, key3);
CQueryPlanKey key4 = planKey(query().alias("alias"));
assertSame(key1, key4);
}
private DefaultOrmQuery<Customer> list_id_eq_42() {
return (DefaultOrmQuery<Customer>) server().find(Customer.class)
.where().eq("id", 42).query();
}
private DefaultOrmQuery<Customer> list_id_eq_43() {
return (DefaultOrmQuery<Customer>) server().find(Customer.class)
.where().eq("id", 43).query();
}
private DefaultOrmQuery<Customer> list_id_eq_42_and_name_eq_rob() {
return (DefaultOrmQuery<Customer>) server().find(Customer.class)
.where().eq("id", 43).eq("name", "rob").query();
}
@Test
public void equals_when_sameWhere() {
assertSame(list_id_eq_42(), list_id_eq_43());
}
@Test
public void equals_when_diffWhere() {
assertDifferent(list_id_eq_42(), list_id_eq_42_and_name_eq_rob());
}
@Test
public void equals_when_diffWhereNullLast() {
assertDifferent(list_id_eq_42(), query());
}
@Test
public void equals_when_diffHaving() {
CQueryPlanKey key1 = planKey(query().having().eq("id", 42));
CQueryPlanKey key2 = planKey(query().having().eq("id", 42).eq("name", "Rob"));
assertDifferent(key1, key2);
CQueryPlanKey key3 = planKey(query().where().eq("id", 42));
assertDifferent(key1, key3);
CQueryPlanKey key4 = planKey(query().having().eq("name", "Rob"));
assertDifferent(key1, key4);
}
@Test
public void equals_when_sameHaving() {
CQueryPlanKey key1 = planKey(query().having().eq("id", 42));
CQueryPlanKey key2 = planKey(query().having().eq("id", 43));
assertSame(key1, key2);
}
@Test
public void equals_when_manualId_andSelectClause() {
DefaultOrmQuery<Customer> q1 = (DefaultOrmQuery<Customer>)query().select("name");
q1.setManualId();
assertDifferent(q1, query().select("name"));
}
@Test
public void equals_when_manualId_andNoSelectClause() {
DefaultOrmQuery<Customer> q1 = query();
q1.setManualId();
assertSame(q1, query());
}
private CQueryPlanKey planKey(ExpressionList<Customer> id) {
return planKey(id.query());
}
@SuppressWarnings({"rawtypes"})
private CQueryPlanKey planKey(Query<Customer> query) {
return ((DefaultOrmQuery) query).createQueryPlanKey();
}
@SuppressWarnings({"unchecked", "rawtypes"})
private void assertDifferent(Query q1, Query q2) {
assertDifferent(planKey(q1), planKey(q2));
}
@SuppressWarnings({"unchecked", "rawtypes"})
private void assertSame(Query q1, Query q2) {
assertSame(planKey(q1), planKey(q2));
}
private void assertDifferent(CQueryPlanKey key1, CQueryPlanKey key2) {
assertThat(key1).isNotEqualTo(key2);
assertThat(key1.hashCode()).isNotEqualTo(key2.hashCode());
}
private void assertSame(CQueryPlanKey key1, CQueryPlanKey key2) {
assertThat(key1).isEqualTo(key2);
assertThat(key1.hashCode()).isEqualTo(key2.hashCode());
}
}
@@ -82,8 +82,8 @@ public class Order implements Serializable {
@DocEmbedded
List<OrderDetail> details;
// @OneToMany(cascade = CascadeType.ALL, mappedBy = "order", orphanRemoval = true)
// List<OrderShipment> shipments;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "order", orphanRemoval = true)
List<OrderShipment> shipments;
@Override
public String toString() {
@@ -234,19 +234,19 @@ public class Order implements Serializable {
details.add(detail);
}
// public List<OrderShipment> getShipments() {
// return shipments;
// }
//
// public void setShipments(List<OrderShipment> shipments) {
// this.shipments = shipments;
// }
//
// public void addShipment(OrderShipment shipment) {
//
// if (shipments == null) {
// shipments = new ArrayList<>();
// }
// shipments.add(shipment);
// }
public List<OrderShipment> getShipments() {
return shipments;
}
public void setShipments(List<OrderShipment> shipments) {
this.shipments = shipments;
}
public void addShipment(OrderShipment shipment) {
if (shipments == null) {
shipments = new ArrayList<>();
}
shipments.add(shipment);
}
}
@@ -0,0 +1,64 @@
package org.tests.model.basic;
import io.ebean.annotation.Sql;
import javax.persistence.Entity;
import javax.persistence.OneToOne;
/**
* An example of an Aggregate object.
* <p>
* Note the &#064;Sql indicates to Ebean that this bean is not based on a table but
* instead uses RawSql.
* </p>
*/
@Entity
@Sql
public class OrderAggregate {
@OneToOne
Order order;
Double maxAmount;
Double totalAmount;
Long totalItems;
@Override
public String toString() {
return order.getId() + " totalAmount:" + totalAmount + " totalItems:" + totalItems;
}
public Order getOrder() {
return order;
}
public void setOrder(Order order) {
this.order = order;
}
public Double getTotalAmount() {
return totalAmount;
}
public void setTotalAmount(Double totalAmount) {
this.totalAmount = totalAmount;
}
public Long getTotalItems() {
return totalItems;
}
public void setTotalItems(Long totalItems) {
this.totalItems = totalItems;
}
public Double getMaxAmount() {
return maxAmount;
}
public void setMaxAmount(Double maxAmount) {
this.maxAmount = maxAmount;
}
}
@@ -0,0 +1,35 @@
package org.tests.model.basic;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import java.sql.Timestamp;
@Entity
@Table(name = "or_order_ship")
public class OrderShipment extends BasicDomain {
private static final long serialVersionUID = 1L;
@ManyToOne
private Order order;
private Timestamp shipTime = new Timestamp(System.currentTimeMillis());
public Timestamp getShipTime() {
return shipTime;
}
public void setShipTime(Timestamp shipTime) {
this.shipTime = shipTime;
}
public Order getOrder() {
return order;
}
public void setOrder(Order order) {
this.order = order;
}
}