1package org.jbehave.core.configuration;2import org.hamcrest.Matchers;3import org.jbehave.core.ConfigurableEmbedder;4import org.jbehave.core.InjectableEmbedder;5import org.jbehave.core.annotations.Configure;6import org.jbehave.core.annotations.UsingEmbedder;7import org.jbehave.core.annotations.UsingPaths;8import org.jbehave.core.annotations.UsingSteps;9import org.jbehave.core.configuration.AnnotationBuilder.InstantiationFailed;10import org.jbehave.core.embedder.Embedder;11import org.jbehave.core.embedder.EmbedderControls;12import org.jbehave.core.i18n.LocalizedKeywords;13import org.jbehave.core.steps.CandidateSteps;14import org.jbehave.core.steps.ParameterConverters.ParameterConverter;15import org.jbehave.core.steps.Steps;16import org.junit.Test;17import java.io.ByteArrayOutputStream;18import java.io.PrintStream;19import java.lang.reflect.Type;20import java.util.List;21import static java.util.Arrays.asList;22import static org.hamcrest.MatcherAssert.assertThat;23import static org.hamcrest.Matchers.containsString;24import static org.hamcrest.Matchers.equalTo;25import static org.hamcrest.Matchers.greaterThan;26import static org.hamcrest.Matchers.instanceOf;27import static org.hamcrest.Matchers.is;28import static org.hamcrest.Matchers.notNullValue;29public class AnnotationBuilderBehaviour {30 @Test31 public void shouldReturnDependencies() {32 AnnotationBuilder annotated = new AnnotationBuilder(Annotated.class);33 assertThat(annotated.annotatedClass().getName(), equalTo(Annotated.class.getName()));34 assertThat(annotated.annotationFinder(), instanceOf(AnnotationFinder.class));35 assertThat(annotated.annotationMonitor(), instanceOf(PrintStreamAnnotationMonitor.class));36 }37 @Test38 public void shouldBuildDefaultEmbedderIfAnnotationNotPresent() {39 AnnotationBuilder notAnnotated = new AnnotationBuilder(NotAnnotated.class);40 assertThat(notAnnotated.buildEmbedder(), is(notNullValue()));41 }42 @Test43 public void shouldBuildEmbedderWithAnnotatedControls() {44 AnnotationBuilder annotated = new AnnotationBuilder(AnnotedEmbedderControls.class);45 EmbedderControls embedderControls = annotated.buildEmbedder().embedderControls();46 assertThat(embedderControls.batch(), is(true));47 assertThat(embedderControls.generateViewAfterStories(), is(true));48 assertThat(embedderControls.ignoreFailureInStories(), is(true));49 assertThat(embedderControls.ignoreFailureInView(), is(true));50 assertThat(embedderControls.skip(), is(true));51 assertThat(embedderControls.storyTimeoutInSecs(), equalTo(100L));52 assertThat(embedderControls.threads(), equalTo(2));53 assertThat(embedderControls.verboseFailures(), is(true));54 assertThat(embedderControls.verboseFiltering(), is(true));55 }56 @Test57 public void shouldBuildWithCustomConfiguration() {58 AnnotationBuilder annotated = new AnnotationBuilder(AnnotatedCustomConfiguration.class);59 assertThat(annotated.buildConfiguration(), instanceOf(MyConfiguration.class));60 }61 @Test62 public void shouldBuildCandidateSteps() {63 AnnotationBuilder annotated = new AnnotationBuilder(Annotated.class);64 assertThatStepsInstancesAre(annotated.buildCandidateSteps(), MySteps.class, MyOtherSteps.class);65 }66 @Test67 public void shouldBuildCandidateStepsAsEmptyListIfAnnotationOrAnnotatedValuesNotPresent() {68 ByteArrayOutputStream baos = new ByteArrayOutputStream();69 AnnotationBuilder notAnnotated = new AnnotationBuilder(NotAnnotated.class, new PrintStreamAnnotationMonitor(70 new PrintStream(baos)));71 assertThatStepsInstancesAre(notAnnotated.buildCandidateSteps());72 AnnotationBuilder annotatedWithoutSteps = new AnnotationBuilder(AnnotatedWithoutSteps.class);73 assertThatStepsInstancesAre(annotatedWithoutSteps.buildCandidateSteps());74 assertThat(baos.toString().trim(), is(equalTo("Annotation " + UsingSteps.class + " not found in "75 + NotAnnotated.class)));76 }77 @Test78 public void shouldInheritStepsInstances() {79 AnnotationBuilder annotated = new AnnotationBuilder(AnnotatedInheriting.class);80 assertThatStepsInstancesAre(annotated.buildCandidateSteps(), MyOtherOtherSteps.class, MySteps.class,81 MyOtherSteps.class);82 }83 @Test84 public void shouldNotInheritStepsInstances() {85 AnnotationBuilder builderAnnotated = new AnnotationBuilder(AnnotatedNotInheriting.class);86 assertThatStepsInstancesAre(builderAnnotated.buildCandidateSteps(), MyOtherOtherSteps.class);87 }88 @Test89 public void shouldNotIgnoreFailingStepsInstances() {90 ByteArrayOutputStream baos = new ByteArrayOutputStream();91 AnnotationBuilder annotatedFailing = new AnnotationBuilder(AnnotatedFailing.class,92 new PrintStreamAnnotationMonitor(new PrintStream(baos)));93 try {94 assertThatStepsInstancesAre(annotatedFailing.buildCandidateSteps(), MySteps.class);95 } catch (RuntimeException e) {96 assertThat(baos.toString(), containsString("Element creation failed"));97 assertThat(baos.toString(), containsString("RuntimeException"));98 }99 }100 private void assertThatStepsInstancesAre(List<CandidateSteps> candidateSteps, Class<?>... stepsClasses) {101 for (Class<?> stepsClass : stepsClasses) {102 boolean found = false;103 for (CandidateSteps steps : candidateSteps) {104 Object instance = ((Steps) steps).instance();105 if (instance.getClass() == stepsClass) {106 found = true;107 }108 }109 assertThat(found, is(true));110 }111 }112 @Test113 public void shouldCreateEmbeddableInstanceFromInjectableEmbedder() {114 AnnotationBuilder annotatedInjectable = new AnnotationBuilder(AnnotedInjectable.class);115 Object instance = annotatedInjectable.embeddableInstance();116 assertThat(instance, Matchers.instanceOf(InjectableEmbedder.class));117 Embedder embedder = ((InjectableEmbedder) instance).injectedEmbedder();118 assertThat(embedder.configuration().keywords(), instanceOf(MyKeywords.class));119 assertThat(embedder.metaFilters(), equalTo(asList("+embedder injectable")));120 assertThat(embedder.systemProperties().getProperty("one"), equalTo("One"));121 assertThat(embedder.systemProperties().getProperty("two"), equalTo("Two"));122 assertThatStepsInstancesAre(embedder.stepsFactory().createCandidateSteps(), MySteps.class);123 }124 @Test125 public void shouldCreateEmbeddableInstanceFromInjectableEmbedderWithoutStepsFactory() {126 AnnotationBuilder annotatedInjectable = new AnnotationBuilder(AnnotedInjectableWithoutStepsFactory.class);127 Object instance = annotatedInjectable.embeddableInstance();128 assertThat(instance, Matchers.instanceOf(InjectableEmbedder.class));129 Embedder embedder = ((InjectableEmbedder) instance).injectedEmbedder();130 assertThat(embedder.configuration().keywords(), instanceOf(MyKeywords.class));131 assertThat(embedder.metaFilters(), equalTo(asList("+embedder injectable")));132 assertThatStepsInstancesAre(embedder.candidateSteps(), MySteps.class);133 }134 @Test135 public void shouldCreateEmbeddableInstanceFromConfigurableEmbedder() {136 AnnotationBuilder annotatedConfigurable = new AnnotationBuilder(AnnotedConfigurable.class);137 Object instance = annotatedConfigurable.embeddableInstance();138 assertThat(instance, Matchers.instanceOf(ConfigurableEmbedder.class));139 Embedder embedder = ((ConfigurableEmbedder) instance).configuredEmbedder();140 assertThat(embedder.configuration().keywords(), instanceOf(MyKeywords.class));141 assertThat(embedder.metaFilters(), equalTo(asList("+embedder configurable")));142 assertThatStepsInstancesAre(embedder.stepsFactory().createCandidateSteps(), MySteps.class);143 }144 @Test145 public void shouldCreateEmbeddableInstanceFromConfigurableEmbedderWithoutStepsFactory() {146 AnnotationBuilder annotatedConfigurable = new AnnotationBuilder(AnnotedConfigurableWithoutStepsFactory.class);147 Object instance = annotatedConfigurable.embeddableInstance();148 assertThat(instance, Matchers.instanceOf(ConfigurableEmbedder.class));149 Embedder embedder = ((ConfigurableEmbedder) instance).configuredEmbedder();150 assertThat(embedder.configuration().keywords(), instanceOf(MyKeywords.class));151 assertThat(embedder.metaFilters(), equalTo(asList("+embedder configurable")));152 assertThatStepsInstancesAre(embedder.candidateSteps(), MySteps.class);153 }154 @Test155 public void shouldFindStoryPaths() {156 assertThat(new AnnotationBuilder(AnnotatedWithPaths.class).findPaths().size(), greaterThan(0));157 assertThat(new AnnotationBuilder(AnnotedConfigurable.class).findPaths().size(), equalTo(0));158 }159 @Test160 public void shouldNotCreateEmbeddableInstanceForAnnotatedClassThatIsNotInstantiable() {161 ByteArrayOutputStream baos = new ByteArrayOutputStream();162 AnnotationBuilder annotatedPrivate = new AnnotationBuilder(AnnotatedPrivate.class,163 new PrintStreamAnnotationMonitor(new PrintStream(baos)));164 try {165 annotatedPrivate.embeddableInstance();166 } catch (InstantiationFailed e) {167 assertThat(baos.toString(), containsString("Element creation failed"));168 assertThat(baos.toString(), containsString("IllegalAccessException"));169 }170 }171 @Configure(parameterConverters = { MyParameterConverter.class })172 @UsingSteps(instances = { MySteps.class, MyOtherSteps.class })173 static class Annotated {174 }175 static class MyParameterConverter implements ParameterConverter {176 public boolean accept(Type type) {177 return true;178 }179 public Object convertValue(String value, Type type) {180 return value + "Converted";181 }182 }183 @UsingSteps(instances = { MyOtherOtherSteps.class })184 static class AnnotatedInheriting extends Annotated {185 }186 @UsingSteps(instances = { MyOtherOtherSteps.class }, inheritInstances = false)187 static class AnnotatedNotInheriting extends Annotated {188 }189 @UsingSteps(instances = { MySteps.class, MyFailingSteps.class })190 static class AnnotatedFailing {191 }192 @UsingSteps()193 static class AnnotatedWithoutSteps {194 }195 static class NotAnnotated {196 }197 static class MySteps {198 }199 static class MyOtherSteps {200 }201 static class MyOtherOtherSteps {202 }203 static class MyFailingSteps {204 public MyFailingSteps() {205 throw new RuntimeException();206 }207 }208 @Configure(using = MyConfiguration.class)209 static class AnnotatedCustomConfiguration extends InjectableEmbedder {210 public void run() throws Throwable {211 }212 }213 static class MyConfiguration extends Configuration {214 }215 @UsingEmbedder(batch = true, generateViewAfterStories = true, ignoreFailureInStories = true, ignoreFailureInView = true, skip = true, verboseFailures = true, verboseFiltering = true, storyTimeoutInSecs = 100, threads = 2)216 @UsingSteps(instances = { MySteps.class })217 static class AnnotedEmbedderControls extends InjectableEmbedder {218 public void run() throws Throwable {219 }220 }221 @Configure(keywords = MyKeywords.class)222 @UsingEmbedder(metaFilters = "+embedder injectable", systemProperties = "one=One,two=Two")223 @UsingSteps(instances = { MySteps.class })224 static class AnnotedInjectable extends InjectableEmbedder {225 public void run() throws Throwable {226 }227 }228 @Configure(keywords = MyKeywords.class)229 @UsingEmbedder(metaFilters = "+embedder injectable", stepsFactory = false)230 @UsingSteps(instances = { MySteps.class })231 static class AnnotedInjectableWithoutStepsFactory extends InjectableEmbedder {232 public void run() throws Throwable {233 }234 }235 @Configure(keywords = MyKeywords.class)236 @UsingEmbedder(metaFilters = "+embedder configurable")237 @UsingSteps(instances = { MySteps.class })238 static class AnnotedConfigurable extends ConfigurableEmbedder {239 public void run() throws Throwable {240 }241 }242 @Configure(keywords = MyKeywords.class)243 @UsingEmbedder(metaFilters = "+embedder configurable", stepsFactory = false)244 @UsingSteps(instances = { MySteps.class })245 static class AnnotedConfigurableWithoutStepsFactory extends ConfigurableEmbedder {246 public void run() throws Throwable {247 }248 }249 static class MyKeywords extends LocalizedKeywords {250 }251 @Configure()252 @UsingEmbedder()253 @UsingSteps(instances = { MySteps.class })254 private static class AnnotatedPrivate extends ConfigurableEmbedder {255 public void run() throws Throwable {256 }257 }258 @UsingPaths(searchIn = "src/test/java", includes = { "**/stories/*story" })259 private static class AnnotatedWithPaths {260 }261}...