From 545d1f3600942accb975c3081b7369286bb84b5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Westk=C3=A4mper?= Date: Tue, 27 Oct 2009 12:16:46 +0000 Subject: [PATCH] added test for Expr subclass behaviour inspection --- .../com/mysema/query/domain/ExprTest.java | 106 ++++++++++++++++++ .../com/mysema/query/types/expr/ENumber.java | 36 ++++++ .../mysema/query/types/expr/ENumberConst.java | 21 ++++ .../com/mysema/query/types/expr/EString.java | 7 +- .../com/mysema/query/types/expr/ETime.java | 4 +- .../query/types/path/PComponentList.java | 14 +++ .../mysema/query/types/path/PEntityList.java | 15 ++- 7 files changed, 200 insertions(+), 3 deletions(-) create mode 100644 querydsl-apt/src/test/java/com/mysema/query/domain/ExprTest.java diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/ExprTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/ExprTest.java new file mode 100644 index 000000000..8fc333afd --- /dev/null +++ b/querydsl-apt/src/test/java/com/mysema/query/domain/ExprTest.java @@ -0,0 +1,106 @@ +package com.mysema.query.domain; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +import org.junit.Test; + +import com.mysema.query.types.expr.EBoolean; +import com.mysema.query.types.expr.ENumber; +import com.mysema.query.types.expr.EString; +import com.mysema.query.types.expr.Expr; + +public class ExprTest { + + @Test + public void test() throws Exception { + List> exprs = new ArrayList>(); + exprs.add(QAnimal.animal); + exprs.add(QCat.cat); + exprs.add(QCategory.category); + exprs.add(QClassWithConstructor.classWithConstructor); + exprs.add(QEntity1.entity1); + exprs.add(QEntity2.entity2); + exprs.add(QEntity3.entity3); + exprs.add(QEntityWithEmbedded.entityWithEmbedded); + exprs.add(QGenericType.genericType); + exprs.add(QInterfaceType.interfaceType); + exprs.add(QInterfaceType2.interfaceType2); + exprs.add(QInterfaceType3.interfaceType3); + exprs.add(QInterfaceType4.interfaceType4); + exprs.add(QInterfaceType5.interfaceType5); + exprs.add(QItemType.itemType); + exprs.add(QJodaTimeSupport.jodaTimeSupport); + exprs.add(QPEntity.pEntity); + exprs.add(QPEntity2.pEntity2); + exprs.add(QPEntity3.pEntity3); + exprs.add(QPEntity4.pEntity4); + exprs.add(QQueryTypeEntity.queryTypeEntity); + exprs.add(QReference.reference); + exprs.add(QRelationType.relationType); + exprs.add(QReservedNames.reservedNames); + exprs.add(QSimpleTypes.simpleTypes); + + exprs.add(EString.create("Hello World!")); + exprs.add(ENumber.create(1000)); + exprs.add(ENumber.create(10l)); + exprs.add(EBoolean.TRUE); + exprs.add(EBoolean.FALSE); + + Set> toVisit = new HashSet>(); + + // all entities + toVisit.addAll(exprs); + // and all their direct properties + for (Expr expr : exprs){ + for (Field field : expr.getClass().getFields()){ + Object rv = field.get(expr); + if (rv instanceof Expr) toVisit.add((Expr) rv); + } + } + + Set failures = new TreeSet(); + + for (Expr expr : toVisit){ + for (Method method : expr.getClass().getMethods()){ + if (method.getReturnType() != void.class + && !method.getReturnType().isPrimitive()){ + Class[] types = method.getParameterTypes(); + Object[] args; + if (types.length == 0){ + args = new Object[0]; + }else if (types.length == 1){ + if (types[0] == int.class){ + args = new Object[]{Integer.valueOf(1)}; + }else{ + continue; + } + + }else{ + continue; + } + Object rv = method.invoke(expr, args); + if (method.invoke(expr, args) != rv){ + failures.add(expr.getClass().getSimpleName()+"."+method.getName()+" is unstable"); + } + } + } + } + + if (failures.size() > 0){ + System.err.println("Got "+failures.size()+" failures\n"); + } + for (String failure : failures){ + System.err.println(failure); + } + + +// assertTrue("Got "+failures.size()+" failures",failures.isEmpty()); + } + +} diff --git a/querydsl-core/src/main/java/com/mysema/query/types/expr/ENumber.java b/querydsl-core/src/main/java/com/mysema/query/types/expr/ENumber.java index 6cfa86c74..d907d6c01 100644 --- a/querydsl-core/src/main/java/com/mysema/query/types/expr/ENumber.java +++ b/querydsl-core/src/main/java/com/mysema/query/types/expr/ENumber.java @@ -31,10 +31,22 @@ public abstract class ENumber> extends ECompara @SuppressWarnings("unchecked") private static final ENumber[] ints = new ENumber[256]; + @SuppressWarnings("unchecked") + private static final ENumber[] bytes = new ENumber[256]; + + @SuppressWarnings("unchecked") + private static final ENumber[] shorts = new ENumber[256]; + + @SuppressWarnings("unchecked") + private static final ENumber[] longs = new ENumber[256]; + static{ random = ONumber.create(Double.class, MathOps.RANDOM); for (int i = 0; i < 256; i++){ ints[i] = new ENumberConst(Integer.class, Integer.valueOf(i)); + shorts[i] = new ENumberConst(Short.class, Short.valueOf((short)i)); + bytes[i] = new ENumberConst(Byte.class, Byte.valueOf((byte)i)); + longs[i] = new ENumberConst(Long.class, Long.valueOf(i)); } } @@ -50,6 +62,30 @@ public abstract class ENumber> extends ECompara return new ENumberConst((Class)val.getClass(), Assert.notNull(val,"val is null")); } + public static ENumber create(byte i){ + if (i >= 0 && i < 256){ + return bytes[i]; + }else{ + return new ENumberConst(Byte.class, Byte.valueOf(i)); + } + } + + public static ENumber create(short i){ + if (i >= 0 && i < 256){ + return shorts[i]; + }else{ + return new ENumberConst(Short.class, Short.valueOf(i)); + } + } + + public static ENumber create(long i){ + if (i >= 0 && i < 256){ + return longs[(int)i]; + }else{ + return new ENumberConst(Long.class, Long.valueOf(i)); + } + } + public static ENumber create(int i){ if (i >= 0 && i < 256){ return ints[i]; diff --git a/querydsl-core/src/main/java/com/mysema/query/types/expr/ENumberConst.java b/querydsl-core/src/main/java/com/mysema/query/types/expr/ENumberConst.java index 6429e7628..0e80701bd 100644 --- a/querydsl-core/src/main/java/com/mysema/query/types/expr/ENumberConst.java +++ b/querydsl-core/src/main/java/com/mysema/query/types/expr/ENumberConst.java @@ -86,4 +86,25 @@ public class ENumberConst> extends ENumber i } } + public ENumber byteValue() { + return ENumber.create(constant.byteValue()); + } + + public ENumber doubleValue() { + return ENumber.create(constant.doubleValue()); + } + + public ENumber floatValue() { + return ENumber.create(constant.floatValue()); + } + + public ENumber longValue() { + return ENumber.create(constant.longValue()); + } + + public ENumber shortValue() { + return ENumber.create(constant.shortValue()); + } + + } diff --git a/querydsl-core/src/main/java/com/mysema/query/types/expr/EString.java b/querydsl-core/src/main/java/com/mysema/query/types/expr/EString.java index 84455ba74..828704e4d 100644 --- a/querydsl-core/src/main/java/com/mysema/query/types/expr/EString.java +++ b/querydsl-core/src/main/java/com/mysema/query/types/expr/EString.java @@ -67,6 +67,8 @@ public abstract class EString extends EComparable { private volatile ENumber length; private volatile EString lower, trim, upper; + + private volatile EBoolean isempty; public EString() { super(String.class); @@ -242,7 +244,10 @@ public abstract class EString extends EComparable { * @see java.lang.String#isEmpty() */ public EBoolean isEmpty(){ - return OBoolean.create(Ops.STRING_IS_EMPTY, this); + if (isempty == null){ + isempty = OBoolean.create(Ops.STRING_IS_EMPTY, this); + } + return isempty; } /** diff --git a/querydsl-core/src/main/java/com/mysema/query/types/expr/ETime.java b/querydsl-core/src/main/java/com/mysema/query/types/expr/ETime.java index 24324fc01..b7d5f496c 100644 --- a/querydsl-core/src/main/java/com/mysema/query/types/expr/ETime.java +++ b/querydsl-core/src/main/java/com/mysema/query/types/expr/ETime.java @@ -21,6 +21,8 @@ import com.mysema.query.types.operation.Ops; @SuppressWarnings({"unchecked","serial"}) public abstract class ETime extends EDateOrTime { + private static final ETime currentTime = currentTime(Date.class); + private volatile ENumber hours, minutes, seconds, milliseconds; public static ETime create(java.sql.Time time){ @@ -87,7 +89,7 @@ public abstract class ETime extends EDateOrTime { * @return */ public static ETime currentTime() { - return currentTime(Date.class); + return currentTime; } /** diff --git a/querydsl-core/src/main/java/com/mysema/query/types/path/PComponentList.java b/querydsl-core/src/main/java/com/mysema/query/types/path/PComponentList.java index 3ebd4ae54..e26c5fe2a 100644 --- a/querydsl-core/src/main/java/com/mysema/query/types/path/PComponentList.java +++ b/querydsl-core/src/main/java/com/mysema/query/types/path/PComponentList.java @@ -17,6 +17,8 @@ import com.mysema.query.types.expr.Expr; @SuppressWarnings("serial") public class PComponentList extends PComponentCollection implements PList { + private volatile PSimple first, second; + public PComponentList(Class type, PathMetadata metadata) { super(type, metadata); } @@ -28,6 +30,18 @@ public class PComponentList extends PComponentCollection implements PList< @Override public PSimple get(int index) { + if (index == 0){ + if (first == null) first = create(0); + return first; + }else if (index == 1){ + if (second == null) second = create(1); + return second; + }else{ + return create(index); + } + } + + private PSimple create(int index){ return new PSimple(type, PathMetadata.forListAccess(this, index)); } } \ No newline at end of file diff --git a/querydsl-core/src/main/java/com/mysema/query/types/path/PEntityList.java b/querydsl-core/src/main/java/com/mysema/query/types/path/PEntityList.java index 7f785f531..7020cf108 100644 --- a/querydsl-core/src/main/java/com/mysema/query/types/path/PEntityList.java +++ b/querydsl-core/src/main/java/com/mysema/query/types/path/PEntityList.java @@ -19,6 +19,8 @@ public class PEntityList> extends PEntityCollection i private final Class queryType; + private volatile E first, second; + public PEntityList(Class elementType, Class queryType, PathMetadata metadata) { super(elementType, elementType.getSimpleName(), metadata); this.queryType = queryType; @@ -36,7 +38,18 @@ public class PEntityList> extends PEntityCollection i @Override public E get(int index) { - // TODO : cache + if (index == 0){ + if (first == null) first = create(0); + return first; + }else if (index == 1){ + if (second == null) second = create(1); + return second; + }else{ + return create(index); + } + } + + private E create(int index){ PathMetadata md = PathMetadata.forListAccess(this, index); try { return queryType.getConstructor(PathMetadata.class).newInstance(md);