Skip to content

Add new matcher syntax for comparing collections regardless of order #1372

@leonard84

Description

@leonard84

Is your feature request related to a problem?

I'm always frustrated, when I want to make sure, that two collections have the same elements, regardless of their order.

The current way to do it, is to cast both to Set, e.g., x as Set == [1, 2, 3] as Set, but that is verbose. Also if you want to make sure that duplicate Elements are recognized as well, then you'll have to use something like Hamcrest's containsInAnyOrder.

Describe the solution you'd like

I'd like to be able to use a shorter Spock like syntax for comparing collections.
So, I propose to use =~ and ==~ for this:

  • x =~ [1, 2, 3] would be a lenient match, i.e., casting both to Set before comparing
  • x ==~ [1, 3, 3] would be a strict match, using containsInAnyOrder under the hood so that duplicate elements are verified as well.

Describe alternatives you've considered

No response

Additional context

The proposed matchers have some limitations as we will have to do this in the AST transformation during compile time. So we only have static data available, and we don't want to break the existing behavior.

Limitations

  • Would only be applied if either of the Expression in the BinaryExpression
    • Is a VariableExpression which type is a known Collection subclass or Iterable
    • Is a ListExpression
  def "matchers"() {
    def x = [1]
    List y = [1]
    def z = [1]
    
    expect:
    x ==~ [1]  // works 
    x ==~ y    // works
    x ==~ z    // would default to normal Groovy Semantics as both are `Object` and fail for this case
  }

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions