pact-foundation / pact-reference

Reference implementations for the pact specifications
https://pact.io
MIT License
91 stars 46 forks source link

Support composing matching rules in FFI #399

Closed mefellows closed 3 months ago

mefellows commented 4 months ago

Pact JVM supports combining matching rules using the AND logical expression.

It is currently not possible to do this via the FFI (e.g. using https://docs.pact.io/implementation_guides/rust/pact_ffi/integrationjson as a guide).

The matching definition expressions do support nesting, however they are not supported via the FFI in the integration JSON.

There are two options to support this:

  1. update the FFI to allow multiple matching rules
  2. update the FFI to support the matching definition expressions

Ideally, a method that allows the most flexible

Example

From a request in slack.

How might you write a matcher to check both the keys and values and the same time (use eachKeyMatches and eachValueMatches simultaneously):

    enum Keys {
      One = "One",
      Two = "Two",
    }

    interface Value {
      min: number
      max: number
    }

    type R = Record<Keys, Value>
    const record: R  = {
      [Keys.One]:
        {
          min: 1,
          max: 2
        }
    }

  it("check record", async () => {
    messagePact
      .expectsToReceive("record")
      .withContent({
        // What need to write here to check type R ?
      })
  })
github-actions[bot] commented 3 months ago

🤖 Great news! We've labeled this issue as smartbear-supported and created a tracking ticket in PactFlow's Jira (PACT-1915). We'll keep work public and post updates here. Meanwhile, feel free to check out our docs. Thanks for your patience!

JP-Ellis commented 3 months ago

The work required for this should be partially covered by #383. I had to implement that to allow low-level JSON matching rules to be given straight to the FFI, because I found myself rewriting a matching rule parser in Python.

The FFI is the low-level implementation which will take the bare matching rule JSON, and the downstream libraries would likely need to implement a high level abstraction to help build these matching rules in a manner which makes most sense to each language.

mefellows commented 3 months ago

Nice!

and the downstream libraries would likely need to implement a high level abstraction to help build these matching rules in a manner which makes most sense to each language.

Yes, and we should probably update the compatibility suite also if that's not already covered.

JP-Ellis commented 3 months ago

Well, I added this because of the compatibility suite. I found myself implementing a parser for the matching rules to convert them into the other JSON format as described in integrationJson.

This in itself begs the questions as to why we even had these two different formats, though I am sure there's a good reason.

sergewar commented 3 months ago

Hi. I see that issue closed but maybe can you provide the code example how to use this new feature?

// What need to write here to check type R ?

rholshausen commented 3 months ago

This has been implemented in the Rust core, but still needs work to use it in Pact-JS

mefellows commented 3 months ago

Created https://github.com/pact-foundation/pact-js/issues/1203 to track the Pact JS request @sergewar

YOU54F commented 1 month ago

From the original request

Pact JVM supports combining matching rules using the AND logical expression.

Would we also want to support the OR operator here to bring in line with pact-jvm?

https://github.com/pact-foundation/pact-jvm/blob/master/consumer/junit/README.md#combining-matching-rules-with-andor

Matching rules can be combined with AND/OR. There are two methods available on the DSL for this. For example:

DslPart body = new PactDslJsonBody()
  .numberValue("valueA", 100)
  .and("valueB","AB", PM.includesStr("A"), PM.includesStr("B")) // Must match both matching rules
  .or("valueC", null, PM.date(), PM.nullValue()) // will match either a valid date or a null value
rholshausen commented 1 month ago

We want to discourage using OR as it can lead to situations where not all variations are covered in the Pact tests.