JBehave
  1. JBehave
  2. JBEHAVE-702

Allow directives to support multiple step pattern variant

    Details

    • Type: New Feature New Feature
    • Status: Resolved Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 3.5.4
    • Fix Version/s: 3.6
    • Component/s: Core
    • Labels:
    • Number of attachments :
      3

      Description

      To get more natural German story texts, it would be very helpful if the Steps.listCandidates() method could be amended.
      This would allow for automatically generating slight variations of the texts without having to specify them all as aliases. Currently I am doing this:

      @Then("soll foo bar with $xyz")
      @Aliases(values =

      { "foo bar with $xyz", "soll foo bar: $xyz", "foo bar: $xyz" }

      )

      The word "soll" is made optional this way. The reasoning behind this is that when using "And" it is more natural to write

      Then soll something else
      And foo bar with $xyz

      instead of

      Then soll something else
      And soll foo bar with $xyz

      It would be very nice to not have define aliases for all these variants, because it makes the code harder to maintain. Instead, I though I'd add this dynamically, the same way annotated Aliases are, but it seems this functionality would require providing a new subclass of org.jbehave.core.steps.Steps which I cannot see how to do.

      I suggest a change like this:

      1) In org.jbehave.core.steps.Steps add another call in listCandidates() after each of the addCandidatesFromAliases(...) like addCustomDerivedCandidates(...) with the same signature and a protected empty default implementation.
      2) Allow configuration to specify a custom subclass of org.jbehave.core.steps.Steps. In there custom additions to the candidates list could be made, like the one I described.

        Activity

        Hide
        Brian Repko added a comment -

        Been sort of watching this issue go by - thought I'd jump in. At first I thought that perhaps this points to variant keyword expression but now see that that isn't the case.

        If we go the route of permutable @Given/@When/@Then, then we could introduce a regex escape character - allowing the author to specify the explicit regex for that part of the value. In Daniel's examples, the '

        {' and '}

        ' characters do that. But it could look a bit like JAX-RS @Path regex escapes as well - if you are looking for a syntax that is already in use in the java world. JAX-RS does this around variables but perhaps we could introduce the variable as optional.

        @Then(value="A {:must|has to|is to} be

        {x}

        unless {:it's|it is} {:part of|contained in} {:list?}

        {y}

        ")
        @Then(value="A $:must|has to|is to be $x unless $:it's|it is $:part of|contained in $:list?$y")

        Problem as you can tell is that we have variable prefix but not suffix (variable ends at whitespace).
        It may be that if you want to use regex, then you have to have prefix AND suffix.

        Just my thought from another space (JAX-RS) that is somewhat similar.

        Also be careful with your spaces - matching on your examples requires 2 spaces - "A must be $x unless it's..."

        Show
        Brian Repko added a comment - Been sort of watching this issue go by - thought I'd jump in. At first I thought that perhaps this points to variant keyword expression but now see that that isn't the case. If we go the route of permutable @Given/@When/@Then, then we could introduce a regex escape character - allowing the author to specify the explicit regex for that part of the value. In Daniel's examples, the ' {' and '} ' characters do that. But it could look a bit like JAX-RS @Path regex escapes as well - if you are looking for a syntax that is already in use in the java world. JAX-RS does this around variables but perhaps we could introduce the variable as optional. @Then(value="A {:must|has to|is to} be {x} unless {:it's|it is} {:part of|contained in} {:list?} {y} ") @Then(value="A $:must|has to|is to be $x unless $:it's|it is $:part of|contained in $:list?$y") Problem as you can tell is that we have variable prefix but not suffix (variable ends at whitespace). It may be that if you want to use regex, then you have to have prefix AND suffix. Just my thought from another space (JAX-RS) that is somewhat similar. Also be careful with your spaces - matching on your examples requires 2 spaces - "A must be $x unless it's..."
        Hide
        Mauro Talevi added a comment -

        Hi Daniel, nice work. I've applied and pushed patch (slightly modified wrt names).

        Show
        Mauro Talevi added a comment - Hi Daniel, nice work. I've applied and pushed patch (slightly modified wrt names).
        Hide
        Mauro Talevi added a comment -

        Hi Daniel, can you confirm if this issue can be reseolved? Does the current master satisfy your usecase?

        Show
        Mauro Talevi added a comment - Hi Daniel, can you confirm if this issue can be reseolved? Does the current master satisfy your usecase?
        Hide
        Ivan Verdezoto added a comment -

        Hi,
        I updated to jbehave-core 3.6 and I am not able to use the pattern variant.
        All steps had matched perfect before with this configuration,
        But after I changed some steps (in the steps class) with the variant notation, Jbehave marks thess steps as pending. Do I miss something? Should I change something in the configuration class?

        Here is a dumb tested example of what I got:

        • Story file:

        Scenario: Test

        Given A x B 10.0
        And A y B 1.0

        • Steps class:

        @Given("A

        {x|y}

        B $quantity")
        public void theItemPriceIs(String q)

        { // ... }
        • Configuration:

        MostUsefulConfiguration()
        .useStoryControls(new StoryControls().doSkipScenariosAfterFailure(false))
        .useStoryLoader(new LoadFromClasspath(embeddableClass.getClassLoader()))
        .usePathCalculator(new RelativePathCalculator())
        .useStoryReporterBuilder(reporterBuilder);

        • Eclipse console output:

        Processing system properties {}
        Using controls EmbedderControls[batch=false,skip=false,generateViewAfterStories=true,ignoreFailureInStories=true,ignoreFailureInView=true,verboseFailures=false,verboseFiltering=false,storyTimeoutInSecs=300,threads=1]
        Using 1 threads

        (BeforeStories)

        Running story jbehave/tmp_stories/123.story

        (jbehave/tmp_stories/123.story)
        Scenario: Test
        Given A x B 10.0 (PENDING)
        And A y B 1.0 (PENDING)
        @Given("A x B 10.0")
        @Pending
        public void givenAXB100()

        { // PENDING }

        @Given("A y B 1.0")
        @Pending
        public void givenAYB10(){ // PENDING }

        .
        .
        .

        Show
        Ivan Verdezoto added a comment - Hi, I updated to jbehave-core 3.6 and I am not able to use the pattern variant. All steps had matched perfect before with this configuration, But after I changed some steps (in the steps class) with the variant notation, Jbehave marks thess steps as pending. Do I miss something? Should I change something in the configuration class? Here is a dumb tested example of what I got: Story file: Scenario: Test Given A x B 10.0 And A y B 1.0 Steps class: @Given("A {x|y} B $quantity") public void theItemPriceIs(String q) { // ... } Configuration: MostUsefulConfiguration() .useStoryControls(new StoryControls().doSkipScenariosAfterFailure(false)) .useStoryLoader(new LoadFromClasspath(embeddableClass.getClassLoader())) .usePathCalculator(new RelativePathCalculator()) .useStoryReporterBuilder(reporterBuilder); Eclipse console output: Processing system properties {} Using controls EmbedderControls [batch=false,skip=false,generateViewAfterStories=true,ignoreFailureInStories=true,ignoreFailureInView=true,verboseFailures=false,verboseFiltering=false,storyTimeoutInSecs=300,threads=1] Using 1 threads (BeforeStories) Running story jbehave/tmp_stories/123.story (jbehave/tmp_stories/123.story) Scenario: Test Given A x B 10.0 (PENDING) And A y B 1.0 (PENDING) @Given("A x B 10.0") @Pending public void givenAXB100() { // PENDING } @Given("A y B 1.0") @Pending public void givenAYB10(){ // PENDING } . . .
        Hide
        Daniel Schneller added a comment -

        Should not be anything special you need to do. I tried your method with the annotations (copy and pasted them), and it worked ok. I suspect you might not have switched to 3.6 after all. Maybe double check (if need be with a debugger), which JAR is being loaded at runtime. However, I think further bug hunting is not for JIRA, but would better happen on a mailing list? (http://jbehave.org/mailing-lists.html)

        Show
        Daniel Schneller added a comment - Should not be anything special you need to do. I tried your method with the annotations (copy and pasted them), and it worked ok. I suspect you might not have switched to 3.6 after all. Maybe double check (if need be with a debugger), which JAR is being loaded at runtime. However, I think further bug hunting is not for JIRA, but would better happen on a mailing list? ( http://jbehave.org/mailing-lists.html )

          People

          • Assignee:
            Mauro Talevi
            Reporter:
            Daniel Schneller
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: