added test for Expr subclass behaviour inspection

This commit is contained in:
Timo Westkämper 2009-10-27 12:16:46 +00:00
parent 5aaa73daa9
commit 545d1f3600
7 changed files with 200 additions and 3 deletions

View File

@ -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<Expr<?>> exprs = new ArrayList<Expr<?>>();
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<Expr<?>> toVisit = new HashSet<Expr<?>>();
// 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<String> failures = new TreeSet<String>();
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());
}
}

View File

@ -31,10 +31,22 @@ public abstract class ENumber<D extends Number & Comparable<?>> extends ECompara
@SuppressWarnings("unchecked")
private static final ENumber<Integer>[] ints = new ENumber[256];
@SuppressWarnings("unchecked")
private static final ENumber<Byte>[] bytes = new ENumber[256];
@SuppressWarnings("unchecked")
private static final ENumber<Short>[] shorts = new ENumber[256];
@SuppressWarnings("unchecked")
private static final ENumber<Long>[] longs = new ENumber[256];
static{
random = ONumber.create(Double.class, MathOps.RANDOM);
for (int i = 0; i < 256; i++){
ints[i] = new ENumberConst<Integer>(Integer.class, Integer.valueOf(i));
shorts[i] = new ENumberConst<Short>(Short.class, Short.valueOf((short)i));
bytes[i] = new ENumberConst<Byte>(Byte.class, Byte.valueOf((byte)i));
longs[i] = new ENumberConst<Long>(Long.class, Long.valueOf(i));
}
}
@ -50,6 +62,30 @@ public abstract class ENumber<D extends Number & Comparable<?>> extends ECompara
return new ENumberConst<T>((Class<T>)val.getClass(), Assert.notNull(val,"val is null"));
}
public static ENumber<Byte> create(byte i){
if (i >= 0 && i < 256){
return bytes[i];
}else{
return new ENumberConst<Byte>(Byte.class, Byte.valueOf(i));
}
}
public static ENumber<Short> create(short i){
if (i >= 0 && i < 256){
return shorts[i];
}else{
return new ENumberConst<Short>(Short.class, Short.valueOf(i));
}
}
public static ENumber<Long> create(long i){
if (i >= 0 && i < 256){
return longs[(int)i];
}else{
return new ENumberConst<Long>(Long.class, Long.valueOf(i));
}
}
public static ENumber<Integer> create(int i){
if (i >= 0 && i < 256){
return ints[i];

View File

@ -86,4 +86,25 @@ public class ENumberConst<D extends Number & Comparable<?>> extends ENumber<D> i
}
}
public ENumber<Byte> byteValue() {
return ENumber.create(constant.byteValue());
}
public ENumber<Double> doubleValue() {
return ENumber.create(constant.doubleValue());
}
public ENumber<Float> floatValue() {
return ENumber.create(constant.floatValue());
}
public ENumber<Long> longValue() {
return ENumber.create(constant.longValue());
}
public ENumber<Short> shortValue() {
return ENumber.create(constant.shortValue());
}
}

View File

@ -67,6 +67,8 @@ public abstract class EString extends EComparable<String> {
private volatile ENumber<Long> 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<String> {
* @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;
}
/**

View File

@ -21,6 +21,8 @@ import com.mysema.query.types.operation.Ops;
@SuppressWarnings({"unchecked","serial"})
public abstract class ETime<D extends Comparable> extends EDateOrTime<D> {
private static final ETime<Date> currentTime = currentTime(Date.class);
private volatile ENumber<Integer> hours, minutes, seconds, milliseconds;
public static ETime<java.sql.Time> create(java.sql.Time time){
@ -87,7 +89,7 @@ public abstract class ETime<D extends Comparable> extends EDateOrTime<D> {
* @return
*/
public static ETime<Date> currentTime() {
return currentTime(Date.class);
return currentTime;
}
/**

View File

@ -17,6 +17,8 @@ import com.mysema.query.types.expr.Expr;
@SuppressWarnings("serial")
public class PComponentList<D> extends PComponentCollection<D> implements PList<D> {
private volatile PSimple<D> first, second;
public PComponentList(Class<D> type, PathMetadata<?> metadata) {
super(type, metadata);
}
@ -28,6 +30,18 @@ public class PComponentList<D> extends PComponentCollection<D> implements PList<
@Override
public PSimple<D> 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<D> create(int index){
return new PSimple<D>(type, PathMetadata.forListAccess(this, index));
}
}

View File

@ -19,6 +19,8 @@ public class PEntityList<D, E extends PEntity<D>> extends PEntityCollection<D> i
private final Class<E> queryType;
private volatile E first, second;
public PEntityList(Class<? super D> elementType, Class<E> queryType, PathMetadata<?> metadata) {
super(elementType, elementType.getSimpleName(), metadata);
this.queryType = queryType;
@ -36,7 +38,18 @@ public class PEntityList<D, E extends PEntity<D>> extends PEntityCollection<D> 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<Integer> md = PathMetadata.forListAccess(this, index);
try {
return queryType.getConstructor(PathMetadata.class).newInstance(md);