Skip to content

Commit

Permalink
Merge pull request #284 from powerunit/issues/#282
Browse files Browse the repository at this point in the history
Add a way to generate a WithSameValue matcher also when missing parent class
  • Loading branch information
boretti committed May 18, 2020
2 parents 46e5e08 + b5559ab commit 81968ef
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 24 deletions.
53 changes: 34 additions & 19 deletions src/main/java/ch/powerunit/extensions/matchers/ProvideMatchers.java
Expand Up @@ -213,8 +213,8 @@
* This attribute may be used to override the default class name that will
* contains the generated matchers.
* <p>
* <i>By default, this attribute is an empty string, which indicate to use
* the default construction pattern.</i>
* <i>By default, this attribute is an empty string, which indicate to use the
* default construction pattern.</i>
* <p>
* By default, the Matchers class name is the name of the annotated class,
* followed by {@code Matchers}.
Expand All @@ -225,39 +225,38 @@
String matchersClassName() default "";

/**
* This attribute may be used to override the default package name that will
* be used for the generated matchers.
* This attribute may be used to override the default package name that will be
* used for the generated matchers.
* <p>
* <i>By default, this attribute is an empty string, which indicate to use
* the default construction pattern.</i>
* <i>By default, this attribute is an empty string, which indicate to use the
* default construction pattern.</i>
* <p>
* By default, the Matchers package name is the same that the annotated
* class.
* By default, the Matchers package name is the same that the annotated class.
*
* @return the name of the matchers package or an empty string if this is
* not overloaded.
* @return the name of the matchers package or an empty string if this is not
* overloaded.
*/
String matchersPackageName() default "";

/**
* This attribute may be used to set a comments that will be passed inside
* the {@link javax.annotation.Generated#comments() comments} attribute of
* the {@link javax.annotation.Generated @Generated} annotation.
* This attribute may be used to set a comments that will be passed inside the
* {@link javax.annotation.Generated#comments() comments} attribute of the
* {@link javax.annotation.Generated @Generated} annotation.
*
* @return the comments or an empty string if ignored.
*/
String comments() default "";

/**
* This attribute may be used to generate additional exposition methods for
* the object.
* This attribute may be used to generate additional exposition methods for the
* object.
* <p>
* By default, only the standard method are generated.
*
* @return additional method to be generated or an empty array by default.
* @since 0.1.0
*/
ComplementaryExpositionMethod[]moreMethod() default {};
ComplementaryExpositionMethod[] moreMethod() default {};

/**
* This attribute may be used to enable some extensions for this objects.
Expand All @@ -267,11 +266,27 @@
* @return the extension to be used or an empty array by default.
* @since 0.1.0
* @see #JSON_EXTENSION An extension to add a validation on String, as JSON,
* based on the
* <a href="https://github.com/spotify/java-hamcrest">Spotify
* based on the <a href="https://github.com/spotify/java-hamcrest">Spotify
* Matchers</a>.
*/
String[]extensions() default {};
String[] extensions() default {};

/**
* This attribute may be used in case when it is not possible to create a
* <i>sure</i> <code>WithSameValue</code> matcher. This may be the case when the
* annotated class extends a not annotated class or when the parent class is
* already compiled.
* <p>
* By default, this mode is set to false.
* <p>
* In case this option is set to true and the <code>WithSameValue</code> matcher
* is considered as weak, a warning will be produced.
*
* @return to create (or not) a <code>WithSameValue</code> matcher even if it is
* not possible to ensure the control of the field of the parent class.
* @since 2.0.0
*/
boolean allowWeakWithSameValue() default false;

/**
* May be use as part of {@link #extensions()} to enable, if available, an
Expand Down
Expand Up @@ -23,6 +23,7 @@
import java.util.Optional;

import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;

/**
Expand Down Expand Up @@ -65,6 +66,13 @@ public String getParamComment() {
return doc.map(AbstractElementMirror::extractParamCommentFromJavadoc).orElse(" * \n");
}

public Optional<AnnotationMirror> getAnnotationMirror() {
return annotation.map(
a -> getTypeUtils().getDeclaredType(getElementUtils().getTypeElement(a.annotationType().getName())))
.map(a -> element.getAnnotationMirrors().stream().filter(m -> a.equals(m.getAnnotationType())).findAny()
.orElse(null));
}

@Override
public ProcessingEnvironment getProcessingEnv() {
return getRoundMirror().getProcessingEnv();
Expand Down
Expand Up @@ -45,6 +45,7 @@ public class ProvideMatchersMirror extends AbstractTypeElementMirror<ProvideMatc
protected final String simpleNameOfGeneratedClass;
protected final String packageNameOfGeneratedClass;
protected final String simpleNameOfGeneratedInterfaceMatcher;
protected final boolean allowWeakWithSameValue;

public ProvideMatchersMirror(RoundMirror roundMirror, TypeElement annotatedElement) {
super(ProvideMatchers.class, roundMirror, annotatedElement);
Expand All @@ -53,6 +54,7 @@ public ProvideMatchersMirror(RoundMirror roundMirror, TypeElement annotatedEleme
this.packageNameOfGeneratedClass = generatePackageNameOfGeneratedClass(annotatedElement, pm,
getProcessingEnv().getElementUtils());
this.simpleNameOfGeneratedInterfaceMatcher = getSimpleNameOfClassAnnotated() + "Matcher";
this.allowWeakWithSameValue = pm.allowWeakWithSameValue();
}

private String generateSimpleNameOfGeneratedClass(TypeElement annotatedElement, ProvideMatchers pm) {
Expand Down
Expand Up @@ -33,12 +33,16 @@
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;

import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic.Kind;

import ch.powerunit.extensions.matchers.provideprocessor.dsl.DSLMethod;

Expand Down Expand Up @@ -77,7 +81,7 @@ public Collection<DSLMethod> process() {
jfo -> new PrintWriter(jfo.openWriter()), wjfo -> {
wjfo.println("package " + getPackageNameOfGeneratedClass() + ";");
wjfo.println();
wjfo.println("// Generated by version "+getClass().getPackage().getImplementationVersion());
wjfo.println("// Generated by version " + getClass().getPackage().getImplementationVersion());
wjfo.println(generateMainJavaDoc());
wjfo.println(generateGeneratedAnnotation(ProvidesMatchersAnnotationsProcessor.class,
annotation.get().comments()));
Expand All @@ -95,9 +99,9 @@ public Collection<DSLMethod> process() {
tmp.stream().map(m -> addPrefix(" ", m.asStaticImplementation())).forEach(wjfo::println);
wjfo.println("}");
return tmp;
}, e -> traceErrorAndDump(getMessager(),getFiler(),e,te));
}, e -> traceErrorAndDump(getMessager(), getFiler(), e, te));
}

public Collection<DSLMethod> generateDSLStarter() {
return dslProvider.stream().map(Supplier::get).filter(Objects::nonNull).collect(toList());
}
Expand Down Expand Up @@ -165,7 +169,7 @@ public DSLMethod generatParentValueDSLStarter(String argumentForParentBuilder) {
List<String> lines = new ArrayList<>();
lines.add(genericNoParent + " m=new " + getSimpleNameOfGeneratedImplementationMatcherWithGenericNoParent() + "("
+ argumentForParentBuilder + ");");
lines.addAll(fields.stream().map(f -> " " + f.getFieldCopy("m", "other") + ";").collect(toList()));
lines.addAll(fields.stream().map(f -> f.getFieldCopy("m", "other") + ";").collect(toList()));
lines.add("return m;");
return of(fullGeneric + " " + getFullyQualifiedNameOfGeneratedClass() + "." + genericNoParent + " "
+ methodShortClassName + "WithSameValue")
Expand All @@ -179,11 +183,26 @@ public Optional<ProvidesMatchersAnnotatedElementMirror> getParentMirror() {
rm.getByName(getQualifiedName(((TypeElement) rm.getTypeUtils().asElement(element.getSuperclass())))));
}

public DSLMethod generateParentValueDSLStarterWeak() {
if (allowWeakWithSameValue) {
Optional<AnnotationMirror> am = getAnnotationMirror();
Optional<? extends AnnotationValue> av = am.map(a -> a.getElementValues().entrySet().stream()
.filter(kv -> kv.getKey().getSimpleName().toString().equals("allowWeakWithSameValue"))
.map(Entry::getValue).findAny().orElse(null));
getMessager().printMessage(Kind.MANDATORY_WARNING,
"This class use the option allowWeakWithSameValue and a weak WithSameValue is detected. The generated WithSameValue DSL may not be able to fully control all the field of this class",
element, am.orElse(null), av.orElse(null));

return generatParentValueDSLStarter("org.hamcrest.Matchers.anything()");
}
return null;
}

public DSLMethod generateParentValueDSLStarter() {
return getParentMirror()
.map(parentMirror -> generatParentValueDSLStarter(parentMirror.getFullyQualifiedNameOfGeneratedClass()
+ "." + parentMirror.methodShortClassName + "WithSameValue(other)"))
.orElse(null);
.orElse(generateParentValueDSLStarterWeak());
}

public DSLMethod generateParentInSameRoundWithChaningDSLStarter() {
Expand Down
@@ -0,0 +1,27 @@
package ch.powerunit.extensions.matchers.samples.extension;

import org.apache.commons.lang3.tuple.Pair;

import ch.powerunit.extensions.matchers.ProvideMatchers;

@ProvideMatchers(allowWeakWithSameValue = true)
public class MyPair2<L,R> extends Pair<L, R> {

public String test;

@Override
public R setValue(R arg0) {
return null;
}

@Override
public L getLeft() {
return null;
}

@Override
public R getRight() {
return null;
}

}
@@ -0,0 +1,12 @@
package ch.powerunit.extensions.matchers.samples.extension;

import org.apache.commons.lang3.text.StrBuilder;

import ch.powerunit.extensions.matchers.ProvideMatchers;

@ProvideMatchers(allowWeakWithSameValue = true)
public class MyTestWithoutGeneric2 extends StrBuilder {

public String test;

}

0 comments on commit 81968ef

Please sign in to comment.