grape-path-helpers 1.0.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 +7 -0
- data/.gitignore +3 -0
- data/.gitlab-ci.yml +18 -0
- data/.rubocop.yml +10 -0
- data/.travis.yml +18 -0
- data/CHANGELOG.md +42 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +99 -0
- data/LICENSE.txt +22 -0
- data/README.md +172 -0
- data/Rakefile +17 -0
- data/grape-path-helpers.gemspec +21 -0
- data/lib/grape-path-helpers.rb +16 -0
- data/lib/grape-path-helpers/all_routes.rb +18 -0
- data/lib/grape-path-helpers/decorated_route.rb +168 -0
- data/lib/grape-path-helpers/named_route_matcher.rb +36 -0
- data/lib/grape-path-helpers/railtie.rb +9 -0
- data/lib/grape-path-helpers/route_displayer.rb +31 -0
- data/lib/grape-path-helpers/tasks.rb +1 -0
- data/lib/grape-path-helpers/version.rb +4 -0
- data/lib/grape/path_helpers.rb +1 -0
- data/lib/tasks/grape_path_helpers.rake +6 -0
- data/spec/grape_path_helpers/all_routes_spec.rb +37 -0
- data/spec/grape_path_helpers/decorated_route_spec.rb +241 -0
- data/spec/grape_path_helpers/named_route_matcher_spec.rb +173 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/support/api.rb +77 -0
- metadata +154 -0
@@ -0,0 +1,173 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# rubocop:disable Metrics/BlockLength
|
4
|
+
describe GrapePathHelpers::NamedRouteMatcher do
|
5
|
+
include described_class
|
6
|
+
|
7
|
+
let(:routes) do
|
8
|
+
Grape::API.decorated_routes
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:ping_route) do
|
12
|
+
routes.detect do |route|
|
13
|
+
route.route_path =~ /ping/ && route.route_version == 'v1'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:index_route) do
|
18
|
+
routes.detect do |route|
|
19
|
+
route.route_namespace =~ /cats$/
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
let(:show_route) do
|
24
|
+
routes.detect do |route|
|
25
|
+
route.route_namespace =~ %r{cats/:id}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#route_match?' do
|
30
|
+
context 'when route responds to a method name' do
|
31
|
+
let(:route) { ping_route }
|
32
|
+
let(:method_name) { :api_v1_ping_path }
|
33
|
+
let(:segments) { {} }
|
34
|
+
|
35
|
+
context 'when segments is not a hash' do
|
36
|
+
it 'raises an ArgumentError' do
|
37
|
+
expect do
|
38
|
+
route_match?(route, method_name, 1234)
|
39
|
+
end.to raise_error(ArgumentError)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'returns true' do
|
44
|
+
is_match = route_match?(route, method_name, segments)
|
45
|
+
expect(is_match).to eq(true)
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'when requested segments contains expected options' do
|
49
|
+
let(:segments) { { 'format' => 'xml' } }
|
50
|
+
|
51
|
+
it 'returns true' do
|
52
|
+
is_match = route_match?(route, method_name, segments)
|
53
|
+
expect(is_match).to eq(true)
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'when no dynamic segments are requested' do
|
57
|
+
context 'when the route requires dynamic segments' do
|
58
|
+
let(:route) { show_route }
|
59
|
+
let(:method_name) { :ap1_v1_cats_path }
|
60
|
+
|
61
|
+
it 'returns false' do
|
62
|
+
is_match = route_match?(route, method_name, segments)
|
63
|
+
expect(is_match).to eq(false)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'when the route does not require dynamic segments' do
|
68
|
+
it 'returns true' do
|
69
|
+
is_match = route_match?(route, method_name, segments)
|
70
|
+
expect(is_match).to eq(true)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'when route requires the requested segments' do
|
76
|
+
let(:route) { show_route }
|
77
|
+
let(:method_name) { :api_v1_cats_path }
|
78
|
+
let(:segments) { { id: 1 } }
|
79
|
+
|
80
|
+
it 'returns true' do
|
81
|
+
is_match = route_match?(route, method_name, segments)
|
82
|
+
expect(is_match).to eq(true)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'when route does not require the requested segments' do
|
87
|
+
let(:segments) { { some_option: 'some value' } }
|
88
|
+
|
89
|
+
it 'returns false' do
|
90
|
+
is_match = route_match?(route, method_name, segments)
|
91
|
+
expect(is_match).to eq(false)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'when segments contains unexpected options' do
|
97
|
+
let(:segments) { { some_option: 'some value' } }
|
98
|
+
|
99
|
+
it 'returns false' do
|
100
|
+
is_match = route_match?(route, method_name, segments)
|
101
|
+
expect(is_match).to eq(false)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context 'when route does not respond to a method name' do
|
107
|
+
let(:method_name) { :some_other_path }
|
108
|
+
let(:route) { ping_route }
|
109
|
+
let(:segments) { {} }
|
110
|
+
|
111
|
+
it 'returns false' do
|
112
|
+
is_match = route_match?(route, method_name, segments)
|
113
|
+
expect(is_match).to eq(false)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe '#method_missing' do
|
119
|
+
context 'when method name matches a Grape::Route path helper name' do
|
120
|
+
it 'returns the path for that route object' do
|
121
|
+
path = api_v1_ping_path
|
122
|
+
expect(path).to eq('/api/v1/ping.json')
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'when argument to the helper is not a hash' do
|
126
|
+
it 'raises an ArgumentError' do
|
127
|
+
expect do
|
128
|
+
api_v1_ping_path(1234)
|
129
|
+
end.to raise_error(ArgumentError)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
context 'when method name does not match a Grape::Route path helper name' do
|
135
|
+
it 'raises a NameError' do
|
136
|
+
expect do
|
137
|
+
some_method_name
|
138
|
+
end.to raise_error(NameError)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
context 'when Grape::Route objects share the same helper name' do
|
144
|
+
context 'when helpers require different segments to generate their path' do
|
145
|
+
it 'uses arguments to infer which route to use' do
|
146
|
+
show_path = api_v1_cats_path('id' => 1)
|
147
|
+
expect(show_path).to eq('/api/v1/cats/1.json')
|
148
|
+
|
149
|
+
index_path = api_v1_cats_path
|
150
|
+
expect(index_path).to eq('/api/v1/cats.json')
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'does not get shadowed by another route with less segments' do
|
154
|
+
show_path = api_v1_cats_owners_path('id' => 1)
|
155
|
+
expect(show_path).to eq('/api/v1/cats/1/owners.json')
|
156
|
+
|
157
|
+
show_path = api_v1_cats_owners_path('id' => 1, 'owner_id' => 1)
|
158
|
+
expect(show_path).to eq('/api/v1/cats/1/owners/1.json')
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context 'when query params are passed in' do
|
163
|
+
it 'uses arguments to infer which route to use' do
|
164
|
+
show_path = api_v1_cats_path('id' => 1, params: { 'foo' => 'bar' })
|
165
|
+
expect(show_path).to eq('/api/v1/cats/1.json?foo=bar')
|
166
|
+
|
167
|
+
index_path = api_v1_cats_path(params: { 'foo' => 'bar' })
|
168
|
+
expect(index_path).to eq('/api/v1/cats.json?foo=bar')
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
# rubocop:enable Metrics/BlockLength
|
data/spec/spec_helper.rb
ADDED
data/spec/support/api.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
module Spec
|
2
|
+
module Support
|
3
|
+
# Test API
|
4
|
+
class API < Grape::API
|
5
|
+
version 'v1'
|
6
|
+
prefix 'api'
|
7
|
+
format 'json'
|
8
|
+
|
9
|
+
get 'custom_name', as: :my_custom_route_name do
|
10
|
+
'hello'
|
11
|
+
end
|
12
|
+
|
13
|
+
get 'ping' do
|
14
|
+
'pong'
|
15
|
+
end
|
16
|
+
|
17
|
+
resource :cats do
|
18
|
+
get '/' do
|
19
|
+
%w[cats cats cats]
|
20
|
+
end
|
21
|
+
|
22
|
+
route_param :id do
|
23
|
+
get do
|
24
|
+
'cat'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
get ':id/owners' do
|
29
|
+
%w[owner1 owner2]
|
30
|
+
end
|
31
|
+
|
32
|
+
get ':id/owners/:owner_id' do
|
33
|
+
'owner'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
route :any, '*path' do
|
38
|
+
'catch-all route'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# API with more than one version
|
43
|
+
class APIWithMultipleVersions < Grape::API
|
44
|
+
version %w[beta alpha v1]
|
45
|
+
|
46
|
+
get 'ping' do
|
47
|
+
'pong'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# API with another API mounted inside it
|
52
|
+
class MountedAPI < Grape::API
|
53
|
+
mount Spec::Support::API
|
54
|
+
mount Spec::Support::APIWithMultipleVersions
|
55
|
+
end
|
56
|
+
|
57
|
+
# API with a version that would be illegal as a method name
|
58
|
+
class APIWithIllegalVersion < Grape::API
|
59
|
+
version 'beta-1'
|
60
|
+
|
61
|
+
get 'ping' do
|
62
|
+
'pong'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# API with multiple POST routes
|
67
|
+
class MultiplePostsAPI < Grape::API
|
68
|
+
resource :hamlet do
|
69
|
+
post 'to_be' do
|
70
|
+
end
|
71
|
+
|
72
|
+
post 'or_not_to_be' do
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
metadata
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: grape-path-helpers
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Drew Blessing
|
8
|
+
- Harper Henn
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2018-05-30 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: grape
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '1.0'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '1.0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rake
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :runtime
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: pry
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: rspec
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: rubocop
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
description: Route path helpers for Grape
|
99
|
+
email: ''
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- ".gitignore"
|
105
|
+
- ".gitlab-ci.yml"
|
106
|
+
- ".rubocop.yml"
|
107
|
+
- ".travis.yml"
|
108
|
+
- CHANGELOG.md
|
109
|
+
- Gemfile
|
110
|
+
- Gemfile.lock
|
111
|
+
- LICENSE.txt
|
112
|
+
- README.md
|
113
|
+
- Rakefile
|
114
|
+
- grape-path-helpers.gemspec
|
115
|
+
- lib/grape-path-helpers.rb
|
116
|
+
- lib/grape-path-helpers/all_routes.rb
|
117
|
+
- lib/grape-path-helpers/decorated_route.rb
|
118
|
+
- lib/grape-path-helpers/named_route_matcher.rb
|
119
|
+
- lib/grape-path-helpers/railtie.rb
|
120
|
+
- lib/grape-path-helpers/route_displayer.rb
|
121
|
+
- lib/grape-path-helpers/tasks.rb
|
122
|
+
- lib/grape-path-helpers/version.rb
|
123
|
+
- lib/grape/path_helpers.rb
|
124
|
+
- lib/tasks/grape_path_helpers.rake
|
125
|
+
- spec/grape_path_helpers/all_routes_spec.rb
|
126
|
+
- spec/grape_path_helpers/decorated_route_spec.rb
|
127
|
+
- spec/grape_path_helpers/named_route_matcher_spec.rb
|
128
|
+
- spec/spec_helper.rb
|
129
|
+
- spec/support/api.rb
|
130
|
+
homepage: https://github.com/gitlab/grape-path-helpers
|
131
|
+
licenses:
|
132
|
+
- MIT
|
133
|
+
metadata: {}
|
134
|
+
post_install_message:
|
135
|
+
rdoc_options: []
|
136
|
+
require_paths:
|
137
|
+
- lib
|
138
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
139
|
+
requirements:
|
140
|
+
- - ">="
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
143
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
144
|
+
requirements:
|
145
|
+
- - ">="
|
146
|
+
- !ruby/object:Gem::Version
|
147
|
+
version: '0'
|
148
|
+
requirements: []
|
149
|
+
rubyforge_project:
|
150
|
+
rubygems_version: 2.5.2.2
|
151
|
+
signing_key:
|
152
|
+
specification_version: 4
|
153
|
+
summary: Route path helpers for Grape
|
154
|
+
test_files: []
|