api_matchers 0.3.0 → 0.4.0

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
- YTM2MmZhOGZkNjQ4N2Q1M2ZjMTU0ODhmZjE1ZDBiMjljZTE1YTk4NA==
5
- data.tar.gz: !binary |-
6
- ZGQzMDNiNTQ2YmI2YmU1YWQzZjlkZmZmODk2OTVkZGFmODE1NDc0MA==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- Y2RhNTE5NzdmYTkwMjE0ZTVlM2EwZmM0ZjY2Y2U3MWQ2ZjA5OWIwMjY2NGVh
10
- MmMzNGZhYmE0MzA0OGQ2NjQxYTgyNTJkMDI4YjhmNDJhZmM0NGNmMjAxZjQw
11
- ZTRjM2NlNjI4ZDc5ZjYwZTM2ZTY0ZWIwYTQ1MzRiNmNlOGQ2ZDg=
12
- data.tar.gz: !binary |-
13
- MzIyNmE0NmIwOGQxODRhMmJkN2ZmNmZkMTllOTFjMGJjMzc1MjQ3ZGY4MWZl
14
- NWJjMGFiNjA3ZGRmYjZhMzBkOTAxNzgxM2JkOWQyNzUxNmI5NGRkYWRlMDA1
15
- NTI4MWEzNDY1MGY0YzI2NzYzMGYxYzEwZDAwNDQyZGUyZTg3NjQ=
2
+ SHA1:
3
+ metadata.gz: 55a5fba1fb8dd8e0534a451e2db5af8662312b0e
4
+ data.tar.gz: dfe3690699a99aeffe353d50c7401a5eb741e084
5
+ SHA512:
6
+ metadata.gz: 8a28c82e8bfeede2915149c45e89f0698c9c1600dfeaefb4ddda8e06ad0e88649144a59dd0f40cbe4f2b6b2465b5ea5ca0b205d41bcf8110a416354691d12582
7
+ data.tar.gz: 0d594066a2ba47024bb9cd1126578e0cef31f81a6b97ad009d8f7161f7290384a7a641127b35639b02043662f8b56f44acfeba49c14ed73f75999a6db521c443
data/.travis.yml ADDED
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0
5
+ - jruby
6
+ before_install:
7
+ - export DISPLAY=:99.0
8
+ - sh -e /etc/init.d/xvfb start
9
+ script:
10
+ - bundle exec rspec
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source 'https://rubygems.org'
1
+ source 'http://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in api_matchers.gemspec
4
4
  gemspec
data/README.markdown CHANGED
@@ -1,30 +1,40 @@
1
- # API Matchers
1
+ # API Matchers [![Build Status](https://travis-ci.org/tomas-stefano/api_matchers.png?branch=master)](https://travis-ci.org/tomas-stefano/api_matchers)
2
2
 
3
- Collection of RSpec matchers for create your API.
3
+ Collection of RSpec matchers for your API.
4
4
 
5
5
  ## Response Body Matchers
6
6
 
7
- * have_node
8
- * have_json_node
9
- * have_xml_node
7
+ * `have_node`
8
+ * `have_json_node`
9
+ * `have_xml_node`
10
+ * `have_json`
10
11
 
11
- # Response Status Matchers
12
+ ## Response Status Matchers
12
13
 
13
- * be_ok_
14
- * create_resource
15
- * be_a_bad_request
16
- * be_unauthorized
17
- * be_internal_server_error
18
- * be_not_found
14
+ * `be_ok`
15
+ * `create_resource`
16
+ * `be_a_bad_request`
17
+ * `be_unauthorized`
18
+ * `be_internal_server_error`
19
+ * `be_not_found`
19
20
 
20
- # Other Matcher
21
+ ## Other Matchers
21
22
 
22
- * be_in_xml
23
- * be_a_json
23
+ * `be_in_xml`
24
+ * `be_in_json`
24
25
 
25
26
  ## Install
26
27
 
27
- gem install api_matchers
28
+ Include the gem to your test group in you Gemfile:
29
+
30
+ ```ruby
31
+ group :test do
32
+ gem 'api_matchers'
33
+ # other gems
34
+ end
35
+ ```
36
+
37
+ Or install it manually: `gem install api_matchers`.
28
38
 
29
39
  ## Usage
30
40
 
@@ -33,9 +43,9 @@ Collection of RSpec matchers for create your API.
33
43
  To include all this matchers you need to include the APIMatchers::RSpecMatchers module:
34
44
 
35
45
  ```ruby
36
- RSpec.configure do |config|
37
- config.include APIMatchers::RSpecMatchers
38
- end
46
+ RSpec.configure do |config|
47
+ config.include APIMatchers::RSpecMatchers
48
+ end
39
49
  ```
40
50
 
41
51
  ### Have Node Matcher
@@ -46,33 +56,33 @@ The have_node matcher parse the actual and see if have the expcted node with the
46
56
  You can verify if node exists:
47
57
 
48
58
  ```ruby
49
- '{ "transaction": { "id": 54, "status": "paid" } }'.should have_node(:transaction)
59
+ '{ "transaction": { "id": 54, "status": "paid" } }'.should have_node(:transaction)
50
60
  ```
51
61
 
52
62
  Or if node exist with a value:
53
63
 
54
64
  ```ruby
55
- '{ "transaction": { "id": 54, "status": "paid" } }'.should have_node(:id).with(54)
65
+ '{ "transaction": { "id": 54, "status": "paid" } }'.should have_node(:id).with(54)
56
66
  ```
57
67
 
58
68
  ```ruby
59
- '{ "error": "not_authorized" }'.should have_node(:error).with('not_authorized')
69
+ '{ "error": "not_authorized" }'.should have_node(:error).with('not_authorized')
60
70
  ```
61
71
 
62
72
  ```ruby
63
- '{"parcels":1 }'.should have_node(:parcels).with(1)
73
+ '{"parcels":1 }'.should have_node(:parcels).with(1)
64
74
  ```
65
75
 
66
76
  To see the json node and see if include a text, you can do this:
67
77
 
68
78
  ```ruby
69
- '{"error": "Transaction error: Name cant be blank"}'.should have_node(:error).including_text("Transaction error")
79
+ '{"error": "Transaction error: Name cant be blank"}'.should have_node(:error).including_text("Transaction error")
70
80
  ```
71
81
 
72
82
  You can verify boolean values too:
73
83
 
74
84
  ```ruby
75
- '{"creditcard":true}'.should have_node(:creditcard).with(true)
85
+ '{"creditcard":true}'.should have_node(:creditcard).with(true)
76
86
  ```
77
87
 
78
88
  ### HAVE NODE Matcher Configuration
@@ -80,65 +90,67 @@ You can verify boolean values too:
80
90
  You can configure if you want xml (JSON is the default):
81
91
 
82
92
  ```ruby
83
- APIMatchers.setup do |config|
84
- config.content_type = :xml
85
- end
93
+ APIMatchers.setup do |config|
94
+ config.content_type = :xml
95
+ end
86
96
  ```
87
97
 
88
98
  ```ruby
89
- '<transaction><id>200</id><status>paid</status></transaction>'.should have_node(:status)
99
+ '<transaction><id>200</id><status>paid</status></transaction>'.should have_node(:status)
90
100
  ```
91
101
 
92
- Using the with method:
102
+ Using the `with` method:
93
103
 
94
104
  ```ruby
95
- '<transaction><id>200</id><status>paid</status></transaction>'.should have_node(:status).with('paid')
105
+ '<transaction><id>200</id><status>paid</status></transaction>'.should have_node(:status).with('paid')
96
106
  ```
97
107
 
98
- Or you can use the **have_xml_node** matcher:
108
+ Or you can use the `have_xml_node` matcher:
99
109
 
100
110
  ```ruby
101
- "<error>Transaction error: Name can't be blank</error>".should have_xml_node(:error).with("Transaction error: Name can't be blank")
111
+ "<error>Transaction error: Name can't be blank</error>".should have_xml_node(:error).with("Transaction error: Name can't be blank")
102
112
  ```
103
113
 
104
114
  To see the xml node and see if include a text, you can do this:
105
115
 
106
116
  ```ruby
107
- "<error>Transaction error: Name can't be blank</error>".should have_xml_node(:error).including_text("Transaction error")
117
+ "<error>Transaction error: Name can't be blank</error>".should have_xml_node(:error).including_text("Transaction error")
108
118
  ```
109
119
 
110
- **If you work with xml and json in the same API, I recommend that you check the have_json_node and have_xml_node matchers.**
120
+ **If you work with xml and json in the same API, check the have_json_node and have_xml_node matchers.**
111
121
 
112
- You can configure the name of the method for example:
122
+ You can configure the name of the method and then you will be able to use *without* the **#body** method, for example:
113
123
 
114
124
  ```ruby
115
- ## Instead of this
116
- response.body.should have_node(:foo)
125
+ APIMatchers.setup do |config|
126
+ config.response_body_method = :body
127
+ end
128
+
129
+ response.should have_node(:foo).with('bar')
117
130
  ```
118
131
 
119
- ```ruby
120
- ## YOU can do this
121
- APIMatchers.setup do |config|
122
- config.response_body_method = :body
123
- end
132
+ # Instead of:
133
+ response.body.should have_node(:foo)
124
134
  ```
125
135
 
126
- Then you can use *without* call the **#body** method:
136
+ ### Have JSON Node Matcher
127
137
 
128
138
  ```ruby
129
- response.should have_node(:foo).with('bar')
139
+ '{ "transaction": { "id": 54, "status": "paid" } }'.should have_json_node(:id).with(54)
130
140
  ```
131
141
 
132
- ### Have JSON Node Matcher
142
+ ### Have XML Node Matcher
133
143
 
134
144
  ```ruby
135
- '{ "transaction": { "id": 54, "status": "paid" } }'.should have_json_node(:id).with(54)
145
+ "<product><name>gateway</name></product>".should have_xml_node(:name).with('gateway')
136
146
  ```
137
147
 
138
- ### Have XML Node Matcher
148
+ ### Have JSON Matcher
149
+
150
+ Sometimes, you want to compare the entire JSON structure:
139
151
 
140
152
  ```ruby
141
- "<product><name>gateway</name></product>".should have_xml_node(:name).with('gateway')
153
+ "['Foo', 'Bar', 'Baz']".should have_json(['Foo', 'Bar', 'Baz'])
142
154
  ```
143
155
 
144
156
  ### Create Resource Matcher
@@ -146,7 +158,7 @@ Then you can use *without* call the **#body** method:
146
158
  This matchers see the HTTP STATUS CODE is equal to 201.
147
159
 
148
160
  ```ruby
149
- response.status.should create_resource
161
+ response.status.should create_resource
150
162
  ```
151
163
 
152
164
  ### BAD REQUEST Matcher
@@ -154,8 +166,8 @@ This matchers see the HTTP STATUS CODE is equal to 201.
154
166
  This BAD REQUEST is a matcher that see if the HTTP STATUS code is equal to 400.
155
167
 
156
168
  ```ruby
157
- response.status.should be_a_bad_request
158
- response.status.should be_bad_request
169
+ response.status.should be_a_bad_request
170
+ response.status.should be_bad_request
159
171
  ```
160
172
 
161
173
  ### UNAUTHORIZED Matcher
@@ -163,8 +175,8 @@ This BAD REQUEST is a matcher that see if the HTTP STATUS code is equal to 400.
163
175
  This UNAUTHORIZED is a matcher that see if the HTTP STATUS code is equal to 401.
164
176
 
165
177
  ```ruby
166
- response.status.should be_unauthorized
167
- response.body.should have_node(:message).with('Invalid Credentials')
178
+ response.status.should be_unauthorized
179
+ response.body.should have_node(:message).with('Invalid Credentials')
168
180
  ```
169
181
 
170
182
  ### INTERNAL SERVER ERROR Matcher
@@ -172,8 +184,8 @@ This UNAUTHORIZED is a matcher that see if the HTTP STATUS code is equal to 401.
172
184
  This INTERNAL SERVER Error is a matcher that see if the HTTP STATUS code is equal to 500.
173
185
 
174
186
  ```ruby
175
- response.status.should be_internal_server_error
176
- response.body.should have_node(:message).with('An Internal Error Occurs in our precious app. :S')
187
+ response.status.should be_internal_server_error
188
+ response.body.should have_node(:message).with('An Internal Error Occurs in our precious app. :S')
177
189
  ```
178
190
 
179
191
  ### HTTP STATUS CODE Configuration
@@ -181,32 +193,32 @@ This INTERNAL SERVER Error is a matcher that see if the HTTP STATUS code is equa
181
193
  You can configure the name method to call the http status code:
182
194
 
183
195
  ```ruby
184
- APIMatchers.setup do |config|
185
- config.http_status_method = :status
186
- end
196
+ APIMatchers.setup do |config|
197
+ config.http_status_method = :status
198
+ end
187
199
  ```
188
200
 
189
201
  Then you can use without call the **#status** method:
190
202
 
191
203
  ```ruby
192
- response.should create_resource
204
+ response.should create_resource
193
205
  ```
194
206
 
195
207
  This configurations affects this matchers:
196
208
 
197
- * be_ok
198
- * create_resource
199
- * be_a_bad_request
200
- * be_internal_server_error
201
- * be_unauthorized
202
- * be_not_found
209
+ * `be_ok`
210
+ * `create_resource`
211
+ * `be_a_bad_request`
212
+ * `be_internal_server_error`
213
+ * `be_unauthorized`
214
+ * `be_not_found`
203
215
 
204
216
  ### Be in XML Matcher
205
217
 
206
218
  This is a matcher that see if the content type is xml:
207
219
 
208
220
  ```ruby
209
- response.headers['Content-Type'].should be_in_xml
221
+ response.headers['Content-Type'].should be_in_xml
210
222
  ```
211
223
 
212
224
  ### Be in JSON Matcher
@@ -214,7 +226,7 @@ This is a matcher that see if the content type is xml:
214
226
  This is a matcher that see if the content type is in JSON:
215
227
 
216
228
  ```ruby
217
- response.headers['Content-Type'].should be_in_json
229
+ response.headers['Content-Type'].should be_in_json
218
230
  ```
219
231
 
220
232
  ### Headers Configuration
@@ -222,17 +234,17 @@ This is a matcher that see if the content type is in JSON:
222
234
  You can configure the name method to call the headers and content type:
223
235
 
224
236
  ```ruby
225
- APIMatchers.setup do |config|
226
- config.header_method = :headers
227
- config.header_content_type_key = 'Content-Type'
228
- end
237
+ APIMatchers.setup do |config|
238
+ config.header_method = :headers
239
+ config.header_content_type_key = 'Content-Type'
240
+ end
229
241
  ```
230
242
 
231
- Then you can use without call the **#headers** calling the **#['Content-Type']** method:
243
+ And then you will be able to use without call the **#headers** calling the **#['Content-Type']** method:
232
244
 
233
245
  ```ruby
234
- response.should be_in_json
235
- response.should be_in_xml
246
+ response.should be_in_json
247
+ response.should be_in_xml
236
248
  ```
237
249
 
238
250
  ### Acknowlegments
@@ -242,3 +254,4 @@ Then you can use without call the **#headers** calling the **#['Content-Type']**
242
254
  ### Contributors
243
255
 
244
256
  * Stephen Orens
257
+ * Lucas Caton
@@ -20,7 +20,6 @@ module APIMatchers
20
20
  expected_value = expected_value.to_datetime.to_s
21
21
  end
22
22
  end
23
-
24
23
  return value if value == expected_value or expected_value.nil?
25
24
  end
26
25
 
@@ -4,17 +4,26 @@ module APIMatchers
4
4
  module ResponseBody
5
5
  class HaveXmlNode < Base
6
6
  def matches?(actual)
7
+ value = false
7
8
  @actual = actual
8
9
  xml = Nokogiri::XML(response_body)
9
- node = xml.xpath("//#{@expected_node}").text
10
10
 
11
- if @with_value
12
- node == @with_value.to_s
13
- elsif @expected_including_text
14
- node.to_s.include?(@expected_including_text)
15
- else
16
- node.present?
11
+ node_set = xml.xpath("//#{@expected_node}")
12
+ if node_set
13
+ node_set.each do |node|
14
+ if @with_value
15
+ value = (node.text == @with_value.to_s)
16
+ elsif @expected_including_text
17
+ value = (node.text.to_s.include?(@expected_including_text))
18
+ else
19
+ value = node.text.present?
20
+ end
21
+ # if value is true, time to return
22
+ return value if value
23
+ end
17
24
  end
25
+ # at this point, it failed to match
26
+ return value
18
27
  end
19
28
  end
20
29
  end
@@ -1,3 +1,3 @@
1
1
  module APIMatchers
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -6,6 +6,10 @@ describe APIMatchers::ResponseBody::HaveJson do
6
6
  it 'equal json' do
7
7
  ['Petshop', 'Dogs'].to_json.should have_json(['Petshop', 'Dogs'])
8
8
  end
9
+
10
+ it 'compares with Hash too' do
11
+ { 'offers' => [10, 90] }.to_json.should have_json({ 'offers' => [10,90] })
12
+ end
9
13
  end
10
14
 
11
15
  context 'when fails' do
@@ -63,6 +63,33 @@ describe APIMatchers::ResponseBody::HaveXmlNode do
63
63
  }.to fail_with(%Q{expected to have node called: 'message' including text: 'Fox on the run'. Got: '<error><message>Transaction error: Name can't be blank</message></error>'})
64
64
  end
65
65
  end
66
+
67
+ context "find matching node when multiple records" do
68
+ it "should pass when the expected is included in the actual (1 level)" do
69
+ %{<messages>
70
+ <message><id>4</id></message>
71
+ <message><id>2</id></message>
72
+ </messages>}.should have_xml_node(:id).with(2)
73
+ end
74
+ it "should fail when the expected is not included in the actual (1 level)" do
75
+ %{<messages>
76
+ <message><id>4</id></message>
77
+ <message><id>2</id></message>
78
+ </messages>}.should_not have_xml_node(:id).with(3)
79
+ end
80
+ it "should pass when the expected is included in the actual (2 levels)" do
81
+ %{<messages>
82
+ <message><header><id>4</id></header></message>
83
+ <message><header><id>2</id></header></message>
84
+ </messages>}.should have_xml_node(:id).with(2)
85
+ end
86
+ it "should fail when the expected is not included in the actual (2 levels)" do
87
+ %{<messages>
88
+ <message><header><id>4</id></header></message>
89
+ <message><header><id>2</id></header></message>
90
+ </messages>}.should_not have_xml_node(:id).with(3)
91
+ end
92
+ end
66
93
  end
67
94
 
68
95
  describe "actual.should_not have_xml_node" do
metadata CHANGED
@@ -1,55 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: api_matchers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomas D'Stefano
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-25 00:00:00.000000000 Z
11
+ date: 2013-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ! '>='
17
+ - - '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: 2.10.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ! '>='
24
+ - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: 2.10.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activesupport
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ! '>='
31
+ - - '>='
32
32
  - !ruby/object:Gem::Version
33
33
  version: 3.2.5
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ! '>='
38
+ - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: 3.2.5
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: nokogiri
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ! '>='
45
+ - - '>='
46
46
  - !ruby/object:Gem::Version
47
47
  version: 1.5.2
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ! '>='
52
+ - - '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: 1.5.2
55
55
  description: Collection of RSpec matchers for create your API.
@@ -61,6 +61,7 @@ extra_rdoc_files: []
61
61
  files:
62
62
  - .gitignore
63
63
  - .rvmrc.example
64
+ - .travis.yml
64
65
  - Gemfile
65
66
  - History.markdown
66
67
  - LICENSE
@@ -117,17 +118,17 @@ require_paths:
117
118
  - lib
118
119
  required_ruby_version: !ruby/object:Gem::Requirement
119
120
  requirements:
120
- - - ! '>='
121
+ - - '>='
121
122
  - !ruby/object:Gem::Version
122
123
  version: '0'
123
124
  required_rubygems_version: !ruby/object:Gem::Requirement
124
125
  requirements:
125
- - - ! '>='
126
+ - - '>='
126
127
  - !ruby/object:Gem::Version
127
128
  version: '0'
128
129
  requirements: []
129
130
  rubyforge_project:
130
- rubygems_version: 2.0.3
131
+ rubygems_version: 2.1.10
131
132
  signing_key:
132
133
  specification_version: 4
133
134
  summary: Collection of RSpec matchers for create your API.