cucumber/cucumber-jvm-scala

Support hooks without parameter

gaeljw opened this issue · 2 comments

If possible we should support hooks without parameters.

For instance instead of writing that:

Before { _ =>
  // Some code
}

We should be able to write this:

Before {
  // Some code
}

Naive implementation would be to add methods like this:

// Current method
def Before(tagExpression: String)(body: Scenario => Unit): Unit = {
  Before(tagExpression, DEFAULT_BEFORE_ORDER)(body)
}

// Added method
def Before(tagExpression: String)(body: => Unit): Unit = {
  Before(tagExpression, DEFAULT_BEFORE_ORDER)(_ => body)
}

But from a user perspective, you get errors "Cannot resolve overloaded method 'Before'".


After having a look, I came up with a solution that I don't think it's worth shipping because it would:

  • bring some complexity in the code (similar to what is done for Step in ScalaDsl)
  • bring a breaking change to the users (need to write Before() { } or Before(order= 2) { })

What I ended up writing:

  sealed trait HookType

  case object BeforeType extends HookType
  // TODO other types

  val Before = new Hook(BeforeType)
  // TODO other vals

  final class Hook(hookType: HookType) {
    def apply(tagExpression: String = EMPTY_TAG_EXPRESSION, order: Int = DEFAULT_BEFORE_ORDER): HookImpl = new HookImpl(hookType, tagExpression, order)
  }

  final class HookImpl(hookType: HookType, tagExpression: String, order: Int) {

    def apply(body: HookBody): Unit = {
      hookType match {
        case BeforeType =>
          registry.beforeHooks += ScalaHookDetails(tagExpression, order, body)
        // TODO other cases
      }
    }

    def apply(body: => Unit): Unit = {
      apply(_ => body)
    }

  }

If anyone has an idea how to implement it easily, please shout :)

Actually, after a day of reflexion and after implementing the ParameterType stuff, the solution became obvious and there is no breaking change.