package org.jbehave.core.configuration.spring;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.sameInstance;
import static org.jbehave.core.reporters.Format.CONSOLE;
import static org.jbehave.core.reporters.Format.HTML;
import static org.jbehave.core.reporters.Format.STATS;
import static org.jbehave.core.reporters.Format.TXT;
import static org.jbehave.core.reporters.Format.XML;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.isA;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import org.jbehave.core.annotations.Configure;
import org.jbehave.core.annotations.UsingSteps;
import org.jbehave.core.annotations.spring.UsingSpring;
import org.jbehave.core.configuration.AnnotationBuilder;
import org.jbehave.core.configuration.AnnotationMonitor;
import org.jbehave.core.configuration.Configuration;
import org.jbehave.core.configuration.Keywords;
import org.jbehave.core.configuration.MostUsefulConfiguration;
import org.jbehave.core.failures.SilentlyAbsorbingFailure;
import org.jbehave.core.i18n.LocalizedKeywords;
import org.jbehave.core.io.LoadFromURL;
import org.jbehave.core.parsers.RegexPrefixCapturingPatternParser;
import org.jbehave.core.steps.CandidateSteps;
import org.jbehave.core.steps.ParameterConverters;
import org.jbehave.core.steps.Steps;
import org.jbehave.core.steps.spring.SpringStepsFactoryBehaviour.FooSteps;
import org.jbehave.core.steps.spring.SpringStepsFactoryBehaviour.FooStepsWithDependency;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
public class SpringAnnotationBuilderBehaviour {
@Test
public void shouldBuildConfigurationFromAnnotations() {
SpringAnnotationBuilder builder = new SpringAnnotationBuilder(
AnnotatedUsingSpring.class);
Configuration configuration = builder.buildConfiguration();
assertThat(configuration.storyControls().dryRun(), is(true));
assertThat(configuration.storyControls().skipScenariosAfterFailure(),
is(true));
assertThat(configuration.failureStrategy(),
instanceOf(SilentlyAbsorbingFailure.class));
assertThat(configuration.storyLoader(), instanceOf(LoadFromURL.class));
assertThat(configuration.stepPatternParser(),
instanceOf(RegexPrefixCapturingPatternParser.class));
assertThat(
((RegexPrefixCapturingPatternParser) configuration.stepPatternParser())
.getPrefix(), equalTo("MyPrefix"));
assertThatDateIsConvertedWithFormat(
configuration.parameterConverters(), new SimpleDateFormat(
"yyyy-MM-dd"));
assertThat(configuration.parameterControls().nameDelimiterLeft(),
equalTo("["));
assertThat(configuration.parameterControls().nameDelimiterRight(),
equalTo("]"));
assertThat(configuration.storyReporterBuilder().formats(),
hasItems(CONSOLE, HTML, TXT, XML, STATS));
Keywords keywords = configuration.storyReporterBuilder().keywords();
assertThat(keywords, instanceOf(LocalizedKeywords.class));
assertThat(((LocalizedKeywords) keywords).getLocale(),
equalTo(Locale.ITALIAN));
assertThat(configuration.storyReporterBuilder().outputDirectory()
.getName(), equalTo("my-output-directory"));
assertThat(configuration.storyReporterBuilder().viewResources()
.getProperty("index"), equalTo("my-reports-index.ftl"));
assertThat(configuration.storyReporterBuilder().viewResources()
.getProperty("decorateNonHtml"), equalTo("true"));
assertThat(configuration.storyReporterBuilder().reportFailureTrace(),
is(true));
}
private void assertThatDateIsConvertedWithFormat(
ParameterConverters parameterConverters, DateFormat dateFormat) {
String date = "2010-10-10";
try {
assertThat((Date) parameterConverters.convert(date, Date.class),
equalTo(dateFormat.parse(date)));
} catch (ParseException e) {
fail();
}
}
@Test
public void shouldBuildDefaultConfigurationIfAnnotationOrAnnotatedValuesNotPresent() {
SpringAnnotationBuilder builderNotAnnotated = new SpringAnnotationBuilder(
NotAnnotated.class);
assertThatConfigurationIs(builderNotAnnotated.buildConfiguration(),
new MostUsefulConfiguration());
SpringAnnotationBuilder builderAnnotatedWithoutLocations = new SpringAnnotationBuilder(
AnnotatedWithoutResources.class);
assertThatConfigurationIs(
builderAnnotatedWithoutLocations.buildConfiguration(),
new MostUsefulConfiguration());
}
private void assertThatConfigurationIs(Configuration builtConfiguration,
Configuration defaultConfiguration) {
assertThat(builtConfiguration.failureStrategy(),
instanceOf(defaultConfiguration.failureStrategy().getClass()));
assertThat(builtConfiguration.storyLoader(),
instanceOf(defaultConfiguration.storyLoader().getClass()));
assertThat(builtConfiguration.stepPatternParser(),
instanceOf(defaultConfiguration.stepPatternParser().getClass()));
assertThat(builtConfiguration.storyReporterBuilder().formats(),
equalTo(defaultConfiguration.storyReporterBuilder().formats()));
assertThat(builtConfiguration.storyReporterBuilder().outputDirectory(),
equalTo(defaultConfiguration.storyReporterBuilder()
.outputDirectory()));
assertThat(builtConfiguration.storyReporterBuilder().viewResources(),
equalTo(defaultConfiguration.storyReporterBuilder()
.viewResources()));
assertThat(builtConfiguration.storyReporterBuilder()
.reportFailureTrace(), equalTo(defaultConfiguration
.storyReporterBuilder().reportFailureTrace()));
}
@Test
public void shouldBuildCandidateStepsFromAnnotationsUsingSpring() {
SpringAnnotationBuilder builderAnnotated = new SpringAnnotationBuilder(
AnnotatedUsingSpring.class);
Configuration configuration = builderAnnotated.buildConfiguration();
assertThatStepsInstancesAreFound(
builderAnnotated.buildCandidateSteps(configuration),
FooSteps.class, FooStepsWithDependency.class);
}
@Test
public void shouldBuildCandidateStepsFromAnnotationsUsingStepsAndSpring() {
SpringAnnotationBuilder builderAnnotated = new SpringAnnotationBuilder(
AnnotatedUsingStepsAndSpring.class);
Configuration configuration = builderAnnotated.buildConfiguration();
assertThatStepsInstancesAre(
builderAnnotated.buildCandidateSteps(configuration),
FooSteps.class);
}
@Test
public void shouldBuildCandidateStepsFromAnnotationsUsingStepsAndInheritingPicoFromParent() {
AnnotationBuilder builderAnnotated = new SpringAnnotationBuilder(
InheritingAnnotatedUsingSteps.class);
Configuration configuration = builderAnnotated.buildConfiguration();
assertThatStepsInstancesAre(
builderAnnotated.buildCandidateSteps(configuration),
FooSteps.class);
}
@Test
public void shouldBuildEmptyStepsListIfAnnotationOrAnnotatedValuesNotPresent() {
SpringAnnotationBuilder builderNotAnnotated = new SpringAnnotationBuilder(
NotAnnotated.class);
assertThatStepsInstancesAre(builderNotAnnotated.buildCandidateSteps());
SpringAnnotationBuilder builderAnnotatedWithoutResources = new SpringAnnotationBuilder(
AnnotatedWithoutResources.class);
assertThatStepsInstancesAre(builderAnnotatedWithoutResources
.buildCandidateSteps());
}
private void assertThatStepsInstancesAre(
List<CandidateSteps> candidateSteps, Class<?>... stepsClasses) {
assertThat(candidateSteps.size(), equalTo(stepsClasses.length));
for (int i = 0; i < stepsClasses.length; i++) {
assertThat(((Steps) candidateSteps.get(i)).instance(),
instanceOf(stepsClasses[i]));
}
}
private void assertThatStepsInstancesAreFound(
List<CandidateSteps> candidateSteps, Class<?>... stepsClasses) {
boolean found = false;
for (Class<?> stepsClass : stepsClasses) {
for (CandidateSteps candidates : candidateSteps) {
if (((Steps) candidates).instance().getClass()
.equals(stepsClass)) {
found = true;
break;
}
}
if (!found) {
Assert.fail("Class " + stepsClass + " not found in "
+ candidateSteps);
}
}
}
@Test
public void shouldNotBuildContainerIfResourceNotLoadable() {
AnnotationMonitor annotationMonitor = mock(AnnotationMonitor.class);
AnnotationBuilder builderUnloadableResource = new SpringAnnotationBuilder(
AnnotatedWithUnloadableResource.class, annotationMonitor);
try {
assertThatStepsInstancesAre(builderUnloadableResource
.buildCandidateSteps());
fail("Exception expected");
} catch (AnnotationBuilder.InstantiationFailed e) {
// expected
}
verify(annotationMonitor).elementCreationFailed(isA(Class.class),
isA(Exception.class));
}
@Test
public void shouldCreateOnlyOneContainerForMultipleBuildInvocations() {
SpringAnnotationBuilder builderAnnotated = new SpringAnnotationBuilder(
AnnotatedUsingStepsAndSpring.class);
builderAnnotated.buildConfiguration();
ApplicationContext applicationContext = builderAnnotated
.applicationContext();
builderAnnotated.buildConfiguration();
assertThat(builderAnnotated.applicationContext(),
sameInstance(applicationContext));
}
@Configure()
@UsingSpring(resources = {
"org/jbehave/core/configuration/spring/configuration.xml",
"org/jbehave/core/steps/spring/steps.xml",
"org/jbehave/core/steps/spring/steps-with-dependency.xml" })
private static class AnnotatedUsingSpring {
}
@Configure()
@UsingSteps(instances = { FooSteps.class })
@UsingSpring(resources = { "org/jbehave/core/configuration/spring/configuration.xml" })
private static class AnnotatedUsingStepsAndSpring {
}
@Configure()
@UsingSpring(resources = { "org/jbehave/core/configuration/spring/configuration.xml" })
private static class ParentAnnotatedUsingSpring {
}
@UsingSteps(instances = { FooSteps.class })
private static class InheritingAnnotatedUsingSteps extends
ParentAnnotatedUsingSpring {
}
@Configure()
@UsingSpring()
private static class AnnotatedWithoutResources {
}
@Configure()
@UsingSpring(resources = { "inexistent" }, ignoreContextFailure = false)
private static class AnnotatedWithUnloadableResource {
}
private static class NotAnnotated {
}
}