Skip to content

Get rid of ScenarioScoped #391

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

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ scalaVersion := scala213

// Library versions

val cucumberVersion = "7.21.1"
val cucumberVersion = "7.22.0"
val jacksonVersion = "2.18.3"
val mockitoScalaVersion = "1.17.37"
val junitVersion = "4.13.2"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ trait AbstractGlueDefinition extends Located {

val location: StackTraceElement

lazy val sourceReference: SourceReference =
def body: Any => Any

// def updateClosure(other: AbstractGlueDefinition): Unit

private lazy val sourceReference: SourceReference =
SourceReference.fromStackTraceElement(location)

override def getLocation(): String = {
Expand Down
87 changes: 73 additions & 14 deletions cucumber-scala/src/main/scala/io/cucumber/scala/GlueAdaptor.scala
Original file line number Diff line number Diff line change
@@ -1,9 +1,31 @@
package io.cucumber.scala

import io.cucumber.core.backend.Glue
import io.cucumber.core.backend.{CucumberBackendException, Glue}

import scala.collection.mutable.ArrayBuffer

class GlueAdaptor(glue: Glue) {

private val definitions: ArrayBuffer[AbstractGlueDefinition] = ArrayBuffer()
private var registered: Int = 0
private var expectedRegistrations: Int = -1

def startRegistration(): Unit = {
registered = 0
}

def finishRegistration(): Unit = {
if (expectedRegistrations < 0) {
expectedRegistrations = registered
} else if (expectedRegistrations != registered) {
throw new CucumberBackendException(
s"""Found an inconsistent number of glue registrations.
|Previously $expectedRegistrations step definitions, hooks and parameter types were registered. Currently $registered.
|To optimize performance Cucumber expects glue registration to be identical for each scenario and example.""".stripMargin
)
}
}

/** Load the step definitions and hooks from a ScalaDsl instance into the
* glue.
*
Expand All @@ -25,50 +47,87 @@ class GlueAdaptor(glue: Glue) {

registry.stepDefinitions
.map(ScalaStepDefinition(_, scenarioScoped))
.foreach(glue.addStepDefinition)
.foreach(df => updateOrRegister(df, glue.addStepDefinition))

// The presence of beforeAll/afterAll hooks with scenarioScoped is checked by checkConsistency above
if (!scenarioScoped) {
registry.beforeAllHooks
.map(ScalaStaticHookDefinition(_))
.foreach(glue.addBeforeAllHook)
.foreach(df => updateOrRegister(df, glue.addBeforeAllHook))
registry.afterAllHooks
.map(ScalaStaticHookDefinition(_))
.foreach(glue.addAfterAllHook)
.foreach(df => updateOrRegister(df, glue.addAfterAllHook))
}

registry.beforeHooks
.map(ScalaHookDefinition(_, scenarioScoped))
.foreach(glue.addBeforeHook)
.foreach(df => updateOrRegister(df, glue.addBeforeHook))
registry.afterHooks
.map(ScalaHookDefinition(_, scenarioScoped))
.foreach(glue.addAfterHook)
.foreach(df => updateOrRegister(df, glue.addAfterHook))
registry.beforeStepHooks
.map(ScalaHookDefinition(_, scenarioScoped))
.foreach(glue.addBeforeStepHook)
.foreach(df => updateOrRegister(df, glue.addBeforeStepHook))
registry.afterStepHooks
.map(ScalaHookDefinition(_, scenarioScoped))
.foreach(glue.addAfterStepHook)
.foreach(df => updateOrRegister(df, glue.addAfterStepHook))

registry.docStringTypes
.map(ScalaDocStringTypeDefinition(_, scenarioScoped))
.foreach(glue.addDocStringType)
.foreach(df => updateOrRegister(df, glue.addDocStringType))
registry.dataTableTypes
.map(ScalaDataTableTypeDefinition(_, scenarioScoped))
.foreach(glue.addDataTableType)
.foreach(df => updateOrRegister(df, glue.addDataTableType))
registry.parameterTypes
.map(ScalaParameterTypeDefinition(_, scenarioScoped))
.foreach(glue.addParameterType)
.foreach(df => updateOrRegister(df, glue.addParameterType))

registry.defaultParameterTransformers
.map(ScalaDefaultParameterTransformerDefinition(_, scenarioScoped))
.foreach(glue.addDefaultParameterTransformer)
.foreach(df => updateOrRegister(df, glue.addDefaultParameterTransformer))
registry.defaultDataTableCellTransformers
.map(ScalaDefaultDataTableCellTransformerDefinition(_, scenarioScoped))
.foreach(glue.addDefaultDataTableCellTransformer)
.foreach(df =>
updateOrRegister(df, glue.addDefaultDataTableCellTransformer)
)
registry.defaultDataTableEntryTransformers
.map(ScalaDefaultDataTableEntryTransformerDefinition(_, scenarioScoped))
.foreach(glue.addDefaultDataTableEntryTransformer)
.foreach(df =>
updateOrRegister(df, glue.addDefaultDataTableEntryTransformer)
)
}

private def updateOrRegister[T <: AbstractGlueDefinition](
candidate: T,
register: T => Unit
): Unit = {
if (definitions.size <= registered) {
definitions.addOne(candidate)
register.apply(candidate)
} else {
val existing: AbstractGlueDefinition = definitions(registered)
requireSameGlueClass(existing, candidate)
println("BOOM should update closure")
// TODO
}
registered = registered + 1
}

private def requireSameGlueClass[T <: AbstractGlueDefinition](
existing: AbstractGlueDefinition,
candidate: AbstractGlueDefinition
): Unit = {
if (existing.getClass != candidate.getClass) {
throw new CucumberBackendException(
s"""Found an inconsistent glue registrations.
|Previously the registration in slot $registered was a '${existing.getClass.getName}'. Currently '${candidate.getClass.getName}'.
|To optimize performance Cucumber expects glue registration to be identical for each scenario and example."""".stripMargin
)
}
}

// private[scala] def disposeClosures(): Unit = {
// definitions.foreach(_.disposeClosure)
// }

}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class ScalaBackend(

override def disposeWorld(): Unit = {
// Nothing to do
// TODO maybe something
}

override def getSnippet(): Snippet = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.cucumber.scala

import io.cucumber.core.backend.ScenarioScoped
import io.cucumber.datatable.{DataTableType, TableCellTransformer}

trait ScalaDataTableCellDefinition[T] extends ScalaDataTableTypeDefinition {
Expand All @@ -22,8 +21,7 @@ trait ScalaDataTableCellDefinition[T] extends ScalaDataTableTypeDefinition {

class ScalaScenarioScopedDataTableCellDefinition[T](
override val details: ScalaDataTableCellTypeDetails[T]
) extends ScalaDataTableCellDefinition[T]
with ScenarioScoped {}
) extends ScalaDataTableCellDefinition[T] {}

class ScalaGlobalDataTableCellDefinition[T](
override val details: ScalaDataTableCellTypeDetails[T]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.cucumber.scala

import io.cucumber.core.backend.ScenarioScoped
import io.cucumber.datatable.{DataTable, DataTableType, TableTransformer}

trait ScalaDataTableDefinition[T] extends ScalaDataTableTypeDefinition {
Expand All @@ -22,8 +21,7 @@ trait ScalaDataTableDefinition[T] extends ScalaDataTableTypeDefinition {

class ScalaScenarioScopedDataTableDefinition[T](
override val details: ScalaDataTableTableTypeDetails[T]
) extends ScalaDataTableDefinition[T]
with ScenarioScoped {}
) extends ScalaDataTableDefinition[T] {}

class ScalaGlobalDataTableDefinition[T](
override val details: ScalaDataTableTableTypeDetails[T]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package io.cucumber.scala

import java.util.{Map => JavaMap}

import io.cucumber.core.backend.ScenarioScoped
import io.cucumber.datatable.{DataTableType, TableEntryTransformer}

import java.util.{Map => JavaMap}
import scala.jdk.CollectionConverters._

trait ScalaDataTableEntryDefinition[T] extends ScalaDataTableTypeDefinition {
Expand All @@ -29,8 +27,7 @@ trait ScalaDataTableEntryDefinition[T] extends ScalaDataTableTypeDefinition {

class ScalaScenarioScopedDataTableEntryDefinition[T](
override val details: ScalaDataTableEntryTypeDetails[T]
) extends ScalaDataTableEntryDefinition[T]
with ScenarioScoped {}
) extends ScalaDataTableEntryDefinition[T] {}

class ScalaGlobalDataTableEntryDefinition[T](
override val details: ScalaDataTableEntryTypeDetails[T]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.cucumber.scala

import io.cucumber.core.backend.ScenarioScoped
import io.cucumber.datatable.{DataTableType, TableCellTransformer}

trait ScalaDataTableOptionalCellDefinition[T]
Expand All @@ -23,8 +22,7 @@ trait ScalaDataTableOptionalCellDefinition[T]

class ScalaScenarioScopedDataTableOptionalCellDefinition[T](
override val details: ScalaDataTableOptionalCellTypeDetails[T]
) extends ScalaDataTableOptionalCellDefinition[T]
with ScenarioScoped {}
) extends ScalaDataTableOptionalCellDefinition[T] {}

class ScalaGlobalDataTableOptionalCellDefinition[T](
override val details: ScalaDataTableOptionalCellTypeDetails[T]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package io.cucumber.scala

import java.util.{Map => JavaMap}

import io.cucumber.core.backend.ScenarioScoped
import io.cucumber.datatable.{DataTableType, TableEntryTransformer}

import java.util.{Map => JavaMap}
import scala.jdk.CollectionConverters._

trait ScalaDataTableOptionalEntryDefinition[T]
Expand All @@ -31,8 +29,7 @@ trait ScalaDataTableOptionalEntryDefinition[T]

class ScalaScenarioScopedDataTableOptionalEntryDefinition[T](
override val details: ScalaDataTableOptionalEntryTypeDetails[T]
) extends ScalaDataTableOptionalEntryDefinition[T]
with ScenarioScoped {}
) extends ScalaDataTableOptionalEntryDefinition[T] {}

class ScalaGlobalDataTableOptionalEntryDefinition[T](
override val details: ScalaDataTableOptionalEntryTypeDetails[T]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package io.cucumber.scala

import java.util.{List => JavaList}

import io.cucumber.core.backend.ScenarioScoped
import io.cucumber.datatable.{DataTableType, TableRowTransformer}

import java.util.{List => JavaList}
import scala.jdk.CollectionConverters._

trait ScalaDataTableOptionalRowDefinition[T]
Expand Down Expand Up @@ -32,8 +30,7 @@ trait ScalaDataTableOptionalRowDefinition[T]

class ScalaScenarioScopedDataTableOptionalRowDefinition[T](
override val details: ScalaDataTableOptionalRowTypeDetails[T]
) extends ScalaDataTableOptionalRowDefinition[T]
with ScenarioScoped {}
) extends ScalaDataTableOptionalRowDefinition[T] {}

class ScalaGlobalDataTableOptionalRowDefinition[T](
override val details: ScalaDataTableOptionalRowTypeDetails[T]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package io.cucumber.scala

import java.util.{List => JavaList}

import io.cucumber.core.backend.ScenarioScoped
import io.cucumber.datatable.{DataTableType, TableRowTransformer}

import java.util.{List => JavaList}
import scala.jdk.CollectionConverters._

trait ScalaDataTableRowDefinition[T] extends ScalaDataTableTypeDefinition {
Expand All @@ -28,8 +26,7 @@ trait ScalaDataTableRowDefinition[T] extends ScalaDataTableTypeDefinition {

class ScalaScenarioScopedDataTableRowDefinition[T](
override val details: ScalaDataTableRowTypeDetails[T]
) extends ScalaDataTableRowDefinition[T]
with ScenarioScoped {}
) extends ScalaDataTableRowDefinition[T] {}

class ScalaGlobalDataTableRowDefinition[T](
override val details: ScalaDataTableRowTypeDetails[T]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
package io.cucumber.scala

import java.lang.reflect.Type

import io.cucumber.core.backend.{
DefaultDataTableCellTransformerDefinition,
ScenarioScoped
}
import io.cucumber.core.backend.DefaultDataTableCellTransformerDefinition
import io.cucumber.datatable.TableCellByTypeTransformer

import java.lang.reflect.Type

trait ScalaDefaultDataTableCellTransformerDefinition
extends DefaultDataTableCellTransformerDefinition
with AbstractDatatableElementTransformerDefinition {
Expand Down Expand Up @@ -45,8 +42,7 @@ object ScalaDefaultDataTableCellTransformerDefinition {

class ScalaScenarioScopedDataTableCellTransformerDefinition(
override val details: ScalaDefaultDataTableCellTransformerDetails
) extends ScalaDefaultDataTableCellTransformerDefinition
with ScenarioScoped {}
) extends ScalaDefaultDataTableCellTransformerDefinition {}

class ScalaGlobalDataTableCellTransformerDefinition(
override val details: ScalaDefaultDataTableCellTransformerDetails
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
package io.cucumber.scala

import java.lang.reflect.Type
import java.util.{Map => JavaMap}

import io.cucumber.core.backend.{
DefaultDataTableEntryTransformerDefinition,
ScenarioScoped
}
import io.cucumber.core.backend.DefaultDataTableEntryTransformerDefinition
import io.cucumber.datatable.{
TableCellByTypeTransformer,
TableEntryByTypeTransformer
}

import java.lang.reflect.Type
import java.util.{Map => JavaMap}
import scala.jdk.CollectionConverters._

trait ScalaDefaultDataTableEntryTransformerDefinition
Expand Down Expand Up @@ -55,8 +51,7 @@ object ScalaDefaultDataTableEntryTransformerDefinition {

class ScalaScenarioScopedDataTableEntryTransformerDefinition(
override val details: ScalaDefaultDataTableEntryTransformerDetails
) extends ScalaDefaultDataTableEntryTransformerDefinition
with ScenarioScoped {}
) extends ScalaDefaultDataTableEntryTransformerDefinition {}

class ScalaGlobalDataTableEntryTransformerDefinition(
override val details: ScalaDefaultDataTableEntryTransformerDetails
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
package io.cucumber.scala

import java.lang.reflect.Type

import io.cucumber.core.backend.{
DefaultParameterTransformerDefinition,
ScenarioScoped
}
import io.cucumber.core.backend.DefaultParameterTransformerDefinition
import io.cucumber.cucumberexpressions.ParameterByTypeTransformer

import java.lang.reflect.Type

trait ScalaDefaultParameterTransformerDefinition
extends DefaultParameterTransformerDefinition
with AbstractGlueDefinition {
Expand Down Expand Up @@ -40,8 +37,7 @@ object ScalaDefaultParameterTransformerDefinition {

class ScalaScenarioScopedDefaultParameterTransformerDefinition(
override val details: ScalaDefaultParameterTransformerDetails
) extends ScalaDefaultParameterTransformerDefinition
with ScenarioScoped {}
) extends ScalaDefaultParameterTransformerDefinition {}

class ScalaGlobalDefaultParameterTransformerDefinition(
override val details: ScalaDefaultParameterTransformerDetails
Expand Down
Loading
Loading