grape-path-helpers 1.1.0 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e5de62b3e52c6df10f69653f7aad9f4c81a64298c4ad74eb0085b06985a98474
4
- data.tar.gz: bc29c3966d9f85de40b845d9e071fce2bc869d73776ce95078816c6f553a0494
3
+ metadata.gz: 40792c146fc9c26dd609bc8dd99adce92b010820e3c2ca9644144f3493dd06ec
4
+ data.tar.gz: aed680f63272f1e61467787e0d374bb8a8145b61979c18b5c61e332763472cd5
5
5
  SHA512:
6
- metadata.gz: 04bb77b1e0ee4b792ca6edc6ce1dfd1a18f9af85bc828f2e5f384f621f5ad42a7ad16e2712e9dfb50c8f8e2e8229e5947279122888169eeaeaf12d78860d64fc
7
- data.tar.gz: 0bfc95924b6ed43d02c39c6f77123c047122d2cfebc762745362273c837950e568fb22894008cd729de90a17373ea48d2dd933a8e9b85d5b7acdfab156aa836d
6
+ metadata.gz: ff06e53d14f8d46a398cc14754fbc61e7e1a1e28179aa83a27bbca47698c117daaf064f62d3e03e1a385112fea2c0dd076b102e64e4c2f1ffa3c4d4fae7d3279
7
+ data.tar.gz: 82fde6483c7ad996189c59ab9c79969495e642fb0274d9e209228b6633e6c6c731066a4bf24effa6e00e990f3fc82b94eca8084b469f64aad15e8f9a5f486728
@@ -1,8 +1,9 @@
1
- image: "ruby:2.4-alpine"
1
+ image: "ruby:3.0-alpine"
2
2
 
3
3
  cache:
4
4
  paths:
5
5
  - vendor/ruby
6
+ key: ruby-3.0
6
7
 
7
8
  before_script:
8
9
  - apk add --update git
@@ -8,3 +8,7 @@ Metrics/MethodLength:
8
8
 
9
9
  Style/FileName:
10
10
  Enabled: false
11
+
12
+ # Removed in newer versions of Rubocop
13
+ Lint/SplatKeywordArguments:
14
+ Enabled: false
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.6.0
4
+
5
+ * [Extract kwargs to fix 2.7 warnings](https://gitlab.com/gitlab-org/grape-path-helpers/-/merge_requests/29)
6
+
7
+ ## 1.5.0
8
+
9
+ * [Relax rake dependency](https://gitlab.com/gitlab-org/grape-path-helpers/-/merge_requests/27)
10
+
11
+ ## 1.4.0
12
+
13
+ * [Support using a base class other than Grape::API::Instance](https://gitlab.com/gitlab-org/grape-path-helpers/-/merge_requests/23)
14
+
15
+ ## 1.3.0
16
+
17
+ * [Upgrade to Grape 1.3.1](https://gitlab.com/gitlab-org/grape-path-helpers/-/merge_requests/21)
18
+
19
+ ## 1.2.0
20
+
21
+ * [Add wildcard segments support](https://gitlab.com/gitlab-org/grape-path-helpers/merge_requests/16)
22
+
3
23
  ## 1.1.0
4
24
 
5
25
  * [Relax dependency on ActiveSupport](https://gitlab.com/gitlab-org/grape-path-helpers/merge_requests/12)
@@ -1,48 +1,60 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- grape-path-helpers (1.0.6)
5
- activesupport (>= 4, < 5.1)
6
- grape (~> 1.0)
7
- rake (~> 12)
4
+ grape-path-helpers (1.6.0)
5
+ activesupport
6
+ grape (~> 1.3)
7
+ rake (> 12)
8
8
 
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- activesupport (5.0.7)
12
+ activesupport (6.1.1)
13
13
  concurrent-ruby (~> 1.0, >= 1.0.2)
14
- i18n (>= 0.7, < 2)
15
- minitest (~> 5.1)
16
- tzinfo (~> 1.1)
14
+ i18n (>= 1.6, < 2)
15
+ minitest (>= 5.1)
16
+ tzinfo (~> 2.0)
17
+ zeitwerk (~> 2.3)
17
18
  ast (2.4.0)
18
- axiom-types (0.1.1)
19
- descendants_tracker (~> 0.0.4)
20
- ice_nine (~> 0.11.0)
21
- thread_safe (~> 0.3, >= 0.3.1)
22
- builder (3.2.3)
19
+ builder (3.2.4)
23
20
  coderay (1.1.2)
24
- coercible (1.0.0)
25
- descendants_tracker (~> 0.0.1)
26
- concurrent-ruby (1.0.5)
27
- descendants_tracker (0.0.4)
28
- thread_safe (~> 0.3, >= 0.3.1)
21
+ concurrent-ruby (1.1.7)
29
22
  diff-lcs (1.3)
30
- equalizer (0.0.11)
31
- grape (1.0.3)
23
+ dry-configurable (0.12.0)
24
+ concurrent-ruby (~> 1.0)
25
+ dry-core (~> 0.5, >= 0.5.0)
26
+ dry-container (0.7.2)
27
+ concurrent-ruby (~> 1.0)
28
+ dry-configurable (~> 0.1, >= 0.1.3)
29
+ dry-core (0.5.0)
30
+ concurrent-ruby (~> 1.0)
31
+ dry-equalizer (0.3.0)
32
+ dry-inflector (0.2.0)
33
+ dry-logic (1.1.0)
34
+ concurrent-ruby (~> 1.0)
35
+ dry-core (~> 0.5, >= 0.5)
36
+ dry-types (1.4.0)
37
+ concurrent-ruby (~> 1.0)
38
+ dry-container (~> 0.3)
39
+ dry-core (~> 0.4, >= 0.4.4)
40
+ dry-equalizer (~> 0.3)
41
+ dry-inflector (~> 0.1, >= 0.1.2)
42
+ dry-logic (~> 1.0, >= 1.0.2)
43
+ grape (1.5.1)
32
44
  activesupport
33
45
  builder
46
+ dry-types (>= 1.1)
34
47
  mustermann-grape (~> 1.0.0)
35
48
  rack (>= 1.3.0)
36
49
  rack-accept
37
- virtus (>= 1.0.0)
38
- i18n (1.0.1)
50
+ i18n (1.8.7)
39
51
  concurrent-ruby (~> 1.0)
40
- ice_nine (0.11.2)
41
52
  method_source (0.9.0)
42
- minitest (5.11.3)
43
- mustermann (1.0.2)
44
- mustermann-grape (1.0.0)
45
- mustermann (~> 1.0.0)
53
+ minitest (5.14.3)
54
+ mustermann (1.1.1)
55
+ ruby2_keywords (~> 0.0.1)
56
+ mustermann-grape (1.0.1)
57
+ mustermann (>= 1.0.0)
46
58
  parallel (1.12.1)
47
59
  parser (2.5.1.0)
48
60
  ast (~> 2.4.0)
@@ -50,11 +62,11 @@ GEM
50
62
  pry (0.11.3)
51
63
  coderay (~> 1.1.0)
52
64
  method_source (~> 0.9.0)
53
- rack (2.0.5)
65
+ rack (2.2.3)
54
66
  rack-accept (0.4.5)
55
67
  rack (>= 0.4)
56
68
  rainbow (3.0.0)
57
- rake (12.3.1)
69
+ rake (13.0.3)
58
70
  rspec (3.7.0)
59
71
  rspec-core (~> 3.7.0)
60
72
  rspec-expectations (~> 3.7.0)
@@ -76,15 +88,11 @@ GEM
76
88
  ruby-progressbar (~> 1.7)
77
89
  unicode-display_width (~> 1.0, >= 1.0.1)
78
90
  ruby-progressbar (1.9.0)
79
- thread_safe (0.3.6)
80
- tzinfo (1.2.5)
81
- thread_safe (~> 0.1)
91
+ ruby2_keywords (0.0.2)
92
+ tzinfo (2.0.4)
93
+ concurrent-ruby (~> 1.0)
82
94
  unicode-display_width (1.3.3)
83
- virtus (1.0.5)
84
- axiom-types (~> 0.1)
85
- coercible (~> 1.0)
86
- descendants_tracker (~> 0.0, >= 0.0.3)
87
- equalizer (~> 0.0, >= 0.0.9)
95
+ zeitwerk (2.4.2)
88
96
 
89
97
  PLATFORMS
90
98
  ruby
@@ -96,4 +104,4 @@ DEPENDENCIES
96
104
  rubocop (~> 0.56)
97
105
 
98
106
  BUNDLED WITH
99
- 1.16.2
107
+ 2.2.3
@@ -1,6 +1,7 @@
1
1
  MIT License (MIT)
2
2
 
3
- Copyright (c) 2015 Harper Henn
3
+ Copyright (c) 2015,2016 Harper Henn
4
+ Copyright (c) 2018-2020 GitLab B.V.
4
5
 
5
6
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
7
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # grape-path-helpers
2
2
 
3
- [![Build status](https://gitlab.com/gitlab-org/grape-path-helpers/badges/master/build.svg)](https://gitlab.com/gitlab-org/grape-path-helpers/commits/master)
3
+ [![Build status](https://gitlab.com/gitlab-org/grape-path-helpers/badges/master/pipeline.svg)](https://gitlab.com/gitlab-org/grape-path-helpers/commits/master)
4
4
 
5
5
  Provides named route helpers for Grape APIs, similar to [Rails' route helpers](http://edgeguides.rubyonrails.org/routing.html#path-and-url-helpers).
6
6
 
7
- **This is a fork and rename of [group-route-helpers](https://github.com/reprah/grape-route-helpers). It [includes some fixes](CHANGELOG.md) needed for GitLab.**
7
+ **This is a fork and rename of [grape-route-helpers](https://github.com/reprah/grape-route-helpers). It [includes some fixes](CHANGELOG.md) needed for GitLab.**
8
8
 
9
9
  ### Installation
10
10
 
@@ -76,7 +76,7 @@ You can use helper methods in your REPL session by including a module:
76
76
  Use the methods inside your Grape API actions. Given this example API:
77
77
 
78
78
  ```ruby
79
- class ExampleAPI < Grape::API
79
+ class ExampleAPI < Grape::API::Instance
80
80
  version 'v1'
81
81
  prefix 'api'
82
82
  format 'json'
@@ -127,7 +127,7 @@ api_v1_anything_path # => '/api/v1/*anything'
127
127
  If you want to assign a custom helper name to a route, pass the `:as` option when creating your route in your API:
128
128
 
129
129
  ```ruby
130
- class Base < Grape::API
130
+ class Base < Grape::API::Instance
131
131
  get 'ping', as: 'is_the_server_running'
132
132
  'pong'
133
133
  end
@@ -169,6 +169,14 @@ end
169
169
 
170
170
  6.) Create a new pull request
171
171
 
172
+ ### Releasing
173
+
174
+ 1. Update the [CHANGELOG](CHANGELOG.md).
175
+ 2. Update the version in [lib/grape-path-helpers/version.rb](lib/grape-path-helpers/version.rb).
176
+ 3. [Tag](https://gitlab.com/gitlab-org/grape-path-helpers/-/tags) the commit with the version number prefixed by 'v'.
177
+ 4. Run `gem build grape-path-helpers` locally.
178
+ 5. Run `gem push $new_file.gem` locally, where `$new_file` is the file generated by the step above.
179
+
172
180
  ### License
173
181
 
174
182
  See LICENSE
data/Rakefile CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'bundler'
3
+ require 'bundler/gem_tasks'
3
4
 
4
5
  Bundler.setup :default, :test, :development
5
6
 
@@ -12,8 +12,8 @@ Gem::Specification.new do |gem|
12
12
  gem.homepage = 'https://gitlab.com/gitlab-org/grape-path-helpers'
13
13
 
14
14
  gem.add_runtime_dependency 'activesupport'
15
- gem.add_runtime_dependency 'grape', '~> 1.0'
16
- gem.add_runtime_dependency 'rake', '~> 12'
15
+ gem.add_runtime_dependency 'grape', '~> 1.3'
16
+ gem.add_runtime_dependency 'rake', '> 12'
17
17
 
18
18
  gem.add_development_dependency 'pry', '~> 0.11'
19
19
  gem.add_development_dependency 'rspec', '~> 3.7'
@@ -12,5 +12,5 @@ module GrapePathHelpers
12
12
  require 'grape-path-helpers/railtie' if defined?(Rails)
13
13
  end
14
14
 
15
- Grape::API.extend GrapePathHelpers::AllRoutes
15
+ Grape::API::Instance.extend GrapePathHelpers::AllRoutes
16
16
  Grape::Endpoint.send(:include, GrapePathHelpers::NamedRouteMatcher)
@@ -11,7 +11,7 @@ module GrapePathHelpers
11
11
  end
12
12
 
13
13
  def all_routes
14
- routes = subclasses.flat_map { |s| s.send(:prepare_routes) }
14
+ routes = descendants.flat_map { |s| s.send(:prepare_routes) }
15
15
  routes.uniq { |r| r.options.merge(path: r.path) }
16
16
  end
17
17
  end
@@ -4,6 +4,9 @@ module GrapePathHelpers
4
4
  attr_reader :route, :helper_names, :helper_arguments,
5
5
  :extension, :route_options
6
6
 
7
+ PATH_SEGMENTS_REGEXP = %r{\(/?\.:?\w+\)|/(?!\))|(?<=\))|\??\*}
8
+ PATH_SEGMENTS_WITH_WILDCARDS_REGEXP = %r{\(/?\.:?\w+\)|/(?!\))|(?<=\))|\?}
9
+
7
10
  def self.sanitize_method_name(string)
8
11
  string.gsub(/\W|^[0-9]/, '_')
9
12
  end
@@ -40,12 +43,12 @@ module GrapePathHelpers
40
43
 
41
44
  def define_path_helper(method_name, route_attributes)
42
45
  method_body = <<-RUBY
43
- def #{method_name}(attributes = {})
46
+ def #{method_name}(attributes = {}, include_wildcard_segments = false)
44
47
  attrs = #{route_attributes}.merge(attributes)
45
48
 
46
49
  query_params = attrs.delete(:params)
47
50
  content_type = attrs.delete(:format)
48
- path = '/' + path_segments_with_values(attrs).join('/')
51
+ path = '/' + path_segments_with_values(attrs, include_wildcard_segments).join('/')
49
52
 
50
53
  path + content_type + query_string(query_params)
51
54
  end
@@ -99,13 +102,19 @@ module GrapePathHelpers
99
102
  end
100
103
  end
101
104
 
102
- def path_segments_with_values(opts)
103
- segments = path_segments.map { |s| segment_to_value(s, opts) }
105
+ def path_segments_with_values(opts, include_wildcard_segments = false)
106
+ segments = path_segments(include_wildcard_segments).map do |s|
107
+ segment_to_value(s, opts)
108
+ end
104
109
  segments.reject(&:blank?)
105
110
  end
106
111
 
107
- def path_segments
108
- pattern = %r{\(/?\.:?\w+\)|/(?!\))|(?<=\))|\??\*}
112
+ def path_segments(include_wildcard_segments = false)
113
+ pattern = if include_wildcard_segments
114
+ PATH_SEGMENTS_WITH_WILDCARDS_REGEXP
115
+ else
116
+ PATH_SEGMENTS_REGEXP
117
+ end
109
118
  route_path.split(pattern).reject(&:blank?)
110
119
  end
111
120
 
@@ -117,7 +126,7 @@ module GrapePathHelpers
117
126
  end
118
127
 
119
128
  def dynamic_segment?(segment)
120
- segment.start_with?(':')
129
+ segment.start_with?(':', '*')
121
130
  end
122
131
 
123
132
  def optional_segment?(segment)
@@ -3,26 +3,34 @@ module GrapePathHelpers
3
3
  # to unknown methods will look for a route with a matching
4
4
  # helper function name
5
5
  module NamedRouteMatcher
6
- def method_missing(method_id, *arguments)
6
+ def method_missing(method_id, *args, **kwargs)
7
7
  return super unless method_id.to_s =~ /_path$/
8
8
 
9
+ success, result = call_path_method(method_id, *args, **kwargs)
10
+
11
+ if success
12
+ result
13
+ else
14
+ super
15
+ end
16
+ end
17
+
18
+ def call_path_method(method_id, *arguments)
9
19
  segments = arguments.first || {}
10
20
 
11
- route = Grape::API.decorated_routes.detect do |r|
21
+ route = Grape::API::Instance.decorated_routes.detect do |r|
12
22
  route_match?(r, method_id, segments)
13
23
  end
14
24
 
15
- if route
16
- route.send(method_id, *arguments)
17
- else
18
- super
19
- end
25
+ return false unless route
26
+
27
+ [true, route.send(method_id, *arguments)]
20
28
  end
21
29
 
22
30
  def respond_to_missing?(method_name, _include_private = false)
23
31
  return super unless method_name =~ /_path$/
24
32
 
25
- Grape::API.decorated_routes.detect do |route|
33
+ Grape::API::Instance.decorated_routes.detect do |route|
26
34
  return true if route.respond_to?(method_name)
27
35
  end
28
36
 
@@ -3,7 +3,7 @@ module GrapePathHelpers
3
3
  # and required arguments for every Grape::Route.
4
4
  class RouteDisplayer
5
5
  def route_attributes
6
- Grape::API.decorated_routes.map do |route|
6
+ Grape::API::Instance.decorated_routes.map do |route|
7
7
  {
8
8
  route_path: route.route_path,
9
9
  route_method: route.route_method,
@@ -1,4 +1,4 @@
1
1
  # Gem version
2
2
  module GrapePathHelpers
3
- VERSION = '1.1.0'.freeze
3
+ VERSION = '1.6.0'.freeze
4
4
  end
@@ -1,7 +1,8 @@
1
1
  require 'spec_helper'
2
2
 
3
+ # rubocop:disable Metrics/BlockLength
3
4
  describe GrapePathHelpers::AllRoutes do
4
- Grape::API.extend described_class
5
+ Grape::API::Instance.extend described_class
5
6
 
6
7
  describe '#all_routes' do
7
8
  context 'when API is mounted within another API' do
@@ -11,7 +12,7 @@ describe GrapePathHelpers::AllRoutes do
11
12
  mounting_api
12
13
 
13
14
  # 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
+ all_route_options = Grape::API::Instance.all_routes.map do |r|
15
16
  r.instance_variable_get(:@options).merge(path: r.path)
16
17
  end
17
18
 
@@ -28,10 +29,18 @@ describe GrapePathHelpers::AllRoutes do
28
29
  it 'returns all POST routes' do
29
30
  expected_routes = Spec::Support::MultiplePostsAPI.routes.map(&:path)
30
31
 
31
- all_routes = Grape::API.all_routes
32
+ all_routes = Grape::API::Instance.all_routes
32
33
  expect(all_routes.map(&:path)).to include(*expected_routes)
33
34
  end
34
35
  end
36
+
37
+ context 'when an API is created via an intermediate class' do
38
+ it 'includes those routes on both Grape::API::Instance and the base class' do
39
+ expect(Spec::Support::BaseAPI.all_routes.map(&:origin)).to include('/derived_ping')
40
+ expect(Grape::API::Instance.all_routes.map(&:origin)).to include('/derived_ping')
41
+ end
42
+ end
35
43
  # rubocop:enable Metrics/LineLength
36
44
  end
37
45
  end
46
+ # rubocop:enable Metrics/BlockLength
@@ -19,7 +19,7 @@ describe GrapePathHelpers::DecoratedRoute do
19
19
  end
20
20
 
21
21
  let(:catch_all_route) do
22
- routes.detect { |route| route.route_path =~ /\*/ }
22
+ routes.detect { |route| route.route_path =~ /\*path/ }
23
23
  end
24
24
 
25
25
  let(:custom_route) do
@@ -34,6 +34,10 @@ describe GrapePathHelpers::DecoratedRoute do
34
34
  routes.detect { |route| route.route_path =~ /optional/ }
35
35
  end
36
36
 
37
+ let(:wildcard_route) do
38
+ routes.detect { |route| route.route_path =~ /\*owner_ids/ }
39
+ end
40
+
37
41
  describe '#sanitize_method_name' do
38
42
  it 'removes characters that are illegal in Ruby method names' do
39
43
  illegal_names = ['beta-1', 'name_with_+', 'name_with_(']
@@ -51,6 +55,53 @@ describe GrapePathHelpers::DecoratedRoute do
51
55
  end
52
56
  end
53
57
 
58
+ describe '#define_path_helper' do
59
+ context 'with only static segments' do
60
+ let(:route) { ping_route }
61
+
62
+ subject { route.api_v1_ping_path }
63
+
64
+ it { is_expected.to eq '/api/v1/ping.json' }
65
+ end
66
+
67
+ context 'with optional segments' do
68
+ let(:route) { optional_route }
69
+
70
+ subject { route.api_v1_cats______optional_path }
71
+
72
+ it { is_expected.to eq '/api/v1/cats/(-/)/optional.json' }
73
+ end
74
+
75
+ context 'with dynamic segments' do
76
+ let(:route) { show_route }
77
+
78
+ subject { route.api_v1_cats_path(id: 1) }
79
+
80
+ it { is_expected.to eq '/api/v1/cats/1.json' }
81
+ end
82
+
83
+ context 'with wildcard segments' do
84
+ let(:route) { wildcard_route }
85
+
86
+ context 'including them' do
87
+ subject do
88
+ route.api_v1_cats_owners_owner_ids_cats_path(
89
+ { owner_ids: 'foobar' },
90
+ true
91
+ )
92
+ end
93
+
94
+ it { is_expected.to eq '/api/v1/cats/owners/foobar/cats.json' }
95
+ end
96
+
97
+ context 'excluding them' do
98
+ subject { route.api_v1_cats_owners_owner_ids_cats_path }
99
+
100
+ it { is_expected.to eq '/api/v1/cats/owners/owner_ids/cats.json' }
101
+ end
102
+ end
103
+ end
104
+
54
105
  describe '#helper_names' do
55
106
  context 'when a route is given a custom helper name' do
56
107
  it 'uses the custom name instead of the dynamically generated one' do
@@ -119,7 +170,7 @@ describe GrapePathHelpers::DecoratedRoute do
119
170
 
120
171
  describe '#path_segments_with_values' do
121
172
  context 'when path has dynamic segments' do
122
- it 'replaces segments with corresponding values found in @options' do
173
+ it 'replaces segments with corresponding values found in options' do
123
174
  opts = { id: 1 }
124
175
  result = show_route.path_segments_with_values(opts)
125
176
  expect(result).to include(1)
@@ -133,6 +184,74 @@ describe GrapePathHelpers::DecoratedRoute do
133
184
  end
134
185
  end
135
186
  end
187
+
188
+ context 'when path has wildcard segments' do
189
+ context 'with regex excluding them' do
190
+ it "doesn't replaces wildcard segments" do
191
+ opts = { version: 4, id: 34, owner_ids: 'foobar' }
192
+
193
+ result = wildcard_route.path_segments_with_values(opts)
194
+ expect(result).to include(4)
195
+ expect(result).to include(34)
196
+ expect(result).to include('owner_ids')
197
+ expect(result).not_to include('foobar')
198
+ end
199
+
200
+ it "doesn't blank wildcard segments" do
201
+ opts = { version: 4, id: 34, owner_ids: '' }
202
+
203
+ result = wildcard_route.path_segments_with_values(opts)
204
+ expect(result).to include(4)
205
+ expect(result).to include(34)
206
+ expect(result).to include('owner_ids')
207
+ end
208
+ end
209
+
210
+ context 'with regex including them' do
211
+ context 'replaces segments' do
212
+ it 'with static text' do
213
+ opts = { version: 4, id: 34, owner_ids: 'foobar' }
214
+
215
+ result = wildcard_route.path_segments_with_values(opts, true)
216
+ expect(result).to include(4)
217
+ expect(result).to include(34)
218
+ expect(result).to include('foobar')
219
+ expect(result).not_to include('owner_ids')
220
+ end
221
+
222
+ it 'with additional segments' do
223
+ opts = { version: 4, id: 34, owner_ids: 'foo/bar/baz' }
224
+
225
+ result = wildcard_route.path_segments_with_values(opts, true)
226
+ expect(result).to include(4)
227
+ expect(result).to include(34)
228
+ expect(result).to include('foo/bar/baz')
229
+ expect(result).not_to include('owner_ids')
230
+ end
231
+ end
232
+
233
+ it 'blanks wildcard segments' do
234
+ opts = { version: 4, id: 34, owner_ids: '' }
235
+
236
+ result = wildcard_route.path_segments_with_values(opts, true)
237
+ expect(result).to include(4)
238
+ expect(result).to include(34)
239
+ expect(result).not_to include('owner_ids')
240
+ end
241
+
242
+ context 'when options contains string keys' do
243
+ it 'replaces segments' do
244
+ opts = { 'version' => 4, 'id' => 34, 'owner_ids' => 'foobar' }
245
+
246
+ result = wildcard_route.path_segments_with_values(opts, true)
247
+ expect(result).to include(4)
248
+ expect(result).to include(34)
249
+ expect(result).to include('foobar')
250
+ expect(result).not_to include('owner_ids')
251
+ end
252
+ end
253
+ end
254
+ end
136
255
  end
137
256
 
138
257
  describe '#path_helper_name' do
@@ -165,6 +284,13 @@ describe GrapePathHelpers::DecoratedRoute do
165
284
  expect(result).to eq('api_v1_path_path')
166
285
  end
167
286
  end
287
+
288
+ context 'when the path has a wildcard segment' do
289
+ it 'returns a name without the glob star' do
290
+ result = wildcard_route.path_helper_name
291
+ expect(result).to eq('api_v1_cats_owners_owner_ids_cats_path')
292
+ end
293
+ end
168
294
  end
169
295
 
170
296
  describe '#segment_to_value' do
@@ -5,7 +5,7 @@ describe GrapePathHelpers::NamedRouteMatcher do
5
5
  include described_class
6
6
 
7
7
  let(:routes) do
8
- Grape::API.decorated_routes
8
+ Grape::API::Instance.decorated_routes
9
9
  end
10
10
 
11
11
  let(:ping_route) do
@@ -30,8 +30,8 @@ describe GrapePathHelpers::NamedRouteMatcher do
30
30
  fake_class = Class.new do
31
31
  prepend GrapePathHelpers::NamedRouteMatcher
32
32
 
33
- def method_missing(_method_id, *_args)
34
- 'whatever' || super
33
+ def method_missing(method_id, *args, **kwargs)
34
+ [method_id, args, kwargs] || super
35
35
  end
36
36
 
37
37
  def respond_to_missing?(_method_name, _include_private = false)
@@ -44,13 +44,14 @@ describe GrapePathHelpers::NamedRouteMatcher do
44
44
 
45
45
  describe '#method_missing' do
46
46
  it 'returns super method_missing if the method does not end with path' do
47
- expect(Grape::API).not_to receive(:decorated_routes)
47
+ expect(Grape::API::Instance).not_to receive(:decorated_routes)
48
48
 
49
- helper_class.test_method
49
+ expect(helper_class.test_method(:arg1, kwarg1: :kwarg1))
50
+ .to eq([:test_method, [:arg1], { kwarg1: :kwarg1 }])
50
51
  end
51
52
 
52
53
  it 'search for the route if the method ends with path' do
53
- expect(Grape::API).to receive(:decorated_routes).and_call_original
54
+ expect(Grape::API::Instance).to receive(:decorated_routes).and_call_original # rubocop:disable Metrics/LineLength
54
55
 
55
56
  helper_class.test_method_path
56
57
  end
@@ -146,14 +147,14 @@ describe GrapePathHelpers::NamedRouteMatcher do
146
147
  end
147
148
 
148
149
  describe '#respond_to_missing?' do
149
- it 'returns super if the method doesb not end with path' do
150
- expect(Grape::API).not_to receive(:decorated_routes)
150
+ it 'returns super if the method does not end with path' do
151
+ expect(Grape::API::Instance).not_to receive(:decorated_routes) # rubocop:disable Metrics/LineLength
151
152
 
152
153
  expect(helper_class.send(:respond_to_missing?, :test)).to eq(false)
153
154
  end
154
155
 
155
156
  it 'search for the route if the method ends with path' do
156
- expect(Grape::API).to receive(:decorated_routes).and_call_original
157
+ expect(Grape::API::Instance).to receive(:decorated_routes).and_call_original # rubocop:disable Metrics/LineLength
157
158
 
158
159
  expect(helper_class.send(:respond_to_missing?, :test_path)).to eq(false)
159
160
  end
@@ -1,7 +1,7 @@
1
1
  module Spec
2
2
  module Support
3
3
  # Test API
4
- class API < Grape::API
4
+ class API < Grape::API::Instance
5
5
  version 'v1'
6
6
  prefix 'api'
7
7
  format 'json'
@@ -36,6 +36,10 @@ module Spec
36
36
  get ':id/owners/:owner_id' do
37
37
  'owner'
38
38
  end
39
+
40
+ get ':id/owners/*owner_ids/cats' do
41
+ %w[cats cats cats]
42
+ end
39
43
  end
40
44
 
41
45
  route :any, '*path' do
@@ -44,7 +48,7 @@ module Spec
44
48
  end
45
49
 
46
50
  # API with more than one version
47
- class APIWithMultipleVersions < Grape::API
51
+ class APIWithMultipleVersions < Grape::API::Instance
48
52
  version %w[beta alpha v1]
49
53
 
50
54
  get 'ping' do
@@ -53,13 +57,13 @@ module Spec
53
57
  end
54
58
 
55
59
  # API with another API mounted inside it
56
- class MountedAPI < Grape::API
60
+ class MountedAPI < Grape::API::Instance
57
61
  mount Spec::Support::API
58
62
  mount Spec::Support::APIWithMultipleVersions
59
63
  end
60
64
 
61
65
  # API with a version that would be illegal as a method name
62
- class APIWithIllegalVersion < Grape::API
66
+ class APIWithIllegalVersion < Grape::API::Instance
63
67
  version 'beta-1'
64
68
 
65
69
  get 'ping' do
@@ -68,7 +72,7 @@ module Spec
68
72
  end
69
73
 
70
74
  # API with multiple POST routes
71
- class MultiplePostsAPI < Grape::API
75
+ class MultiplePostsAPI < Grape::API::Instance
72
76
  resource :hamlet do
73
77
  post 'to_be' do
74
78
  end
@@ -77,5 +81,14 @@ module Spec
77
81
  end
78
82
  end
79
83
  end
84
+
85
+ class BaseAPI < Grape::API::Instance
86
+ end
87
+
88
+ class DerivedAPI < BaseAPI
89
+ get 'derived_ping' do
90
+ 'pong'
91
+ end
92
+ end
80
93
  end
81
94
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grape-path-helpers
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Drew Blessing
8
8
  - Harper Henn
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-12-17 00:00:00.000000000 Z
12
+ date: 2021-01-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -31,26 +31,26 @@ dependencies:
31
31
  requirements:
32
32
  - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: '1.0'
34
+ version: '1.3'
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: '1.0'
41
+ version: '1.3'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: rake
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
- - - "~>"
46
+ - - ">"
47
47
  - !ruby/object:Gem::Version
48
48
  version: '12'
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
- - - "~>"
53
+ - - ">"
54
54
  - !ruby/object:Gem::Version
55
55
  version: '12'
56
56
  - !ruby/object:Gem::Dependency
@@ -131,7 +131,7 @@ homepage: https://gitlab.com/gitlab-org/grape-path-helpers
131
131
  licenses:
132
132
  - MIT
133
133
  metadata: {}
134
- post_install_message:
134
+ post_install_message:
135
135
  rdoc_options: []
136
136
  require_paths:
137
137
  - lib
@@ -146,9 +146,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
146
146
  - !ruby/object:Gem::Version
147
147
  version: '0'
148
148
  requirements: []
149
- rubyforge_project:
150
- rubygems_version: 2.7.6
151
- signing_key:
149
+ rubygems_version: 3.2.3
150
+ signing_key:
152
151
  specification_version: 4
153
152
  summary: Route path helpers for Grape
154
153
  test_files: []