grape-path-helpers 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []