joshbuddy-usher 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -27,3 +27,10 @@ namespace(:spec) do
27
27
  end
28
28
 
29
29
  end
30
+
31
+ desc "Run all examples with RCov"
32
+ Spec::Rake::SpecTask.new('spec_with_rcov') do |t|
33
+ t.spec_files = FileList['spec/**/*.rb']
34
+ t.rcov = true
35
+ t.rcov_opts = ['--exclude', 'spec']
36
+ end
@@ -1,4 +1,4 @@
1
1
  ---
2
- :minor: 3
3
- :patch: 2
2
+ :patch: 3
4
3
  :major: 0
4
+ :minor: 3
@@ -44,10 +44,10 @@ class Usher
44
44
  # The +request_methods+ are methods that are called against the request object in order to
45
45
  # enforce the +conditions+ segment of the routes. For HTTP routes (and in fact the default), those
46
46
  # methods are <tt>[:protocol, :domain, :port, :query_string, :remote_ip, :user_agent, :referer, :method]</tt>.
47
- def initialize(delimiters = ['/', '.'], request_methods = [:protocol, :domain, :port, :query_string, :remote_ip, :user_agent, :referer, :method])
48
- @delimiters = delimiters
49
- @splitter = Splitter.for_delimiters(delimiters)
50
- @request_methods = request_methods
47
+ def initialize(options = {})
48
+ @delimiters = options.delete(:options) || ['/', '.']
49
+ @request_methods = options.delete(:request_methods) || [:protocol, :domain, :port, :query_string, :remote_ip, :user_agent, :referer, :method, :subdomains]
50
+ @splitter = Splitter.for_delimiters(@delimiters)
51
51
  reset!
52
52
  end
53
53
 
@@ -117,7 +117,7 @@ class Usher
117
117
  conditions = options.delete(:conditions) || {}
118
118
  requirements = options.delete(:requirements) || {}
119
119
  options.delete_if do |k, v|
120
- if v.is_a?(Regexp)
120
+ if v.is_a?(Regexp) || v.is_a?(Proc)
121
121
  requirements[k] = v
122
122
  true
123
123
  end
@@ -173,7 +173,7 @@ class Usher
173
173
  else
174
174
  route
175
175
  end
176
-
176
+ raise UnrecognizedException.new unless path
177
177
  params_hash = {}
178
178
  param_list = case params
179
179
  when Hash
@@ -16,7 +16,6 @@ class Usher
16
16
  @value = value
17
17
  @lookup = FuzzyHash.new
18
18
  @exclusive_type = nil
19
- @has_globber = find_parent{|p| p.value && p.value.is_a?(Route::Variable)}
20
19
  end
21
20
 
22
21
  def depth
@@ -29,28 +28,10 @@ class Usher
29
28
  root
30
29
  end
31
30
 
32
- def has_globber?
33
- @has_globber
34
- end
35
-
36
31
  def terminates?
37
32
  @terminates
38
33
  end
39
34
 
40
- def find_parent(&blk)
41
- if @parent.nil? || !@parent.is_a?(Node)
42
- nil
43
- elsif yield @parent
44
- @parent
45
- else #keep searching
46
- @parent.find_parent(&blk)
47
- end
48
- end
49
-
50
- def replace(src, dest)
51
- @lookup.replace(src, dest)
52
- end
53
-
54
35
  def pp
55
36
  $stdout << " " * depth
56
37
  $stdout << "#{depth}: #{value.inspect} #{!!terminates?}\n"
@@ -83,12 +64,7 @@ class Usher
83
64
  current_node.lookup[nil] ||= Node.new(current_node, Route::RequestMethod.new(current_node.exclusive_type, nil))
84
65
  end
85
66
  else
86
- if current_node.exclusive_type
87
- parts.unshift(key)
88
- current_node.lookup[nil] ||= Node.new(current_node, Route::RequestMethod.new(current_node.exclusive_type, nil))
89
- else
90
- current_node.lookup[key.is_a?(Route::Variable) ? nil : key] ||= Node.new(current_node, key)
91
- end
67
+ current_node.lookup[key.is_a?(Route::Variable) ? nil : key] ||= Node.new(current_node, key)
92
68
  end
93
69
  current_node = target_node
94
70
  end
@@ -109,8 +85,8 @@ class Usher
109
85
  elsif path.size.zero? && !part
110
86
  if terminates?
111
87
  Response.new(terminates, params)
112
- else
113
- nil
88
+ elsif params.last.is_a?(Array) && @lookup[nil]
89
+ Response.new(@lookup[nil].terminates, params)
114
90
  end
115
91
  elsif next_part = @lookup[part]
116
92
  next_part.find(request, path, params)
@@ -120,16 +96,14 @@ class Usher
120
96
  next_part.value.valid!(part)
121
97
  case next_part.value.type
122
98
  when :*
123
- params << [next_part.value.name, []]
124
- params.last.last << part
99
+ params << [next_part.value.name, []] unless params.last && params.last.first == next_part.value.name
100
+ params.last.last << part unless part.is_a?(Symbol)
101
+ find(request, path, params)
125
102
  when :':'
126
103
  params << [next_part.value.name, part]
104
+ next_part.find(request, path, params)
127
105
  end
128
106
  end
129
- next_part.find(request, path, params)
130
- elsif has_globber? && p = find_parent{|p| p.value.is_a?(Route::Variable) && p.value.type == :*}
131
- params.last.last << part
132
- find(request, path, params)
133
107
  else
134
108
  nil
135
109
  end
@@ -14,8 +14,9 @@ class Usher
14
14
  end
15
15
 
16
16
  def eql?(o)
17
- o.is_a?(Http) && o.type == type && o.value == value
17
+ o.is_a?(self.class) && o.type == type && o.value == value
18
18
  end
19
+ alias == eql?
19
20
  end
20
21
  end
21
22
  end
@@ -80,9 +80,18 @@ describe "Usher URL generation" do
80
80
  proc {route_set.generate_url(route_set.add_route('/:controller/:action').primary_path, {:controller => 'controller'})}.should raise_error Usher::MissingParameterException
81
81
  end
82
82
 
83
+ it "should generate from a route" do
84
+ route_set.generate_url(route_set.add_route('/:controller/:action'), {:controller => 'controller', :action => 'action'}).should == '/controller/action'
85
+ end
86
+
83
87
  it "should require all the parameters (array) to generate a route" do
84
88
  route_set.add_named_route(:name, '/:controller/:action.:format')
85
89
  proc {route_set.generate_url(:name, ['controller', 'action'])}.should raise_error Usher::MissingParameterException
86
90
  end
87
91
 
92
+ it "should generate a route when only one parameter is given" do
93
+ route_set.add_named_route(:name, '/:controller')
94
+ route_set.generate_url(:name, 'controller').should == '/controller'
95
+ end
96
+
88
97
  end
@@ -19,6 +19,11 @@ describe "Usher grapher" do
19
19
  route_set.generate_url(nil, {:a => 'A', :b => 'B', :c => 'C'}).should == '/A/B/C'
20
20
  end
21
21
 
22
+ it "should fail to generate a route when none matches" do
23
+ route_set.add_route('/:a/:b')
24
+ proc {route_set.generate_url(nil, {:c => 'C', :d => 'D'}) }.should raise_error Usher::UnrecognizedException
25
+ end
26
+
22
27
  it "should find the most specific route and append extra parts on as a query string" do
23
28
  route_set.add_route('/:a/:b/:c')
24
29
  route_set.add_route('/:a/:b')
@@ -36,4 +36,33 @@ describe "Usher route adding" do
36
36
  route_set.add_named_route(:route, '/bad/route', :controller => 'sample').should == route_set.named_routes[:route]
37
37
  end
38
38
 
39
+ it "should calculate depths for nodes" do
40
+ route_set.add_named_route(:route, '/bad/route/three/four')
41
+ route_set.tree.depth.should == 0
42
+ route_set.tree.lookup[:/].depth.should == 1
43
+ end
44
+
45
+ it "should pp for nodes" do
46
+ route_set.add_named_route(:route, '/bad/route/three/four')
47
+ route_set.tree.depth.should == 0
48
+ old_out = $stdout
49
+ $stdout = (output = StringIO.new)
50
+ route_set.tree.lookup[:/].lookup['bad'].lookup[:/].pp
51
+ $stdout = old_out
52
+ output.rewind
53
+ output.read.should == <<-HEREDOC
54
+ 3: :/ false
55
+ route ==>
56
+ 4: "route" false
57
+ / ==>
58
+ 5: :/ false
59
+ three ==>
60
+ 6: "three" false
61
+ / ==>
62
+ 7: :/ false
63
+ four ==>
64
+ 8: "four" true
65
+ HEREDOC
66
+ end
67
+
39
68
  end
@@ -35,6 +35,11 @@ describe "Usher route recognition" do
35
35
  route_set.recognize(build_request({:method => 'get', :path => '/sample.html', :domain => 'admin.host.com'})).should == Usher::Node::Response.new(target_route.paths.first, [[:format , 'html']])
36
36
  end
37
37
 
38
+ it "should recognize a glob-style variable" do
39
+ target_route = route_set.add_route('/sample/*format', :controller => 'sample', :action => 'action')
40
+ route_set.recognize(build_request({:method => 'get', :path => '/sample/html/json/apple'})).params.should == [[:format, ['html', 'json', 'apple']]]
41
+ end
42
+
38
43
  it "should recognize a format-style literal" do
39
44
  target_route = route_set.add_route('/:action.html', :controller => 'sample', :action => 'action')
40
45
  route_set.recognize(build_request({:method => 'get', :path => '/sample.html', :domain => 'admin.host.com'})).should == Usher::Node::Response.new(target_route.paths.first, [[:action , 'sample']])
@@ -72,11 +77,26 @@ describe "Usher route recognition" do
72
77
  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
73
78
  end
74
79
 
80
+ it "should use conditionals that are arrays" do
81
+ # hijacking user_agent
82
+ www_product_show_route = route_set.add_route('/products/show/:id', :id => /\d+/, :conditions => {:subdomains => ['www'], :method => 'get'})
83
+ admin_product_show_route = route_set.add_route('/products/show/:id', :id => /\d+/, :conditions => {:subdomains => ['admin'], :method => 'get'})
84
+
85
+ admin_product_show_route.should == route_set.recognize(build_request({:method => 'get', :path => '/products/show/123', :subdomains => ['admin'], :user_agent => true})).path.route
86
+ www_product_show_route.should == route_set.recognize(build_request({:method => 'get', :path => '/products/show/123', :subdomains => ['www'], :user_agent => false})).path.route
87
+ end
88
+
75
89
  it "should use a transformer (proc) on incoming variables" do
76
90
  route_set.add_route('/:controller/:action/:id', :transformers => {:id => proc{|v| v.to_i}})
77
91
  route_set.recognize(build_request({:method => 'get', :path => '/products/show/123asd', :domain => 'admin.host.com'})).params.rassoc(123).first.should == :id
78
92
  end
79
93
 
94
+ it "should use a requirement (proc) on incoming variables" do
95
+ route_set.add_route('/:controller/:action/:id', :id => proc{|v| Integer(v)})
96
+ proc {route_set.recognize(build_request({:method => 'get', :path => '/products/show/123', :domain => 'admin.host.com'}))}.should_not raise_error Usher::ValidationException
97
+ proc {route_set.recognize(build_request({:method => 'get', :path => '/products/show/123asd', :domain => 'admin.host.com'}))}.should raise_error Usher::ValidationException
98
+ end
99
+
80
100
  it "shouldn't care about mildly weird characters in the URL" do
81
101
  route = route_set.add_route('/!asd,qwe/hjk$qwe/:id')
82
102
  route_set.recognize(build_request({:method => 'get', :path => '/!asd,qwe/hjk$qwe/09AZaz$-_+!*\'', :domain => 'admin.host.com'})).params.rassoc('09AZaz$-_+!*\'').first.should == :id
@@ -0,0 +1,15 @@
1
+ require 'lib/usher'
2
+
3
+ describe "Usher request method" do
4
+
5
+ it "support eql? and ==" do
6
+ Usher::Route::RequestMethod.new(:method, 'blah').should == Usher::Route::RequestMethod.new(:method, 'blah')
7
+ Usher::Route::RequestMethod.new(:method, 'blah').should.eql?(Usher::Route::RequestMethod.new(:method, 'blah'))
8
+ end
9
+
10
+ it "support hash" do
11
+ Usher::Route::RequestMethod.new(:method, 'blah').hash.should == (Usher::Route::RequestMethod.new(:method, 'blah')).hash
12
+ end
13
+
14
+
15
+ end
@@ -53,5 +53,15 @@ describe "Usher route tokenizing" do
53
53
  [:/, "test", :/, "this", :/, "split", '.', Usher::Route::Variable.new(:':', :format)]
54
54
  ]
55
55
  end
56
+
57
+ it "should to_s all different variable types" do
58
+ Usher::Splitter.for_delimiters(['/', '.']).split('/:split/*splitter').first.collect{|v| v.to_s} ==
59
+ [ ':split', '*splitter' ]
60
+ end
61
+
62
+ it "should == variable types" do
63
+ parts = Usher::Splitter.for_delimiters(['/', '.']).split('/:split/:split').first
64
+ parts[1].should == parts[3]
65
+ end
56
66
 
57
67
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: joshbuddy-usher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Hull
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-06 00:00:00 -07:00
12
+ date: 2009-04-07 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -68,6 +68,7 @@ files:
68
68
  - spec/rails/path_spec.rb
69
69
  - spec/rails/recognize_spec.rb
70
70
  - spec/recognize_spec.rb
71
+ - spec/request_method_spec.rb
71
72
  - spec/spec.opts
72
73
  - spec/split_spec.rb
73
74
  - rails/init.rb