Skip to content

Commit

Permalink
Merge pull request #15 from EaseTech/master
Browse files Browse the repository at this point in the history
Fixed issue #1 and #2
  • Loading branch information
ravi-polampelli committed Nov 21, 2012
2 parents 612cbac + 1034c00 commit 2a43db1
Show file tree
Hide file tree
Showing 18 changed files with 607 additions and 463 deletions.
243 changes: 166 additions & 77 deletions src/main/java/org/easetech/easytest/annotation/Param.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@

package org.easetech.easytest.converter;

import java.lang.reflect.Modifier;

import junit.framework.Assert;

import java.lang.reflect.ParameterizedType;

/**
*
* An abstract class that can be used by the user to define their converters.
* It hides behind it the convertTo method implementation to get the converted object's class
*
* An abstract class that can be used by the user to define their converters. It hides behind it the convertTo method
* implementation to get the converted object's class
*
* @param <Type> the type of object to convert to.
*/
public abstract class AbstractConverter<Type> implements Converter<Type> {
Expand All @@ -24,4 +29,46 @@ public Class<Type> convertTo() {
return type;
}

/**
* Method responsible for returning an instance of the provided Generic Type argument.
* The default implementation assumes that the generic type argument is a concrete type with a default
* no arg constructor. It calls the {@link Class#newInstance()} method to return the instance.
* If the passed generic type argument is an interface or an abstract type, then the method calls the {@link Assert#fail()}
* telling the user that the passed Class object was not a Concrete class.
*
* <br>
* A user can always extend this behavior to return specific instances in case the passed instance is an interface or an abstract class.
* It is recommended to extend the Abstract Converter instead of implementing the Converter interface directly.
* @return an instance of the generic type argument passed to the {@link AbstractConverter}
*/
@Override
public Type instanceOfType() {
Type type = null;
Class<Type> classType = convertTo();
try {
type = classType.newInstance();
} catch (InstantiationException e) {
if (classType.isInterface()) {
Assert
.fail(classType.getCanonicalName()
+ " is not of Concrete type. EasyTest cannot instantiate an interface. Please provide a Concrete type as Generic Parameter Type while extending "
+ AbstractConverter.class.getSimpleName());
} else if (Modifier.isAbstract(convertTo().getModifiers())) {
Assert
.fail(classType.getCanonicalName()
+ " is not of Concrete type. EasyTest cannot instantiate an abstract class. Please provide a Concrete type as Generic Parameter Type while extending "
+ AbstractConverter.class.getSimpleName());
}
else{
Assert
.fail("Error instantiating a class of type "+ classType.toString() + e.getMessage());
}

} catch (IllegalAccessException e) {
Assert
.fail("IllegalAccessException occured while instantiating a class of type "+ classType.toString() + e.getMessage());
}
return type;
}

}
9 changes: 8 additions & 1 deletion src/main/java/org/easetech/easytest/converter/Converter.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
public interface Converter<Type> {

/**
* The class of the object to convert to
* The class of the generic type argument to which the data should be converted to.
* @return the class of the object to convert to
*/
Class<Type> convertTo();
Expand All @@ -22,5 +22,12 @@ public interface Converter<Type> {
* @return the object to convert to identified by {@link #convertTo()} class.
*/
Type convert(Map<String , Object> convertFrom);

/**
* Method responsible for returning an instance of the provided Generic Type argument.
* Look at {@link AbstractConverter#instanceOfType()} methods Javadoc for details on the default implementation.
* @return an instance of the provided Generic Type argument.
*/
Type instanceOfType();

}
36 changes: 20 additions & 16 deletions src/main/java/org/easetech/easytest/converter/ConverterManager.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

package org.easetech.easytest.converter;


import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
Expand All @@ -21,30 +20,32 @@ public class ConverterManager {

/**
* Find the registered Converter for the given class type
*
* @param targetType the class type to find teh converter for.
* @return an instance of registered converter or Null if not found.
*/
public static Converter<?> findConverter(Class<?> targetType) {

Set<Converter> cnvrtrs = converters.get();
Converter result = null;
if(cnvrtrs!=null){
Iterator<Converter> itr = cnvrtrs.iterator();
while (itr.hasNext()) {
Converter converter = itr.next();
if (converter.convertTo().equals(targetType)) {
result = converter;
break;
}
}
}
Set<Converter> cnvrtrs = converters.get();
Converter result = null;
if (cnvrtrs != null) {
Iterator<Converter> itr = cnvrtrs.iterator();

while (itr.hasNext()) {
Converter converter = itr.next();
if (converter.convertTo().equals(targetType)) {
result = converter;
break;
}
}
}

return result;
}

/**
* Register the converter with the ConverterManager
*
* @param converterClass the class object identifying the concrete {@link Converter} class.
*/
public static void registerConverter(Class converterClass) {
Expand All @@ -69,7 +70,10 @@ public static void registerConverter(Class converterClass) {
}

} else {
System.out.println("Converter with class :" + converterClass + " not registered");
throw new RuntimeException("Could not register the converter for " + converterClass
+ " . Either the passed argument is NULL or the passed class does not extend the "
+ AbstractConverter.class.getSimpleName() + " abstract class or implement the "
+ Converter.class.getSimpleName() + " interface.");
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@
import java.util.Collection;
import java.util.Iterator;

/**
*
* An extension of {@link RuntimeException} class that handles {@link ParamAssertionError}
*
* @author Anuj Kumar
*
*/
public class ParamAssertionError extends RuntimeException {

private static final long serialVersionUID = 1L;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
* A internal util class for working with the parameters of a test method.
* This class provides EasyTest the facility to identify the method arguments, identify the DataSupplier
* associated with the Test Framework and more.
*
* @author Anuj Kumar
*
*/
public class EasyAssignments {
Expand Down Expand Up @@ -94,9 +96,9 @@ public List<PotentialAssignment> potentialsForNextUnassigned() throws Instantiat

/**
* Get the instance of class that provides the functionality to provide Data.
* In our case, its always {@link Param.DataSupplier}
* In our case, its always {@link org.easetech.easytest.annotation.Param.DataSupplier}
* @param unassigned
* @return {@link Param.DataSupplier}
* @return {@link org.easetech.easytest.annotation.Param.DataSupplier}
* @throws InstantiationException
* @throws IllegalAccessException
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
*
* A single instance of {@link EasyParamSignature}
* identifies a single test method parameter associated with the test method
*
* @author Anuj Kumar
*
*/
public class EasyParamSignature {
Expand Down
12 changes: 10 additions & 2 deletions src/main/java/org/easetech/easytest/loader/CSVDataLoader.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@

package org.easetech.easytest.loader;

import java.lang.reflect.Array;

import com.csvreader.CsvReader;
import com.csvreader.CsvWriter;
import java.io.FileNotFoundException;
Expand Down Expand Up @@ -38,6 +40,10 @@
* A CSV cannot have a blank line in between test data whether it is for a single test or for multiple tests.
* The framework is capable of handling multiple test datas for multiple test methods in a single CSV file.
* Although a user can choose to define the test data in multiple files as well.
* <br>
* If you want to pass a Collection to the test method, just separate each instance with a ":". For eg. to pass
* a list of Itemids , pass them as a colon separated list like this -> 12:34:5777:9090
*
*
* @author Anuj Kumar
*
Expand Down Expand Up @@ -179,7 +185,8 @@ public void writeData(String[] filePaths, String methodName, Map<String, List<Ma
String[] dataKeys = null;
while (csvReader.readRecord()) {
String[] splitValues = csvReader.getValues();
String[] newSplitValues = Arrays.copyOf(splitValues, splitValues.length);
String[] newSplitValues = (String[])Array.newInstance(String[].class.getComponentType(), splitValues.length);
System.arraycopy(splitValues, 0, newSplitValues, 0, Math.min(splitValues.length, newSplitValues.length));
if (splitValues.length > 0 && "".equals(splitValues[0])) {
isKeyRow = false;

Expand All @@ -199,7 +206,8 @@ public void writeData(String[] filePaths, String methodName, Map<String, List<Ma
if (currentMethodData != null && !currentMethodData.isEmpty()) {
if (currentMethodData.get(0).keySet().contains(Loader.ACTUAL_RESULT)) {
int length = splitValues.length;
newSplitValues = Arrays.copyOf(splitValues, length + 1);
newSplitValues = (String[])Array.newInstance(String[].class.getComponentType(), length + 1);
System.arraycopy(splitValues, 0, newSplitValues, 0, Math.min(splitValues.length, newSplitValues.length));
newSplitValues[length] = Loader.ACTUAL_RESULT;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public Map<String, List<Map<String, Object>>> loadData(String[] filePaths) {

@Override
public void writeData(String[] filePaths, String methodName, Map<String, List<Map<String, Object>>> actualData) {
// TODO Auto-generated method stub
//do nothing

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
* The framework is capable of handling multiple test data for multiple test methods in a single Excel file.
* Although a user can choose to define the test data in multiple files as well.
*
* <br>
* If you want to pass a Collection to the test method, just separate each instance with a ":". For eg. to pass
* a list of Itemids , pass them as a colon separated list like this -> 12:34:5777:9090
*
* @author Anuj Kumar
*
*/
Expand Down
11 changes: 7 additions & 4 deletions src/main/java/org/easetech/easytest/loader/XMLDataLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:org:easetech:easytest:1.0 testDataSchema.xsd"&gt;<br>
* <B>&lt;TestMethod name="getSimpleData"&gt;</B><br>
* &nbsp;&nbsp;&lt;TestRecord&gt;<br>
* &nbsp;&nbsp;&lt;TestRecord id="1"&gt;<br>
* &nbsp;&nbsp;&lt;InputData&gt;<br>
* &nbsp;&nbsp;&nbsp;&lt;Entry key="libraryId" value="91475" /&gt;<br>
* &nbsp;&nbsp;&nbsp;&lt;Entry key="itemId" value="12" /&gt;<br>
* &nbsp;&nbsp;&nbsp;&lt;Entry key="itemType" value="book" /&gt;<br>
* &nbsp;&nbsp;&lt;/InputData&gt;<br>
* &nbsp;&nbsp;&lt;/TestRecord&gt;<br>
* &nbsp;&nbsp;&lt;TestRecord&gt;<br>
* &nbsp;&nbsp;&lt;TestRecord id="2"&gt;<br>
* &nbsp;&nbsp;&lt;InputData&gt;<br>
* &nbsp;&nbsp;&nbsp;&lt;Entry key="libraryId" value="234" /&gt;<br>
* &nbsp;&nbsp;&nbsp;&lt;Entry key="itemId" value="1452" /&gt;<br>
Expand All @@ -65,14 +65,14 @@
* &nbsp;&nbsp;&lt;/TestRecord&gt;<br>
* <B>&lt;/TestMethod&gt;</B><br>
* <B>&lt;TestMethod name="getAnotherData"&gt;</B><br>
* &nbsp;&nbsp;&lt;TestRecord&gt;<br>
* &nbsp;&nbsp;&lt;TestRecord id="3"&gt;<br>
* &nbsp;&nbsp;&lt;InputData&gt;<br>
* &nbsp;&nbsp;&nbsp;&lt;Entry key="picId" value="1111" /&gt;<br>
* &nbsp;&nbsp;&nbsp;&lt;Entry key="picNum" value="12" /&gt;<br>
* &nbsp;&nbsp;&nbsp;&lt;Entry key="picFormat" value="jpeg" /&gt;<br>
* &nbsp;&nbsp;&lt;/InputData&gt;<br>
* &nbsp;&nbsp;&lt;/TestRecord&gt;<br>
* &nbsp;&nbsp;&lt;TestRecord&gt;<br>
* &nbsp;&nbsp;&lt;TestRecord id="4"&gt;<br>
* &nbsp;&nbsp;&lt;InputData&gt;<br>
* &nbsp;&nbsp;&nbsp;&lt;Entry key="picId" value="1561" /&gt;<br>
* &nbsp;&nbsp;&nbsp;&lt;Entry key="picNum" value="178" /&gt;<br>
Expand All @@ -85,6 +85,9 @@
* As you can guess, the root element is {@link InputTestData} that can have multiple {@link TestMethod} elements in it.<br>
* Each {@link TestMethod} element identifies a method to test with its name attribute.<br>
* Each {@link TestMethod} can have many TestRecords. Each Record identifies data for a single test execution.<br>
* Each {@link TestRecord} element has an id attribute. This id attribute has to be unique in the entire XML file.
* So you should not have the id = 1 for more than one test record. If you do, then the behavior is undefined in such a scenario.
* <br>
* {@link TestRecord} contains {@link InputData} element as well as {@link OutputData} element. A user never specifies an {@link OutputData} element.
* If it is specified, it will be ignored by the {@link Loader}. {@link OutputData} is used internally by the {@link XMLDataLoader} to write output data back to the file.
* Each Entry element identifies a method parameter.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public void setEndInNano(long endInNano) {
/**
* Time difference in nano seconds
*
* @return
* @return Time difference in nano seconds
*/
public long getNanoDifference() {
return (this.endInNano - this.startInNano);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,16 @@ public class DataDrivenTestRunner extends Suite {
* contains all the available test data key / value pairs for easy consumption by the user. It also supports user
* defined custom Objects as parameters.<br>
* <br>
* Finally, EasyTest also supports {@link Intercept} annotation. This annotation can be used to intercept calls to
* the test subject that is currently being tested. For eg. if you want to capture how much time a particular method
* of the actual service class is taking, then you can mark the field representing the testSubject with
* {@link Intercept} annotation. The framework also provides convenient way to write your own custom method
* interceptors.
*
*
* @author Anuj Kumar
*/

// Finally, EasyTest also supports {@link Intercept} annotation. This annotation can be used to intercept calls to
// * the test subject that is currently being tested. For eg. if you want to capture how much time a particular method
// * of the actual service class is taking, then you can mark the field representing the testSubject with
// * {@link Intercept} annotation. The framework also provides convenient way to write your own custom method
// * interceptors.
private class EasyTestRunner extends BlockJUnit4ClassRunner {

/**
Expand Down Expand Up @@ -436,7 +438,7 @@ public void evaluate() throws Throwable {
* This method encapsulates the actual change in behavior from the traditional JUnit Theories way of
* populating and supplying the test data to the test method. This method creates a list of
* {@link Assignments} identified by {@link #listOfAssignments} and then calls
* {@link #runWithCompleteAssignment(Assignments)} for each {@link Assignments} element in the
* {@link #runWithCompleteAssignment(EasyAssignments)} for each {@link Assignments} element in the
* {@link #listOfAssignments}
*
* @param parameterAssignment an instance of {@link Assignments} identifying the parameters that needs to be
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/easetech/easytest/util/CommonUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public static Double getRounded(double valueToRound, int numberOfDecimalPlaces)
* Create directory
*
* @param destinationFolder
* @return
* @return a string representing the path to the output folder.
*/
public static String createDefaultOutputFolder(String destinationFolder) {
if (destinationFolder == null || destinationFolder.equals("")) {
Expand Down
7 changes: 0 additions & 7 deletions src/main/java/org/easetech/easytest/util/ReflectionsUtil.java

This file was deleted.

Loading

0 comments on commit 2a43db1

Please sign in to comment.