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.
@@ -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
@@ -0,0 +1,7 @@
1
+ $LOAD_PATH.unshift File.expand_path('lib')
2
+
3
+ require 'pry'
4
+ require 'grape/path_helpers'
5
+
6
+ support_files = Dir.glob('spec/support/*')
7
+ support_files.each { |f| require File.expand_path(f) }
@@ -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: []