Hi, I have a question regarding use of `eachKeyLik...
# pact-js
z
Hi, I have a question regarding use of
eachKeyLike
. Is it possible to use
eachKeyLike
for nested (up-to 3 levels) dynamic keys? It seems that it only works on one level but in my use case, we can have nested dynamic keys and I just want to ensure the shape of the request/response payload. Any help would be appreciated. An example payload is as follows:
Copy code
{
  "john-doe1": {
    "brown-fox": {
      "jumps": "over",
      "the": "lazy dog"
    }
  },
  "john-doe2": {
    "brown-fox2": {
      "jumps": "over",
      "the": "lazy dog"
    }
  }
}
And the matcher which I am trying to use is as follows (roughly). It skips checking the first level of the keys (as expected) but then it compares the other keys literally:
Copy code
Matchers.eachKeyLike("some string", Matchers.eachKeyLike("some-string", Matchers.eachKeyLike("some-string", Matchers.string())))
u
Unfortunately, eachKeyLike was designed to only work at the current level, and not propagate to children.
t
This isn't asking for propagation, though - if the contract is
eachKeyLike(<key definition>, <value definition>)
, wouldn't we expect nested calls to match the example given here?
the docs say:
eachKeyLike(key: string, template: any)
Object where the keys itself is ignored, but the values must match a particular shape. Variants may be objects containing matching rules
So, wouldn't we expect the example above to work?
u
Matchers for nested calls are enabled via propagation.
t
Hmm ok. That feels like an implementation detail that users shouldn't need to know - but either way, the current documentation suggests that this case should be possible. I'm not sure what the correct update to the docs would be
I would expect the nested call to only be "at the current level" as in at that level of nesting
Like, for arbitrary keys where the values are typed arrays, I'd expect it to be written
Matchers.eachKeyLike("exampleKey", Matchers.eachLike(exampleArrayEntry))
u
Coming back to the original question, if it is nested, how do you know when to stop? If the rule is eachKeyLike
\w+\-\w+
, then
"jumps"
and
"the"
are invalid keys.
How do you know to only apply the rule to the first two levels and not the third?
t
Because that's all that is specified in the example:
Copy code
Matchers.eachKeyLike( // top level object has keys that are
     // any string, for example
   "some string",
    // and values that are
   Matchers.eachKeyLike( // objects with keys that are
       // any string, for example:
      "some-string", 
      // and values that are:
      Matchers.eachKeyLike( // objects with keys that are:
           // any string, for example
           "some-string", 
           // and values that are 
            Matchers.string() // also any string
)))
My understanding - from the docs - is that it's not possible to specify rules on what the keys are
u
Ah! Ok, that might be the DSL is just not setting up the matchers correctly, the each key matcher should work if it is specified at each level.
t
Copy code
export const eachKeyLike = <T extends AnyTemplate>(
  keyTemplate: string,
  template: T
): Matcher<AnyTemplate> => ({
  'pact:matcher:type': 'values',
  value: {
    [keyTemplate]: template,
  },
});
u
Yeah, that is not even setting up the eachKey matcher, only the eachValue one which ignores the keys
t
Yes, that's what the documentation says
This is expected to match the values only
What @Zebi is saying is that it doesn't do that beyond the first level, when it should.
I can't find any documentation on what the format is supposed to be for the object
it's not in here, but I suppose this is actually a different format for talking to the FFI?
according to V4, https://github.com/pact-foundation/pact-specification/tree/version-4 there's
eachKey
and
eachValue
, but those were introduced later than V3's
eachKeyLike
, which I think is correctly the values matcher? I'm a bit confused
u
I haven't had a chance to document that format yet. It is the intermediate format that gets translated into the actual Pact format via the FFI call
So, yes, V3's
eachKeyLike
only works on values, and it should be able to apply to multiple levels, however, I imagine the matcher paths are not being setup correctly. It will need some time to investigate what is going on.
👍 2
t
Got it. Should we file an issue somewhere?
u
It's more than likely an FFI issue, lets start there. It may also be Pact-JS DSL issue, but less likely
👍 2
t
u
Thank you!
t
🤣 2
z
Thanks @Timothy Jones for being so active. I just woke-up and it is so good to see such level of support blob clap
🙌 2
t
You're welcome!
m
🌮 for @Timothy Jones because 💯