lotus-router 0.0.0 → 0.1.0
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.
- checksums.yaml +4 -4
- data/.coveralls.yml +2 -0
- data/.gitignore +5 -13
- data/.travis.yml +5 -0
- data/.yardopts +3 -0
- data/Gemfile +10 -3
- data/README.md +470 -6
- data/Rakefile +10 -1
- data/benchmarks/callable +23 -0
- data/benchmarks/named_routes +72 -0
- data/benchmarks/resource +44 -0
- data/benchmarks/resources +58 -0
- data/benchmarks/routes +67 -0
- data/benchmarks/run.sh +11 -0
- data/benchmarks/utils.rb +56 -0
- data/lib/lotus-router.rb +1 -0
- data/lib/lotus/router.rb +752 -3
- data/lib/lotus/router/version.rb +2 -2
- data/lib/lotus/routing/endpoint.rb +114 -0
- data/lib/lotus/routing/endpoint_resolver.rb +251 -0
- data/lib/lotus/routing/http_router.rb +130 -0
- data/lib/lotus/routing/namespace.rb +86 -0
- data/lib/lotus/routing/resource.rb +73 -0
- data/lib/lotus/routing/resource/action.rb +340 -0
- data/lib/lotus/routing/resource/options.rb +48 -0
- data/lib/lotus/routing/resources.rb +40 -0
- data/lib/lotus/routing/resources/action.rb +123 -0
- data/lib/lotus/routing/route.rb +53 -0
- data/lotus-router.gemspec +16 -12
- data/test/fixtures.rb +193 -0
- data/test/integration/client_error_test.rb +16 -0
- data/test/integration/pass_on_response_test.rb +13 -0
- data/test/named_routes_test.rb +123 -0
- data/test/namespace_test.rb +289 -0
- data/test/new_test.rb +67 -0
- data/test/redirect_test.rb +33 -0
- data/test/resource_test.rb +128 -0
- data/test/resources_test.rb +136 -0
- data/test/routing/endpoint_resolver_test.rb +110 -0
- data/test/routing/resource/options_test.rb +36 -0
- data/test/routing_test.rb +99 -0
- data/test/test_helper.rb +32 -0
- data/test/version_test.rb +7 -0
- metadata +102 -10
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Lotus::Router do
|
4
|
+
before do
|
5
|
+
@router = Lotus::Router.new { get '/', to: ->(env) {} }
|
6
|
+
@app = Rack::MockRequest.new(@router)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'returns 404 for unknown path' do
|
10
|
+
@app.get('/unknown').status.must_equal 404
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'returns 405 for unacceptable HTTP method' do
|
14
|
+
@app.post('/').status.must_equal 405
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe 'Pass on response' do
|
4
|
+
before do
|
5
|
+
@routes = Lotus::Router.new { get '/', to: ->(env) { Rack::Response.new } }
|
6
|
+
@app = Rack::MockRequest.new(@routes)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'is successful' do
|
10
|
+
response = @app.get('/')
|
11
|
+
response.status.must_equal 200
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
describe Lotus::Router do
|
2
|
+
before do
|
3
|
+
@router = Lotus::Router.new(scheme: 'https', host: 'test.com', port: 443)
|
4
|
+
|
5
|
+
@router.get('/lotus', to: endpoint, as: :fixed)
|
6
|
+
@router.get('/flowers/:id', to: endpoint, as: :variables)
|
7
|
+
@router.get('/books/:id', id: /\d+/, to: endpoint, as: :constraints)
|
8
|
+
@router.get('/articles(.:format)', to: endpoint, as: :optional)
|
9
|
+
@router.get('/files/*', to: endpoint, as: :glob)
|
10
|
+
end
|
11
|
+
|
12
|
+
after do
|
13
|
+
@router.reset!
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:endpoint) { ->(env) { [200, {}, ['Hi!']] } }
|
17
|
+
|
18
|
+
describe '#path' do
|
19
|
+
it 'recognizes fixed string' do
|
20
|
+
@router.path(:fixed).must_equal '/lotus'
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'recognizes string with variables' do
|
24
|
+
@router.path(:variables, id: 'lotus').must_equal '/flowers/lotus'
|
25
|
+
end
|
26
|
+
|
27
|
+
it "raises error when variables aren't satisfied" do
|
28
|
+
-> {
|
29
|
+
@router.path(:variables)
|
30
|
+
}.must_raise(Lotus::Routing::InvalidRouteException)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'recognizes string with variables and constraints' do
|
34
|
+
@router.path(:constraints, id: 23).must_equal '/books/23'
|
35
|
+
end
|
36
|
+
|
37
|
+
it "raises error when constraints aren't satisfied" do
|
38
|
+
-> {
|
39
|
+
@router.path(:constraints, id: 'x')
|
40
|
+
}.must_raise(Lotus::Routing::InvalidRouteException)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'recognizes optional variables' do
|
44
|
+
@router.path(:optional).must_equal '/articles'
|
45
|
+
@router.path(:optional, page: '1').must_equal '/articles?page=1'
|
46
|
+
@router.path(:optional, format: 'rss').must_equal '/articles.rss'
|
47
|
+
@router.path(:optional, format: 'rss', page: '1').must_equal '/articles.rss?page=1'
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'recognizes glob string' do
|
51
|
+
@router.path(:glob).must_equal '/files/'
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'escapes additional params in query string' do
|
55
|
+
@router.path(:fixed, return_to: '/dashboard').must_equal '/lotus?return_to=%2Fdashboard'
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'raises error when insufficient params are passed' do
|
59
|
+
-> {
|
60
|
+
@router.path(nil)
|
61
|
+
}.must_raise(Lotus::Routing::InvalidRouteException)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'raises error when too many params are passed' do
|
65
|
+
-> {
|
66
|
+
@router.path(:fixed, 'x')
|
67
|
+
}.must_raise(Lotus::Routing::InvalidRouteException)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '#url' do
|
72
|
+
it 'recognizes fixed string' do
|
73
|
+
@router.url(:fixed).must_equal 'https://test.com/lotus'
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'recognizes string with variables' do
|
77
|
+
@router.url(:variables, id: 'lotus').must_equal 'https://test.com/flowers/lotus'
|
78
|
+
end
|
79
|
+
|
80
|
+
it "raises error when variables aren't satisfied" do
|
81
|
+
-> {
|
82
|
+
@router.url(:variables)
|
83
|
+
}.must_raise(Lotus::Routing::InvalidRouteException)
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'recognizes string with variables and constraints' do
|
87
|
+
@router.url(:constraints, id: 23).must_equal 'https://test.com/books/23'
|
88
|
+
end
|
89
|
+
|
90
|
+
it "raises error when constraints aren't satisfied" do
|
91
|
+
-> {
|
92
|
+
@router.url(:constraints, id: 'x')
|
93
|
+
}.must_raise(Lotus::Routing::InvalidRouteException)
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'recognizes optional variables' do
|
97
|
+
@router.url(:optional).must_equal 'https://test.com/articles'
|
98
|
+
@router.url(:optional, page: '1').must_equal 'https://test.com/articles?page=1'
|
99
|
+
@router.url(:optional, format: 'rss').must_equal 'https://test.com/articles.rss'
|
100
|
+
@router.url(:optional, format: 'rss', page: '1').must_equal 'https://test.com/articles.rss?page=1'
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'recognizes glob string' do
|
104
|
+
@router.url(:glob).must_equal 'https://test.com/files/'
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'escapes additional params in query string' do
|
108
|
+
@router.url(:fixed, return_to: '/dashboard').must_equal 'https://test.com/lotus?return_to=%2Fdashboard'
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'raises error when insufficient params are passed' do
|
112
|
+
-> {
|
113
|
+
@router.url(nil)
|
114
|
+
}.must_raise(Lotus::Routing::InvalidRouteException)
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'raises error when too many params are passed' do
|
118
|
+
-> {
|
119
|
+
@router.url(:fixed, 'x')
|
120
|
+
}.must_raise(Lotus::Routing::InvalidRouteException)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,289 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Lotus::Router do
|
4
|
+
before do
|
5
|
+
@router = Lotus::Router.new
|
6
|
+
@app = Rack::MockRequest.new(@router)
|
7
|
+
end
|
8
|
+
|
9
|
+
after do
|
10
|
+
@router.reset!
|
11
|
+
end
|
12
|
+
|
13
|
+
def endpoint(response)
|
14
|
+
->(env) { response }
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#namespace' do
|
18
|
+
it 'recognizes get path' do
|
19
|
+
endpoint = endpoint([200, {}, ['Trees (GET)!']])
|
20
|
+
@router.namespace 'trees' do
|
21
|
+
get '/plane-tree', to: endpoint
|
22
|
+
end
|
23
|
+
|
24
|
+
@app.request('GET', '/trees/plane-tree').body.must_equal 'Trees (GET)!'
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'recognizes post path' do
|
28
|
+
endpoint = endpoint([200, {}, ['Trees (POST)!']])
|
29
|
+
@router.namespace 'trees' do
|
30
|
+
post '/sequoia', to: endpoint
|
31
|
+
end
|
32
|
+
|
33
|
+
@app.request('POST', '/trees/sequoia').body.must_equal 'Trees (POST)!'
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'recognizes put path' do
|
37
|
+
endpoint = endpoint([200, {}, ['Trees (PUT)!']])
|
38
|
+
@router.namespace 'trees' do
|
39
|
+
put '/cherry-tree', to: endpoint
|
40
|
+
end
|
41
|
+
|
42
|
+
@app.request('PUT', '/trees/cherry-tree').body.must_equal 'Trees (PUT)!'
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'recognizes patch path' do
|
46
|
+
endpoint = endpoint([200, {}, ['Trees (PATCH)!']])
|
47
|
+
@router.namespace 'trees' do
|
48
|
+
patch '/cedar', to: endpoint
|
49
|
+
end
|
50
|
+
|
51
|
+
@app.request('PATCH', '/trees/cedar').body.must_equal 'Trees (PATCH)!'
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'recognizes delete path' do
|
55
|
+
endpoint = endpoint([200, {}, ['Trees (DELETE)!']])
|
56
|
+
@router.namespace 'trees' do
|
57
|
+
delete '/pine', to: endpoint
|
58
|
+
end
|
59
|
+
|
60
|
+
@app.request('DELETE', '/trees/pine').body.must_equal 'Trees (DELETE)!'
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'recognizes trace path' do
|
64
|
+
endpoint = endpoint([200, {}, ['Trees (TRACE)!']])
|
65
|
+
@router.namespace 'trees' do
|
66
|
+
trace '/cypress', to: endpoint
|
67
|
+
end
|
68
|
+
|
69
|
+
@app.request('TRACE', '/trees/cypress').body.must_equal 'Trees (TRACE)!'
|
70
|
+
end
|
71
|
+
|
72
|
+
describe 'nested' do
|
73
|
+
before do
|
74
|
+
endpoint = endpoint([200, {}, ['Meow!']])
|
75
|
+
@router.namespace 'animals' do
|
76
|
+
namespace 'mammals' do
|
77
|
+
get '/cats', to: endpoint
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'recognizes get path' do
|
83
|
+
@app.request('GET', '/animals/mammals/cats').body.must_equal 'Meow!'
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe 'redirect' do
|
88
|
+
before do
|
89
|
+
endpoint = endpoint([200, {}, ['New Home!']])
|
90
|
+
@router.namespace 'users' do
|
91
|
+
get '/home', to: endpoint
|
92
|
+
redirect '/dashboard', to: '/home'
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'recognizes get path' do
|
97
|
+
@app.request('GET', '/users/dashboard').headers['Location'].must_equal '/users/home'
|
98
|
+
@app.request('GET', '/users/dashboard').status.must_equal 302
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe 'restful resources' do
|
103
|
+
before do
|
104
|
+
@router.namespace 'vegetals' do
|
105
|
+
resources 'flowers'
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'recognizes get index' do
|
110
|
+
@router.path(:vegetals_flowers).must_equal '/vegetals/flowers'
|
111
|
+
@app.request('GET', '/vegetals/flowers').body.must_equal 'Flowers::Index'
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'recognizes get new' do
|
115
|
+
@router.path(:vegetals_new_flowers).must_equal '/vegetals/flowers/new'
|
116
|
+
@app.request('GET', '/vegetals/flowers/new').body.must_equal 'Flowers::New'
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'recognizes post create' do
|
120
|
+
@router.path(:vegetals_flowers).must_equal '/vegetals/flowers'
|
121
|
+
@app.request('POST', '/vegetals/flowers').body.must_equal 'Flowers::Create'
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'recognizes get show' do
|
125
|
+
@router.path(:vegetals_flowers, id: 23).must_equal '/vegetals/flowers/23'
|
126
|
+
@app.request('GET', '/vegetals/flowers/23').body.must_equal 'Flowers::Show 23'
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'recognizes get edit' do
|
130
|
+
@router.path(:vegetals_edit_flowers, id: 23).must_equal '/vegetals/flowers/23/edit'
|
131
|
+
@app.request('GET', '/vegetals/flowers/23/edit').body.must_equal 'Flowers::Edit 23'
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'recognizes patch update' do
|
135
|
+
@router.path(:vegetals_flowers, id: 23).must_equal '/vegetals/flowers/23'
|
136
|
+
@app.request('PATCH', '/vegetals/flowers/23').body.must_equal 'Flowers::Update 23'
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'recognizes delete destroy' do
|
140
|
+
@router.path(:vegetals_flowers, id: 23).must_equal '/vegetals/flowers/23'
|
141
|
+
@app.request('DELETE', '/vegetals/flowers/23').body.must_equal 'Flowers::Destroy 23'
|
142
|
+
end
|
143
|
+
|
144
|
+
describe ':only option' do
|
145
|
+
before do
|
146
|
+
@router.namespace 'electronics' do
|
147
|
+
resources 'keyboards', only: [:index, :edit]
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'recognizes only specified paths' do
|
152
|
+
@router.path(:electronics_keyboards).must_equal '/electronics/keyboards'
|
153
|
+
@app.request('GET', '/electronics/keyboards').body.must_equal 'Keyboards::Index'
|
154
|
+
|
155
|
+
@router.path(:electronics_edit_keyboards, id: 23).must_equal '/electronics/keyboards/23/edit'
|
156
|
+
@app.request('GET', '/electronics/keyboards/23/edit').body.must_equal 'Keyboards::Edit 23'
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'does not recognize other paths' do
|
160
|
+
@app.request('GET', '/electronics/keyboards/new').status.must_equal 404
|
161
|
+
@app.request('POST', '/electronics/keyboards').status.must_equal 405
|
162
|
+
@app.request('GET', '/electronics/keyboards/23').status.must_equal 404
|
163
|
+
@app.request('PATCH', '/electronics/keyboards/23').status.must_equal 405
|
164
|
+
@app.request('DELETE', '/electronics/keyboards/23').status.must_equal 405
|
165
|
+
|
166
|
+
-> { @router.path(:electronics_new_keyboards) }.must_raise HttpRouter::InvalidRouteException
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
describe ':except option' do
|
171
|
+
before do
|
172
|
+
@router.namespace 'electronics' do
|
173
|
+
resources 'keyboards', except: [:new, :show, :update, :destroy]
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'recognizes only the non-rejected paths' do
|
178
|
+
@router.path(:electronics_keyboards).must_equal '/electronics/keyboards'
|
179
|
+
@app.request('GET', '/electronics/keyboards').body.must_equal 'Keyboards::Index'
|
180
|
+
|
181
|
+
@router.path(:electronics_edit_keyboards, id: 23).must_equal '/electronics/keyboards/23/edit'
|
182
|
+
@app.request('GET', '/electronics/keyboards/23/edit').body.must_equal 'Keyboards::Edit 23'
|
183
|
+
|
184
|
+
@router.path(:electronics_keyboards).must_equal '/electronics/keyboards'
|
185
|
+
@app.request('POST', '/electronics/keyboards').body.must_equal 'Keyboards::Create'
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'does not recognize other paths' do
|
189
|
+
@app.request('GET', '/electronics/keyboards/new').status.must_equal 404
|
190
|
+
@app.request('PATCH', '/electronics/keyboards/23').status.must_equal 405
|
191
|
+
@app.request('DELETE', '/electronics/keyboards/23').status.must_equal 405
|
192
|
+
|
193
|
+
-> { @router.path(:electronics_new_keyboards) }.must_raise HttpRouter::InvalidRouteException
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
describe 'restful resource' do
|
199
|
+
before do
|
200
|
+
@router.namespace 'settings' do
|
201
|
+
resource 'avatar'
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'recognizes get new' do
|
206
|
+
@router.path(:settings_new_avatar).must_equal '/settings/avatar/new'
|
207
|
+
@app.request('GET', '/settings/avatar/new').body.must_equal 'Avatar::New'
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'recognizes post create' do
|
211
|
+
@router.path(:settings_avatar).must_equal '/settings/avatar'
|
212
|
+
@app.request('POST', '/settings/avatar').body.must_equal 'Avatar::Create'
|
213
|
+
end
|
214
|
+
|
215
|
+
it 'recognizes get show' do
|
216
|
+
@router.path(:settings_avatar).must_equal '/settings/avatar'
|
217
|
+
@app.request('GET', '/settings/avatar').body.must_equal 'Avatar::Show'
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'recognizes get edit' do
|
221
|
+
@router.path(:settings_edit_avatar).must_equal '/settings/avatar/edit'
|
222
|
+
@app.request('GET', '/settings/avatar/edit').body.must_equal 'Avatar::Edit'
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'recognizes patch update' do
|
226
|
+
@router.path(:settings_avatar).must_equal '/settings/avatar'
|
227
|
+
@app.request('PATCH', '/settings/avatar').body.must_equal 'Avatar::Update'
|
228
|
+
end
|
229
|
+
|
230
|
+
it 'recognizes delete destroy' do
|
231
|
+
@router.path(:settings_avatar).must_equal '/settings/avatar'
|
232
|
+
@app.request('DELETE', '/settings/avatar').body.must_equal 'Avatar::Destroy'
|
233
|
+
end
|
234
|
+
|
235
|
+
describe ':only option' do
|
236
|
+
before do
|
237
|
+
@router.namespace 'settings' do
|
238
|
+
resource 'profile', only: [:edit, :update]
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
it 'recognizes only specified paths' do
|
243
|
+
@router.path(:settings_edit_profile).must_equal '/settings/profile/edit'
|
244
|
+
@app.request('GET', '/settings/profile/edit').body.must_equal 'Profile::Edit'
|
245
|
+
|
246
|
+
@router.path(:settings_profile).must_equal '/settings/profile'
|
247
|
+
@app.request('PATCH', '/settings/profile').body.must_equal 'Profile::Update'
|
248
|
+
end
|
249
|
+
|
250
|
+
it 'does not recognize other paths' do
|
251
|
+
@app.request('GET', '/settings/profile').status.must_equal 405
|
252
|
+
@app.request('GET', '/settings/profile/new').status.must_equal 405
|
253
|
+
@app.request('POST', '/settings/profile').status.must_equal 405
|
254
|
+
@app.request('DELETE', '/settings/profile').status.must_equal 405
|
255
|
+
|
256
|
+
-> { @router.path(:settings_new_profile) }.must_raise HttpRouter::InvalidRouteException
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
describe ':except option' do
|
261
|
+
before do
|
262
|
+
@router.namespace 'settings' do
|
263
|
+
resource 'profile', except: [:edit, :update]
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
it 'recognizes only the non-rejected paths' do
|
268
|
+
@router.path(:settings_profile).must_equal '/settings/profile'
|
269
|
+
@app.request('GET', '/settings/profile').body.must_equal 'Profile::Show'
|
270
|
+
|
271
|
+
@router.path(:settings_new_profile).must_equal '/settings/profile/new'
|
272
|
+
@app.request('GET', '/settings/profile/new').body.must_equal 'Profile::New'
|
273
|
+
|
274
|
+
@router.path(:settings_profile).must_equal '/settings/profile'
|
275
|
+
@app.request('POST', '/settings/profile').body.must_equal 'Profile::Create'
|
276
|
+
|
277
|
+
@router.path(:settings_profile).must_equal '/settings/profile'
|
278
|
+
@app.request('DELETE', '/settings/profile').body.must_equal 'Profile::Destroy'
|
279
|
+
end
|
280
|
+
|
281
|
+
it 'does not recognize other paths' do
|
282
|
+
@app.request('GET', '/settings/profile/edit').status.must_equal 404
|
283
|
+
|
284
|
+
-> { @router.path(:settings_edit_profile) }.must_raise HttpRouter::InvalidRouteException
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
data/test/new_test.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Lotus::Router do
|
4
|
+
describe '.new' do
|
5
|
+
before do
|
6
|
+
class MockRoute
|
7
|
+
end
|
8
|
+
|
9
|
+
endpoint = ->(env) { [200, {}, ['']] }
|
10
|
+
@router = Lotus::Router.new do
|
11
|
+
get '/route', to: endpoint
|
12
|
+
get '/named_route', to: endpoint, as: :named_route
|
13
|
+
resource 'avatar'
|
14
|
+
resources 'flowers'
|
15
|
+
namespace 'admin' do
|
16
|
+
get '/dashboard', to: endpoint
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
@app = Rack::MockRequest.new(@router)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'returns instance of Lotus::Router with empty block' do
|
24
|
+
router = Lotus::Router.new { }
|
25
|
+
router.must_be_instance_of Lotus::Router
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'returns instance of Lotus::Router' do
|
29
|
+
@router.must_be_instance_of Lotus::Router
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'sets options' do
|
33
|
+
router = Lotus::Router.new(scheme: 'https') do
|
34
|
+
get '/', to: ->(env) { }, as: :root
|
35
|
+
end
|
36
|
+
|
37
|
+
router.url(:root).must_match('https')
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'sets custom separator' do
|
41
|
+
router = Lotus::Router.new(action_separator: '^')
|
42
|
+
route = router.get('/', to: 'test^show', as: :root)
|
43
|
+
|
44
|
+
route.dest.must_equal(TestController::Show)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'recognizes path' do
|
48
|
+
@app.get('/route').status.must_equal 200
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'recognizes named path' do
|
52
|
+
@app.get('/named_route').status.must_equal 200
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'recognizes resource' do
|
56
|
+
@app.get('/avatar').status.must_equal 200
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'recognizes resources' do
|
60
|
+
@app.get('/avatar').status.must_equal 200
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'recognizes namespaced path' do
|
64
|
+
@app.get('/admin/dashboard').status.must_equal 200
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|