Skip to content
Browse files

Added support for hook methods that run before and after the cucumber…

… features
  • Loading branch information...
1 parent 7496ace commit 6bcb74af3af73d3bef595234c5efd62e9b8a9dfd @skipoleschris committed Feb 26, 2011
View
35 .idea/findbugs-idea.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="org.twodividedbyzero.idea.findbugs">
+ <option name="_basePreferences">
+ <map>
+ <entry key="property.analysisEffortLevel" value="default" />
+ <entry key="property.analyzeAfterCompile" value="false" />
+ <entry key="property.exportAsHtml" value="true" />
+ <entry key="property.exportAsXml" value="true" />
+ <entry key="property.exportBaseDir" value="" />
+ <entry key="property.exportCreateArchiveDir" value="false" />
+ <entry key="property.exportOpenBrowser" value="true" />
+ <entry key="property.minPriorityToReport" value="Medium" />
+ <entry key="property.runAnalysisInBackground" value="false" />
+ <entry key="property.showHiddenDetectors" value="false" />
+ <entry key="property.toolWindowToFront" value="true" />
+ </map>
+ </option>
+ <option name="_reportCategories">
+ <map>
+ <entry key="BAD_PRACTICE" value="true" />
+ <entry key="CORRECTNESS" value="true" />
+ <entry key="EXPERIMENTAL" value="true" />
+ <entry key="I18N" value="true" />
+ <entry key="MALICIOUS_CODE" value="true" />
+ <entry key="MT_CORRECTNESS" value="true" />
+ <entry key="NOISE" value="false" />
+ <entry key="PERFORMANCE" value="true" />
+ <entry key="SECURITY" value="true" />
+ <entry key="STYLE" value="true" />
+ </map>
+ </option>
+ </component>
+</project>
+
View
11 README.markdown
@@ -117,11 +117,22 @@ The plugin supports a number of customisations. The following overrides can be a
* htmlCucumberOptions - Allows overriding the custom options for the 'cucumber-html' goal (default: --format html --out target/cucumber.html)
* pdfCucumberOptions - Allows overriding the custom options for the 'cucumber-pdf' goal (default: --format pdf --out target/cucumber.pdf)
+## Before/After Hooks ##
+The plugin supports a number of before and after hooks. These are provided to allow services to be started before cucumber test runs and to shut them down once the test run is complete. The following hooks are provided:
+
+* beforeCucumberSuite and afterCucumberSuite - The default methods that are run. Override these to run custom hooks before/after both the cucumber and cuke tasks
+* beforeCucumber and afterCucumber - Override these custom hooks that run before/after only the cucumber tasks (won't be run for cuke tasks)
+* beforeCuke and afterCuke - Override these custom hooke that run before/after only the cuke tasks (won't be run for cucumber tasks). These have access to the tag and name parameters passed to the task.
+
## Roadmap ##
## Release History ##
+### 0.5.0 ###
+* Added lifecycle methods that are run before and after cucumber feature executions
+
+
### 0.4.1 ###
* Renamed all the parameterised cucumberp tasks to be cuke instead as this is more in keeping with the Cucumber project naming style
View
189 cucumber-sbt-plugin.iml
@@ -29,5 +29,194 @@
<orderEntry type="library" exported="" name="Scala-2.7.7" level="project" />
<orderEntry type="library" name="Sbt-0.7.4" level="project" />
</component>
+ <component name="org.twodividedbyzero.idea.findbugs">
+ <option name="_basePreferences">
+ <map>
+ <entry key="property.analysisEffortLevel" value="default" />
+ <entry key="property.analyzeAfterCompile" value="false" />
+ <entry key="property.exportAsHtml" value="true" />
+ <entry key="property.exportAsXml" value="true" />
+ <entry key="property.exportBaseDir" value="" />
+ <entry key="property.exportCreateArchiveDir" value="false" />
+ <entry key="property.exportOpenBrowser" value="true" />
+ <entry key="property.minPriorityToReport" value="Medium" />
+ <entry key="property.runAnalysisInBackground" value="false" />
+ <entry key="property.showHiddenDetectors" value="false" />
+ <entry key="property.toolWindowToFront" value="true" />
+ </map>
+ </option>
+ <option name="_detectors">
+ <map>
+ <entry key="AppendingToAnObjectOutputStream" value="true" />
+ <entry key="BCPMethodReturnCheck" value="false" />
+ <entry key="BadAppletConstructor" value="false" />
+ <entry key="BadResultSetAccess" value="true" />
+ <entry key="BadSyntaxForRegularExpression" value="true" />
+ <entry key="BadUseOfReturnValue" value="true" />
+ <entry key="BadlyOverriddenAdapter" value="true" />
+ <entry key="BooleanReturnNull" value="true" />
+ <entry key="BuildInterproceduralCallGraph" value="false" />
+ <entry key="BuildObligationPolicyDatabase" value="true" />
+ <entry key="CallToUnsupportedMethod" value="false" />
+ <entry key="CalledMethods" value="true" />
+ <entry key="CheckCalls" value="false" />
+ <entry key="CheckExpectedWarnings" value="false" />
+ <entry key="CheckImmutableAnnotation" value="true" />
+ <entry key="CheckTypeQualifiers" value="true" />
+ <entry key="CloneIdiom" value="true" />
+ <entry key="ComparatorIdiom" value="true" />
+ <entry key="ConfusedInheritance" value="true" />
+ <entry key="ConfusionBetweenInheritedAndOuterMethod" value="true" />
+ <entry key="CrossSiteScripting" value="true" />
+ <entry key="DoInsideDoPrivileged" value="true" />
+ <entry key="DontCatchIllegalMonitorStateException" value="true" />
+ <entry key="DontIgnoreResultOfPutIfAbsent" value="true" />
+ <entry key="DontUseEnum" value="true" />
+ <entry key="DroppedException" value="true" />
+ <entry key="DumbMethodInvocations" value="true" />
+ <entry key="DumbMethods" value="true" />
+ <entry key="DuplicateBranches" value="true" />
+ <entry key="EmptyZipFileEntry" value="true" />
+ <entry key="EqStringTest" value="false" />
+ <entry key="EqualsOperandShouldHaveClassCompatibleWithThis" value="true" />
+ <entry key="FieldItemSummary" value="true" />
+ <entry key="FinalizerNullsFields" value="true" />
+ <entry key="FindBadCast" value="false" />
+ <entry key="FindBadCast2" value="true" />
+ <entry key="FindBadEqualsImplementation" value="false" />
+ <entry key="FindBadForLoop" value="true" />
+ <entry key="FindBugsSummaryStats" value="true" />
+ <entry key="FindCircularDependencies" value="false" />
+ <entry key="FindDeadLocalStores" value="true" />
+ <entry key="FindDoubleCheck" value="true" />
+ <entry key="FindEmptySynchronizedBlock" value="true" />
+ <entry key="FindFieldSelfAssignment" value="true" />
+ <entry key="FindFinalizeInvocations" value="true" />
+ <entry key="FindFloatEquality" value="true" />
+ <entry key="FindFloatMath" value="false" />
+ <entry key="FindHEmismatch" value="true" />
+ <entry key="FindInconsistentSync2" value="true" />
+ <entry key="FindJSR166LockMonitorenter" value="true" />
+ <entry key="FindLocalSelfAssignment2" value="true" />
+ <entry key="FindMaskedFields" value="true" />
+ <entry key="FindMismatchedWaitOrNotify" value="true" />
+ <entry key="FindNakedNotify" value="true" />
+ <entry key="FindNonSerializableStoreIntoSession" value="true" />
+ <entry key="FindNonSerializableValuePassedToWriteObject" value="true" />
+ <entry key="FindNonShortCircuit" value="true" />
+ <entry key="FindNullDeref" value="true" />
+ <entry key="FindNullDerefsInvolvingNonShortCircuitEvaluation" value="true" />
+ <entry key="FindOpenStream" value="true" />
+ <entry key="FindPuzzlers" value="true" />
+ <entry key="FindRefComparison" value="true" />
+ <entry key="FindReturnRef" value="true" />
+ <entry key="FindRunInvocations" value="true" />
+ <entry key="FindSelfComparison" value="true" />
+ <entry key="FindSelfComparison2" value="true" />
+ <entry key="FindSleepWithLockHeld" value="true" />
+ <entry key="FindSpinLoop" value="true" />
+ <entry key="FindSqlInjection" value="true" />
+ <entry key="FindTwoLockWait" value="true" />
+ <entry key="FindUncalledPrivateMethods" value="true" />
+ <entry key="FindUnconditionalWait" value="true" />
+ <entry key="FindUninitializedGet" value="true" />
+ <entry key="FindUnrelatedTypesInGenericContainer" value="true" />
+ <entry key="FindUnreleasedLock" value="true" />
+ <entry key="FindUnsatisfiedObligation" value="true" />
+ <entry key="FindUnsyncGet" value="true" />
+ <entry key="FindUselessControlFlow" value="true" />
+ <entry key="FormatStringChecker" value="true" />
+ <entry key="HugeSharedStringConstants" value="true" />
+ <entry key="IDivResultCastToDouble" value="true" />
+ <entry key="IncompatMask" value="true" />
+ <entry key="InconsistentAnnotations" value="true" />
+ <entry key="InefficientMemberAccess" value="false" />
+ <entry key="InefficientToArray" value="true" />
+ <entry key="InfiniteLoop" value="true" />
+ <entry key="InfiniteRecursiveLoop" value="true" />
+ <entry key="InfiniteRecursiveLoop2" value="false" />
+ <entry key="InheritanceUnsafeGetResource" value="true" />
+ <entry key="InitializationChain" value="true" />
+ <entry key="InstantiateStaticClass" value="true" />
+ <entry key="InvalidJUnitTest" value="true" />
+ <entry key="IteratorIdioms" value="true" />
+ <entry key="LazyInit" value="true" />
+ <entry key="LoadOfKnownNullValue" value="true" />
+ <entry key="LockedFields" value="false" />
+ <entry key="LostLoggerDueToWeakReference" value="true" />
+ <entry key="MethodReturnCheck" value="true" />
+ <entry key="Methods" value="true" />
+ <entry key="MultithreadedInstanceAccess" value="true" />
+ <entry key="MutableLock" value="true" />
+ <entry key="MutableStaticFields" value="true" />
+ <entry key="Naming" value="true" />
+ <entry key="Noise" value="false" />
+ <entry key="NoiseNullDeref" value="false" />
+ <entry key="NoteAnnotationRetention" value="true" />
+ <entry key="NoteCheckReturnValue" value="true" />
+ <entry key="NoteCheckReturnValueAnnotations" value="true" />
+ <entry key="NoteDirectlyRelevantTypeQualifiers" value="true" />
+ <entry key="NoteJCIPAnnotation" value="true" />
+ <entry key="NoteNonNullAnnotations" value="true" />
+ <entry key="NoteNonnullReturnValues" value="true" />
+ <entry key="NoteSuppressedWarnings" value="true" />
+ <entry key="NoteUnconditionalParamDerefs" value="true" />
+ <entry key="NumberConstructor" value="true" />
+ <entry key="OverridingEqualsNotSymmetrical" value="true" />
+ <entry key="PreferZeroLengthArrays" value="true" />
+ <entry key="PublicSemaphores" value="false" />
+ <entry key="QuestionableBooleanAssignment" value="true" />
+ <entry key="ReadOfInstanceFieldInMethodInvokedByConstructorInSuperclass" value="true" />
+ <entry key="ReadReturnShouldBeChecked" value="true" />
+ <entry key="RedundantInterfaces" value="true" />
+ <entry key="ReflectiveClasses" value="true" />
+ <entry key="RepeatedConditionals" value="true" />
+ <entry key="ResolveAllReferences" value="false" />
+ <entry key="RuntimeExceptionCapture" value="true" />
+ <entry key="SerializableIdiom" value="true" />
+ <entry key="StartInConstructor" value="true" />
+ <entry key="StaticCalendarDetector" value="true" />
+ <entry key="StringConcatenation" value="true" />
+ <entry key="SuperfluousInstanceOf" value="true" />
+ <entry key="SuspiciousThreadInterrupted" value="true" />
+ <entry key="SwitchFallthrough" value="true" />
+ <entry key="SynchronizationOnSharedBuiltinConstant" value="true" />
+ <entry key="SynchronizeAndNullCheckField" value="true" />
+ <entry key="SynchronizeOnClassLiteralNotGetClass" value="true" />
+ <entry key="SynchronizingOnContentsOfFieldToProtectField" value="true" />
+ <entry key="TestASM" value="false" />
+ <entry key="TestDataflowAnalysis" value="false" />
+ <entry key="TestingGround" value="false" />
+ <entry key="TrainFieldStoreTypes" value="true" />
+ <entry key="TrainNonNullAnnotations" value="true" />
+ <entry key="TrainUnconditionalDerefParams" value="true" />
+ <entry key="URLProblems" value="true" />
+ <entry key="UncallableMethodOfAnonymousClass" value="true" />
+ <entry key="UnnecessaryMath" value="true" />
+ <entry key="UnreadFields" value="true" />
+ <entry key="UseObjectEquals" value="false" />
+ <entry key="UselessSubclassMethod" value="false" />
+ <entry key="VarArgsProblems" value="true" />
+ <entry key="VolatileUsage" value="true" />
+ <entry key="WaitInLoop" value="true" />
+ <entry key="WrongMapIterator" value="true" />
+ <entry key="XMLFactoryBypass" value="true" />
+ </map>
+ </option>
+ <option name="_reportCategories">
+ <map>
+ <entry key="BAD_PRACTICE" value="true" />
+ <entry key="CORRECTNESS" value="true" />
+ <entry key="EXPERIMENTAL" value="true" />
+ <entry key="I18N" value="true" />
+ <entry key="MALICIOUS_CODE" value="true" />
+ <entry key="MT_CORRECTNESS" value="true" />
+ <entry key="NOISE" value="false" />
+ <entry key="PERFORMANCE" value="true" />
+ <entry key="SECURITY" value="true" />
+ <entry key="STYLE" value="true" />
+ </map>
+ </option>
+ </component>
</module>
View
2 project/build.properties
@@ -3,6 +3,6 @@
project.organization=templemore
project.name=cucumber-sbt-plugin
sbt.version=0.7.5.RC0
-project.version=0.4.1
+project.version=0.5.0
build.scala.versions=2.7.7
project.initialize=false
View
65 src/main/scala/templemore/sbt/CucumberProject.scala
@@ -66,6 +66,7 @@ trait CucumberProject extends BasicScalaProject {
private def installGems = {
log.info("Installing required gems for Cucumber and Cuke4Duke...")
+ gemPath.asFile.mkdirs
def gemInstalled(gem: Gem) = {
val gemDirectory = gemPath / "gems" / (gem.name + "-" + gem.version)
gemDirectory.exists
@@ -103,27 +104,47 @@ trait CucumberProject extends BasicScalaProject {
}
}
- protected def cucumberAction(tags: List[String], names: List[String]) = task {
- runCucumber(standardCucumberOptions, tags, names)
+ protected def cucumberAction(tags: List[String],
+ names: List[String],
+ before: (List[String], List[String]) => Unit,
+ after: (List[String], List[String]) => Unit) = task {
+ before(tags, names)
+ try { runCucumber(standardCucumberOptions, tags, names) }
+ finally { after(tags, names) }
} dependsOn(testCompile) describedAs ("Runs cucumber features with output on the console")
- protected def cucumberDevAction(tags: List[String], names: List[String]) = task {
- runCucumber(devCucumberOptions, tags, names)
+ protected def cucumberDevAction(tags: List[String],
+ names: List[String],
+ before: (List[String], List[String]) => Unit,
+ after: (List[String], List[String]) => Unit) = task {
+ before(tags, names)
+ try { runCucumber(devCucumberOptions, tags, names) }
+ finally { after(tags, names) }
} dependsOn(testCompile) describedAs ("Runs cucumber features with developer report output on the console")
- protected def cucumberHtmlAction(tags: List[String], names: List[String]) = task {
- runCucumber(htmlCucumberOptions, tags, names)
+ protected def cucumberHtmlAction(tags: List[String],
+ names: List[String],
+ before: (List[String], List[String]) => Unit,
+ after: (List[String], List[String]) => Unit) = task {
+ before(tags, names)
+ try { runCucumber(htmlCucumberOptions, tags, names) }
+ finally { after(tags, names) }
} dependsOn(testCompile) describedAs ("Runs cucumber features with html report in the target directory")
- protected def cucumberPdfAction(tags: List[String], names: List[String]) = task {
- runCucumber(pdfCucumberOptions, tags, names)
+ protected def cucumberPdfAction(tags: List[String],
+ names: List[String],
+ before: (List[String], List[String]) => Unit,
+ after: (List[String], List[String]) => Unit) = task {
+ before(tags, names)
+ try { runCucumber(pdfCucumberOptions, tags, names) }
+ finally { after(tags, names) }
} dependsOn(testCompile) describedAs ("Runs cucumber features with pdf report in the target directory")
// Main tasks (no arguments supported)
- lazy val cucumber = cucumberAction(List(), List())
- lazy val cucumberDev = cucumberDevAction(List(), List())
- lazy val cucumberHtml = cucumberHtmlAction(List(), List())
- lazy val cucumberPdf = cucumberPdfAction(List(), List())
+ lazy val cucumber = cucumberAction(List(), List(), internalBeforeCucumber, internalAfterCucumber)
+ lazy val cucumberDev = cucumberDevAction(List(), List(), internalBeforeCucumber, internalAfterCucumber)
+ lazy val cucumberHtml = cucumberHtmlAction(List(), List(), internalBeforeCucumber, internalAfterCucumber)
+ lazy val cucumberPdf = cucumberPdfAction(List(), List(), internalBeforeCucumber, internalAfterCucumber)
// NOTE: The design of SBT prevents method tasks (tasks with arguments)
// from be called on the parent project in a multi-project
@@ -133,14 +154,26 @@ trait CucumberProject extends BasicScalaProject {
// is selected, whereas the non-parameter versions can be called on the
// parent and child projects. The tasks supporting parameters are appended
// with a 'p'
- lazy val cuke = task { args => cucumberAction(tagsFromArgs(args), namesFromArgs(args)) }
- lazy val cukeDev = task { args => cucumberDevAction(tagsFromArgs(args), namesFromArgs(args)) }
- lazy val cukeHtml = task { args => cucumberHtmlAction(tagsFromArgs(args), namesFromArgs(args)) }
- lazy val cukePdf = task { args => cucumberPdfAction(tagsFromArgs(args), namesFromArgs(args)) }
+ lazy val cuke = task { args => cucumberAction(tagsFromArgs(args), namesFromArgs(args), beforeCuke, afterCuke) }
+ lazy val cukeDev = task { args => cucumberDevAction(tagsFromArgs(args), namesFromArgs(args), beforeCuke, afterCuke) }
+ lazy val cukeHtml = task { args => cucumberHtmlAction(tagsFromArgs(args), namesFromArgs(args), beforeCuke, afterCuke) }
+ lazy val cukePdf = task { args => cucumberPdfAction(tagsFromArgs(args), namesFromArgs(args), beforeCuke, afterCuke) }
private def tagsFromArgs(args: Array[String]) =
args.filter(arg => arg.startsWith("@") || arg.startsWith("~")).toList
private def namesFromArgs(args: Array[String]) =
args.filter(arg => !arg.startsWith("@") && !arg.startsWith("~")).toList
+
+ // Functions that provide lifecycle hooks to allow before and after actions to be
+ // tied to the running of cucumber features
+ private def internalBeforeCucumber(tags: List[String], names: List[String]) = beforeCucumber
+ private def internalAfterCucumber(tags: List[String], names: List[String]) = afterCucumber
+
+ protected def beforeCucumber = beforeCucumberSuite
+ protected def afterCucumber = afterCucumberSuite
+ protected def beforeCuke(tags: List[String], names: List[String]) = beforeCucumberSuite
+ protected def afterCuke(tags: List[String], names: List[String]) = afterCucumberSuite
+ protected def beforeCucumberSuite = { }
+ protected def afterCucumberSuite = { }
}
View
2 test-project/project/build.properties
@@ -3,6 +3,6 @@
project.organization=templemore
project.name=cucumber-plugin-test-project
sbt.version=0.7.5.RC0
-project.version=0.4.1
+project.version=0.5.0
build.scala.versions=2.8.1
project.initialize=false
View
3 test-project/project/build/TestProject.scala
@@ -11,6 +11,9 @@ class TestProject(info: ProjectInfo) extends ParentProject(info) {
class JarProject(info: ProjectInfo) extends DefaultProject(info) with CucumberProject {
// Test Dependencies
val scalatest = "org.scalatest" % "scalatest" % "1.2" % "test"
+
+ override protected def beforeCucumberSuite = println("Will be run before cucumber suite")
+ override protected def afterCucumberSuite = println("Will be run after cucumber suite")
}
// War project
View
2 test-project/project/plugins/Plugins.scala
@@ -2,5 +2,5 @@ import sbt._
class Plugins(info: ProjectInfo) extends PluginDefinition(info) {
val templemoreRepo = "templemore repo" at "http://templemore.co.uk/repo"
- val cucumberPlugin = "templemore" % "cucumber-sbt-plugin" % "0.4.1"
+ val cucumberPlugin = "templemore" % "cucumber-sbt-plugin" % "0.5.0"
}

0 comments on commit 6bcb74a

Please sign in to comment.
Something went wrong with that request. Please try again.