stub_requests 0.1.9 → 0.1.10
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/.reek.yml +5 -9
- data/.rubocop.yml +1 -0
- data/CHANGELOG.md +23 -0
- data/README.md +9 -9
- data/Rakefile +7 -5
- data/lib/stub_requests.rb +30 -16
- data/lib/stub_requests/api.rb +45 -26
- data/lib/stub_requests/callback.rb +3 -1
- data/lib/stub_requests/callback_registry.rb +9 -55
- data/lib/stub_requests/concerns/argument_validation.rb +47 -0
- data/lib/stub_requests/concerns/property.rb +114 -0
- data/lib/stub_requests/concerns/property/validator.rb +137 -0
- data/lib/stub_requests/concerns/register_verb.rb +110 -0
- data/lib/stub_requests/configuration.rb +19 -2
- data/lib/stub_requests/dsl.rb +5 -6
- data/lib/stub_requests/dsl/method_definition.rb +2 -8
- data/lib/stub_requests/endpoint.rb +22 -23
- data/lib/stub_requests/endpoint_registry.rb +157 -0
- data/lib/stub_requests/exceptions.rb +28 -10
- data/lib/stub_requests/request_stub.rb +29 -14
- data/lib/stub_requests/service.rb +55 -7
- data/lib/stub_requests/service_registry.rb +30 -79
- data/lib/stub_requests/stub_registry.rb +22 -80
- data/lib/stub_requests/stub_requests.rb +8 -5
- data/lib/stub_requests/uri.rb +0 -17
- data/lib/stub_requests/utils/fuzzy.rb +70 -0
- data/lib/stub_requests/version.rb +1 -1
- data/lib/stub_requests/webmock/builder.rb +9 -51
- data/lib/stub_requests/webmock/stub_registry_extension.rb +1 -1
- data/lib/tasks/changelog.rake +1 -7
- data/stub_requests.gemspec +1 -0
- data/update_docs.sh +2 -2
- metadata +27 -8
- data/lib/stub_requests/argument_validation.rb +0 -48
- data/lib/stub_requests/endpoint_stub.rb +0 -89
- data/lib/stub_requests/endpoints.rb +0 -246
- data/lib/stub_requests/hash_util.rb +0 -32
- data/lib/stub_requests/observable.rb +0 -18
- data/lib/stub_requests/property.rb +0 -112
- data/lib/stub_requests/property/validator.rb +0 -135
@@ -0,0 +1,114 @@
|
|
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
|
+
module Concerns
|
11
|
+
#
|
12
|
+
# Module Property provides type checked attribute definition with default value
|
13
|
+
#
|
14
|
+
# @author Mikael Henriksson <mikael@zoolutions.se>
|
15
|
+
# @since 0.1.2
|
16
|
+
#
|
17
|
+
module Property
|
18
|
+
include ArgumentValidation
|
19
|
+
|
20
|
+
#
|
21
|
+
# Extends the base class with the ClassMethods module
|
22
|
+
#
|
23
|
+
# @param [Class,Module] base the class where this module is included
|
24
|
+
#
|
25
|
+
# @return [void]
|
26
|
+
#
|
27
|
+
def self.included(base)
|
28
|
+
base.class_attribute :properties, default: {}
|
29
|
+
base.send(:extend, ClassMethods)
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# Module ClassMethods provides class methods for {Property}
|
34
|
+
#
|
35
|
+
# @author Mikael Henriksson <mikael@zoolutions.se>
|
36
|
+
#
|
37
|
+
module ClassMethods
|
38
|
+
#
|
39
|
+
# Define property methods for the name
|
40
|
+
#
|
41
|
+
# @param [Symbol] name the name of the property
|
42
|
+
# @param [Object] type the expected type of the property
|
43
|
+
# @param [Hash<Symbol>] options a hash with options
|
44
|
+
# @option options [Object] :default a default value for the property
|
45
|
+
#
|
46
|
+
# @return [void]
|
47
|
+
#
|
48
|
+
def property(name, type:, **options)
|
49
|
+
type = normalize_type(type, options)
|
50
|
+
default = options[:default]
|
51
|
+
Validator.call(name, type, default, properties)
|
52
|
+
|
53
|
+
Docile.dsl_eval(self) do
|
54
|
+
define_property(name, type, default)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# @api private
|
59
|
+
def normalize_type(type, **options)
|
60
|
+
type_array = Array(type)
|
61
|
+
return type_array unless (default = options[:default])
|
62
|
+
|
63
|
+
type_array.concat([default.class]).flatten.uniq
|
64
|
+
end
|
65
|
+
|
66
|
+
# @api private
|
67
|
+
def define_property(name, type, default)
|
68
|
+
property_reader(name, default)
|
69
|
+
property_predicate(name)
|
70
|
+
property_writer(name, type)
|
71
|
+
|
72
|
+
set_property_default(name, default)
|
73
|
+
set_property_defined(name, type, default)
|
74
|
+
end
|
75
|
+
|
76
|
+
# @api private
|
77
|
+
def property_reader(name, default)
|
78
|
+
invar = "@#{name}"
|
79
|
+
silence_redefinition_of_method(name.to_s)
|
80
|
+
redefine_method(name) do
|
81
|
+
instance_variable_set(invar, default) unless instance_variable_defined?(invar)
|
82
|
+
instance_variable_get(invar)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# @api private
|
87
|
+
def property_predicate(name)
|
88
|
+
silence_redefinition_of_method("#{name}?")
|
89
|
+
redefine_method("#{name}?") do
|
90
|
+
!!public_send(name) # rubocop:disable Style/DoubleNegation
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# @api private
|
95
|
+
def property_writer(name, type)
|
96
|
+
redefine_method("#{name}=") do |obj|
|
97
|
+
validate! name: name, value: obj, type: type
|
98
|
+
instance_variable_set("@#{name}", obj)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def set_property_default(name, default)
|
103
|
+
instance_variable_set("@#{name}", default)
|
104
|
+
end
|
105
|
+
|
106
|
+
# @api private
|
107
|
+
def set_property_defined(name, type, default)
|
108
|
+
self.properties ||= {}
|
109
|
+
properties[name] = { type: type, default: default }
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,137 @@
|
|
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
|
+
module Concerns
|
11
|
+
#
|
12
|
+
# Module Property provides type checked attribute definition with default value
|
13
|
+
#
|
14
|
+
# @author Mikael Henriksson <mikael@zoolutions.se>
|
15
|
+
# @since 0.1.2
|
16
|
+
#
|
17
|
+
module Property
|
18
|
+
#
|
19
|
+
# Class Validator provides validation for adding properties
|
20
|
+
#
|
21
|
+
# @author Mikael Henriksson <mikael@zoolutions.se>
|
22
|
+
# @since 0.1.2
|
23
|
+
#
|
24
|
+
class Validator
|
25
|
+
include ArgumentValidation
|
26
|
+
|
27
|
+
#
|
28
|
+
# Validates that the property can be added to the class
|
29
|
+
#
|
30
|
+
#
|
31
|
+
# @param [Symbol] name the name of the property
|
32
|
+
# @param [Class, Module] type the type of the property
|
33
|
+
# @param [Object] default the default value of the property
|
34
|
+
# @param [Hash] properties the list of currently defined properties
|
35
|
+
#
|
36
|
+
# @raise [InvalidArgumentType] when name is not a Symbol
|
37
|
+
# @raise [InvalidArgumentType] when default does not match type
|
38
|
+
# @raise [PropertyDefined] when property has already been defined
|
39
|
+
#
|
40
|
+
# @return [void]
|
41
|
+
#
|
42
|
+
def self.call(name, type, default, properties)
|
43
|
+
new(name, type, default, properties).run_validations
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# @!attribute [r] name
|
48
|
+
# @return [Symbol] the name of the property
|
49
|
+
attr_reader :name
|
50
|
+
#
|
51
|
+
# @!attribute [r] type
|
52
|
+
# @return [Class, Module] the type of the property
|
53
|
+
attr_reader :type
|
54
|
+
#
|
55
|
+
# @!attribute [r] default
|
56
|
+
# @return [Object] the default value of the property
|
57
|
+
attr_reader :default
|
58
|
+
#
|
59
|
+
# @!attribute [r] properties
|
60
|
+
# @return [Hash] the list of currently defined properties
|
61
|
+
attr_reader :properties
|
62
|
+
|
63
|
+
# Initializes a new {Validator}
|
64
|
+
#
|
65
|
+
# @param [Symbol] name the name of the property
|
66
|
+
# @param [Class, Module] type the type of the property
|
67
|
+
# @param [Object] default the default value of the property
|
68
|
+
# @param [Hash] properties the list of currently defined properties
|
69
|
+
#
|
70
|
+
def initialize(name, type, default = nil, properties = {})
|
71
|
+
@type = Array(type).flatten
|
72
|
+
@default = default
|
73
|
+
@name = name
|
74
|
+
@properties = properties || {}
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# Performs all validations
|
79
|
+
#
|
80
|
+
#
|
81
|
+
# @raise [InvalidArgumentType] when name is not a Symbol
|
82
|
+
# @raise [InvalidArgumentType] when default does not match type
|
83
|
+
# @raise [PropertyDefined] when property has already been defined
|
84
|
+
#
|
85
|
+
# @return [void]
|
86
|
+
#
|
87
|
+
def run_validations
|
88
|
+
validate_undefined
|
89
|
+
validate_name
|
90
|
+
validate_default
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
#
|
96
|
+
# Validates that the name is of type Symbol
|
97
|
+
#
|
98
|
+
# @raise [InvalidArgumentType] when name is not a Symbol
|
99
|
+
#
|
100
|
+
# @return [void]
|
101
|
+
#
|
102
|
+
def validate_name
|
103
|
+
validate! name: :name, value: name, type: Symbol
|
104
|
+
end
|
105
|
+
|
106
|
+
#
|
107
|
+
# Validate that the default value matches the type
|
108
|
+
#
|
109
|
+
#
|
110
|
+
# @raise [InvalidArgumentType] when default does not match type
|
111
|
+
#
|
112
|
+
# @return [void]
|
113
|
+
#
|
114
|
+
def validate_default
|
115
|
+
return unless default || default.is_a?(FalseClass)
|
116
|
+
|
117
|
+
validate! name: :default, value: default, type: type
|
118
|
+
end
|
119
|
+
|
120
|
+
#
|
121
|
+
# Validate that the property has not been defined
|
122
|
+
#
|
123
|
+
#
|
124
|
+
# @raise [PropertyDefined] when property has already been defined
|
125
|
+
#
|
126
|
+
# @return [void]
|
127
|
+
#
|
128
|
+
def validate_undefined
|
129
|
+
return unless properties
|
130
|
+
return unless (prop = properties[name])
|
131
|
+
|
132
|
+
raise PropertyDefined, name: name, type: prop[:type], default: prop[:default]
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StubRequests
|
4
|
+
module Concerns
|
5
|
+
#
|
6
|
+
# Module RegisterVerb provides <description>
|
7
|
+
# @since 0.1.10
|
8
|
+
#
|
9
|
+
#
|
10
|
+
# @author Mikael Henriksson <mikael@zoolutions.se>
|
11
|
+
#
|
12
|
+
module RegisterVerb
|
13
|
+
#
|
14
|
+
# Convenience wrapper for register
|
15
|
+
#
|
16
|
+
#
|
17
|
+
# @example **Register a get endpoint**
|
18
|
+
# . get("documents/:id", as: :documents_show)
|
19
|
+
#
|
20
|
+
# @param [String] path the path to the endpoint
|
21
|
+
# @param [Symbol] as the id of the endpoint
|
22
|
+
#
|
23
|
+
# @return [Endpoint] the registered endpoint
|
24
|
+
#
|
25
|
+
def any(path, as:) # rubocop:disable Naming/UncommunicativeMethodParamName
|
26
|
+
register(as, __method__, path)
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# Convenience wrapper for register
|
31
|
+
#
|
32
|
+
#
|
33
|
+
# @example **Register a get endpoint**
|
34
|
+
# . get("documents/:id", as: :documents_show)
|
35
|
+
#
|
36
|
+
# @param [String] path the path to the endpoint
|
37
|
+
# @param [Symbol] as the id of the endpoint
|
38
|
+
#
|
39
|
+
# @return [Endpoint] the registered endpoint
|
40
|
+
#
|
41
|
+
def get(path, as:) # rubocop:disable Naming/UncommunicativeMethodParamName
|
42
|
+
register(as, __method__, path)
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# Register a :post endpoint
|
47
|
+
#
|
48
|
+
#
|
49
|
+
# @example **Register a post endpoint**
|
50
|
+
# . post("documents", as: :documents_create)
|
51
|
+
#
|
52
|
+
# @param [String] path the path to the endpoint
|
53
|
+
# @param [Symbol] as the id of the endpoint
|
54
|
+
#
|
55
|
+
# @return [Endpoint] the registered endpoint
|
56
|
+
#
|
57
|
+
def post(path, as:) # rubocop:disable Naming/UncommunicativeMethodParamName
|
58
|
+
register(as, __method__, path)
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# Register a :patch endpoint
|
63
|
+
#
|
64
|
+
#
|
65
|
+
# @example **Register a patch endpoint**
|
66
|
+
# . patch("documents/:id", as: :documents_update)
|
67
|
+
#
|
68
|
+
# @param [String] path the path to the endpoint
|
69
|
+
# @param [Symbol] as the id of the endpoint
|
70
|
+
#
|
71
|
+
# @return [Endpoint] the registered endpoint
|
72
|
+
#
|
73
|
+
def patch(path, as:) # rubocop:disable Naming/UncommunicativeMethodParamName
|
74
|
+
register(as, __method__, path)
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# Register a :put endpoint
|
79
|
+
#
|
80
|
+
#
|
81
|
+
# @example **Register a put endpoint**
|
82
|
+
# . put("documents/:id", as: :documents_update)
|
83
|
+
#
|
84
|
+
# @param [String] path the path to the endpoint
|
85
|
+
# @param [Symbol] as the id of the endpoint
|
86
|
+
#
|
87
|
+
# @return [Endpoint] the registered endpoint
|
88
|
+
#
|
89
|
+
def put(path, as:) # rubocop:disable Naming/UncommunicativeMethodParamName
|
90
|
+
register(as, __method__, path)
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
# Register a :delete endpoint
|
95
|
+
#
|
96
|
+
#
|
97
|
+
# @example **Register a delete endpoint**
|
98
|
+
# . delete("documents/:id", as: :documents_destroy)
|
99
|
+
#
|
100
|
+
# @param [String] path the path to the endpoint
|
101
|
+
# @param [Symbol] as the id of the endpoint
|
102
|
+
#
|
103
|
+
# @return [Endpoint] the registered endpoint
|
104
|
+
#
|
105
|
+
def delete(path, as:) # rubocop:disable Naming/UncommunicativeMethodParamName
|
106
|
+
register(as, __method__, path)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -14,8 +14,25 @@ module StubRequests
|
|
14
14
|
# @since 0.1.2
|
15
15
|
#
|
16
16
|
class Configuration
|
17
|
-
|
17
|
+
# includes "Concerns::Property"
|
18
|
+
# @!parse include Concerns::Property
|
19
|
+
include Concerns::Property
|
18
20
|
|
19
|
-
|
21
|
+
#
|
22
|
+
# @!attribute [rw] record_stubs
|
23
|
+
# @return [Hash] record_stubs set to true to keep track of stubs
|
24
|
+
property :record_stubs, type: [TrueClass, FalseClass], default: false
|
25
|
+
#
|
26
|
+
# @!attribute [rw] jaro_options
|
27
|
+
# @return [Hash] options to use for jaro winkler
|
28
|
+
property :jaro_options, type: Hash, default: {
|
29
|
+
weight: 0.1,
|
30
|
+
threshold: 0.7,
|
31
|
+
ignore_case: true,
|
32
|
+
}
|
33
|
+
#
|
34
|
+
# @!attribute [rw] logger
|
35
|
+
# @return [Logger] any object that responds to the standard logger methods
|
36
|
+
property :logger, type: Logger
|
20
37
|
end
|
21
38
|
end
|
data/lib/stub_requests/dsl.rb
CHANGED
@@ -29,15 +29,15 @@ module StubRequests
|
|
29
29
|
# Stubs.instance_methods #=> [:stub_documents_show, :stub_documents_index, :stub_documents_create]
|
30
30
|
# module Stubs
|
31
31
|
# def stub_documents_show(id:, &block)
|
32
|
-
# stub_endpoint(:
|
32
|
+
# stub_endpoint(:documents_show, id: id, &block)
|
33
33
|
# end
|
34
34
|
#
|
35
35
|
# def stub_documents_index(&block)
|
36
|
-
# stub_endpoint(:
|
36
|
+
# stub_endpoint(:documents_index, &block)
|
37
37
|
# end
|
38
38
|
#
|
39
39
|
# def stub_documents_create(&block)
|
40
|
-
# stub_endpoint(:
|
40
|
+
# stub_endpoint(:documents_create, &block)
|
41
41
|
# end
|
42
42
|
# end
|
43
43
|
#
|
@@ -90,9 +90,8 @@ module StubRequests
|
|
90
90
|
# @param [Module] receiver the receiver of the stub methods
|
91
91
|
#
|
92
92
|
def initialize(service_id, receiver: nil)
|
93
|
-
@
|
93
|
+
@endpoints = StubRequests::EndpointRegistry[service_id]
|
94
94
|
@receiver = receiver
|
95
|
-
@endpoints = service.endpoints.endpoints.values
|
96
95
|
end
|
97
96
|
|
98
97
|
#
|
@@ -123,7 +122,7 @@ module StubRequests
|
|
123
122
|
|
124
123
|
def method_definitions
|
125
124
|
@method_definitions ||= endpoints.map do |endpoint|
|
126
|
-
MethodDefinition.new(
|
125
|
+
MethodDefinition.new(endpoint.id, endpoint.route_params)
|
127
126
|
end
|
128
127
|
end
|
129
128
|
end
|
@@ -13,10 +13,6 @@ module StubRequests
|
|
13
13
|
# @return [String]
|
14
14
|
BLOCK_ARG = "&block"
|
15
15
|
|
16
|
-
#
|
17
|
-
# @!attribute [r] service_id
|
18
|
-
# @return [Symbol] the id of a registered service
|
19
|
-
attr_reader :service_id
|
20
16
|
#
|
21
17
|
# @!attribute [r] endpoint_id
|
22
18
|
# @return [Symbol] the id of a registered endpoint
|
@@ -29,12 +25,10 @@ module StubRequests
|
|
29
25
|
#
|
30
26
|
# Initialize a new endpoint of {MethodDefinition}
|
31
27
|
#
|
32
|
-
# @param [Symbol] service_id the id of a registered service
|
33
28
|
# @param [Symbol] endpoint_id the id of a registered endpoint
|
34
29
|
# @param [Array<Symbol>] route_params the route parameter keys
|
35
30
|
#
|
36
|
-
def initialize(
|
37
|
-
@service_id = service_id
|
31
|
+
def initialize(endpoint_id, route_params)
|
38
32
|
@endpoint_id = endpoint_id
|
39
33
|
@route_params = route_params
|
40
34
|
end
|
@@ -52,7 +46,7 @@ module StubRequests
|
|
52
46
|
def to_s
|
53
47
|
<<~METHOD
|
54
48
|
def #{name}(#{keywords})
|
55
|
-
StubRequests.stub_endpoint(:#{
|
49
|
+
StubRequests.stub_endpoint(:#{endpoint_id}, #{arguments})
|
56
50
|
end
|
57
51
|
METHOD
|
58
52
|
end
|