Skip to content

Commit b5b620b

Browse files
committed
WIP
1 parent 73affe9 commit b5b620b

18 files changed

+114
-86
lines changed

cucumber-scala/src/main/scala/io/cucumber/scala/AbstractGlueDefinition.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ trait AbstractGlueDefinition extends Located {
1515

1616
val location: StackTraceElement
1717

18-
lazy val sourceReference: SourceReference =
18+
def body: Any => Any
19+
20+
// def updateClosure(other: AbstractGlueDefinition): Unit
21+
22+
private lazy val sourceReference: SourceReference =
1923
SourceReference.fromStackTraceElement(location)
2024

2125
override def getLocation(): String = {
Lines changed: 73 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,31 @@
11
package io.cucumber.scala
22

3-
import io.cucumber.core.backend.Glue
3+
import io.cucumber.core.backend.{CucumberBackendException, Glue}
4+
5+
import scala.collection.mutable.ArrayBuffer
46

57
class GlueAdaptor(glue: Glue) {
68

9+
private val definitions: ArrayBuffer[AbstractGlueDefinition] = ArrayBuffer()
10+
private var registered: Int = 0
11+
private var expectedRegistrations: Int = -1
12+
13+
def startRegistration(): Unit = {
14+
registered = 0
15+
}
16+
17+
def finishRegistration(): Unit = {
18+
if (expectedRegistrations < 0) {
19+
expectedRegistrations = registered
20+
} else if (expectedRegistrations != registered) {
21+
throw new CucumberBackendException(
22+
s"""Found an inconsistent number of glue registrations.
23+
|Previously $expectedRegistrations step definitions, hooks and parameter types were registered. Currently $registered.
24+
|To optimize performance Cucumber expects glue registration to be identical for each scenario and example.""".stripMargin
25+
)
26+
}
27+
}
28+
729
/** Load the step definitions and hooks from a ScalaDsl instance into the
830
* glue.
931
*
@@ -25,50 +47,87 @@ class GlueAdaptor(glue: Glue) {
2547

2648
registry.stepDefinitions
2749
.map(ScalaStepDefinition(_, scenarioScoped))
28-
.foreach(glue.addStepDefinition)
50+
.foreach(df => updateOrRegister(df, glue.addStepDefinition))
2951

3052
// The presence of beforeAll/afterAll hooks with scenarioScoped is checked by checkConsistency above
3153
if (!scenarioScoped) {
3254
registry.beforeAllHooks
3355
.map(ScalaStaticHookDefinition(_))
34-
.foreach(glue.addBeforeAllHook)
56+
.foreach(df => updateOrRegister(df, glue.addBeforeAllHook))
3557
registry.afterAllHooks
3658
.map(ScalaStaticHookDefinition(_))
37-
.foreach(glue.addAfterAllHook)
59+
.foreach(df => updateOrRegister(df, glue.addAfterAllHook))
3860
}
3961

4062
registry.beforeHooks
4163
.map(ScalaHookDefinition(_, scenarioScoped))
42-
.foreach(glue.addBeforeHook)
64+
.foreach(df => updateOrRegister(df, glue.addBeforeHook))
4365
registry.afterHooks
4466
.map(ScalaHookDefinition(_, scenarioScoped))
45-
.foreach(glue.addAfterHook)
67+
.foreach(df => updateOrRegister(df, glue.addAfterHook))
4668
registry.beforeStepHooks
4769
.map(ScalaHookDefinition(_, scenarioScoped))
48-
.foreach(glue.addBeforeStepHook)
70+
.foreach(df => updateOrRegister(df, glue.addBeforeStepHook))
4971
registry.afterStepHooks
5072
.map(ScalaHookDefinition(_, scenarioScoped))
51-
.foreach(glue.addAfterStepHook)
73+
.foreach(df => updateOrRegister(df, glue.addAfterStepHook))
5274

5375
registry.docStringTypes
5476
.map(ScalaDocStringTypeDefinition(_, scenarioScoped))
55-
.foreach(glue.addDocStringType)
77+
.foreach(df => updateOrRegister(df, glue.addDocStringType))
5678
registry.dataTableTypes
5779
.map(ScalaDataTableTypeDefinition(_, scenarioScoped))
58-
.foreach(glue.addDataTableType)
80+
.foreach(df => updateOrRegister(df, glue.addDataTableType))
5981
registry.parameterTypes
6082
.map(ScalaParameterTypeDefinition(_, scenarioScoped))
61-
.foreach(glue.addParameterType)
83+
.foreach(df => updateOrRegister(df, glue.addParameterType))
6284

6385
registry.defaultParameterTransformers
6486
.map(ScalaDefaultParameterTransformerDefinition(_, scenarioScoped))
65-
.foreach(glue.addDefaultParameterTransformer)
87+
.foreach(df => updateOrRegister(df, glue.addDefaultParameterTransformer))
6688
registry.defaultDataTableCellTransformers
6789
.map(ScalaDefaultDataTableCellTransformerDefinition(_, scenarioScoped))
68-
.foreach(glue.addDefaultDataTableCellTransformer)
90+
.foreach(df =>
91+
updateOrRegister(df, glue.addDefaultDataTableCellTransformer)
92+
)
6993
registry.defaultDataTableEntryTransformers
7094
.map(ScalaDefaultDataTableEntryTransformerDefinition(_, scenarioScoped))
71-
.foreach(glue.addDefaultDataTableEntryTransformer)
95+
.foreach(df =>
96+
updateOrRegister(df, glue.addDefaultDataTableEntryTransformer)
97+
)
98+
}
99+
100+
private def updateOrRegister[T <: AbstractGlueDefinition](
101+
candidate: T,
102+
register: T => Unit
103+
): Unit = {
104+
if (definitions.size <= registered) {
105+
definitions.addOne(candidate)
106+
register.apply(candidate)
107+
} else {
108+
val existing: AbstractGlueDefinition = definitions(registered)
109+
requireSameGlueClass(existing, candidate)
110+
println("BOOM should update closure")
111+
// TODO
112+
}
113+
registered = registered + 1
114+
}
115+
116+
private def requireSameGlueClass[T <: AbstractGlueDefinition](
117+
existing: AbstractGlueDefinition,
118+
candidate: AbstractGlueDefinition
119+
): Unit = {
120+
if (existing.getClass != candidate.getClass) {
121+
throw new CucumberBackendException(
122+
s"""Found an inconsistent glue registrations.
123+
|Previously the registration in slot $registered was a '${existing.getClass.getName}'. Currently '${candidate.getClass.getName}'.
124+
|To optimize performance Cucumber expects glue registration to be identical for each scenario and example."""".stripMargin
125+
)
126+
}
72127
}
73128

129+
// private[scala] def disposeClosures(): Unit = {
130+
// definitions.foreach(_.disposeClosure)
131+
// }
132+
74133
}

cucumber-scala/src/main/scala/io/cucumber/scala/ScalaBackend.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class ScalaBackend(
4242

4343
override def disposeWorld(): Unit = {
4444
// Nothing to do
45+
// TODO maybe something
4546
}
4647

4748
override def getSnippet(): Snippet = {

cucumber-scala/src/main/scala/io/cucumber/scala/ScalaDataTableCellDefinition.scala

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package io.cucumber.scala
22

3-
import io.cucumber.core.backend.ScenarioScoped
43
import io.cucumber.datatable.{DataTableType, TableCellTransformer}
54

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

2322
class ScalaScenarioScopedDataTableCellDefinition[T](
2423
override val details: ScalaDataTableCellTypeDetails[T]
25-
) extends ScalaDataTableCellDefinition[T]
26-
with ScenarioScoped {}
24+
) extends ScalaDataTableCellDefinition[T] {}
2725

2826
class ScalaGlobalDataTableCellDefinition[T](
2927
override val details: ScalaDataTableCellTypeDetails[T]

cucumber-scala/src/main/scala/io/cucumber/scala/ScalaDataTableDefinition.scala

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package io.cucumber.scala
22

3-
import io.cucumber.core.backend.ScenarioScoped
43
import io.cucumber.datatable.{DataTable, DataTableType, TableTransformer}
54

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

2322
class ScalaScenarioScopedDataTableDefinition[T](
2423
override val details: ScalaDataTableTableTypeDetails[T]
25-
) extends ScalaDataTableDefinition[T]
26-
with ScenarioScoped {}
24+
) extends ScalaDataTableDefinition[T] {}
2725

2826
class ScalaGlobalDataTableDefinition[T](
2927
override val details: ScalaDataTableTableTypeDetails[T]

cucumber-scala/src/main/scala/io/cucumber/scala/ScalaDataTableEntryDefinition.scala

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package io.cucumber.scala
22

3-
import java.util.{Map => JavaMap}
4-
5-
import io.cucumber.core.backend.ScenarioScoped
63
import io.cucumber.datatable.{DataTableType, TableEntryTransformer}
74

5+
import java.util.{Map => JavaMap}
86
import scala.jdk.CollectionConverters._
97

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

3028
class ScalaScenarioScopedDataTableEntryDefinition[T](
3129
override val details: ScalaDataTableEntryTypeDetails[T]
32-
) extends ScalaDataTableEntryDefinition[T]
33-
with ScenarioScoped {}
30+
) extends ScalaDataTableEntryDefinition[T] {}
3431

3532
class ScalaGlobalDataTableEntryDefinition[T](
3633
override val details: ScalaDataTableEntryTypeDetails[T]

cucumber-scala/src/main/scala/io/cucumber/scala/ScalaDataTableOptionalCellDefinition.scala

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package io.cucumber.scala
22

3-
import io.cucumber.core.backend.ScenarioScoped
43
import io.cucumber.datatable.{DataTableType, TableCellTransformer}
54

65
trait ScalaDataTableOptionalCellDefinition[T]
@@ -23,8 +22,7 @@ trait ScalaDataTableOptionalCellDefinition[T]
2322

2423
class ScalaScenarioScopedDataTableOptionalCellDefinition[T](
2524
override val details: ScalaDataTableOptionalCellTypeDetails[T]
26-
) extends ScalaDataTableOptionalCellDefinition[T]
27-
with ScenarioScoped {}
25+
) extends ScalaDataTableOptionalCellDefinition[T] {}
2826

2927
class ScalaGlobalDataTableOptionalCellDefinition[T](
3028
override val details: ScalaDataTableOptionalCellTypeDetails[T]

cucumber-scala/src/main/scala/io/cucumber/scala/ScalaDataTableOptionalEntryDefinition.scala

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package io.cucumber.scala
22

3-
import java.util.{Map => JavaMap}
4-
5-
import io.cucumber.core.backend.ScenarioScoped
63
import io.cucumber.datatable.{DataTableType, TableEntryTransformer}
74

5+
import java.util.{Map => JavaMap}
86
import scala.jdk.CollectionConverters._
97

108
trait ScalaDataTableOptionalEntryDefinition[T]
@@ -31,8 +29,7 @@ trait ScalaDataTableOptionalEntryDefinition[T]
3129

3230
class ScalaScenarioScopedDataTableOptionalEntryDefinition[T](
3331
override val details: ScalaDataTableOptionalEntryTypeDetails[T]
34-
) extends ScalaDataTableOptionalEntryDefinition[T]
35-
with ScenarioScoped {}
32+
) extends ScalaDataTableOptionalEntryDefinition[T] {}
3633

3734
class ScalaGlobalDataTableOptionalEntryDefinition[T](
3835
override val details: ScalaDataTableOptionalEntryTypeDetails[T]

cucumber-scala/src/main/scala/io/cucumber/scala/ScalaDataTableOptionalRowDefinition.scala

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package io.cucumber.scala
22

3-
import java.util.{List => JavaList}
4-
5-
import io.cucumber.core.backend.ScenarioScoped
63
import io.cucumber.datatable.{DataTableType, TableRowTransformer}
74

5+
import java.util.{List => JavaList}
86
import scala.jdk.CollectionConverters._
97

108
trait ScalaDataTableOptionalRowDefinition[T]
@@ -32,8 +30,7 @@ trait ScalaDataTableOptionalRowDefinition[T]
3230

3331
class ScalaScenarioScopedDataTableOptionalRowDefinition[T](
3432
override val details: ScalaDataTableOptionalRowTypeDetails[T]
35-
) extends ScalaDataTableOptionalRowDefinition[T]
36-
with ScenarioScoped {}
33+
) extends ScalaDataTableOptionalRowDefinition[T] {}
3734

3835
class ScalaGlobalDataTableOptionalRowDefinition[T](
3936
override val details: ScalaDataTableOptionalRowTypeDetails[T]

cucumber-scala/src/main/scala/io/cucumber/scala/ScalaDataTableRowDefinition.scala

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package io.cucumber.scala
22

3-
import java.util.{List => JavaList}
4-
5-
import io.cucumber.core.backend.ScenarioScoped
63
import io.cucumber.datatable.{DataTableType, TableRowTransformer}
74

5+
import java.util.{List => JavaList}
86
import scala.jdk.CollectionConverters._
97

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

2927
class ScalaScenarioScopedDataTableRowDefinition[T](
3028
override val details: ScalaDataTableRowTypeDetails[T]
31-
) extends ScalaDataTableRowDefinition[T]
32-
with ScenarioScoped {}
29+
) extends ScalaDataTableRowDefinition[T] {}
3330

3431
class ScalaGlobalDataTableRowDefinition[T](
3532
override val details: ScalaDataTableRowTypeDetails[T]

0 commit comments

Comments
 (0)