http_router 0.8.10 → 0.8.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,142 @@
1
+ require 'json'
2
+
3
+ recognition_file = "#{File.dirname(__FILE__)}/common/recognize.txt"
4
+ recognition = File.read(recognition_file)
5
+
6
+ class RecognitionTest
7
+ Info = Struct.new(:case, :original_line, :num)
8
+
9
+ attr_reader :routes, :tests
10
+ def initialize(file)
11
+ @tests = []
12
+ @routes = Info.new([], "", 0)
13
+ end
14
+
15
+ def error(msg)
16
+ raise("Error in case: #{@routes.original_line.strip}:#{@routes.num + 1}\n#{msg}")
17
+ end
18
+
19
+ def add_test(line, num)
20
+ @tests << Info.new(JSON.parse(line), line, num)
21
+ end
22
+
23
+ def add_routes(line, num)
24
+ info = Info.new(JSON.parse(line), line, num)
25
+ error("Routes have already been defined without tests") if info.case.is_a?(Array) && !@routes.case.empty?
26
+ if info.case.is_a?(Array)
27
+ @routes = info
28
+ elsif @routes.case.empty?
29
+ info.case = [info.case]
30
+ @routes = info
31
+ else
32
+ @routes.case << info.case
33
+ end
34
+ end
35
+
36
+ def interpret_val(val)
37
+ case val
38
+ when nil
39
+ error("Unable to interpret #{val.inspect}")
40
+ when Hash
41
+ val['regex'] ? Regexp.new(val['regex']) : error("Okay serious, no idea #{val.inspect}")
42
+ else
43
+ val
44
+ end
45
+ end
46
+
47
+ def invoke
48
+ error("invoke called with no tests or routes") if @tests.empty? || @routes.nil?
49
+ router = HttpRouter.new
50
+ @routes.case.each do |route_definition|
51
+ error("Too many keys! #{route_definition.keys.inspect}") unless route_definition.keys.size == 1
52
+ route_name, route_properties = route_definition.keys.first, route_definition.values.first
53
+ route = case route_properties
54
+ when String
55
+ router.add(route_properties)
56
+ when Hash
57
+ opts = {}
58
+ route_path = interpret_val(route_properties.delete("path"))
59
+ if route_properties.key?("conditions")
60
+ opts[:conditions] = Hash[route_properties.delete("conditions").map{|k, v| [k.to_sym, interpret_val(v)]}]
61
+ end
62
+ route_properties.each do |key, val|
63
+ opts[key.to_sym] = interpret_val(val)
64
+ end
65
+ router.add(route_path, opts)
66
+ else
67
+ error("Route isn't a String or hash")
68
+ end
69
+ route.name(route_name.to_sym)
70
+ route.to{|env| [200, {"env-to-test" => env.dup}, [route_name]]}
71
+ end
72
+ @tests.map(&:case).each do |(name, req, params)|
73
+ env = case req
74
+ when String
75
+ Rack::MockRequest.env_for(req)
76
+ when Hash
77
+ e = Rack::MockRequest.env_for(req['path'])
78
+ e['REQUEST_METHOD'] = req['method'] if req.key?('method')
79
+ e['rack.url_scheme'] = req['scheme'] if req.key?('scheme')
80
+ e
81
+ end
82
+ response = router.call(env)
83
+ case name
84
+ when nil
85
+ error("Expected no response") unless response.first == 404
86
+ when Array
87
+ name.each_with_index do |part, i|
88
+ case part
89
+ when Hash then part.keys.all? or error("#{part.inspect} didn't match #{response[i].inspect}")
90
+ else part == response[i] or error("#{part.inspect} didn't match #{response[i].inspect}")
91
+ end
92
+ end
93
+ else
94
+ error("Expected #{name} for #{req.inspect} got #{response.inspect}") unless response.last == [name]
95
+ end
96
+ env['router.params'] ||= {}
97
+ params ||= {}
98
+ if params['PATH_INFO']
99
+ path_info = params.delete("PATH_INFO")
100
+ error("path_info #{env['PATH_INFO'].inspect} is not #{path_info.inspect}") unless path_info == env['PATH_INFO']
101
+ end
102
+
103
+ env['router.params'].keys.each do |k|
104
+ p_v = params.delete(k.to_s)
105
+ v = env['router.params'].delete(k.to_sym)
106
+ error("I got #{p_v.inspect} but expected #{v.inspect}") unless p_v == v
107
+ end
108
+ error("Left over expectations: #{params.inspect}") unless params.empty?
109
+ error("Left over matched params: #{env['router.params'].inspect}") unless env['router.params'].empty?
110
+ end
111
+ print '.'
112
+ end
113
+ end
114
+
115
+ tests = []
116
+ test = nil
117
+ num = 0
118
+ recognition.each_line do |line|
119
+ begin
120
+ case line
121
+ when /^#/, /^\s*$/
122
+ # skip
123
+ when /^( |\t)/
124
+ test.add_test(line, num)
125
+ else
126
+ if test.nil? || !test.tests.empty?
127
+ tests << test if test
128
+ test = RecognitionTest.new(recognition_file)
129
+ end
130
+ test.add_routes(line, num)
131
+ end
132
+ rescue
133
+ warn "There was a problem with #{num}:#{line}"
134
+ raise
135
+ end
136
+ num += 1
137
+ end
138
+ tests << test
139
+
140
+ puts "Running recognition tests (Routes: #{tests.size}, Tests: #{tests.inject(0){|s, t| s+=t.tests.size}})..."
141
+ tests.each(&:invoke)
142
+ puts "\ndone!"
@@ -1,4 +1,13 @@
1
- class TestArbitrary < MiniTest::Unit::TestCase
1
+ class TestRecognition < MiniTest::Unit::TestCase
2
+ if //.respond_to?(:names)
3
+ eval <<-EOT
4
+ def test_match_path_with_groups
5
+ r = router { add(%r{/(?<year>\\d{4})/(?<month>\\d{2})/(?<day>\\d{2})/?}) }
6
+ assert_route r, "/1234/23/56", {:year => "1234", :month => "23", :day => "56"}
7
+ end
8
+ EOT
9
+ end
10
+
2
11
  def test_match
3
12
  hello, love80, love8080 = router {
4
13
  add('test').arbitrary(Proc.new{|req, params| req.rack.host == 'hellodooly' })
@@ -55,4 +64,30 @@ class TestArbitrary < MiniTest::Unit::TestCase
55
64
  }
56
65
  assert_route yes, '/test'
57
66
  end
58
- end
67
+
68
+ def test_passing
69
+ passed, working = router {
70
+ add('/').to { |env| throw :pass; [200, {}, ['pass']] }
71
+ add('/').to { |env| [200, {}, ['working']] }
72
+ }
73
+ assert_body 'working', router.call(Rack::MockRequest.env_for('/'))
74
+ end
75
+
76
+ def test_passing_with_cascade
77
+ passed, working = router {
78
+ add('/').to { |env| [200, {'X-Cascade' => 'pass'}, ['pass']] }
79
+ add('/').to { |env| [200, {}, ['working']] }
80
+ }
81
+ assert_body 'working', router.call(Rack::MockRequest.env_for('/'))
82
+ end
83
+
84
+ def test_request_mutation
85
+ got_this_far = false
86
+ non_matching, matching = router {
87
+ add("/test/:var/:var2/*glob").matching(:var2 => /123/, :glob => /[a-z]+/).get.arbitrary{|env, params| got_this_far = true; false}
88
+ add("/test/:var/:var2/*glob").matching(:var2 => /123/, :glob => /[a-z]+/).get
89
+ }
90
+ assert_route matching, '/test/123/123/asd/aasd/zxcqwe/asdzxc', {:var => '123', :var2 => '123', :glob => %w{asd aasd zxcqwe asdzxc}}
91
+ assert got_this_far, "matching should have gotten this far"
92
+ end
93
+ end
metadata CHANGED
@@ -1,13 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: http_router
3
3
  version: !ruby/object:Gem::Version
4
- hash: 43
5
4
  prerelease:
6
- segments:
7
- - 0
8
- - 8
9
- - 10
10
- version: 0.8.10
5
+ version: 0.8.11
11
6
  platform: ruby
12
7
  authors:
13
8
  - Joshua Hull
@@ -15,7 +10,7 @@ autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
12
 
18
- date: 2011-06-23 00:00:00 -07:00
13
+ date: 2011-07-05 00:00:00 -07:00
19
14
  default_executable:
20
15
  dependencies:
21
16
  - !ruby/object:Gem::Dependency
@@ -26,11 +21,6 @@ dependencies:
26
21
  requirements:
27
22
  - - ">="
28
23
  - !ruby/object:Gem::Version
29
- hash: 23
30
- segments:
31
- - 1
32
- - 0
33
- - 0
34
24
  version: 1.0.0
35
25
  type: :runtime
36
26
  version_requirements: *id001
@@ -42,11 +32,6 @@ dependencies:
42
32
  requirements:
43
33
  - - ~>
44
34
  - !ruby/object:Gem::Version
45
- hash: 21
46
- segments:
47
- - 0
48
- - 2
49
- - 1
50
35
  version: 0.2.1
51
36
  type: :runtime
52
37
  version_requirements: *id002
@@ -58,11 +43,6 @@ dependencies:
58
43
  requirements:
59
44
  - - ~>
60
45
  - !ruby/object:Gem::Version
61
- hash: 15
62
- segments:
63
- - 2
64
- - 0
65
- - 0
66
46
  version: 2.0.0
67
47
  type: :development
68
48
  version_requirements: *id003
@@ -74,9 +54,6 @@ dependencies:
74
54
  requirements:
75
55
  - - ">="
76
56
  - !ruby/object:Gem::Version
77
- hash: 3
78
- segments:
79
- - 0
80
57
  version: "0"
81
58
  type: :development
82
59
  version_requirements: *id004
@@ -88,11 +65,6 @@ dependencies:
88
65
  requirements:
89
66
  - - ~>
90
67
  - !ruby/object:Gem::Version
91
- hash: 49
92
- segments:
93
- - 0
94
- - 8
95
- - 7
96
68
  version: 0.8.7
97
69
  type: :development
98
70
  version_requirements: *id005
@@ -104,58 +76,53 @@ dependencies:
104
76
  requirements:
105
77
  - - ">="
106
78
  - !ruby/object:Gem::Version
107
- hash: 3
108
- segments:
109
- - 0
110
79
  version: "0"
111
80
  type: :development
112
81
  version_requirements: *id006
113
82
  - !ruby/object:Gem::Dependency
114
- name: phocus
83
+ name: json
115
84
  prerelease: false
116
85
  requirement: &id007 !ruby/object:Gem::Requirement
117
86
  none: false
118
87
  requirements:
119
88
  - - ">="
120
89
  - !ruby/object:Gem::Version
121
- hash: 3
122
- segments:
123
- - 0
124
90
  version: "0"
125
91
  type: :development
126
92
  version_requirements: *id007
127
93
  - !ruby/object:Gem::Dependency
128
- name: bundler
94
+ name: phocus
129
95
  prerelease: false
130
96
  requirement: &id008 !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: "0"
102
+ type: :development
103
+ version_requirements: *id008
104
+ - !ruby/object:Gem::Dependency
105
+ name: bundler
106
+ prerelease: false
107
+ requirement: &id009 !ruby/object:Gem::Requirement
131
108
  none: false
132
109
  requirements:
133
110
  - - ~>
134
111
  - !ruby/object:Gem::Version
135
- hash: 23
136
- segments:
137
- - 1
138
- - 0
139
- - 0
140
112
  version: 1.0.0
141
113
  type: :development
142
- version_requirements: *id008
114
+ version_requirements: *id009
143
115
  - !ruby/object:Gem::Dependency
144
116
  name: thin
145
117
  prerelease: false
146
- requirement: &id009 !ruby/object:Gem::Requirement
118
+ requirement: &id010 !ruby/object:Gem::Requirement
147
119
  none: false
148
120
  requirements:
149
121
  - - "="
150
122
  - !ruby/object:Gem::Version
151
- hash: 15
152
- segments:
153
- - 1
154
- - 2
155
- - 8
156
123
  version: 1.2.8
157
124
  type: :development
158
- version_requirements: *id009
125
+ version_requirements: *id010
159
126
  description: This library allows you to recognize and build URLs in a Rack application.
160
127
  email: joshbuddy@gmail.com
161
128
  executables: []
@@ -211,18 +178,16 @@ files:
211
178
  - lib/http_router/response.rb
212
179
  - lib/http_router/route.rb
213
180
  - lib/http_router/version.rb
181
+ - test/common/generate.txt
182
+ - test/common/recognize.txt
183
+ - test/generation.rb
214
184
  - test/helper.rb
215
185
  - test/rack/test_route.rb
216
- - test/test_arbitrary.rb
217
- - test/test_generate.rb
218
- - test/test_greedy.rb
219
- - test/test_interstitial.rb
186
+ - test/recognition.rb
220
187
  - test/test_misc.rb
221
188
  - test/test_mounting.rb
222
- - test/test_recognize.rb
223
- - test/test_request.rb
189
+ - test/test_recognition.rb
224
190
  - test/test_trailing_slash.rb
225
- - test/test_variable.rb
226
191
  has_rdoc: true
227
192
  homepage: http://github.com/joshbuddy/http_router
228
193
  licenses: []
@@ -237,18 +202,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
237
202
  requirements:
238
203
  - - ">="
239
204
  - !ruby/object:Gem::Version
240
- hash: 3
241
- segments:
242
- - 0
243
205
  version: "0"
244
206
  required_rubygems_version: !ruby/object:Gem::Requirement
245
207
  none: false
246
208
  requirements:
247
209
  - - ">="
248
210
  - !ruby/object:Gem::Version
249
- hash: 3
250
- segments:
251
- - 0
252
211
  version: "0"
253
212
  requirements: []
254
213
 
@@ -1,110 +0,0 @@
1
- # encoding: utf-8
2
- class TestGenerate < MiniTest::Unit::TestCase
3
-
4
- def test_static
5
- router {
6
- add('/').name(:a)
7
- add('/test').name(:b)
8
- add('/test/time').name(:c)
9
- add('/one/more/what').name(:d)
10
- add('/test.html').name(:e)
11
- }
12
- assert_generate '/', :a
13
- assert_generate '/test', :b
14
- assert_generate '/test/time', :c
15
- assert_generate '/one/more/what', :d
16
- assert_generate '/test.html', :e
17
- end
18
-
19
- def test_dynamic
20
- assert_generate '/test', '/:var', :var => 'test'
21
- assert_generate '/test', '/:var', 'test'
22
- end
23
-
24
- def test_array_with_extras
25
- assert_generate '/test?query=string', '/:var', :var => 'test', :query => 'string'
26
- assert_generate '/test?query=string', '/:var', 'test', :query => 'string'
27
- end
28
-
29
- def test_multiple_dynamics
30
- assert_generate '/one/two', "/:var/:baz", :var => 'one', :baz => 'two'
31
- assert_generate '/one/two', "/:var/:baz", 'one', 'two'
32
- end
33
-
34
- def test_extension
35
- assert_generate '/test.html', "/test.:format", :format => 'html'
36
- assert_generate '/test.html', "/test.:format", 'html'
37
- end
38
-
39
- def test_optional_extension
40
- assert_generate '/test.html', "/test(.:format)", :format => 'html'
41
- assert_generate '/test.html', "/test(.:format)", 'html'
42
- assert_generate '/test', "/test(.:format)"
43
- end
44
-
45
- def test_variable_with_extension
46
- assert_generate '/test.html', "/:var.:format", :var => 'test', :format => 'html'
47
- assert_generate '/test.html', "/:var.:format", 'test', 'html'
48
- end
49
-
50
- def test_variable_with_optional_extension
51
- assert_generate '/test.html', "/:var(.:format)", :var => 'test', :format => 'html'
52
- assert_generate '/test.html', "/:var(.:format)", 'test', 'html'
53
- assert_generate '/test', "/:var(.:format)", :var => 'test'
54
- assert_generate '/test', "/:var(.:format)", 'test'
55
- end
56
-
57
- def test_optionals
58
- assert_generate '/var', "/:var1(/:var2)", 'var'
59
- assert_generate '/var/fooz', "/:var1(/:var2)", 'var', 'fooz'
60
- assert_generate '/var', "/:var1(/:var2)", :var1 => 'var'
61
- assert_generate '/var/fooz', "/:var1(/:var2)", :var1 => 'var', :var2 => 'fooz'
62
- assert_raises(HttpRouter::InvalidRouteException) { router.url(router.add("/:var1(/:var2)").to(:test), :var2 => 'fooz') }
63
- end
64
-
65
- def test_optionals_with_format
66
- assert_generate '/var', "/:var1(/:var2.:format)", 'var'
67
- assert_generate '/var/fooz.html', "/:var1(/:var2.:format)", 'var', 'fooz', 'html'
68
- assert_generate '/var', "/:var1(/:var2.:format)", :var1 => 'var'
69
- assert_generate '/var/fooz.html', "/:var1(/:var2.:format)", :var1 => 'var', :var2 => 'fooz', :format => 'html'
70
- end
71
-
72
- def test_nested_optionals
73
- assert_generate '/var', "/:var1(/:var2(/:var3))", 'var'
74
- assert_generate '/var/fooz', "/:var1(/:var2(/:var3))", 'var', 'fooz'
75
- assert_generate '/var/fooz/baz', "/:var1(/:var2(/:var3))", 'var', 'fooz', 'baz'
76
- assert_generate '/var', "/:var1(/:var2(/:var3))", :var1 => 'var'
77
- assert_generate '/var/fooz', "/:var1(/:var2(/:var3))", :var1 => 'var', :var2 => 'fooz'
78
- assert_generate '/var/fooz/baz', "/:var1(/:var2(/:var3))", :var1 => 'var', :var2 => 'fooz', :var3 => 'baz'
79
- end
80
-
81
- def test_default_value
82
- assert_generate "/123?page=1", router.add("/:var").default(:page => 1), 123
83
- assert_generate "/1/123", router.add("/:page/:entry").default(:page => 1), :entry => '123'
84
- end
85
-
86
- def test_nil_values
87
- assert_generate '/url', "/url(/:var)", :var => nil
88
- end
89
-
90
- def test_unicode
91
- assert_generate '/%C3%A4', "/:var", :var => 'ä'
92
- end
93
-
94
- def test_raise
95
- r = router { add(':var').matching(:var => /\d+/) }
96
- assert_raises(HttpRouter::InvalidRouteException) { router.url(r, 'asd') }
97
- end
98
-
99
- def test_array
100
- assert_generate '/var?foo[]=baz&foo[]=bar', '/var', :foo => ['baz', 'bar']
101
- end
102
-
103
- def test_hash
104
- assert_generate '/var?foo[az]=baz', '/var', :foo => {:az => 'baz'}
105
- end
106
-
107
- def test_hash_with_array
108
- assert_generate '/var?foo[ar][]=bar', '/var', :foo => {:ar => ['bar']}
109
- end
110
- end