rspec-resembles_json_matchers 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +16 -0
  5. data/Appraisals +14 -0
  6. data/Gemfile +4 -0
  7. data/Guardfile +47 -0
  8. data/README.md +225 -0
  9. data/Rakefile +6 -0
  10. data/examples/example_spec.rb +123 -0
  11. data/gemfiles/rails_42.gemfile +8 -0
  12. data/gemfiles/rails_42.gemfile.lock +173 -0
  13. data/gemfiles/rails_42_rspec_33.gemfile +8 -0
  14. data/gemfiles/rails_42_rspec_33.gemfile.lock +173 -0
  15. data/gemfiles/rails_5.gemfile +8 -0
  16. data/gemfiles/rails_5.gemfile.lock +184 -0
  17. data/lib/rspec/resembles_json_matchers.rb +57 -0
  18. data/lib/rspec/resembles_json_matchers/attribute_matcher.rb +85 -0
  19. data/lib/rspec/resembles_json_matchers/helpers.rb +29 -0
  20. data/lib/rspec/resembles_json_matchers/json_matcher.rb +85 -0
  21. data/lib/rspec/resembles_json_matchers/matcherizer.rb +25 -0
  22. data/lib/rspec/resembles_json_matchers/resembles_any_of_matcher.rb +61 -0
  23. data/lib/rspec/resembles_json_matchers/resembles_array_matcher.rb +35 -0
  24. data/lib/rspec/resembles_json_matchers/resembles_class_matcher.rb +29 -0
  25. data/lib/rspec/resembles_json_matchers/resembles_date_matcher.rb +44 -0
  26. data/lib/rspec/resembles_json_matchers/resembles_hash_matcher.rb +110 -0
  27. data/lib/rspec/resembles_json_matchers/resembles_matcher.rb +59 -0
  28. data/lib/rspec/resembles_json_matchers/resembles_numeric_matcher.rb +32 -0
  29. data/lib/rspec/resembles_json_matchers/resembles_route_matcher.rb +25 -0
  30. data/lib/rspec/resembles_json_matchers/resembles_string_matcher.rb +25 -0
  31. data/lib/rspec/resembles_json_matchers/version.rb +5 -0
  32. data/rspec-resembles_json_matchers.gemspec +39 -0
  33. metadata +226 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 85c0060d722ce75ef9a360088d85b78f095cb7c0
4
+ data.tar.gz: f51a19065d79d805b34f6745f494691379527538
5
+ SHA512:
6
+ metadata.gz: a2a0c803b0fa775e02f5077b76df085adbc1b065ffea9b11902a927c3600b2e891b44d6d256d2b6866fdcf067921f9c284ada4a2f158863d81fda0773e0c395b
7
+ data.tar.gz: 7a402c3ca3573eeff8861b557ee7587affaf5cdf2049be860cc0af04eb2c81a57ff9a8a3156ffb46f4a958eea2de47ef2b48cfb421ebed699b125cdb0e77a816
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,16 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.2
4
+ - 2.3.0
5
+ - ruby-head
6
+ before_install: gem install bundler -v 1.11.2
7
+ gemfile:
8
+ - gemfiles/rails_42.gemfile
9
+ - gemfiles/rails_42_rspec_33.gemfile
10
+ - gemfiles/rails_5.gemfile
11
+ matrix:
12
+ fast_finish: true
13
+ allow_failures:
14
+ - rvm: ruby-head
15
+ notifications:
16
+ email: false
@@ -0,0 +1,14 @@
1
+ appraise "rails-42" do
2
+ gem "rails", "~> 4.2.0"
3
+ gem "rspec", "~> 3.4.0"
4
+ end
5
+
6
+ appraise "rails-42-rspec-33" do
7
+ gem "rails", "~> 4.2.0"
8
+ gem "rspec", "~> 3.3.0"
9
+ end
10
+
11
+ appraise "rails-5" do
12
+ gem "rails", "~> 5.0.0.beta2"
13
+ gem "rspec", "~> 3.5.0.beta1"
14
+ end
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rspec-json_api_matchers.gemspec
4
+ gemspec
@@ -0,0 +1,47 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ ## Uncomment and set this to only include directories you want to watch
5
+ # directories %w(app lib config test spec features) \
6
+ # .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
7
+
8
+ ## Note: if you are using the `directories` clause above and you are not
9
+ ## watching the project directory ('.'), then you will want to move
10
+ ## the Guardfile to a watched dir and symlink it back, e.g.
11
+ #
12
+ # $ mkdir config
13
+ # $ mv Guardfile config/
14
+ # $ ln -s config/Guardfile .
15
+ #
16
+ # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
17
+
18
+ # Note: The cmd option is now required due to the increasing number of ways
19
+ # rspec may be run, below are examples of the most common uses.
20
+ # * bundler: 'bundle exec rspec'
21
+ # * bundler binstubs: 'bin/rspec'
22
+ # * spring: 'bin/rspec' (This will use spring if running and you have
23
+ # installed the spring binstubs per the docs)
24
+ # * zeus: 'zeus rspec' (requires the server to be started separately)
25
+ # * 'just' rspec: 'rspec'
26
+
27
+ guard :rspec, cmd: "bundle exec rspec" do
28
+ require "guard/rspec/dsl"
29
+ dsl = Guard::RSpec::Dsl.new(self)
30
+
31
+ # Feel free to open issues for suggestions and improvements
32
+
33
+ # RSpec files
34
+ rspec = dsl.rspec
35
+ watch(rspec.spec_helper) { rspec.spec_dir }
36
+ watch(rspec.spec_support) { rspec.spec_dir }
37
+ watch(rspec.spec_files)
38
+
39
+ # Ruby files
40
+ ruby = dsl.ruby
41
+ dsl.watch_spec_files_for(ruby.lib_files)
42
+
43
+ watch(%r{^lib/rspec/resembles_json_matchers/(.+_matcher)\.rb$}) do |m|
44
+ "spec/matchers/#{m[1]}_spec.rb"
45
+ end
46
+
47
+ end
@@ -0,0 +1,225 @@
1
+ # RSpec::ResemblesJsonMatchers
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/rspec-json_api_matchers.svg)](https://badge.fury.io/rb/rspec-json_api_matchers)[![Build Status](https://travis-ci.org/paul/rspec-json_api_matchers.svg?branch=master)](https://travis-ci.org/paul/rspec-json_api_matchers)
4
+
5
+ This gem provides a set of matchers that make testing JSON documents (actually
6
+ the hashes parsed from them) simpler and more elegant.
7
+
8
+ It provides two primary matchers, `have_attribute` and `resembles`/`resembles_json`.
9
+
10
+ ## `#have_attribute`
11
+
12
+ Use this matcher when you want to examine a single attribute, and optionally
13
+ match against its value.
14
+
15
+ ### Example Usage
16
+
17
+ ```ruby
18
+ RSpec.describe "my hash" do
19
+ include RSpec::ResemblesJsonMatchers
20
+
21
+ subject(:response_document) do
22
+ {
23
+ author: "Paul",
24
+ gems_published: 42,
25
+ created_at: "2016-01-01T00:00:00Z"
26
+ }
27
+ end
28
+
29
+ # Test that the key is present, regardless of value (even nil)
30
+ it { should have_attribute :author }
31
+
32
+ # Test the value by using another matcher
33
+ it { should have_attribute :author, eq("Paul") }
34
+ it { should have_attribute :author, match(/Paul/) }
35
+ it { should have_attribute :gems_published, be > 40 }
36
+ it { should have_attribute :created_at, iso8601_timestamp }
37
+ end
38
+ ```
39
+
40
+ It will also provide nice descriptions in the rspec doc format, and useful
41
+ failure messages:
42
+
43
+ ```
44
+ my hash
45
+ should have attribute :author be present
46
+ should have attribute :author eq "Paul"
47
+ should have attribute :author match /Paul/
48
+ should have attribute :gems_published be > 40
49
+ should have attribute :created_at match /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z/
50
+ ```
51
+
52
+ ```
53
+ Failures:
54
+
55
+ 1) my hash should have attribute :full_name be present
56
+ Failure/Error: it { should have_attribute :full_name }
57
+ Expected attribute :full_name to be present
58
+ # ./spec/examples_spec.rb:24:in `block (2 levels) in <top (required)>'
59
+
60
+ 2) my hash should have attribute :author match /paul/
61
+ Failure/Error: it { should have_attribute :author, match(/paul/) }
62
+ Expected value of attribute :author to match /paul/ but it was "Paul"
63
+ # ./spec/examples_spec.rb:25:in `block (2 levels) in <top (required)>'
64
+ ```
65
+
66
+ ## `#resembles_json`
67
+
68
+ This matcher builds upon `#have_attribute` to let you test an entire JSON document in a single example, but still provide detailed errors about each attribute.
69
+
70
+ Additionally, it does "fuzzy" matching on the fields (unless a matcher is explicitly given), because its primary purpose it do have a clear and concise example of the API output for documentation.
71
+
72
+ See the examples folder for more.
73
+
74
+ ### Example Usage
75
+
76
+ ```ruby
77
+ RSpec.describe "a basic json document" do
78
+ let(:document) do
79
+ {
80
+ "@id": "/posts/2016/test1",
81
+ "@type": "Post",
82
+ "title": "Hello World!",
83
+ "body": "lorem ipsum",
84
+ "created_at": "2016-03-01T00:03:42",
85
+ "published_at": "2016-03-10T15:35:00"
86
+ }
87
+ end
88
+
89
+ specify do
90
+ expect(document).to resemble_json(
91
+ {
92
+ "@id": "/posts/:year/:title",
93
+ "@type": eq("Post"),
94
+ "title": "Hello World!",
95
+ "body": "lorem ipsum",
96
+ "created_at": "2016-03-01T00:03:42",
97
+ "published_at": "2016-03-10T15:35:00"
98
+ }
99
+ )
100
+ end
101
+ end
102
+ ```
103
+
104
+ Again, it provides good descriptions:
105
+
106
+ ```
107
+ a basic json document
108
+ should resemble json
109
+ {
110
+ "@id": /posts/:year/:title,
111
+ "@type": "Post",
112
+ "title": Hello World!,
113
+ "body": lorem ipsum,
114
+ "created_at": "2016-03-01T00:03:42",
115
+ "published_at": "2016-03-10T15:35:00"
116
+ }
117
+ ```
118
+
119
+ And useful failure messages:
120
+
121
+ ```
122
+ Failures:
123
+
124
+ 1) The resembles json matcher a basic json document with several attributes that failed to match should resemble json
125
+ {
126
+ "@id": /posts/:year/:title,
127
+ "@type": "PostCollection",
128
+ "title": 42.0,
129
+ "body": lorem ipsum,
130
+ "created_at": "2016-03-01T00:03:42",
131
+ "published_at": "2016-03-10T15:35:00"
132
+ }
133
+
134
+ Failure/Error:
135
+ expect(document).to resemble_json(
136
+ {
137
+ "@id": "/posts/:year/:title",
138
+ "@type": eq("PostCollection"),
139
+ "title": 42.0,
140
+ "body": "lorem ipsum",
141
+ "created_at": "2016-03-01T00:03:42",
142
+ "published_at": "2016-03-10T15:35:00"
143
+ }
144
+ )
145
+
146
+ failed because
147
+ attribute "@type":
148
+ expected: "PostCollection"
149
+ got: "Post"
150
+ attribute "title":
151
+ "Hello World!" does not resemble a number
152
+ # ./examples/example_spec.rb:40:in `block (4 levels) in <top (required)>'
153
+
154
+ 2) The resembles json matcher a basic json document when the matcher is missing a field that is present in the document should resemble json
155
+ {
156
+ "@id": /posts/:year/:title,
157
+ "@type": "Post",
158
+ "body": lorem ipsum,
159
+ "created_at": "2016-03-01T00:03:42",
160
+ "published_at": "2016-03-10T15:35:00"
161
+ }
162
+
163
+ Failure/Error:
164
+ expect(document).to resemble_json(
165
+ {
166
+ "@id": "/posts/:year/:title",
167
+ "@type": eq("Post"),
168
+ "body": "lorem ipsum",
169
+ "created_at": "2016-03-01T00:03:42",
170
+ "published_at": "2016-03-10T15:35:00"
171
+ }
172
+ )
173
+
174
+ failed because
175
+ attribute "title":
176
+ is present, but no matcher provided to match it
177
+ # ./examples/example_spec.rb:55:in `block (4 levels) in <top (required)>'
178
+
179
+ 3) The resembles json matcher a basic json document when the document is missing a field that is present in the matcher should resemble json
180
+ {
181
+ "@id": /posts/:year/:title,
182
+ "@type": "Post",
183
+ "body": lorem ipsum,
184
+ "created_at": "2016-03-01T00:03:42",
185
+ "published_at": "2016-03-10T15:35:00"
186
+ }
187
+
188
+ Failure/Error:
189
+ expect(document).to resemble_json(
190
+ {
191
+ "@id": "/posts/:year/:title",
192
+ "@type": eq("Post"),
193
+ "body": "lorem ipsum",
194
+ "created_at": "2016-03-01T00:03:42",
195
+ "published_at": "2016-03-10T15:35:00"
196
+ }
197
+ )
198
+
199
+ failed because
200
+ attribute "title":
201
+ is present, but no matcher provided to match it
202
+ # ./examples/example_spec.rb:69:in `block (4 levels) in <top (required)>'
203
+ ```
204
+
205
+
206
+ # Installation
207
+
208
+ Add this line to your application's Gemfile:
209
+
210
+ ```ruby
211
+ gem 'rspec-json_api_matchers'
212
+ ```
213
+
214
+ And then execute:
215
+
216
+ $ bundle
217
+
218
+ Or install it yourself as:
219
+
220
+ $ gem install rspec-json_api_matchers
221
+
222
+ # Contributing
223
+
224
+ Bug reports and pull requests are welcome on GitHub at https://github.com/paul/rspec-json_api_matchers.
225
+
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,123 @@
1
+ require_relative "../spec/spec_helper"
2
+
3
+ RSpec.describe "The resembles json matcher" do
4
+ include RSpec::ResemblesJsonMatchers
5
+
6
+ before :all do
7
+ puts <<-WARNING.strip_heredoc
8
+ NOTE: some of these are expected to fail, they are meant to demonstrate
9
+ the output generated by failing specs
10
+ WARNING
11
+ end
12
+
13
+ describe "a basic json document" do
14
+ let(:document) do
15
+ {
16
+ "@id": "/posts/2016/test1",
17
+ "@type": "Post",
18
+ "title": "Hello World!",
19
+ "body": "lorem ipsum",
20
+ "created_at": "2016-03-01T00:03:42",
21
+ "published_at": "2016-03-10T15:35:00"
22
+ }
23
+ end
24
+
25
+ specify do
26
+ expect(document).to resemble_json(
27
+ {
28
+ "@id": "/posts/:year/:title",
29
+ "@type": eq("Post"),
30
+ "title": "Hello World!",
31
+ "body": "lorem ipsum",
32
+ "created_at": "2016-03-01T00:03:42",
33
+ "published_at": "2016-03-10T15:35:00"
34
+ }
35
+ )
36
+ end
37
+
38
+ context "with several attributes that failed to match" do
39
+ specify do
40
+ expect(document).to resemble_json(
41
+ {
42
+ "@id": "/posts/:year/:title",
43
+ "@type": eq("PostCollection"),
44
+ "title": 42.0,
45
+ "body": "lorem ipsum",
46
+ "created_at": "2016-03-01T00:03:42",
47
+ "published_at": "2016-03-10T15:35:00"
48
+ }
49
+ )
50
+ end
51
+ end
52
+
53
+ context "when the matcher is missing a field that is present in the document" do
54
+ specify do
55
+ expect(document).to resemble_json(
56
+ {
57
+ "@id": "/posts/:year/:title",
58
+ "@type": eq("Post"),
59
+ "body": "lorem ipsum",
60
+ "created_at": "2016-03-01T00:03:42",
61
+ "published_at": "2016-03-10T15:35:00"
62
+ }
63
+ )
64
+ end
65
+ end
66
+
67
+ context "when the document is missing a field that is present in the matcher" do
68
+ specify do
69
+ expect(document).to resemble_json(
70
+ {
71
+ "@id": "/posts/:year/:title",
72
+ "@type": eq("Post"),
73
+ "body": "lorem ipsum",
74
+ "created_at": "2016-03-01T00:03:42",
75
+ "published_at": "2016-03-10T15:35:00"
76
+ }
77
+ )
78
+ end
79
+ end
80
+ end
81
+
82
+ describe "complex nested json documents" do
83
+ let(:document) do
84
+ {
85
+ "@id": "/posts",
86
+ "@type": "PostCollection",
87
+ "nextPage": "/posts?page=2",
88
+ "members": [
89
+ {
90
+ "@id": "/posts/2016/test1",
91
+ "@type": "Post",
92
+ "title": "Hello World!",
93
+ "body": "lorem ipsum",
94
+ "created_at": "2016-03-01T00:03:42",
95
+ "published_at": "2016-03-10T15:35:00"
96
+ }
97
+ ]
98
+ }
99
+ end
100
+
101
+ specify do
102
+ expect(document).to resemble_json(
103
+ {
104
+ "@id": "/posts",
105
+ "@type": eq("PostCollection"),
106
+ "nextPage": "/posts?page=2",
107
+ "members": [
108
+ {
109
+ "@id": "/posts/:year/:title",
110
+ "@type": eq("Post"),
111
+ "title": "Hello World!",
112
+ "body": "lorem ipsum",
113
+ "created_at": "2016-03-01T00:03:42",
114
+ "published_at": "2016-03-10T15:35:00"
115
+ }
116
+ ]
117
+ }
118
+ )
119
+ end
120
+
121
+
122
+ end
123
+ end