http_stub 0.9.6 → 0.9.7

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 (34) hide show
  1. data/lib/http_stub/configurer/request/controllable_value.rb +21 -0
  2. data/lib/http_stub/configurer/request/omittable.rb +18 -0
  3. data/lib/http_stub/configurer/request/regexpable.rb +2 -7
  4. data/lib/http_stub/configurer/request/stub.rb +3 -3
  5. data/lib/http_stub/models/exact_value_matcher.rb +13 -0
  6. data/lib/http_stub/models/hash_with_value_matchers.rb +20 -0
  7. data/lib/http_stub/models/omitted_value_matcher.rb +19 -0
  8. data/lib/http_stub/models/regexp_value_matcher.rb +14 -0
  9. data/lib/http_stub/models/stub_headers.rb +1 -1
  10. data/lib/http_stub/models/stub_parameters.rb +1 -1
  11. data/lib/http_stub/models/stub_uri.rb +1 -1
  12. data/lib/http_stub/models/value_matcher.rb +29 -0
  13. data/lib/http_stub/version.rb +1 -1
  14. data/lib/http_stub.rb +7 -2
  15. data/spec/lib/http_stub/configurer/request/controllable_value_spec.rb +34 -0
  16. data/spec/lib/http_stub/configurer/request/omittable_spec.rb +70 -0
  17. data/spec/lib/http_stub/configurer/request/stub_spec.rb +11 -11
  18. data/spec/lib/http_stub/configurer_integration_spec.rb +51 -9
  19. data/spec/lib/http_stub/models/exact_value_matcher_spec.rb +33 -0
  20. data/spec/lib/http_stub/models/hash_with_value_matchers_spec.rb +156 -0
  21. data/spec/lib/http_stub/models/omitted_value_matcher_spec.rb +58 -0
  22. data/spec/lib/http_stub/models/regexp_value_matcher_spec.rb +48 -0
  23. data/spec/lib/http_stub/models/stub_headers_spec.rb +4 -4
  24. data/spec/lib/http_stub/models/stub_parameters_spec.rb +4 -4
  25. data/spec/lib/http_stub/models/stub_uri_spec.rb +9 -9
  26. data/spec/lib/http_stub/models/value_matcher_spec.rb +81 -0
  27. data/spec/lib/http_stub/server_integration_spec.rb +33 -7
  28. data/spec/lib/http_stub/server_spec.rb +13 -16
  29. data/spec/spec_helper.rb +1 -1
  30. metadata +36 -21
  31. data/lib/http_stub/models/hash_with_regexpable_values.rb +0 -20
  32. data/lib/http_stub/models/regexpable_value.rb +0 -22
  33. data/spec/lib/http_stub/models/hash_with_regexpable_values_spec.rb +0 -149
  34. data/spec/lib/http_stub/models/regexpable_value_spec.rb +0 -69
@@ -0,0 +1,21 @@
1
+ module HttpStub
2
+ module Configurer
3
+ module Request
4
+
5
+ class ControllableValue
6
+
7
+ private
8
+
9
+ CONTROL_FORMATTERS = [ HttpStub::Configurer::Request::Regexpable,
10
+ HttpStub::Configurer::Request::Omittable ].freeze
11
+
12
+ public
13
+
14
+ def self.format(value)
15
+ CONTROL_FORMATTERS.reduce(value) { |result, formatter| formatter.format(result) }
16
+ end
17
+
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,18 @@
1
+ module HttpStub
2
+ module Configurer
3
+ module Request
4
+
5
+ class Omittable
6
+
7
+ def self.format(value)
8
+ value.is_a?(Hash) ? value.reduce({}) do |result, entry|
9
+ key, value = entry
10
+ result[key] = value == :omitted ? "control:omitted" : value
11
+ result
12
+ end : value
13
+ end
14
+
15
+ end
16
+ end
17
+ end
18
+ end
@@ -8,22 +8,17 @@ module HttpStub
8
8
 
9
9
  private
10
10
 
11
- FORMATTERS = { String => :format_string, Regexp => :format_regexp, Hash => :format_hash }
11
+ FORMATTERS = { Regexp => :format_regexp, Hash => :format_hash }.freeze
12
12
 
13
13
  public
14
14
 
15
15
  def format(value)
16
16
  formatter = FORMATTERS.find { |formatter_entry| value.is_a?(formatter_entry[0]) }
17
- raise "No Regexp formatter found for #{value}" unless formatter
18
- self.send(formatter[1], value)
17
+ formatter ? self.send(formatter[1], value) : value
19
18
  end
20
19
 
21
20
  private
22
21
 
23
- def format_string(string)
24
- string
25
- end
26
-
27
22
  def format_regexp(regexp)
28
23
  "regexp:#{regexp.source.gsub(/\\\//, "/")}"
29
24
  end
@@ -8,10 +8,10 @@ module HttpStub
8
8
  super("/stubs")
9
9
  self.content_type = "application/json"
10
10
  self.body = {
11
- "uri" => HttpStub::Configurer::Request::Regexpable.format(uri),
11
+ "uri" => HttpStub::Configurer::Request::ControllableValue.format(uri),
12
12
  "method" => options[:method],
13
- "headers" => HttpStub::Configurer::Request::Regexpable.format(options[:headers] || {}),
14
- "parameters" => HttpStub::Configurer::Request::Regexpable.format(options[:parameters] || {}),
13
+ "headers" => HttpStub::Configurer::Request::ControllableValue.format(options[:headers] || {}),
14
+ "parameters" => HttpStub::Configurer::Request::ControllableValue.format(options[:parameters] || {}),
15
15
  "response" => {
16
16
  "status" => options[:response][:status] || "",
17
17
  "content_type" => options[:response][:content_type] || "application/json",
@@ -0,0 +1,13 @@
1
+ module HttpStub
2
+ module Models
3
+
4
+ class ExactValueMatcher
5
+
6
+ def self.match?(stub_value, actual_value)
7
+ stub_value == actual_value
8
+ end
9
+
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,20 @@
1
+ module HttpStub
2
+ module Models
3
+
4
+ class HashWithValueMatchers < Hash
5
+
6
+ def initialize(stub_hash)
7
+ stub_hash.each_pair { |key, value| self[key] = HttpStub::Models::ValueMatcher.new(value) }
8
+ end
9
+
10
+ def match?(actual_hash)
11
+ !(self.find do |key_and_value_matcher|
12
+ other_value = actual_hash[key_and_value_matcher[0]]
13
+ !key_and_value_matcher[1].match?(other_value)
14
+ end)
15
+ end
16
+
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ module HttpStub
2
+ module Models
3
+
4
+ class OmittedValueMatcher
5
+
6
+ private
7
+
8
+ OMITTED_CONTROL_VALUE = "control:omitted".freeze
9
+
10
+ public
11
+
12
+ def self.match?(stub_value, actual_value)
13
+ stub_value == OMITTED_CONTROL_VALUE && actual_value.nil?
14
+ end
15
+
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,14 @@
1
+ module HttpStub
2
+ module Models
3
+
4
+ class RegexpValueMatcher
5
+
6
+ def self.match?(stub_value, actual_value)
7
+ match_data = stub_value.match(/^regexp:(.*)/)
8
+ match_data && !!Regexp.new(match_data[1]).match(actual_value)
9
+ end
10
+
11
+ end
12
+
13
+ end
14
+ end
@@ -4,7 +4,7 @@ module HttpStub
4
4
  class StubHeaders
5
5
 
6
6
  def initialize(headers)
7
- @headers = HttpStub::Models::HashWithRegexpableValues.new((headers || {}).downcase_and_underscore_keys)
7
+ @headers = HttpStub::Models::HashWithValueMatchers.new((headers || {}).downcase_and_underscore_keys)
8
8
  end
9
9
 
10
10
  def match?(request)
@@ -4,7 +4,7 @@ module HttpStub
4
4
  class StubParameters
5
5
 
6
6
  def initialize(parameters)
7
- @parameters = HttpStub::Models::HashWithRegexpableValues.new(parameters || {})
7
+ @parameters = HttpStub::Models::HashWithValueMatchers.new(parameters || {})
8
8
  end
9
9
 
10
10
  def match?(request)
@@ -4,7 +4,7 @@ module HttpStub
4
4
  class StubUri
5
5
 
6
6
  def initialize(uri)
7
- @uri = HttpStub::Models::RegexpableValue.new(uri)
7
+ @uri = HttpStub::Models::ValueMatcher.new(uri)
8
8
  end
9
9
 
10
10
  def match?(request)
@@ -0,0 +1,29 @@
1
+ module HttpStub
2
+ module Models
3
+
4
+ class ValueMatcher
5
+
6
+ private
7
+
8
+ MATCHERS = [ HttpStub::Models::OmittedValueMatcher,
9
+ HttpStub::Models::RegexpValueMatcher,
10
+ HttpStub::Models::ExactValueMatcher ].freeze
11
+
12
+ public
13
+
14
+ def initialize(stub_value)
15
+ @stub_value = stub_value
16
+ end
17
+
18
+ def match?(actual_value)
19
+ !!MATCHERS.find { |matcher| matcher.match?(@stub_value, actual_value) }
20
+ end
21
+
22
+ def to_s
23
+ @stub_value
24
+ end
25
+
26
+ end
27
+
28
+ end
29
+ end
@@ -1,3 +1,3 @@
1
1
  module HttpStub
2
- VERSION = "0.9.6"
2
+ VERSION = "0.9.7"
3
3
  end
data/lib/http_stub.rb CHANGED
@@ -11,8 +11,11 @@ require 'json'
11
11
 
12
12
  require File.expand_path('../http_stub/hash_extensions', __FILE__)
13
13
  require File.expand_path('../http_stub/models/response', __FILE__)
14
- require File.expand_path('../http_stub/models/regexpable_value', __FILE__)
15
- require File.expand_path('../http_stub/models/hash_with_regexpable_values', __FILE__)
14
+ require File.expand_path('../http_stub/models/omitted_value_matcher', __FILE__)
15
+ require File.expand_path('../http_stub/models/regexp_value_matcher', __FILE__)
16
+ require File.expand_path('../http_stub/models/exact_value_matcher', __FILE__)
17
+ require File.expand_path('../http_stub/models/value_matcher', __FILE__)
18
+ require File.expand_path('../http_stub/models/hash_with_value_matchers', __FILE__)
16
19
  require File.expand_path('../http_stub/models/request_header_parser', __FILE__)
17
20
  require File.expand_path('../http_stub/models/stub_uri', __FILE__)
18
21
  require File.expand_path('../http_stub/models/stub_headers', __FILE__)
@@ -24,7 +27,9 @@ require File.expand_path('../http_stub/models/request_pipeline', __FILE__)
24
27
  require File.expand_path('../http_stub/controllers/stub_controller', __FILE__)
25
28
  require File.expand_path('../http_stub/controllers/stub_activator_controller', __FILE__)
26
29
  require File.expand_path('../http_stub/server', __FILE__)
30
+ require File.expand_path('../http_stub/configurer/request/omittable', __FILE__)
27
31
  require File.expand_path('../http_stub/configurer/request/regexpable', __FILE__)
32
+ require File.expand_path('../http_stub/configurer/request/controllable_value', __FILE__)
28
33
  require File.expand_path('../http_stub/configurer/request/stub', __FILE__)
29
34
  require File.expand_path('../http_stub/configurer/request/stub_activator', __FILE__)
30
35
  require File.expand_path('../http_stub/configurer/command', __FILE__)
@@ -0,0 +1,34 @@
1
+ describe HttpStub::Configurer::Request::ControllableValue do
2
+
3
+ describe ".format" do
4
+
5
+ let(:value) { "some value" }
6
+
7
+ it "should format the potential control value via the Regexpable formatter" do
8
+ HttpStub::Configurer::Request::Regexpable.should_receive(:format).with(value)
9
+
10
+ perform_format
11
+ end
12
+
13
+ it "should chain formatting by formatting the Regexpable formatter result via the Omittable formatter" do
14
+ regexp_formatted_value = "some regexp formatted value"
15
+ HttpStub::Configurer::Request::Regexpable.stub(:format).and_return(regexp_formatted_value)
16
+ HttpStub::Configurer::Request::Omittable.should_receive(:format).with(regexp_formatted_value)
17
+
18
+ perform_format
19
+ end
20
+
21
+ it "should return the Omittable formatter result" do
22
+ omit_formatted_value = "some omit formatted value"
23
+ HttpStub::Configurer::Request::Omittable.stub(:format).and_return(omit_formatted_value)
24
+
25
+ perform_format.should eql(omit_formatted_value)
26
+ end
27
+
28
+ def perform_format
29
+ HttpStub::Configurer::Request::ControllableValue.format(value)
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -0,0 +1,70 @@
1
+ describe HttpStub::Configurer::Request::Omittable do
2
+
3
+ describe ".format" do
4
+
5
+ context "when the value is a hash" do
6
+
7
+ context "that contains entries with values that are :omitted" do
8
+
9
+ let(:value) do
10
+ (1..5).reduce({}) do |result, i|
11
+ result["key#{i}"] = (i % 2 == 0) ? "value#{i}" : :omitted
12
+ result
13
+ end
14
+ end
15
+
16
+ it "should return a hash containing the omitted values converted to 'control:omitted'" do
17
+ expected_hash = (1..5).reduce({}) do |result, i|
18
+ result["key#{i}"] = (i % 2 == 0) ? "value#{i}" : "control:omitted"
19
+ result
20
+ end
21
+
22
+ perform_format.should eql(expected_hash)
23
+ end
24
+
25
+ end
26
+
27
+ context "that contains no entries to be omitted" do
28
+
29
+ let(:value) do
30
+ (1..3).reduce({}) do |result, i|
31
+ result["key#{i}"] = "value#{i}"
32
+ result
33
+ end
34
+ end
35
+
36
+ it "should return the hash unchanged" do
37
+ perform_format.should eql(value)
38
+ end
39
+
40
+ end
41
+
42
+ context "that is empty" do
43
+
44
+ let(:value) { {} }
45
+
46
+ it "should return the hash unchanged" do
47
+ perform_format.should eql({})
48
+ end
49
+
50
+ end
51
+
52
+ end
53
+
54
+ context "when the value is not a hash" do
55
+
56
+ let(:value) { "not a hash" }
57
+
58
+ it "should return the value unchanged" do
59
+ perform_format.should eql(value)
60
+ end
61
+
62
+ end
63
+
64
+ def perform_format
65
+ HttpStub::Configurer::Request::Omittable.format(value)
66
+ end
67
+
68
+ end
69
+
70
+ end
@@ -30,7 +30,7 @@ describe HttpStub::Configurer::Request::Stub do
30
30
  let(:request) { HttpStub::Configurer::Request::Stub.new(uri, stub_options) }
31
31
  let(:request_body) { JSON.parse(request.body) }
32
32
 
33
- before(:each) { HttpStub::Configurer::Request::Regexpable.stub(:format) }
33
+ before(:each) { HttpStub::Configurer::Request::ControllableValue.stub(:format) }
34
34
 
35
35
  it "should create a HTTP POST request" do
36
36
  request.method.should eql("POST")
@@ -46,8 +46,8 @@ describe HttpStub::Configurer::Request::Stub do
46
46
 
47
47
  context "when a header option is provided" do
48
48
 
49
- it "should format the headers with regexp support" do
50
- HttpStub::Configurer::Request::Regexpable.should_receive(:format).with(headers)
49
+ it "should format the headers into control values" do
50
+ HttpStub::Configurer::Request::ControllableValue.should_receive(:format).with(headers)
51
51
 
52
52
  request
53
53
  end
@@ -59,7 +59,7 @@ describe HttpStub::Configurer::Request::Stub do
59
59
  let(:headers) { nil }
60
60
 
61
61
  it "should format an empty header hash" do
62
- HttpStub::Configurer::Request::Regexpable.should_receive(:format).with({})
62
+ HttpStub::Configurer::Request::ControllableValue.should_receive(:format).with({})
63
63
 
64
64
  request
65
65
  end
@@ -68,8 +68,8 @@ describe HttpStub::Configurer::Request::Stub do
68
68
 
69
69
  context "when a parameter option is provided" do
70
70
 
71
- it "should format the parameters with regexp support" do
72
- HttpStub::Configurer::Request::Regexpable.should_receive(:format).with(parameters)
71
+ it "should format the parameters into control values" do
72
+ HttpStub::Configurer::Request::ControllableValue.should_receive(:format).with(parameters)
73
73
 
74
74
  request
75
75
  end
@@ -81,7 +81,7 @@ describe HttpStub::Configurer::Request::Stub do
81
81
  let(:parameters) { nil }
82
82
 
83
83
  it "should format an empty parameter hash" do
84
- HttpStub::Configurer::Request::Regexpable.should_receive(:format).with({})
84
+ HttpStub::Configurer::Request::ControllableValue.should_receive(:format).with({})
85
85
 
86
86
  request
87
87
  end
@@ -90,8 +90,8 @@ describe HttpStub::Configurer::Request::Stub do
90
90
 
91
91
  context "generates a JSON body which" do
92
92
 
93
- it "should have an entry containing the regexpable representation of the uri" do
94
- HttpStub::Configurer::Request::Regexpable.should_receive(:format).with(uri).and_return("uri as a string")
93
+ it "should have an entry containing the control value representation of the uri" do
94
+ HttpStub::Configurer::Request::ControllableValue.should_receive(:format).with(uri).and_return("uri as a string")
95
95
 
96
96
  request_body.should include("uri" => "uri as a string")
97
97
  end
@@ -101,14 +101,14 @@ describe HttpStub::Configurer::Request::Stub do
101
101
  end
102
102
 
103
103
  it "should have an entry containing the string representation of the headers" do
104
- HttpStub::Configurer::Request::Regexpable.should_receive(:format)
104
+ HttpStub::Configurer::Request::ControllableValue.should_receive(:format)
105
105
  .with(headers).and_return("headers as string")
106
106
 
107
107
  request_body.should include("headers" => "headers as string")
108
108
  end
109
109
 
110
110
  it "should have an entry containing the string representation of the parameters" do
111
- HttpStub::Configurer::Request::Regexpable.should_receive(:format)
111
+ HttpStub::Configurer::Request::ControllableValue.should_receive(:format)
112
112
  .with(parameters).and_return("parameters as string")
113
113
 
114
114
  request_body.should include("parameters" => "parameters as string")
@@ -11,8 +11,8 @@ describe HttpStub::Configurer, "when the server is running" do
11
11
  context "and the configurer is initialized" do
12
12
 
13
13
  before(:each) do
14
- configurer.class.host server_host
15
- configurer.class.port server_port
14
+ configurer.class.host(server_host)
15
+ configurer.class.port(server_port)
16
16
  configurer.class.initialize!
17
17
  end
18
18
 
@@ -231,8 +231,10 @@ describe HttpStub::Configurer, "when the server is running" do
231
231
  context "whose values are strings" do
232
232
 
233
233
  before(:each) do
234
- configurer.stub_response!("/stub_with_headers", method: :get, headers: { key: "value" },
235
- response: { status: 202, body: "Another stub body" })
234
+ configurer.stub_response!(
235
+ "/stub_with_headers", method: :get, headers: { key: "value" },
236
+ response: { status: 202, body: "Another stub body" }
237
+ )
236
238
  end
237
239
 
238
240
  context "and that request is made" do
@@ -261,8 +263,10 @@ describe HttpStub::Configurer, "when the server is running" do
261
263
  context "whose values are regular expressions" do
262
264
 
263
265
  before(:each) do
264
- configurer.stub_response!("/stub_with_headers", method: :get, headers: { key: /^match.*/ },
265
- response: { status: 202, body: "Another stub body" })
266
+ configurer.stub_response!(
267
+ "/stub_with_headers", method: :get, headers: { key: /^match.*/ },
268
+ response: { status: 202, body: "Another stub body" }
269
+ )
266
270
  end
267
271
 
268
272
  context "and a request that matches is made" do
@@ -331,8 +335,10 @@ describe HttpStub::Configurer, "when the server is running" do
331
335
  context "whose values are regular expressions" do
332
336
 
333
337
  before(:each) do
334
- configurer.stub_response!("/stub_with_parameters", method: :get, parameters: { key: /^match.*/ },
335
- response: { status: 202, body: "Another stub body" })
338
+ configurer.stub_response!(
339
+ "/stub_with_parameters", method: :get, parameters: { key: /^match.*/ },
340
+ response: { status: 202, body: "Another stub body" }
341
+ )
336
342
  end
337
343
 
338
344
  context "and a request that matches is made" do
@@ -362,6 +368,40 @@ describe HttpStub::Configurer, "when the server is running" do
362
368
 
363
369
  end
364
370
 
371
+ context "whose values indicate the parameters must be omitted" do
372
+
373
+ before(:each) do
374
+ configurer.stub_response!(
375
+ "/stub_with_omitted_parameters", method: :get, parameters: { key: :omitted },
376
+ response: { status: 202, body: "Omitted parameter stub body" }
377
+ )
378
+ end
379
+
380
+ context "and a request that matches is made" do
381
+
382
+ let(:response) { Net::HTTP.get_response(server_host, "/stub_with_omitted_parameters", server_port) }
383
+
384
+ it "should replay the stubbed response" do
385
+ response.code.should eql("202")
386
+ response.body.should eql("Omitted parameter stub body")
387
+ end
388
+
389
+ end
390
+
391
+ context "and a request that does not match is made" do
392
+
393
+ let(:response) do
394
+ Net::HTTP.get_response(server_host, "/stub_with_omitted_parameters?key=must_be_omitted", server_port)
395
+ end
396
+
397
+ it "should respond with a 404 status code" do
398
+ response.code.should eql("404")
399
+ end
400
+
401
+ end
402
+
403
+ end
404
+
365
405
  end
366
406
 
367
407
  end
@@ -430,7 +470,9 @@ describe HttpStub::Configurer, "when the server is running" do
430
470
  describe "and an attempt is made to register a response with a given content type" do
431
471
 
432
472
  before(:each) do
433
- configurer.stub_response!("/some_stub_path", method: :get, response: { body: "Some stub body", content_type: "application/xhtml" })
473
+ configurer.stub_response!(
474
+ "/some_stub_path", method: :get, response: { body: "Some stub body", content_type: "application/xhtml" }
475
+ )
434
476
  end
435
477
 
436
478
  it "should register the stub" do
@@ -0,0 +1,33 @@
1
+ describe HttpStub::Models::ExactValueMatcher do
2
+
3
+ describe ".match?" do
4
+
5
+ let(:stub_value) { "some stub value" }
6
+
7
+ describe "when the stub value is equal to the actual value" do
8
+
9
+ let(:actual_value) { stub_value }
10
+
11
+ it "should return true" do
12
+ perform_match.should be_true
13
+ end
14
+
15
+ end
16
+
17
+ describe "when the stub value is not equal to the actual value" do
18
+
19
+ let(:actual_value) { "not equal to stub value" }
20
+
21
+ it "should return false" do
22
+ perform_match.should be_false
23
+ end
24
+
25
+ end
26
+
27
+ def perform_match
28
+ HttpStub::Models::ExactValueMatcher.match?(stub_value, actual_value)
29
+ end
30
+
31
+ end
32
+
33
+ end