diff --git a/lib/webmock/api.rb b/lib/webmock/api.rb index 4110c095..26069870 100644 --- a/lib/webmock/api.rb +++ b/lib/webmock/api.rb @@ -72,6 +72,10 @@ def reset_executed_requests! WebMock::RequestRegistry.instance.reset! end + def requests_made + WebMock::RequestRegistry.instance.requests_made + end + private def convert_uri_method_and_options_to_request_and_options(method, uri, options, &block) diff --git a/lib/webmock/request_registry.rb b/lib/webmock/request_registry.rb index e4618d3e..4e2ef3c6 100644 --- a/lib/webmock/request_registry.rb +++ b/lib/webmock/request_registry.rb @@ -21,6 +21,15 @@ def times_executed(request_pattern) end.inject(0) { |sum, (_, times_executed)| sum + times_executed } end + def requests_made + to_a + end + + def to_a + requested_signatures. + array + end + def to_s if requested_signatures.hash.empty? "No requests were made." diff --git a/lib/webmock/util/hash_counter.rb b/lib/webmock/util/hash_counter.rb index ce7c059c..3f2baab4 100644 --- a/lib/webmock/util/hash_counter.rb +++ b/lib/webmock/util/hash_counter.rb @@ -5,22 +5,32 @@ module WebMock module Util class HashCounter - attr_accessor :hash + attr_accessor :hash, :array def initialize self.hash = Hash.new(0) @order = {} @max = 0 @lock = ::Mutex.new + self.array = [] + @request_objects = {} end def put(key, num=1) @lock.synchronize do + store_to_array(key, num) hash[key] += num @order[key] = @max += 1 end end + def store_to_array(key, num) + stored_object = @request_objects[key] ||= key + num.times do + array << stored_object + end + end + def get(key) @lock.synchronize do hash[key] diff --git a/spec/unit/api_spec.rb b/spec/unit/api_spec.rb index 15c6ebd6..c17d53f8 100644 --- a/spec/unit/api_spec.rb +++ b/spec/unit/api_spec.rb @@ -172,4 +172,19 @@ def hash_excluding(*args) }.from(1).to(0) end end + + describe '#requests_made' do + subject { WebMock::API.requests_made } + + let(:request_signature) { WebMock::RequestSignature.new(:get, "www.example.com") } + let(:request_pattern) { WebMock::RequestPattern.new(:get, "www.example.com") } + + before do + WebMock::RequestRegistry.instance.requested_signatures.put(request_signature) + end + + it 'returns the number of requests made' do + expect(subject.count).to eq(1) + end + end end diff --git a/spec/unit/request_registry_spec.rb b/spec/unit/request_registry_spec.rb index 2ed57706..fca30b90 100644 --- a/spec/unit/request_registry_spec.rb +++ b/spec/unit/request_registry_spec.rb @@ -92,4 +92,56 @@ end end + describe "requests_made" do + it "returns the requests made" do + request_registry = WebMock::RequestRegistry.instance + request_registry.requested_signatures.put(WebMock::RequestSignature.new(:get, "www.example.com")) + request_registry.requested_signatures.put(WebMock::RequestSignature.new(:put, "www.example.org")) + expect(request_registry.requests_made.count).to eq(2) + expect(request_registry.requests_made[0].method).to eq(:get) + expect(request_registry.requests_made[0].uri).to eq(Addressable::URI.parse("http://www.example.com/")) + expect(request_registry.requests_made[1].method).to eq(:put) + expect(request_registry.requests_made[1].uri).to eq(Addressable::URI.parse("http://www.example.org/")) + end + + it "returns the headers of the request" do + request_registry = WebMock::RequestRegistry.instance + request_registry.requested_signatures.put(WebMock::RequestSignature.new(:get, "www.example.com", headers: { 'Content-Type' => 'application/json' })) + expect(request_registry.requests_made.first.headers).to eq({ 'Content-Type' => 'application/json' }) + end + + it "only stores references to existing signatures" do + request_registry = WebMock::RequestRegistry.instance + signature = WebMock::RequestSignature.new(:get, "www.example.com") + duplicate_signature = WebMock::RequestSignature.new(:get, "www.example.com") + request_registry.requested_signatures.put(signature) + request_registry.requested_signatures.put(duplicate_signature) + expect(request_registry.requests_made[0].object_id).to eq(signature.object_id) + expect(request_registry.requests_made[1].object_id).to eq(signature.object_id) + end + + context "when storing the same signature with a count" do + it "adds two references to the signature" do + request_registry = WebMock::RequestRegistry.instance + signature = WebMock::RequestSignature.new(:get, "www.example.com") + request_registry.requested_signatures.put(signature, 2) + expect(request_registry.requests_made[0].object_id).to eq(signature.object_id) + expect(request_registry.requests_made[1].object_id).to eq(signature.object_id) + end + end + + context "with a JSON request" do + it "returns the body of the request" do + request_registry = WebMock::RequestRegistry.instance + request_registry.requested_signatures.put(json_request_with_body(a: 1)) + expect(request_registry.requests_made.first.body).to eq({ a: 1 }.to_json) + end + end + end + + private + + def json_request_with_body(body) + WebMock::RequestSignature.new(:get, "www.example.com", body: JSON.generate(body)) + end end