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

refactor: overhaul body and query matching #1632

Merged
merged 3 commits into from Jul 28, 2019

Conversation

mastermatt
Copy link
Member

@mastermatt mastermatt commented Jul 18, 2019

Drop deep-equal and qs dependencies.

Replace qs.parse with querystring.parse from the std lib.
The main difference between the two being that qs "unpacks" nested
objects when the search keys use JSON path notation eg "foo[bar][0]".
This has no affect on URL encoded form bodies during matching because
we manually convert the notation to nested objects for comparison now,
which means users can now provide expectations in either form.
Similarly, when matching search params using a provided object, there
is no net effect. The only breaking change is when a user provides a
callback function to .query().

Replace deep-equal with a custom utility function in common.js.
Doing so not only dropped a dependency, it also achieved a more generic
utility for our use case with less code.

Interceptor matching had some refactoring:

  • Query matching was moved to its own method in an effort to isolate concerns.
  • Matching the request method was moved to the top of the match method.
  • Debugging statements were updated as a baby step towards having more insight into why a match was missed.

Fixes #507
Fixes #1552

BREAKING CHANGE: The only argument passed to the Interceptor.query
callback now receives the output from querystring.parse instead of
qs.parse. This means that instead of nested objects the argument will
be a flat object.

Also don't bother calling `transformRequestBodyFunction` or `matchBody`
if there is no request body on the Interceptor.
Drop `deep-equal` and `qs` dependency.

Replace `qs.parse` with `querystring.parse` from the std lib.
The main difference between the two being that `qs` "unpacks" nested
objects when the search keys use JSON path notation eg "foo[bar][0]".
This has no affect on URL encoded form bodies during matching because
we manually convert the notation to nested objects for comparison now,
which means users can now provide expectations in either form.
Similarly, when matching search params using a provided object, there
is no net affect. The only breaking change is when a user provides a
callback function to `.query()`.

Replace `deep-equal` with a custom utility function in common.js.
Doing so not only dropped a dependency, it also achieved a more generic
utility for our usec ase with less code.

Interceptor matching had some refactoring:
- Query matching was moved to its own method in an effort to isolate concerns.
- Matching the request method was moved to the top of the match method.
- Debugging statements were updated as a baby step towards having more insight into why a match was missed.

Fixes nock#507
Fixes nock#1552

BREAKING CHANGE: The only argument passed to the Interceptor.query
callback now receives the output from querystring.parse instead of
qs.parse. This means that instead of nested objects the argument will
be a flat object.
@@ -412,3 +412,35 @@ test('query(true) will match when the path has no query', t => {
t.end()
})
})

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two tests are the regression tests for #1552

Copy link
Member

@gr2m gr2m left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great 👍

@paulmelnikow
Copy link
Member

I'd like to dig into this a little bit, mostly in thinking clearly about exactly what's changed.

I'm fine with the breaking change to the query() callback, though we should add a note to the API documentation (probably documenting both the 10.x and 11.x behaviors).

@mastermatt
Copy link
Member Author

@paulmelnikow sounds good. I'm going to hold off on the doc updates until you're ok with the change themselves.

Copy link
Member

@paulmelnikow paulmelnikow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Thanks for giving me the time to read this!

I want to add that I'm in two minds about whether we should support this behavior. It is so common in frameworks that it is a kind of de facto standard, however since it's not really a standard, various systems, including backends written in other languages, may implement it subtly differently. In the future I wonder if we could disable the nested interpretation by default, and enable it with an option passed to nock().

Since we currently support it, I'm fine continuing to support it with this new implementation, and appreciate the cleanup. Just something to consider for the future.

@mastermatt mastermatt merged commit 35221ce into nock:beta Jul 28, 2019
@mastermatt mastermatt deleted the refactor-body-query-matching branch July 28, 2019 17:14
@nockbot
Copy link
Collaborator

nockbot commented Jul 28, 2019

🎉 This PR is included in version 11.0.0-beta.30 🎉

The release is available on:

Your semantic-release bot 📦🚀

mastermatt added a commit to mastermatt/nock that referenced this pull request Aug 1, 2019
The `qs` dependency was removed, however, recorder.js retained usage
of it. Replacing it with `querystring` from the std lib is sufficient.

Introduced: nock#1632
Fixes: nock#1651
mastermatt added a commit that referenced this pull request Aug 6, 2019
The `qs` dependency was removed, however, recorder.js retained usage
of it. Replacing it with `querystring` from the std lib is sufficient.

Introduced: #1632
Fixes: #1651
@nockbot
Copy link
Collaborator

nockbot commented Aug 12, 2019

🎉 This PR is included in version 11.0.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

gr2m pushed a commit that referenced this pull request Sep 4, 2019
* refactor(match_body): options obj as arg instead of context

Also don't bother calling `transformRequestBodyFunction` or `matchBody`
if there is no request body on the Interceptor.

* perf: prefer regexp.test over match when applicable

* refactor: overhaul body and query matching

Drop `deep-equal` and `qs` dependency.

Replace `qs.parse` with `querystring.parse` from the std lib.
The main difference between the two being that `qs` "unpacks" nested
objects when the search keys use JSON path notation eg "foo[bar][0]".
This has no affect on URL encoded form bodies during matching because
we manually convert the notation to nested objects for comparison now,
which means users can now provide expectations in either form.
Similarly, when matching search params using a provided object, there
is no net affect. The only breaking change is when a user provides a
callback function to `.query()`.

Replace `deep-equal` with a custom utility function in common.js.
Doing so not only dropped a dependency, it also achieved a more generic
utility for our usec ase with less code.

Interceptor matching had some refactoring:
- Query matching was moved to its own method in an effort to isolate concerns.
- Matching the request method was moved to the top of the match method.
- Debugging statements were updated as a baby step towards having more insight into why a match was missed.

Fixes #507
Fixes #1552

BREAKING CHANGE: The only argument passed to the Interceptor.query
callback now receives the output from querystring.parse instead of
qs.parse. This means that instead of nested objects the argument will
be a flat object.
gr2m pushed a commit that referenced this pull request Sep 4, 2019
The `qs` dependency was removed, however, recorder.js retained usage
of it. Replacing it with `querystring` from the std lib is sufficient.

Introduced: #1632
Fixes: #1651
gr2m pushed a commit that referenced this pull request Sep 4, 2019
* refactor(match_body): options obj as arg instead of context

Also don't bother calling `transformRequestBodyFunction` or `matchBody`
if there is no request body on the Interceptor.

* perf: prefer regexp.test over match when applicable

* refactor: overhaul body and query matching

Drop `deep-equal` and `qs` dependency.

Replace `qs.parse` with `querystring.parse` from the std lib.
The main difference between the two being that `qs` "unpacks" nested
objects when the search keys use JSON path notation eg "foo[bar][0]".
This has no affect on URL encoded form bodies during matching because
we manually convert the notation to nested objects for comparison now,
which means users can now provide expectations in either form.
Similarly, when matching search params using a provided object, there
is no net affect. The only breaking change is when a user provides a
callback function to `.query()`.

Replace `deep-equal` with a custom utility function in common.js.
Doing so not only dropped a dependency, it also achieved a more generic
utility for our usec ase with less code.

Interceptor matching had some refactoring:
- Query matching was moved to its own method in an effort to isolate concerns.
- Matching the request method was moved to the top of the match method.
- Debugging statements were updated as a baby step towards having more insight into why a match was missed.

Fixes #507
Fixes #1552

BREAKING CHANGE: The only argument passed to the Interceptor.query
callback now receives the output from querystring.parse instead of
qs.parse. This means that instead of nested objects the argument will
be a flat object.
gr2m pushed a commit that referenced this pull request Sep 4, 2019
The `qs` dependency was removed, however, recorder.js retained usage
of it. Replacing it with `querystring` from the std lib is sufficient.

Introduced: #1632
Fixes: #1651
gr2m pushed a commit that referenced this pull request Sep 5, 2019
* refactor(match_body): options obj as arg instead of context

Also don't bother calling `transformRequestBodyFunction` or `matchBody`
if there is no request body on the Interceptor.

* perf: prefer regexp.test over match when applicable

* refactor: overhaul body and query matching

Drop `deep-equal` and `qs` dependency.

Replace `qs.parse` with `querystring.parse` from the std lib.
The main difference between the two being that `qs` "unpacks" nested
objects when the search keys use JSON path notation eg "foo[bar][0]".
This has no affect on URL encoded form bodies during matching because
we manually convert the notation to nested objects for comparison now,
which means users can now provide expectations in either form.
Similarly, when matching search params using a provided object, there
is no net affect. The only breaking change is when a user provides a
callback function to `.query()`.

Replace `deep-equal` with a custom utility function in common.js.
Doing so not only dropped a dependency, it also achieved a more generic
utility for our usec ase with less code.

Interceptor matching had some refactoring:
- Query matching was moved to its own method in an effort to isolate concerns.
- Matching the request method was moved to the top of the match method.
- Debugging statements were updated as a baby step towards having more insight into why a match was missed.

Fixes #507
Fixes #1552

BREAKING CHANGE: The only argument passed to the Interceptor.query
callback now receives the output from querystring.parse instead of
qs.parse. This means that instead of nested objects the argument will
be a flat object.
gr2m pushed a commit that referenced this pull request Sep 5, 2019
The `qs` dependency was removed, however, recorder.js retained usage
of it. Replacing it with `querystring` from the std lib is sufficient.

Introduced: #1632
Fixes: #1651
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants