Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recursive matching rules #74

Open
jcasado94 opened this issue Jul 16, 2020 · 5 comments
Open

Recursive matching rules #74

jcasado94 opened this issue Jul 16, 2020 · 5 comments

Comments

@jcasado94
Copy link

jcasado94 commented Jul 16, 2020

Given the current specification, I don't see a way to deal with self-contained matching rules -- i.e. matching rules for an object which contains itself as an attribute --, where the depth of the recursion is unknown.

For instance,

[
  {
    "id": "1",
    "elements": [
      {
        "id": "1.1"
      }
    ]
  },
  {
    "id": "2",
    "elements": [
      {
        "id": "2.1",
        "elements": [
          {
            "id": "2.1.1"
          },
          {
            "id": "2.1.2"
          },
        ]
      }
    ]
  }
]

A pseudo-definition for such data structure,

element: { id: string, elements: []element }

This could be solved by enabling nth-level path expressions, so one could specify the matching rules for any "elements" attribute (1). Another solution could be implementing named matching rules and being able to reference them, so that the first-level "elements" would just reference back to a general named matching rule (2).

(1)

"matchingRules": {
	"$.body": {
		"match": "type",
		"min": "1"
	},
	"$.body[*].id": {
		"match": "type"
	},
	"*.elements": { // matches any "elements" attribute in the tree
		"match": "type",
		"min": "1"
	},
	"*.elements[*].id": {
		"match": "type"
	}
}

(2)

"matchingRules": {
	"rules": {
		"elements": {
			"$": {
				"match": "type",
				"min": "1"
			},
			"$[*].id": {
				"match": "type"
			},
			"$[*].elements": {
				"match": "rules.elements" // reference to named rule
			}
		}
	},
	"$.body": "rules.elements" // reference to named rule
}

The problem with (2) is it generates an infinite number of possible rules, so I'm not sure of it's compatibility with your rule-weighting algorithm.

I am not sure if this could be pactified via regexp capturing groups, but in any case, I don't think that's a sustainable option.

@uglyog
Copy link
Member

uglyog commented Jul 25, 2020

One way to do it would be to use something like the // operator from X-Path. I.e.

{
  "//elements.id": {
    "match": "type"
  }
}

This might be something to address with the V4 RFC

@uglyog uglyog mentioned this issue Jul 25, 2020
@uglyog uglyog added the v4 label Jul 25, 2020
@jcasado94
Copy link
Author

Any Idea how would you weigh such matcher?

@uglyog
Copy link
Member

uglyog commented Aug 8, 2020

It would be weighted on the number of elements that match

@uglyog
Copy link
Member

uglyog commented May 27, 2021

This may be difficult to implement, because the consumer DSLs build up the structure as they go. So while we can define matching rules that can be applied to a subset of the document, I am unsure how the DSLs can be built to accommodate this. Having a DSL that has similar to eachAndAnyChildLike or eachPatternLike, it will only be able to construct the first level.

Pact has to deal with both matching a document as well as generating one.

@uglyog uglyog removed the v4 label May 27, 2021
@uglyog
Copy link
Member

uglyog commented May 27, 2021

I'm removing this from the V4 spec for now, because it needs more thinking.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants