Skip to content

Commit

Permalink
[#6] provide documentation ghpages
Browse files Browse the repository at this point in the history
Added page about testing annotation processors

fixed logic to disable navigation on submenu items
  • Loading branch information
tobiasstamann committed Jul 10, 2017
1 parent 51dabf5 commit db1895c
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 17 deletions.
23 changes: 14 additions & 9 deletions docs/_includes/navigation.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<ul>
{% for p in rootpages %}

{% if p.used_in_navigation != null && p.used_in_navigation == true %}
{% if p.used_in_navigation != null and p.used_in_navigation == true %}
{% assign menu_name = p.menu_name %}

{% if menu_name == null %}
Expand All @@ -31,18 +31,23 @@

<li><a {% if page.url contains subpageDirectory %} class="current"{% endif %} href="#">{{ menu_name }}</a>


{% if p.isSection == true and subpages != empty %}
<ul>


{% for p2 in subpages %}
{% assign p2menu_name = p2.menu_name %}
{% if p2menu_name == null %}
{% assign p2menu_name = p2.title %}
{% endif %}

<a href="{{ p2.url || relative_url}}">
<li>{{p2menu_name}}</li>
</a>
{% assign p2menu_name = p2.menu_name %}
{% if p2menu_name == null %}
{% assign p2menu_name = p2.title %}
{% endif %}

{% if p2.used_in_navigation != null and p2.used_in_navigation == true %}

<a href="{{ p2.url || relative_url}}">
<li>{{p2menu_name}}</li>
</a>
{% endif %}
{% endfor %}
</ul>
{% endif %}
Expand Down
2 changes: 1 addition & 1 deletion docs/documentation/aboutAnnotationProcessors.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
layout: default
used_in_navigation: true
used_in_navigation: false
menu_name: About Annotation Processors
order: 1
---
18 changes: 11 additions & 7 deletions docs/documentation/gettingStarted.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ order: 2

# Prerequisites

There are not much preconditions regarding the usage of the annotation processor toolkit.
There are not many preconditions regarding the usage of the annotation processor toolkit.
You just need a JDK 6 or higher to get started.

Nevertheless we recommend you to use Maven for building your annotation processor project.
This page explains what needs to added to your Maven configuration to enable the annotation processor toolkit support to your project.
This page explains what needs to be configured in your Maven configuration to enable the annotation processor toolkit in your projects.

# Build and dependency management
## Dependency mangement
Expand Down Expand Up @@ -48,7 +48,7 @@ We recommend you to repackage all 3rd party dependencies of your annotation proc

This should be done for several reasons:

1. To get rid of versioning conflicts between the dependencies of your annotation processor and code to be processed.
1. To get rid of versioning conflicts between the dependencies of your annotation processor and of the code to be processed.
2. You need to add just one provided scope dependency to the code you want to be processed, since provided dependencies aren't handled transitively by Maven

In Maven, this can be done by using the shade plugin:
Expand Down Expand Up @@ -133,6 +133,10 @@ To enable the annotation processor toolkit support use the _de.holisticon.annota

## Declare which annotations are processed by the annotation processor

There are two approaches to tell the compiler which annotations are supported by an annnotation processor.

It can either be done by annotation or by overwriting the _getSupportedAnnotationTypes_ method declared by the _javax.annotation.processing.AbstractProcessor_ class.

### By annotation

Supported annotations can be defined by adding the _SupportedAnnotationTypes_ annotation to your annotation processor class:
Expand All @@ -156,17 +160,17 @@ An alternative approach is to overwrite the _getSupportedAnnotationTypes_ method
return SUPPORTED_ANNOTATION_TYPES;
}

The logic to load supported annotations is implemented in _javax.annotation.processing.AbstractProcessor.getSupportedAnnotationTypes()_.
The logic to configure supported annotations by the _SupportedAnnotationTypes_ annotation is implemented in _javax.annotation.processing.AbstractProcessor.getSupportedAnnotationTypes()_.
So overwriting of this method might break configuration by annotation.

## Setup annotation processor SPI
## Setup annotation processor detection

Since annotation processors are internally using the SPI you need to create a file _javax.annotation.processing.Processor_ in _/src/main/resources_.
Since annotation processors are internally detected via a _Service Provider Interface (SPI)_ you need to create a file _javax.annotation.processing.Processor_ in _/src/main/resources_.
The file just contains a list of full qualified annotation processor class names (one per line).
So just add you full qualified class name of your annotation processor to it.

# Applying the annotation processor
Your annotation processor will be automatically applied if it resides in class path during the compilation.
Your annotation processor will be automatically detected and applied if it resides in class path during the compilation.
Therefore you should add it as a provided dependency to your projects.


Expand Down
76 changes: 76 additions & 0 deletions docs/documentation/testingAnnotationProcessors.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
layout: default
used_in_navigation: true
menu_name: Testing Annotation Processors
order: 3
---

# Testing Annotation Processors

Testing of annotation processors is very tricky. Your annotation processors heavily rely on the _ProcessingEnvironment_ tools.
Those tools offer you access to the java compile time model and cannot be mocked or simulated very easily in unit tests.

So best way to test your annotation processors is to actually do a compile time test. Doing this all tools offered by the _ProcessingEnvironment_ are provided by the compiler.
This can be done by using the com.google.testing.compile compile-testing framework which allows to do compilations of some test source code during your tests and to check the outcomes.
One thing to mention is that JDK >=6 is supported up to version 0.9 - all following versions are base on JDK >=8.

This project simplifies testing even more by hiding the complexity of using the compile-testing framework.

We will show you what needs to be done in the following...

## Setting up a test

Setting up a junit test is quite easy. This framework is using parameterized unit tests to do some testing.

Here's a small example for a testcase that validates the compile outcome. This is quite useful for annotation processors that are doing validations about the usage of annotations:

package de.holisticon.example.annotationprocessortoolkit.annotationprocessor;

import de.holisticon.annotationprocessortoolkit.testhelper.AbstractAnnotationProcessorTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.util.Arrays;
import java.util.List;


@RunWith(Parameterized.class)
public class MethodWithOneStringParameterAndVoidReturnTypeProcessorTest extends AbstractAnnotationProcessorTest<MethodWithOneStringParameterAndVoidReturnTypeAnnotationProcessor> {


public MethodWithOneStringParameterAndVoidReturnTypeProcessorTest(String description, String resource, String[] errors, String[] warnings) {
super(description, resource, errors, warnings);
}

@Override
protected MethodWithOneStringParameterAndVoidReturnTypeAnnotationProcessor getAnnotationProcessor() {
return new MethodWithOneStringParameterAndVoidReturnTypeAnnotationProcessor();
}

@Parameterized.Parameters(name = "{index}: \"{0}\"")
public static List<Object[]> data() {

return Arrays.asList(new Object[][]{
{"Test valid usage", "testcases/methodWithOneStringParameterAndVoidReturn/ValidUsageTest.java", new String[]{}, new String[]{}},
{"Test invalid usage : non void return type", "testcases/methodWithOneStringParameterAndVoidReturn/InvalidUsageNonVoidReturnType.java", new String[]{"Method must have void return type"}, new String[]{}},
{"Test invalid usage : non String parameter", "testcases/methodWithOneStringParameterAndVoidReturn/InvalidUsageNonStringParameter.java", new String[]{"Method must have parameters of types [java.lang.String], but has parameters of types [java.lang.Object]"}, new String[]{}},

});

}


@Test
public void testCorrectnessOfAdviceArgumentAnnotation() {
super.test();
}

So basically you need to do the following things:

1. Create a test class which should extend the abstract _AbstractAnnotationProcessorTest<YourAnnotationPracessor>_ class
2. Implement the abstract method _getAnnotationProcessor_ declared by the _AbstractAnnotationProcessorTest<YourAnnotationPracessor>_ class. It should return an instance of the annotation processor to use.
3. Add the annotation _@Parameterized_ to the class
4. Create a constructor with parameters _(String description, String resource, String[] errors, String[] warnings)_ which delegates to super constructor.
5. Create a method that provides the parameterized test data. (Annotated with _@Parameterized.Parameters_)
6. Add a test method which delegated to super.test()

0 comments on commit db1895c

Please sign in to comment.