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

[bugfix] Fix method subrouter handler matching (#300) #317

Merged
merged 7 commits into from
Nov 28, 2017

Conversation

mtso
Copy link
Contributor

@mtso mtso commented Nov 27, 2017

Fix handler match for subrouters created from method-matcher-based routes where the paths match (issue #300).

  • Add a test case for routers with methods-based subrouters and matching paths
  • Pass the test case with an addition to Route.Match

mux_test.go Outdated

// TestMethodsSubrouter tests the correct matching of handlers for
// subrouters registered after a route's method-matcher is set.
func TestMethodsSubrouter(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

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

It may be better to break this up a little, to allow parallel test execution (via t.Parallel()),.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I can try that.

mux_test.go Outdated
// TestMethodsSubrouter tests the correct matching of handlers for
// subrouters registered after a route's method-matcher is set.
func TestMethodsSubrouter(t *testing.T) {
flags1 := make([]bool, 3)
Copy link
Contributor

Choose a reason for hiding this comment

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

It isn't obvious (e.g. at first) what the purpose of the slice of bools / flags are for at first. Can you add a comment here to aid future contributors, and/or (better) look at a better way to test these that doesn't require this state tracking?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I can try that, would inspecting the response body be better?

Copy link
Contributor

Choose a reason for hiding this comment

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

I actually don't quite understand it, is it just to show which methods matched? Why not use a map[string]bool for this?

Copy link
Contributor Author

@mtso mtso Nov 27, 2017

Choose a reason for hiding this comment

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

The flags are used to check which handler is invoked. I wanted to check sequentially (for when two same routes are registered, but only the first one should be matched), but I can use map[string]bool with [method][number] like get1 and get2.

Copy link
Contributor

Choose a reason for hiding this comment

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

I would also call it something like matched_methods instead of just flags. The tests for this package are pretty confusing and convoluted, so anything that helps add some clarity is a big plus.

@mtso
Copy link
Contributor Author

mtso commented Nov 28, 2017

Broke up TestMethodsSubrouter into five separate test cases based on the router initialized for each one. t.Parallel is also invoked in each one, so they run concurrently. Breaking them up further without t.Run would make the router initialization strategy more verbose.

methodsSubrouterTest has also been made stateless so the handler-match assertions are cleaner.

Copy link
Contributor

@elithrar elithrar left a comment

Choose a reason for hiding this comment

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

Minor style changes, but otherwise: thanks for refactoring the tests. Much more readable now! 👌

}

// TestMethodsSubrouterPathPrefix matches handlers on subrouters created
// on a router with a path prefix matcher and method matcher.
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

mux_test.go Outdated
switch test.wantCode {
case http.StatusMethodNotAllowed:
if resp.Code != http.StatusMethodNotAllowed {
t.Errorf("(%s) Expected \"405 Method Not Allowed\", but got %d code", test.title, resp.Code)
Copy link
Contributor

Choose a reason for hiding this comment

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

Use backticks (`) for raw strings so you don't have to escape quotes.

@mtso
Copy link
Contributor Author

mtso commented Nov 28, 2017

The relevant string literals have been updated to use backticks. Thanks for both your helpful feedback!

mux_test.go Outdated
)

// Method handlers return the method string.
var (
Copy link
Contributor

@kisielk kisielk Nov 28, 2017

Choose a reason for hiding this comment

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

I think this would make it more clear:

func methodHandler(method string) http.HandlerFunc {
   return func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte(method))
   }
}

That way when you're defining the test fixtures, the string returned by the handler is right there in the fixture as opposed to these global functions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, makes sense. I noticed the HTTP methods in other tests are raw strings. Should these constants be replaced, too?

Copy link
Contributor

Choose a reason for hiding this comment

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

You could probably just the put the strings inline, yeah. I don't think it helps much to have them as constants here

@mtso
Copy link
Contributor Author

mtso commented Nov 28, 2017

The global method handler variables and constants have been removed.

@kisielk kisielk merged commit 4a3d4f3 into gorilla:master Nov 28, 2017
@kisielk
Copy link
Contributor

kisielk commented Nov 28, 2017

LGTM! Thanks

@elithrar
Copy link
Contributor

Thanks for the contribution @mtso!

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

Successfully merging this pull request may close these issues.

3 participants