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

Hierarchical tags #99

Merged
merged 14 commits into from
Aug 2, 2015
19 changes: 17 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,28 @@

## New Features

### Hierarchical Tags

Tags can now have parent tags by tagging a tag annotation. This allows you to define tag hierarchies.

#### Example

The following example tags the `FeatureHtml5Report` annotation with the `FeatureReport` annotation:

```
@FeatureReport
@IsTag( name = "HTML5 Report" )
@Retention( RetentionPolicy.RUNTIME )
public @interface FeatureHtml5Report { }
```

### Enhanced Spring Support [#94](https://github.com/TNG/JGiven/pull/94)

* The Spring support has been greatly improved. JGiven Stages can now be directly managed by the Spring framework, resulting in a much better Spring integration.
** Note that the usage of Spring is optional and is provided by the `jgiven-spring` module.
* Introduced `@JGivenStage` to ease writing spring beans that act as JGiven stage

### HTML5 Report
### Hierarchical Package Structure in the HTML5 Report

* Classes are shown now in hierarchical navigation tree and scenarios can be listed by package [#91](https://github.com/TNG/JGiven/pull/91)

Expand All @@ -17,7 +32,7 @@
* HTML5 Report: tables with duplicate entries cannot be used as step parameters [#89](https://github.com/TNG/JGiven/issues/89)
* Fixed an issue that the `@Description` annotation was not regarded for methods with the `@IntroWord` [#87](https://github.com/TNG/JGiven/issues/87)

## New Annotation
## New Annotations

* Introduced the `@As` annotation that replaces the `@Description` annotation when used on step methods and test methods. The `@Description` annotation should only be used for descriptions of test classes.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,21 @@
Class<? extends TagDescriptionGenerator> descriptionGenerator() default DefaultTagDescriptionGenerator.class;

/**
* An optional type description that overrides the default which is the name of the annotation.
* @deprecated use {@link #name()} instead
*/
@Deprecated
String type() default "";

/**
* An optional name that overrides the default which is the name of the annotation.
* <p>
* It is possible that multiple annotations have the same type name. However, in this case every
* annotation must have a specified value that must be unique.
* </p>
* @since 0.7.4
*/
String name() default "";

/**
* Whether the type should be prepended to the tag if the tag has a value.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.tngtech.jgiven.annotation;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

/**
* Marks methods of step definitions as not implemented yet.
* Such steps will not be executed, but will appear in
* the report as not implemented yet.
* <p>
* This is useful if one already wants to define the scenario without
* already implementing all steps, for example, to verify that
* all acceptance criteria of a story are covered by the scenario.
* <p>
* Annotating a stage class indicates
* that no step is implemented yet.
* <p>
* Finally, a test method can be annotated to indicate that the whole
* test is not implemented yet. The test will then be ignored by the testing-framework.
* (In fact an AssumptionException is thrown. It depends on the test runner how this
* is interpreted)
* <i>Currently only works for JUnit</i>
*
* <h2>Example</h2>
* <pre>
* {@literal @}NotImplementedYet
* public void my_cool_new_feature() {
*
* }
* </pre>
*
*/
@Documented
@Inherited
@Retention( RUNTIME )
@Target( { METHOD, TYPE } )
@IsTag( ignoreValue = true, description = "Not implemented Scenarios" )
public @interface Pending {
/**
* Optional description to describe when the implementation will be done.
*/
String value() default "";

/**
* Instead of only reporting not implemented yet steps,
* the steps are actually executed.
* This is useful to see whether some steps fail, for example.
* Failing steps, however, have no influence on the overall test result.
*/
boolean executeSteps() default false;

/**
* If <b>no</b> step fails during the execution of the test,
* the test will fail.
* <p>
* This makes sense if one ensures that a not implemented feature
* always leads to failing tests in the spirit of test-driven development.
* <p>
* If this is true, the <code>executeSteps</code> attribute is implicitly <code>true</code>.
*/
boolean failIfPass() default false;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public abstract class AbstractJGivenConfiguraton {
private final Map<Class<? extends Annotation>, TagConfiguration> tagConfigurations = Maps.newHashMap();

public final TagConfiguration.Builder configureTag( Class<? extends Annotation> tagAnnotation ) {
TagConfiguration configuration = new TagConfiguration();
TagConfiguration configuration = new TagConfiguration( tagAnnotation );
tagConfigurations.put( tagAnnotation, configuration );
return new TagConfiguration.Builder( configuration );
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.tngtech.jgiven.config;

import java.lang.annotation.Annotation;
import java.util.List;

import com.google.common.collect.Lists;
import com.tngtech.jgiven.annotation.DefaultTagDescriptionGenerator;
import com.tngtech.jgiven.annotation.IsTag;
import com.tngtech.jgiven.annotation.TagDescriptionGenerator;

/**
Expand All @@ -10,6 +13,7 @@
* @see com.tngtech.jgiven.annotation.IsTag for a documentation of the different values.
*/
public class TagConfiguration {
private final String annotationType;
private boolean ignoreValue;
private boolean explodeArray = true;
private boolean prependType;
Expand All @@ -18,7 +22,16 @@ public class TagConfiguration {
private String color = "";
private String cssClass = "";
private Class<? extends TagDescriptionGenerator> descriptionGenerator = DefaultTagDescriptionGenerator.class;
private String type = "";
private String name = "";
private List<String> tags = Lists.newArrayList();

public TagConfiguration( Class<? extends Annotation> tagAnnotation ) {
this.annotationType = tagAnnotation.getSimpleName();
}

public static Builder builder( Class<? extends Annotation> tagAnnotation ) {
return new Builder( new TagConfiguration( tagAnnotation ) );
}

public static class Builder {
final TagConfiguration configuration;
Expand Down Expand Up @@ -52,8 +65,17 @@ public Builder descriptionGenerator( Class<? extends TagDescriptionGenerator> de
return this;
}

/**
* @deprecated use {@link #name(String)} instead
*/
@Deprecated
public Builder type( String s ) {
configuration.type = s;
configuration.name = s;
return this;
}

public Builder name( String s ) {
configuration.name = s;
return this;
}

Expand All @@ -72,6 +94,15 @@ public Builder color( String color ) {
return this;
}

public Builder tags( List<String> tags ) {
configuration.tags = tags;
return this;
}

public TagConfiguration build() {
return configuration;
}

}

/**
Expand Down Expand Up @@ -100,10 +131,20 @@ public Class<? extends TagDescriptionGenerator> getDescriptionGenerator() {

/**
* {@link com.tngtech.jgiven.annotation.IsTag#type()}
* @deprecated use {@link #getName()} instead
* @see com.tngtech.jgiven.annotation.IsTag
*/
@Deprecated
public String getType() {
return type;
return name;
}

/**
* {@link com.tngtech.jgiven.annotation.IsTag#name()}
* @see com.tngtech.jgiven.annotation.IsTag
*/
public String getName() {
return name;
}

/**
Expand Down Expand Up @@ -146,17 +187,12 @@ public String getCssClass() {
return cssClass;
}

public static TagConfiguration fromIsTag( IsTag isTag ) {
TagConfiguration result = new TagConfiguration();
result.defaultValue = isTag.value();
result.description = isTag.description();
result.explodeArray = isTag.explodeArray();
result.ignoreValue = isTag.ignoreValue();
result.prependType = isTag.prependType();
result.type = isTag.type();
result.descriptionGenerator = isTag.descriptionGenerator();
result.cssClass = isTag.cssClass();
result.color = isTag.color();
return result;
public List<String> getTags() {
return tags;
}

public String getAnnotationType() {
return annotationType;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public void setModel( ReportModel scenarioCollectionModel ) {
}

public ReportModel getModel() {
return modelBuilder.getScenarioCollectionModel();
return modelBuilder.getReportModel();
}

public <T> T addStage( Class<T> stepsClass ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@

import java.io.PrintWriter;

import com.tngtech.jgiven.report.model.ScenarioCaseModel;
import com.tngtech.jgiven.report.model.ScenarioModel;
import com.tngtech.jgiven.report.model.StepModel;
import com.tngtech.jgiven.report.model.Word;
import com.tngtech.jgiven.report.model.*;

public class DataTableScenarioHtmlWriter extends ScenarioHtmlWriter {

public DataTableScenarioHtmlWriter( PrintWriter writer ) {
super( writer );
public DataTableScenarioHtmlWriter( PrintWriter writer, ReportModel reportModel ) {
super( writer, reportModel );
}

@Override
Expand Down Expand Up @@ -74,7 +71,7 @@ public void visit( StepModel stepModel ) {
}

@Override
String formatValue(Word value) {
String formatValue( Word value ) {
String paramName = findParameterName( value );
return "&lt;" + paramName + "&gt;";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

import java.io.PrintWriter;

import com.tngtech.jgiven.report.model.ReportModel;

public class MultiCaseScenarioHtmlWriter extends ScenarioHtmlWriter {

public MultiCaseScenarioHtmlWriter( PrintWriter writer ) {
super( writer );
public MultiCaseScenarioHtmlWriter( PrintWriter writer, ReportModel reportModel ) {
super( writer, reportModel );
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@

import static java.lang.String.format;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.io.*;
import java.text.DateFormat;
import java.util.Date;

Expand All @@ -19,16 +14,13 @@
import com.tngtech.jgiven.impl.util.PrintWriterUtil;
import com.tngtech.jgiven.impl.util.ResourceUtil;
import com.tngtech.jgiven.impl.util.Version;
import com.tngtech.jgiven.report.model.ReportModel;
import com.tngtech.jgiven.report.model.ReportModelVisitor;
import com.tngtech.jgiven.report.model.ReportStatistics;
import com.tngtech.jgiven.report.model.ScenarioModel;
import com.tngtech.jgiven.report.model.StatisticsCalculator;
import com.tngtech.jgiven.report.model.*;

public class ReportModelHtmlWriter extends ReportModelVisitor {
protected final PrintWriter writer;
protected final HtmlWriterUtils utils;
private ReportStatistics statistics;
private ReportModel reportModel;

public ReportModelHtmlWriter( PrintWriter writer ) {
this.writer = writer;
Expand Down Expand Up @@ -61,7 +53,7 @@ private void closeDiv() {
}

public void write( ScenarioModel model ) {
writeHtmlHeader(model.getClassName());
writeHtmlHeader( model.getClassName() );
model.accept( this );
writeHtmlFooter();
}
Expand Down Expand Up @@ -142,6 +134,7 @@ public static void writeToFile( File file, ReportModel model, HtmlTocWriter html

@Override
public void visit( ReportModel reportModel ) {
this.reportModel = reportModel;
writer.println( "<div id='rightpane'>" );
writeHeader( reportModel );
writer.println( "<div id='content'>" );
Expand Down Expand Up @@ -191,9 +184,9 @@ public void visitEnd( ReportModel reportModel ) {
public void visit( ScenarioModel scenarioModel ) {
ScenarioHtmlWriter scenarioHtmlWriter;
if( scenarioModel.isCasesAsTable() ) {
scenarioHtmlWriter = new DataTableScenarioHtmlWriter( writer );
scenarioHtmlWriter = new DataTableScenarioHtmlWriter( writer, reportModel );
} else {
scenarioHtmlWriter = new MultiCaseScenarioHtmlWriter( writer );
scenarioHtmlWriter = new MultiCaseScenarioHtmlWriter( writer, reportModel );
}
scenarioModel.accept( scenarioHtmlWriter );
}
Expand Down
Loading