Skip to content
Closed
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
25 changes: 22 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.1</version>
<version>3.5</version>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
Expand All @@ -32,7 +32,8 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
<!-- Could be updated to 22.0, however requires Java 1.8 -->
<version>20.0</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
Expand All @@ -52,6 +53,21 @@
<version>4.11</version><!--$NO-MVN-MAN-VER$-->
<scope>test</scope>
</dependency>

<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
<scope>test</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/com.google.testing.compile/compile-testing -->
<dependency>
<groupId>com.google.testing.compile</groupId>
<artifactId>compile-testing</artifactId>
<version>0.11</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down Expand Up @@ -105,7 +121,7 @@
</archive>
</configuration>
</plugin>
<!-- generate jacoco report -->
<!-- generate jacoco report -->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
Expand All @@ -121,6 +137,9 @@
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>${argLine}</argLine>
<!-- Needed because otherwise the classloader does not properly bring in the dependencies from
maven. Source: http://maven.apache.org/surefire/maven-surefire-plugin/examples/class-loading.html -->
<useSystemClassLoader>false</useSystemClassLoader>
</configuration>
</plugin>
</plugins>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@
*/
package org.assertj.assertions.generator;

import com.google.common.reflect.TypeToken;
import org.assertj.assertions.generator.description.ClassDescription;

import java.io.File;
import java.io.IOException;
import java.util.Set;

import org.assertj.assertions.generator.description.ClassDescription;


public interface AssertionGenerator {

Expand Down Expand Up @@ -127,7 +128,7 @@ public interface AssertionGenerator {
* containing the file for the concrete final assertion.
* @throws IOException if something went wrong when creating the assertion files.
*/
File[] generateHierarchicalCustomAssertionFor(ClassDescription classDescription, Set<Class<?>> allClasses) throws IOException;
File[] generateHierarchicalCustomAssertionFor(ClassDescription classDescription, Set<TypeToken<?>> allClasses) throws IOException;

/**
* Builds and returns the custom assertion java file content for the given {@link ClassDescription}.
Expand Down Expand Up @@ -240,7 +241,7 @@ public interface AssertionGenerator {
* @throws RuntimeException
* if something went wrong when creating the assertion content.
*/
String[] generateHierarchicalCustomAssertionContentFor(ClassDescription classDescription, Set<Class<?>> allClasses);
String[] generateHierarchicalCustomAssertionContentFor(ClassDescription classDescription, Set<TypeToken<?>> allClasses);

/**
* Registers a template in the internal TemplateRegistry so that customers can override default templates.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@
*/
package org.assertj.assertions.generator;

import org.assertj.assertions.generator.description.ClassDescription;

import java.io.File;
import java.io.IOException;
import java.util.Set;

import org.assertj.assertions.generator.AssertionsEntryPointType;
import org.assertj.assertions.generator.description.ClassDescription;

public interface AssertionsEntryPointGenerator {

/**
Expand All @@ -34,7 +33,7 @@ public interface AssertionsEntryPointGenerator {
* a.b.c.
*
* @param classDescriptionSet the set of ClassDescription we want to generate an entry point for.
* @param assertionsEntryPointType the type of entry point class to generate
* @param assertionsEntryPointType the valueType of entry point class to generate
* @param entryPointClassPackage the package of the generated entry point class
* @return the assertions entry point class content
*/
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,21 @@
*/
package org.assertj.assertions.generator.cli;

import static com.google.common.collect.Sets.newLinkedHashSet;
import static org.assertj.assertions.generator.util.ClassUtil.collectClasses;

import java.io.File;
import java.io.IOException;
import java.util.Set;

import org.apache.commons.cli.BasicParser;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import com.google.common.reflect.TypeToken;
import org.apache.commons.cli.*;
import org.assertj.assertions.generator.BaseAssertionGenerator;
import org.assertj.assertions.generator.description.ClassDescription;
import org.assertj.assertions.generator.description.converter.ClassToClassDescriptionConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.util.Set;

import static com.google.common.collect.Sets.newLinkedHashSet;
import static org.assertj.assertions.generator.util.ClassUtil.collectClasses;


public class AssertionGeneratorLauncher {

Expand All @@ -51,7 +47,7 @@ public static void main(String[] args) throws IOException {
return;
}

Set<Class<?>> classes = collectClasses(line.getArgs());
Set<TypeToken<?>> classes = collectClasses(line.getArgs());

if (line.hasOption('H')) {
generateHierarchicalAssertions(classes);
Expand All @@ -71,34 +67,34 @@ private static void printHelp(Options options) {
help.printHelp(cmdLine, "Generate AssertJ-style assertions for the specified classes", options, "The list of classes can either be package names (which includes all packages in the class) or fully-qualified class names.");
}

private static void generateHierarchicalAssertions(Set<Class<?>> classes) throws IOException {
private static void generateHierarchicalAssertions(Set<TypeToken<?>> types) throws IOException {
// Create a hashset of the classes for efficient lookup.
Set<Class<?>> classSet = newLinkedHashSet(classes);
logger.info("Generating hierarchical assertions for classes {}", classes);
Set<TypeToken<?>> typeSet = newLinkedHashSet(types);
logger.info("Generating hierarchical assertions for classes {}", types);
BaseAssertionGenerator customAssertionGenerator = new BaseAssertionGenerator();

for (Class<?> clazz : classes) {
logger.info("Generating hierarchical assertions for class : {}", clazz.getName());
File[] customAssertionFiles = customAssertionGenerator.generateHierarchicalCustomAssertionFor(toClassDescription(clazz), classSet);
logger.info("Generated {} hierarchical assertions files -> {}, {}", clazz.getSimpleName(),
for (TypeToken<?> type : types) {
logger.info("Generating hierarchical assertions for class : {}", type);
File[] customAssertionFiles = customAssertionGenerator.generateHierarchicalCustomAssertionFor(toClassDescription(type), typeSet);
logger.info("Generated {} hierarchical assertions files -> {}, {}", type,
customAssertionFiles[0].getAbsolutePath(),
customAssertionFiles[1].getAbsolutePath());
}
}

private static void generateFlatAssertions(Set<Class<?>> classes) throws IOException {
logger.info("Generating assertions for classes {}", classes);
private static void generateFlatAssertions(Set<TypeToken<?>> types) throws IOException {
logger.info("Generating assertions for types {}", types);
BaseAssertionGenerator customAssertionGenerator = new BaseAssertionGenerator();

for (Class<?> clazz : classes) {
logger.info("Generating assertions for class : {}", clazz.getName());
File customAssertionFile = customAssertionGenerator.generateCustomAssertionFor(toClassDescription(clazz));
logger.info("Generated {} assertions file -> {}", clazz.getSimpleName(),
for (TypeToken<?> type : types) {
logger.info("Generating assertions for class : {}", type);
File customAssertionFile = customAssertionGenerator.generateCustomAssertionFor(toClassDescription(type));
logger.info("Generated {} assertions file -> {}", type,
customAssertionFile.getAbsolutePath());
}
}

private static ClassDescription toClassDescription(Class<?> clazz) {
return classDescriptionConverter.convertToClassDescription(clazz);
private static ClassDescription toClassDescription(TypeToken<?> type) {
return classDescriptionConverter.convertToClassDescription(type);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@
*/
package org.assertj.assertions.generator.description;

import java.util.Collection;
import java.util.Set;
import java.util.TreeSet;
import com.google.common.reflect.TypeToken;
import org.apache.commons.lang3.StringUtils;
import org.assertj.assertions.generator.util.ClassUtil;
import org.assertj.assertions.generator.util.StringUtil;

import java.util.*;

/**
*
Expand All @@ -29,40 +32,41 @@ public class ClassDescription implements Comparable<ClassDescription> {
private Set<FieldDescription> fieldsDescriptions;
private Set<GetterDescription> declaredGettersDescriptions;
private Set<FieldDescription> declaredFieldsDescriptions;
private TypeName classTypeName;
private Class<?> superType;
private TypeToken<?> type;
private TypeToken<?> superType;

public ClassDescription(TypeName typeName) {
public ClassDescription(TypeToken<?> type) {
super();
this.classTypeName = typeName;
this.gettersDescriptions = new TreeSet<GetterDescription>();
this.fieldsDescriptions = new TreeSet<FieldDescription>();
this.declaredGettersDescriptions = new TreeSet<GetterDescription>();
this.declaredFieldsDescriptions = new TreeSet<FieldDescription>();
this.type = type;
this.superType = null;
this.gettersDescriptions = new TreeSet<>();
this.fieldsDescriptions = new TreeSet<>();
this.declaredGettersDescriptions = new TreeSet<>();
this.declaredFieldsDescriptions = new TreeSet<>();
}

public String getClassName() {
return classTypeName.getSimpleName();
return type.getRawType().getName();
}

public String getFullyQualifiedClassName() {
return classTypeName.getFullyQualifiedClassName();
return ClassUtil.getTypeDeclaration(type, false, true);
}

public TypeName getTypeName() {
return classTypeName;
public TypeToken<?> getType() {
return type;
}

public String getClassNameWithOuterClass() {
return classTypeName.getSimpleNameWithOuterClass();
return ClassUtil.getTypeDeclaration(type, false, false);
}

public String getClassNameWithOuterClassNotSeparatedByDots() {
return classTypeName.getSimpleNameWithOuterClassNotSeparatedByDots();
return ClassUtil.getTypeNameWithoutDots(getClassNameWithOuterClass()); //classTypeName.getSimpleNameWithOuterClassNotSeparatedByDots();
}

public String getPackageName() {
return classTypeName.getPackageName();
return type.getRawType().getPackage().getName();
}

public Set<GetterDescription> getGettersDescriptions() {
Expand Down Expand Up @@ -96,10 +100,54 @@ public void addDeclaredGetterDescriptions(Collection<GetterDescription> declared
public void addDeclaredFieldDescriptions(Set<FieldDescription> declaredFieldDescriptions) {
this.declaredFieldsDescriptions.addAll(declaredFieldDescriptions);
}

public GetterDescription findGetterDescriptionForField(FieldDescription base) {

final String capName = StringUtils.capitalize(base.getName());
if (ClassUtil.isBoolean(base.getValueType())) {
// deal with predicates

// Build a map for better look-up
Map<String, GetterDescription> fieldMap = new HashMap<>();
for (GetterDescription getter: this.gettersDescriptions) {
fieldMap.put(getter.getOriginalMember().getName(), getter);
}
for (GetterDescription getter: this.declaredGettersDescriptions) {
fieldMap.put(getter.getOriginalMember().getName(), getter);
}

for (String prefix: ClassUtil.PREDICATE_PREFIXES.keySet()) {
String propName = prefix + capName;

GetterDescription getterDesc = fieldMap.get(propName);
if (getterDesc != null) {
return getterDesc;
}
}
} else {

String propName = "get" + capName;

for (GetterDescription desc: this.gettersDescriptions) {
if (Objects.equals(desc.getOriginalMember().getName(), propName)) {
return desc;
}
}

for (GetterDescription desc: this.declaredGettersDescriptions) {
if (Objects.equals(desc.getOriginalMember().getName(), propName)) {
return desc;
}
}
}

// wasn't found
return null;
}

@Override
public String toString() {
return "ClassDescription [classTypeName=" + classTypeName + "]";
return "ClassDescription [valueType=" + type + "]";
}

@Override
Expand All @@ -108,25 +156,28 @@ public boolean equals(final Object o) {
if (!(o instanceof ClassDescription)) return false;

final ClassDescription that = (ClassDescription) o;
if (classTypeName != null ? !classTypeName.equals(that.classTypeName) : that.classTypeName != null) return false;
return true;
return (Objects.equals(type, that.type));
}

@Override
public int hashCode() {
return classTypeName != null ? classTypeName.hashCode() : 0;
return Objects.hash(type);
}

@Override
public int compareTo(ClassDescription o) {
return classTypeName.compareTo(o.classTypeName);
return type.getRawType().getName().compareTo(o.type.getRawType().getName());
}

public Class<?> getSuperType() {
public TypeToken<?> getSuperType() {
return superType;
}

@SuppressWarnings("unchecked")
public void setSuperType(Class<?> superType) {
this.superType = superType;
// TypeToken#getSupertype(..) checks to make sure it is a super type
if (superType != null) {
this.superType = type.getSupertype((Class)superType);
}
}
}
Loading