grape-route-helpers 1.0.1 → 1.2.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/CHANGELOG.md +12 -0
- data/Gemfile.lock +5 -2
- data/README.md +42 -1
- data/lib/grape-route-helpers/all_routes.rb +6 -1
- data/lib/grape-route-helpers/decorated_route.rb +37 -26
- data/lib/grape-route-helpers/route_displayer.rb +2 -0
- data/lib/grape-route-helpers/version.rb +1 -1
- data/spec/grape_route_helpers/all_routes.rb +27 -0
- data/spec/grape_route_helpers/decorated_route_spec.rb +34 -0
- data/spec/grape_route_helpers/named_route_matcher_spec.rb +12 -0
- data/spec/support/route_matcher_helpers.rb +10 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6c89b2de6b727ea2d4e1953bca91338051e68e86
|
4
|
+
data.tar.gz: e2706efbbd654e9b1e19cb9f43fa2dee2e03bd5d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 55a16e85e81fb667b224884f7d54a2e9c833728d62b37862769123e90f2caa4cbd5b123329efe83235c0de6e2b010bea93e8ceba7d6a2152a36b84ad2bb2fb10
|
7
|
+
data.tar.gz: 50d1900fb057a31219f2fe58b7f2aaf683f5ed717391e6bd4428fd766f69925e2433feb1e221a5dc2ff3909a34b381e214a7243f316ce644af2b5c83bd23c6cc
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## September 27 2015
|
4
|
+
|
5
|
+
* Release 1.2.0
|
6
|
+
|
7
|
+
* You can now assign custom helper names to Grape routes
|
8
|
+
* Fixed a bug where routes would be listed more than once in the rake task if they are mounted to another API
|
9
|
+
* Added the HTTP verb to rake task output
|
10
|
+
|
11
|
+
## July 5 2015
|
12
|
+
|
13
|
+
* You can now pass query parameters to helper functions in order to generate your own query string (Issue #1)
|
14
|
+
|
3
15
|
## June 28 2015
|
4
16
|
|
5
17
|
Release 1.0.1
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
grape-route-helpers (1.0
|
4
|
+
grape-route-helpers (1.2.0)
|
5
5
|
activesupport
|
6
6
|
grape
|
7
7
|
rake
|
@@ -46,7 +46,7 @@ GEM
|
|
46
46
|
json (1.8.3)
|
47
47
|
method_source (0.8.2)
|
48
48
|
minitest (5.7.0)
|
49
|
-
multi_json (1.11.
|
49
|
+
multi_json (1.11.2)
|
50
50
|
multi_xml (0.5.5)
|
51
51
|
parser (2.3.0.pre.2)
|
52
52
|
ast (>= 1.1, < 3.0)
|
@@ -100,3 +100,6 @@ DEPENDENCIES
|
|
100
100
|
pry
|
101
101
|
rspec
|
102
102
|
rubocop
|
103
|
+
|
104
|
+
BUNDLED WITH
|
105
|
+
1.10.6
|
data/README.md
CHANGED
@@ -45,14 +45,19 @@ task :environment do
|
|
45
45
|
end
|
46
46
|
```
|
47
47
|
|
48
|
-
### Usage
|
48
|
+
### Usage
|
49
|
+
|
50
|
+
#### List All Helper Names
|
49
51
|
|
50
52
|
To see which methods correspond to which paths, and which options you can pass them:
|
51
53
|
|
52
54
|
```bash
|
55
|
+
# In your API root directory, at the command line
|
53
56
|
$ rake grape:route_helpers
|
54
57
|
```
|
55
58
|
|
59
|
+
#### Use Helpers in Your API
|
60
|
+
|
56
61
|
Use the methods inside your Grape API actions. Given this example API:
|
57
62
|
|
58
63
|
```ruby
|
@@ -92,6 +97,9 @@ api_v1_ping_path # => '/api/v1/ping.json'
|
|
92
97
|
# specifying the format
|
93
98
|
api_v1_cats_path(format: '.xml') # => '/api/v1/cats.xml'
|
94
99
|
|
100
|
+
# adding a query string
|
101
|
+
api_v1_cats_path(params: { sort_by: :age }) # => '/api/v1/cats?sort_by=age'
|
102
|
+
|
95
103
|
# passing in values required to build a path
|
96
104
|
api_v1_cats_path(id: 1) # => '/api/v1/cats/1.json'
|
97
105
|
|
@@ -99,6 +107,39 @@ api_v1_cats_path(id: 1) # => '/api/v1/cats/1.json'
|
|
99
107
|
api_v1_anything_path # => '/api/v1/*anything'
|
100
108
|
```
|
101
109
|
|
110
|
+
#### Custom Helper Names
|
111
|
+
|
112
|
+
If you want to assign a custom helper name to a route, pass the `:as` option when creating your route in your API:
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
class Base < Grape::API
|
116
|
+
get 'ping', as: 'is_the_server_running'
|
117
|
+
'pong'
|
118
|
+
end
|
119
|
+
end
|
120
|
+
```
|
121
|
+
|
122
|
+
This results in creating a helper called `is_the_server_running_path`.
|
123
|
+
|
124
|
+
#### Testing
|
125
|
+
|
126
|
+
You can you the route helpers in our API tests by including the `GrapeRouteHelpers::NamedRouteMatcher` module inside your specs. Here's an example:
|
127
|
+
|
128
|
+
```ruby
|
129
|
+
require 'spec_helper'
|
130
|
+
|
131
|
+
describe Api::Base do
|
132
|
+
include GrapeRouteHelpers::NamedRouteMatcher
|
133
|
+
|
134
|
+
describe 'GET /ping' do
|
135
|
+
it 'returns a 200 OK' do
|
136
|
+
get api_v2_ping_path
|
137
|
+
expect(response.status).to be(200)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
```
|
142
|
+
|
102
143
|
### Contributing
|
103
144
|
|
104
145
|
1.) Fork it
|
@@ -9,7 +9,12 @@ module GrapeRouteHelpers
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def all_routes
|
12
|
-
subclasses.flat_map { |s| s.send(:prepare_routes) }
|
12
|
+
routes = subclasses.flat_map { |s| s.send(:prepare_routes) }
|
13
|
+
# delete duplicate routes
|
14
|
+
routes.delete_if do |route|
|
15
|
+
all_options = routes.map { |r| r.instance_variable_get(:@options) }
|
16
|
+
all_options.count(route.instance_variable_get(:@options)) > 1
|
17
|
+
end
|
13
18
|
end
|
14
19
|
end
|
15
20
|
end
|
@@ -1,10 +1,12 @@
|
|
1
1
|
module GrapeRouteHelpers
|
2
2
|
# wrapper around Grape::Route that adds a helper method
|
3
3
|
class DecoratedRoute
|
4
|
-
attr_reader :route, :helper_names, :helper_arguments,
|
4
|
+
attr_reader :route, :helper_names, :helper_arguments,
|
5
|
+
:extension, :route_options
|
5
6
|
|
6
7
|
def initialize(route)
|
7
8
|
@route = route
|
9
|
+
@route_options = route.instance_variable_get(:@options)
|
8
10
|
@helper_names = []
|
9
11
|
@helper_arguments = required_helper_segments
|
10
12
|
@extension = default_extension
|
@@ -39,15 +41,24 @@ module GrapeRouteHelpers
|
|
39
41
|
#{route_attributes}.merge(attributes)
|
40
42
|
)
|
41
43
|
|
44
|
+
query_params = attrs.delete(:params)
|
42
45
|
content_type = attrs.delete(:format)
|
43
46
|
path = '/' + path_segments_with_values(attrs).join('/')
|
44
47
|
|
45
|
-
path + content_type
|
48
|
+
path + content_type + query_string(query_params)
|
46
49
|
end
|
47
50
|
RUBY
|
48
51
|
instance_eval method_body
|
49
52
|
end
|
50
53
|
|
54
|
+
def query_string(params)
|
55
|
+
if params.nil?
|
56
|
+
''
|
57
|
+
else
|
58
|
+
'?' + params.to_param
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
51
62
|
def route_versions
|
52
63
|
if route_version
|
53
64
|
route_version.split('|')
|
@@ -57,13 +68,18 @@ module GrapeRouteHelpers
|
|
57
68
|
end
|
58
69
|
|
59
70
|
def path_helper_name(opts = {})
|
60
|
-
|
71
|
+
if route.route_as
|
72
|
+
name = route.route_as.to_s
|
73
|
+
else
|
74
|
+
segments = path_segments_with_values(opts)
|
75
|
+
|
76
|
+
name = if segments.empty?
|
77
|
+
'root'
|
78
|
+
else
|
79
|
+
segments.join('_')
|
80
|
+
end
|
81
|
+
end
|
61
82
|
|
62
|
-
name = if segments.empty?
|
63
|
-
'root'
|
64
|
-
else
|
65
|
-
segments.join('_')
|
66
|
-
end
|
67
83
|
name + '_path'
|
68
84
|
end
|
69
85
|
|
@@ -108,39 +124,34 @@ module GrapeRouteHelpers
|
|
108
124
|
dynamic_path_segments - segments_in_options
|
109
125
|
end
|
110
126
|
|
111
|
-
def
|
112
|
-
|
127
|
+
def special_keys
|
128
|
+
%w(format params)
|
113
129
|
end
|
114
130
|
|
115
131
|
def uses_segments_in_path_helper?(segments)
|
116
|
-
|
117
|
-
required = required_helper_segments
|
132
|
+
segments = segments.reject { |x| special_keys.include?(x) }
|
118
133
|
|
119
|
-
if
|
120
|
-
|
134
|
+
if required_helper_segments.empty? && segments.any?
|
135
|
+
false
|
121
136
|
else
|
122
|
-
|
123
|
-
required.include?(segment)
|
124
|
-
end
|
137
|
+
required_helper_segments.all? { |x| segments.include?(x) }
|
125
138
|
end
|
126
139
|
end
|
127
140
|
|
128
|
-
# accessing underlying Grape::Route
|
129
|
-
|
130
141
|
def route_path
|
131
|
-
|
132
|
-
end
|
133
|
-
|
134
|
-
def route_options
|
135
|
-
route.instance_variable_get(:@options)
|
142
|
+
route_options[:path]
|
136
143
|
end
|
137
144
|
|
138
145
|
def route_version
|
139
|
-
|
146
|
+
route_options[:version]
|
140
147
|
end
|
141
148
|
|
142
149
|
def route_namespace
|
143
|
-
|
150
|
+
route_options[:namespace]
|
151
|
+
end
|
152
|
+
|
153
|
+
def route_method
|
154
|
+
route_options[:method]
|
144
155
|
end
|
145
156
|
end
|
146
157
|
end
|
@@ -6,6 +6,7 @@ module GrapeRouteHelpers
|
|
6
6
|
Grape::API.decorated_routes.map do |route|
|
7
7
|
{
|
8
8
|
route_path: route.route_path,
|
9
|
+
route_method: route.route_method,
|
9
10
|
helper_names: route.helper_names,
|
10
11
|
helper_arguments: route.helper_arguments
|
11
12
|
}
|
@@ -15,6 +16,7 @@ module GrapeRouteHelpers
|
|
15
16
|
def display
|
16
17
|
puts("== GRAPE ROUTE HELPERS ==\n\n")
|
17
18
|
route_attributes.each do |attributes|
|
19
|
+
printf("%s: %s\n", 'Verb', attributes[:route_method])
|
18
20
|
printf("%s: %s\n", 'Path', attributes[:route_path])
|
19
21
|
printf("%s: %s\n",
|
20
22
|
'Helper Method',
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe GrapeRouteHelpers::AllRoutes do
|
4
|
+
Grape::API.extend described_class
|
5
|
+
|
6
|
+
describe '#all_routes' do
|
7
|
+
context 'when API is mounted within another API' do
|
8
|
+
let(:mounting_api) { Spec::Support::RouteMatcherHelpers.mounting_api }
|
9
|
+
|
10
|
+
it 'does not include the same route twice' do
|
11
|
+
mounting_api
|
12
|
+
|
13
|
+
# A route is unique if no other route shares the same set of options
|
14
|
+
all_route_options = Grape::API.all_routes.map do |r|
|
15
|
+
r.instance_variable_get(:@options)
|
16
|
+
end
|
17
|
+
|
18
|
+
duplicates = all_route_options.select do |o|
|
19
|
+
all_route_options.count(o) > 1
|
20
|
+
end
|
21
|
+
|
22
|
+
expect(duplicates).to be_empty
|
23
|
+
expect(all_route_options.size).to eq(5)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -21,7 +21,24 @@ describe GrapeRouteHelpers::DecoratedRoute do
|
|
21
21
|
routes.detect { |route| route.route_path =~ /\*/ }
|
22
22
|
end
|
23
23
|
|
24
|
+
let(:custom_route) do
|
25
|
+
routes.detect { |route| route.route_path =~ /custom_name/ }
|
26
|
+
end
|
27
|
+
|
24
28
|
describe '#helper_names' do
|
29
|
+
context 'when a route is given a custom helper name' do
|
30
|
+
it 'uses the custom name instead of the dynamically generated one' do
|
31
|
+
expect(custom_route.helper_names.first)
|
32
|
+
.to eq('my_custom_route_name_path')
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'returns the correct path' do
|
36
|
+
expect(
|
37
|
+
custom_route.my_custom_route_name_path
|
38
|
+
).to eq('/api/v1/custom_name.json')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
25
42
|
context 'when an API has multiple versions' do
|
26
43
|
let(:api_versions) { %w(beta alpha v1) }
|
27
44
|
|
@@ -132,6 +149,23 @@ describe GrapeRouteHelpers::DecoratedRoute do
|
|
132
149
|
end
|
133
150
|
|
134
151
|
describe 'path helper method' do
|
152
|
+
context 'when given a "params" key' do
|
153
|
+
context 'when value under "params" key is a hash' do
|
154
|
+
it 'creates a query string' do
|
155
|
+
query = { foo: :bar, baz: :zot }
|
156
|
+
path = index_route.api_v1_cats_path(params: query)
|
157
|
+
expect(path).to eq('/api/v1/cats.json?' + query.to_param)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context 'when value under "params" is not a hash' do
|
162
|
+
it 'coerces the value into a string' do
|
163
|
+
path = index_route.api_v1_cats_path(params: 1)
|
164
|
+
expect(path).to eq('/api/v1/cats.json?1')
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
135
169
|
# handle different Grape::Route#route_path formats in Grape 0.12.0
|
136
170
|
context 'when route_path contains a specific format' do
|
137
171
|
it 'returns the correct path with the correct format' do
|
@@ -160,5 +160,17 @@ describe GrapeRouteHelpers::NamedRouteMatcher do
|
|
160
160
|
expect(index_path).to eq('/api/v1/cats.json')
|
161
161
|
end
|
162
162
|
end
|
163
|
+
|
164
|
+
context 'when query params are passed in' do
|
165
|
+
it 'uses arguments to infer which route to use' do
|
166
|
+
api
|
167
|
+
|
168
|
+
show_path = api_v1_cats_path('id' => 1, params: { 'foo' => 'bar' })
|
169
|
+
expect(show_path).to eq('/api/v1/cats/1.json?foo=bar')
|
170
|
+
|
171
|
+
index_path = api_v1_cats_path(params: { 'foo' => 'bar' })
|
172
|
+
expect(index_path).to eq('/api/v1/cats.json?foo=bar')
|
173
|
+
end
|
174
|
+
end
|
163
175
|
end
|
164
176
|
end
|
@@ -8,6 +8,10 @@ module Spec
|
|
8
8
|
prefix 'api'
|
9
9
|
format 'json'
|
10
10
|
|
11
|
+
get 'custom_name', as: :my_custom_route_name do
|
12
|
+
'hello'
|
13
|
+
end
|
14
|
+
|
11
15
|
get 'ping' do
|
12
16
|
'pong'
|
13
17
|
end
|
@@ -29,6 +33,12 @@ module Spec
|
|
29
33
|
end
|
30
34
|
end
|
31
35
|
end
|
36
|
+
|
37
|
+
def self.mounting_api
|
38
|
+
Class.new(Grape::API) do
|
39
|
+
mount Spec::Support::RouteMatcherHelpers.api
|
40
|
+
end
|
41
|
+
end
|
32
42
|
end
|
33
43
|
end
|
34
44
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grape-route-helpers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Harper Henn
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: grape
|
@@ -118,6 +118,7 @@ files:
|
|
118
118
|
- lib/grape-route-helpers/version.rb
|
119
119
|
- lib/grape/route_helpers.rb
|
120
120
|
- lib/tasks/grape_route_helpers.rake
|
121
|
+
- spec/grape_route_helpers/all_routes.rb
|
121
122
|
- spec/grape_route_helpers/decorated_route_spec.rb
|
122
123
|
- spec/grape_route_helpers/named_route_matcher_spec.rb
|
123
124
|
- spec/spec_helper.rb
|