Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Javadoc and fix codacy problems #7

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,26 @@
*/
package org.atlanmod.testing;


/**
*
* An object able to randomly generate values of different data types
*
* @param <T> the type of the values to be generated
*/
public interface Generator <T> {

/**
* function responsible for generating values
*
* @return single value of the type T
*/
T generate() ;

/**
* Returns all of the data types the current class is able to generate.
*
* @return an array of class types.
*/
Class<T>[] types();

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,44 @@
package org.atlanmod.testing;

import org.atlanmod.commons.reflect.MoreReflection;

import java.io.*;
import java.util.function.Function;
import java.util.stream.Stream;



/**
* Verifies that the {@code serializable()} interface of a class was correctly implemented, checking that:
*
* - An object is serializable and serialize it by converting it into a sequence (stream) of bytes
* - Deserialize by reading the stream of bytes and convert it back into a Java object
* - The resulting object is equals to the object we want to test.
*
* @param <T>
*/
public class SerializationVerifier<T extends Serializable> {
private Class<T> type;
private Object[] arguments;
private static final long serialVersionUID = 1623437;

/**
* Creates an instance of {@code SerializationVerifier} for class {@code type}.
*
* @param type the class to be verified.
*/
SerializationVerifier(Class<T> type) {
this.type = type;
}

/**
* Arguments are used to create a reference instance of class {@code type}. The reference instance is used
* to be serialized,deserialized in another object and compare it to the resulting object.
*
* The types and the length of {@code arguments} must match either a visible constructor or a static
* method (a factory) that returns an instance of {@code type}.
*
*
* @param arguments an array of instances of {@link Object}.
* @return the current verifier.
*/
public SerializationVerifier<T> withArguments(Object... arguments) {
this.arguments = arguments;
return this;
Expand All @@ -35,6 +57,10 @@ private static Class[] mapToClasses(Object[] objects) {
.toArray(Class[]::new);
}

/**
* Verifies the implementation of interface {@code serializable()}.
*
*/
public void check() throws IOException, ClassNotFoundException {
Class[] argumentTypes = mapToClasses(arguments);
Function<Object[], T> instantiator = MoreReflection.getInstantiator(type, argumentTypes);
Expand All @@ -45,7 +71,7 @@ public void check() throws IOException, ClassNotFoundException {
oos.writeObject(object);
//deserialiser object
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(boos.toByteArray()));
Object object2 = (Object) ois.readObject();
Object object2 = ois.readObject();
assertIsEqual(object,object2);
}

Expand Down
83 changes: 55 additions & 28 deletions commons-testing/src/main/java/org/atlanmod/testing/Verifier.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

import org.atlanmod.commons.Throwables;
import org.atlanmod.testing.generator.*;

import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
Expand Down Expand Up @@ -38,18 +37,18 @@
* </code></pre>
*/
public class Verifier {
private static final Map<Class<?>,Generator<?>> generators= new HashMap<>();
private static final Map<Class<?>, Generator<?>> generators = new HashMap<>();
private static Generator<String> stringGenerator = new RandomStringGenerator();
private static Generator<Integer> integerGenerator = new RandomIntegerGenerator();
private static Generator<Character> charGenerator = new RandomCharGenerator();
//private static Generator byteGenerator= new RandomByteGenerator();
private static Generator byteGenerator= new RandomByteGenerator();
private static Generator<Boolean> booleanGenerator = new RandomBooleanGenerator();

static {
registerGenerator(integerGenerator);
registerGenerator(stringGenerator);
registerGenerator(charGenerator);
//registerGenerator(byteGenerator);
registerGenerator(byteGenerator);
registerGenerator(booleanGenerator);
}

Expand All @@ -61,7 +60,7 @@ private Verifier() {
* Creates a {@link EqualsVerifier} for class {@code type}.
*
* @param type the class whose {@code equals()} method will be verified.
* @param <T> the actual class of the class {@type}.
* @param <T> the actual class of the class {@type}.
* @return an instance of {@link EqualsVerifier}.
*/
public static <T> EqualsVerifier<T> verifyEqualsOf(Class<T> type) {
Expand All @@ -72,33 +71,39 @@ public static <T> EqualsVerifier<T> verifyEqualsOf(Class<T> type) {
* Creates a {@link SerializationVerifier} for class {@code type}.
*
* @param type the class whose {@code serialize()} method will be verified.
* @param <T> the actual class of the class {@type}.
* @param <T> the actual class of the class {@type}.
* @return an instance of {@link SerializationVerifier}.
*/
public static <T extends Serializable> SerializationVerifier<T> verifySerialization(Class<T> type) {
return new SerializationVerifier<>(type);
}

/**
* Register a new generator by adding it in the hashmap generators.
*
* Register a new generator for a specific type.
*
* @param generator the generator of the target class.
* @param <T> the target class to generate.
* @param <T> the target class to generate.
*/
public static <T> void registerGenerator(Generator <T> generator) {
for (Class<?> type :generator.types() ) {
public static <T> void registerGenerator(Generator<T> generator) {
for (Class<?> type : generator.types()) {
generators.put(type, generator);
}
}

/**
*creation of an array generator from his simple generator.
* @param gen the simple generator
* Return a {@link Generator} that generates an array of type {@code arrayType}
*
* creation of an array generator from his simple generator.
*
* @param gen the simple generator
* @param arrayType the class of the array generator we want to create
* @return An array generator
*/
public static Generator createArrayGenerator(Generator gen,Class arrayType) {
Random random =new Random();
int length= random.nextInt(10) + 1;
public static Generator createArrayGenerator(Generator gen, Class arrayType) {
Random random = new Random();
int length = random.nextInt(10) + 1;
return new Generator() {
@Override
public Object generate() {
Expand All @@ -108,6 +113,7 @@ public Object generate() {
}
return list;
}

@Override
public Class[] types() {
List<Class> listTypes = new ArrayList<>();
Expand All @@ -120,28 +126,38 @@ public Class[] types() {
}

/**
* Returns the appropriate generators for each of {@code constr} parameters
*
* For each of {@code constr} parameters :
* - if the parameter is a singular value and its generator is available : add generator to the list {@code generate}.
* - if the parameter is an array and a generator for singular value is available :
* call to createArrayGenerator, new array generator is added to the list {@code generate}
* - if the parameter is a singular value or array but the generator for singular value is not available : return an empty instance of {@link Optional}
*
*
* Provide an optional list which contains the specific generator of each parameter of the constructor
*
* @param constr the constructor to be verified
* @return An optional list of generator
*/
private static Optional<List<Generator>> getGeneratorsForConstructor (Constructor<?> constr) {
if(constr.getParameters().length==0) {
private static Optional<List<Generator>> getGeneratorsForConstructor(Constructor<?> constr) {
if (constr.getParameters().length == 0) {
return Optional.of(Collections.emptyList());
}
List<Generator> generate = new ArrayList<>();
for (Class<?> type : constr.getParameterTypes()) {
Generator newgen = generators.get(type);
if (newgen==null && type.isArray()) {
if (newgen == null && type.isArray()) {
Class<?> arrayType = type.getComponentType();
newgen = generators.get(arrayType);
if (newgen!=null) {
if (newgen != null) {
//Creer le nouveau generateur d'array à partir de newgen et l'ajouter à generators
Generator newGenerator = createArrayGenerator(newgen, arrayType);
registerGenerator(newGenerator);
newgen = newGenerator;
}
}
if(newgen==null) {
if (newgen == null) {
return Optional.empty();
}
generate.add(newgen);
Expand All @@ -150,7 +166,15 @@ private static Optional<List<Generator>> getGeneratorsForConstructor (Constructo
}

/**
*Generate a new instance of a constructor and return it.
* Return a new instance of the constructor {@code construc}
*
* Get the list of generators of the different parameters of this constructor using {@code getGeneratorsForConstructor}.
* Then call each of these generators to generate a value and add it to a list of objects.
* Create a new instance of the constructor {@code construc} using the generated values.
*
*
* Generate a new instance of a constructor and return it.
*
* @param construc the constructor we want to generate
* @return A new instance of a constructor
*/
Expand All @@ -161,26 +185,33 @@ public static Object generateConstructor(Constructor<?> construc) {
generatedArguments.add(gen.generate());
}
try {
return construc.newInstance(generatedArguments.toArray());
} catch (InstantiationException | IllegalAccessException |InvocationTargetException e ) {
return construc.newInstance(generatedArguments.toArray());
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
return e.getCause().getClass();
}
}

/**
* Get all the constructor of the class {@code klass}
* For each constructor :
* - Get the list of generators of the different parameters using {@code getGeneratorsForConstructor}
* - If the list is not empty then generate the values and create a new instance of the constructor.
*
*
* Generate a new instance of the constructors of a class and put them in a list.
*
* @param klass the class we want to generate all constructors
* @return A list of objects of type klass
*/
public static List<Object> generateConstructorsOfClass(Class klass) {
public static List<Object> generateConstructorsOfClass(Class klass) {
if (klass.getName().equals(Integer.class.getName())) {
registerGenerator(new RandomStringOfIntGenerator());
}
List<Object> listConstructors = new ArrayList<>();
for (Constructor<?> each : klass.getConstructors()) {
Optional<List<Generator>> optionalGeneratorList = getGeneratorsForConstructor(each);
if(optionalGeneratorList.isPresent()) {
if (optionalGeneratorList.isPresent()) {
listConstructors.add(generateConstructor(each));
}
}
Expand All @@ -189,8 +220,4 @@ public static List<Object> generateConstructorsOfClass(Class klass) {
}
return listConstructors;
}

public static void main(String[] args) {
generateConstructorsOfClass(String.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@

import org.atlanmod.commons.Guards;
import org.atlanmod.testing.Generator;

import java.util.Arrays;
import java.util.Random;

/**
*
* Generator class for bound values of the type Integer.
*/
public class IntegerBoundaryGenerator implements Generator<Integer> {

private int[] values;
private int index = 0;
private Random random = new Random();

public IntegerBoundaryGenerator(){
this(new int[]{Integer.MIN_VALUE, 0, Integer.MAX_VALUE});
Expand All @@ -26,13 +30,25 @@ public IntegerBoundaryGenerator(int[] values) {
this.values = Arrays.copyOfRange(values, 0, values.length) ;
}

/**
* Generates a single integer at a time
* Produced values are random using class java.util.Random
*
* @return a single integer value
*/
@Override
public Integer generate() {
return this.values[index % values.length];
int index = random.nextInt(values.length);
return this.values[index];
}

/**
* Returns all of the variation of the integer data type the current class is able to generate.
*
* @return an array of class types.
*/
@Override
public Class<Integer>[] types() {
return new Class[0];
return new Class[]{Integer.class, int.class};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,33 @@
package org.atlanmod.testing.generator;

import org.atlanmod.testing.Generator;

import java.util.Random;

/**
*
* Generator class for values of the type Boolean.
*
*/
public class RandomBooleanGenerator implements Generator<Boolean> {
private Random random = new Random();

@Override
/**
* Generate a boolean.
* Generates a random boolean value.
*
* @return a boolean value
*/
public Boolean generate() {
Random r = new Random();
boolean bool = r.nextBoolean();
return bool;
return random.nextBoolean();
}

@Override
/**
* return an array of class which contains the boolean class.
* Returns all of the variation of the boolean data type the current class is able to generate.
*
* @return an array of class types.
*/
public Class<Boolean>[] types() {
Class[] types={Boolean.class};
return types;
return new Class[]{Boolean.class};
}
}
Loading