https://pact.io logo
Join Slack
Powered by
# libpact_ffi-users
  • t

    Tien Vo

    10/11/2023, 2:03 PM
    This scenario Request with a binary body (negative case) doesn't look right to me.
    Copy code
    Scenario: Request with a binary body (negative case)
        When the mock server is started with interaction 7
        And request 7 is made to the mock server with the following changes:
          | body             |
          | file: spider.jpg |
        Then a 500 error response is returned
        And the mismatches will contain a "body" mismatch with error "Actual body [image/jpeg, 30922 bytes, starting with ffd8ffe000104a46494600010101004800480000ffe100ae4578696600004949] is not equal to the expected body [image/jpeg, 28058 bytes, starting with ffd8ffe000104a46494600010101012c012c0000ffe12db64578696600004949]"
    According to document of pactffi_with_binary_file:
    Will use a mime type matcher to match the body.
    I think the content of the binary file doesn't matter. If we change the content of the binary file, as long as the mime type doesn't change (image/jpeg), the mock server shouldn't consider this as a mismatch . The response code should be 200, not 500.
    r
    m
    +2
    • 5
    • 29
  • t

    Tien Vo

    10/23/2023, 1:30 AM
    I'm trying to match header/query to contain multiple values using ffi call but it doesn't work as I expected.
  • t

    Tien Vo

    10/23/2023, 1:31 AM
    For header, see this thread
    r
    • 2
    • 12
  • t

    Tien Vo

    10/23/2023, 1:31 AM
    For query, see this thread
    r
    • 2
    • 11
  • t

    Tien Vo

    10/26/2023, 2:05 AM
    https://github.com/pact-foundation/pact-reference/blob/master/rust/pact_ffi/IntegrationJson.md Is it true that: • Any matcher can be used with any generator, no restriction? • Any matcher can have any example value, no restriction (as long as the example value can be JSON encoded)?
  • r

    rholshausen

    10/26/2023, 2:36 AM
    Any matcher can be used with any generator, no restriction?
    Technically, yes, but they should compliment each other, otherwise they won't be useful. For instance if you set a regex matcher with
    \d+
    and a DateTime generator, that will not make much sense because the generated values will be different to the regex. However, a regex matcher with
    \d+
    and a RandomInt generator will work well.
  • r

    rholshausen

    10/26/2023, 2:38 AM
    Any matcher can have any example value, no restriction (as long as the example value can be JSON encoded)?
    The example values should represent what the matcher is matching. In the customer facing DSL, this should be validated.
  • t

    Tien Vo

    10/26/2023, 3:45 AM
    Thanks Ron
  • t

    Tien Vo

    10/26/2023, 3:45 AM
    The example values should represent what the matcher is matching. In the customer facing DSL, this should be validated.
    r
    • 2
    • 8
  • t

    Tien Vo

    11/03/2023, 2:30 AM
    Use
    eachValue
    matcher for query parameter. See this thread for more details:
    r
    • 2
    • 9
  • t

    Tien Vo

    11/03/2023, 3:03 AM
    To test generators in compatibility suite, I have to use Integration Json. But there are some difficulties: •
    pact:generator:type
    is only optional,
    pact:matcher:type
    is still required • Set
    pact:matcher:type
    to
    null
    or
    integer
    is the easiest way • If I set
    pact:matcher:type
    to something like
    type
    , I need to also set
    value
    , which prevent
    pact:generator:type
    from working • But I got these errors
    Could not generate a random decimal from null
    • Other generator like
    date
    ,
    time
    ,
    datetime
    or
    boolean
    works fine because they don't validate the
    value
    • Is this change a good idea: https://github.com/pact-foundation/pact-reference/compare/master...tienvx:pact-reference:force-generator-works-regardless-value-type?expand=1
    • 1
    • 2
  • p

    Priyaranjan Mudliar

    03/17/2024, 8:38 PM
    Hi !! I am trying to run a provider verification using ffi lib, but it seems its unable to send the request to (http://localhost:8080/test_weather/generate_weather) verify the message pact : Code snippet:
    Copy code
    struct VerifierHandle *verifierhandle;
        verifierhandle = pactffi_verifier_new_for_application(name, version);
        pactffi_verifier_set_provider_info(verifierhandle, name, scheme, host, port, path);
        pactffi_verifier_add_provider_transport(verifierhandle, protocol, port, path, scheme);
        pactffi_verifier_set_publish_options(verifierhandle, version, NULL, NULL, -1, branch);
        pactffi_verifier_add_directory_source(verifierhandle, file_path);
        int output = pactffi_verifier_execute(verifierhandle);
        pactffi_verifier_shutdown(verifierhandle);
    Here are the debug lvl logs attached
    Copy code
    2024-03-17T20:22:21.013948Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: Path = $    
    2024-03-17T20:22:21.014020Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: Configuring a normal object    
    2024-03-17T20:22:21.014407Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: Path = $.timestamp    
    2024-03-17T20:22:21.014430Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: detected pact:matcher:type, will configure a matcher    
    2024-03-17T20:22:21.014513Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: Path = $.weather    
    2024-03-17T20:22:21.014527Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: Configuring a normal object    
    2024-03-17T20:22:21.014541Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: Path = $.weather.humidity    
    2024-03-17T20:22:21.014553Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: detected pact:matcher:type, will configure a matcher    
    2024-03-17T20:22:21.014575Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: Path = $.weather.temperature    
    2024-03-17T20:22:21.014588Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: detected pact:matcher:type, will configure a matcher    
    2024-03-17T20:22:21.014614Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: Path = $.weather.wind_speed_kmh    
    2024-03-17T20:22:21.014626Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: detected pact:matcher:type, will configure a matcher    
    2024-03-17T20:22:21.020918Z DEBUG ThreadId(01) pact_ffi::mock_server::handles: pact_ffi::mock_server::handles::pactffi_pact_handle_write_file FFI function invoked
    2024-03-17T20:22:21.021017Z DEBUG ThreadId(01) pact_models::pact: Writing new pact file to "./pacts/animal_service-weather_service.json"
    %%% message_pact_SUITE ==> consumer.animal_consume_message: OK
    2024-03-17T20:22:21.149207Z DEBUG ThreadId(01) pact_ffi::verifier: pact_ffi::verifier::pactffi_verifier_new_for_application FFI function invoked
    2024-03-17T20:22:21.149308Z DEBUG ThreadId(01) pact_ffi::verifier: pact_ffi::verifier::pactffi_verifier_set_provider_info FFI function invoked
    2024-03-17T20:22:21.149344Z DEBUG ThreadId(01) pact_ffi::verifier: pact_ffi::verifier::pactffi_verifier_add_provider_transport FFI function invoked
    2024-03-17T20:22:21.149391Z DEBUG ThreadId(01) pact_ffi::verifier: pact_ffi::verifier::pactffi_verifier_set_publish_options FFI function invoked
    2024-03-17T20:22:21.149421Z DEBUG ThreadId(01) pact_ffi::verifier: pact_ffi::verifier::pactffi_verifier_add_directory_source FFI function invoked
    2024-03-17T20:22:21.149453Z DEBUG ThreadId(01) pact_ffi::verifier: pact_ffi::verifier::pactffi_verifier_execute FFI function invoked
    2024-03-17T20:22:21.149474Z DEBUG ThreadId(01) pact_ffi::verifier::handle: Pact source to verify = Dir(./pacts)
    2024-03-17T20:22:21.153359Z DEBUG ThreadId(01) pact_plugin_driver::catalogue_manager: Updated catalogue entries:
    core/content-generator/binary
    core/content-generator/json
    core/content-matcher/json
    core/content-matcher/multipart-form-data
    core/content-matcher/text
    core/content-matcher/xml
    2024-03-17T20:22:21.153423Z DEBUG ThreadId(01) pact_plugin_driver::catalogue_manager: Updated catalogue entries:
    core/matcher/v1-equality
    core/matcher/v2-max-type
    core/matcher/v2-min-type
    core/matcher/v2-minmax-type
    core/matcher/v2-regex
    core/matcher/v2-type
    core/matcher/v3-content-type
    core/matcher/v3-date
    core/matcher/v3-datetime
    core/matcher/v3-decimal-type
    core/matcher/v3-includes
    core/matcher/v3-integer-type
    core/matcher/v3-null
    core/matcher/v3-number-type
    core/matcher/v3-time
    core/matcher/v4-array-contains
    core/matcher/v4-equals-ignore-order
    core/matcher/v4-max-equals-ignore-order
    core/matcher/v4-min-equals-ignore-order
    core/matcher/v4-minmax-equals-ignore-order
    core/matcher/v4-not-empty
    core/matcher/v4-semver
    2024-03-17T20:22:21.153533Z DEBUG ThreadId(01) pact_verifier: Scanning "./pacts"
    2024-03-17T20:22:21.154630Z DEBUG ThreadId(01) verify_interaction{interaction="a weather data message"}: pact_verifier: Executing provider states
    2024-03-17T20:22:21.154649Z  INFO ThreadId(01) verify_interaction{interaction="a weather data message"}: pact_verifier: Running setup provider state change handler 'weather data for animals' for 'a weather data message'
    2024-03-17T20:22:21.154662Z  WARN ThreadId(01) verify_interaction{interaction="a weather data message"}: pact_verifier::callback_executors: State Change ignored as there is no state change URL provided for interaction 
    2024-03-17T20:22:21.154675Z DEBUG ThreadId(01) verify_interaction{interaction="a weather data message"}: pact_verifier: State Change: "ProviderState { name: "weather data for animals", params: {} }" -> Ok({})
    2024-03-17T20:22:21.154689Z  INFO ThreadId(01) verify_interaction{interaction="a weather data message"}: pact_verifier: Running provider verification for 'a weather data message'
    2024-03-17T20:22:21.154696Z DEBUG ThreadId(01) verify_interaction{interaction="a weather data message"}: pact_verifier: Verifying an asynchronous message (single shot)
    2024-03-17T20:22:21.154729Z  INFO ThreadId(01) verify_interaction{interaction="a weather data message"}: pact_verifier::provider_client: Sending request to provider at <http://localhost:8080/test_weather/generate_weather>
    2024-03-17T20:22:21.154737Z DEBUG ThreadId(01) verify_interaction{interaction="a weather data message"}: pact_verifier::provider_client: Provider details = ProviderInfo { name: "weather_service", protocol: "http", host: "localhost", port: Some(8080), path: "/test_weather/generate_weather", transports: [ProviderTransport { transport: "http", port: Some(8080), path: Some("/test_weather/generate_weather"), scheme: None }, ProviderTransport { transport: "message", port: Some(8080), path: Some("/test_weather/generate_weather"), scheme: Some("http") }] }
    2024-03-17T20:22:21.154766Z  INFO ThreadId(01) verify_interaction{interaction="a weather data message"}: pact_verifier::provider_client: Sending request HTTP Request ( method: POST, path: /, query: None, headers: Some({"Content-Type": ["application/json"]}), body: Present(95 bytes, application/json) )
    2024-03-17T20:22:21.154781Z DEBUG ThreadId(01) verify_interaction{interaction="a weather data message"}: pact_verifier::provider_client: body:
    {"description":"a weather data message","providerStates":[{"name":"weather data for animals"}]}
    2024-03-17T20:22:21.154895Z DEBUG ThreadId(01) verify_interaction{interaction="a weather data message"}: reqwest::connect: starting new connection: <http://localhost:8080/>    
    2024-03-17T20:22:21.155114Z DEBUG tokio-runtime-worker hyper::client::connect::dns: resolving host="localhost"
    2024-03-17T20:22:21.155328Z DEBUG ThreadId(01) verify_interaction{interaction="a weather data message"}: hyper::client::connect::http: connecting to 127.0.0.1:8080
    2024-03-17T20:22:21.155535Z DEBUG ThreadId(01) verify_interaction{interaction="a weather data message"}: hyper::client::connect::http: connected to 127.0.0.1:8080
    2024-03-17T20:22:21.155860Z DEBUG tokio-runtime-worker hyper::proto::h1::io: flushed 262 bytes
    2024-03-17T20:22:26.156256Z  INFO ThreadId(01) pact_verifier: Not publishing results as publishing for pact source Dir("./pacts") is not possible or not yet implemented
    2024-03-17T20:22:26.156350Z DEBUG ThreadId(01) pact_matching::metrics: 'PACT_DO_NOT_TRACK' environment variable is set, will not send metrics
    
    Verifying a pact between animal_service and weather_service
    
      a weather data message (0s loading, 5s 2ms verification)
         Given weather data for animals
          Request Failed - error sending request for url (<http://localhost:8080/test_weather/generate_weather>): operation timed out
    
    
    Failures:
    
    1) Verifying a pact between animal_service and weather_service Given weather data for animals - a weather data message - error sending request for url (<http://localhost:8080/test_weather/generate_weather>): operation timed out
    
    
    There were 1 pact failures
    Also i am able to connect to this particular url via postman, but not via pact ffi. Any clues what could be wrong here?
    r
    m
    • 3
    • 16
  • p

    Priyaranjan Mudliar

    04/11/2024, 3:06 PM
    Hi I am getting segmentation fault when i am executing
    pactffi_verifier_broker_source_with_selectors
    Copy code
    2024-04-11T15:03:22.613421Z DEBUG ThreadId(10) pact_ffi::verifier: pact_ffi::verifier::pactffi_verifier_new_for_application FFI function invoked
    2024-04-11T15:03:22.613463Z DEBUG ThreadId(10) pact_ffi::verifier: pact_ffi::verifier::pactffi_verifier_set_provider_info FFI function invoked
    2024-04-11T15:03:22.613480Z DEBUG ThreadId(10) pact_ffi::verifier: pact_ffi::verifier::pactffi_verifier_add_provider_transport FFI function invoked
    2024-04-11T15:03:22.613495Z DEBUG ThreadId(10) pact_ffi::verifier: pact_ffi::verifier::pactffi_verifier_set_provider_state FFI function invoked
    2024-04-11T15:03:22.613532Z DEBUG ThreadId(10) pact_ffi::verifier: pact_ffi::verifier::pactffi_verifier_set_verification_options FFI function invoked
    2024-04-11T15:03:22.613546Z DEBUG ThreadId(10) pact_ffi::verifier: pact_ffi::verifier::pactffi_verifier_set_publish_options FFI function invoked
    broker_url Variable: <http://localhost:9292/>
    broker_username Variable: pact_workshop
    broker_password Variable: pact_workshop
    enable_pending Variable: 1
    branch Variable: develop
    consumer_version_selectors Variable: {}
    consumer_version_selectors_len Variable: 0
    2024-04-11T15:03:22.613621Z DEBUG ThreadId(10) pact_ffi::verifier: pact_ffi::verifier::pactffi_verifier_broker_source_with_selectors FFI function invoked
    2024-04-11T15:03:22.613640Z DEBUG ThreadId(10) pact_ffi::verifier: pact_ffi::verifier::pactffi_verifier_execute FFI function invoked
    2024-04-11T15:03:22.613651Z DEBUG ThreadId(10) pact_ffi::verifier::handle: Pact source to verify = PactBrokerWithDynamicConfiguration(<http://localhost:9292/>, provider_name='animal_service', enable_pending=true, include_wip_since=None, provider_tags=[], provider_branch=Some("develop"), consumer_version_selectors='[], auth=User(pact_workshop, pact*********)')
    2024-04-11T15:03:22.749605Z  INFO ThreadId(10) pact_verifier::pact_broker: Fetching path '/' from pact broker
    
    make: *** [Makefile:13: test] Segmentation fault (core dumped)
    Any pointers as to what might be causing this or how should i debug this?
    j
    r
    • 3
    • 11
  • t

    Tien Vo

    05/03/2024, 1:20 AM
    I would like to discuss about this change https://github.com/pact-foundation/pact-reference/pull/405/files#diff-4ebc1aebf7776ab6040dc317cf34fd5ff89ac78e80c07d13de1bce2ce898650fR187-R217 Should we change the format into something like this:
    Copy code
    {
      "results": {
        "pact:matcher:type": "matchAll",
        "rules": [
          {
            "pact:matcher:type": "each-key",
            "value": "AUK-155332",
            "rules": [
              {
                "pact:matcher:type": "regex",
                "regex": "\\w{3}-\\d+"
              }
            ]
          },
          {
            "pact:matcher:type": "each-value",
            "rules": [
              {
                "pact:matcher:type": "type"
              }
            ]
          }
        ],
        "value": {
          "AUK-155332": {
            "title": "...",
            "description": "...",
            "link": "http://....",
            "relatesTo": [
              "BAF-88654"
            ]
          }
        }
      }
    }
    r
    • 2
    • 2
  • m

    Matt (pactflow.io / pact-js / pact-go)

    05/20/2024, 10:14 AM
    We don't have support for this in the FFI yet do we? https://pact.canny.io/feature-requests/p/add-metadata-injection-support-to-pact-js-verifier
    p
    • 2
    • 3
  • s

    Siim Mardus

    07/10/2024, 6:50 AM
    Hi! We are using pact_erlang for provider verification. I am going through the steps described as Pact nirvana to take us from local flow to full integration with our CI/CD workflows. I wish to modify the provider tests to have two options (as described here): 1. Run tests in CI/CD and publish verification results 2. Run tests locally agains latest pacts and do not publish the results I am trying to figure out the best option for doing that. I dug through the pact_ffi library but didn't see any option I can provide to easily use some flag to say "_Don't publish the results_". Any suggestions?
    ✅ 1
    r
    • 2
    • 8
  • s

    Siim Mardus

    07/10/2024, 10:52 AM
    Hi again! 👋 I am trying to implement consumer version selectors. I am struggling to understand either why is it not working for me or how is it supposed to work 😅 For testing purposes, I did the following:
    Copy code
    char myJson[256];
        strcpy(myJson, "[{");
        strcat(myJson, "\"branch\": \"foo-bar\"");
        strcat(myJson, "}]");
        const char *mockSelectors[] = {myJson};
    
        printf("mockSelectors is %s\n", mockSelectors[0]);
        // prints out mockSelectors is [{"branch": "foo-bar"}]
    
        pactffi_verifier_broker_source_with_selectors(..., mockSelectors, 1, ...)
    ...
    As I understand, this is supposed to verify against consumers with branch
    foo-bar
    ? When I run the verifier, it instead uses the latest version.
    Copy code
    The pact at ... is being verified because the pact content belongs to the consumer version matching the following criterion:
        * latest version of <consumer> that has a pact with <provider> (<absolute-version of consumer>)
    Any help would be greatly appreciated! 🙇
    ✅ 1
    m
    • 2
    • 53
  • t

    Tien Vo

    08/30/2024, 8:46 AM
    Hi, Anyone tested Pact with
    application/x-www-form-urlencoded
    ? Does it support matchers? I try to test it here https://github.com/pact-foundation/pact-php/pull/627, but from the log, look like it doesn't support matchers:
    Copy code
    2024-08-30T08:38:28.146149Z DEBUG tokio-runtime-worker pact_mock_server::hyper_server: Request did not match: Request did not match - HTTP Request ( method: POST, path: /users, query: None, headers: Some({"Accept": ["application/json"], "Content-Type": ["application/x-www-form-urlencoded"]}), body: Present(287 bytes) )    0) $.^_-]{8,}$","value":"user@password111"}} -> Expected form post parameter '^_-]{8,}$","value":"user@password111"}}' but was missing    1) $.email -> Unexpected form post parameter 'email' received    2) $.password -> Unexpected form post parameter 'password' received    3) $.{"fullname":{"pact:matcher:type":"type","value":"User name"},"email":{"pact:matcher:type":"regex","regex":"^[a-zA-Z0-9._% -] @[a-zA-Z0-9.-] .[a-zA-Z]{2,}$","value":"user@email.test"},"password":{"pact:matcher:type":"regex","regex":"^[\\w\\d@$!%*#? -> Expected form post parameter '{"fullname":{"pact:matcher:type":"type","value":"User name"},"email":{"pact:matcher:type":"regex","regex":"^[a-zA-Z0-9._% -] @[a-zA-Z0-9.-] .[a-zA-Z]{2,}$","value":"user@email.test"},"password":{"pact:matcher:type":"regex","regex":"^[\\w\\d@$!%*#?' but was missing    4) $.fullname -> Unexpected form post parameter 'fullname' received
    m
    • 2
    • 2
  • v

    Val Kolovos

    10/02/2024, 2:02 PM
    I'm trying to set multiple values in given namespace for pact metadata but always only get the last value I set. I'm using
    pact-python
    , but it passes its arguments along to
    lib.pactffi_with_pact_metadata(
    . My example is this:
    Copy code
    pact.with_metadata('namespace', {'var_1': 'value_1', 'var_2': 'value_2'})
    which breaks down into multiple calls as listed above, but the resulting pact file only contains:
    Copy code
    "metadata": {
        "namespace": {
          "var_2": "value_2"
        },
        ...
    y
    • 2
    • 19
  • t

    Tien Vo

    11/14/2024, 8:27 AM
    Does anyone get this error before?
    Copy code
    pact.so' (/lib/x86_64-linux-gnu/libc.so: invalid ELF header)
    Do you know how to fix it? Original issue https://github.com/pact-foundation/pact-php/issues/692
    r
    • 2
    • 3
  • m

    Marko (IttyBittyApps / pact-swift)

    01/27/2025, 10:38 PM
    Are there any matcher limitations for query parameters? I'm setting up a test for PactSwift implementation verifying interactions with query parameters where I'm sending (as per docs for the FFI method):
    Copy code
    "{\"value\":\"12:12\",\"pact:matcher:type\":\"time\",\"format\":\"HH:mm\"}"
    Into
    pactffi_with_query_parameter_v2
    When sent
    GET  /interaction?value=10:12
    pactffi
    is complaining with:
    Copy code
    {
      "Request-Mismatch": {
        "method": "GET",
        "path": "/interaction",
        "query": {
          "item": ["10:12"]
        },
        "headers": {
          "host": ["127.0.0.1:5772"],
          "accept-language": ["en-AU", "en;q=0.9"],
          "connection": ["keep-alive"],
          "user-agent": ["xctest/23600 CFNetwork/1568.300.101 Darwin/24.2.0"],
          "accept-encoding": ["gzip", "deflate"],
          "accept": ["*/*"]},
          "body": "Empty",
          "matching_rules": { "rules": {} },    # ?????
          "generators": { "categories": {} }
        }
    }
    because
    matching_rules
    is missing the matcher value I sent through to FFI. Both
    .v3
    and
    .v4
    Coming back to this after a very long time time away, so I'm a bit rusty (no pun intended).
    r
    g
    • 3
    • 16
  • m

    Marko (IttyBittyApps / pact-swift)

    01/28/2025, 3:25 AM
    ok, I doubt it's
    pactffi
    issue now with matchers, but... Pact setup:
    Copy code
    RefCell { 
      value: PactHandleInner { 
        pact: V4Pact { 
          consumer: Consumer { name: "Consumer" }, 
          provider: Provider { name: "Provider" }, 
          interactions: [
            SynchronousHttp { 
              id: None, 
              key: None, 
              description: "an interaction with query item matcher 'includes'", 
              provider_states: [], 
              request: HttpRequest { 
                method: "GET", 
                path: "/interaction", 
                query: Some({"item": [Some("sub")]}), 
                headers: None, 
                body: Missing, 
                matching_rules: MatchingRules { 
                  rules: {
                    PATH: MatchingRuleCategory { name: PATH, rules: {} }, 
                    QUERY: MatchingRuleCategory { name: QUERY, rules: {
                      DocPath { 
                        path_tokens: [Root, Field("item")], 
                        expr: "$.item" 
                      }: 
                      RuleList { 
                        rules: [Include("sub")], 
                        rule_logic: And, 
                        cascaded: false 
                      }
                    } 
                  }
                } 
              }, 
              generators: Generators { categories: {} } }, 
              response: HttpResponse { 
                status: 200, 
                headers: None, 
                body: Missing, 
                matching_rules: MatchingRules { rules: {} }, 
                generators: Generators { categories: {} } }, 
                comments: {}, 
                pending: false, 
                plugin_config: {}, 
                interaction_markup: InteractionMarkup { markup: "", markup_type: "" }, 
                transport: None 
              }
            ], 
          metadata: {
            "namespace1": Object {"name1": String("value1")}, 
            "namespace2": Object {"name2": String("value2")}, 
            "pactRust": Object {"ffi": String("0.4.25")}
          }, 
          plugin_data: [] 
        }, 
        mock_server_started: true, 
        specification_version: V4 
      } 
    }
    Simple GET request
    Copy code
    ----------------------------------------------------------------------------------------
           method: GET
           path: /interaction
           query: Some({"item": [Some("substring")]})
           headers: Some({"accept-language": ["en-AU", "en;q=0.9"], "user-agent": ["xctest/23600 CFNetwork/1568.300.101 Darwin/24.2.0"], "host": ["127.0.0.1:4658"], "accept-encoding": ["gzip", "deflate"], "connection": ["keep-alive"], "accept": ["*/*"]})
           body: Empty
          ----------------------------------------------------------------------------------------
    Failing to verify
    Copy code
    QueryMismatch: Unable to match ["sub"] using Include("sub")
      Expected: ["sub"]
      Actual: ["substring"]
      Parameter: $.item])"
    r
    • 2
    • 10
  • m

    Marko (IttyBittyApps / pact-swift)

    01/28/2025, 3:26 AM
    Backstory, I've had a major refactor on the back burner for almost 2 years now and some of the tests written already set various matchers for query parameters. Like
    Matcher.bool(true)
    which doesn't make sense in URL query parameters, but hey, I'm fixing it now.
  • m

    Marko (IttyBittyApps / pact-swift)

    01/28/2025, 3:27 AM
    But am getting a bit frustrated with these unable to match includes "sub" in "substring" 😐
  • m

    Marko (IttyBittyApps / pact-swift)

    01/28/2025, 3:27 AM
    any ideas what I am doing wrong are much appreciated
  • m

    Marko (IttyBittyApps / pact-swift)

    01/28/2025, 3:49 AM
    have yet another one, sorry 🤷, this time a false positive:
    Copy code
    RefCell { 
      value: PactHandleInner { 
        pact: V4Pact { 
          consumer: Consumer { name: "Consumer" }, 
          provider: Provider { name: "Provider" }, 
          interactions: [ 
            SynchronousHttp { 
              id: None, 
              key: None,
              description: "a request for a known path with a body matching number", 
              provider_states: [], 
              request: HttpRequest { 
                method: "POST", 
                path: "/jsonbody", 
                query: None, 
                headers: Some({"Content-Type": ["application/json"]}), 
                
                body: Present(
                 b"{\"key1\":123.1,\"key2\":321}", 
                 Some(ContentType { main_type: "application", sub_type: "json", attributes: {}, suffix: None }), None
               ),
                
                matching_rules: MatchingRules { rules: {
                  PATH: MatchingRuleCategory { name: PATH, rules: {} }, 
                  BODY: MatchingRuleCategory { name: BODY, rules: {
                    DocPath { 
                      path_tokens: [Root, Field("key2")], expr: "$.key2" 
                    }: RuleList { 
                      rules: [Number], 
                      rule_logic: And,
                      cascaded: false 
                    }, 
                    DocPath { 
                      path_tokens: [Root, Field("key1")], expr: "$.key1" 
                    }: RuleList { 
                      rules: [Number], 
                      rule_logic: And, 
                      cascaded: false 
                    }, 
                    DocPath { path_tokens: [Root], expr: "$" }: RuleList { rules: [Type], rule_logic: And, cascaded: false }} }} 
              }, 
              generators: Generators { categories: {} } }, 
              response: HttpResponse { status: 200, headers: None, body: Missing, matching_rules: MatchingRules { rules: {} }, generators: Generators { categories: {} } }, comments: {}, pending: false, plugin_config: {}, interaction_markup: InteractionMarkup { markup: "", markup_type: "" }, transport: None }], 
    
    metadata: {
      "namespace1": Object {"name1": String("value1")},  
      "namespace2": Object {"name2": String("value2")}, 
      "pactRust": Object {"ffi": String("0.4.25")}}, 
      plugin_data: [] 
    }, 
    mock_server_started: true, 
    specification_version: V4 
    } 
    }
    Request sending string values instead of expected numbers: POST /jsonbody body:
    {"key1": "321.1", "key2": "456"}
    Copy code
    2025-01-28T03:42:33.886570Z INFO tokio-runtime-worker pact_mock_server::hyper_server: Request matched, sending response
    2025-01-28T03:42:33.886572Z DEBUG tokio-runtime-worker pact_mock_server::hyper_server: 
         ----------------------------------------------------------------------------------------
          status: 200
          headers: None
          body: Missing
         ----------------------------------------------------------------------------------------
    Should have failed, right? I mean, matcher said "numeric" value, I sent "string". Something ain't right here.
  • m

    Marko (IttyBittyApps / pact-swift)

    01/28/2025, 4:26 AM
    Raised a couple more. tbh, hope I'm using it wrong
  • m

    Marko (IttyBittyApps / pact-swift)

    01/28/2025, 5:33 AM
    feel free to ping me here, or in comments, for more info
  • r

    rholshausen

    01/28/2025, 9:56 PM
    I can look into these today
  • f

    Feisal Ahmad

    04/01/2025, 4:22 PM
    We’re working on using matchers using the
    pactffi_matches_json_value
    function, and are seeing some unexpected behavior for some more advanced rules where the check passes even though it shouldn’t… For example, with an
    arrayContains
    matching rule, no error is returned even though an array with one element that doesn’t satisfy the matching rules is passed to it. Here’s the line in the pactffi log for the check:
    Copy code
    2025-03-31T15:16:12.632536Z DEBUG ThreadId(01) pact_matching::json: JSON -> JSON: Comparing '[{"baz":42,"foo":"bar"}]' to '["bla"]' using ArrayContains([(0, MatchingRuleCategory { name: BODY, rules: {DocPath { path_tokens: [Root, Field("baz")], expr: "$.baz" }: RuleList { rules: [Type], rule_logic: And, cascaded: false }} }, {})]) -> Ok(())
    We’re using pactffi release 0.4.26 btw, am I missing something here? Thread in Slack Conversation
    r
    • 2
    • 4