dnclabs-fakeweb-matcher 1.1.0

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.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Pat Allan
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,35 @@
1
+ h1. FakeWeb Matcher
2
+
3
+ An RSpec matcher for the Fakeweb HTTP stubbing library, allowing you to use RSpec syntax to check if requests to particular URIs have been made.
4
+
5
+ h2. Installing
6
+
7
+ First, install the gem
8
+ <pre><code>gem install fakeweb-matcher --source http://gemcutter.org</code></pre>
9
+
10
+ Then, in your @spec/spec_helper.rb@ file, you'll need to require the library _after_ you have required "FakeWeb":http://fakeweb.rubyforge.org and "RSpec":http://rspec.info. It should end up looking something like this:
11
+
12
+ <pre><code>require 'spec'
13
+ require 'fakeweb'
14
+ require 'fakeweb_matcher'</code></pre>
15
+
16
+ This ensures that the matcher is automatically loaded into RSpec for you.
17
+
18
+ h2. Usage
19
+
20
+ <pre><code>FakeWeb.should have_requested(:get, 'http://example.com')
21
+ FakeWeb.should have_requested(:any, 'http://example.com')
22
+ FakeWeb.should have_requested(:post, /http:\/\/example.com\/)
23
+ FakeWeb.should_not have_requested(:put, 'http://example.com')</code></pre>
24
+
25
+ h2. Contribution
26
+
27
+ Unsurprisingly, this library is tested using RSpec, and relies upon FakeWeb. It also uses "YARD":http://yard.soen.ca/ for documentation, so if you're submitting patches (which are most definitely welcome!) please use YARD syntax and have valid specs.
28
+
29
+ h2. Contributors
30
+
31
+ * "Thilo Utke":http://github.com/thilo (Regex URL matching)
32
+
33
+ h2. Copyright
34
+
35
+ Copyright (c) 2009 Pat Allan, released under an MIT Licence
@@ -0,0 +1,4 @@
1
+ require 'tasks/distribution'
2
+ require 'tasks/testing'
3
+
4
+ task :default => :spec
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 1
3
+ :minor: 1
4
+ :patch: 0
@@ -0,0 +1,37 @@
1
+ require 'fake_web_matcher/extension'
2
+ require 'fake_web_matcher/matchers'
3
+ require 'fake_web_matcher/request_matcher'
4
+
5
+ # An RSpec matcher for the Fakeweb HTTP stubbing library, allowing you to use
6
+ # RSpec syntax to check if requests to particular URIs have been made.
7
+ #
8
+ # The matcher is automatically included into RSpec's set, and can be used as
9
+ # follows:
10
+ #
11
+ # @example
12
+ # FakeWeb.should have_requested(:get, 'http://example.com')
13
+ # FakeWeb.should have_requested(:any, 'http://example.com')
14
+ # FakeWeb.should_not have_requested(:put, 'http://example.com')
15
+ #
16
+ # @see FakeWebMatcher::Matchers
17
+ # @see http://fakeweb.rubyforge.org
18
+ # @author Pat Allan
19
+ #
20
+ module FakeWebMatcher
21
+ #
22
+ end
23
+
24
+ FakeWeb::Registry.class_eval do
25
+ # Don't like doing this, but need some way to track the requests
26
+ include FakeWebMatcher::Extension
27
+ end
28
+
29
+ Spec::Runner.configure { |config|
30
+ # Adding the custom matcher to the default set
31
+ config.include FakeWebMatcher::Matchers
32
+
33
+ # Ensuring the request list gets cleared after each spec
34
+ config.before :each do
35
+ FakeWeb::Registry.instance.clear_requests
36
+ end
37
+ }
@@ -0,0 +1,43 @@
1
+ module FakeWebMatcher
2
+ # Extension for FakeWeb::Registry, to track requests made for given URIs. The
3
+ # code that includes this into FakeWeb is in the base FakeWebMatcher module.
4
+ #
5
+ # @see http://fakeweb.rubyforge.org
6
+ #
7
+ module Extension
8
+ def self.included(base)
9
+ base.class_eval do
10
+ # Keep the original response_for method
11
+ alias_method :response_without_request_tracking, :response_for
12
+
13
+ # Overwrites the existing FakeWeb::Registry#response method, to ensure
14
+ # requests are tracked. Returns the usual stubbed response.
15
+ #
16
+ # @param [Symbol] method HTTP method
17
+ # @param [String] uri URI requested
18
+ # @param [Proc] block The block passed into Net::HTTP requests
19
+ # @return [String] The stubbed page response
20
+ #
21
+ def response_for(method, uri, &block)
22
+ requests << [method, uri]
23
+ response_without_request_tracking(method, uri, &block)
24
+ end
25
+ end
26
+ end
27
+
28
+ # A list of the requests, kept as an array of arrays, where each child array
29
+ # has two values - the method and the URI.
30
+ #
31
+ # @return [Array] Recorded requests
32
+ #
33
+ def requests
34
+ @requests ||= []
35
+ end
36
+
37
+ # Clears the stored request list
38
+ #
39
+ def clear_requests
40
+ requests.clear
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,22 @@
1
+ # An RSpec matcher for the Fakeweb HTTP stubbing library, allowing you to use
2
+ # RSpec syntax to check if requests to particular URIs have been made.
3
+ #
4
+ # @see FakeWebMatcher::Matchers
5
+ # @see http://fakeweb.rubyforge.org
6
+ # @author Pat Allan
7
+ #
8
+ module FakeWebMatcher
9
+ # Custom matcher holder for RSpec
10
+ #
11
+ module Matchers
12
+ # Returns a new matcher instance.
13
+ #
14
+ # @param [Symbol] method The HTTP method
15
+ # @param [String] uri The URI to check for
16
+ # @return [FakeWebMatcher::RequestMatcher]
17
+ #
18
+ def have_requested(method, uri)
19
+ FakeWebMatcher::RequestMatcher.new(method, uri)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,139 @@
1
+ module FakeWebMatcher
2
+ # Matcher class, following RSpec's expectations. Used to confirm whether a
3
+ # request has been made on a given method and URI.
4
+ #
5
+
6
+ # Monkey patch to add a normalize! method to the URI::HTTP class.
7
+ # It doesn't currently sort the query params which means two URLs
8
+ # that are equivalent except for a different order of query params
9
+ # will be !=. This isn't how FakeWeb works, so we patch it here.
10
+ class ::URI::HTTP
11
+
12
+ # Normalize an HTTP URI so that query param order differences don't
13
+ # affect equality.
14
+ def normalize!
15
+ if query
16
+ query_array = self.query.split('&')
17
+ set_query(query_array.sort.join('&'))
18
+ end
19
+ super
20
+ end
21
+ end
22
+
23
+ class RequestMatcher
24
+ attr_reader :url, :method
25
+
26
+ # Create a new matcher.
27
+ #
28
+ # @param [Symbol] method The HTTP method. Defaults to :any if not supplied.
29
+ # @param [String, Regexp] uri The URI to check for
30
+ #
31
+ def initialize(*args)
32
+ @method, @url = args_split(*args)
33
+ end
34
+
35
+ # Indication of whether there's a match on the URI from given requests.
36
+ #
37
+ # @param [Module] FakeWeb Module, necessary for RSpec, although not
38
+ # required internally.
39
+ # @return [Boolean] true if the URI was requested, otherwise false.
40
+ #
41
+ def matches?(fakeweb)
42
+ !FakeWeb::Registry.instance.requests.detect { |req|
43
+ method, url = args_split(*req)
44
+ match_method(method) && match_url(url)
45
+ }.nil?
46
+ end
47
+
48
+ # Failure message if the URI should have been requested.
49
+ #
50
+ # @return [String] failure message
51
+ #
52
+ def failure_message
53
+ regex?(@url) ? regex_failure_message : url_failure_message
54
+ end
55
+
56
+ # Failure message if the URI should not have been requested.
57
+ #
58
+ # @return [String] failure message
59
+ #
60
+ def negative_failure_message
61
+ regex?(@url) ? regex_negative_failure_message : url_negative_failure_message
62
+ end
63
+
64
+ private
65
+
66
+ def regex_negative_failure_message
67
+ "A URL that matches #{@url.inspect} was requested#{failure_message_method} and should not have been."
68
+ end
69
+
70
+ def url_negative_failure_message
71
+ "The URL #{@url} was requested#{failure_message_method} and should not have been."
72
+ end
73
+
74
+ def regex_failure_message
75
+ "A URL that matches #{@url.inspect} was not requested#{failure_message_method}."
76
+ end
77
+
78
+ def url_failure_message
79
+ "The URL #{@url} was not requested#{failure_message_method}."
80
+ end
81
+
82
+ def failure_message_method
83
+ " using #{formatted_method}" unless @method == :any
84
+ end
85
+
86
+ # Compares methods, or ignores if either side of the comparison is :any.
87
+ #
88
+ # @param [Symbol] method HTTP method
89
+ # @return [Boolean] true if methods match or either is :any.
90
+ #
91
+ def match_method(method)
92
+ @method == :any || method == :any || method == @method
93
+ end
94
+
95
+ # Compares the url either by match it agains a regular expression or
96
+ # by simple comparison
97
+ #
98
+ # @param [String] url the called URI
99
+ # @return [Boolean] true if exprexted URI and called URI match.
100
+ #
101
+ def match_url(url)
102
+ return @url.match(url.to_s) if regex?(@url)
103
+ @url == url
104
+ end
105
+
106
+ # Expected method formatted to be an uppercase string. Example: :get becomes
107
+ # "GET".
108
+ #
109
+ # @return [String] uppercase method
110
+ #
111
+ def formatted_method
112
+ @method.to_s.upcase
113
+ end
114
+
115
+ # Interprets given arguments to a method and URI instance. The URI, as a
116
+ # string, is required, but the method is not (will default to :any).
117
+ #
118
+ # @param [Array] args
119
+ # @return [Array] Two items: method and URI instance or regular expression
120
+ #
121
+ def args_split(*args)
122
+ method = :any
123
+ uri = nil
124
+
125
+ case args.length
126
+ when 1 then uri = args[0]
127
+ when 2 then method, uri = args[0], args[1]
128
+ else
129
+ raise ArgumentError.new("wrong number of arguments")
130
+ end
131
+ uri = URI.parse(uri) unless regex?(uri)
132
+ return method, uri
133
+ end
134
+
135
+ def regex?(object)
136
+ object.is_a?(Regexp)
137
+ end
138
+ end
139
+ end
@@ -0,0 +1 @@
1
+ require 'fake_web_matcher'
@@ -0,0 +1,42 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe FakeWebMatcher::Extension do
4
+ it "should be included into the FakeWeb::Registry class" do
5
+ FakeWeb::Registry.included_modules.should include(FakeWebMatcher::Extension)
6
+ end
7
+
8
+ describe '#requests' do
9
+ it "should return an empty Array by default" do
10
+ FakeWeb::Registry.instance.requests.should == []
11
+ end
12
+ end
13
+
14
+ describe '#clear_requests' do
15
+ it "should clear the requests array" do
16
+ registry = FakeWeb::Registry.instance
17
+ registry.requests << :something
18
+ registry.requests.should == [:something]
19
+
20
+ registry.clear_requests
21
+ registry.requests.should == []
22
+ end
23
+ end
24
+
25
+ describe '#response_for' do
26
+ before :each do
27
+ @registry = FakeWeb::Registry.instance
28
+ end
29
+
30
+ it "should track request" do
31
+ @registry.response_for(:any, 'http://uri.com')
32
+
33
+ @registry.requests.should == [[:any, 'http://uri.com']]
34
+ end
35
+
36
+ it "should return the underlying response from response_without_request_tracking" do
37
+ @registry.stub!(:response_without_request_tracking => :response)
38
+
39
+ @registry.response_for(:any, 'http://uri.com').should == :response
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe FakeWebMatcher::Matchers do
4
+ describe '#have_requested' do
5
+ before :each do
6
+ class Matchbox
7
+ include FakeWebMatcher::Matchers
8
+ end
9
+
10
+ @matcher = Matchbox.new.have_requested(:put, 'http://url.com')
11
+ end
12
+
13
+ it "should return an instance of RequestMatcher" do
14
+ @matcher.should be_a(FakeWebMatcher::RequestMatcher)
15
+ end
16
+
17
+ it "should set the url and method using the matcher arguments" do
18
+ @matcher.url.to_s.should == 'http://url.com'
19
+ @matcher.method.should == :put
20
+ end
21
+ end
22
+
23
+ it "should pass if the request has been made" do
24
+ FakeWeb.register_uri(:get, 'http://example.com/', :body => 'foo')
25
+ open('http://example.com/')
26
+
27
+ FakeWeb.should have_requested(:get, 'http://example.com')
28
+ end
29
+
30
+ it "should pass if the request has not been made" do
31
+ FakeWeb.register_uri(:get, 'http://example.com/', :body => 'foo')
32
+
33
+ FakeWeb.should_not have_requested(:get, 'http://example.com')
34
+ end
35
+
36
+ it "should not care about the order of the query parameters" do
37
+ FakeWeb.register_uri(:get, URI.parse('http://example.com/page?foo=bar&baz=qux'), :body => 'foo')
38
+ open('http://example.com/page?baz=qux&foo=bar')
39
+
40
+ FakeWeb.should have_requested(:get, 'http://example.com/page?foo=bar&baz=qux')
41
+ end
42
+ end
@@ -0,0 +1,123 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe FakeWebMatcher::RequestMatcher do
4
+ describe '#initialize' do
5
+ it "should set the url if no method is supplied" do
6
+ matcher = FakeWebMatcher::RequestMatcher.new('http://example.com')
7
+ matcher.url.to_s.should == 'http://example.com'
8
+ end
9
+
10
+ it "set the url if a method is explicitly supplied" do
11
+ matcher = FakeWebMatcher::RequestMatcher.new(:get, 'http://example.com')
12
+ matcher.url.to_s.should == 'http://example.com'
13
+ end
14
+
15
+ it "should set the method to any if not supplied" do
16
+ matcher = FakeWebMatcher::RequestMatcher.new('http://example.com')
17
+ matcher.method.should == :any
18
+ end
19
+
20
+ it "set the method if explicitly supplied" do
21
+ matcher = FakeWebMatcher::RequestMatcher.new(:get, 'http://example.com')
22
+ matcher.method.should == :get
23
+ end
24
+ end
25
+
26
+ describe '#matches?' do
27
+ before :each do
28
+ FakeWeb.register_uri(:get, 'http://example.com/', :body => 'foo')
29
+ open('http://example.com/')
30
+ end
31
+
32
+ it "should return true if same url and any method" do
33
+ matcher = FakeWebMatcher::RequestMatcher.new('http://example.com')
34
+ matcher.matches?(FakeWeb).should be_true
35
+ end
36
+
37
+ it "should return true if same url and same explicit method" do
38
+ matcher = FakeWebMatcher::RequestMatcher.new(:get, 'http://example.com')
39
+ matcher.matches?(FakeWeb).should be_true
40
+ end
41
+
42
+ it "should return false if same url and different explicit method" do
43
+ matcher = FakeWebMatcher::RequestMatcher.new(:post, 'http://example.com')
44
+ matcher.matches?(FakeWeb).should be_false
45
+ end
46
+
47
+ it "should return false if different url and same method" do
48
+ matcher = FakeWebMatcher::RequestMatcher.new(:get, 'http://domain.com')
49
+ matcher.matches?(FakeWeb).should be_false
50
+ end
51
+
52
+ it "should return false if different url and different explicit method" do
53
+ matcher = FakeWebMatcher::RequestMatcher.new(:post, 'http://domain.com')
54
+ matcher.matches?(FakeWeb).should be_false
55
+ end
56
+
57
+ describe "matching url is regular expression" do
58
+ it "should return true if expression matches" do
59
+ matcher = FakeWebMatcher::RequestMatcher.new(:get, /example/)
60
+ matcher.matches?(FakeWeb).should be_true
61
+ end
62
+
63
+ it "should return false if don't match" do
64
+ matcher = FakeWebMatcher::RequestMatcher.new(:get, /domain/)
65
+ matcher.matches?(FakeWeb).should be_false
66
+ end
67
+
68
+ end
69
+ end
70
+
71
+ describe '#failure_message' do
72
+ it "should mention the method if explicitly set" do
73
+ matcher = FakeWebMatcher::RequestMatcher.new(:get, 'http://example.com')
74
+ matcher.failure_message.
75
+ should == 'The URL http://example.com was not requested using GET.'
76
+ end
77
+
78
+ it "should not mention the method if not explicitly set" do
79
+ matcher = FakeWebMatcher::RequestMatcher.new('http://example.com')
80
+ matcher.failure_message.
81
+ should == 'The URL http://example.com was not requested.'
82
+ end
83
+
84
+ it "should mention failing match" do
85
+ matcher = FakeWebMatcher::RequestMatcher.new(/example.com/)
86
+ matcher.failure_message.
87
+ should == 'A URL that matches /example.com/ was not requested.'
88
+ end
89
+
90
+ it "should mention failing match with method if set" do
91
+ matcher = FakeWebMatcher::RequestMatcher.new(:get, /example.com/)
92
+ matcher.failure_message.
93
+ should == 'A URL that matches /example.com/ was not requested using GET.'
94
+ end
95
+ end
96
+
97
+ describe '#negative_failure_message' do
98
+ it "should mention the method if explicitly set" do
99
+ matcher = FakeWebMatcher::RequestMatcher.new(:get, 'http://example.com')
100
+ matcher.negative_failure_message.
101
+ should == 'The URL http://example.com was requested using GET and should not have been.'
102
+ end
103
+
104
+ it "should not mention the method if not explicitly set" do
105
+ matcher = FakeWebMatcher::RequestMatcher.new('http://example.com')
106
+ matcher.negative_failure_message.
107
+ should == 'The URL http://example.com was requested and should not have been.'
108
+ end
109
+
110
+ it "should mention unexpected match" do
111
+ matcher = FakeWebMatcher::RequestMatcher.new(/example.com/)
112
+ matcher.negative_failure_message.
113
+ should == 'A URL that matches /example.com/ was requested and should not have been.'
114
+ end
115
+
116
+ it "should mention unexpected match with method if set" do
117
+ matcher = FakeWebMatcher::RequestMatcher.new(:get, /example.com/)
118
+ matcher.negative_failure_message.
119
+ should == 'A URL that matches /example.com/ was requested using GET and should not have been.'
120
+ end
121
+
122
+ end
123
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe FakeWebMatcher do
4
+ #
5
+ end
@@ -0,0 +1,11 @@
1
+ $:.unshift File.dirname(__FILE__) + '/../lib'
2
+
3
+ require 'rubygems'
4
+ require 'open-uri'
5
+ require 'spec'
6
+ require 'fake_web'
7
+ require 'fake_web_matcher'
8
+
9
+ Spec::Runner.configure do |config|
10
+ #
11
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dnclabs-fakeweb-matcher
3
+ version: !ruby/object:Gem::Version
4
+ hash: 19
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 1
9
+ - 0
10
+ version: 1.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Pat Allan
14
+ - Wes Morgan
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2010-10-23 00:00:00 -04:00
20
+ default_executable:
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: fakeweb
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ hash: 21
31
+ segments:
32
+ - 1
33
+ - 2
34
+ - 5
35
+ version: 1.2.5
36
+ type: :runtime
37
+ version_requirements: *id001
38
+ - !ruby/object:Gem::Dependency
39
+ name: rspec
40
+ prerelease: false
41
+ requirement: &id002 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ hash: 31
47
+ segments:
48
+ - 1
49
+ - 2
50
+ - 0
51
+ version: 1.2.0
52
+ type: :runtime
53
+ version_requirements: *id002
54
+ description:
55
+ email:
56
+ - pat@freelancing-gods.com
57
+ - morganw@dnc.org
58
+ executables: []
59
+
60
+ extensions: []
61
+
62
+ extra_rdoc_files:
63
+ - LICENSE
64
+ - README.textile
65
+ files:
66
+ - LICENSE
67
+ - README.textile
68
+ - Rakefile
69
+ - VERSION.yml
70
+ - lib/fake_web_matcher.rb
71
+ - lib/fake_web_matcher/extension.rb
72
+ - lib/fake_web_matcher/matchers.rb
73
+ - lib/fake_web_matcher/request_matcher.rb
74
+ - lib/fakeweb_matcher.rb
75
+ - spec/lib/fake_web_matcher/extension_spec.rb
76
+ - spec/lib/fake_web_matcher/matchers_spec.rb
77
+ - spec/lib/fake_web_matcher/request_matcher_spec.rb
78
+ - spec/lib/fake_web_matcher_spec.rb
79
+ - spec/spec_helper.rb
80
+ has_rdoc: true
81
+ homepage: http://github.com/dnclabs/fakeweb-matcher
82
+ licenses: []
83
+
84
+ post_install_message:
85
+ rdoc_options:
86
+ - --charset=UTF-8
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ hash: 3
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ hash: 3
104
+ segments:
105
+ - 0
106
+ version: "0"
107
+ requirements: []
108
+
109
+ rubyforge_project:
110
+ rubygems_version: 1.3.7
111
+ signing_key:
112
+ specification_version: 3
113
+ summary: RSpec matcher for the FakeWeb library
114
+ test_files:
115
+ - spec/lib/fake_web_matcher/extension_spec.rb
116
+ - spec/lib/fake_web_matcher/matchers_spec.rb
117
+ - spec/lib/fake_web_matcher/request_matcher_spec.rb
118
+ - spec/lib/fake_web_matcher_spec.rb
119
+ - spec/spec_helper.rb