org.itest.impl.ITestDefinitionFactoryImpl Maven / Gradle / Ivy
The newest version!
/**
*
* The MIT License (MIT)
*
* Copyright (c) 2014 Grzegorz Kochański
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package org.itest.impl;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.itest.ITestConfig;
import org.itest.declaration.ITest;
import org.itest.declaration.ITestRef;
import org.itest.declaration.ITests;
import org.itest.definition.ITestDefinition;
import org.itest.definition.ITestDefinitionFactory;
import org.itest.exception.ITestParamDefinitionException;
import org.itest.param.ITestParamAssignment;
import org.itest.param.ITestParamState;
public class ITestDefinitionFactoryImpl implements ITestDefinitionFactory {
private final Map> itestDependencyMap = new HashMap>();
private final Map itestMap = new HashMap();
private final Map itestDefinitionMap = new HashMap();
private static final String[] EMPTY_TRANSFORMATION = { "" };
private final ITestConfig iTestConfig;
private final byte[] buffer = new byte[1024];
public ITestDefinitionFactoryImpl(ITestConfig iTestConfig) {
this.iTestConfig = iTestConfig;
}
@Override
public Collection buildTestFlowDefinitions(Class>... classes) {
for (Class> clazz : classes) {
buildDependencies(clazz);
}
for (ITestIdentifier itestIdentifier : itestMap.keySet()) {
buildDefinition(itestIdentifier);
}
return itestDefinitionMap.values();
}
private void buildDefinition(ITestIdentifier itestIdentifier) {
Collection children = itestDependencyMap.get(itestIdentifier);
if ( null != children ) {
for (ITestDependency child : itestDependencyMap.get(itestIdentifier)) {
buildDefinition(child.itestIdentifier);
}
define(itestIdentifier);
}
}
private void define(ITestIdentifier itestIdentifier) {
if ( null == itestDefinitionMap.get(itestIdentifier) ) {
ITestDeclaration itestDefinition = itestMap.get(itestIdentifier);
// Collection transformations = new ArrayList();
// Collection params = new ArrayList();
Collection iTestParamAssignments = new ArrayList();
for (ITestDependency child : itestDependencyMap.get(itestIdentifier)) {
ITestDefinition childPathDefintion = itestDefinitionMap.get(child.itestIdentifier);
// transformations.add(child.transformation);
ITestParamState childParams;
if ( null == childPathDefintion ) {
childParams = loadParams(child.itestIdentifier);
} else {
childParams = childPathDefintion.getInitParams();
}
// params.add(childParams);
iTestParamAssignments.add(new ITestParamAssignmentImpl(child.transformation, childParams));
}
if ( null != itestDefinition.path.init() ) {
iTestParamAssignments.add(new ITestParamAssignmentImpl(EMPTY_TRANSFORMATION,
// parseInitParam(itestDefinition.method, itestDefinition.path.init())
itestDefinition.path.init()));
}
Map, Map> iTestStaticAssignment = Collections.emptyMap();// toITestStaticAssignment(itestDefinition.path.assignment());
ITestParamAssignment[] iTestParamAssignmentsArray = iTestParamAssignments.toArray(new ITestParamAssignment[iTestParamAssignments.size()]);
ITestParamState itestParams = iTestConfig.getITestParamsMerger().merge(iTestParamAssignmentsArray);
ITestDefinition res = new ITestDefinitionImpl(itestDefinition.method.getDeclaringClass(), itestDefinition.method, itestIdentifier.itestName,
itestParams, itestDefinition.path.verify(), new HashMap(), iTestStaticAssignment);
itestDefinitionMap.put(itestIdentifier, res);
}
}
private ITestParamState loadParams(ITestIdentifier itestIdentifier) {
return iTestConfig.getITestParamLoader().loadITestParam(itestIdentifier.itestClass, itestIdentifier.itestName);
}
// TODO: check if required
// private Map, Map> toITestStaticAssignment(ITestAssignment[] assignment) {
// Map, Map> assignmentMap = new HashMap, Map>();
// for (ITestAssignment iTestAssignment : assignment) {
// Map fieldMap = assignmentMap.get(iTestAssignment.targetClass());
// if ( null == fieldMap ) {
// fieldMap = new HashMap();
// assignmentMap.put(iTestAssignment.targetClass(), fieldMap);
// }
// fieldMap.put(iTestAssignment.targetField(), iTestAssignment.sourcePath());
// }
// return assignmentMap;
// }
private void buildDependencies(Class> clazz) {
L: for (Method method : clazz.getDeclaredMethods()) {
ITests iTests = iTestConfig.getITestDeclarationProvider().getITestDeclaration(method);
if ( null != iTests ) {
int methodTestCounter = 0;
for (ITest path : iTests.value()) {
String testName = path.name();
if ( 0 == testName.length() ) {
testName = method.getName() + "#itest" + methodTestCounter;
}
ITestIdentifier itestIdentifier = new ITestIdentifier(clazz, testName);
if ( null == itestMap.get(itestIdentifier) ) {
itestMap.put(itestIdentifier, new ITestDeclaration(method, path));
Collection col = new ArrayList();
itestDependencyMap.put(itestIdentifier, col);
for (ITestRef initRef : path.initRef()) {
Class> refClass = null == initRef.useClass() ? clazz : initRef.useClass();
String refTestName = initRef.use();
col.add(new ITestDependency(initRef.assign(), new ITestIdentifier(refClass, refTestName)));
if ( refClass != clazz ) {
buildDependencies(refClass);
}
}
} else {
break L;
}
methodTestCounter++;
}
}
}
}
static class ITestDependency {
private final String[] transformation;
private final ITestIdentifier itestIdentifier;
public ITestDependency(String[] transform, ITestIdentifier itestIdentifier) {
this.transformation = transform;
this.itestIdentifier = itestIdentifier;
}
}
static class ITestIdentifier {
Class> itestClass;
String itestName;
public ITestIdentifier(Class> itestClass, String itestName) {
this.itestClass = itestClass;
this.itestName = itestName;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((itestClass == null) ? 0 : itestClass.hashCode());
result = prime * result + ((itestName == null) ? 0 : itestName.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if ( this == obj ) {
return true;
}
if ( obj == null ) {
return false;
}
if ( getClass() != obj.getClass() ) {
return false;
}
ITestIdentifier other = (ITestIdentifier) obj;
if ( itestClass == null ) {
if ( other.itestClass != null ) {
return false;
}
} else if ( !itestClass.equals(other.itestClass) ) {
return false;
}
if ( itestName == null ) {
if ( other.itestName != null ) {
return false;
}
} else if ( !itestName.equals(other.itestName) ) {
return false;
}
return true;
}
@Override
public String toString() {
return itestClass.getName() + "." + itestName;
}
}
static class ITestDeclaration {
private final Method method;
private final ITest path;
public ITestDeclaration(Method method, ITest path) {
this.method = method;
this.path = path;
}
public Method getMethod() {
return method;
}
public ITest getPath() {
return path;
}
}
private ITestParamState parseInitParam(Method method, String init) {
try {
ITestParamState res = iTestConfig.getITestParamParser().parse(init);
return res;
} catch (RuntimeException e) {
throw new ITestParamDefinitionException(method, null, init, e);
}
}
}