Skip to content
This repository was archived by the owner on May 20, 2020. It is now read-only.

Source test suite should use something more powerful than JSON pointer #98

Closed
euclio opened this issue Aug 1, 2017 · 8 comments
Closed

Comments

@euclio
Copy link
Contributor

euclio commented Aug 1, 2017

I wrote this originally as a proof of concept. What we really need is a way to query the JSON. For example, the current rustdoc uses XPath, which is a very powerful query language. The current tests are fragile because every directive depends on the exact order of the JSON. If there's more than one def kind or multiple defs in the same file, things can get messy fast.

I'm not too familiar with this domain, but there are solutions like JPATH and json-query. I'm even less familiar with the options available to Rust.

We should address this before we get too many tests :)

@steveklabnik
Copy link
Owner

Marking this as a quest issue; I don't know the best solution either!

@euclio
Copy link
Contributor Author

euclio commented Aug 4, 2017

Some options:

  • JSONpath
  • JMESpath (seems to have a well-tested crate!)

@steveklabnik
Copy link
Owner

Marking this as hard since there's a lot of work to do; first to come up with the tech we should use, second to implement it.

@euclio
Copy link
Contributor Author

euclio commented Aug 9, 2017

I have a proof of concept using JMESPath instead of JSON pointer. Here's what I'm thinking design-wise:

The @has directive takes one or two arguments. The first argument is a JMESPath, and the second argument is a JSON data type. If the two arguments evaluate to the same value, the test passes.

This means that a simple check could be

// @has included[0].type '"module"'

(I'm not super happy about having to duplicate the quotes, but I think it's necessary to resolve ambiguity)

If the second argument is not supplied, it's assumed to be true. To check that a string contains another:

// @has 'data.attributes.docs | contains(@, "crate")'
// or
// @has 'contains(data.attributes.docs, "crate")'

You can also provide a JSON object on the right side. This can be used to match more complex queries.

// @has data.relationships.modules.data[0] '{ "type": "module", "id": "modules::module" }'

While we no longer would have the ability to Regex match on the right side, JMESPath is extremely powerful, and I believe that contains would serve most of the use case. If it became a problem we could customize the JMESPath runtime with a regex_match function.
Thoughts, @steveklabnik?

@steveklabnik
Copy link
Owner

My thoughts are mostly, "I've never heard of JMESPath before and it looks interesting, but that kinda gives me pause."

Hm.

@euclio
Copy link
Contributor Author

euclio commented Aug 9, 2017 via email

@euclio
Copy link
Contributor Author

euclio commented Aug 27, 2017

We could consider using jq as a library. That's a bit more tried and true, but we'd be introducing a C dependency.

steveklabnik added a commit that referenced this issue Oct 18, 2017
related to #98, our current
tests mean that some stuff has really long lines
@euclio
Copy link
Contributor Author

euclio commented Oct 20, 2017

Not to sound like a broken record, but I really think that JMESPath is the right choice here.

  • Well tested
  • Maintained
  • Simple syntax for simple cases, but very powerful for more advanced cases

If I get the go-ahead, I'll rewrite that PR.

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

Successfully merging a pull request may close this issue.

2 participants