On Aug 17, 2010, at 12:46 PM, Michael Kintzer wrote:
> On Jul 7, 11:25 pm, Wincent Colaiuta <[email protected]> wrote:
>>
>> So, when I see this kind of thing, I think _what_ are we trying to achieve
>> in ourroutingspecs and _why_? At least for me, the answers are:
>>
>> 1. Confirm: To confirm that the routes I've defined actually do what I
>> think they do
>>
>> 2. Describe: To serve as a complete, explicit, readable specification of
>> the behavior I expect from my routes
>>
>> And finally:
>>
>> 3. That the Railsroutingcode actually works as advertised
>>
>> This last one is a bit dubious, but the truth is the Rails 3 router is a
>> complete re-write and bugs in it and incompatibilities with the old router
>> are being found and squished constantly. An exhaustive set ofroutingspecs
>> can definitely help to uncover undiscovered edge cases.
>>
>> So, bearing in mind those goals, what I actually need from RSpec in order to
>> achieve them is:
>>
>> - most importantly, a way of asserting that a user action (eg. HTTP verb +
>> path + params) gets routed to a given controller + action with certain
>> additional parameters (ie. a wrapper for assert_recognizes)
>>
>> - less importantly, a way of asserting that a set of params (action,
>> controller, additional params) generates a particular path (ie. a wrapper
>> for assert_generates); this is less important for me because in practice
>> close to all (98%) of my URL generation is done with named URL helpers, and
>> I can test those explicitly if I want
>>
>> - as syntactic sugar, a way of combining the above two assertions into one
>> for those cases where the mapping is perfectly bidirectional (ie. a wrapper
>> for assert_routing).
>>
>> With these tools I can achieve pretty much everything I need: not only test
>> that user actions end up hitting the right spots in my application, but also
>> specify clearly and explicitly what I expect those mappings to be.
>>
>> So for me, anything else doesn't really help me achieve my goals. The
>> "have_resource(s)" matcher, for instance, doesn't help me and in fact
>> actually undermines my goal of providing a complete and explicit
>> specification of how my routes work.
>>
>> The "recognize" and "generate" matchers you suggest obviously are "on
>> target" to help me fulfill my goals. Of these, the "recognize" one is the
>> most important one though.
>>
>> Of the "match" and "get" matchers you suggest, seeing as they both wrap the
>> same thing (assert_routing), one of them would have to go. I'd probably
>> ditch "match" because it is just a repetition of the router DSL method of
>> the same name, and my goal here isn't just to repeat that DSL in my specs.
>>
>> In fact, if you look at my most important goal -- asserting that a user
>> action (HTTP verb, path, params) hits a specific end point (controller +
>> action + additional params) -- you'll understand why, in my proposal, all of
>> my specifications start with "get"/"post" etc followed by path, params and
>> then controller/action. It's not just for resonance with other parts of
>> RSpec like where we use "get" etc in controller specs.
>>
>> But if the goal is just to wrap the 3 Rails assertions as faithfully as
>> possible, then you wind up with a different proposal. What David has posted
>> is probably the closest to this goal.
>>
>> And if the goal is make the specs map as closely as possible onto the
>> language of config/routes.rb, then you wind up with a different proposal
>> still... (ie. the one you just made).
>>
>> So, I guess what I'm saying here is I'd like to hear _what_ people are
>> wanting to achieve in theirroutingspecs and _why_; and then to ask what kind
>> of means RSpec should provide to best achieve those goals.
>>
>> Cheers,
>> Wincent
> Lots of good proposals here. I would at least like to chime in that I
> agree with the goals as set out by Wincent below, and from a
> readability standpoint have preferred the API as suggested by
> Trevor.
>
> -Michael
Time to resurrect this discussion.
Thinking about Wincent's very thoughtful synopsis has lead me to a slightly
different line of thinking here.
We've always seen route recognition and route generation as opposite sides of
the same coin, but I think that's due to how they are presented to us by the
Rails testing facilities. The more I think of it, route generation is not
really the concern of the router at all. It's a responsibility of controllers
(and views, by proxy) to generate a recognizable route from a set of params.
What this leads me to is that I'd like to simplify all of this and make
route_to only care about the routing side of this equation (i.e. have it
delegate to assert_recognizes, rather than assert_routing).
The implication of this would be that we'd theoretically lose coverage that
routes are generated correctly, but I don't think that actually matters. We
still need to assemble the right parameters in our controllers/views to get the
routes we want, so those should be specified in relation to the controller or
view. i.e. in a view spec:
rendered.should have_css("a", :href => projects_path)
The fact that the controller can generate that link from {:controller =>
"projects", :action => "index"} is a matter of Rails working as advertised.
Plus, if we wrote that link in a view and it generated an unrecognizable route,
the error message we'd get is that no route matches, not that the route could
not be generated.
To sum up: I'd like to have route_to delegate to assert_recognizes, and leave
it at that.
That said, I'd be perfectly willing to add some of the sugar that has been
proposed in this thread, so we can say:
get("/").should route_to("projects#index")
I agree that this is more terse, yet very expressive in the context of other
facilities we're dealing with.
Thoughts?
_______________________________________________
rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users