http_stub 0.9.6 → 0.9.7

Sign up to get free protection for your applications and to get access to all the features.
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