rspec-api-matchers 0.5.0 → 0.6.0

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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +24 -19
  3. data/lib/rspec-api/matchers.rb +38 -21
  4. data/lib/rspec-api/matchers/attributes/have_attributes.rb +23 -0
  5. data/lib/rspec-api/matchers/attributes/matcher.rb +101 -0
  6. data/lib/rspec-api/matchers/collection/be_a_collection.rb +20 -0
  7. data/lib/rspec-api/matchers/collection/matcher.rb +19 -0
  8. data/lib/rspec-api/matchers/content_type/have_content_type.rb +24 -0
  9. data/lib/rspec-api/matchers/content_type/matcher.rb +23 -0
  10. data/lib/rspec-api/matchers/filter/be_filtered.rb +20 -0
  11. data/lib/rspec-api/matchers/filter/matcher.rb +57 -0
  12. data/lib/rspec-api/matchers/headers/have_headers.rb +20 -0
  13. data/lib/rspec-api/matchers/headers/matcher.rb +28 -0
  14. data/lib/rspec-api/matchers/json/be_valid_json.rb +20 -0
  15. data/lib/rspec-api/matchers/json/matcher.rb +41 -0
  16. data/lib/rspec-api/matchers/jsonp/be_wrapped_in_callback.rb +24 -0
  17. data/lib/rspec-api/matchers/jsonp/matcher.rb +23 -0
  18. data/lib/rspec-api/matchers/page_links/have_page_links.rb +25 -0
  19. data/lib/rspec-api/matchers/page_links/matcher.rb +18 -0
  20. data/lib/rspec-api/matchers/response/be_a_valid_response.rb +20 -0
  21. data/lib/rspec-api/matchers/response/matcher.rb +52 -0
  22. data/lib/rspec-api/matchers/sort/be_sorted.rb +20 -0
  23. data/lib/rspec-api/matchers/sort/matcher.rb +56 -0
  24. data/lib/rspec-api/matchers/status/have_status.rb +25 -0
  25. data/lib/rspec-api/matchers/status/matcher.rb +46 -0
  26. data/lib/rspec-api/matchers/version.rb +1 -1
  27. metadata +24 -18
  28. data/lib/rspec-api/dsl/be_a_collection.rb +0 -24
  29. data/lib/rspec-api/dsl/be_a_jsonp.rb +0 -24
  30. data/lib/rspec-api/dsl/be_filtered.rb +0 -24
  31. data/lib/rspec-api/dsl/be_sorted.rb +0 -24
  32. data/lib/rspec-api/dsl/have_attributes.rb +0 -37
  33. data/lib/rspec-api/dsl/have_prev_page_link.rb +0 -20
  34. data/lib/rspec-api/dsl/have_status.rb +0 -20
  35. data/lib/rspec-api/dsl/include_content_type.rb +0 -24
  36. data/lib/rspec-api/matchers/attributes.rb +0 -171
  37. data/lib/rspec-api/matchers/collection.rb +0 -42
  38. data/lib/rspec-api/matchers/content_type.rb +0 -26
  39. data/lib/rspec-api/matchers/filter.rb +0 -58
  40. data/lib/rspec-api/matchers/jsonp.rb +0 -27
  41. data/lib/rspec-api/matchers/prev_page_link.rb +0 -23
  42. data/lib/rspec-api/matchers/sort.rb +0 -65
  43. data/lib/rspec-api/matchers/status.rb +0 -60
@@ -0,0 +1,28 @@
1
+ require 'rspec-api/matchers/response/matcher'
2
+
3
+ module RSpecApi
4
+ module Matchers
5
+ module Headers
6
+ class Matcher < Response::Matcher
7
+
8
+ def matches?(response)
9
+ super && headers.is_a?(Hash) && headers.any?
10
+ end
11
+
12
+ def description
13
+ %Q{be a non-empty Hash}
14
+ end
15
+
16
+ private
17
+
18
+ def actual
19
+ headers
20
+ end
21
+
22
+ def match
23
+ 'headers'
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,20 @@
1
+ require 'rspec-api/matchers/json/matcher'
2
+
3
+ module RSpecApi
4
+ module Matchers
5
+ module Json
6
+ # Passes if response body is a valid JSON or callback-wrapped JSON
7
+ #
8
+ # @example
9
+ #
10
+ # # Passes if the body is valid JSON
11
+ # body = '[{"id": 1}]'
12
+ # expect(OpenStruct.new body: body).to be_valid_json
13
+ #
14
+ # For more examples check +be_valid_json_spec.rb+.
15
+ def be_valid_json
16
+ RSpecApi::Matchers::Json::Matcher.new
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,41 @@
1
+ require 'rspec-api/matchers/response/matcher'
2
+ require 'json'
3
+
4
+ module RSpecApi
5
+ module Matchers
6
+ module Json
7
+ class Matcher < Response::Matcher
8
+
9
+ def matches?(response)
10
+ super && json
11
+ end
12
+ alias == matches?
13
+
14
+ def description
15
+ %Q(be valid JSON)
16
+ end
17
+
18
+ private
19
+
20
+ def actual
21
+ body
22
+ end
23
+
24
+ def match
25
+ 'body'
26
+ end
27
+
28
+ def json
29
+ @json ||= JSON strip_callback(body), symbolize_names: true
30
+ rescue JSON::ParserError, JSON::GeneratorError
31
+ nil
32
+ end
33
+
34
+ def strip_callback(text)
35
+ callback_pattern = %r[^.+?\((.*?)\)$]
36
+ text =~ callback_pattern ? text.match(callback_pattern)[1] : text
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,24 @@
1
+ require 'rspec-api/matchers/jsonp/matcher'
2
+
3
+ module RSpecApi
4
+ module Matchers
5
+ module Jsonp
6
+ # Passes if response body is a valid JSON wrapped in a JSONP callback
7
+ #
8
+ # @example
9
+ #
10
+ # # Passes if the body is wrapped in "alert"
11
+ # body = 'alert([{"id": 1}])'
12
+ # expect(OpenStruct.new body: body).to be_wrapped_in_callback(:alert)
13
+ #
14
+ # @note
15
+ #
16
+ # A JSONP should actually return application/javascript...
17
+ #
18
+ # For more examples check +be_wrapped_in_callback_spec.rb+.
19
+ def be_wrapped_in_callback(callback = nil)
20
+ RSpecApi::Matchers::Jsonp::Matcher.new callback
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ require 'rspec-api/matchers/json/matcher'
2
+
3
+ module RSpecApi
4
+ module Matchers
5
+ module Jsonp
6
+ class Matcher < Json::Matcher
7
+ attr_accessor :callback
8
+
9
+ def initialize(callback)
10
+ @callback = callback
11
+ end
12
+
13
+ def matches?(response)
14
+ super && body =~ %r{^#{callback || '.+?'}\((.*?)\)$}
15
+ end
16
+
17
+ def description
18
+ %Q(be wrapped in a JSONP callback #{callback}).rstrip
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ require 'rspec-api/matchers/page_links/matcher'
2
+
3
+ module RSpecApi
4
+ module Matchers
5
+ module PageLinks
6
+ # Passes if response headers include pagination links ()
7
+ #
8
+ # @example
9
+ #
10
+ # # Passes if the headers include a link to the previous page
11
+ # headers = {'Link' => '<https://example.com/1>; rel="prev"'}
12
+ # expect(OpenStruct.new headers: headers).to have_page_links
13
+ #
14
+ # @note
15
+ #
16
+ # Checking for the rel="prev" is probably enough for the purpose.
17
+ # See http://tools.ietf.org/html/rfc5988#page-6 for Link specification.
18
+ #
19
+ # For more examples check +have_page_links_spec.rb+.
20
+ def have_page_links
21
+ RSpecApi::Matchers::PageLinks::Matcher.new
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,18 @@
1
+ require 'rspec-api/matchers/headers/matcher'
2
+
3
+ module RSpecApi
4
+ module Matchers
5
+ module PageLinks
6
+ class Matcher < Headers::Matcher
7
+ def matches?(response)
8
+ # NOTE: Only use headers.fetch('Link', '') after http://git.io/CUz3-Q
9
+ super && (headers['Link'] || '') =~ %r{<.+?>. rel\="prev"}
10
+ end
11
+
12
+ def description
13
+ %Q{include a 'Link' to the previous page}
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,20 @@
1
+ require 'rspec-api/matchers/response/matcher'
2
+
3
+ module RSpecApi
4
+ module Matchers
5
+ module Response
6
+ # Passes if response is present
7
+ #
8
+ # @example
9
+ #
10
+ # # Passes if the response has a status
11
+ # response = OpenStruct.new status: 100
12
+ # expect(response).to be_a_valid_response
13
+ #
14
+ # For more examples check +be_a_valid_response_spec.rb+.
15
+ def be_a_valid_response
16
+ RSpecApi::Matchers::Response::Matcher.new
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,52 @@
1
+ require 'ostruct'
2
+ require 'json'
3
+
4
+ module RSpecApi
5
+ module Matchers
6
+ module Response
7
+ class Matcher
8
+ attr_accessor :response
9
+
10
+ def matches?(response)
11
+ @response = response || OpenStruct.new
12
+ status || headers || body
13
+ end
14
+ alias == matches?
15
+
16
+ def description
17
+ %Q(be a valid response)
18
+ end
19
+
20
+ def failure_message_for_should
21
+ "expected #{match} to #{description}, but got #{actual}"
22
+ end
23
+
24
+ def failure_message_for_should_not
25
+ "expected #{match} not to #{description}, but got #{actual}"
26
+ end
27
+
28
+ private
29
+
30
+ def body
31
+ @body ||= response.body
32
+ end
33
+
34
+ def headers
35
+ @headers ||= response.headers
36
+ end
37
+
38
+ def status
39
+ @status ||= response.status
40
+ end
41
+
42
+ def match
43
+ 'response'
44
+ end
45
+
46
+ def actual
47
+ response
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,20 @@
1
+ require 'rspec-api/matchers/sort/matcher'
2
+
3
+ module RSpecApi
4
+ module Matchers
5
+ module Sort
6
+ # Passes if the response body is a non-empty sorted JSON collection
7
+ #
8
+ # @example
9
+ #
10
+ # # Passes if the body is sorted by descending IDs
11
+ # body = '[{"id": 3}, {"id": 2}, {"id": 1}]'
12
+ # expect(OpenStruct.new body: body).to be_sorted(by: :id, verse: :desc)
13
+ #
14
+ # For more examples check +be_sorted_spec.rb+.
15
+ def be_sorted(options = {})
16
+ RSpecApi::Matchers::Sort::Matcher.new options
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,56 @@
1
+ require 'rspec-api/matchers/collection/matcher'
2
+
3
+ module RSpecApi
4
+ module Matchers
5
+ module Sort
6
+ class Matcher < Collection::Matcher
7
+ attr_accessor :field, :verse
8
+
9
+ def initialize(options = {})
10
+ @field = options[:by]
11
+ @verse = options[:verse]
12
+ end
13
+
14
+ def matches?(response)
15
+ super && all_objects_have_field? && has_two_objects? && is_sorted?
16
+ end
17
+
18
+ def description
19
+ if field
20
+ %Q(be sorted by #{reverse? ? 'descending' : 'ascending'} #{field})
21
+ else
22
+ %Q(be sorted)
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def all_objects_have_field?
29
+ if field
30
+ json.all?{|item| item.is_a?(Hash) && item.key?(field)}
31
+ else
32
+ true
33
+ end
34
+ end
35
+
36
+ def has_two_objects?
37
+ if json.length < 2
38
+ msg = "Cannot test sorting on an array with #{json.length} items"
39
+ raise RSpec::Core::Pending::PendingDeclaredInExample.new msg
40
+ else
41
+ true
42
+ end
43
+ end
44
+
45
+ def is_sorted?
46
+ values = json.map{|item| item[field]}
47
+ values.sort == (reverse? ? values.reverse : values)
48
+ end
49
+
50
+ def reverse?
51
+ ['desc', 'descending'].include? verse.to_s
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,25 @@
1
+ require 'rspec-api/matchers/status/matcher'
2
+
3
+ module RSpecApi
4
+ module Matchers
5
+ module Status
6
+ # Passes if the response has a status that matches +status+.
7
+ #
8
+ # @example
9
+ #
10
+ # # Passes if the response status matches :ok
11
+ # status = :ok
12
+ # expect(OpenStruct.new status: status).to have_status 200
13
+ #
14
+ # @note
15
+ #
16
+ # The full list of symbolic HTTP status codes is available at:
17
+ # http://git.io/YwpDnA#L542
18
+ #
19
+ # For more examples check +have_headers_spec.rb+.
20
+ def have_status(status)
21
+ RSpecApi::Matchers::Status::Matcher.new status
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,46 @@
1
+ require 'rack/utils'
2
+ require 'rspec-api/matchers/response/matcher'
3
+
4
+ module RSpecApi
5
+ module Matchers
6
+ module Status
7
+ class Matcher < Response::Matcher
8
+ attr_accessor :status_symbol_or_code
9
+
10
+ def initialize(status_symbol_or_code)
11
+ @status_symbol_or_code = status_symbol_or_code
12
+ end
13
+
14
+ def matches?(response)
15
+ super && status == status_code
16
+ end
17
+
18
+ def description
19
+ "be #{status_code}"
20
+ end
21
+
22
+ private
23
+
24
+ def status_code
25
+ to_code status_symbol_or_code
26
+ end
27
+
28
+ def to_code(symbol_or_code)
29
+ if symbol_or_code.is_a? Symbol
30
+ Rack::Utils.status_code symbol_or_code
31
+ else
32
+ symbol_or_code
33
+ end
34
+ end
35
+
36
+ def actual
37
+ status
38
+ end
39
+
40
+ def match
41
+ 'status code'
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -1,5 +1,5 @@
1
1
  module RSpecApi
2
2
  module Matchers
3
- VERSION = '0.5.0'
3
+ VERSION = '0.6.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-api-matchers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - claudiob
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-09 00:00:00.000000000 Z
11
+ date: 2013-11-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -101,22 +101,28 @@ executables: []
101
101
  extensions: []
102
102
  extra_rdoc_files: []
103
103
  files:
104
- - lib/rspec-api/dsl/be_a_collection.rb
105
- - lib/rspec-api/dsl/be_a_jsonp.rb
106
- - lib/rspec-api/dsl/be_filtered.rb
107
- - lib/rspec-api/dsl/be_sorted.rb
108
- - lib/rspec-api/dsl/have_attributes.rb
109
- - lib/rspec-api/dsl/have_prev_page_link.rb
110
- - lib/rspec-api/dsl/have_status.rb
111
- - lib/rspec-api/dsl/include_content_type.rb
112
- - lib/rspec-api/matchers/attributes.rb
113
- - lib/rspec-api/matchers/collection.rb
114
- - lib/rspec-api/matchers/content_type.rb
115
- - lib/rspec-api/matchers/filter.rb
116
- - lib/rspec-api/matchers/jsonp.rb
117
- - lib/rspec-api/matchers/prev_page_link.rb
118
- - lib/rspec-api/matchers/sort.rb
119
- - lib/rspec-api/matchers/status.rb
104
+ - lib/rspec-api/matchers/attributes/have_attributes.rb
105
+ - lib/rspec-api/matchers/attributes/matcher.rb
106
+ - lib/rspec-api/matchers/collection/be_a_collection.rb
107
+ - lib/rspec-api/matchers/collection/matcher.rb
108
+ - lib/rspec-api/matchers/content_type/have_content_type.rb
109
+ - lib/rspec-api/matchers/content_type/matcher.rb
110
+ - lib/rspec-api/matchers/filter/be_filtered.rb
111
+ - lib/rspec-api/matchers/filter/matcher.rb
112
+ - lib/rspec-api/matchers/headers/have_headers.rb
113
+ - lib/rspec-api/matchers/headers/matcher.rb
114
+ - lib/rspec-api/matchers/json/be_valid_json.rb
115
+ - lib/rspec-api/matchers/json/matcher.rb
116
+ - lib/rspec-api/matchers/jsonp/be_wrapped_in_callback.rb
117
+ - lib/rspec-api/matchers/jsonp/matcher.rb
118
+ - lib/rspec-api/matchers/page_links/have_page_links.rb
119
+ - lib/rspec-api/matchers/page_links/matcher.rb
120
+ - lib/rspec-api/matchers/response/be_a_valid_response.rb
121
+ - lib/rspec-api/matchers/response/matcher.rb
122
+ - lib/rspec-api/matchers/sort/be_sorted.rb
123
+ - lib/rspec-api/matchers/sort/matcher.rb
124
+ - lib/rspec-api/matchers/status/have_status.rb
125
+ - lib/rspec-api/matchers/status/matcher.rb
120
126
  - lib/rspec-api/matchers/version.rb
121
127
  - lib/rspec-api/matchers.rb
122
128
  - lib/rspec-api-matchers.rb