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.
data/README.md CHANGED
@@ -41,10 +41,12 @@ Once you have a route object, use `HttpRouter::Route#to` to add a destination an
41
41
 
42
42
  e.g.
43
43
 
44
+ ```ruby
44
45
  r = HttpRouter.new
45
46
  r.add('/test/:variable(.:format)').name(:my_test_path).to {|env| [200, {}, "Hey dude #{env['router.params'][:variable]}"]}
46
47
  r.add('/test').redirect("http://www.google.com/")
47
48
  r.add('/static').static('/my_file_system')
49
+ ```
48
50
 
49
51
  As well, you can support regex matching and request conditions. To add a regex match, use `matching(:id => /\d+/)`.
50
52
  To match on a request condition you can use `condition(:request_method => %w(POST HEAD))` or more succinctly `request_method('POST', 'HEAD')`.
data/Rakefile CHANGED
@@ -3,7 +3,7 @@ require 'bundler'
3
3
  Bundler::GemHelper.install_tasks
4
4
 
5
5
  desc "Run all tests"
6
- task :test => ['test:integration', 'test:examples', 'test:rdoc_examples']
6
+ task :test => ['test:generation', 'test:recognition', 'test:integration', 'test:examples', 'test:rdoc_examples']
7
7
 
8
8
  require 'pp'
9
9
 
@@ -21,6 +21,21 @@ namespace :test do
21
21
  require './test/helper'
22
22
  Dir['./test/**/test_*.rb'].each { |test| require test }
23
23
  end
24
+
25
+ desc "Run generic recognition tests"
26
+ task :recognition do
27
+ $: << 'lib'
28
+ require 'http_router'
29
+ require './test/recognition'
30
+ end
31
+
32
+ desc "Run generic recognition tests"
33
+ task :generation do
34
+ $: << 'lib'
35
+ require 'http_router'
36
+ require './test/generation'
37
+ end
38
+
24
39
  desc "Run example tests"
25
40
  task :examples do
26
41
  $: << 'lib'
@@ -26,6 +26,7 @@ Gem::Specification.new do |s|
26
26
  s.add_development_dependency 'code_stats'
27
27
  s.add_development_dependency 'rake', '~> 0.8.7'
28
28
  s.add_development_dependency 'rbench'
29
+ s.add_development_dependency 'json'
29
30
  s.add_development_dependency 'phocus'
30
31
  s.add_development_dependency 'bundler', '~> 1.0.0'
31
32
  s.add_development_dependency 'thin', '= 1.2.8'
@@ -202,7 +202,8 @@ class HttpRouter
202
202
 
203
203
  private
204
204
  def no_response(env, perform_call = true)
205
- supported_methods = (@known_methods - [env['REQUEST_METHOD']]).select do |m|
205
+ supported_methods = @known_methods.select do |m|
206
+ next if m == env['REQUEST_METHOD']
206
207
  test_env = ::Rack::Request.new(env.clone)
207
208
  test_env.env['REQUEST_METHOD'] = m
208
209
  test_env.env['_HTTP_ROUTER_405_TESTING_ACCEPTANCE'] = true
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  class HttpRouter #:nodoc
3
- VERSION = '0.8.10'
3
+ VERSION = '0.8.11'
4
4
  end
@@ -0,0 +1,87 @@
1
+ {"a": "/"}
2
+ {"b": "/test"}
3
+ {"c": "/test/time"}
4
+ {"d": "/one/more/what"}
5
+ {"e": "/test.html"}
6
+ ["/", "a"]
7
+ ["/test", "b"]
8
+ ["/test/time", "c"]
9
+ ["/one/more/what", "d"]
10
+ ["/test.html", "e"]
11
+
12
+ {"a": "/:var"}
13
+ ["/test", "a", {"var":"test"}]
14
+ ["/test", "a", ["test"]]
15
+
16
+ {"a": "/:var"}
17
+ ["/test?query=string", "a", {"var":"test", "query": "string"}]
18
+ ["/test?query=string", "a", ["test", {"query": "string"}]]
19
+
20
+ {"a": "/:var/:baz"}
21
+ ["/one/two", "a", {"var":"one", "baz": "two"}]
22
+ ["/one/two", "a", ["one", "two"]]
23
+
24
+ {"a": "/test.:format"}
25
+ ["/test.html", "a", {"format":"html"}]
26
+ ["/test.html", "a", ["html"]]
27
+
28
+ {"a": "/test(.:format)"}
29
+ ["/test.html", "a", {"format":"html"}]
30
+ ["/test.html", "a", ["html"]]
31
+ ["/test", "a"]
32
+
33
+ {"a": "/:var.:format"}
34
+ ["/test.html", "a", {"var": "test", "format":"html"}]
35
+ ["/test.html", "a", ["test", "html"]]
36
+ ["/test.html", "a", ["test", {"format": "html"}]]
37
+ [null, "a", {"format": "html"}]
38
+
39
+ {"a": "/:var(.:format)"}
40
+ ["/test.html", "a", {"var": "test", "format":"html"}]
41
+ ["/test.html", "a", ["test", "html"]]
42
+ ["/test.html", "a", ["test", {"format": "html"}]]
43
+ ["/test", "a", ["test"]]
44
+ ["/test", "a", {"var": "test"}]
45
+ [null, "a", {"format": "html"}]
46
+ [null, "a"]
47
+
48
+ {"a": "/:var1(/:var2)"}
49
+ ["/foo/bar", "a", {"var1": "foo", "var2":"bar"}]
50
+ [null, "a", ["foo", {"var1": "bar"}]]
51
+ ["/foo", "a", {"var1": "foo"}]
52
+ ["/foo", "a", ["foo"]]
53
+ ["/foo", "a", ["foo", null]]
54
+
55
+ {"a": "/:var1(/:var2.:format)"}
56
+ ["/test/test2.html", "a", {"var1": "test", "var2": "test2", "format":"html"}]
57
+ ["/test/test2.html", "a", ["test", "test2", "html"]]
58
+ ["/test", "a", ["test"]]
59
+
60
+ {"a": "/:var1(/:var2(/:var3))"}
61
+ ["/var/fooz/baz", "a", {"var1": "var", "var2":"fooz", "var3": "baz"}]
62
+ ["/var/fooz", "a", {"var1": "var", "var2":"fooz"}]
63
+ ["/var", "a", {"var1": "var"}]
64
+ ["/var/fooz/baz", "a", ["var", "fooz", "baz"]]
65
+ ["/var/fooz", "a", ["var", "fooz"]]
66
+ ["/var", "a", ["var"]]
67
+
68
+ {"a": {"path":"/:var", "default":{"page":1}}}
69
+ ["/123?page=1", "a", [123]]
70
+
71
+ {"a": {"path":"/:page/:entry", "default":{"page":1}}}
72
+ ["/1/123", "a", {"entry": "123"}]
73
+
74
+ {"a": "/:var"}
75
+ ["/%C3%A4", "a", "ä"]
76
+
77
+ {"a": {"path": ":var", "var": {"regex": "\\d+"}}}
78
+ [null, "a", "asd"]
79
+
80
+ {"a": "/var"}
81
+ ["/var?foo%5B%5D=baz&foo%5B%5D=bar", "a", {"foo": ["baz", "bar"]}]
82
+
83
+ {"a": "/var"}
84
+ ["/var?foo%5Baz%5D=baz", "a", {"foo": {"az": "baz"}}]
85
+
86
+ {"a": "/var"}
87
+ ["/var?foo%5Baz%5D%5B%5D=baz", "a", {"foo": {"az": ["baz"]}}]
@@ -0,0 +1,263 @@
1
+ {"route": ":one"}
2
+ ["route", "/two", {"one": "two"}]
3
+
4
+ {"route": "test/:one"}
5
+ ["route", "/test/three", {"one": "three"}]
6
+
7
+ {"static": "one"}
8
+ {"dynamic": ":one"}
9
+ ["dynamic", "/two", {"one": "two"}]
10
+ ["static", "/one"]
11
+
12
+ [{"variable": ":var/one"}, {"static": "one"}]
13
+ ["variable", "/two/one", {"var": "two"}]
14
+ ["static", "/one"]
15
+ [null, "/two"]
16
+
17
+ [{"dynamic": "/foo/:id"}, {"static": "/foo"}]
18
+ ["dynamic", "/foo/id", {"id": "id"}]
19
+ ["static", "/foo"]
20
+
21
+ [{"static": "/foo/foo"}, {"dynamic": "/:foo/foo2"}]
22
+ ["dynamic", "/foo/foo2", {"foo": "foo"}]
23
+ ["static", "/foo/foo"]
24
+
25
+ [{"route": ":var"}]
26
+ ["route", "/%E6%AE%BA%E3%81%99", {"var": "殺す"}]
27
+
28
+ [{"route": {"path":{"regex": "/(test123|\\d+)"}}}]
29
+ ["route", "/test123"]
30
+ ["route", "/123"]
31
+ [null, "/test123andmore"]
32
+ [null, "/lesstest123"]
33
+
34
+ [{"route": "/test.:format"}]
35
+ ["route", "/test.html", {"format": "html"}]
36
+
37
+ [{"route": "/test(.:format)"}]
38
+ ["route", "/test.html", {"format": "html"}]
39
+ ["route", "/test"]
40
+
41
+ [{"route": "(.:format)"}]
42
+ ["route", "/.html", {"format": "html"}]
43
+ ["route", "/"]
44
+
45
+ [{"route": "/:test.:format"}]
46
+ ["route", "/foo.bar", {"format": "bar", "test": "foo"}]
47
+
48
+ [{"route": "/:test(.:format)"}]
49
+ ["route", "/foo", {"test": "foo"}]
50
+ ["route", "/foo.bar", {"format": "bar", "test": "foo"}]
51
+
52
+ [{"route": {"path": "/:test(.:format)", "format": {"regex": "[^\\.]+"}}}]
53
+ ["route", "/asd@asd.com.json", {"test": "asd@asd.com", "format": "json"}]
54
+
55
+ [{"route": "/test/*variable"}]
56
+ ["route", "/test/one/two/three", {"variable": ["one", "two", "three"]}]
57
+
58
+ [{"route": "test/*variable/test"}]
59
+ [null, "/test/one/two/three"]
60
+ ["route", "/test/one/two/three/test", {"variable": ["one", "two", "three"]}]
61
+
62
+ [{"route": "test/*variable/test/*variable2"}]
63
+ [null, "/test/one/two/three"]
64
+ ["route", "/test/one/two/three/test/four/five/six", {"variable": ["one", "two", "three"], "variable2": ["four", "five", "six"]}]
65
+
66
+ [{"route": "/test/:test-*variable.:format"}]
67
+ ["route", "/test/one-two/three/four/five.six", {"test": "one", "variable": ["two", "three", "four", "five"], "format": "six"}]
68
+
69
+ [{"route": {"path": "test/*variable", "variable": {"regex": "[a-z]+"}}}]
70
+ [null, "/test/asd/123"]
71
+ [null, "/test/asd/asd123"]
72
+ ["route", "/test/asd/qwe", {"variable": ["asd", "qwe"]}]
73
+
74
+ [{"route": {"path": "test/*variable/test", "variable": {"regex": "[a-z]+"}}}]
75
+ [null, "/test/asd/123"]
76
+ [null, "/test/asd/asd123"]
77
+ [null, "/test/asd/qwe"]
78
+ ["route", "/test/asd/qwe/test", {"variable": ["asd", "qwe"]}]
79
+
80
+ [{"route": {"path": "test/*variable/:test", "variable": {"regex": "[a-z]+"}}}]
81
+ ["route", "/test/asd/qwe/help", {"variable": ["asd", "qwe"], "test": "help"}]
82
+
83
+ [{"route": {"path": "test/*variable.:format"}}]
84
+ ["route", "/test/asd/qwe.html", {"variable": ["asd", "qwe"], "format": "html"}]
85
+
86
+ [{"route": {"path": "test/*variable.:format", "variable": {"regex": "[a-z]+"}}}]
87
+ [null, "/test/asd/123"]
88
+ [null, "/test/asd/asd123"]
89
+ [null, "/test/asd/qwe"]
90
+ ["route", "/test/asd/qwe.html", {"variable": ["asd", "qwe"], "format": "html"}]
91
+
92
+
93
+ [{"route": {"path": "test/*variable(.:format)", "variable": {"regex": "[a-z]+"}}}]
94
+ [null, "/test/asd/123"]
95
+ [null, "/test/asd/asd123"]
96
+ ["route", "/test/asd/qwe", {"variable": ["asd", "qwe"]}]
97
+ ["route", "/test/asd/qwe.html", {"variable": ["asd", "qwe"], "format": "html"}]
98
+
99
+ [{"route": {"path": "test/*variable.html"}}]
100
+ [null, "/test/asd/123"]
101
+ ["route", "/test/asd/qwe.html", {"variable": ["asd", "qwe"]}]
102
+
103
+ [{"with_regex": {"path": "/:common_variable/:matched", "matched": {"regex": "\\d+"}}}, {"with_post": {"path": "/:common_variable/:matched", "conditions": {"request_method": "POST"}}}, {"without_regex": "/:common_variable/:unmatched"}]
104
+ ["with_regex", "/common/123", {"common_variable": "common", "matched": "123"}]
105
+ ["without_regex", "/common/other", {"common_variable": "common", "unmatched": "other"}]
106
+ ["with_regex", {"path": "/common/123", "method": "POST"}, {"common_variable": "common", "matched": "123"}]
107
+ ["with_post", {"path": "/common/other", "method": "POST"}, {"common_variable": "common", "matched": "other"}]
108
+
109
+ [{"regex": {"path":":test/number", "test": {"regex": "\\d+"}}}, {"greedy": ":test/anything"}]
110
+ ["regex", "/123/number", {"test": "123"}]
111
+ ["greedy", "/123/anything", {"test": "123"}]
112
+
113
+ [{"route": {"path": ":test", "test": {"regex": ".*"}}}]
114
+ ["route", "/test/", {"test": "test/"}]
115
+
116
+ [{"route": {"path": "/:test", "test": {"regex": ".*"}}}]
117
+ ["route", "/test.html", {"test": "test.html"}]
118
+
119
+ [{"route": {"path": ":test", "test": {"regex": "\\d+"}}}]
120
+ ["route", "/123", {"test": "123"}]
121
+ [null, "/a123"]
122
+
123
+ [{"route": ""}]
124
+ ["route", "/"]
125
+ ["route", ""]
126
+
127
+ [{"route": "/"}]
128
+ ["route", "/"]
129
+
130
+ [{"route": "/test"}]
131
+ ["route", "/test"]
132
+
133
+ [{"route": "/test/one"}]
134
+ ["route", "/test/one"]
135
+
136
+ [{"route": "/test/one/two"}]
137
+ ["route", "/test/one/two"]
138
+
139
+ [{"route": "/test.html"}]
140
+ ["route", "/test.html"]
141
+
142
+ [{"route": ".html"}]
143
+ ["route", "/.html"]
144
+
145
+ [{"route": "one(/two(/three(/four)(/five)))"}]
146
+ ["route", "/one"]
147
+ ["route", "/one/two"]
148
+ ["route", "/one/two/three"]
149
+ ["route", "/one/two/three/four"]
150
+ ["route", "/one/two/three/five"]
151
+ ["route", "/one/two/three/four/five"]
152
+ [null, "/one/two/four/five"]
153
+
154
+ [{"route": "test\\(:variable\\)"}]
155
+ ["route", "/test(hello)", {"variable": "hello"}]
156
+
157
+ [{"route": "test\\:variable"}]
158
+ ["route", "/test:variable"]
159
+
160
+ [{"route": "test\\*variable"}]
161
+ ["route", "/test*variable"]
162
+
163
+ [{"route": "/føø"}]
164
+ ["route", "/f%C3%B8%C3%B8"]
165
+
166
+ [{"route": "/test*"}]
167
+ ["route", "/test/optional", {"PATH_INFO": "/optional"}]
168
+ ["route", "/test", {"PATH_INFO": "/"}]
169
+
170
+ [{"route": "/*"}]
171
+ ["route", "/optional", {"PATH_INFO": "/optional"}]
172
+ ["route", "/", {"PATH_INFO": "/"}]
173
+
174
+ [{"test": "/test*"}, {"root": "/*"}]
175
+ ["test", "/test/optional", {"PATH_INFO": "/optional"}]
176
+ ["test", "/test/optional/", {"PATH_INFO": "/optional/"}]
177
+ ["root", "/testing/optional", {"PATH_INFO": "/testing/optional"}]
178
+
179
+ [{"route": "/one-:variable-time"}]
180
+ ["route", "one-value-time", {"variable": "value"}]
181
+
182
+ [{"route": {"path": "/one-:variable-time", "variable": {"regex": "\\d+"}}}]
183
+ ["route", "one-123-time", {"variable": "123"}]
184
+ [null, "one-value-time"]
185
+
186
+ [{"route": {"path": "/one-:variable-time", "variable": {"regex": "\\d+"}}}]
187
+ ["route", "one-123-time", {"variable": "123"}]
188
+ [null, "one-value-time"]
189
+
190
+ [{"route": "hey.:greed.html"}]
191
+ ["route", "/hey.greedybody.html", {"greed": "greedybody"}]
192
+
193
+ [{"r6": "/:v1-:v2-:v3-:v4-:v5-:v6"}, {"r5": "/:v1-:v2-:v3-:v4-:v5"}, {"r4": "/:v1-:v2-:v3-:v4"}, {"r3": "/:v1-:v2-:v3"}, {"r2": "/:v1-:v2"}, {"r1":"/:v1"}]
194
+ ["r1", "/one", {"v1": "one"}]
195
+ ["r2", "/one-two", {"v1": "one", "v2": "two"}]
196
+ ["r3", "/one-two-three", {"v1": "one", "v2":"two", "v3":"three"}]
197
+ ["r4", "/one-two-three-four", {"v1": "one", "v2":"two", "v3":"three", "v4":"four"}]
198
+ ["r5", "/one-two-three-four-five", {"v1": "one", "v2":"two", "v3":"three", "v4":"four", "v5":"five"}]
199
+ ["r6", "/one-two-three-four-five-six", {"v1": "one", "v2":"two", "v3":"three", "v4":"four", "v5":"five", "v6":"six"}]
200
+
201
+ {"with_regex": {"path": "/:common_variable.:matched", "matched": {"regex": "\\d+"}}}
202
+ {"without_regex": "/:common_variable.:unmatched"}
203
+ ["with_regex", "/common.123", {"common_variable": "common", "matched": "123"}]
204
+ ["without_regex", "/common.other", {"common_variable": "common", "unmatched": "other"}]
205
+
206
+ {"nothing":{"path":"/", "conditions": {"request_method": "GET"}}}
207
+ {"post":{"path":"/test", "conditions": {"request_method": "POST"}}}
208
+ {"put":{"path":"/test", "conditions": {"request_method": "PUT"}}}
209
+ ["post", {"path": "/test", "method": "POST"}]
210
+ [[405, {"Allow": "POST, PUT"}], {"path": "/test", "method": "GET"}]
211
+
212
+ {"router": {"path": "/test", "conditions": {"request_method": ["POST", "GET"]}}}
213
+ ["router", {"path": "/test", "method": "POST"}]
214
+ ["router", {"path": "/test", "method": "GET"}]
215
+ [[405, {"Allow": "GET, POST"}], {"path": "/test", "method": "PUT"}]
216
+
217
+ {"get": {"path": "/test(.:format)", "conditions": {"request_method": "GET"}}}
218
+ {"post": {"path": "/test(.:format)", "conditions": {"request_method": "POST"}}}
219
+ {"delete": {"path": "/test(.:format)", "conditions": {"request_method": "DELETE"}}}
220
+ ["get", {"path": "/test", "method": "GET"}]
221
+ ["post", {"path": "/test", "method": "POST"}]
222
+ ["delete", {"path": "/test", "method": "DELETE"}]
223
+ ["get", {"path": "/test.html", "method": "GET"}, {"format": "html"}]
224
+ ["post", {"path": "/test.html", "method": "POST"}, {"format": "html"}]
225
+ ["delete", {"path": "/test.html", "method": "DELETE"}, {"format": "html"}]
226
+ [[405, {"Allow": "DELETE, GET, POST"}], {"path": "/test", "method": "PUT"}]
227
+
228
+ {"post": {"path": "/test", "conditions": {"request_method": "POST"}}}
229
+ {"post_2": {"path": "/test/post", "conditions": {"request_method": "POST"}}}
230
+ {"get": {"path": "/test", "conditions": {"request_method": "GET"}}}
231
+ {"get_2": {"path": "/test/post", "conditions": {"request_method": "GET"}}}
232
+ {"any_2": "/test/post"}
233
+ {"any": "/test"}
234
+ ["post", {"path": "/test", "method": "POST"}]
235
+ ["get", {"path": "/test", "method": "GET"}]
236
+ ["any", {"path": "/test", "method": "PUT"}]
237
+ ["post_2", {"path": "/test/post", "method": "POST"}]
238
+ ["get_2", {"path": "/test/post", "method": "GET"}]
239
+ ["any_2", {"path": "/test/post", "method": "PUT"}]
240
+
241
+ {"post": {"path": "/test", "conditions": {"request_method": "POST"}}}
242
+ {"any": "/test"}
243
+ ["post", {"path": "/test", "method": "POST"}]
244
+ ["any", {"path": "/test", "method": "PUT"}]
245
+
246
+ {"host2_post": {"path": "/test", "conditions": {"request_method": "POST", "host": "host2"}}}
247
+ {"host2_get": {"path": "/test", "conditions": {"request_method": "GET", "host": "host2"}}}
248
+ {"host2": {"path": "/test", "conditions": {"host": "host2"}}}
249
+ {"post": {"path": "/test", "conditions": {"request_method": "POST"}}}
250
+ ["host2", {"path": "http://host2/test", "method": "PUT"}]
251
+ ["post", {"path": "http://host1/test", "method": "POST"}]
252
+ ["host2_get", {"path": "http://host2/test", "method": "GET"}]
253
+ ["host2_post", {"path": "http://host2/test", "method": "POST"}]
254
+
255
+ {"with": {"path": "/test", "conditions": {"request_method": "GET", "host": {"regex": "host1"}}}}
256
+ {"without": {"path": "/test", "conditions": {"request_method": "GET"}}}
257
+ ["without", "http://host2/test"]
258
+ ["with", "http://host2.host1.com/test"]
259
+
260
+ {"http": {"path": "/test", "conditions": {"scheme": "http"}}}
261
+ {"https": {"path": "/test", "conditions": {"scheme": "https"}}}
262
+ ["http", {"path": "/test", "scheme": "http"}]
263
+ ["https", {"path": "/test", "scheme": "https"}]
@@ -0,0 +1,119 @@
1
+ require 'json'
2
+
3
+ generation_file = "#{File.dirname(__FILE__)}/common/generate.txt"
4
+ generation = File.read(generation_file)
5
+
6
+ class GenerationTest
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
+ if route_properties.key?("default")
63
+ opts[:default_values] = Hash[route_properties.delete("default").map{|k, v| [k.to_sym, interpret_val(v)]}]
64
+ end
65
+ route_properties.each do |key, val|
66
+ opts[key.to_sym] = interpret_val(val)
67
+ end
68
+ router.add(route_path, opts)
69
+ else
70
+ error("Route isn't a String or hash")
71
+ end
72
+ route.name(route_name.to_sym)
73
+ route.to{|env| [200, {"env-to-test" => env.dup}, [route_name]]}
74
+ end
75
+ @tests.map(&:case).each do |(expected_result, name, args)|
76
+ args = [args] unless args.is_a?(Array)
77
+ args.compact!
78
+ args.map!{|a| a.is_a?(Hash) ? Hash[a.map{|k,v| [k.to_sym, v]}] : a }
79
+ result = begin
80
+ router.url(name.to_sym, *args)
81
+ rescue HttpRouter::InvalidRouteException
82
+ nil
83
+ rescue HttpRouter::MissingParameterException
84
+ nil
85
+ end
86
+ error("Result #{result.inspect} did not match expectation #{expected_result.inspect}") unless result == expected_result
87
+ end
88
+ print '.'
89
+ end
90
+ end
91
+
92
+ tests = []
93
+ test = nil
94
+ num = 0
95
+ generation.each_line do |line|
96
+ begin
97
+ case line
98
+ when /^#/, /^\s*$/
99
+ # skip
100
+ when /^( |\t)/
101
+ test.add_test(line, num)
102
+ else
103
+ if test.nil? || !test.tests.empty?
104
+ tests << test if test
105
+ test = GenerationTest.new(generation_file)
106
+ end
107
+ test.add_routes(line, num)
108
+ end
109
+ rescue
110
+ warn "There was a problem with #{num}:#{line}"
111
+ raise
112
+ end
113
+ num += 1
114
+ end
115
+ tests << test
116
+
117
+ puts "Running generation tests (Routes: #{tests.size}, Tests: #{tests.inject(0){|s, t| s+=t.tests.size}})..."
118
+ tests.each(&:invoke)
119
+ puts "\ndone!"