stub_requests 0.1.1 → 0.1.2
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/.gitignore +5 -2
- data/.reek.yml +1 -0
- data/.rubocop.yml +33 -35
- data/.simplecov +14 -8
- data/.yardopts +1 -1
- data/CHANGELOG.md +4 -1
- data/README.md +19 -11
- data/Rakefile +1 -3
- data/bin/update_docs.sh +16 -0
- data/gemfiles/webmock_2.3.gemfile.lock +1 -1
- data/gemfiles/webmock_3.5.gemfile.lock +1 -1
- data/gemfiles/webmock_develop.gemfile.lock +1 -1
- data/lib/rspec/subject_as_lambda.rb +138 -0
- data/lib/stub_requests/api.rb +42 -8
- data/lib/stub_requests/argument_validation.rb +17 -6
- data/lib/stub_requests/configuration.rb +21 -0
- data/lib/stub_requests/core_ext/all.rb +4 -0
- data/lib/stub_requests/core_ext/array/extract_options.rb +32 -0
- data/lib/stub_requests/core_ext/class/attribute.rb +61 -0
- data/lib/stub_requests/core_ext/kernel/singleton_class.rb +12 -0
- data/lib/stub_requests/core_ext/module/redefine_method.rb +44 -0
- data/lib/stub_requests/core_ext/object/blank.rb +99 -155
- data/lib/stub_requests/endpoint.rb +28 -30
- data/lib/stub_requests/endpoint_registry.rb +18 -16
- data/lib/stub_requests/exceptions.rb +84 -0
- data/lib/stub_requests/hash_util.rb +2 -0
- data/lib/stub_requests/metrics/endpoint_stat.rb +97 -0
- data/lib/stub_requests/metrics/registry.rb +132 -0
- data/lib/stub_requests/metrics/stub_stat.rb +80 -0
- data/lib/stub_requests/metrics.rb +32 -0
- data/lib/stub_requests/property/validator.rb +136 -0
- data/lib/stub_requests/property.rb +99 -0
- data/lib/stub_requests/service.rb +12 -53
- data/lib/stub_requests/service_registry.rb +8 -9
- data/lib/stub_requests/stub_requests.rb +23 -51
- data/lib/stub_requests/uri/builder.rb +5 -1
- data/lib/stub_requests/uri/scheme.rb +3 -1
- data/lib/stub_requests/uri/suffix.rb +5 -0
- data/lib/stub_requests/uri/validator.rb +3 -1
- data/lib/stub_requests/uri.rb +34 -0
- data/lib/stub_requests/version.rb +1 -1
- data/lib/stub_requests/webmock/builder.rb +116 -0
- data/lib/stub_requests/webmock/stub_registry_extension.rb +46 -0
- data/lib/stub_requests.rb +21 -3
- metadata +19 -49
- data/docs/.gitkeep +0 -0
- data/docs/Array.html +0 -137
- data/docs/FalseClass.html +0 -232
- data/docs/Hash.html +0 -137
- data/docs/NilClass.html +0 -232
- data/docs/Numeric.html +0 -233
- data/docs/Object.html +0 -396
- data/docs/String.html +0 -298
- data/docs/StubRequests/API.html +0 -651
- data/docs/StubRequests/ArgumentValidation.html +0 -309
- data/docs/StubRequests/Endpoint.html +0 -1187
- data/docs/StubRequests/EndpointNotFound.html +0 -157
- data/docs/StubRequests/EndpointRegistry.html +0 -1527
- data/docs/StubRequests/Error.html +0 -153
- data/docs/StubRequests/HashUtil.html +0 -304
- data/docs/StubRequests/InvalidType.html +0 -252
- data/docs/StubRequests/InvalidUri.html +0 -252
- data/docs/StubRequests/Service.html +0 -1307
- data/docs/StubRequests/ServiceHaveEndpoints.html +0 -244
- data/docs/StubRequests/ServiceNotFound.html +0 -252
- data/docs/StubRequests/ServiceRegistry.html +0 -1031
- data/docs/StubRequests/URI/Builder.html +0 -1194
- data/docs/StubRequests/URI/Scheme.html +0 -315
- data/docs/StubRequests/URI/Suffix.html +0 -315
- data/docs/StubRequests/URI/Validator.html +0 -770
- data/docs/StubRequests/URI.html +0 -144
- data/docs/StubRequests/UriSegmentMismatch.html +0 -157
- data/docs/StubRequests/WebMockBuilder.html +0 -887
- data/docs/StubRequests.html +0 -452
- data/docs/Time.html +0 -232
- data/docs/TrueClass.html +0 -232
- data/docs/_config.yml +0 -1
- data/docs/_index.html +0 -391
- data/docs/class_list.html +0 -51
- data/docs/css/common.css +0 -1
- data/docs/css/full_list.css +0 -58
- data/docs/css/style.css +0 -496
- data/docs/file.README.html +0 -225
- data/docs/file_list.html +0 -56
- data/docs/frames.html +0 -17
- data/docs/index.html +0 -225
- data/docs/js/app.js +0 -292
- data/docs/js/full_list.js +0 -216
- data/docs/js/jquery.js +0 -4
- data/docs/method_list.html +0 -707
- data/docs/top-level-namespace.html +0 -112
- data/lib/stub_requests/webmock_builder.rb +0 -108
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @see Hash
|
4
|
+
# @api private
|
5
|
+
class Hash
|
6
|
+
# @api private
|
7
|
+
def extractable_options?
|
8
|
+
instance_of?(Hash)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# @see Array
|
13
|
+
# @api private
|
14
|
+
class Array
|
15
|
+
# @api private
|
16
|
+
def extract_options!
|
17
|
+
if last.is_a?(Hash) && last.extractable_options?
|
18
|
+
pop
|
19
|
+
else
|
20
|
+
{}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# @api private
|
25
|
+
def extract_options
|
26
|
+
if last.is_a?(Hash) && last.extractable_options?
|
27
|
+
last
|
28
|
+
else
|
29
|
+
{}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
unless defined?(Rails) || defined?(ActiveSupport)
|
4
|
+
# See {Class}
|
5
|
+
# @api private
|
6
|
+
class Class
|
7
|
+
# @api private
|
8
|
+
def class_attribute(*attrs)
|
9
|
+
options = attrs.extract_options!
|
10
|
+
default_value = options.fetch(:default, nil)
|
11
|
+
|
12
|
+
attrs.each do |name|
|
13
|
+
singleton_class.silence_redefinition_of_method(name)
|
14
|
+
define_singleton_method(name) { nil }
|
15
|
+
|
16
|
+
singleton_class.silence_redefinition_of_method("#{name}?")
|
17
|
+
define_singleton_method("#{name}?") { !!public_send(name) }
|
18
|
+
|
19
|
+
ivar = "@#{name}"
|
20
|
+
|
21
|
+
singleton_class.silence_redefinition_of_method("#{name}=")
|
22
|
+
define_singleton_method("#{name}=") do |val|
|
23
|
+
singleton_class.class_eval do
|
24
|
+
redefine_method(name) { val }
|
25
|
+
end
|
26
|
+
|
27
|
+
if singleton_class?
|
28
|
+
class_eval do
|
29
|
+
redefine_method(name) do
|
30
|
+
if instance_variable_defined? ivar
|
31
|
+
instance_variable_get ivar
|
32
|
+
else
|
33
|
+
singleton_class.send name
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
val
|
39
|
+
end
|
40
|
+
|
41
|
+
redefine_method(name) do
|
42
|
+
if instance_variable_defined?(ivar)
|
43
|
+
instance_variable_get ivar
|
44
|
+
else
|
45
|
+
self.class.public_send name
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
redefine_method("#{name}?") { !!public_send(name) }
|
50
|
+
|
51
|
+
redefine_method("#{name}=") do |val|
|
52
|
+
instance_variable_set ivar, val
|
53
|
+
end
|
54
|
+
|
55
|
+
unless default_value.nil?
|
56
|
+
self.send("#{name}=", default_value)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
unless defined?(Rails) || defined?(ActiveSupport)
|
4
|
+
# See {Module}
|
5
|
+
# @api private
|
6
|
+
class Module
|
7
|
+
# @api private
|
8
|
+
def silence_redefinition_of_method(method)
|
9
|
+
if method_defined?(method) || private_method_defined?(method)
|
10
|
+
alias_method :__rails_redefine, method
|
11
|
+
remove_method :__rails_redefine
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Replaces the existing method definition, if there is one, with the passed
|
16
|
+
# block as its body.
|
17
|
+
# @api private
|
18
|
+
def redefine_method(method, &block)
|
19
|
+
visibility = method_visibility(method)
|
20
|
+
silence_redefinition_of_method(method)
|
21
|
+
define_method(method, &block)
|
22
|
+
send(visibility, method)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Replaces the existing singleton method definition, if there is one, with
|
26
|
+
# the passed block as its body.
|
27
|
+
# @api private
|
28
|
+
def redefine_singleton_method(method, &block)
|
29
|
+
singleton_class.redefine_method(method, &block)
|
30
|
+
end
|
31
|
+
|
32
|
+
# @api private
|
33
|
+
def method_visibility(method) # :nodoc:
|
34
|
+
case
|
35
|
+
when private_method_defined?(method)
|
36
|
+
:private
|
37
|
+
when protected_method_defined?(method)
|
38
|
+
:protected
|
39
|
+
else
|
40
|
+
:public
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -1,171 +1,115 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "concurrent/map"
|
4
|
-
|
5
3
|
# Copied from https://raw.githubusercontent.com/rails/rails/d66e7835bea9505f7003e5038aa19b6ea95ceea1/activesupport/lib/active_support/core_ext/object/blank.rb
|
6
4
|
|
7
|
-
|
8
|
-
# :nocov:
|
9
|
-
|
10
|
-
# @see Object
|
11
|
-
class Object # :nodoc: # :nocov:
|
12
|
-
# An object is blank if it's false, empty, or a whitespace string.
|
13
|
-
# For example, +nil+, '', ' ', [], {}, and +false+ are all blank.
|
14
|
-
#
|
15
|
-
# This simplifies
|
16
|
-
#
|
17
|
-
# !address || address.empty?
|
18
|
-
#
|
19
|
-
# to
|
20
|
-
#
|
21
|
-
# address.blank?
|
22
|
-
#
|
23
|
-
# @return [true, false]
|
24
|
-
def blank?
|
25
|
-
respond_to?(:empty?) ? !!empty? : !self # rubocop:disable Style/DoubleNegation
|
26
|
-
end unless respond_to?(:blank?)
|
5
|
+
unless defined?(Rails) || defined?(ActiveSupport)
|
27
6
|
|
28
|
-
#
|
29
|
-
#
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
7
|
+
# @see Object
|
8
|
+
# @api private
|
9
|
+
class Object
|
10
|
+
# @api private
|
11
|
+
def blank?
|
12
|
+
respond_to?(:empty?) ? !!empty? : !self # rubocop:disable Style/DoubleNegation
|
13
|
+
end
|
14
|
+
# @api private
|
15
|
+
def present?
|
16
|
+
!blank?
|
17
|
+
end
|
18
|
+
# @api private
|
19
|
+
def presence
|
20
|
+
self if present?
|
21
|
+
end
|
22
|
+
end
|
34
23
|
|
35
|
-
#
|
36
|
-
#
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
# country = params[:country] if params[:country].present?
|
44
|
-
# region = state || country || 'US'
|
45
|
-
#
|
46
|
-
# becomes
|
47
|
-
#
|
48
|
-
# region = params[:state].presence || params[:country].presence || 'US'
|
49
|
-
#
|
50
|
-
# @return [Object]
|
51
|
-
def presence
|
52
|
-
self if present?
|
53
|
-
end unless respond_to?(:presence)
|
54
|
-
end
|
24
|
+
# @see NilClass
|
25
|
+
# @api private
|
26
|
+
class NilClass
|
27
|
+
# @api private
|
28
|
+
def blank?
|
29
|
+
true
|
30
|
+
end
|
31
|
+
end
|
55
32
|
|
56
|
-
# @see
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
true
|
65
|
-
end unless respond_to?(:blank?)
|
66
|
-
end
|
33
|
+
# @see FalseClass
|
34
|
+
# @api private
|
35
|
+
class FalseClass
|
36
|
+
# @api private
|
37
|
+
def blank?
|
38
|
+
true
|
39
|
+
end
|
40
|
+
end
|
67
41
|
|
68
|
-
# @see
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
true
|
77
|
-
end unless respond_to?(:blank?)
|
78
|
-
end
|
42
|
+
# @see TrueClass
|
43
|
+
# @api private
|
44
|
+
class TrueClass
|
45
|
+
# @api private
|
46
|
+
def blank?
|
47
|
+
false
|
48
|
+
end
|
49
|
+
end
|
79
50
|
|
80
|
-
# @see
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
# @return [false]
|
87
|
-
def blank?
|
88
|
-
false
|
89
|
-
end unless respond_to?(:blank?)
|
90
|
-
end
|
51
|
+
# @see Array
|
52
|
+
# @api private
|
53
|
+
class Array
|
54
|
+
# @api private
|
55
|
+
alias blank? empty?
|
56
|
+
end
|
91
57
|
|
92
|
-
# @see
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
#
|
99
|
-
# @return [true, false]
|
100
|
-
alias blank? empty?
|
101
|
-
end
|
58
|
+
# @see Hash
|
59
|
+
# @api private
|
60
|
+
class Hash
|
61
|
+
# @api private
|
62
|
+
alias blank? empty?
|
63
|
+
end
|
102
64
|
|
103
|
-
# @see
|
104
|
-
class
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
end
|
65
|
+
# @see String
|
66
|
+
class String
|
67
|
+
# :nodoc:
|
68
|
+
# @api private
|
69
|
+
BLANK_RE = /\A[[:space:]]*\z/.freeze
|
70
|
+
# :nodoc:
|
71
|
+
# @api private
|
72
|
+
ENCODED_BLANKS = Concurrent::Map.new do |map, enc|
|
73
|
+
map[enc] = Regexp.new(BLANK_RE.source.encode(enc), BLANK_RE.options | Regexp::FIXEDENCODING)
|
74
|
+
end
|
113
75
|
|
114
|
-
# @
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
76
|
+
# @api private
|
77
|
+
def blank?
|
78
|
+
# The regexp that matches blank strings is expensive. For the case of empty
|
79
|
+
# strings we can speed up this method (~3.5x) with an empty? call. The
|
80
|
+
# penalty for the rest of strings is marginal.
|
81
|
+
empty? ||
|
82
|
+
begin
|
83
|
+
if RUBY_VERSION >= "2.4"
|
84
|
+
BLANK_RE.match?(self)
|
85
|
+
else
|
86
|
+
!!BLANK_RE.match(self)
|
87
|
+
end
|
88
|
+
rescue Encoding::CompatibilityError
|
89
|
+
if RUBY_VERSION >= "2.4"
|
90
|
+
ENCODED_BLANKS[encoding].match?(self)
|
91
|
+
else
|
92
|
+
!!ENCODED_BLANKS[encoding].match(self)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
121
96
|
end
|
122
97
|
|
123
|
-
#
|
124
|
-
#
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
#
|
132
|
-
# "\u00a0".blank? # => true
|
133
|
-
#
|
134
|
-
# @return [true, false]
|
135
|
-
def blank?
|
136
|
-
# The regexp that matches blank strings is expensive. For the case of empty
|
137
|
-
# strings we can speed up this method (~3.5x) with an empty? call. The
|
138
|
-
# penalty for the rest of strings is marginal.
|
139
|
-
empty? ||
|
140
|
-
begin
|
141
|
-
BLANK_RE.match?(self)
|
142
|
-
rescue Encoding::CompatibilityError
|
143
|
-
ENCODED_BLANKS[encoding].match?(self)
|
144
|
-
end
|
145
|
-
end unless respond_to?(:blank?)
|
146
|
-
end
|
147
|
-
|
148
|
-
# @see Numeric
|
149
|
-
class Numeric
|
150
|
-
# No number is blank:
|
151
|
-
#
|
152
|
-
# 1.blank? # => false
|
153
|
-
# 0.blank? # => false
|
154
|
-
#
|
155
|
-
# @return [false]
|
156
|
-
def blank?
|
157
|
-
false
|
158
|
-
end unless respond_to?(:blank?)
|
159
|
-
end
|
98
|
+
# @see Numeric
|
99
|
+
# @api private
|
100
|
+
class Numeric
|
101
|
+
# @api private
|
102
|
+
def blank?
|
103
|
+
false
|
104
|
+
end
|
105
|
+
end
|
160
106
|
|
161
|
-
# @see Time
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
false
|
170
|
-
end unless respond_to?(:blank?)
|
107
|
+
# @see Time
|
108
|
+
# @api private
|
109
|
+
class Time
|
110
|
+
# @api private
|
111
|
+
def blank?
|
112
|
+
false
|
113
|
+
end
|
114
|
+
end
|
171
115
|
end
|
@@ -10,30 +10,32 @@ module StubRequests
|
|
10
10
|
#
|
11
11
|
# Class Endpoint provides registration of stubbed endpoints
|
12
12
|
#
|
13
|
+
# @author Mikael Henriksson <mikael@zoolutions.se>
|
14
|
+
#
|
13
15
|
class Endpoint
|
14
|
-
include ArgumentValidation
|
15
16
|
include Comparable
|
17
|
+
include Property
|
16
18
|
|
17
19
|
#
|
18
20
|
# @!attribute [rw] id
|
19
21
|
# @return [Symbol] the id of the endpoint
|
20
|
-
|
22
|
+
property :id, type: Symbol
|
21
23
|
|
22
24
|
#
|
23
25
|
# @!attribute [rw] verb
|
24
26
|
# @return [Symbol] a HTTP verb
|
25
|
-
|
27
|
+
property :verb, type: Symbol
|
26
28
|
|
27
29
|
#
|
28
30
|
# @!attribute [rw] uri_template
|
29
31
|
# @return [String] a string template for the endpoint
|
30
|
-
|
32
|
+
property :uri_template, type: String
|
31
33
|
|
32
34
|
#
|
33
|
-
# @!attribute [rw]
|
35
|
+
# @!attribute [rw] options
|
34
36
|
# @see
|
35
|
-
# @return [Hash<Symbol>] a
|
36
|
-
|
37
|
+
# @return [Hash<Symbol>] a Hash with default request/response options
|
38
|
+
property :options, type: Hash, default: {}
|
37
39
|
|
38
40
|
#
|
39
41
|
# An endpoint for a specific {Service}
|
@@ -41,21 +43,17 @@ module StubRequests
|
|
41
43
|
# @param [Symbol] endpoint_id a descriptive id for the endpoint
|
42
44
|
# @param [Symbol] verb a HTTP verb
|
43
45
|
# @param [String] uri_template how to reach the endpoint
|
44
|
-
# @param [optional, Hash<Symbol>]
|
45
|
-
# @option
|
46
|
-
# @option
|
47
|
-
# @option
|
48
|
-
# @option
|
46
|
+
# @param [optional, Hash<Symbol>] options
|
47
|
+
# @option options [optional, Hash<Symbol>] :request for request_stub.with
|
48
|
+
# @option options [optional, Hash<Symbol>] :response for request_stub.to_return
|
49
|
+
# @option options [optional, Array, Exception, StandardError, String] :error for request_stub.to_raise
|
50
|
+
# @option options [optional, TrueClass] :timeout for request_stub.to_timeout
|
49
51
|
#
|
50
|
-
def initialize(endpoint_id, verb, uri_template,
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
@id = endpoint_id
|
56
|
-
@verb = verb
|
57
|
-
@uri_template = uri_template
|
58
|
-
@default_options = default_options
|
52
|
+
def initialize(endpoint_id, verb, uri_template, options = {})
|
53
|
+
self.id = endpoint_id
|
54
|
+
self.verb = verb
|
55
|
+
self.uri_template = uri_template
|
56
|
+
self.options = options
|
59
57
|
end
|
60
58
|
|
61
59
|
#
|
@@ -63,18 +61,18 @@ module StubRequests
|
|
63
61
|
#
|
64
62
|
# @param [Symbol] verb a HTTP verb
|
65
63
|
# @param [String] uri_template how to reach the endpoint
|
66
|
-
# @param [optional, Hash<Symbol>]
|
67
|
-
# @option
|
68
|
-
# @option
|
69
|
-
# @option
|
70
|
-
# @option
|
64
|
+
# @param [optional, Hash<Symbol>] options
|
65
|
+
# @option options [optional, Hash<Symbol>] :request for request_stub.with
|
66
|
+
# @option options [optional, Hash<Symbol>] :response for request_stub.to_return
|
67
|
+
# @option options [optional, Array, Exception, StandardError, String] :error for request_stub.to_raise
|
68
|
+
# @option options [optional, TrueClass] :timeout for request_stub.to_timeout
|
71
69
|
#
|
72
70
|
# @return [Endpoint] returns the updated endpoint
|
73
71
|
#
|
74
|
-
def update(verb, uri_template,
|
75
|
-
|
76
|
-
|
77
|
-
|
72
|
+
def update(verb, uri_template, options)
|
73
|
+
self.verb = verb
|
74
|
+
self.uri_template = uri_template
|
75
|
+
self.options = options
|
78
76
|
self
|
79
77
|
end
|
80
78
|
|
@@ -10,6 +10,8 @@ module StubRequests
|
|
10
10
|
#
|
11
11
|
# Class EndpointRegistry holds a collection of {Endpoint}
|
12
12
|
#
|
13
|
+
# @author Mikael Henriksson <mikael@zoolutions.se>
|
14
|
+
#
|
13
15
|
class EndpointRegistry
|
14
16
|
include Enumerable
|
15
17
|
|
@@ -39,18 +41,18 @@ module StubRequests
|
|
39
41
|
# @param [Symbol] endpoint_id the id of this Endpoint
|
40
42
|
# @param [Symbol] verb a HTTP verb
|
41
43
|
# @param [String] uri_template the URI to reach the endpoint
|
42
|
-
# @param [optional, Hash<Symbol>]
|
44
|
+
# @param [optional, Hash<Symbol>] options default options
|
43
45
|
#
|
44
46
|
# @return [Endpoint]
|
45
47
|
#
|
46
48
|
# :reek:LongParameterList { max_params: 4 }
|
47
|
-
def register(endpoint_id, verb, uri_template,
|
49
|
+
def register(endpoint_id, verb, uri_template, options = {})
|
48
50
|
endpoint =
|
49
|
-
if (endpoint =
|
51
|
+
if (endpoint = find(endpoint_id))
|
50
52
|
StubRequests.logger.warn("Endpoint already registered: #{endpoint}")
|
51
|
-
endpoint.update(verb, uri_template,
|
53
|
+
endpoint.update(verb, uri_template, options)
|
52
54
|
else
|
53
|
-
Endpoint.new(endpoint_id, verb, uri_template,
|
55
|
+
Endpoint.new(endpoint_id, verb, uri_template, options)
|
54
56
|
end
|
55
57
|
|
56
58
|
endpoints[endpoint.id] = endpoint
|
@@ -74,20 +76,20 @@ module StubRequests
|
|
74
76
|
# @param [Symbol] endpoint_id the id of the endpoint
|
75
77
|
# @param [Symbol] verb a HTTP verb
|
76
78
|
# @param [String] uri_template how to reach the endpoint
|
77
|
-
# @param [optional, Hash<Symbol>]
|
78
|
-
# @option
|
79
|
-
# @option
|
80
|
-
# @option
|
81
|
-
# @option
|
79
|
+
# @param [optional, Hash<Symbol>] options
|
80
|
+
# @option options [optional, Hash<Symbol>] :request request options
|
81
|
+
# @option options [optional, Hash<Symbol>] :response options
|
82
|
+
# @option options [optional, Array, Exception, StandardError, String] :error to raise
|
83
|
+
# @option options [optional, TrueClass] :timeout raise a timeout error?
|
82
84
|
#
|
83
85
|
# @raise [EndpointNotFound] when the endpoint couldn't be found
|
84
86
|
#
|
85
87
|
# @return [Endpoint] returns the updated endpoint
|
86
88
|
#
|
87
89
|
# :reek:LongParameterList { max_params: 4 }
|
88
|
-
def update(endpoint_id, verb, uri_template,
|
89
|
-
endpoint =
|
90
|
-
endpoint.update(verb, uri_template,
|
90
|
+
def update(endpoint_id, verb, uri_template, options)
|
91
|
+
endpoint = find!(endpoint_id)
|
92
|
+
endpoint.update(verb, uri_template, options)
|
91
93
|
end
|
92
94
|
|
93
95
|
#
|
@@ -108,7 +110,7 @@ module StubRequests
|
|
108
110
|
#
|
109
111
|
# @return [Endpoint]
|
110
112
|
#
|
111
|
-
def
|
113
|
+
def find(endpoint_id)
|
112
114
|
endpoints[endpoint_id]
|
113
115
|
end
|
114
116
|
|
@@ -121,8 +123,8 @@ module StubRequests
|
|
121
123
|
#
|
122
124
|
# @return [Endpoint, nil]
|
123
125
|
#
|
124
|
-
def
|
125
|
-
|
126
|
+
def find!(endpoint_id)
|
127
|
+
find(endpoint_id) || raise(EndpointNotFound, "Couldn't find an endpoint with id=:#{endpoint_id}")
|
126
128
|
end
|
127
129
|
|
128
130
|
#
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Abstraction over WebMock to reduce duplication
|
5
|
+
#
|
6
|
+
# @author Mikael Henriksson <mikael@zoolutions.se>
|
7
|
+
# @since 0.1.0
|
8
|
+
#
|
9
|
+
module StubRequests
|
10
|
+
#
|
11
|
+
# Error is a base class for all gem errors
|
12
|
+
#
|
13
|
+
class Error < StandardError; end
|
14
|
+
|
15
|
+
#
|
16
|
+
# EndpointNotFound is raised when an endpoint cannot be found
|
17
|
+
#
|
18
|
+
class EndpointNotFound < Error; end
|
19
|
+
|
20
|
+
#
|
21
|
+
# InvalidType is raised when an argument is invalid
|
22
|
+
#
|
23
|
+
class InvalidType < Error
|
24
|
+
def initialize(actual, expected)
|
25
|
+
super("Expected `#{actual}` to be any of [#{expected}]")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# InvalidArgumentType is raised when an argument is not of the expected type
|
31
|
+
#
|
32
|
+
class InvalidArgumentType < Error
|
33
|
+
#
|
34
|
+
# @param [Symbol] name the name of the argument
|
35
|
+
# @param [Object] actual the actual value of the argument
|
36
|
+
# @param [Array<Class>, Array<Module>] expected the types the argument is expected to be
|
37
|
+
#
|
38
|
+
def initialize(name:, actual:, expected:)
|
39
|
+
super("The argument `:#{name}` was `#{actual}`, expected any of [#{expected.join(', ')}]")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# InvalidUri is raised when a URI is invalid
|
45
|
+
#
|
46
|
+
class InvalidUri < Error
|
47
|
+
def initialize(uri)
|
48
|
+
super("'#{uri}' is not a valid URI.")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
#
|
53
|
+
# PropertyDefined is raised when trying to add the same property twice
|
54
|
+
#
|
55
|
+
class PropertyDefined < Error
|
56
|
+
def initialize(name:, type:, default:)
|
57
|
+
default = "nil" if default.is_a?(NilClass)
|
58
|
+
super("Property ##{name} was already defined as `{ type: #{type}, default: #{default} }")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# ServiceHaveEndpoints is raised to prevent overwriting a registered service's endpoints
|
64
|
+
#
|
65
|
+
class ServiceHaveEndpoints < StandardError
|
66
|
+
def initialize(service)
|
67
|
+
super("Service with id #{service.id} have already been registered. #{service}")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
#
|
72
|
+
# ServiceNotFound is raised when a service cannot be found
|
73
|
+
#
|
74
|
+
class ServiceNotFound < Error
|
75
|
+
def initialize(service_id)
|
76
|
+
super("Couldn't find a service with id=:#{service_id}")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
#
|
81
|
+
# UriSegmentMismatch is raised when a segment cannot be replaced
|
82
|
+
#
|
83
|
+
class UriSegmentMismatch < Error; end
|
84
|
+
end
|