Skip to content

Commit

Permalink
Issue aaberg#314: add test
Browse files Browse the repository at this point in the history
  • Loading branch information
mvysny committed Jan 21, 2019
1 parent 01d3490 commit b0c72df
Showing 1 changed file with 96 additions and 0 deletions.
96 changes: 96 additions & 0 deletions core/src/test/java/org/sql2o/reflection/PojoMetadataTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package org.sql2o.reflection;

import javassist.*;
import org.junit.AssumptionViolatedException;
import org.junit.Test;

import java.util.HashMap;
import java.util.UUID;

import static org.junit.Assert.*;

/**
* Tests the {@link PojoMetadata} class.
* @author mavi
*/
public class PojoMetadataTest {
/**
* Tests that when there are two getters with different return types, the one with more concrete type is preferred.
* See https://github.com/aaberg/sql2o/issues/314 for more details.
*/
@Test
public void testPrefersGetterWithMoreConcreteType() throws Exception {
Class<?> clazz = createClassWithGetters(false);
if (clazz.getDeclaredMethods()[0].getReturnType() == Object.class) {
// the method order is undefined :( We need to have two methods, first one returning String, second one
// returning Object. The old PojoMetadata would incorrectly use the latter; the fixed version would use the
// function returning more concrete result.
//
// try to create the class with reversed method ordering, maybe it helps?
clazz = createClassWithGetters(true);
if (clazz.getDeclaredMethods()[0].getReturnType() == Object.class) {
// nah, didn't help. bail out.
throw new AssumptionViolatedException("Can't enforce method order");
}
}

final PojoMetadata metadata = new PojoMetadata(clazz, false, false, new HashMap<String, String>(), true);
assertEquals(String.class, metadata.getPropertyGetter("id").getType());
}

/**
* Tests that when there are two setters with different return types, the one with more concrete type is preferred.
* See https://github.com/aaberg/sql2o/issues/314 for more details.
*/
@Test
public void testPrefersSetterWithMoreConcreteType() throws Exception {
Class<?> clazz = createClassWithSetters(false);
if (clazz.getDeclaredMethods()[0].getParameterTypes()[0] == Object.class) {
// the method order is undefined :( We need to have two methods, first one returning String, second one
// returning Object. The old PojoMetadata would incorrectly use the latter; the fixed version would use the
// function returning more concrete result.
//
// try to create the class with reversed method ordering, maybe it helps?
clazz = createClassWithSetters(true);
if (clazz.getDeclaredMethods()[0].getParameterTypes()[0] == Object.class) {
// nah, didn't help. bail out.
throw new AssumptionViolatedException("Can't enforce method order");
}
}

final PojoMetadata metadata = new PojoMetadata(clazz, false, false, new HashMap<String, String>(), true);
assertEquals(String.class, metadata.getPropertySetter("id").getType());
}

private Class<?> createClassWithGetters(boolean objectThenString) throws CannotCompileException, NotFoundException {
final ClassPool pool = ClassPool.getDefault();
final CtClass ctClass = pool.makeClass("my.test.Klass" + UUID.randomUUID().toString().replace("-", ""));
ctClass.addField(new CtField(pool.get("java.lang.String"), "id", ctClass));
if (objectThenString) {
ctClass.addMethod(CtNewMethod.make("public Object getId() { return id; }", ctClass));
ctClass.addMethod(CtNewMethod.make("public String getId() { return id; }", ctClass));
} else {
ctClass.addMethod(CtNewMethod.make("public String getId() { return id; }", ctClass));
ctClass.addMethod(CtNewMethod.make("public Object getId() { return id; }", ctClass));
}
final Class<?> clazz = ctClass.toClass();
assertEquals(2, clazz.getDeclaredMethods().length);
return clazz;
}

private Class<?> createClassWithSetters(boolean objectThenString) throws CannotCompileException, NotFoundException {
final ClassPool pool = ClassPool.getDefault();
final CtClass ctClass = pool.makeClass("my.test.Klass" + UUID.randomUUID().toString().replace("-", ""));
ctClass.addField(new CtField(pool.get("java.lang.Object"), "id", ctClass));
if (objectThenString) {
ctClass.addMethod(CtNewMethod.make("public void setId(Object id) { this.id = id; }", ctClass));
ctClass.addMethod(CtNewMethod.make("public void setId(String id) { this.id = id; }", ctClass));
} else {
ctClass.addMethod(CtNewMethod.make("public void setId(String id) { this.id = id; }", ctClass));
ctClass.addMethod(CtNewMethod.make("public void setId(Object id) { this.id = id; }", ctClass));
}
final Class<?> clazz = ctClass.toClass();
assertEquals(2, clazz.getDeclaredMethods().length);
return clazz;
}
}

0 comments on commit b0c72df

Please sign in to comment.