JBehave
  1. JBehave
  2. JBEHAVE-162

Need to be able to set order of steps for matching

    Details

    • Type: Improvement Improvement
    • Status: Resolved Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.2
    • Fix Version/s: 2.5
    • Component/s: None
    • Labels:
      None
    • Number of attachments :
      0

      Description

      We have run into some difficulty declaring steps that have similar wording such that the matching was incorrect for some of our scenarios. For example:

      We have a line from one of scenarios that looks like this:

      And the table.testtable with test_1_id of foo has exactly one test_2_id of bar

      We want this line to match on the following step:

      @Given("the $tableName with $whereColumnName of $whereColumnValue has exactly one $selectColumnName of $selectColumnValue")

      But instead the match is always occuring on this step:

      @Given("the $tableName with $whereColumnName of $whereColumnValue has $selectColumnName of $selectColumnValue")

      where $selectColumnName gets interpreted as "exactly one test_2_id"

      Can we have an annotation that indicates the order by which the matching occurs? That way, the first step in our example would always get compared first to our example input line instead of step two. For example something like this:

      @Order(1)
      @Given("the $tableName with $whereColumnName of $whereColumnValue has exactly one $selectColumnName of $selectColumnValue")

      @Order(2)
      @Given("the $tableName with $whereColumnName of $whereColumnValue has $selectColumnName of $selectColumnValue")

        Activity

        Hide
        Mauro Talevi added a comment -

        I'm not sure that we'd gain much by adding an @Order annotation.

        Couldn't you just add a qualifier in the second Given step: e.g. adding "at least one" to match the "exactly one" of the other step, and thus distinguishing the two steps?

        Show
        Mauro Talevi added a comment - I'm not sure that we'd gain much by adding an @Order annotation. Couldn't you just add a qualifier in the second Given step: e.g. adding "at least one" to match the "exactly one" of the other step, and thus distinguishing the two steps?
        Hide
        Douglas Padian added a comment -

        In the end, this is what we did. But this then forces you to change your language to get around this issue. In my opinion, the code should be flexible enough to recognize the difference between two different steps. The @Order (or whatever you want to call that) would do this. There might be a cleaner way to do this, but this was the first thing that came to mind.

        Show
        Douglas Padian added a comment - In the end, this is what we did. But this then forces you to change your language to get around this issue. In my opinion, the code should be flexible enough to recognize the difference between two different steps. The @Order (or whatever you want to call that) would do this. There might be a cleaner way to do this, but this was the first thing that came to mind.
        Hide
        Hitesh added a comment -

        Would changing the match to use non-greedy match not help?
        Current implementation is greedy:
        this.anyWordBeginningWithThePrefix = "(
        " + prefix + "\\w*)(\\W|
        Z)";
        changing it to:
        this.anyWordBeginningWithThePrefix = "(
        " + prefix + "\\w*?)(\\W|
        Z)"; //notice the ?
        will make the matching stop at the first whitespace instead of the last possible.

        Show
        Hitesh added a comment - Would changing the match to use non-greedy match not help? Current implementation is greedy: this.anyWordBeginningWithThePrefix = "( " + prefix + "\\w*)(\\W| Z)"; changing it to: this.anyWordBeginningWithThePrefix = "( " + prefix + "\\w*?)(\\W| Z)"; //notice the ? will make the matching stop at the first whitespace instead of the last possible.
        Hide
        Douglas Padian added a comment -

        I think that might work – please run your proposed solution against the example that I posted and see if it works properly. If it does, that is a more elegant solution.

        Show
        Douglas Padian added a comment - I think that might work – please run your proposed solution against the example that I posted and see if it works properly. If it does, that is a more elegant solution.
        Hide
        Mauro Talevi added a comment -

        Added order_matching.scenario in trader example to reproduce simplified behaviour and allow investigation.

        The non-greedy regex solution did not seem to work.

        Show
        Mauro Talevi added a comment - Added order_matching.scenario in trader example to reproduce simplified behaviour and allow investigation. The non-greedy regex solution did not seem to work.
        Hide
        Mauro Talevi added a comment -

        More investigation is needed, so descoping it from 2.4 release.

        Show
        Mauro Talevi added a comment - More investigation is needed, so descoping it from 2.4 release.
        Hide
        Mauro Talevi added a comment -

        Reclassified from bug to enhancement.

        Show
        Mauro Talevi added a comment - Reclassified from bug to enhancement.
        Hide
        Mauro Talevi added a comment -

        Added optional priority attribute to step method annotations (@Given, @When, @Then), to allow ordering or priotisation of methods whose regex patterns both match the same text step. To prioritise the less-greedy pattern, simply give it a higher priority (which by default is zero):

        @Given(value = "the $tableName with $whereColumnName of $whereColumnValue has exactly one $selectColumnName of $selectColumnValue", priority=1)

        will take precendence over

        @Given("the $tableName with $whereColumnName of $whereColumnValue has $selectColumnName of $selectColumnValue")

        Show
        Mauro Talevi added a comment - Added optional priority attribute to step method annotations (@Given, @When, @Then), to allow ordering or priotisation of methods whose regex patterns both match the same text step. To prioritise the less-greedy pattern, simply give it a higher priority (which by default is zero): @Given(value = "the $tableName with $whereColumnName of $whereColumnValue has exactly one $selectColumnName of $selectColumnValue", priority=1) will take precendence over @Given("the $tableName with $whereColumnName of $whereColumnValue has $selectColumnName of $selectColumnValue")

          People

          • Assignee:
            Mauro Talevi
            Reporter:
            Douglas Padian
          • Votes:
            2 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: