lotus-router 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +45 -0
- data/{LICENSE.txt → LICENSE.md} +0 -0
- data/README.md +33 -9
- data/lib/lotus/router.rb +98 -0
- data/lib/lotus/router/version.rb +1 -1
- data/lib/lotus/routing/endpoint.rb +1 -1
- data/lib/lotus/routing/endpoint_resolver.rb +23 -3
- data/lib/lotus/routing/http_router.rb +12 -0
- data/lib/lotus/routing/resource/options.rb +27 -2
- data/lotus-router.gemspec +1 -1
- metadata +6 -46
- data/.coveralls.yml +0 -2
- data/.gitignore +0 -9
- data/.travis.yml +0 -5
- data/.yardopts +0 -3
- data/Gemfile +0 -11
- data/Rakefile +0 -10
- data/benchmarks/callable +0 -23
- data/benchmarks/named_routes +0 -72
- data/benchmarks/resource +0 -44
- data/benchmarks/resources +0 -58
- data/benchmarks/routes +0 -67
- data/benchmarks/run.sh +0 -11
- data/benchmarks/utils.rb +0 -56
- data/test/fixtures.rb +0 -193
- data/test/integration/client_error_test.rb +0 -16
- data/test/integration/pass_on_response_test.rb +0 -13
- data/test/named_routes_test.rb +0 -123
- data/test/namespace_test.rb +0 -289
- data/test/new_test.rb +0 -67
- data/test/redirect_test.rb +0 -33
- data/test/resource_test.rb +0 -128
- data/test/resources_test.rb +0 -136
- data/test/routing/endpoint_resolver_test.rb +0 -110
- data/test/routing/resource/options_test.rb +0 -36
- data/test/routing_test.rb +0 -99
- data/test/test_helper.rb +0 -32
- data/test/version_test.rb +0 -7
data/test/redirect_test.rb
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
describe Lotus::Router do
|
4
|
-
before do
|
5
|
-
@router = Lotus::Router.new
|
6
|
-
end
|
7
|
-
|
8
|
-
describe '#redirect' do
|
9
|
-
it 'recognizes string endpoint' do
|
10
|
-
endpoint = ->(env) { [200, {}, ['Redirect destination!']] }
|
11
|
-
@router.get('/redirect_destination', to: endpoint)
|
12
|
-
@router.redirect('/redirect', to: '/redirect_destination')
|
13
|
-
|
14
|
-
env = Rack::MockRequest.env_for('/redirect')
|
15
|
-
status, headers, _ = @router.call(env)
|
16
|
-
|
17
|
-
status.must_equal 302
|
18
|
-
headers['Location'].must_equal '/redirect_destination'
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'recognizes string endpoint with custom http code' do
|
22
|
-
endpoint = ->(env) { [200, {}, ['Redirect destination!']] }
|
23
|
-
@router.get('/redirect_destination', to: endpoint)
|
24
|
-
@router.redirect('/redirect', to: '/redirect_destination', code: 301)
|
25
|
-
|
26
|
-
env = Rack::MockRequest.env_for('/redirect')
|
27
|
-
status, headers, _ = @router.call(env)
|
28
|
-
|
29
|
-
status.must_equal 301
|
30
|
-
headers['Location'].must_equal '/redirect_destination'
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
data/test/resource_test.rb
DELETED
@@ -1,128 +0,0 @@
|
|
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 '#resource' do
|
18
|
-
before do
|
19
|
-
@router.resource 'avatar'
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'recognizes get new' do
|
23
|
-
@router.path(:new_avatar).must_equal '/avatar/new'
|
24
|
-
@app.request('GET', '/avatar/new').body.must_equal 'Avatar::New'
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'recognizes post create' do
|
28
|
-
@router.path(:avatar).must_equal '/avatar'
|
29
|
-
@app.request('POST', '/avatar').body.must_equal 'Avatar::Create'
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'recognizes get show' do
|
33
|
-
@router.path(:avatar).must_equal '/avatar'
|
34
|
-
@app.request('GET', '/avatar').body.must_equal 'Avatar::Show'
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'recognizes get edit' do
|
38
|
-
@router.path(:edit_avatar).must_equal '/avatar/edit'
|
39
|
-
@app.request('GET', '/avatar/edit').body.must_equal 'Avatar::Edit'
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'recognizes patch update' do
|
43
|
-
@router.path(:avatar).must_equal '/avatar'
|
44
|
-
@app.request('PATCH', '/avatar').body.must_equal 'Avatar::Update'
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'recognizes delete destroy' do
|
48
|
-
@router.path(:avatar).must_equal '/avatar'
|
49
|
-
@app.request('DELETE', '/avatar').body.must_equal 'Avatar::Destroy'
|
50
|
-
end
|
51
|
-
|
52
|
-
describe ':only option' do
|
53
|
-
before do
|
54
|
-
@router.resource 'profile', only: [:edit, :update]
|
55
|
-
end
|
56
|
-
|
57
|
-
it 'recognizes only specified paths' do
|
58
|
-
@router.path(:edit_profile).must_equal '/profile/edit'
|
59
|
-
@app.request('GET', '/profile/edit').body.must_equal 'Profile::Edit'
|
60
|
-
|
61
|
-
@router.path(:profile).must_equal '/profile'
|
62
|
-
@app.request('PATCH', '/profile').body.must_equal 'Profile::Update'
|
63
|
-
end
|
64
|
-
|
65
|
-
it 'does not recognize other paths' do
|
66
|
-
@app.request('GET', '/profile/new').status.must_equal 405
|
67
|
-
@app.request('POST', '/profile').status.must_equal 405
|
68
|
-
@app.request('GET', '/profile').status.must_equal 405
|
69
|
-
@app.request('DELETE', '/profile').status.must_equal 405
|
70
|
-
|
71
|
-
-> { @router.path(:new_profile) }.must_raise HttpRouter::InvalidRouteException
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
describe ':except option' do
|
76
|
-
before do
|
77
|
-
@router.resource 'profile', except: [:new, :show, :create, :destroy]
|
78
|
-
end
|
79
|
-
|
80
|
-
it 'recognizes only the non-rejected paths' do
|
81
|
-
@router.path(:edit_profile).must_equal '/profile/edit'
|
82
|
-
@app.request('GET', '/profile/edit').body.must_equal 'Profile::Edit'
|
83
|
-
|
84
|
-
@router.path(:profile).must_equal '/profile'
|
85
|
-
@app.request('PATCH', '/profile').body.must_equal 'Profile::Update'
|
86
|
-
end
|
87
|
-
|
88
|
-
it 'does not recognize other paths' do
|
89
|
-
@app.request('GET', '/profile/new').status.must_equal 405
|
90
|
-
@app.request('POST', '/profile').status.must_equal 405
|
91
|
-
@app.request('GET', '/profile').status.must_equal 405
|
92
|
-
@app.request('DELETE', '/profile').status.must_equal 405
|
93
|
-
|
94
|
-
-> { @router.path(:new_profile) }.must_raise HttpRouter::InvalidRouteException
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
describe 'member' do
|
99
|
-
before do
|
100
|
-
@router.resource 'profile', only: [] do
|
101
|
-
member do
|
102
|
-
patch 'activate'
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
it 'recognizes the path' do
|
108
|
-
@router.path(:activate_profile).must_equal '/profile/activate'
|
109
|
-
@app.request('PATCH', '/profile/activate').body.must_equal 'Profile::Activate'
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
describe 'collection' do
|
114
|
-
before do
|
115
|
-
@router.resource 'profile', only: [] do
|
116
|
-
collection do
|
117
|
-
get 'keys'
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
it 'recognizes the path' do
|
123
|
-
@router.path(:keys_profile).must_equal '/profile/keys'
|
124
|
-
@app.request('GET', '/profile/keys').body.must_equal 'Profile::Keys'
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
data/test/resources_test.rb
DELETED
@@ -1,136 +0,0 @@
|
|
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 '#resources' do
|
18
|
-
before do
|
19
|
-
@router.resources 'flowers'
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'recognizes get index' do
|
23
|
-
@router.path(:flowers).must_equal '/flowers'
|
24
|
-
@app.request('GET', '/flowers').body.must_equal 'Flowers::Index'
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'recognizes get new' do
|
28
|
-
@router.path(:new_flowers).must_equal '/flowers/new'
|
29
|
-
@app.request('GET', '/flowers/new').body.must_equal 'Flowers::New'
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'recognizes post create' do
|
33
|
-
@router.path(:flowers).must_equal '/flowers'
|
34
|
-
@app.request('POST', '/flowers').body.must_equal 'Flowers::Create'
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'recognizes get show' do
|
38
|
-
@router.path(:flowers, id: 23).must_equal '/flowers/23'
|
39
|
-
@app.request('GET', '/flowers/23').body.must_equal 'Flowers::Show 23'
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'recognizes get edit' do
|
43
|
-
@router.path(:edit_flowers, id: 23).must_equal '/flowers/23/edit'
|
44
|
-
@app.request('GET', '/flowers/23/edit').body.must_equal 'Flowers::Edit 23'
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'recognizes patch update' do
|
48
|
-
@router.path(:flowers, id: 23).must_equal '/flowers/23'
|
49
|
-
@app.request('PATCH', '/flowers/23').body.must_equal 'Flowers::Update 23'
|
50
|
-
end
|
51
|
-
|
52
|
-
it 'recognizes delete destroy' do
|
53
|
-
@router.path(:flowers, id: 23).must_equal '/flowers/23'
|
54
|
-
@app.request('DELETE', '/flowers/23').body.must_equal 'Flowers::Destroy 23'
|
55
|
-
end
|
56
|
-
|
57
|
-
describe ':only option' do
|
58
|
-
before do
|
59
|
-
@router.resources 'keyboards', only: [:index, :edit]
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'recognizes only specified paths' do
|
63
|
-
@router.path(:keyboards).must_equal '/keyboards'
|
64
|
-
@app.request('GET', '/keyboards').body.must_equal 'Keyboards::Index'
|
65
|
-
|
66
|
-
@router.path(:edit_keyboards, id: 23).must_equal '/keyboards/23/edit'
|
67
|
-
@app.request('GET', '/keyboards/23/edit').body.must_equal 'Keyboards::Edit 23'
|
68
|
-
end
|
69
|
-
|
70
|
-
it 'does not recognize other paths' do
|
71
|
-
@app.request('GET', '/keyboards/new').status.must_equal 404
|
72
|
-
@app.request('POST', '/keyboards').status.must_equal 405
|
73
|
-
@app.request('GET', '/keyboards/23').status.must_equal 404
|
74
|
-
@app.request('PATCH', '/keyboards/23').status.must_equal 405
|
75
|
-
@app.request('DELETE', '/keyboards/23').status.must_equal 405
|
76
|
-
|
77
|
-
-> { @router.path(:new_keyboards) }.must_raise HttpRouter::InvalidRouteException
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
describe ':except option' do
|
82
|
-
before do
|
83
|
-
@router.resources 'keyboards', except: [:new, :show, :update, :destroy]
|
84
|
-
end
|
85
|
-
|
86
|
-
it 'recognizes only the non-rejected paths' do
|
87
|
-
@router.path(:keyboards).must_equal '/keyboards'
|
88
|
-
@app.request('GET', '/keyboards').body.must_equal 'Keyboards::Index'
|
89
|
-
|
90
|
-
@router.path(:edit_keyboards, id: 23).must_equal '/keyboards/23/edit'
|
91
|
-
@app.request('GET', '/keyboards/23/edit').body.must_equal 'Keyboards::Edit 23'
|
92
|
-
|
93
|
-
@router.path(:keyboards).must_equal '/keyboards'
|
94
|
-
@app.request('POST', '/keyboards').body.must_equal 'Keyboards::Create'
|
95
|
-
end
|
96
|
-
|
97
|
-
it 'does not recognize other paths' do
|
98
|
-
@app.request('GET', '/keyboards/new').status.must_equal 404
|
99
|
-
@app.request('PATCH', '/keyboards/23').status.must_equal 405
|
100
|
-
@app.request('DELETE', '/keyboards/23').status.must_equal 405
|
101
|
-
|
102
|
-
-> { @router.path(:new_keyboards) }.must_raise HttpRouter::InvalidRouteException
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
describe 'member' do
|
107
|
-
before do
|
108
|
-
@router.resources 'keyboards', only: [] do
|
109
|
-
member do
|
110
|
-
get 'screenshot'
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
it 'recognizes the path' do
|
116
|
-
@router.path(:screenshot_keyboards, id: 23).must_equal '/keyboards/23/screenshot'
|
117
|
-
@app.request('GET', '/keyboards/23/screenshot').body.must_equal 'Keyboards::Screenshot 23'
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
describe 'collection' do
|
122
|
-
before do
|
123
|
-
@router.resources 'keyboards', only: [] do
|
124
|
-
collection do
|
125
|
-
get 'search'
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
it 'recognizes the path' do
|
131
|
-
@router.path(:search_keyboards).must_equal '/keyboards/search'
|
132
|
-
@app.request('GET', '/keyboards/search').body.must_equal 'Keyboards::Search'
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|
@@ -1,110 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
describe Lotus::Routing::EndpointResolver do
|
4
|
-
before do
|
5
|
-
@resolver = Lotus::Routing::EndpointResolver.new
|
6
|
-
end
|
7
|
-
|
8
|
-
it 'recognizes :to when it is a callable object' do
|
9
|
-
endpoint = Object.new
|
10
|
-
endpoint.define_singleton_method(:call) { }
|
11
|
-
|
12
|
-
options = { to: endpoint }
|
13
|
-
|
14
|
-
@resolver.resolve(options).must_equal(endpoint)
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'recognizes :to when it is a string that references a class that can be retrieved now' do
|
18
|
-
options = { to: 'test_endpoint' }
|
19
|
-
@resolver.resolve(options).call({}).must_equal 'Hi from TestEndpoint!'
|
20
|
-
end
|
21
|
-
|
22
|
-
describe 'when :to references a missing class' do
|
23
|
-
it 'if the class is available when invoking call, it succeed' do
|
24
|
-
options = { to: 'lazy_controller' }
|
25
|
-
endpoint = @resolver.resolve(options)
|
26
|
-
LazyController = Class.new(Object) { define_method(:call) {|env| env } }
|
27
|
-
|
28
|
-
endpoint.call({}).must_equal({})
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'if the class is not available when invoking call, it raises error' do
|
32
|
-
options = { to: 'missing_endpoint' }
|
33
|
-
endpoint = @resolver.resolve(options)
|
34
|
-
|
35
|
-
-> { endpoint.call({}) }.must_raise Lotus::Routing::EndpointNotFound
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'recognizes :to when it is a string with separator' do
|
40
|
-
options = { to: 'test#show' }
|
41
|
-
@resolver.resolve(options).call({}).must_equal 'Hi from Test::Show!'
|
42
|
-
end
|
43
|
-
|
44
|
-
it 'returns the default endpoint when cannot match anything' do
|
45
|
-
options = { to: 23 }
|
46
|
-
@resolver.resolve(options).call({}).first.must_equal 404
|
47
|
-
end
|
48
|
-
|
49
|
-
describe 'namespace' do
|
50
|
-
before do
|
51
|
-
@resolver = Lotus::Routing::EndpointResolver.new(namespace: TestApp)
|
52
|
-
end
|
53
|
-
|
54
|
-
it 'recognizes :to when it is a string and an explicit namespace' do
|
55
|
-
options = { to: 'test_endpoint' }
|
56
|
-
@resolver.resolve(options).call({}).must_equal 'Hi from TestApp::TestEndpoint!'
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'recognizes :to when it is a string with separator and it has an explicit namespace' do
|
60
|
-
options = { to: 'test2#show' }
|
61
|
-
@resolver.resolve(options).call({}).must_equal 'Hi from TestApp::Test2Controller::Show!'
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
describe 'custom endpoint' do
|
66
|
-
before :all do
|
67
|
-
class CustomEndpoint
|
68
|
-
def initialize(endpoint)
|
69
|
-
@endpoint = endpoint
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
@resolver = Lotus::Routing::EndpointResolver.new(endpoint: CustomEndpoint)
|
74
|
-
end
|
75
|
-
|
76
|
-
after do
|
77
|
-
Object.send(:remove_const, :CustomEndpoint)
|
78
|
-
end
|
79
|
-
|
80
|
-
it 'returns specified endpoint instance' do
|
81
|
-
@resolver.resolve({}).class.must_equal(CustomEndpoint)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
describe 'custom separator' do
|
86
|
-
before do
|
87
|
-
@resolver = Lotus::Routing::EndpointResolver.new(action_separator: action_separator)
|
88
|
-
end
|
89
|
-
|
90
|
-
let(:action_separator) { '@' }
|
91
|
-
|
92
|
-
it 'matches controller and action with a custom separator' do
|
93
|
-
options = { to: "test#{ action_separator }show" }
|
94
|
-
@resolver.resolve(options).call({}).must_equal 'Hi from Test::Show!'
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
describe 'custom suffix' do
|
99
|
-
before do
|
100
|
-
@resolver = Lotus::Routing::EndpointResolver.new(suffix: suffix)
|
101
|
-
end
|
102
|
-
|
103
|
-
let(:suffix) { 'Controller::' }
|
104
|
-
|
105
|
-
it 'matches controller and action with a custom separator' do
|
106
|
-
options = { to: 'test#show' }
|
107
|
-
@resolver.resolve(options).call({}).must_equal 'Hi from Test::Show!'
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
describe Lotus::Routing::Resource::Options do
|
4
|
-
before do
|
5
|
-
@actions = [:index, :new, :create, :show, :edit, :update, :destroy]
|
6
|
-
end
|
7
|
-
|
8
|
-
it 'returns all the actions when no exceptions are requested' do
|
9
|
-
Lotus::Routing::Resources::Options.new(@actions).actions.must_equal @actions
|
10
|
-
end
|
11
|
-
|
12
|
-
it 'returns only the action requested via the :only option' do
|
13
|
-
options = Lotus::Routing::Resources::Options.new(@actions, only: :show)
|
14
|
-
options.actions.must_equal [:show]
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'returns only the actions requested via the :only options' do
|
18
|
-
options = Lotus::Routing::Resources::Options.new(@actions, only: [:create, :edit])
|
19
|
-
options.actions.must_equal [:create, :edit]
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'returns only the action not rejected via the :except option' do
|
23
|
-
options = Lotus::Routing::Resources::Options.new(@actions, except: :destroy)
|
24
|
-
options.actions.must_equal [:index, :new, :create, :show, :edit, :update]
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'returns only the actions requested via the :only options' do
|
28
|
-
options = Lotus::Routing::Resources::Options.new(@actions, except: [:index, :new, :edit])
|
29
|
-
options.actions.must_equal [:create, :show, :update, :destroy]
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'allow access to values' do
|
33
|
-
options = Lotus::Routing::Resources::Options.new(@actions, name: :lotus)
|
34
|
-
options[:name].must_equal :lotus
|
35
|
-
end
|
36
|
-
end
|