stub_requests 0.1.3 → 0.1.4

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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.reek.yml +1 -0
  3. data/CHANGELOG.md +2 -0
  4. data/README.md +2 -2
  5. data/lib/stub_requests/api.rb +8 -22
  6. data/lib/stub_requests/callback.rb +58 -0
  7. data/lib/stub_requests/callback_registry.rb +188 -0
  8. data/lib/stub_requests/core_ext/all.rb +1 -0
  9. data/lib/stub_requests/core_ext/array/extract_options.rb +4 -6
  10. data/lib/stub_requests/core_ext/class/attribute.rb +2 -3
  11. data/lib/stub_requests/core_ext/kernel/singleton_class.rb +2 -3
  12. data/lib/stub_requests/core_ext/module/redefine_method.rb +6 -0
  13. data/lib/stub_requests/core_ext/object/blank.rb +21 -22
  14. data/lib/stub_requests/core_ext/string/to_route_param.rb +35 -0
  15. data/lib/stub_requests/dsl/define_method.rb +49 -0
  16. data/lib/stub_requests/dsl/method_definition.rb +72 -0
  17. data/lib/stub_requests/dsl.rb +94 -0
  18. data/lib/stub_requests/endpoint.rb +48 -36
  19. data/lib/stub_requests/endpoint_stub.rb +89 -0
  20. data/lib/stub_requests/endpoints.rb +147 -0
  21. data/lib/stub_requests/observable.rb +0 -44
  22. data/lib/stub_requests/request_stub.rb +80 -0
  23. data/lib/stub_requests/service.rb +77 -0
  24. data/lib/stub_requests/service_registry.rb +174 -0
  25. data/lib/stub_requests/stub_registry.rb +159 -0
  26. data/lib/stub_requests/uri/builder.rb +27 -34
  27. data/lib/stub_requests/uri.rb +31 -4
  28. data/lib/stub_requests/version.rb +1 -1
  29. data/lib/stub_requests/webmock/stub_registry_extension.rb +1 -1
  30. data/lib/stub_requests.rb +12 -12
  31. data/lib/tasks/changelog.rake +2 -1
  32. metadata +14 -16
  33. data/gemfiles/webmock_2.3.gemfile.lock +0 -206
  34. data/gemfiles/webmock_3.5.gemfile.lock +0 -206
  35. data/gemfiles/webmock_develop.gemfile.lock +0 -211
  36. data/lib/stub_requests/metrics/endpoint.rb +0 -98
  37. data/lib/stub_requests/metrics/registry.rb +0 -132
  38. data/lib/stub_requests/metrics/request.rb +0 -89
  39. data/lib/stub_requests/metrics.rb +0 -33
  40. data/lib/stub_requests/observable/registry.rb +0 -152
  41. data/lib/stub_requests/observable/subscription.rb +0 -58
  42. data/lib/stub_requests/registration/endpoint.rb +0 -107
  43. data/lib/stub_requests/registration/endpoints.rb +0 -156
  44. data/lib/stub_requests/registration/registry.rb +0 -112
  45. data/lib/stub_requests/registration/service.rb +0 -85
  46. data/lib/stub_requests/registration.rb +0 -87
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StubRequests
4
+ class DSL
5
+ #
6
+ # Class DefineMethod generates method definition for a stubbed endpoint
7
+ #
8
+ # @author Mikael Henriksson <mikael@zoolutions.se>
9
+ # @since 0.1.4
10
+ #
11
+ class MethodDefinition
12
+ #
13
+ # @return [String]
14
+ BLOCK_ARG = "&block"
15
+
16
+ #
17
+ # @!attribute [r] service_id
18
+ # @return [Symbol] the id of a registered service
19
+ attr_reader :service_id
20
+ #
21
+ # @!attribute [r] endpoint_id
22
+ # @return [Symbol] the id of a registered endpoint
23
+ attr_reader :endpoint_id
24
+ #
25
+ # @!attribute [r] route_params
26
+ # @return [Array<Symbol>] the URI parameters for the endpoint
27
+ attr_reader :route_params
28
+
29
+ #
30
+ # Initialize a new endpoint of {MethodDefinition}
31
+ #
32
+ # @param [Symbol] service_id the id of a registered service
33
+ # @param [Symbol] endpoint_id the id of a registered endpoint
34
+ # @param [Array<Symbol>] route_params the route parameter keys
35
+ #
36
+ def initialize(service_id, endpoint_id, route_params)
37
+ @service_id = service_id
38
+ @endpoint_id = endpoint_id
39
+ @route_params = route_params
40
+ end
41
+
42
+ #
43
+ # The name of this method
44
+ #
45
+ #
46
+ # @return [String] a string prefixed with stub_, `"stub_documents_show"`
47
+ #
48
+ def name
49
+ @name ||= "stub_#{endpoint_id}"
50
+ end
51
+
52
+ def to_s
53
+ <<~METHOD
54
+ def #{name}(#{keywords})
55
+ stub_endpoint(:#{service_id}, :#{endpoint_id}, #{arguments})
56
+ end
57
+ METHOD
58
+ end
59
+ alias to_str to_s
60
+
61
+ private
62
+
63
+ def keywords
64
+ @keywords ||= route_params.map { |param| "#{param}:" }.concat([+BLOCK_ARG]).join(", ")
65
+ end
66
+
67
+ def arguments
68
+ @arguments ||= route_params.map { |param| "#{param}: #{param}" }.concat([+BLOCK_ARG]).join(", ")
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StubRequests
4
+ #
5
+ # Module DSL takes the id of a registered service
6
+ #
7
+ # @author Mikael Henriksson <mikael@zoolutions.se>
8
+ # @since 0.1.4
9
+ #
10
+ # @example **Register service with endpoints**
11
+ # StubRequests.register_service(:documents, "https://company.com/api/v1") do
12
+ # register_endpoints do
13
+ # register(:show, :get, "documents/:id")
14
+ # register(:index, :get, "documents")
15
+ # register(:create, :post, "documents")
16
+ # end
17
+ # end
18
+ # @example **Create a receiver module for the stub methods**
19
+ # module Stubs; end
20
+ #
21
+ # Stubs.instance_methods #=> []
22
+ # @example **Define the endpoint methods using the DSL**
23
+ # StubRequests::DSL.define_endpoint_methods(
24
+ # :documents, receiver: Stubs
25
+ # )
26
+ #
27
+ # # This turns the module Stubs into the following:
28
+ #
29
+ # Stubs.instance_methods #=> [:stub_documents_show, :stub_documents_index, :stub_documents_create]
30
+ # module Stubs
31
+ # def stub_documents_show(id:, &block)
32
+ # stub_endpoint(:documents, :show, id: id, &block)
33
+ # end
34
+ #
35
+ # def stub_documents_index(&block)
36
+ # stub_endpoint(:documents, :index, &block)
37
+ # end
38
+ #
39
+ # def stub_documents_create(&block)
40
+ # stub_endpoint(:documents, :create, &block)
41
+ # end
42
+ # end
43
+ #
44
+ # @example **Use the helper methods in your tests**
45
+ # include Stubs
46
+ #
47
+ # let(:document_id) { 1234 }
48
+ # let(:request_body) { { key: "value" }.to_json }
49
+ # let(:response_body) { { id: document_id, key: "value" }.to_json }
50
+ #
51
+ # before do
52
+ # stub_documents_create do
53
+ # with(body: request_body)
54
+ # to_return(body: response_body)
55
+ # end
56
+ #
57
+ # stub_documents_show(id: document_id) do
58
+ # with(body: request_body)
59
+ # to_return(body: response_body)
60
+ # end
61
+ # end
62
+ #
63
+ # it "stubs the requests nicely" do
64
+ # create_uri = URI("https://company.com/api/v1/documents")
65
+ # response = Net::HTTP.post(create_uri)
66
+ # expect(response).to be_json_eql(response_body.to_json)
67
+ #
68
+ # show_uri = URI("https://company.com/api/v1/documents/#{document_id}")
69
+ # response = Net::HTTP.post(create_uri)
70
+ # expect(response).to be_json_eql(response_body.to_json)
71
+ # end
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
78
+
79
+ def initialize(service_id, receiver:)
80
+ @service = StubRequests::ServiceRegistry.instance.find(service_id)
81
+ @receiver = receiver
82
+ @endpoints = service.endpoints.endpoints.values
83
+ end
84
+
85
+ def define_endpoint_methods
86
+ receiver.send(:include, StubRequests::API)
87
+
88
+ endpoints.each do |endpoint|
89
+ definition = MethodDefinition.new(service.id, endpoint.id, endpoint.route_params)
90
+ DefineMethod.new(definition, receiver).define
91
+ end
92
+ end
93
+ end
94
+ end
@@ -17,9 +17,6 @@ module StubRequests
17
17
 
18
18
  include Comparable
19
19
  include Property
20
-
21
- # Delegate id, uri and endpoints to service
22
- delegate [:id, :uri, :endpoints] => :service
23
20
  #
24
21
  # @!attribute [rw] id
25
22
  # @return [Symbol] the id of the endpoint
@@ -29,57 +26,72 @@ module StubRequests
29
26
  # @return [Symbol] a HTTP verb
30
27
  property :verb, type: Symbol
31
28
  #
32
- # @!attribute [rw] uri_template
29
+ # @!attribute [rw] path
33
30
  # @return [String] a string template for the endpoint
34
- property :uri_template, type: String
31
+ property :path, type: String
32
+
33
+ #
34
+ # @!attribute [rw] service
35
+ # @see
36
+ # @return [Service] a service
37
+ attr_reader :service
38
+
39
+ #
40
+ # @!attribute [rw] service_id
41
+ # @see
42
+ # @return [Symbol] the id of the service
43
+ attr_reader :service_id
44
+
45
+ #
46
+ # @!attribute [rw] service_uri
47
+ # @see
48
+ # @return [String] a service's base URI
49
+ attr_reader :service_uri
50
+
35
51
  #
36
52
  # @!attribute [rw] options
37
53
  # @see
38
- # @return [Hash<Symbol>] a Hash with default request/response options
39
- property :options, type: Hash, default: {}
54
+ # @return [Array<Symbol>] an array with required route params
55
+ attr_reader :route_params
40
56
 
41
57
  #
42
- # An endpoint for a specific {StubRequests::Registration::Service}
58
+ # An endpoint for a specific {StubRequests::Service}
43
59
  #
60
+ #
61
+ # @param [Service] service a registered service
44
62
  # @param [Symbol] endpoint_id a descriptive id for the endpoint
45
63
  # @param [Symbol] verb a HTTP verb
46
- # @param [String] uri_template how to reach the endpoint
47
- # @param [optional, Hash<Symbol>] options
48
- # @option options [optional, Hash<Symbol>] :request for request_stub.with
49
- # @option options [optional, Hash<Symbol>] :response for request_stub.to_return
50
- # @option options [optional, Array, Exception, StandardError, String] :error for request_stub.to_raise
51
- # @option options [optional, TrueClass] :timeout for request_stub.to_timeout
52
- #
53
- def initialize(service, endpoint_id, verb, uri_template, options = {})
54
- self.service = service
55
- self.id = endpoint_id
56
- self.verb = verb
57
- self.uri_template = uri_template
58
- self.options = options
64
+ # @param [String] path how to reach the endpoint
65
+ #
66
+ def initialize(service, endpoint_id, verb, path)
67
+ self.id = endpoint_id
68
+ self.verb = verb
69
+ self.path = path
70
+
71
+ @service = service
72
+ @service_id = service.id
73
+ @service_uri = service.uri
74
+ @route_params = URI.route_params(path)
59
75
  end
60
76
 
61
77
  #
62
78
  # Updates this endpoint
63
79
  #
80
+ #
64
81
  # @param [Symbol] verb a HTTP verb
65
- # @param [String] uri_template how to reach the endpoint
66
- # @param [optional, Hash<Symbol>] options
67
- # @option options [optional, Hash<Symbol>] :request for request_stub.with
68
- # @option options [optional, Hash<Symbol>] :response for request_stub.to_return
69
- # @option options [optional, Array, Exception, StandardError, String] :error for request_stub.to_raise
70
- # @option options [optional, TrueClass] :timeout for request_stub.to_timeout
71
- #
72
- # @return [Registration::Endpoint] returns the updated endpoint
73
- #
74
- def update(verb, uri_template, options)
75
- self.verb = verb
76
- self.uri_template = uri_template
77
- self.options = options
82
+ # @param [String] path how to reach the endpoint
83
+ #
84
+ # @return [Endpoint] returns the updated endpoint
85
+ #
86
+ def update(verb, path)
87
+ self.verb = verb
88
+ self.path = path
78
89
  self
79
90
  end
80
91
 
81
92
  def <=>(other)
82
- id <=> other.id
93
+ service_id <=> other.service_id &&
94
+ id <=> other.id
83
95
  end
84
96
 
85
97
  def hash
@@ -94,7 +106,7 @@ module StubRequests
94
106
  # @return [String]
95
107
  #
96
108
  def to_s
97
- "#<#{self.class} id=:#{id} verb=:#{verb} uri_template='#{uri_template}'>"
109
+ "#<#{self.class} id=:#{id} verb=:#{verb} path='#{path}'>"
98
110
  end
99
111
  end
100
112
  end
@@ -0,0 +1,89 @@
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
+ # Class Endpoint provides metrics for stubbed endpoints
12
+ #
13
+ # @author Mikael Henriksson <mikael@zoolutions.se>
14
+ # @since 0.1.2
15
+ #
16
+ class EndpointStub
17
+ # includes "Enumerable"
18
+ # @!parse include Enumerable
19
+ include Enumerable
20
+ # @api private
21
+ include Property
22
+ # @api private
23
+
24
+ #
25
+ # @!attribute [r] service_id
26
+ # @return [Symbol] the id of a {StubRequests::Service}
27
+ property :service_id, type: Symbol
28
+ #
29
+ # @!attribute [r] endpoint_id
30
+ # @return [Symbol] the id of an endpoint
31
+ property :endpoint_id, type: Symbol
32
+ #
33
+ # @!attribute [r] verb
34
+ # @return [String] the HTTP verb/method for this endpoint
35
+ property :verb, type: Symbol
36
+ #
37
+ # @!attribute [r] path
38
+ # @return [String] the full URI template for the endpoint
39
+ property :path, type: String
40
+ #
41
+ # @!attribute [r] stubs
42
+ # @return [Array] an array with recorded stubs
43
+ attr_reader :stubs
44
+
45
+ #
46
+ # Initializes a new Endpoint
47
+ #
48
+ # @param [Service] service a service
49
+ # @param [Endpoint] endpoint an endpoint
50
+ #
51
+ def initialize(service, endpoint)
52
+ self.service_id = service.id
53
+ self.endpoint_id = endpoint.id
54
+ self.verb = endpoint.verb
55
+ self.path = [service.uri, endpoint.path].join("/")
56
+
57
+ @stubs = Concurrent::Array.new
58
+ end
59
+
60
+ def find_by(attribute:, value:)
61
+ find { |request| request.send(attribute) == value }
62
+ end
63
+
64
+ #
65
+ # Required by Enumerable
66
+ #
67
+ #
68
+ # @return [Concurrent::Map<Symbol, Service>] an map with services
69
+ #
70
+ # @yield used by Enumerable
71
+ #
72
+ def each(&block)
73
+ stubs.each(&block)
74
+ end
75
+
76
+ #
77
+ # Records a WebMock::RequestStub as stubbed
78
+ #
79
+ # @param [WebMock::RequestStub] webmock_stub <description>
80
+ #
81
+ # @return [RequestStub]
82
+ #
83
+ def record(webmock_stub)
84
+ request_stub = RequestStub.new(self, webmock_stub)
85
+ stubs.push(request_stub)
86
+ request_stub
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,147 @@
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
+ # Class Endpoints manages a collection of endpoints
12
+ #
13
+ # @author Mikael Henriksson <mikael@zoolutions.se>
14
+ #
15
+ class Endpoints
16
+ include Enumerable
17
+
18
+ #
19
+ # @!attribute [rw] service
20
+ # @return [Service] the service the collection belongs to
21
+ attr_reader :service
22
+ #
23
+ # @!attribute [rw] endpoints
24
+ # @return [Concurrent::Map<Symbol, Endpoint>] a map with endpoints
25
+ attr_reader :endpoints
26
+
27
+ def initialize(service)
28
+ @service = service
29
+ @endpoints = Concurrent::Map.new
30
+ end
31
+
32
+ #
33
+ # Required by Enumerable
34
+ #
35
+ # @return [Concurrent::Map<Symbol, Service>] a map with endpoints
36
+ #
37
+ # @yield used by Enumerable
38
+ #
39
+ def each(&block)
40
+ endpoints.each(&block)
41
+ end
42
+
43
+ #
44
+ # Registers an endpoint in the collection
45
+ #
46
+ # @param [Symbol] endpoint_id the id of this Endpoint
47
+ # @param [Symbol] verb a HTTP verb
48
+ # @param [String] path the URI to reach the endpoint
49
+ #
50
+ # @return [Endpoint]
51
+ #
52
+ # :reek:LongParameterList { max_params: 4 }
53
+ def register(endpoint_id, verb, path)
54
+ endpoint =
55
+ if (endpoint = find(endpoint_id))
56
+ StubRequests.logger.warn("Endpoint already registered: #{endpoint}")
57
+ endpoint.update(verb, path)
58
+ else
59
+ Endpoint.new(service, endpoint_id, verb, path)
60
+ end
61
+
62
+ endpoints[endpoint.id] = endpoint
63
+ endpoint
64
+ end
65
+
66
+ #
67
+ # Updates an endpoint
68
+ #
69
+ # @param [Symbol] endpoint_id the id of the endpoint
70
+ # @param [Symbol] verb a HTTP verb
71
+ # @param [String] path the path to the endpoint
72
+ #
73
+ # @raise [EndpointNotFound] when the endpoint couldn't be found
74
+ #
75
+ # @return [Endpoint] returns the updated endpoint
76
+ #
77
+ # :reek:LongParameterList { max_params: 4 }
78
+ def update(endpoint_id, verb, path)
79
+ endpoint = find!(endpoint_id)
80
+ endpoint.update(verb, path)
81
+ end
82
+
83
+ #
84
+ # Removes an endpoint from the collection
85
+ #
86
+ # @param [Symbol] endpoint_id the id of the endpoint, `:file_service`
87
+ #
88
+ # @return [Endpoint] the endpoint that was removed
89
+ #
90
+ def remove(endpoint_id)
91
+ endpoints.delete(endpoint_id)
92
+ end
93
+
94
+ #
95
+ # Fetches an endpoint from the collection
96
+ #
97
+ # @param [<type>] endpoint_id <description>
98
+ #
99
+ # @return [Endpoint]
100
+ #
101
+ def find(endpoint_id)
102
+ endpoints[endpoint_id]
103
+ end
104
+
105
+ #
106
+ # Fetches an endpoint from the collection or raises an error
107
+ #
108
+ # @param [Symbol] endpoint_id the id of the endpoint
109
+ #
110
+ # @raise [EndpointNotFound] when an endpoint couldn't be found
111
+ #
112
+ # @return [Endpoint, nil]
113
+ #
114
+ def find!(endpoint_id)
115
+ find(endpoint_id) || raise(EndpointNotFound, "Couldn't find an endpoint with id=:#{endpoint_id}")
116
+ end
117
+
118
+ #
119
+ # Returns a descriptive string with all endpoints in the collection
120
+ #
121
+ # @return [String]
122
+ #
123
+ def to_s
124
+ [
125
+ +"#<#{self.class} endpoints=",
126
+ +endpoints_string,
127
+ +">",
128
+ ].join("")
129
+ end
130
+
131
+ #
132
+ # Returns a nicely formatted string with an array of endpoints
133
+ #
134
+ #
135
+ # @return [<type>] <description>
136
+ #
137
+ def endpoints_string
138
+ "[#{endpoints_as_string}]"
139
+ end
140
+
141
+ private
142
+
143
+ def endpoints_as_string
144
+ endpoints.values.map(&:to_s).join(",") if endpoints.size.positive?
145
+ end
146
+ end
147
+ end
@@ -14,49 +14,5 @@ module StubRequests
14
14
  # @since 0.1.3
15
15
  #
16
16
  module Observable
17
- #
18
- # Subscribe to a service endpoint call
19
- # @see Observable::Registry#subscribe
20
- #
21
- #
22
- # @param [Symbol] service_id the id of a service
23
- # @param [Symbol] endpoint_id the id of an endpoint
24
- # @param [Symbol] verb the HTTP verb to subscribe to
25
- # @param [Proc] callback the callback to use for when.a request was made
26
- #
27
- # @return [Subscription]
28
- #
29
- # :reek:LongParameterList
30
- def self.subscribe_to(service_id, endpoint_id, verb, callback)
31
- Registry.instance.subscribe(service_id, endpoint_id, verb, callback)
32
- end
33
-
34
- #
35
- # Unsubscribe from a service endpoint call
36
- # @see Observable::Registry#unsubscribe
37
- #
38
- #
39
- # @param [Symbol] service_id the id of a service
40
- # @param [Symbol] endpoint_id the id of an endpoint
41
- # @param [Symbol] verb the HTTP verb to subscribe to
42
- #
43
- # @return [Subscription]
44
- #
45
- def self.unsubscribe_from(service_id, endpoint_id, verb)
46
- Registry.instance.unsubscribe(service_id, endpoint_id, verb)
47
- end
48
-
49
- #
50
- # Notifies subscribers that a request was made
51
- # @see Observable::Registry#notify_subscribers
52
- #
53
- #
54
- # @param [Metrics::Request] request the stubbed request
55
- #
56
- # @return [Request]
57
- #
58
- def self.notify_subscribers(request)
59
- Registry.instance.notify_subscribers(request)
60
- end
61
17
  end
62
18
  end
@@ -0,0 +1,80 @@
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
+ # Class Stub tracks the WebMock::RequestStub life cycle
12
+ #
13
+ # @author Mikael Henriksson <mikael@zoolutions.se>
14
+ # @since 0.1.2
15
+ #
16
+ # :reek:TooManyInstanceVariables
17
+ class RequestStub
18
+ include Property
19
+ extend Forwardable
20
+
21
+ # Delegate service_id, endpoint_id, verb and path to endpoint
22
+ delegate [:service_id, :endpoint_id, :verb, :path] => :endpoint
23
+ #
24
+ # @!attribute [r] endpoint
25
+ # @return [StubRequests::EndpointStub] a stubbed endpoint
26
+ property :endpoint, type: StubRequests::EndpointStub
27
+ #
28
+ # @!attribute [r] verb
29
+ # @return [Symbol] a HTTP verb/method
30
+ property :verb, type: Symbol
31
+ #
32
+ # @!attribute [r] uri
33
+ # @return [String] the full URI for this endpoint
34
+ property :uri, type: String
35
+ #
36
+ # @!attribute [r] request_stub
37
+ # @return [WebMock::RequestStub] a webmock stubbed request
38
+ property :request_stub, type: WebMock::RequestStub
39
+ #
40
+ # @!attribute [r] recorded_at
41
+ # @return [Time] the time this record was recorded
42
+ property :recorded_at, type: Time
43
+ #
44
+ # @!attribute [r] recorded_from
45
+ # @return [String] the relative path to the spec that recorded it
46
+ property :recorded_from, type: String
47
+ #
48
+ # @!attribute [r] responded_at
49
+ # @return [Time] the time this stubs response was used
50
+ property :responded_at, type: Time
51
+
52
+ #
53
+ # Initialize a new Record
54
+ #
55
+ #
56
+ # @param [Endpoint] endpoint a stubbed endpoint
57
+ # @param [WebMock::RequestStub] request_stub the stubbed webmock request
58
+ #
59
+ def initialize(endpoint, request_stub)
60
+ request_pattern = request_stub.request_pattern
61
+ self.endpoint = endpoint
62
+ self.verb = request_pattern.method_pattern.to_s.to_sym
63
+ self.uri = request_pattern.uri_pattern.to_s
64
+ self.request_stub = request_stub
65
+ self.recorded_at = Time.now
66
+ self.recorded_from = RSpec.current_example.metadata[:location]
67
+ @responded_at = nil # ByPass the validation for the initializer
68
+ end
69
+
70
+ #
71
+ # Marks this record as having responded
72
+ #
73
+ #
74
+ # @return [Time] the time it was marked responded
75
+ #
76
+ def mark_as_responded
77
+ self.responded_at = Time.now
78
+ end
79
+ end
80
+ end