Skip to content

Commit acfae16

Browse files
committed
Moved *all* the matchers from RSpecApi
* Added include_content_type matcher * Added have_prev_page_link matcher * Added be_valid_json matcher * Added be_a_jsonp matcher * Added be_sorted matcher * Added be_filtered matcher * Added have_attributes matcher * Added run_if, to execute matchers conditionally * Make sorted/filtered matchers pending if given an empty array
1 parent baa41f0 commit acfae16

32 files changed

+1270
-84
lines changed

Gemfile.lock

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,31 @@
11
PATH
22
remote: .
33
specs:
4-
rspec-api-matchers (0.0.1)
4+
rspec-api-matchers (0.1.0)
5+
activesupport
56
rack
67
rspec
78

89
GEM
910
remote: https://rubygems.org/
1011
specs:
12+
activesupport (4.0.1)
13+
i18n (~> 0.6, >= 0.6.4)
14+
minitest (~> 4.2)
15+
multi_json (~> 1.3)
16+
thread_safe (~> 0.1)
17+
tzinfo (~> 0.3.37)
18+
atomic (1.1.14)
1119
coveralls (0.7.0)
1220
multi_json (~> 1.3)
1321
rest-client
1422
simplecov (>= 0.7)
1523
term-ansicolor
1624
thor
1725
diff-lcs (1.2.4)
26+
i18n (0.6.5)
1827
mime-types (2.0)
28+
minitest (4.7.5)
1929
multi_json (1.8.2)
2030
rack (1.5.2)
2131
rake (10.1.0)
@@ -25,7 +35,7 @@ GEM
2535
rspec-core (~> 2.14.0)
2636
rspec-expectations (~> 2.14.0)
2737
rspec-mocks (~> 2.14.0)
28-
rspec-core (2.14.6)
38+
rspec-core (2.14.7)
2939
rspec-expectations (2.14.3)
3040
diff-lcs (>= 1.1.3, < 2.0)
3141
rspec-mocks (2.14.4)
@@ -36,7 +46,10 @@ GEM
3646
term-ansicolor (1.2.2)
3747
tins (~> 0.8)
3848
thor (0.18.1)
49+
thread_safe (0.1.3)
50+
atomic
3951
tins (0.12.0)
52+
tzinfo (0.3.38)
4053

4154
PLATFORMS
4255
ruby

HISTORY.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,18 @@
1-
v0.0.1 - 2013/10/29 Extracted `match_status` from RSpecApi
1+
v0.1.0 - 2013/11/03
2+
--------------------
3+
4+
* Added include_content_type matcher
5+
* Added have_prev_page_link matcher
6+
* Added be_valid_json matcher
7+
* Added be_a_jsonp matcher
8+
* Added be_sorted matcher
9+
* Added be_filtered matcher
10+
* Added have_attributes matcher
11+
* Added run_if, to execute matchers conditionally
12+
* Make sorted/filtered matchers pending if given an empty array
13+
14+
15+
v0.0.1 - 2013/10/29
16+
--------------------
17+
18+
* Extracted `match_status` from RSpecApi

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ Available matchers
2424
expect(response).to have_status(:ok)
2525
expect(response).to include_content_type(:json)
2626
expect(response).to have_prev_page_link
27+
expect(response).to be_valid_json(Array)
28+
expect(response).to be_a_jsonp('alert')
29+
expect(response).to be_sorted(by: :id, verse: :desc)
30+
expect(response).to be_filtered(10, by: :id)
31+
expect(response).to have_attributes(id: {value: 1.2}, url: {type: {string: :url}})
2732

2833
How to contribute
2934
=================

TODO.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
* Use `default_color` or `fixed_color` for "should not expect to"
2+
* Extract a common matcher class for "expect not_to" (`does_not_match?`)
3+
* Improve example description
4+
* Warn if the app declares matchers with the same name, like `be_filtered_by`

lib/rspec-api/dsl/be_a_jsonp.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
require 'rspec-api/matchers/jsonp'
2+
3+
module RSpecApi
4+
module Matchers
5+
# Convert RSpecAPI::Matchers classes into RSpec-compatible matchers, e.g.:
6+
# makes RSpecApi::Matchers::Status available as expect(...).to match_status
7+
module DSL
8+
# Passes if response body is in JSONP format
9+
#
10+
# @note
11+
#
12+
# A JSONP should actually return application/javascript...
13+
#
14+
# @example
15+
#
16+
# # Passes if the body is a JSON wrapped in a callback
17+
# body = 'alert([{"website":"http://www.example.com","flag":null}])'
18+
# expect(OpenStruct.new body: body).to be_a_jsonp(:alert)
19+
def be_a_jsonp(callback = nil)
20+
RSpecApi::Matchers::Jsonp.new(callback)
21+
end
22+
end
23+
end
24+
end

lib/rspec-api/dsl/be_filtered.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
require 'rspec-api/matchers/filter'
2+
3+
module RSpecApi
4+
module Matchers
5+
# Convert RSpecAPI::Matchers classes into RSpec-compatible matchers, e.g.:
6+
# makes RSpecApi::Matchers::Status available as expect(...).to match_status
7+
module DSL
8+
# Passes if response body is filtered by +options[:by]+ comparing with +options[:comparing_with]+
9+
#
10+
# @example
11+
#
12+
# # Passes if the body only contains ID = 1
13+
# body = '[{"id": 1}, {"id": 1}, {"id": 1}]'
14+
# expect(OpenStruct.new body: body).to be_filtered(1, by: :id)
15+
#
16+
# # Passes if the body only contains ID < 10
17+
# body = '[{"id": 1}, {"id": 6}, {"id": 3}]'
18+
# expect(OpenStruct.new body: body).to be_filtered(10, by: :id, comparing_with: :<)
19+
def be_filtered(value = nil, options = {})
20+
RSpecApi::Matchers::Filter.new value, options
21+
end
22+
end
23+
end
24+
end

lib/rspec-api/dsl/be_sorted.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
require 'rspec-api/matchers/sort'
2+
3+
module RSpecApi
4+
module Matchers
5+
# Convert RSpecAPI::Matchers classes into RSpec-compatible matchers, e.g.:
6+
# makes RSpecApi::Matchers::Status available as expect(...).to match_status
7+
module DSL
8+
# Passes if response body is sorted by +options[:by]+ with +options[:verse]+
9+
#
10+
# @example
11+
#
12+
# # Passes if the body is sorted by ascending IDs
13+
# body = '[{"id": 1}, {"id": 2}, {"id": 3}]'
14+
# expect(OpenStruct.new body: body).to be_sorted(by: :id)
15+
#
16+
# # Passes if the body is sorted by descending timestamps
17+
# body = '[{"t": "2013-10-29T18:09:43Z"}, {"t": "2009-01-12T18:09:43Z"}]'
18+
# expect(OpenStruct.new body: body).to be_sorted(by: :t, verse: :desc)
19+
def be_sorted(options = {})
20+
RSpecApi::Matchers::Sort.new options
21+
end
22+
end
23+
end
24+
end

lib/rspec-api/dsl/be_valid_json.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
require 'rspec-api/matchers/json'
2+
3+
module RSpecApi
4+
module Matchers
5+
# Convert RSpecAPI::Matchers classes into RSpec-compatible matchers, e.g.:
6+
# makes RSpecApi::Matchers::Status available as expect(...).to match_status
7+
module DSL
8+
# Passes if response body is JSON. Optionally check if Array or Hash.
9+
# Skips if if response body is JSON. Optionally check if Array or Hash.
10+
#
11+
# @example
12+
#
13+
# # Passes if the body is valid JSON
14+
# body = '{"id": 1}'
15+
# expect(OpenStruct.new body: body).to be_valid_json
16+
#
17+
# # Passes if the body is a valid JSON-marshalled Hash
18+
# body = '{"id": 1}'
19+
# expect(OpenStruct.new body: body).to be_valid_json(Hash)
20+
#
21+
# # Passes if the body is a valid JSON-marshalled Array
22+
# body = '[{"id": 1}, {"id": 2}]'
23+
# expect(OpenStruct.new body: body).to be_valid_json(Array)
24+
def be_valid_json(type = nil)
25+
RSpecApi::Matchers::Json.new(type)
26+
end
27+
end
28+
end
29+
end
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
require 'rspec-api/matchers/attributes'
2+
3+
module RSpecApi
4+
module Matchers
5+
# Convert RSpecAPI::Matchers classes into RSpec-compatible matchers, e.g.:
6+
# makes RSpecApi::Matchers::Status available as expect(...).to match_status
7+
module DSL
8+
# Passes if response body is an object or array of objects with +key+.
9+
#
10+
# @example
11+
#
12+
# # Passes if the body is an object with key :id
13+
# body = '{"id": 1, "url": "http://www.example.com"}'
14+
# expect(OpenStruct.new body: body).to have_attributes(:id)
15+
#
16+
# # Passes if the body is an object with key :id and value 1
17+
# body = '{"id": 1, "url": "http://www.example.com"}'
18+
# expect(OpenStruct.new body: body).to have_attributes(id: {value: 1})
19+
#
20+
# # Passes if the body is an array of objects, all with key :id
21+
# body = '{"id": 1, "name": ""}, {"id": 2}]'
22+
# expect(OpenStruct.new body: body).to have_attributes(:id)
23+
#
24+
# # Passes if the body is an array of object with key :id and odd values
25+
# body = '{"id": 1, "name": ""}, {"id": 3}], {"id": 5}]'
26+
# expect(OpenStruct.new body: body).to have_attributes(id: {value: -> v {v.odd?}})
27+
28+
# TODO: add &block options
29+
def have_attributes(attributes = {})
30+
RSpecApi::Matchers::Attributes.new attributes
31+
end
32+
# alias have_attribute have_attributes
33+
# alias have_keys have_attributes
34+
# alias have_key have_attributes
35+
end
36+
end
37+
end
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
require 'rspec-api/matchers/prev_page_link'
2+
3+
module RSpecApi
4+
module Matchers
5+
# Convert RSpecAPI::Matchers classes into RSpec-compatible matchers, e.g.:
6+
# makes RSpecApi::Matchers::Status available as expect(...).to match_status
7+
module DSL
8+
# Passes if response includes the pagination Link rel=prev in the headers
9+
#
10+
# @example
11+
#
12+
# # Passes if the headers specify the pagination link for Prev
13+
# headers = {'Link' => '<https://example.com/1>; rel="prev"'}
14+
# expect(OpenStruct.new headers: headers).to have_prev_page_link
15+
def have_prev_page_link
16+
RSpecApi::Matchers::PrevPageLink.new
17+
end
18+
end
19+
end
20+
end

0 commit comments

Comments
 (0)