On Oct 19, 2010, at 2:05 AM, Wincent C. wrote:
I thought someone posted a pretty good analysis of exactly what the breakage is
and why it happens, but I can’t find it. Guess when I get time will have to do
some analysis of the Rails codebase and figure out what’s happening and put
together another ticket.
While Googling, found this, however, describing changes in 2.0.0:
API for uni-directional routing expectations · Issue #221 · rspec/rspec-rails · GitHub
Which notes that RSpec’s “route_to” now delegates to “assert_recognizes” (a
one-way assertion) rather than “assert_routing” (a two-way assertion).
The problem with the bi-directional expectation was that you can have
two routes that map to the same path:
resources :widgets
root :to => “widgets#index”
In this case, both of these are true if all we expect is the route
recognition:
{ :get => “/” }.should route_to(:controller => “widgets”, :action =>
“index”)
{ :get => “/widgets/index” }.should route_to(:controller => “widgets”,
:action => “index”)
However, route generation would not generate “/” from (:controller =>
“widgets”, :action => “index”). Assuming a bi-directional mapping for
every case was wrong, so I changed it to uni-directional (route
recognition).
The other 1/2 of the motivation for this change was that route
generation is something that is well specified and tested in Rails
itself. In our apps, our specs should spec things like “generates a link
to the widget,” not “builds a link using the widget.” So I don’t see
much value in expectations about generation, and I certainly don’t see
them as a routing concern any longer. They may be so within the rails
framework, but they are unrelated to what I’m specifying when I specify
routes. Make sense?
So for me, all we need is uni-directional expectations for routes we
want to exist and routes we want to not exist, hence:
{ :get => “/” }.should route_to(:controller => “foo”, :action =>
“bar”)
{ :get => “/private_stuff” }.should_not be_routable
I would definitely be open to adding conveniences to clean this up:
get(“/”).should route_to(“foo#bar”)
get(“/private_stuff”).should_not be_routable
Then Joe’s DSL could exploit those and we’d get:
get “/blog” => “blogs-controller#index”
Still not sure about the negative (unroutable).
Cheers,
David