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

Reply via email to