/*
* (c) Copyright 2010-2011 by Volker Bergmann. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, is permitted under the terms of the
* GNU General Public License (GPL).
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* WITHOUT A WARRANTY OF ANY KIND. ALL EXPRESS OR IMPLIED CONDITIONS,
* REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE
* HEREBY EXCLUDED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.databene.benerator.anno;
import static org.junit.Assert.*;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import org.databene.benerator.distribution.sequence.StepSequence;
import org.databene.benerator.engine.BeneratorContext;
import org.databene.benerator.engine.DefaultBeneratorContext;
import org.databene.benerator.factory.EquivalenceGeneratorFactory;
import org.databene.benerator.sample.ConstantGenerator;
import org.databene.model.data.ArrayElementDescriptor;
import org.databene.model.data.ArrayTypeDescriptor;
import org.databene.model.data.DataModel;
import org.databene.model.data.InstanceDescriptor;
import org.databene.model.data.SimpleTypeDescriptor;
import org.databene.platform.db.DBSystem;
import org.databene.platform.java.BeanDescriptorProvider;
import org.junit.Before;
import org.junit.Test;
/**
* Tests the {@link AnnotationMapper}.<br/><br/>
* Created: 30.04.2010 13:57:59
* @since 0.6.1
* @author Volker Bergmann
*/
public class AnnotationMapperTest {
private AnnotationMapper annotationMapper;
private BeneratorContext context;
@Before
public void setUp() {
DataModel dataModel = new DataModel();
new BeanDescriptorProvider(dataModel);
EquivalenceGeneratorFactory generatorFactory = new EquivalenceGeneratorFactory();
context = new DefaultBeneratorContext();
context.setDataModel(dataModel);
context.setGeneratorFactory(generatorFactory);
annotationMapper = new AnnotationMapper(generatorFactory, dataModel, new DefaultPathResolver());
}
@Test
public void testUnannotated() throws Exception {
checkMethod("unannotatedMethod", String.class, "string");
}
public void unannotatedMethod(String name) { }
@Test
public void testGenerator() throws Exception {
checkMethod("generatorMethod", String.class, "string", "generator", "myGen");
}
public void generatorMethod(@Generator("myGen") String name) { }
@Test
public void testNullQuota() throws Exception {
checkMethod("nullQuotaMethod", String.class, "string", "nullQuota", 1.);
}
public void nullQuotaMethod(@NullQuota(1) String name) { }
@Test
public void testUniqueMethod() throws Exception {
Method stringMethod = getClass().getDeclaredMethod("uniqueMethod", new Class[] { String.class });
BeneratorContext context = new DefaultBeneratorContext();
AnnotationMapper mapper = new AnnotationMapper(new EquivalenceGeneratorFactory(), context.getDataModel(), new DefaultPathResolver());
ArrayTypeDescriptor type = mapper.createMethodParamsType(stringMethod);
InstanceDescriptor arrayDescriptor = mapper.createMethodParamsInstanceDescriptor(stringMethod, type);
assertEquals(true, arrayDescriptor.isUnique());
}
@Unique
public void uniqueMethod(String name) { }
@Test
public void testUniqueParam() throws Exception {
checkMethod("uniqueParam", String.class, "string", "unique", true);
}
public void uniqueParam(@Unique String name) { }
@Test
public void testValues() throws Exception {
checkMethod("valuesMethod", String.class, "string", "values", "'A','B'" );
}
public void valuesMethod(@Values({"A", "B"}) String name) { }
@Test
public void testPattern() throws Exception {
checkMethod("patternMethod", String.class, "string", "pattern", "ABC");
}
public void patternMethod(@Pattern(regexp = "ABC") String name) { }
@Test
public void testPatternMinMaxLength() throws Exception {
checkMethod("patternMinMaxLengthMethod", String.class, "string", "pattern", "[A-Z]*", "minLength", 5, "maxLength", 8);
}
public void patternMinMaxLengthMethod(@Pattern(regexp = "[A-Z]*") @Size(min = 5, max = 8) String name) { }
@Test
public void testDbSource() throws Exception {
checkMethod("dbSourceMethod", String.class, "string",
"source", "db",
"selector", "select id from db_user");
}
public void dbSourceMethod(@Source(id = "db", selector ="select id from db_user") String name) { }
@Test
public void testFileSource() throws Exception {
checkMethod("fileSourceMethod", String.class, "string",
"source", "customers.csv",
"dataset", "DE",
"nesting", "region",
"separator", ";",
"encoding", "UTF-8",
"filter", "candidate.age >= 18");
}
public void fileSourceMethod(
@Source(uri = "customers.csv", dataset = "DE", nesting = "region", separator = ";",
encoding = "UTF-8", filter ="candidate.age >= 18")
String name) {
}
// test number generation settings ---------------------------------------------------------------------------------
@Test
public void testStdSequenceInt() throws Exception {
checkMethod("predefSequenceIntMethod", int.class, "int",
"min", "3",
"max", "8",
"granularity", "2",
"distribution", "cumulated");
}
public void predefSequenceIntMethod(@Min(3) @Max(8) @Granularity(2) @Distribution("cumulated") int n) { }
@Test
public void testSequenceClassInt() throws Exception {
checkMethod("sequenceClassIntMethod", int.class, "int",
"distribution", StepSequence.class.getName());
}
public void sequenceClassIntMethod(
@Distribution("org.databene.benerator.distribution.sequence.StepSequence") int n) { }
@Test
public void testSequenceCtorInt() throws Exception {
checkMethod("sequenceCtorIntMethod", int.class, "int",
"distribution", "new " + StepSequence.class.getName() + "()");
}
public void sequenceCtorIntMethod(
@Distribution("new org.databene.benerator.distribution.sequence.StepSequence()") int n) { }
// testing lengths -------------------------------------------------------------------------------------------------
@Test
public void testPredefLengthSequenceInt() throws Exception {
checkMethod("predefLengthSequenceIntMethod", String.class, "string",
"minLength", 3,
"maxLength", 8,
"lengthDistribution", "cumulated");
}
public void predefLengthSequenceIntMethod(
@Size(min = 3, max = 8) @SizeDistribution("cumulated") String s) { }
@Test
public void testLengthSequenceClassInt() throws Exception {
checkMethod("lengthSequenceClassIntMethod", String.class, "string",
"lengthDistribution", StepSequence.class.getName());
}
public void lengthSequenceClassIntMethod(
@SizeDistribution("org.databene.benerator.distribution.sequence.StepSequence") String s) { }
@Test
public void testLengthSequenceCtorInt() throws Exception {
checkMethod("lengthSequenceCtorIntMethod", String.class, "string",
"lengthDistribution", "new " + StepSequence.class.getName() + "()");
}
public void lengthSequenceCtorIntMethod(
@SizeDistribution("new org.databene.benerator.distribution.sequence.StepSequence()") String s) { }
// test class annotations ------------------------------------------------------------------------------------------
@Test
public void testDatabaseAnnotation() {
annotationMapper.parseClassAnnotations(ClassWithDatabase.class.getAnnotations(), context);
DBSystem db = (DBSystem) context.get("db");
assertNotNull(db);
assertEquals("hsqlmem", db.getEnvironment());
}
@Database(id = "db", environment = "hsqlmem")
static class ClassWithDatabase {
}
@Test
public void testSimpleBeanAnnotation() {
annotationMapper.parseClassAnnotations(ClassWithSimpleBean.class.getAnnotations(), context);
Object bean = context.get("bean");
assertNotNull(bean);
assertEquals(ArrayList.class, bean.getClass());
}
@Bean(id = "bean", type = ArrayList.class)
static class ClassWithSimpleBean {
}
@Test
public void testBeanSpecAnnotation() {
annotationMapper.parseClassAnnotations(ClassWithBeanSpec.class.getAnnotations(), context);
Object bean = context.get("bean");
assertNotNull(bean);
assertEquals(Date.class, bean.getClass());
assertEquals(123, ((Date) bean).getTime());
}
@Bean(id = "bean", spec = "new java.util.Date(123)")
static class ClassWithBeanSpec {
}
@Test
public void testBeanPropertiesAnnotation() {
annotationMapper.parseClassAnnotations(ClassWithBeanProperties.class.getAnnotations(), context);
Object bean = context.get("bean");
assertNotNull(bean);
assertEquals(Date.class, bean.getClass());
assertEquals(234, ((Date) bean).getTime());
}
@Bean(id = "bean", type = Date.class, properties = { @Property(name="time", value="234") })
static class ClassWithBeanProperties {
}
@Test
public void testBeanPropertiesSpecAnnotation() {
annotationMapper.parseClassAnnotations(ClassWithBeanPropertiesSpec.class.getAnnotations(), context);
Object bean = context.get("bean");
assertNotNull(bean);
assertEquals(Date.class, bean.getClass());
assertEquals(345, ((Date) bean).getTime());
}
@Bean(id = "bean", spec = "new java.util.Date{ time = 345 }")
static class ClassWithBeanPropertiesSpec {
}
@Test
public void testBeanSource() {
annotationMapper.parseClassAnnotations(ClassWithBeanSource.class.getAnnotations(), context);
Object bean = context.get("bean");
assertNotNull(bean);
assertEquals(ConstantGenerator.class, bean.getClass());
assertEquals(42, ((ConstantGenerator<?>) bean).getValue());
}
@Bean(id = "bean", spec = "new org.databene.benerator.sample.ConstantGenerator(42)")
static class ClassWithBeanSource {
@Test
@Source("bean")
public void test(int value) {
}
}
// helper methods --------------------------------------------------------------------------------------------------
private void checkMethod(String methodName, Class<?> methodArgType, String expectedType, Object ... details)
throws NoSuchMethodException {
Method stringMethod = getClass().getDeclaredMethod(methodName, new Class[] { methodArgType });
DefaultBeneratorContext context = new DefaultBeneratorContext();
AnnotationMapper mapper = new AnnotationMapper(new EquivalenceGeneratorFactory(), context.getDataModel(), new DefaultPathResolver());
ArrayTypeDescriptor type = mapper.createMethodParamsType(stringMethod);
InstanceDescriptor arrayDescriptor = mapper.createMethodParamsInstanceDescriptor(stringMethod, type);
ArrayTypeDescriptor typeDescriptor = (ArrayTypeDescriptor) arrayDescriptor.getTypeDescriptor();
ArrayTypeDescriptor parentTypeDescriptor = typeDescriptor.getParent();
assertEquals(1, parentTypeDescriptor.getElements().size());
ArrayElementDescriptor param1 = typeDescriptor.getElement(0);
assertEquals(expectedType, ((SimpleTypeDescriptor) parentTypeDescriptor.getElement(0).getTypeDescriptor()).getPrimitiveType().getName());
for (int i = 0; i < details.length; i += 2) {
String detailName = (String) details[i];
Object expectedValue = details[i + 1];
Object actualValue;
if (param1.supportsDetail(detailName))
actualValue = param1.getDetailValue(detailName);
else
actualValue = param1.getTypeDescriptor().getDetailValue(detailName);
assertEquals(expectedValue, actualValue);
}
}
}