usher 0.5.11 → 0.5.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/Rakefile +48 -53
  2. data/VERSION.yml +2 -2
  3. data/lib/usher.rb +12 -12
  4. data/lib/usher/delimiters.rb +7 -7
  5. data/lib/usher/interface.rb +19 -30
  6. data/lib/usher/interface/{email_interface.rb → email.rb} +1 -1
  7. data/lib/usher/interface/{merb_interface.rb → merb.rb} +1 -1
  8. data/lib/usher/interface/{rack_interface.rb → rack.rb} +14 -10
  9. data/lib/usher/interface/{rack_interface → rack}/mapper.rb +0 -0
  10. data/lib/usher/interface/rack/route.rb +16 -0
  11. data/lib/usher/interface/rails20.rb +7 -0
  12. data/lib/usher/interface/{rails2_2_interface.rb → rails22.rb} +18 -18
  13. data/lib/usher/interface/{rails2_2_interface → rails22}/mapper.rb +2 -2
  14. data/lib/usher/interface/{rails2_3_interface.rb → rails23.rb} +1 -1
  15. data/lib/usher/interface/rails23/mapper.rb +44 -0
  16. data/lib/usher/interface/{rails3_interface.rb → rails3.rb} +1 -1
  17. data/lib/usher/interface/{text_interface.rb → text.rb} +1 -1
  18. data/lib/usher/node.rb +71 -57
  19. data/lib/usher/route.rb +10 -5
  20. data/lib/usher/route/static.rb +9 -0
  21. data/lib/usher/route/variable.rb +28 -9
  22. data/lib/usher/util.rb +3 -3
  23. data/lib/usher/util/generate.rb +55 -18
  24. data/lib/usher/util/parser.rb +25 -18
  25. data/rails/init.rb +24 -8
  26. data/spec/private/generate_spec.rb +116 -1
  27. data/spec/private/generate_with_spec.rb +28 -0
  28. data/spec/private/rack/dispatch_spec.rb +23 -2
  29. data/spec/private/rack/route_spec.rb +50 -0
  30. data/spec/private/rails2_2/generate_spec.rb +1 -1
  31. data/spec/private/rails2_2/path_spec.rb +1 -1
  32. data/spec/private/rails2_2/recognize_spec.rb +1 -1
  33. data/spec/private/rails2_3/generate_spec.rb +1 -1
  34. data/spec/private/rails2_3/path_spec.rb +1 -1
  35. data/spec/private/rails2_3/recognize_spec.rb +1 -1
  36. data/spec/private/recognize_spec.rb +4 -5
  37. data/spec/private/url_parts_spec.rb +116 -0
  38. metadata +26 -12
  39. data/lib/usher/interface/rack_interface/route.rb +0 -16
@@ -1,8 +1,24 @@
1
- if Rails::VERSION::MAJOR == 2 && Rails::VERSION::MINOR == 3
2
- ActionController::Routing.module_eval "remove_const(:Routes); Routes = Usher::Interface.for(:rails2_3)"
3
- elsif Rails::VERSION::MAJOR == 2 && Rails::VERSION::MINOR >= 2
4
- class Usher::Interface::Rails2_2Interface::Mapper
5
- include ActionController::Resources
6
- end
7
- ActionController::Routing.module_eval "remove_const(:Routes); Routes = Usher::Interface.for(:rails2_2)"
8
- end
1
+ rails_version = "#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}"
2
+
3
+ case rails_version
4
+ when '2.3'
5
+ ActionController::Routing.module_eval "remove_const(:Routes); Routes = Usher::Interface.for(:rails23)"
6
+
7
+ when '2.2'
8
+ class Usher::Interface::Rails22::Mapper
9
+ include ActionController::Resources
10
+ end
11
+ ActionController::Routing.module_eval "remove_const(:Routes); Routes = Usher::Interface.for(:rails22)"
12
+
13
+ when '2.0'
14
+ class Usher::Interface::Rails20::Mapper
15
+ include ActionController::Resources
16
+ end
17
+
18
+ ActionController::Routing.module_eval <<CODE
19
+ remove_const(:Routes);
20
+ interface = Usher::Interface.for(:rails20);
21
+ interface.configuration_file = File.join(RAILS_ROOT, 'config', 'routes.rb')
22
+ Routes = interface;
23
+ CODE
24
+ end
@@ -137,6 +137,122 @@ describe "Usher URL generation" do
137
137
  @route_set.generator.generate(:optionals, {:controller => "foo", :action => "bar"}).should == '/foo/bar'
138
138
  end
139
139
 
140
+ describe "when named route was added with string key" do
141
+ before :each do
142
+ @route_set.add_named_route 'items', '/items', :controller => 'items', :action => 'index'
143
+ end
144
+
145
+ it "should generate a named route by given symbolic key" do
146
+ @route_set.generator.generate(:items).should == '/items'
147
+ end
148
+ end
149
+
150
+ describe "#generate_start" do
151
+ before :all do
152
+ UrlParts = Usher::Util::Generators::URL::UrlParts
153
+ @url_parts_stub = UrlParts.new :some_path, :some_request
154
+ UrlParts.stub! :new => @url_parts_stub
155
+ end
156
+
157
+ describe "when url does not end with /" do
158
+ before :each do
159
+ @url_parts_stub.stub! :url => 'http://localhost'
160
+ end
161
+
162
+ it "should just return an url given by UrlParts" do
163
+ @route_set.generator.generate_start(:some_path, :some_request).should == 'http://localhost'
164
+ end
165
+ end
166
+
167
+ describe "when url ends with /" do
168
+ before :each do
169
+ @url_parts_stub.stub! :url => 'http://localhost/'
170
+ end
171
+
172
+ it "should strip trailing slash" do
173
+ @route_set.generator.generate_start(:some_path, :some_request).should == 'http://localhost'
174
+ end
175
+ end
176
+ end
177
+
178
+ describe "#generate_full" do
179
+ shared_examples_for "correct routes generator" do
180
+ describe "when request is a Rack::Request (Rails >= 2.3)" do
181
+ before :each do
182
+ @route_set.add_named_route :items, '/items'
183
+ @request = Rack::Request.new(Rack::MockRequest.env_for(@url))
184
+ end
185
+
186
+ it "should generate an URL correctly" do
187
+ @route_set.generator.generate_full(:items, @request).should == @url + '/items'
188
+ end
189
+ end
190
+
191
+ describe "when request is a AbstractRequest (Rails <= 2.2)" do
192
+ before :each do
193
+ @route_set.add_named_route :items, '/items'
194
+
195
+ @request = Struct.new(:url, :protocol, :host, :port).new(@url.dup, "#{@scheme}://", @host, @port)
196
+ end
197
+
198
+ it "should generate an URL correctly" do
199
+ @route_set.generator.generate_full(:items, @request).should == @url + '/items'
200
+ end
201
+ end
202
+
203
+ describe "when data is provided in @generated_with" do
204
+ before :each do
205
+ @route_set.add_named_route :items, '/items', :generate_with => { :scheme => @scheme, :host => @host, :port => @port }
206
+ @request = Rack::Request.new(Rack::MockRequest.env_for('ftp://something-another:9393'))
207
+ end
208
+
209
+ it "should generate an URL correctly" do
210
+ @route_set.generator.generate_full(:items, @request).should == @url + '/items'
211
+ end
212
+ end
213
+ end
214
+
215
+ describe "when protocol is http" do
216
+ describe "whem port is 80" do
217
+ before :each do
218
+ @scheme, @host, @port = 'http', 'localhost', 80
219
+ @url = 'http://localhost'
220
+ end
221
+
222
+ it_should_behave_like "correct routes generator"
223
+ end
224
+
225
+ describe "when port is custom" do
226
+ before :each do
227
+ @scheme, @host, @port = 'http', 'localhost', 8080
228
+ @url = 'http://localhost:8080'
229
+ end
230
+
231
+ it_should_behave_like "correct routes generator"
232
+ end
233
+ end
234
+
235
+ describe "when protocol is https" do
236
+ describe "whem port is 443 (standard)" do
237
+ before :each do
238
+ @scheme, @host, @port = 'https', 'localhost', 443
239
+ @url = 'https://localhost'
240
+ end
241
+
242
+ it_should_behave_like "correct routes generator"
243
+ end
244
+
245
+ describe "when port is custom" do
246
+ before :each do
247
+ @scheme, @host, @port = 'https', 'localhost', 8443
248
+ @url = 'https://localhost:8443'
249
+ end
250
+
251
+ it_should_behave_like "correct routes generator"
252
+ end
253
+ end
254
+ end
255
+
140
256
  describe "nested generation" do
141
257
  before do
142
258
  @route_set2 = Usher.new(:generator => Usher::Util::Generators::URL.new)
@@ -272,5 +388,4 @@ describe "Usher URL generation" do
272
388
  @r2.generator.generate(:route).should == "/r2"
273
389
  end
274
390
  end
275
-
276
391
  end
@@ -0,0 +1,28 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
2
+ require "usher"
3
+
4
+ describe Usher::Route::GenerateWith, "#empty?" do
5
+ before :all do
6
+ GenerateWith = Usher::Route::GenerateWith
7
+ end
8
+
9
+ describe "when all fields are nil" do
10
+ before :each do
11
+ @empty_generate_with = GenerateWith.new
12
+ end
13
+
14
+ it "should return true" do
15
+ @empty_generate_with.empty?.should be_true
16
+ end
17
+ end
18
+
19
+ describe "when at least one field is filled" do
20
+ before :each do
21
+ @filled_generate_with = GenerateWith.new('http')
22
+ end
23
+
24
+ it "should return false" do
25
+ @filled_generate_with.empty?.should be_false
26
+ end
27
+ end
28
+ end
@@ -56,6 +56,25 @@ describe "Usher (for rack) route dispatching" do
56
56
  response.status.should eql(404)
57
57
  end
58
58
 
59
+ describe "shortcuts" do
60
+ describe "get" do
61
+ before(:each) do
62
+ route_set.reset!
63
+ route_set.get('/sample').to(@app)
64
+ end
65
+
66
+ it "should dispatch a GET request" do
67
+ response = route_set.call_with_mock_request("/sample", "GET")
68
+ response.body.should eql("Hello World!")
69
+ end
70
+
71
+ it "should dispatch a HEAD request" do
72
+ response = route_set.call_with_mock_request("/sample", "HEAD")
73
+ response.body.should eql("Hello World!")
74
+ end
75
+ end
76
+ end
77
+
59
78
  describe "mounted rack instances" do
60
79
  before do
61
80
  @bad_app = mock("bad_app")
@@ -181,7 +200,8 @@ describe "Usher (for rack) route dispatching" do
181
200
  it "should allow me to set a default application to use" do
182
201
  @app.should_receive(:call).with{|e| e['usher.params'].should == {:middle => :ware}}
183
202
 
184
- u = Usher::Interface::RackInterface.new(@app)
203
+ u = Usher::Interface.for(:rack)
204
+ u.app = @app
185
205
  u.add("/foo", :default_values => {:middle => :ware}).name(:foo)
186
206
 
187
207
  u.call(Rack::MockRequest.env_for("/foo"))
@@ -190,7 +210,8 @@ describe "Usher (for rack) route dispatching" do
190
210
  it "should use the default application when no routes match" do
191
211
  env = Rack::MockRequest.env_for("/not_a_route")
192
212
  @app.should_receive(:call).with(env)
193
- u = Usher::Interface::RackInterface.new(@app)
213
+ u = Usher::Interface.for(:rack)
214
+ u.app = @app
194
215
  u.call(env)
195
216
  end
196
217
 
@@ -0,0 +1,50 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
2
+ require "usher"
3
+
4
+ describe "Rack interface extensions for Usher::Route" do
5
+ before(:each) do
6
+ @route_set = Usher::Interface.for(:rack)
7
+ @app = MockApp.new("Hello World!")
8
+ @env = Rack::MockRequest.env_for("/index.html")
9
+ end
10
+
11
+ describe "basic functinality" do
12
+ it "should set redirect headers" do
13
+ @route_set.get("/index.html").redirect("/")
14
+ raw_response = @route_set.call(@env)
15
+ response = Rack::MockResponse.new(*raw_response)
16
+ response.should be_redirect
17
+ end
18
+
19
+ it "should redirect '/index.html' to '/'" do
20
+ @route_set.get("/index.html").redirect("/")
21
+ status, headers, body = @route_set.call(@env)
22
+ headers["Location"].should eql("/")
23
+ end
24
+ end
25
+
26
+ describe "chaining" do
27
+ it "should be chainable" do
28
+ @route_set.get("/index.html").redirect("/").name(:root)
29
+ url = @route_set.router.generator.generate(:root)
30
+ url.should eql("/index.html")
31
+ end
32
+
33
+ it "should not influence actual invoking" do
34
+ @route_set.get("/index.html").redirect("/").name(:root)
35
+ @route_set.call(@env)
36
+ end
37
+ end
38
+
39
+ describe "custom status" do
40
+ it "should enable to set custom HTTP status" do
41
+ @route_set.get("/index.html").redirect("/", 303)
42
+ status, headers, body = @route_set.call(@env)
43
+ status.should eql(303)
44
+ end
45
+
46
+ it "should raise an exception if given HTTP code isn't a redirection" do
47
+ lambda { @route_set.get("/index.html").redirect("/", 200) }.should raise_error(ArgumentError)
48
+ end
49
+ end
50
+ end
@@ -2,7 +2,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_hel
2
2
  require File.expand_path(File.join(File.dirname(__FILE__), 'compat'))
3
3
  require "usher"
4
4
 
5
- route_set = Usher::Interface.for(:rails2_2)
5
+ route_set = Usher::Interface.for(:rails22)
6
6
 
7
7
  describe "Usher (for rails 2.2) URL generation" do
8
8
 
@@ -2,7 +2,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_hel
2
2
  require File.expand_path(File.join(File.dirname(__FILE__), 'compat'))
3
3
  require "usher"
4
4
 
5
- route_set = Usher::Interface.for(:rails2_2)
5
+ route_set = Usher::Interface.for(:rails22)
6
6
 
7
7
  describe "Usher (for rails 2.2) route adding" do
8
8
 
@@ -3,7 +3,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), 'compat'))
3
3
  require "usher"
4
4
  require 'action_controller'
5
5
 
6
- route_set = Usher::Interface.for(:rails2_2)
6
+ route_set = Usher::Interface.for(:rails22)
7
7
 
8
8
  def build_request_mock(path, method, params)
9
9
  request = mock "Request"
@@ -2,7 +2,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_hel
2
2
  require File.expand_path(File.join(File.dirname(__FILE__), 'compat'))
3
3
  require "usher"
4
4
 
5
- route_set = Usher::Interface.for(:rails2_3)
5
+ route_set = Usher::Interface.for(:rails23)
6
6
 
7
7
  describe "Usher (for rails 2.3) URL generation" do
8
8
 
@@ -2,7 +2,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_hel
2
2
  require File.expand_path(File.join(File.dirname(__FILE__), 'compat'))
3
3
  require "usher"
4
4
 
5
- route_set = Usher::Interface.for(:rails2_3)
5
+ route_set = Usher::Interface.for(:rails23)
6
6
 
7
7
  describe "Usher (for rails 2.3) route adding" do
8
8
 
@@ -3,7 +3,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), 'compat'))
3
3
  require "usher"
4
4
  require 'action_controller'
5
5
 
6
- route_set = Usher::Interface.for(:rails2_3)
6
+ route_set = Usher::Interface.for(:rails23)
7
7
 
8
8
  def build_request_mock(path, method, params)
9
9
  request = mock "Request"
@@ -64,13 +64,12 @@ describe "Usher route recognition" do
64
64
  insecure_product_show_route.should == @route_set.recognize(build_request({:method => 'get', :path => '/products/show/123', :domain => 'admin.host.com', :user_agent => false})).path.route
65
65
  end
66
66
 
67
- it "should use conditionals that are arrays" do
67
+ it "should use flatten and use conditionals that are arrays" do
68
68
  # hijacking user_agent
69
- www_product_show_route = @route_set.add_route('/products/show/:id', :id => /\d+/, :conditions => {:subdomains => ['www'], :method => 'get'})
70
- admin_product_show_route = @route_set.add_route('/products/show/:id', :id => /\d+/, :conditions => {:subdomains => ['admin'], :method => 'get'})
69
+ www_product_show_route = @route_set.add_route('/products/show/:id', :id => /\d+/, :conditions => {:subdomains => ['www', 'admin'], :method => 'get'})
71
70
 
72
- admin_product_show_route.should == @route_set.recognize(build_request({:method => 'get', :path => '/products/show/123', :subdomains => ['admin'], :user_agent => true})).path.route
73
- www_product_show_route.should == @route_set.recognize(build_request({:method => 'get', :path => '/products/show/123', :subdomains => ['www'], :user_agent => false})).path.route
71
+ www_product_show_route.should == @route_set.recognize(build_request({:method => 'get', :path => '/products/show/123', :subdomains => 'admin', :user_agent => true})).path.route
72
+ www_product_show_route.should == @route_set.recognize(build_request({:method => 'get', :path => '/products/show/123', :subdomains => 'www', :user_agent => false})).path.route
74
73
  end
75
74
  end
76
75
 
@@ -0,0 +1,116 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
2
+ require "usher"
3
+ require 'rack/test'
4
+
5
+ module PathAndRequestHelper
6
+ def stub_path_with(scheme, host, port)
7
+ generate_with = Usher::Route::GenerateWith.new(scheme, port, host)
8
+
9
+ route = stub 'route'
10
+ route.stub! :generate_with => generate_with
11
+
12
+ path = stub 'path'
13
+ path.stub! :route => route
14
+
15
+ path
16
+ end
17
+
18
+ def stub_path
19
+ stub_path_with nil, nil, nil
20
+ end
21
+
22
+ def rack_request_for(url)
23
+ Rack::Request.new(Rack::MockRequest.env_for(url))
24
+ end
25
+ end
26
+
27
+ describe Usher::Util::Generators::URL::UrlParts do
28
+ include PathAndRequestHelper
29
+
30
+ before :all do
31
+ UrlParts = Usher::Util::Generators::URL::UrlParts
32
+ end
33
+
34
+ describe "#url" do
35
+ describe "when generate_with is provided" do
36
+ before :each do
37
+ @path = stub_path_with 'https', 'overridden', 9443
38
+ @request = rack_request_for 'http://localhost'
39
+ end
40
+
41
+ it "should return url with parts provided by generate_with" do
42
+ url_parts = UrlParts.new(@path, @request)
43
+ url_parts.url.should == "https://overridden:9443"
44
+ end
45
+
46
+ describe "when port is standard" do
47
+ describe "when scheme is https" do
48
+ before :each do
49
+ @path = stub_path_with 'https', 'overridden', 443
50
+ @request = rack_request_for 'http://localhost:8080'
51
+ end
52
+
53
+ it "should not add port to url" do
54
+ url_parts = UrlParts.new(@path, @request)
55
+ url_parts.url.should == "https://overridden"
56
+ end
57
+ end
58
+
59
+ describe "when scheme is http" do
60
+ before :each do
61
+ @path = stub_path_with 'http', 'overridden', 80
62
+ @request = rack_request_for 'http://localhost:8080'
63
+ end
64
+
65
+ it "should not add port to url" do
66
+ url_parts = UrlParts.new(@path, @request)
67
+ url_parts.url.should == "http://overridden"
68
+ end
69
+ end
70
+ end
71
+
72
+ describe "when scheme is not given" do
73
+ before :each do
74
+ @path = stub_path_with nil, 'overridden', 8443
75
+ end
76
+
77
+ describe "when request is Rack's one" do
78
+ before :each do
79
+ @request = rack_request_for 'https://localhost'
80
+ end
81
+
82
+ it "should extract scheme from request" do
83
+ url_parts = UrlParts.new(@path, @request)
84
+ url_parts.url.should == "https://overridden:8443"
85
+ end
86
+ end
87
+
88
+ describe "when request is an AbstractRequest (Rails < 2.3)" do
89
+ before :each do
90
+ @request = stub 'request'
91
+ @request.stub! :protocol => 'https://'
92
+ end
93
+
94
+ it "should call #protocol, not #scheme" do
95
+ url_parts = UrlParts.new(@path, @request)
96
+ url_parts.url.should == "https://overridden:8443"
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ describe "when generate_with is empty" do
103
+ before :each do
104
+ @path = stub_path
105
+ @request = mock 'request'
106
+ end
107
+
108
+ it "should just extract the url" do
109
+ @request.should_receive(:url).and_return('http://localhost')
110
+
111
+ url_parts = UrlParts.new(@path, @request)
112
+ url_parts.url.should == 'http://localhost'
113
+ end
114
+ end
115
+ end
116
+ end