package org.simpleflatmapper.reflect.test;
import org.junit.Test;
import org.simpleflatmapper.reflect.*;
import org.simpleflatmapper.reflect.asm.AsmFactory;
import org.simpleflatmapper.reflect.impl.BuilderInstantiator;
import org.simpleflatmapper.reflect.getter.ConstantGetter;
import org.simpleflatmapper.reflect.getter.ConstantIntGetter;
import org.simpleflatmapper.reflect.impl.BuilderInstantiatorDefinitionFactory;
import org.simpleflatmapper.reflect.instantiator.ExecutableInstantiatorDefinition;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class BuilderInstantiatorDefinitionFactoryTest {
@Test
public void testBuilderFromMethod() throws Exception {
final List<InstantiatorDefinition> instantiatorDefinitions = BuilderInstantiatorDefinitionFactory.extractDefinitions(ClassBuilderWithMethod.class);
assertEquals(1, instantiatorDefinitions.size());
BuilderInstantiatorDefinition b = (BuilderInstantiatorDefinition) instantiatorDefinitions.get(0);
assertEquals(ClassBuilderWithMethod.Builder.class.getName(), b.getName());
// builder instantiator
final ExecutableInstantiatorDefinition builderInstantiator = (ExecutableInstantiatorDefinition) b.getBuilderInstantiator();
assertEquals(ClassBuilderWithMethod.class.getMethod("builder"), builderInstantiator.getExecutable());
assertEquals(0, builderInstantiator.getParameters().length);
final Parameter[] parameters = b.getParameters();
assertEquals(3, parameters.length);
Arrays.sort(parameters, new Comparator<Parameter>() {
@Override
public int compare(Parameter o1, Parameter o2) {
return o1.getName().compareTo(o2.getName());
}
});
assertEquals("name", parameters[1].getName());
assertEquals("id", parameters[0].getName());
Map<Parameter, Getter<? super Void, ?>> params = new HashMap<Parameter, Getter<? super Void, ?>>();
params.put(parameters[1], new ConstantGetter<Void, Object>("myname"));
params.put(parameters[0], new ConstantIntGetter<Void>(3));
final InstantiatorFactory instantiatorFactory = new InstantiatorFactory(new AsmFactory(getClass().getClassLoader()), true);
final Instantiator<Void, ClassBuilderWithMethod> instantiator = instantiatorFactory
.<Void, ClassBuilderWithMethod>getInstantiator(b, Void.class, params, true);
final ClassBuilderWithMethod o = instantiator
.newInstance(null);
assertFalse((instantiator instanceof BuilderInstantiator));
assertEquals("myname", o.getName());
assertEquals(3, o.getId());
}
@Test
public void testBuilderFromMethodNoAsm() throws Exception {
final List<InstantiatorDefinition> instantiatorDefinitions = BuilderInstantiatorDefinitionFactory.extractDefinitions(ClassBuilderWithMethod.class);
assertEquals(1, instantiatorDefinitions.size());
BuilderInstantiatorDefinition b = (BuilderInstantiatorDefinition) instantiatorDefinitions.get(0);
final Parameter[] parameters = b.getParameters();
Arrays.sort(parameters, new Comparator<Parameter>() {
@Override
public int compare(Parameter o1, Parameter o2) {
return o1.getName().compareTo(o2.getName());
}
});
Map<Parameter, Getter<? super Void, ?>> params = new HashMap<Parameter, Getter<? super Void, ?>>();
params.put(parameters[1], new ConstantGetter<Void, Object>("myname"));
params.put(parameters[0], new ConstantIntGetter<Void>(3));
final InstantiatorFactory instantiatorFactory = new InstantiatorFactory(null);
final Instantiator<Void, ClassBuilderWithMethod> instantiator = instantiatorFactory
.<Void, ClassBuilderWithMethod>getInstantiator(b, Void.class, params, true);
final ClassBuilderWithMethod o = instantiator
.newInstance(null);
assertEquals("myname", o.getName());
assertEquals(3, o.getId());
}
@Test
public void testBuilderFromMethodAsmBoxing() throws Exception {
final List<InstantiatorDefinition> instantiatorDefinitions = BuilderInstantiatorDefinitionFactory.extractDefinitions(ClassBuilderWithMethod.class);
assertEquals(1, instantiatorDefinitions.size());
BuilderInstantiatorDefinition b = (BuilderInstantiatorDefinition) instantiatorDefinitions.get(0);
final Parameter[] parameters = b.getParameters();
Arrays.sort(parameters, new Comparator<Parameter>() {
@Override
public int compare(Parameter o1, Parameter o2) {
return o1.getName().compareTo(o2.getName());
}
});
Map<Parameter, Getter<? super Void, ?>> params = new HashMap<Parameter, Getter<? super Void, ?>>();
params.put(parameters[1], new ConstantGetter<Void, Object>("myname"));
params.put(parameters[0], new ConstantGetter<Void, Integer>(3));
final InstantiatorFactory instantiatorFactory = new InstantiatorFactory(new AsmFactory(getClass().getClassLoader()), true);
final Instantiator<Void, ClassBuilderWithMethod> instantiator = instantiatorFactory
.<Void, ClassBuilderWithMethod>getInstantiator(b, Void.class, params, true);
final ClassBuilderWithMethod o = instantiator
.newInstance(null);
assertFalse((instantiator instanceof BuilderInstantiator));
assertEquals("myname", o.getName());
assertEquals(3, o.getId());
}
@Test
public void testBuilderFromMethodVoid() throws Exception {
final List<InstantiatorDefinition> instantiatorDefinitions = BuilderInstantiatorDefinitionFactory.extractDefinitions(ClassBuilderWithMethod.class);
assertEquals(1, instantiatorDefinitions.size());
BuilderInstantiatorDefinition b = (BuilderInstantiatorDefinition) instantiatorDefinitions.get(0);
final Parameter[] parameters = b.getParameters();
Arrays.sort(parameters, new Comparator<Parameter>() {
@Override
public int compare(Parameter o1, Parameter o2) {
return o1.getName().compareTo(o2.getName());
}
});
Map<Parameter, Getter<? super Void, ?>> params = new HashMap<Parameter, Getter<? super Void, ?>>();
params.put(parameters[2], new ConstantGetter<Void, Object>("zrux"));
params.put(parameters[0], new ConstantGetter<Void, Integer>(3));
final InstantiatorFactory instantiatorFactory = new InstantiatorFactory(new AsmFactory(getClass().getClassLoader()), true);
final Instantiator<Void, ClassBuilderWithMethod> instantiator = instantiatorFactory
.<Void, ClassBuilderWithMethod>getInstantiator(b, Void.class, params, true);
final ClassBuilderWithMethod o = instantiator
.newInstance(null);
assertFalse((instantiator instanceof BuilderInstantiator));
assertEquals(3, o.getId());
assertEquals("zrux", o.getZrux());
}
@Test
public void testBuilderFromMethodVoidNoAsm() throws Exception {
final List<InstantiatorDefinition> instantiatorDefinitions = BuilderInstantiatorDefinitionFactory.extractDefinitions(ClassBuilderWithMethod.class);
assertEquals(1, instantiatorDefinitions.size());
BuilderInstantiatorDefinition b = (BuilderInstantiatorDefinition) instantiatorDefinitions.get(0);
final Parameter[] parameters = b.getParameters();
Arrays.sort(parameters, new Comparator<Parameter>() {
@Override
public int compare(Parameter o1, Parameter o2) {
return o1.getName().compareTo(o2.getName());
}
});
Map<Parameter, Getter<? super Void, ?>> params = new HashMap<Parameter, Getter<? super Void, ?>>();
params.put(parameters[2], new ConstantGetter<Void, Object>("zrux"));
params.put(parameters[0], new ConstantGetter<Void, Integer>(3));
final InstantiatorFactory instantiatorFactory = new InstantiatorFactory(null, true);
final Instantiator<Void, ClassBuilderWithMethod> instantiator = instantiatorFactory
.<Void, ClassBuilderWithMethod>getInstantiator(b, Void.class, params, true);
final ClassBuilderWithMethod o = instantiator
.newInstance(null);
assertTrue((instantiator instanceof BuilderInstantiator));
assertEquals(3, o.getId());
assertEquals("zrux", o.getZrux());
}
public static abstract class ClassBuilderWithMethod {
public abstract String getName();
public abstract int getId();
public abstract String getZrux();
public static Builder builder() {
return new Builder();
}
public static class Builder {
private final String name;
private final int id;
private String zrux;
private Builder() {
name = null;
id = 0;
zrux = null;
}
public Builder(String name, int id, String zrux) {
this.name = name;
this.id = id;
this.zrux = zrux;
}
public Builder id(int id) {
return new Builder(name, id, zrux);
}
public Builder name(String name) {
return new Builder(name, id, zrux);
}
public void zrux(String zrux) {
this.zrux = zrux;
}
public ClassBuilderWithMethod build() {
return new ClassBuilderWithMethodImpl(name, id, zrux);
}
}
private static class ClassBuilderWithMethodImpl extends ClassBuilderWithMethod {
private final String name;
private final String zrux;
private final int id;
private ClassBuilderWithMethodImpl(String name, int id, String zrux) {
this.name = name;
this.id = id;
this.zrux = zrux;
}
@Override
public String getName() {
return name;
}
@Override
public int getId() {
return id;
}
@Override
public String getZrux() {
return zrux;
}
}
}
}