Skip to content

Commit

Permalink
✨ feat: implement scalatest integration
Browse files Browse the repository at this point in the history
  • Loading branch information
gaeljw committed Apr 21, 2024
1 parent 3cc5f7e commit fc18ad2
Show file tree
Hide file tree
Showing 16 changed files with 1,006 additions and 4 deletions.
34 changes: 30 additions & 4 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ val cucumberVersion = "7.17.0"
val jacksonVersion = "2.17.0"
val mockitoScalaVersion = "1.17.31"
val junitVersion = "4.13.2"
val scalatestVersion = "3.2.18"

// Projects and settings

Expand All @@ -64,6 +65,7 @@ lazy val root = (project in file("."))
)
.aggregate(
cucumberScala.projectRefs ++
cucumberScalatest.projectRefs ++
integrationTestsCommon.projectRefs ++
integrationTestsJackson.projectRefs ++
integrationTestsPicoContainer.projectRefs ++
Expand Down Expand Up @@ -122,6 +124,17 @@ lazy val cucumberScala = (projectMatrix in file("cucumber-scala"))
)
.jvmPlatform(scalaVersions = Seq(scala3, scala213, scala212))

lazy val cucumberScalatest = (projectMatrix in file("scalatest"))
.settings(commonSettings)
.settings(
name := "cucumber-scalatest",
libraryDependencies ++= Seq(
"io.cucumber" % "cucumber-core" % cucumberVersion,
"org.scalatest" %% "scalatest" % scalatestVersion
)
)
.jvmPlatform(scalaVersions = Seq(scala3, scala213, scala212))

// Integration tests
lazy val integrationTestsCommon =
(projectMatrix in file("integration-tests/common"))
Expand Down Expand Up @@ -167,6 +180,19 @@ lazy val integrationTestsPicoContainer =
.dependsOn(cucumberScala % Test)
.jvmPlatform(scalaVersions = Seq(scala3, scala213, scala212))

lazy val integrationTestsScalatest =
(projectMatrix in file("integration-tests/scalatest"))
.settings(commonSettings)
.settings(
name := "integration-tests-scalatest",
libraryDependencies ++= Seq(
"org.scalatest" %% "scalatest" % scalatestVersion % Test
),
publishArtifact := false
)
.dependsOn(cucumberScala % Test, cucumberScalatest % Test)
.jvmPlatform(scalaVersions = Seq(scala3, scala213, scala212))

// Examples project
lazy val examples = (projectMatrix in file("examples"))
.settings(commonSettings)
Expand Down Expand Up @@ -200,12 +226,12 @@ releaseProcess := Seq[ReleaseStep](
runTest,
setReleaseVersion,
// the 2 following steps are part of the Cucumber release process
//commitReleaseVersion,
//tagRelease,
// commitReleaseVersion,
// tagRelease,
releaseStepCommandAndRemaining("publishSigned"),
releaseStepCommand("sonatypeBundleRelease"),
setNextVersion
// the 2 following steps are part of the Cucumber release process
//commitNextVersion,
//pushChanges
// commitNextVersion,
// pushChanges
)
89 changes: 89 additions & 0 deletions integration-tests/scalatest/src/test/resources/cukes/cukes.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
Feature: Cukes

Scenario: in the belly
Given I have 4 "cukes" in my belly
Then I am "happy"

Scenario: Int in the belly
Given I have eaten an int 100
Then I should have one hundred in my belly

Scenario: Long in the belly
Given I have eaten a long 100
Then I should have long one hundred in my belly

Scenario: String in the belly
Given I have eaten "numnumnum"
Then I should have numnumnum in my belly

Scenario: Double in the belly
Given I have eaten 1.5 doubles
Then I should have one and a half doubles in my belly

Scenario: Float in the belly
Given I have eaten 1.5 floats
Then I should have one and a half floats in my belly

Scenario: Short in the belly
Given I have eaten a short 100
Then I should have short one hundred in my belly

Scenario: Byte in the belly
Given I have eaten a byte 2
Then I should have two byte in my belly

Scenario: BigDecimal in the belly
Given I have eaten 1.5 big decimals
Then I should have one and a half big decimals in my belly

Scenario: BigInt in the belly
Given I have eaten 10 big int
Then I should have a ten big int in my belly

Scenario: Char in the belly
Given I have eaten char 'C'
Then I should have character C in my belly

Scenario: Boolean in the belly
Given I have eaten boolean true
Then I should have truth in my belly

Scenario: DataTable in the belly
Given I have the following foods :
| FOOD | CALORIES |
| cheese | 500 |
| burger | 1000 |
| fries | 750 |
Then I am "definitely happy"
And have eaten 2250.0 calories today

Scenario: DataTable with args in the belly
Given I have a table the sum of all rows should be 400 :
| ROW |
| 20 |
| 80 |
| 300 |

Scenario: Argh! a snake - to be custom mapped
Given I see in the distance ... =====>
Then I have a snake of length 6 moving east
And I see in the distance ... <====================
Then I have a snake of length 21 moving west
Scenario: Custom object with string constructor
Given I have a person Bob
Then he should say "Hello, I'm Bob!"
Scenario: Custom objects in the belly
Given I have eaten the following cukes
| Color | Number |
| Green | 1 |
| Red | 3 |
| Blue | 2 |
Then I should have eaten 6 cukes
And they should have been Green, Red, Blue
Scenario: Did you know that we can handle call by name and zero arity
Given I drink gin and vermouth
When I shake my belly
Then I should have lots of martinis
10 changes: 10 additions & 0 deletions integration-tests/scalatest/src/test/scala/RunCukesTest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package cukes

import io.cucumber.scalatest.{CucumberSuite, CucumberSuiteOptions}

class RunCukesTest extends CucumberSuite with CucumberSuiteOptions {

override def featuresPath: Seq[String] = Nil

override def gluePackages: Seq[String] = Nil
}
185 changes: 185 additions & 0 deletions integration-tests/scalatest/src/test/scala/StepDefs.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
import io.cucumber.datatable.DataTable
import io.cucumber.scala.{EN, ScalaDsl}
import model.{Cukes, Person, Snake}
import org.junit.Assert.assertEquals

import java.util.{List => JList, Map => JMap}
import scala.annotation.nowarn
import scala.jdk.CollectionConverters._

/** Test step definitions to exercise Scala cucumber
*/
@nowarn
class CukesStepDefinitions extends ScalaDsl with EN {

var calorieCount = 0.0
var intBelly: Int = 0
var longBelly: Long = 0L
var stringBelly: String = ""
var doubleBelly: Double = 0.0
var floatBelly: Float = 0.0f
var shortBelly: Short = 0.toShort
var byteBelly: Byte = 0.toByte
var bigDecimalBelly: BigDecimal = BigDecimal(0)
var bigIntBelly: BigInt = BigInt(0)
var charBelly: Char = 'A'
var boolBelly: Boolean = false
var snake: Snake = null
var person: Person = null
var cukes: JList[Cukes] = null
var gin: Int = 13
var vermouth: Int = 42
var maritinis: Int = 0

Given("""I have {} {string} in my belly""") { (howMany: Int, what: String) =>
}

Given("""^I have the following foods :$""") { (table: DataTable) =>
val maps: JList[JMap[String, String]] =
table.asMaps(classOf[String], classOf[String])
calorieCount =
maps.asScala.map(_.get("CALORIES")).map(_.toDouble).fold(0.0)(_ + _)
}
And("""have eaten {double} calories today""") { (calories: Double) =>
assertEquals(calories, calorieCount, 0.0)
}

Given("""I have eaten an int {int}""") { (arg0: Int) =>
intBelly = arg0
}
Then("""^I should have one hundred in my belly$""") { () =>
assertEquals(100, intBelly)
}

Given("""I have eaten a long {long}""") { (arg0: Long) =>
longBelly = arg0
}
Then("""^I should have long one hundred in my belly$""") { () =>
assertEquals(100L, longBelly)
}

Given("""^I have eaten "(.*)"$""") { (arg0: String) =>
stringBelly = arg0
}
Then("""^I should have numnumnum in my belly$""") { () =>
assertEquals("numnumnum", stringBelly)
}

Given("""I have eaten {double} doubles""") { (arg0: Double) =>
doubleBelly = arg0
}
Then("""^I should have one and a half doubles in my belly$""") { () =>
assertEquals(1.5, doubleBelly, 0.0)
}

Given("""I have eaten {} floats""") { (arg0: Float) =>
floatBelly = arg0
}
Then("""^I should have one and a half floats in my belly$""") { () =>
assertEquals(1.5f, floatBelly, 0.0)
}

Given("""I have eaten a short {short}""") { (arg0: Short) =>
shortBelly = arg0
}
Then("""^I should have short one hundred in my belly$""") { () =>
assertEquals(100.toShort, shortBelly)
}

Given("""I have eaten a byte {byte}""") { (arg0: Byte) =>
byteBelly = arg0
}
Then("""^I should have two byte in my belly$""") { () =>
assertEquals(2.toByte, byteBelly)
}

Given("""I have eaten {bigdecimal} big decimals""") {
(arg0: java.math.BigDecimal) =>
bigDecimalBelly = arg0
}
Then("""^I should have one and a half big decimals in my belly$""") { () =>
assertEquals(BigDecimal(1.5), bigDecimalBelly)
}

Given("""I have eaten {biginteger} big int""") {
(arg0: java.math.BigInteger) =>
bigIntBelly = arg0.intValue()
}
Then("""^I should have a ten big int in my belly$""") { () =>
assertEquals(BigInt(10), bigIntBelly)
}

Given("""I have eaten char '{char}'""") { (arg0: Char) =>
charBelly = 'C'
}
Then("""^I should have character C in my belly$""") { () =>
assertEquals('C', charBelly)
}

Given("""I have eaten boolean {boolean}""") { (arg0: Boolean) =>
boolBelly = arg0
}
Then("""^I should have truth in my belly$""") { () =>
assertEquals(true, boolBelly)
}

Given("""I have a table the sum of all rows should be {int} :""") {
(value: Int, table: DataTable) =>
assertEquals(
value,
table
.asList(classOf[String])
.asScala
.drop(1)
.map(String.valueOf(_: String).toInt)
.foldLeft(0)(_ + _)
)
}

Given("""I see in the distance ... {snake}""") { (s: Snake) =>
snake = s
}
Then("""^I have a snake of length (\d+) moving (.*)$""") {
(size: Int, dir: String) =>
assertEquals(size, snake.length)
assertEquals(Symbol(dir), snake.direction)
}

Given("""I have a person {person}""") { (p: Person) =>
person = p
}

Then("""^he should say \"(.*)\"""") { (s: String) =>
assertEquals(person.hello, s)
}

Given("^I have eaten the following cukes$") { (cs: JList[Cukes]) =>
cukes = cs
}

Then("""I should have eaten {int} cukes""") { (total: Int) =>
assertEquals(total, cukes.asScala.map(_.number).sum)
}

And("^they should have been (.*)$") { (colors: String) =>
assertEquals(colors, cukes.asScala.map(_.color).mkString(", "))
}

Given("^I drink gin and vermouth$") { () =>
gin = 13
vermouth = 42
}

When("^I shake my belly$") { // note the lack of () =>
maritinis += vermouth * gin
}

Then("^I should have lots of martinis$") { () =>
assertEquals(13 * 42, maritinis)
}
}

@nowarn
class ThenDefs extends ScalaDsl with EN {
Then("""^I am "([^"]*)"$""") { (arg0: String) => }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import io.cucumber.scala.ScalaDsl
import model.{Cukes, Person, Snake}

class TypeRegistryConfiguration extends ScalaDsl {

/** Transforms an ASCII snake into an object, for example:
*
* {{{
* ====> becomes Snake(length = 5, direction = 'east)
* ==> becomes Snake(length = 3, direction = 'east)
* }}}
*/
ParameterType("snake", "[=><]+") { s =>
val size = s.length
val direction = s.toList match {
case '<' :: _ => Symbol("west")
case l if l.last == '>' => Symbol("east")
case _ => Symbol("unknown")
}
Snake(size, direction)
}

ParameterType("person", ".+") { s =>
Person(s)
}

ParameterType("boolean", "true|false") { s =>
s.trim.equals("true")
}

ParameterType("char", ".") { s =>
s.charAt(0)
}

DataTableType { (map: Map[String, String]) =>
Cukes(map("Number").toInt, map("Color"))
}

}
Loading

0 comments on commit fc18ad2

Please sign in to comment.