-
Notifications
You must be signed in to change notification settings - Fork 122
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e947ff0
commit 118f74c
Showing
6 changed files
with
270 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
89 changes: 89 additions & 0 deletions
89
asciidoctor-maven-plugin/src/test/java/org/asciidoctor/maven/ParametersInitializer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package org.asciidoctor.maven; | ||
|
||
import net.bytebuddy.description.annotation.AnnotationDescription; | ||
import net.bytebuddy.description.annotation.AnnotationValue; | ||
import net.bytebuddy.description.field.FieldDescription; | ||
import net.bytebuddy.description.field.FieldList; | ||
import net.bytebuddy.description.type.TypeDescription; | ||
import net.bytebuddy.pool.TypePool; | ||
import org.apache.maven.plugins.annotations.Parameter; | ||
|
||
import static org.asciidoctor.maven.commons.StringUtils.isBlank; | ||
import static org.codehaus.plexus.util.ReflectionUtils.setVariableValueInObject; | ||
|
||
/** | ||
* | ||
*/ | ||
class ParametersInitializer { | ||
|
||
private static final ClassLoader CLASS_LOADER = ParametersInitializer.class.getClassLoader(); | ||
|
||
/** | ||
* Returns instance of input class with fields initialized according to its | ||
* respective {@link org.apache.maven.plugins.annotations.Parameter}. | ||
*/ | ||
public <T> T initialize(T instance) { | ||
try { | ||
// Use ByteBuddy because annotations is Class retention, not Runtime | ||
TypePool typePool = TypePool.Default.of(CLASS_LOADER); | ||
TypeDescription typeDescription = typePool.describe(instance.getClass().getName()).resolve(); | ||
|
||
initParameterFields(instance, typeDescription); | ||
return instance; | ||
} catch (IllegalAccessException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
private <T> void initParameterFields(T instance, TypeDescription typeDescription) throws IllegalAccessException { | ||
|
||
FieldList<FieldDescription.InDefinedShape> declaredFields = typeDescription.getDeclaredFields(); | ||
|
||
for (FieldDescription field : declaredFields) { | ||
String value = getAnnotationByType(field); | ||
if (value != null) { | ||
if (field.getType().getTypeName().equals(String.class.getName())) { | ||
if (value.length() > 0 && !value.startsWith("$")) { | ||
// TODO support Maven variable: pass Map<String, Object> ? | ||
setVariableValueInObject(instance, field.getName(), value); | ||
} | ||
} | ||
if (field.getType().getTypeName().equals("boolean")) { | ||
// false is already the default | ||
// TODO for PR, the booleans default should appear in XML plugin descriptor now | ||
if (value.equals("true")) { | ||
setVariableValueInObject(instance, field.getName(), Boolean.TRUE); | ||
} else if (!value.equals("false")) { | ||
throw new RuntimeException("Invalid boolean default: not-a-boolean"); | ||
} | ||
} | ||
// TODO | ||
// if (field.getType().getTypeName().equals(File.class.getName())) { | ||
} | ||
} | ||
|
||
TypeDescription superClass = typeDescription.getSuperClass().asErasure(); | ||
|
||
if (hasParent(superClass)) { | ||
initParameterFields(instance, superClass); | ||
} | ||
} | ||
|
||
private boolean hasParent(TypeDescription superClass) { | ||
return superClass != null && !superClass.getTypeName().equals(Object.class.getName()); | ||
} | ||
|
||
// Make MojoReader | ||
private String getAnnotationByType(FieldDescription field) { | ||
for (AnnotationDescription declaredAnnotation : field.getDeclaredAnnotations()) { | ||
String annotationTypeName = declaredAnnotation.getAnnotationType().getName(); | ||
if (annotationTypeName.equals(Parameter.class.getCanonicalName())) { | ||
AnnotationValue<?, ?> defaultValue = declaredAnnotation.getValue("defaultValue"); | ||
String stringValue = defaultValue.toString(); | ||
stringValue = stringValue.substring(1, stringValue.length() - 1).trim(); | ||
return isBlank(stringValue) ? null : stringValue; | ||
} | ||
} | ||
return null; | ||
} | ||
} |
123 changes: 123 additions & 0 deletions
123
asciidoctor-maven-plugin/src/test/java/org/asciidoctor/maven/ParametersInitializerTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
package org.asciidoctor.maven; | ||
|
||
import org.apache.maven.plugins.annotations.Parameter; | ||
import org.junit.jupiter.api.Nested; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.assertj.core.api.Assertions.catchThrowable; | ||
|
||
class ParametersInitializerTest { | ||
|
||
private final ParametersInitializer initializer = new ParametersInitializer(); | ||
|
||
@Test | ||
void should_return_same_instance() { | ||
final var instance = new Simple(); | ||
var actual = initializer.initialize(instance); | ||
assertThat(actual).isEqualTo(instance); | ||
} | ||
|
||
@Nested | ||
class ShouldInitialize { | ||
|
||
@Test | ||
void string_with_default_value() { | ||
final var instance = new StringExampleMojo(); | ||
var initialized = initializer.initialize(instance); | ||
assertThat(initialized.defaultValue).isEqualTo("a-value"); | ||
} | ||
|
||
@Test | ||
void boolean_with_default_value() { | ||
final var instance = new BooleanExampleMojo(); | ||
var initialized = initializer.initialize(instance); | ||
assertThat(initialized.defaultValue).isTrue(); | ||
} | ||
|
||
@Test | ||
void properties_in_class_and_parent() { | ||
final var instance = new SubclassExampleMojo(); | ||
var initialized = initializer.initialize(instance); | ||
assertThat(initialized.getDefaultValue()).isEqualTo("a-value"); | ||
assertThat(initialized.getNonDefaultValue()).isNull(); | ||
assertThat(initialized.anotherValue).isEqualTo("from-subclass"); | ||
} | ||
} | ||
|
||
@Nested | ||
class ShouldNotInitialize { | ||
|
||
@Test | ||
void string_without_default_value() { | ||
final var instance = new StringExampleMojo(); | ||
var initialized = initializer.initialize(instance); | ||
assertThat(initialized.nonDefaultValue).isNull(); | ||
} | ||
|
||
@Test | ||
void boolean_without_default_value() { | ||
final var instance = new BooleanExampleMojo(); | ||
var initialized = initializer.initialize(instance); | ||
assertThat(initialized.nonDefaultValue).isFalse(); | ||
} | ||
} | ||
|
||
@Nested | ||
class ShouldFail { | ||
@Test | ||
void boolean_with_invalid_value() { | ||
final var instance = new FailingExampleMojo(); | ||
Throwable t = catchThrowable(() -> initializer.initialize(instance)); | ||
|
||
assertThat(t).isInstanceOf(RuntimeException.class) | ||
.hasMessage("Invalid boolean default: not-a-boolean"); | ||
} | ||
} | ||
|
||
|
||
class Simple { | ||
|
||
Simple() { | ||
} | ||
|
||
} | ||
|
||
class StringExampleMojo { | ||
|
||
@Parameter(defaultValue = "a-value") | ||
private String defaultValue; | ||
|
||
@Parameter | ||
private String nonDefaultValue; | ||
|
||
public String getDefaultValue() { | ||
return defaultValue; | ||
} | ||
|
||
public String getNonDefaultValue() { | ||
return nonDefaultValue; | ||
} | ||
} | ||
|
||
class BooleanExampleMojo { | ||
|
||
@Parameter(defaultValue = "true") | ||
private boolean defaultValue; | ||
|
||
@Parameter | ||
private boolean nonDefaultValue; | ||
} | ||
|
||
class FailingExampleMojo { | ||
|
||
@Parameter(defaultValue = "not-a-boolean") | ||
private boolean invalidValue; | ||
} | ||
|
||
class SubclassExampleMojo extends StringExampleMojo { | ||
|
||
@Parameter(defaultValue = "from-subclass") | ||
private String anotherValue; | ||
} | ||
} |
Oops, something went wrong.