http_router 0.8.10 → 0.8.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -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