pact-support 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NWE0OThiMTk0ZTVjOTU1YWE5MGZmODZiZDM2MjIzNTc3M2YwYTZhYw==
5
- data.tar.gz: !binary |-
6
- NGE1ZmFlOGY4M2NjZTUyMTMxODhhYzNkODU0YmU4ZjY2OGNiYWEwMw==
2
+ SHA1:
3
+ metadata.gz: c22fbc42f806850fdf59aae86c0ab60221e53b31
4
+ data.tar.gz: d861be0013364c930b5d092caa37fab70a3d9c5c
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- M2QzYmJlY2M5MzJjMWQwY2RiOTRlNDBhMWRkYTc2MDc4Mjk3MjY4NDIzZWYw
10
- Zjc3ODE5OWJhN2JiYzk5MDU0NzI2YWI0Mjg4YmUwMmQ0NjhhZWVmMTEwZDI2
11
- NDNlOTYzYjI2NmQ4YWM4YTVlMTQ2NDlmMWFkOTE5OTAzOWVhYWY=
12
- data.tar.gz: !binary |-
13
- YTBlNGY3YWQ2MzViNjgwNTdiODI2YzM0MzNiMGJiOTAxNTkyOTVmNzAzZTQw
14
- OWY4YTA5YTAwYmZjNTZhZWQ4MmU3Y2NkZmNlNjJkZjcxYWUyNWY4NmUxNzY3
15
- ODFkODcxNjkxYjZiZjhkNTFmZTJlOWM0NThjZDAyYTEzZGUyMWI=
6
+ metadata.gz: ce97bbeb237b4ed9dd74251120aab5a1ad6a452057c0fdf4f7236c811fe35a944bc3a89263983782bbc304104ea2e2f36b37a2b40c0455cf8c647ad26e0c249e
7
+ data.tar.gz: 92b643e2648be79ccf6e7221d7d3a30e3a735fe6cc04f0cede398a7ac6bc720a3d0564d8da9ade013003d616c87b39ae1bff815bb7d8dbb5346f8cb3764b4d0c
@@ -2,6 +2,10 @@ Do this to generate your change history
2
2
 
3
3
  git log --pretty=format:' * %h - %s (%an, %ad)'
4
4
 
5
+ ### 0.0.3 (17 October 2014)
6
+
7
+ * bab0b34 - Added possibility to provide queries as Hash. Then order of parameters in the query is not longer relevant. (André Allavena, Tue Oct 14 00:24:38 2014 +1000)
8
+
5
9
  ### 0.0.2 (12 October 2014)
6
10
 
7
11
  * e7080fe - Added a QueryString class in preparation for a QueryHash class (Beth, Sun Oct 12 14:32:15 2014 +1100)
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pact-support (0.0.2)
4
+ pact-support (0.0.3)
5
5
  awesome_print (~> 1.1)
6
6
  find_a_port (~> 1.0.1)
7
7
  json
@@ -46,7 +46,7 @@ GEM
46
46
  rspec-core (~> 3.1.0)
47
47
  rspec-expectations (~> 3.1.0)
48
48
  rspec-mocks (~> 3.1.0)
49
- rspec-core (3.1.6)
49
+ rspec-core (3.1.7)
50
50
  rspec-support (~> 3.1.0)
51
51
  rspec-expectations (3.1.2)
52
52
  diff-lcs (>= 1.2.0, < 2.0)
@@ -0,0 +1,16 @@
1
+ require_relative 'query_hash'
2
+ require_relative 'query_string'
3
+
4
+ module Pact
5
+ class Query
6
+
7
+ def self.create query
8
+ if query.is_a? Hash
9
+ Pact::QueryHash.new(query)
10
+ else
11
+ Pact::QueryString.new(query)
12
+ end
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,55 @@
1
+ require 'pact/shared/active_support_support'
2
+ require 'pact/matchers'
3
+ require 'pact/symbolize_keys'
4
+
5
+ module Pact
6
+ class QueryHash
7
+
8
+ include ActiveSupportSupport
9
+ include Pact::Matchers
10
+ include SymbolizeKeys
11
+
12
+ def initialize query
13
+ @hash = query.nil? ? query : convert_to_hash_of_arrays(query)
14
+ end
15
+
16
+ def convert_to_hash_of_arrays query
17
+ symbolize_keys(query).inject({}) {|h,(k,v)| h[k] = v.is_a?(Array) ? v : [v] ; h }
18
+ end
19
+
20
+ def as_json opts = {}
21
+ @hash
22
+ end
23
+
24
+ def to_json opts = {}
25
+ as_json(opts).to_json(opts)
26
+ end
27
+
28
+ def eql? other
29
+ self == other
30
+ end
31
+
32
+ def == other
33
+ QueryHash === other && other.query == query
34
+ end
35
+
36
+ # other will always be a QueryString, not a QueryHash, as it will have ben created
37
+ # from the actual query string.
38
+ def difference(other)
39
+ diff(query, symbolize_keys(CGI::parse(other.query)))
40
+ end
41
+
42
+ def query
43
+ @hash
44
+ end
45
+
46
+ def to_s
47
+ @hash.inspect
48
+ end
49
+
50
+ def empty?
51
+ @hash && @hash.empty?
52
+ end
53
+
54
+ end
55
+ end
@@ -1,30 +1,38 @@
1
1
  require 'randexp'
2
-
2
+ require 'rack/utils'
3
+ # reqiore 'active_support/core_ext/object/to_param'
3
4
  module Pact
4
5
  module Reification
6
+ include ActiveSupportSupport
5
7
 
6
8
  def self.from_term(term)
7
9
  case term
8
10
  when Pact::Term, Regexp, Pact::SomethingLike
9
- term.generate
11
+ term.generate
10
12
  when Hash
11
13
  term.inject({}) do |mem, (key,term)|
12
14
  mem[key] = from_term(term)
13
- mem
14
- end
15
- when Array
16
- term.inject([]) do |mem, term|
17
- mem << from_term(term)
18
15
  mem
19
16
  end
17
+ when Array
18
+ term.map{ |t| from_term(t)}
20
19
  when Pact::Request::Base
21
20
  from_term(term.to_hash)
22
21
  when Pact::QueryString
23
22
  from_term(term.query)
23
+ when Pact::QueryHash
24
+ term.query.map { |k, v|
25
+ if v.nil?
26
+ k
27
+ elsif v.is_a?(Array) #For cases where there are multiple instance of the same parameter
28
+ v.map { |x| "#{k}=#{from_term(x)}"}.join('&')
29
+ else
30
+ "#{k}=#{from_term(v)}"
31
+ end
32
+ }.join('&')
24
33
  else
25
34
  term
26
35
  end
27
36
  end
28
-
29
37
  end
30
38
  end
@@ -1,7 +1,7 @@
1
1
  require 'pact/matchers'
2
2
  require 'pact/symbolize_keys'
3
3
  require 'pact/consumer_contract/headers'
4
- require 'pact/consumer_contract/query_string'
4
+ require 'pact/consumer_contract/query'
5
5
 
6
6
  module Pact
7
7
 
@@ -19,7 +19,7 @@ module Pact
19
19
  @path = path.chomp('/')
20
20
  @headers = Hash === headers ? Headers.new(headers) : headers # Could be a NullExpectation - TODO make this more elegant
21
21
  @body = body
22
- @query = is_unspecified?(query) ? query : Pact::QueryString.new(query)
22
+ @query = is_unspecified?(query) ? query : Pact::Query.create(query)
23
23
  end
24
24
 
25
25
  def to_json(options = {})
@@ -1,5 +1,5 @@
1
1
  module Pact
2
2
  module Support
3
- VERSION = "0.0.2"
3
+ VERSION = "0.0.3"
4
4
  end
5
5
  end
@@ -299,7 +299,117 @@ module Pact
299
299
  end
300
300
  end
301
301
 
302
- context "when a string is expected, but a number is found" do
302
+ context 'when a query is specified' do
303
+ context 'when the queries are defined by hashes, order does not matter' do
304
+ let(:expected_query) { { params: 'hello', params2: 'world', params3: 'small' } }
305
+ let(:actual_query) { 'params3=small&params2=world&params=hello' }
306
+
307
+ it "does match" do
308
+ expect(subject.matches? actual_request).to be true
309
+ end
310
+ end
311
+
312
+ context 'when the queries are defined by hashes, order does not matter but content does' do
313
+ let(:expected_query) { { params: 'hello', params2: 'world', params3: 'small' } }
314
+ let(:actual_query) { 'params3=big&params2=world&params=hello' }
315
+
316
+ it "does not match" do
317
+ expect(subject.matches? actual_request).to be false
318
+ end
319
+ end
320
+
321
+ context 'when the queries are defined by hashes, with extra unmatched parameters' do
322
+ let(:expected_query) { { params: 'hello', params2: 'world', params3: 'small' } }
323
+ let(:actual_query) { 'params2=world&params=hello' }
324
+
325
+ it "does not match" do
326
+ expect(subject.matches? actual_request).to be false
327
+ end
328
+ end
329
+
330
+ context 'when the queries are defined by hashes holding Pact Terms, order does not matter but content does' do
331
+ let(:expected_query) { { params: 'hello', params2: Term.new(generate: 'world', matcher: /w\w+/), params3: 'small' } }
332
+ let(:actual_query) { 'params3=small&params=hello&params2=wroom'}
333
+
334
+ it "does match" do
335
+ expect(subject.matches? actual_request).to be true
336
+ end
337
+ end
338
+
339
+ context 'when the queries are defined by hashes holding Pact Terms and the regex does not match' do
340
+ let(:expected_query) { { params: 'hello', params2: Term.new(generate: 'world', matcher: /w\w+/), params3: 'small' } }
341
+ let(:actual_query) { 'params3=small&params=hello&params2=bonjour'}
342
+
343
+ it "does not match" do
344
+ expect(subject.matches? actual_request).to be false
345
+ end
346
+ end
347
+
348
+ context 'when the query is a hash containing arrays, to denote multiple parameters with the same name' do
349
+ let(:expected_query) {
350
+ { simple_param: "hi",
351
+ double_param: ["hello", "world"],
352
+ simple2: "bye",
353
+ }
354
+ }
355
+ context 'when the multipe terms are in the correct order - order 1' do
356
+ let(:actual_query) {['simple_param=hi', 'double_param=hello', 'double_param=world', 'simple2=bye'].join('&')}
357
+ it "does match" do
358
+ expect(subject.matches? actual_request).to be true
359
+ end
360
+ end
361
+ context 'when the multipe terms are in the correct order - order 2' do
362
+ let(:actual_query) {['simple_param=hi', 'double_param=hello', 'simple2=bye', 'double_param=world'].join('&')}
363
+ it "does match" do
364
+ expect(subject.matches? actual_request).to be true
365
+ end
366
+ end
367
+ context 'when the multipe terms are in the correct order - order 3' do
368
+ let(:actual_query) {['simple2=bye', 'double_param=hello', 'double_param=world', 'simple_param=hi'].join('&')}
369
+ it "does match" do
370
+ expect(subject.matches? actual_request).to be true
371
+ end
372
+ end
373
+ context 'when the multiple terms are in incorrect order' do
374
+ let(:actual_query) {['simple2=bye', 'double_param=world', 'double_param=hello', 'simple_param=hi'].join('&')}
375
+ it "does not match" do
376
+ expect(subject.matches? actual_request).to be false
377
+ end
378
+ end
379
+ context 'when the first of the multiple terms is missing' do
380
+ let(:actual_query) {['simple_param=hi', 'double_param=world', 'simple2=bye', ].join('&')}
381
+ it "does not match" do
382
+ expect(subject.matches? actual_request).to be false
383
+ end
384
+ end
385
+ context 'when the last of the multiple terms is missing' do
386
+ let(:actual_query) {['simple_param=hi', 'double_param=hello', 'simple2=bye', ].join('&')}
387
+ it "does not match" do
388
+ expect(subject.matches? actual_request).to be false
389
+ end
390
+ end
391
+ end
392
+
393
+ context 'when the query does not contain multiple params of the same name, but the request does' do
394
+ let(:expected_query) { {param1: 'hi', param2: 'there'} }
395
+ context 'when the param is duplicated' do
396
+ let(:actual_query) { 'param1=hi&param2=there&param2=there'}
397
+ it "does not match" do
398
+ expect(subject.matches? actual_request).to be false
399
+ end
400
+ end
401
+ context 'when the duplicated param has different values' do
402
+ let(:actual_query) { 'param1=hi&param2=there&param2=overthere' }
403
+ it "does not match" do
404
+ expect(subject.matches? actual_request).to be false
405
+ end
406
+ end
407
+ end
408
+ end
409
+
410
+
411
+
412
+ context "when in the body a string is expected, but a number is found" do
303
413
  let(:actual_body) { { thing: 123} }
304
414
  let(:expected_body) { { thing: "123" } }
305
415
 
@@ -75,5 +75,39 @@ module Pact
75
75
 
76
76
  end
77
77
 
78
+ context "when Hash Query" do
79
+
80
+ subject { Reification.from_term(query)}
81
+
82
+ let(:query) { QueryHash.new( {param: 'hello', extra: 'world'})}
83
+
84
+ it "returns the hash in the natural order" do
85
+ expect(subject).to eq("param=hello&extra=world")
86
+ end
87
+ end
88
+
89
+ context "when Hash Query with embeded terms" do
90
+
91
+ subject { Reification.from_term(query)}
92
+
93
+ let(:query) { QueryHash.new( {param: 'hello', extra: Pact::Term.new(generate: "wonderworld", matcher: /\w+world/)})}
94
+
95
+ it "returns the hash in the natural order, and fills in Terms appropriately" do
96
+ expect(subject).to eq("param=hello&extra=wonderworld")
97
+ end
98
+
99
+ end
100
+ context "when Hash Query with Arrays and multiple params with the same name" do
101
+
102
+ subject { Reification.from_term(query)}
103
+
104
+ let(:query) { QueryHash.new( {param: 'hello', double: [Pact::Term.new(generate: "wonder", matcher: /\w+/), 'world'], simple: 'bye'})}
105
+
106
+ it "returns the hash in the natural order, and fills in Terms appropriately" do
107
+ expect(subject).to eq("param=hello&double=wonder&double=world&simple=bye")
108
+ end
109
+
110
+ end
111
+
78
112
  end
79
113
  end
@@ -42,6 +42,13 @@ module Pact
42
42
  end
43
43
  end
44
44
 
45
+ context "with a query that is a hash" do
46
+ let(:query) { { params: 'hello', params2: Term.new(generate: 'world', matcher: /w\w+/), params3: 'small' } }
47
+ it "appends the query" do
48
+ expect(subject).to eq("/something?params=hello&params2=world&params3=small")
49
+ end
50
+ end
51
+
45
52
  context "with an empty query" do
46
53
  let(:query) { "" }
47
54
  it "does include a query" do
@@ -41,6 +41,39 @@ shared_examples "a request" do
41
41
  expect(subject.full_path).to eq "/path?a"
42
42
  end
43
43
  end
44
+ context "with a path and a query that is a QueryString" do
45
+ subject { described_class.from_hash({:path => '/path', :method => 'get', :headers => {}, :query => Pact::Term.new(generate: 'a', matcher: /a/)}) }
46
+ it "returns the full path with reified path" do
47
+ expect(subject.full_path).to eq "/path?a"
48
+ end
49
+ end
50
+ context "with a path and a query that is a QueryHash" do
51
+ subject { described_class.from_hash({:path => '/path', :method => 'get', :headers => {}, :query => {param: 'hello', extra: 'world'}}) }
52
+ it "returns the full path with reified path" do
53
+ expect(subject.full_path).to eq "/path?param=hello&extra=world"
54
+ end
55
+ end
56
+ context "with a path and a query that is a QueryHash with an embeded Term" do
57
+ subject { described_class.from_hash({:path => '/path', :method => 'get', :headers => {},
58
+ :query => {param: 'hello', extra: Pact::Term.new(generate: "wonderworld", matcher: /\w+world/)}}) }
59
+ it "returns the full path with reified path" do
60
+ expect(subject.full_path).to eq "/path?param=hello&extra=wonderworld"
61
+ end
62
+ end
63
+ context "with a path and a query that has multiple terms" do
64
+ subject { described_class.from_hash({:path => '/path', :method => 'get', :headers => {},
65
+ :query => {param: 'hello', simple: 'hi', double: [ 'hello', 'world'], last: 'gone'}}) }
66
+ it "returns the full path with reified path" do
67
+ expect(subject.full_path).to eq "/path?param=hello&simple=hi&double=hello&double=world&last=gone"
68
+ end
69
+ end
70
+ context "with a path and a query that has multiple terms including terms" do
71
+ subject { described_class.from_hash({:path => '/path', :method => 'get', :headers => {},
72
+ :query => {param: 'hello', simple: 'hi', double: [ 'hello', Pact::Term.new(generate: "wonderworld", matcher: /\w+world/)], last: 'gone'}}) }
73
+ it "returns the full path with reified path" do
74
+ expect(subject.full_path).to eq "/path?param=hello&simple=hi&double=hello&double=wonderworld&last=gone"
75
+ end
76
+ end
44
77
  end
45
78
 
46
79
  describe "building from a hash" do
@@ -71,10 +104,15 @@ shared_examples "a request" do
71
104
  expect(subject.body).to eq 'hello mallory'
72
105
  end
73
106
 
74
- it "extracts the query" do
107
+ it "extracts the string query" do
75
108
  expect(subject.query).to eq Pact::QueryString.new('query')
76
109
  end
77
110
 
111
+ it "extracts the hash query" do
112
+ raw_request['query']= {param: 'hello', extra: 'world'}
113
+ expect(subject.query).to eq Pact::QueryHash.new( {param: 'hello', extra: 'world'})
114
+ end
115
+
78
116
  it "blows up if method is absent" do
79
117
  raw_request.delete 'method'
80
118
  expect { described_class.from_hash(raw_request) }.to raise_error
@@ -91,4 +129,4 @@ shared_examples "a request" do
91
129
  end
92
130
 
93
131
  end
94
- end
132
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pact-support
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Fraser
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2014-10-12 00:00:00.000000000 Z
15
+ date: 2014-10-17 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: randexp
@@ -32,14 +32,14 @@ dependencies:
32
32
  name: rspec
33
33
  requirement: !ruby/object:Gem::Requirement
34
34
  requirements:
35
- - - ! '>='
35
+ - - '>='
36
36
  - !ruby/object:Gem::Version
37
37
  version: '2.14'
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
41
41
  requirements:
42
- - - ! '>='
42
+ - - '>='
43
43
  - !ruby/object:Gem::Version
44
44
  version: '2.14'
45
45
  - !ruby/object:Gem::Dependency
@@ -74,14 +74,14 @@ dependencies:
74
74
  name: json
75
75
  requirement: !ruby/object:Gem::Requirement
76
76
  requirements:
77
- - - ! '>='
77
+ - - '>='
78
78
  - !ruby/object:Gem::Version
79
79
  version: '0'
80
80
  type: :runtime
81
81
  prerelease: false
82
82
  version_requirements: !ruby/object:Gem::Requirement
83
83
  requirements:
84
- - - ! '>='
84
+ - - '>='
85
85
  - !ruby/object:Gem::Version
86
86
  version: '0'
87
87
  - !ruby/object:Gem::Dependency
@@ -116,14 +116,14 @@ dependencies:
116
116
  name: thor
117
117
  requirement: !ruby/object:Gem::Requirement
118
118
  requirements:
119
- - - ! '>='
119
+ - - '>='
120
120
  - !ruby/object:Gem::Version
121
121
  version: '0'
122
122
  type: :runtime
123
123
  prerelease: false
124
124
  version_requirements: !ruby/object:Gem::Requirement
125
125
  requirements:
126
- - - ! '>='
126
+ - - '>='
127
127
  - !ruby/object:Gem::Version
128
128
  version: '0'
129
129
  - !ruby/object:Gem::Dependency
@@ -158,14 +158,14 @@ dependencies:
158
158
  name: pry
159
159
  requirement: !ruby/object:Gem::Requirement
160
160
  requirements:
161
- - - ! '>='
161
+ - - '>='
162
162
  - !ruby/object:Gem::Version
163
163
  version: '0'
164
164
  type: :development
165
165
  prerelease: false
166
166
  version_requirements: !ruby/object:Gem::Requirement
167
167
  requirements:
168
- - - ! '>='
168
+ - - '>='
169
169
  - !ruby/object:Gem::Version
170
170
  version: '0'
171
171
  - !ruby/object:Gem::Dependency
@@ -200,14 +200,14 @@ dependencies:
200
200
  name: activesupport
201
201
  requirement: !ruby/object:Gem::Requirement
202
202
  requirements:
203
- - - ! '>='
203
+ - - '>='
204
204
  - !ruby/object:Gem::Version
205
205
  version: '0'
206
206
  type: :development
207
207
  prerelease: false
208
208
  version_requirements: !ruby/object:Gem::Requirement
209
209
  requirements:
210
- - - ! '>='
210
+ - - '>='
211
211
  - !ruby/object:Gem::Version
212
212
  version: '0'
213
213
  description:
@@ -238,6 +238,8 @@ files:
238
238
  - lib/pact/consumer_contract/headers.rb
239
239
  - lib/pact/consumer_contract/interaction.rb
240
240
  - lib/pact/consumer_contract/pact_file.rb
241
+ - lib/pact/consumer_contract/query.rb
242
+ - lib/pact/consumer_contract/query_hash.rb
241
243
  - lib/pact/consumer_contract/query_string.rb
242
244
  - lib/pact/consumer_contract/request.rb
243
245
  - lib/pact/consumer_contract/response.rb
@@ -338,17 +340,17 @@ require_paths:
338
340
  - lib
339
341
  required_ruby_version: !ruby/object:Gem::Requirement
340
342
  requirements:
341
- - - ! '>='
343
+ - - '>='
342
344
  - !ruby/object:Gem::Version
343
345
  version: '0'
344
346
  required_rubygems_version: !ruby/object:Gem::Requirement
345
347
  requirements:
346
- - - ! '>='
348
+ - - '>='
347
349
  - !ruby/object:Gem::Version
348
350
  version: '0'
349
351
  requirements: []
350
352
  rubyforge_project:
351
- rubygems_version: 2.1.11
353
+ rubygems_version: 2.0.14
352
354
  signing_key:
353
355
  specification_version: 4
354
356
  summary: Shared code for Pact gems