stub_requests 0.1.4 → 0.1.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 981c31047c2aad42cd7c11962cb1429e742dfda6ed6656485a78d4b83f5acd78
4
- data.tar.gz: 49b9c4cfd8fde9f4ab99429fcd5ae02b68809f98d47009b43b880f7802d09202
3
+ metadata.gz: fb6e6aa72e0616a2a89284efa00ae33420dcf6cf3247e069af90fda69c769733
4
+ data.tar.gz: f7c963fcc527dce3e5979890b908d9a9a8acd31d676e5a91353180ea8ba55612
5
5
  SHA512:
6
- metadata.gz: 725506e6bfec1e4088bd8cbe436c33c285a0a0d7e7a9601cb6257d4f9375a321ba3ea663e5bcbf81a3d2dbdb5aac75b265676cbcbec220faaf6856706ec12de4
7
- data.tar.gz: eafe65b7a4cec3296935ac42745480a486a1929c5f95a62b8ba9f438317f4ce7d6291724aaece80352e36728193a88cfe782d11651198c349ada37ef560bce7c
6
+ metadata.gz: d6cc37d6d92dec8aeacee90ff793f12db37deef28a4b735854fd34d6838ac47952a39e75f190e3488613a67fb9e475be952da5a4c9d3ec865bd1ed30cd68f5e2
7
+ data.tar.gz: 9db50e02b973429d74fa989baa0212d78b1c6df34e5aca7b556573bdf8bdff25aa689a0b21d053b4308fe8faefbb3826f277686d217687b147d9e9f44dbb0232
data/.gitignore CHANGED
@@ -2,6 +2,7 @@
2
2
  /.rspec_status
3
3
  /.yardoc
4
4
  /_yardoc/
5
+ /gemfiles/*.lock
5
6
  /coverage/
6
7
  /doc/
7
8
  /docs
data/.reek.yml CHANGED
@@ -1,15 +1,55 @@
1
1
  # Auto generated by Reeks --todo flag
2
2
  ---
3
- detectors:
4
- ManualDispatch:
5
- exclude:
6
- - Object#blank?
7
- Attribute:
8
- exclude:
9
- - StubRequests#logger
10
-
11
3
  exclude_paths:
12
4
  - vendor/bundle
13
5
  - gemfiles
14
6
  - lib/stub_requests/core_ext/
15
7
  - spec/
8
+ detectors:
9
+ DuplicateMethodCall:
10
+ exclude:
11
+ - RSpec::SubjectAsLambda#it!
12
+ - StubRequests::CallbackRegistry#find_by
13
+ TooManyMethods:
14
+ exclude:
15
+ - StubRequests::Endpoints
16
+ TooManyStatements:
17
+ exclude:
18
+ - initialize
19
+ - RSpec::SubjectAsLambda#it!
20
+ DataClump:
21
+ exclude:
22
+ - StubRequests::API
23
+ - StubRequests::Endpoints
24
+ - StubRequests::StubRegistry
25
+ LongParameterList:
26
+ exclude:
27
+ - StubRequests::API#register_callback
28
+ - StubRequests::CallbackRegistry#register
29
+ - StubRequests::CallbackRegistry#self.register
30
+ - StubRequests::Property::Validator#self.call
31
+ UtilityFunction:
32
+ exclude:
33
+ - StubRequests::API#define_stubs
34
+ - StubRequests::API#print_stubs
35
+ - StubRequests::API#register_callback
36
+ - StubRequests::API#register_service
37
+ - StubRequests::API#stub_endpoint
38
+ - StubRequests::API#unregister_callback
39
+ - StubRequests::StubRegistry#initialize_endpoint_stub
40
+ ControlParameter:
41
+ exclude:
42
+ - StubRequests::CallbackRegistry#find_by
43
+ - StubRequests::Property::Validator#initialize
44
+ FeatureEnvy:
45
+ exclude:
46
+ - StubRequests::CallbackRegistry#dispatch_callback
47
+ - StubRequests::CallbackRegistry#find_by
48
+ - StubRequests::CallbackRegistry#invoke_callbacks
49
+ - StubRequests::StubRegistry#find_endpoint_stub
50
+ Attribute:
51
+ exclude:
52
+ - StubRequests#logger
53
+ TooManyInstanceVariables:
54
+ exclude:
55
+ - StubRequests::URI::Builder
data/.rspec CHANGED
@@ -1,3 +1,4 @@
1
- --format documentation
1
+ --require fuubar
2
+ --format Fuubar
2
3
  --color
3
4
  --require spec_helper
data/CHANGELOG.md CHANGED
@@ -2,20 +2,59 @@
2
2
 
3
3
  ## [Unreleased](https://github.com/mhenrixon/stub_requests/tree/HEAD)
4
4
 
5
- [Full Changelog](https://github.com/mhenrixon/stub_requests/compare/v0.1.0...HEAD)
5
+ [Full Changelog](https://github.com/mhenrixon/stub_requests/compare/v0.1.4...HEAD)
6
+
7
+ **Implemented enhancements:**
8
+
9
+ - Use fuubar for spec formatting [\#19](https://github.com/mhenrixon/stub_requests/pull/19) ([mhenrixon](https://github.com/mhenrixon))
10
+ - Adds print stub definitions [\#18](https://github.com/mhenrixon/stub_requests/pull/18) ([mhenrixon](https://github.com/mhenrixon))
11
+
12
+ **Fixed bugs:**
13
+
14
+ - Fix bug with defining properties [\#17](https://github.com/mhenrixon/stub_requests/pull/17) ([mhenrixon](https://github.com/mhenrixon))
15
+
16
+ **Merged pull requests:**
17
+
18
+ - Update Changelog [\#16](https://github.com/mhenrixon/stub_requests/pull/16) ([mhenrixon](https://github.com/mhenrixon))
19
+
20
+ ## [v0.1.4](https://github.com/mhenrixon/stub_requests/tree/v0.1.4) (2019-02-06)
21
+ [Full Changelog](https://github.com/mhenrixon/stub_requests/compare/v0.1.3...v0.1.4)
22
+
23
+ **Implemented enhancements:**
24
+
25
+ - DSL for building stub methods [\#15](https://github.com/mhenrixon/stub_requests/pull/15) ([mhenrixon](https://github.com/mhenrixon))
26
+
27
+ **Merged pull requests:**
28
+
29
+ - Update Changelog [\#13](https://github.com/mhenrixon/stub_requests/pull/13) ([mhenrixon](https://github.com/mhenrixon))
30
+
31
+ ## [v0.1.3](https://github.com/mhenrixon/stub_requests/tree/v0.1.3) (2019-02-04)
32
+ [Full Changelog](https://github.com/mhenrixon/stub_requests/compare/v0.1.2...v0.1.3)
6
33
 
7
34
  **Implemented enhancements:**
8
35
 
9
36
  - Add rough initial implementation of subscriptions [\#12](https://github.com/mhenrixon/stub_requests/pull/12) ([mhenrixon](https://github.com/mhenrixon))
37
+
38
+ **Merged pull requests:**
39
+
40
+ - Update Changelog [\#11](https://github.com/mhenrixon/stub_requests/pull/11) ([mhenrixon](https://github.com/mhenrixon))
41
+
42
+ ## [v0.1.2](https://github.com/mhenrixon/stub_requests/tree/v0.1.2) (2019-02-03)
43
+ [Full Changelog](https://github.com/mhenrixon/stub_requests/compare/v0.1.1...v0.1.2)
44
+
45
+ **Implemented enhancements:**
46
+
10
47
  - Script updating documentation [\#9](https://github.com/mhenrixon/stub_requests/pull/9) ([mhenrixon](https://github.com/mhenrixon))
11
48
  - Add a simple script to update documentation [\#8](https://github.com/mhenrixon/stub_requests/pull/8) ([mhenrixon](https://github.com/mhenrixon))
12
49
  - Improve documentation [\#7](https://github.com/mhenrixon/stub_requests/pull/7) ([mhenrixon](https://github.com/mhenrixon))
13
50
  - Initial metrics implementation [\#6](https://github.com/mhenrixon/stub_requests/pull/6) ([mhenrixon](https://github.com/mhenrixon))
14
51
  - Remove the docs folder in preference of a branch [\#5](https://github.com/mhenrixon/stub_requests/pull/5) ([mhenrixon](https://github.com/mhenrixon))
15
52
 
53
+ ## [v0.1.1](https://github.com/mhenrixon/stub_requests/tree/v0.1.1) (2019-02-01)
54
+ [Full Changelog](https://github.com/mhenrixon/stub_requests/compare/v0.1.0...v0.1.1)
55
+
16
56
  **Merged pull requests:**
17
57
 
18
- - Update Changelog [\#11](https://github.com/mhenrixon/stub_requests/pull/11) ([mhenrixon](https://github.com/mhenrixon))
19
58
  - Allow older webmock versions [\#4](https://github.com/mhenrixon/stub_requests/pull/4) ([mhenrixon](https://github.com/mhenrixon))
20
59
  - Add docs folder [\#3](https://github.com/mhenrixon/stub_requests/pull/3) ([mhenrixon](https://github.com/mhenrixon))
21
60
  - Add docs folder and CHANGELOG.md [\#2](https://github.com/mhenrixon/stub_requests/pull/2) ([mhenrixon](https://github.com/mhenrixon))
data/README.md CHANGED
@@ -20,7 +20,8 @@ This is achieve by keeping a registry over the service endpoints.
20
20
  - [Register service endpoints](#register-service-endpoints)
21
21
  - [Stubbing service endpoints](#stubbing-service-endpoints)
22
22
  - [Metrics](#metrics)
23
- - [Observing endpoint invocations](#observing-endpoint-invocations)
23
+ - [Endpoint invocation callbacks](#endpoint-invocation-callbacks)
24
+ - [Using Method Stubs](#using-method-stubs)
24
25
  - [Future Improvements](#future-improvements)
25
26
  - [API Client Gem](#api-client-gem)
26
27
  - [Development](#development)
@@ -68,11 +69,12 @@ The naming of the `service_id` and `endpoint_id`'s is irrelevant. This is just h
68
69
 
69
70
  ```ruby
70
71
  StubRequests.register_service(:google_ads, "https://api.google.com/v5") do
71
- register(:index, :get, "ads")
72
- register(:show, :get, "ads/:id")
73
- register(:update, :patch, "ads/:id")
74
- register(:create, :post, "ads")
75
- register(:destroy, :delete, "ads/:id")
72
+ get "ads", as: :ads_index
73
+ get "ads/:id", as: :ads_show
74
+ patch "ads/:id", as: :ads_update
75
+ put "ads/:id", as: :ads_update
76
+ post "ads", as: :ads_create
77
+ delete "ads/:id", as: :ads_destroy
76
78
  end
77
79
  ```
78
80
 
@@ -119,8 +121,8 @@ StubRequests.configure do |config|
119
121
  end
120
122
  ```
121
123
 
122
- <a id="observing-endpoint-invocations"></a>
123
- ### Observing endpoint invocations
124
+ <a id="endpoint-invocation-callbacks"></a>
125
+ ### Endpoint invocation callbacks
124
126
 
125
127
  ```ruby
126
128
  # To jump into pry when a request is called
@@ -131,14 +133,140 @@ end
131
133
 
132
134
  callback = ->(request) { p request; binding.pry }
133
135
 
134
- StubRequests.register(:document_service, :show, :get, callback)
136
+ StubRequests.register_callback(:document_service, :show, :get, callback)
135
137
  ```
136
138
 
137
139
  ```ruby
138
140
  # To unsubscribe from notifications
139
- StubRequests.unregister(:document_service, :show, :get)
141
+ StubRequests.unregister_callback(:document_service, :show, :get)
140
142
  ```
141
143
 
144
+ <a id="using-method-stubs"></a>
145
+ ### Using Method Stubs
146
+
147
+ ```ruby
148
+ #
149
+ # 1. Register some service endpoints
150
+ #
151
+ StubRequests.register_service(:documents, "https://company.com/api/v1") do
152
+ get "documents/:id", as: :documents_show
153
+ get "documents", as: :documents_index
154
+ post "documents", as: :documents_create
155
+ patch "documents/:id", as: :documents_update
156
+ put "documents/:id", as: :document_put
157
+ delete "documents/:id" as: :documents_destroy
158
+ end
159
+
160
+ #
161
+ # 2. Create a module where the methods should be defined
162
+ #
163
+ module Stubs
164
+ module Documents
165
+ end
166
+ end
167
+
168
+ #
169
+ # 3. Define the stubs for the registered endpoints
170
+ #
171
+ StubRequests::DSL.define_stubs(:documents, Stubs::Documents)
172
+
173
+ Documents.instance_methods #=>
174
+ [
175
+ :stub_documents_show
176
+ :stub_documents_index
177
+ :stub_documents_create
178
+ :stub_documents_update
179
+ :stub_document_put
180
+ :stub_documents_destroy
181
+ ]
182
+
183
+ #
184
+ # 4. Use the module in our tests
185
+ #
186
+ RSpec.describe ClassThatCallsTheDocumentService do
187
+ include Stubs::Documents
188
+
189
+ let(:document_id) { 123455 }
190
+ let(:documents_show_body) do
191
+ {
192
+ id: document_id,
193
+ status: "draft",
194
+ }
195
+ end
196
+
197
+ before do
198
+ stub_documents_show(id: document_id)
199
+ .to_return(status: 200, body: documents_show_body.to_json)
200
+ end
201
+
202
+ it "stubs the request nicely" do
203
+ # execute code that calls the service
204
+ uri = URI("https://company.com/api/v1/documents/#{document_id}")
205
+ response = Net::HTTP.get(uri)
206
+
207
+ expect(response).to be_json_eql(example_api_list_task_response.to_json)
208
+ end
209
+ end
210
+ ```
211
+
212
+ If you prefer to keep a hard copy of the methods in your project then you can print the method definitions to the console and copy paste.
213
+
214
+ This puts the user in charge of keeping them up to date with the gem.
215
+
216
+ ```ruby
217
+ #
218
+ # 1. Register some service endpoints
219
+ #
220
+ StubRequests.register_service(:documents, "https://company.com/api/v1") do
221
+ get "documents/:id", as: :documents_show
222
+ get "documents", as: :documents_index
223
+ post "documents", as: :documents_create
224
+ patch "documents/:id", as: :documents_update
225
+ put "documents/:id", as: :document_put
226
+ delete "documents/:id", as: :documents_destroy
227
+ end
228
+
229
+ #
230
+ # 2. Print the stub definitions to STDOUT
231
+ #
232
+ StubRequests.print_stubs(:documents) #=>
233
+
234
+ #
235
+ # 3. Copy the stubs into a module
236
+ #
237
+ module DocumentStubs
238
+ def stub_documents_show(id:, &block)
239
+ StubRequests.stub_endpoint(:documents, :documents_show, id: id, &block)
240
+ end
241
+
242
+
243
+ def stub_documents_index(&block)
244
+ StubRequests.stub_endpoint(:documents, :documents_index, &block)
245
+ end
246
+
247
+
248
+ def stub_documents_create(&block)
249
+ StubRequests.stub_endpoint(:documents, :documents_create, &block)
250
+ end
251
+
252
+
253
+ def stub_documents_update(id:, &block)
254
+ StubRequests.stub_endpoint(:documents, :documents_update, id: id, &block)
255
+ end
256
+
257
+
258
+ def stub_document_put(id:, &block)
259
+ StubRequests.stub_endpoint(:documents, :document_put, id: id, &block)
260
+ end
261
+
262
+
263
+ def stub_documents_destroy(id:, &block)
264
+ StubRequests.stub_endpoint(:documents, :documents_destroy, id: id, &block)
265
+ end
266
+ end
267
+ ```
268
+
269
+
142
270
  <a id="future-improvements"></a>
143
271
  ## Future Improvements
144
272
 
data/bin/console CHANGED
@@ -4,12 +4,10 @@
4
4
  require "bundler/setup"
5
5
  require "stub_requests"
6
6
 
7
- # You can add fixtures and/or initialization code here to make experimenting
8
- # with your gem easier. You can also use a different console, if you like.
9
-
10
- # (If you use this, don't forget to add pry to your Gemfile!)
11
- # require "pry"
12
- # Pry.start
13
-
14
- require "irb"
15
- IRB.start(__FILE__)
7
+ begin
8
+ require "pry"
9
+ Pry.start(__FILE__)
10
+ rescue LoadError, NameError
11
+ require "irb"
12
+ IRB.start(__FILE__)
13
+ end
@@ -105,8 +105,7 @@ module RSpec
105
105
  # before { subject.age = 25 }
106
106
  # its(:age) { should eq(25) }
107
107
  # end
108
- # :reek:DuplicateMethodCall
109
- # :reek:TooManyStatements
108
+ #
110
109
  def it!(*options, &block)
111
110
  it_lambda_caller = caller.reject { |file_line| file_line =~ %r{/rspec/subject_as_lambda} }
112
111
  describe(nil, caller: it_lambda_caller) do
@@ -15,7 +15,6 @@ module StubRequests
15
15
  #
16
16
  # @author Mikael Henriksson <mikael@zoolutions.se>
17
17
  #
18
- # :reek:DataClump
19
18
  module API
20
19
  # extends "self"
21
20
  # @!parse extend self
@@ -34,22 +33,47 @@ module StubRequests
34
33
  #
35
34
  # @example Register a service with endpoints
36
35
  # register_service(:documents, "https://company.com/api/v1") do
37
- # register_endpoints do
38
- # register(:show, :get, "documents/:id")
39
- # register(:index, :get, "documents")
40
- # register(:create, :post, "documents")
41
- # register(:update, :patch, "documents/:id")
42
- # register(:destroy, :delete, "documents/:id")
43
- # end
36
+ # get "documents/:id", as: :show
37
+ # get "documents", as: :index
38
+ # post "documents", as: :create
39
+ # patch "documents/:id", as: :update
40
+ # delete "documents/:id", as: :destroy
44
41
  # end
45
42
  #
46
43
  # @return [Service] a new service or a previously registered service
47
44
  #
48
- # :reek:UtilityFunction
49
45
  def register_service(service_id, service_uri, &block)
50
46
  StubRequests::ServiceRegistry.register_service(service_id, service_uri, &block)
51
47
  end
52
48
 
49
+ #
50
+ # Define stub methods for service in the receiver
51
+ #
52
+ #
53
+ # @see DSL#define_stubs
54
+ #
55
+ # @param [Symbol] service_id the id of a registered service
56
+ # @param [Module] receiver the receiver of the stub methods
57
+ #
58
+ # @return [void] outputs a list of methods to the console
59
+ #
60
+ def define_stubs(service_id, receiver:)
61
+ DSL.new(service_id, receiver: receiver).define_stubs
62
+ end
63
+
64
+ #
65
+ # Print stub method definitions to manually add to a module or class
66
+ #
67
+ # @see DSL#print_stubs
68
+ #
69
+ # @param [Symbol] service_id the id of a registered service
70
+ #
71
+ # @return [void] prints to STDOUT
72
+ #
73
+ def print_stubs(service_id)
74
+ DSL.new(service_id).print_stubs
75
+ end
76
+
53
77
  #
54
78
  # Stub a request to a registered service endpoint
55
79
  #
@@ -61,7 +85,7 @@ module StubRequests
61
85
  # @note the kind of timeout error raised by webmock is depending on the HTTP client used
62
86
  #
63
87
  # @example Stub a request to a registered service endpoint using block version
64
- # register_stub(:documents, :index) do
88
+ # stub_endpoint(:documents, :index) do
65
89
  # with(headers: { "Accept" => "application/json" }}})
66
90
  # to_return(body: "No content", status: 204)
67
91
  # end
@@ -69,8 +93,6 @@ module StubRequests
69
93
  # @see #stub_http_request
70
94
  # @return [WebMock::RequestStub] a mocked request
71
95
  #
72
- # :reek:UtilityFunction
73
- # :reek:LongParameterList { max_params: 5 }
74
96
  def stub_endpoint(service_id, endpoint_id, route_params = {}, &callback)
75
97
  StubRequests::ServiceRegistry.stub_endpoint(service_id, endpoint_id, route_params, &callback)
76
98
  end
@@ -85,8 +107,6 @@ module StubRequests
85
107
  #
86
108
  # @return [void]
87
109
  #
88
- # :reek:UtilityFunction
89
- # :reek:LongParameterList
90
110
  def register_callback(service_id, endpoint_id, verb, callback)
91
111
  StubRequests::CallbackRegistry.register(service_id, endpoint_id, verb, callback)
92
112
  end
@@ -99,7 +119,6 @@ module StubRequests
99
119
  #
100
120
  # @return [void]
101
121
  #
102
- # :reek:UtilityFunction
103
122
  def unregister_callback(service_id, endpoint_id, verb)
104
123
  StubRequests::CallbackRegistry.unregister(service_id, endpoint_id, verb)
105
124
  end
@@ -30,13 +30,11 @@ module StubRequests
30
30
  #
31
31
  # @return [void]
32
32
  #
33
- # :reek:UtilityFunction
34
33
  def validate!(name:, value:, type:)
35
34
  validate_type!(:name, name, [Symbol, String]) unless name
36
35
  validate_type!(name, value, type) if type
37
36
  end
38
37
 
39
- # :reek:UtilityFunction
40
38
  def validate_type!(name, value, type)
41
39
  expected_types = Array(type).flatten
42
40
  return if expected_types.any? { |is_a| value.is_a?(is_a) }
@@ -47,8 +47,15 @@ module StubRequests
47
47
  self.callback = callback
48
48
  end
49
49
 
50
- def call(*args)
51
- callback.call(*args)
50
+ def call(request_stub)
51
+ case arity
52
+ when 0
53
+ callback.call
54
+ when 1
55
+ callback.call(request_stub)
56
+ else
57
+ raise InvalidCallback, "The callback for a callback can either take 0 or 1 arguments (was #{arity})"
58
+ end
52
59
  end
53
60
 
54
61
  def arity
@@ -13,9 +13,6 @@ module StubRequests
13
13
  # @author Mikael Henriksson <mikael@zoolutions.se>
14
14
  # @since 0.1.3
15
15
  #
16
- # :reek:UtilityFunction
17
- # :reek:DataClump
18
- # :reek:FeatureEnvy
19
16
  class CallbackRegistry
20
17
  include Singleton
21
18
  include Enumerable
@@ -32,7 +29,6 @@ module StubRequests
32
29
  #
33
30
  # @return [Callback]
34
31
  #
35
- # :reek:LongParameterList
36
32
  def self.register(service_id, endpoint_id, verb, callback)
37
33
  instance.register(service_id, endpoint_id, verb, callback)
38
34
  end
@@ -110,7 +106,6 @@ module StubRequests
110
106
  #
111
107
  # @return [Callback] the added callback
112
108
  #
113
- # :reek:LongParameterList
114
109
  def register(service_id, endpoint_id, verb, block)
115
110
  callback = find_by(service_id, endpoint_id, verb)
116
111
  return callback if callback
@@ -130,7 +125,6 @@ module StubRequests
130
125
  #
131
126
  # @return [Callback] the deleted callback
132
127
  #
133
- # :reek:ControlParameter
134
128
  def unregister(service_id, endpoint_id, verb)
135
129
  return unless (callback = find_by(service_id, endpoint_id, verb))
136
130
 
@@ -140,14 +134,14 @@ module StubRequests
140
134
  #
141
135
  # Notifies subscribers that a request was made
142
136
  #
143
- # @param [RequestStub] request the stubbed request
137
+ # @param [RequestStub] request_stub the stubbed request
144
138
  #
145
139
  # @return [void]
146
140
  #
147
- def invoke_callbacks(request)
148
- return unless (callback = find_by(request.service_id, request.endpoint_id, request.verb))
141
+ def invoke_callbacks(request_stub)
142
+ return unless (callback = find_by(request_stub.service_id, request_stub.endpoint_id, request_stub.verb))
149
143
 
150
- dispatch_callback(request, callback)
144
+ callback.call(request_stub)
151
145
  end
152
146
 
153
147
  private
@@ -162,8 +156,6 @@ module StubRequests
162
156
  #
163
157
  # @return [Callback]
164
158
  #
165
- # :reek:ControlParameter
166
- # :reek:DuplicateMethodCall
167
159
  def find_by(service_id, endpoint_id, verb)
168
160
  find do |sub|
169
161
  sub.service_id == service_id &&
@@ -171,18 +163,5 @@ module StubRequests
171
163
  ([sub.verb, verb].include?(:any) || sub.verb == verb)
172
164
  end
173
165
  end
174
-
175
- def dispatch_callback(request_stub, callback)
176
- arity = callback.arity
177
-
178
- case arity
179
- when 0
180
- callback.call
181
- when 1
182
- callback.call(request_stub)
183
- else
184
- raise InvalidCallback, "The callback for a callback can either take 0 or 1 arguments (was #{arity})"
185
- end
186
- end
187
166
  end
188
167
  end
@@ -52,7 +52,7 @@ module StubRequests
52
52
  def to_s
53
53
  <<~METHOD
54
54
  def #{name}(#{keywords})
55
- stub_endpoint(:#{service_id}, :#{endpoint_id}, #{arguments})
55
+ StubRequests.stub_endpoint(:#{service_id}, :#{endpoint_id}, #{arguments})
56
56
  end
57
57
  METHOD
58
58
  end
@@ -10,9 +10,9 @@ module StubRequests
10
10
  # @example **Register service with endpoints**
11
11
  # StubRequests.register_service(:documents, "https://company.com/api/v1") do
12
12
  # register_endpoints do
13
- # register(:show, :get, "documents/:id")
14
- # register(:index, :get, "documents")
15
- # register(:create, :post, "documents")
13
+ # get "documents/:id", as: :documents_show
14
+ # get "documents", as: :documents_index
15
+ # post "documents", as: :documents_create
16
16
  # end
17
17
  # end
18
18
  # @example **Create a receiver module for the stub methods**
@@ -20,7 +20,7 @@ module StubRequests
20
20
  #
21
21
  # Stubs.instance_methods #=> []
22
22
  # @example **Define the endpoint methods using the DSL**
23
- # StubRequests::DSL.define_endpoint_methods(
23
+ # StubRequests::DSL.define_stubs(
24
24
  # :documents, receiver: Stubs
25
25
  # )
26
26
  #
@@ -28,17 +28,17 @@ module StubRequests
28
28
  #
29
29
  # Stubs.instance_methods #=> [:stub_documents_show, :stub_documents_index, :stub_documents_create]
30
30
  # module Stubs
31
- # def stub_documents_show(id:, &block)
32
- # stub_endpoint(:documents, :show, id: id, &block)
33
- # end
31
+ # def stub_documents_show(id:, &block)
32
+ # stub_endpoint(:documents, :show, id: id, &block)
33
+ # end
34
34
  #
35
- # def stub_documents_index(&block)
36
- # stub_endpoint(:documents, :index, &block)
37
- # end
35
+ # def stub_documents_index(&block)
36
+ # stub_endpoint(:documents, :index, &block)
37
+ # end
38
38
  #
39
- # def stub_documents_create(&block)
40
- # stub_endpoint(:documents, :create, &block)
41
- # end
39
+ # def stub_documents_create(&block)
40
+ # stub_endpoint(:documents, :create, &block)
41
+ # end
42
42
  # end
43
43
  #
44
44
  # @example **Use the helper methods in your tests**
@@ -70,24 +70,60 @@ module StubRequests
70
70
  # expect(response).to be_json_eql(response_body.to_json)
71
71
  # end
72
72
  class DSL
73
- def self.define_endpoint_methods(service_id, receiver:)
74
- new(service_id, receiver: receiver).define_endpoint_methods
75
- end
76
-
77
- attr_reader :service, :receiver, :endpoints
73
+ #
74
+ # @!attribute [r] service
75
+ # @return [Service] an instance of a service
76
+ attr_reader :service
77
+ #
78
+ # @!attribute [r] receiver
79
+ # @return [Module, nil] the receiver module
80
+ attr_reader :receiver
81
+ #
82
+ # @!attribute [r] endpoints
83
+ # @return [Array<Endpoint>] a collection of endpoints
84
+ attr_reader :endpoints
78
85
 
79
- def initialize(service_id, receiver:)
80
- @service = StubRequests::ServiceRegistry.instance.find(service_id)
86
+ #
87
+ # Initialize a new instance of DSL
88
+ #
89
+ # @param [Symbol] service_id the id of a registered service
90
+ # @param [Module] receiver the receiver of the stub methods
91
+ #
92
+ def initialize(service_id, receiver: nil)
93
+ @service = StubRequests::ServiceRegistry.instance.find!(service_id)
81
94
  @receiver = receiver
82
95
  @endpoints = service.endpoints.endpoints.values
83
96
  end
84
97
 
85
- def define_endpoint_methods
98
+ #
99
+ # Defines stub methods for #endpoints in the #receiver
100
+ #
101
+ #
102
+ # @return [void]
103
+ #
104
+ def define_stubs
86
105
  receiver.send(:include, StubRequests::API)
87
106
 
88
- endpoints.each do |endpoint|
89
- definition = MethodDefinition.new(service.id, endpoint.id, endpoint.route_params)
90
- DefineMethod.new(definition, receiver).define
107
+ method_definitions.each do |method_definition|
108
+ DefineMethod.new(method_definition, receiver).define
109
+ end
110
+ end
111
+
112
+ #
113
+ # Prints stub methods for #endpoints to STDOUT
114
+ #
115
+ #
116
+ # @return [void]
117
+ #
118
+ def print_stubs
119
+ method_definitions.each do |method_definition|
120
+ puts("#{method_definition}\n\n")
121
+ end
122
+ end
123
+
124
+ def method_definitions
125
+ @method_definitions ||= endpoints.map do |endpoint|
126
+ MethodDefinition.new(service.id, endpoint.id, endpoint.route_params)
91
127
  end
92
128
  end
93
129
  end
@@ -49,7 +49,6 @@ module StubRequests
49
49
  #
50
50
  # @return [Endpoint]
51
51
  #
52
- # :reek:LongParameterList { max_params: 4 }
53
52
  def register(endpoint_id, verb, path)
54
53
  endpoint =
55
54
  if (endpoint = find(endpoint_id))
@@ -63,9 +62,106 @@ module StubRequests
63
62
  endpoint
64
63
  end
65
64
 
65
+ #
66
+ # Convenience wrapper for register
67
+ #
68
+ #
69
+ # @example **Register a get endpoint**
70
+ # . get("documents/:id", as: :documents_show)
71
+ #
72
+ # @param [String] path the path to the endpoint
73
+ # @param [Symbol] as the id of the endpoint
74
+ #
75
+ # @return [Endpoint] the registered endpoint
76
+ #
77
+ def any(path, as:) # rubocop:disable Naming/UncommunicativeMethodParamName
78
+ register(as, __method__, path)
79
+ end
80
+
81
+ #
82
+ # Convenience wrapper for register
83
+ #
84
+ #
85
+ # @example **Register a get endpoint**
86
+ # . get("documents/:id", as: :documents_show)
87
+ #
88
+ # @param [String] path the path to the endpoint
89
+ # @param [Symbol] as the id of the endpoint
90
+ #
91
+ # @return [Endpoint] the registered endpoint
92
+ #
93
+ def get(path, as:) # rubocop:disable Naming/UncommunicativeMethodParamName
94
+ register(as, __method__, path)
95
+ end
96
+
97
+ #
98
+ # Register a :post endpoint
99
+ #
100
+ #
101
+ # @example **Register a post endpoint**
102
+ # . post("documents", as: :documents_create)
103
+ #
104
+ # @param [String] path the path to the endpoint
105
+ # @param [Symbol] as the id of the endpoint
106
+ #
107
+ # @return [Endpoint] the registered endpoint
108
+ #
109
+ def post(path, as:) # rubocop:disable Naming/UncommunicativeMethodParamName
110
+ register(as, __method__, path)
111
+ end
112
+
113
+ #
114
+ # Register a :patch endpoint
115
+ #
116
+ #
117
+ # @example **Register a patch endpoint**
118
+ # . patch("documents/:id", as: :documents_update)
119
+ #
120
+ # @param [String] path the path to the endpoint
121
+ # @param [Symbol] as the id of the endpoint
122
+ #
123
+ # @return [Endpoint] the registered endpoint
124
+ #
125
+ def patch(path, as:) # rubocop:disable Naming/UncommunicativeMethodParamName
126
+ register(as, __method__, path)
127
+ end
128
+
129
+ #
130
+ # Register a :put endpoint
131
+ #
132
+ #
133
+ # @example **Register a put endpoint**
134
+ # . put("documents/:id", as: :documents_update)
135
+ #
136
+ # @param [String] path the path to the endpoint
137
+ # @param [Symbol] as the id of the endpoint
138
+ #
139
+ # @return [Endpoint] the registered endpoint
140
+ #
141
+ def put(path, as:) # rubocop:disable Naming/UncommunicativeMethodParamName
142
+ register(as, __method__, path)
143
+ end
144
+
145
+ #
146
+ # Register a :delete endpoint
147
+ #
148
+ #
149
+ # @example **Register a delete endpoint**
150
+ # . delete("documents/:id", as: :documents_destroy)
151
+ #
152
+ # @param [String] path the path to the endpoint
153
+ # @param [Symbol] as the id of the endpoint
154
+ #
155
+ # @return [Endpoint] the registered endpoint
156
+ #
157
+ def delete(path, as:) # rubocop:disable Naming/UncommunicativeMethodParamName
158
+ register(as, __method__, path)
159
+ end
160
+
66
161
  #
67
162
  # Updates an endpoint
68
163
  #
164
+ #
69
165
  # @param [Symbol] endpoint_id the id of the endpoint
70
166
  # @param [Symbol] verb a HTTP verb
71
167
  # @param [String] path the path to the endpoint
@@ -74,7 +170,6 @@ module StubRequests
74
170
  #
75
171
  # @return [Endpoint] returns the updated endpoint
76
172
  #
77
- # :reek:LongParameterList { max_params: 4 }
78
173
  def update(endpoint_id, verb, path)
79
174
  endpoint = find!(endpoint_id)
80
175
  endpoint.update(verb, path)
@@ -83,6 +178,7 @@ module StubRequests
83
178
  #
84
179
  # Removes an endpoint from the collection
85
180
  #
181
+ #
86
182
  # @param [Symbol] endpoint_id the id of the endpoint, `:file_service`
87
183
  #
88
184
  # @return [Endpoint] the endpoint that was removed
@@ -94,6 +190,7 @@ module StubRequests
94
190
  #
95
191
  # Fetches an endpoint from the collection
96
192
  #
193
+ #
97
194
  # @param [<type>] endpoint_id <description>
98
195
  #
99
196
  # @return [Endpoint]
@@ -105,6 +202,7 @@ module StubRequests
105
202
  #
106
203
  # Fetches an endpoint from the collection or raises an error
107
204
  #
205
+ #
108
206
  # @param [Symbol] endpoint_id the id of the endpoint
109
207
  #
110
208
  # @raise [EndpointNotFound] when an endpoint couldn't be found
@@ -118,6 +216,7 @@ module StubRequests
118
216
  #
119
217
  # Returns a descriptive string with all endpoints in the collection
120
218
  #
219
+ #
121
220
  # @return [String]
122
221
  #
123
222
  def to_s
@@ -38,7 +38,6 @@ module StubRequests
38
38
  #
39
39
  # @return [void]
40
40
  #
41
- # :reek:LongParameterList
42
41
  def self.call(name, type, default, properties)
43
42
  new(name, type, default, properties).run_validations
44
43
  end
@@ -67,12 +66,11 @@ module StubRequests
67
66
  # @param [Object] default the default value of the property
68
67
  # @param [Hash] properties the list of currently defined properties
69
68
  #
70
- # :reek:LongParameterList
71
69
  def initialize(name, type, default = nil, properties = {})
72
70
  @type = Array(type).flatten
73
71
  @default = default
74
72
  @name = name
75
- @properties = properties
73
+ @properties = properties || {}
76
74
  end
77
75
 
78
76
  #
@@ -127,6 +125,7 @@ module StubRequests
127
125
  # @return [void]
128
126
  #
129
127
  def validate_undefined
128
+ return unless properties
130
129
  return unless (prop = properties[name])
131
130
 
132
131
  raise PropertyDefined, name: name, type: prop[:type], default: prop[:default]
@@ -33,7 +33,6 @@ module StubRequests
33
33
  #
34
34
  # @author Mikael Henriksson <mikael@zoolutions.se>
35
35
  #
36
- # :reek:DataClump
37
36
  module ClassMethods
38
37
  #
39
38
  # Define property methods for the name
@@ -43,7 +42,7 @@ module StubRequests
43
42
  # @param [Hash<Symbol>] options a hash with options
44
43
  # @option options [Object] :default a default value for the property
45
44
  #
46
- # @return [Object] the whatever
45
+ # @return [void]
47
46
  #
48
47
  def property(name, type:, **options)
49
48
  type = normalize_type(type, options)
@@ -65,18 +64,21 @@ module StubRequests
65
64
 
66
65
  # @api private
67
66
  def define_property(name, type, default)
68
- property_reader(name)
67
+ property_reader(name, default)
69
68
  property_predicate(name)
70
69
  property_writer(name, type)
71
70
 
71
+ set_property_default(name, default)
72
72
  set_property_defined(name, type, default)
73
73
  end
74
74
 
75
75
  # @api private
76
- def property_reader(name)
76
+ def property_reader(name, default)
77
+ invar = "@#{name}"
77
78
  silence_redefinition_of_method(name.to_s)
78
79
  redefine_method(name) do
79
- instance_variable_get("@#{name}") || properties.dig(name, :default)
80
+ instance_variable_set(invar, default) unless instance_variable_defined?(invar)
81
+ instance_variable_get(invar)
80
82
  end
81
83
  end
82
84
 
@@ -96,8 +98,13 @@ module StubRequests
96
98
  end
97
99
  end
98
100
 
101
+ def set_property_default(name, default)
102
+ instance_variable_set("@#{name}", default)
103
+ end
104
+
99
105
  # @api private
100
106
  def set_property_defined(name, type, default)
107
+ self.properties ||= {}
101
108
  properties[name] = { type: type, default: default }
102
109
  end
103
110
  end
@@ -13,7 +13,6 @@ module StubRequests
13
13
  # @author Mikael Henriksson <mikael@zoolutions.se>
14
14
  # @since 0.1.2
15
15
  #
16
- # :reek:TooManyInstanceVariables
17
16
  class RequestStub
18
17
  include Property
19
18
  extend Forwardable
@@ -24,11 +24,11 @@ module StubRequests
24
24
  #
25
25
  # @example Register a service with endpoints
26
26
  # register_service(:documents, "https://company.com/api/v1") do
27
- # register(:show, :get, "documents/:id")
28
- # register(:index, :get, "documents")
29
- # register(:create, :post, "documents")
30
- # register(:update, :patch, "documents/:id")
31
- # register(:destroy, :delete, "documents/:id")
27
+ # get "documents/:id", as: :show
28
+ # get "documents", as: :index
29
+ # post "documents", as: :create
30
+ # patch "documents/:id", as: :update
31
+ # delete "documents/:id", as: :destroy
32
32
  # end
33
33
  #
34
34
  # @return [Service] a new service or a previously registered service
@@ -50,35 +50,27 @@ module StubRequests
50
50
  # @note the kind of timeout error raised by webmock is depending on the HTTP client used
51
51
  #
52
52
  # @example Stub a request to a registered service endpoint
53
- # register_stub(
54
- # :google_api,
55
- # :get_map_location,
56
- # {}, # No URI replacements needed for this endpoint
57
- # )
58
- # .to_return(body: "No content", status: 204)
53
+ # stub_endpoint(:google_api, :get_map_location)
54
+ # .to_return(body: "No content", status: 204)
59
55
  #
60
56
  # @example Stub a request to a registered service endpoint using block
61
- # register_stub(:documents, :index) do
57
+ # stub_endpoint(:documents, :index) do
62
58
  # with(headers: { "Accept" => "application/json" }}})
63
59
  # to_return(body: "No content", status: 204)
64
60
  # end
65
61
  #
66
- # @see #stub_http_request
67
62
  # @return [WebMock::RequestStub] a mocked request
68
63
  #
69
- # :reek:UtilityFunction
70
- # :reek:LongParameterList { max_params: 5 }
71
64
  def self.stub_endpoint(service_id, endpoint_id, route_params = {}, &callback)
72
65
  service, endpoint, uri = StubRequests::URI.for_service_endpoint(service_id, endpoint_id, route_params)
73
- endpoint_stub = WebMock::Builder.build(endpoint.verb, uri, {}, &callback)
66
+ webmock_stub = WebMock::Builder.build(endpoint.verb, uri, {}, &callback)
74
67
 
75
- StubRegistry.record(service, endpoint, endpoint_stub)
76
- ::WebMock::StubRegistry.instance.register_request_stub(endpoint_stub)
68
+ StubRegistry.record(service, endpoint, webmock_stub)
69
+ ::WebMock::StubRegistry.instance.register_request_stub(webmock_stub)
77
70
  end
78
71
 
79
72
  # @api private
80
73
  # Used only for testing purposes
81
- # :reek:LongParameterList { max_params: 4 }
82
74
  def self.__stub_endpoint(service_id, endpoint_id, route_params = {})
83
75
  _service, endpoint, uri = StubRequests::URI.for_service_endpoint(service_id, endpoint_id, route_params)
84
76
  endpoint_stub = WebMock::Builder.build(endpoint.verb, uri)
@@ -14,7 +14,6 @@ module StubRequests
14
14
  # @author Mikael Henriksson <mikael@zoolutions.se>
15
15
  # @since 0.1.2
16
16
  #
17
- # :reek:DataClump
18
17
  class StubRegistry
19
18
  # includes "Singleton"
20
19
  # @!parse include Singleton
@@ -145,13 +144,10 @@ module StubRequests
145
144
  find_endpoint_stub(service, endpoint) || initialize_endpoint_stub(service, endpoint)
146
145
  end
147
146
 
148
- # :reek:UtilityFunction
149
- # :reek:FeatureEnvy
150
147
  def find_endpoint_stub(service, endpoint)
151
148
  find { |ep| ep.service_id == service.id && ep.endpoint_id == endpoint.id }
152
149
  end
153
150
 
154
- # :reek:UtilityFunction
155
151
  def initialize_endpoint_stub(service, endpoint)
156
152
  EndpointStub.new(service, endpoint)
157
153
  end
@@ -18,7 +18,6 @@ module StubRequests
18
18
  #
19
19
  # @author Mikael Henriksson <mikael@zoolutions.se>
20
20
  #
21
- # :reek:TooManyInstanceVariables { max_instance_variables: 6 }
22
21
  class Builder
23
22
  #
24
23
  # @return [Regexp] A pattern for matching url segment keys
@@ -9,5 +9,5 @@
9
9
  module StubRequests
10
10
  #
11
11
  # @return [String] a version string
12
- VERSION = "0.1.4"
12
+ VERSION = "0.1.5"
13
13
  end
@@ -42,6 +42,7 @@ Gem::Specification.new do |spec|
42
42
  # ===== Testing =====
43
43
  spec.add_development_dependency "appraisal", ">= 2.2.0"
44
44
  spec.add_development_dependency "json_spec", ">= 1.1.5"
45
+ spec.add_development_dependency "fuubar", ">= 2.3"
45
46
  spec.add_development_dependency "rspec", ">= 3.8"
46
47
  spec.add_development_dependency "rspec-its", ">= 1.2"
47
48
  spec.add_development_dependency "rubocop", "~> 0.63.1"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stub_requests
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mikael Henriksson
@@ -146,6 +146,20 @@ dependencies:
146
146
  - - ">="
147
147
  - !ruby/object:Gem::Version
148
148
  version: 1.1.5
149
+ - !ruby/object:Gem::Dependency
150
+ name: fuubar
151
+ requirement: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - ">="
154
+ - !ruby/object:Gem::Version
155
+ version: '2.3'
156
+ type: :development
157
+ prerelease: false
158
+ version_requirements: !ruby/object:Gem::Requirement
159
+ requirements:
160
+ - - ">="
161
+ - !ruby/object:Gem::Version
162
+ version: '2.3'
149
163
  - !ruby/object:Gem::Dependency
150
164
  name: rspec
151
165
  requirement: !ruby/object:Gem::Requirement