jsonapi_rspec 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 6f6a700c0770ee5ba9954b77fcc7818dce6274ae
4
- data.tar.gz: cbd8512415d501c272add052d2b7ae9668ab5ca4
2
+ SHA256:
3
+ metadata.gz: 91691a7bae77e856d4e74a25dd19c77b975db69236cef26c86b63a0c3784aa7e
4
+ data.tar.gz: 73a0e0e28874965a75a9656d7d96f164c3433c1301c067c081109e6c0ff29ee2
5
5
  SHA512:
6
- metadata.gz: 2a59ac4bda91aa5f2ec4c41096779803f1266c9e9d509a22c977b9d2b39145957864da2b8b0a8fb2a3948de1e24654f7e12084da0bbd1803375af8d54a4e783d
7
- data.tar.gz: 9ecc45dad3f2f86d63c992c8c8aff538125c8d9e1a3f2241b5bb740c78aee641c388f036c3fa466a7212d5d9b6a346f371f4cd6ee7afaad6f2a193ca142e2dbd
6
+ metadata.gz: 824688ffa37f0cde362c2bcc3ff17fb3f1186e4c770e723567855f7dc5f5d4802cc57aa1c41eee1b36e7d4336b06c725f20960038c533fbf6faedf6833cb5f65
7
+ data.tar.gz: 1aae4f5f3c127ff877566123e9f0a3cecf165390c0b508dfcca1c7d5fea2a39adef7eafd98ca344955d5a75ddfb36c3ad041c0919a5acbfb4caf912a7c4ccc91
data/.gitignore CHANGED
@@ -9,3 +9,7 @@
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
+
13
+ # Don't checking Gemfile.lock for Gems
14
+ # https://yehudakatz.com/2010/12/16/clarifying-the-roles-of-the-gemspec-and-gemfile/
15
+ Gemfile.lock
data/.rubocop.yml ADDED
@@ -0,0 +1,246 @@
1
+ require:
2
+ - rubocop-rspec
3
+ # - rubocop-factory_bot
4
+ # - rubocop-rails
5
+
6
+ AllCops:
7
+ TargetRubyVersion: 3.2
8
+ NewCops: enable
9
+
10
+ Include:
11
+ - '**/*.gemspec'
12
+ - '**/*.jbuilder'
13
+ - '**/*.rake'
14
+ - '**/Gemfile'
15
+ - '**/Rakefile'
16
+ - '**/Capfile'
17
+ - '**/Guardfile'
18
+ - '**/*.rb'
19
+ Exclude:
20
+ - 'Capfile'
21
+ - 'tmp/**/*'
22
+ - 'log/**/*'
23
+ - 'db/**/*'
24
+ - 'vendor/**/*'
25
+ - 'stubs/**/*'
26
+ - 'bin/**/*'
27
+ - 'node_modules/**/*'
28
+ - 'features/step_definitions/*'
29
+ - 'app/views/**/*.jbuilder'
30
+
31
+ # Checks formatting of special comments
32
+ Style/CommentAnnotation:
33
+ Keywords:
34
+ - TODO
35
+ - FIXME
36
+ - OPTIMIZE
37
+ - HACK
38
+ - REVIEW
39
+
40
+ ########################################
41
+ # Style Cops
42
+
43
+ Style/Documentation:
44
+ Enabled: false
45
+
46
+ Style/RegexpLiteral:
47
+ Enabled: false
48
+
49
+ Style/RaiseArgs:
50
+ Enabled: false
51
+
52
+ Style/DoubleNegation:
53
+ Enabled: false
54
+
55
+ Style/SignalException:
56
+ EnforcedStyle: semantic
57
+
58
+ Style/ClassAndModuleChildren:
59
+ Enabled: false
60
+
61
+ Style/TrivialAccessors:
62
+ Enabled: false
63
+
64
+ Style/NumericLiterals:
65
+ Enabled: false
66
+
67
+ Style/EmptyMethod:
68
+ Enabled: false
69
+
70
+ Style/MixinUsage:
71
+ Enabled: false
72
+
73
+ Style/AndOr:
74
+ Enabled: false
75
+
76
+ Style/FrozenStringLiteralComment:
77
+ EnforcedStyle: always
78
+
79
+ # String#format is private now
80
+ Style/FormatString:
81
+ Enabled: false
82
+
83
+ Style/Alias:
84
+ EnforcedStyle: prefer_alias_method
85
+
86
+ ########################################
87
+ # Layout Cops
88
+
89
+ Layout/LineLength:
90
+ Max: 110
91
+ Exclude:
92
+ - 'app/views/**/*'
93
+
94
+ Layout/ClassStructure:
95
+ Enabled: true
96
+ Categories:
97
+ association:
98
+ - has_many
99
+ - has_one
100
+ attribute_macros:
101
+ - attr_accessor
102
+ - attr_reader
103
+ - attr_writer
104
+ macros:
105
+ - validates
106
+ - validate
107
+ module_inclusion:
108
+ - include
109
+ - prepend
110
+ - extend
111
+ ExpectedOrder:
112
+ - module_inclusion
113
+ - constants
114
+ - association
115
+ - public_attribute_macros
116
+ - public_delegate
117
+ - macros
118
+ - public_class_methods
119
+ - initializer
120
+ - public_methods
121
+ - protected_attribute_macros
122
+ - protected_methods
123
+ - private_attribute_macros
124
+ - private_delegate
125
+ - private_methods
126
+
127
+ Layout/ParameterAlignment:
128
+ EnforcedStyle: with_fixed_indentation
129
+
130
+ Layout/ArgumentAlignment:
131
+ EnforcedStyle: with_fixed_indentation
132
+
133
+ Layout/HashAlignment:
134
+ Enabled: false
135
+ EnforcedColonStyle: key
136
+ EnforcedHashRocketStyle: table
137
+
138
+ Layout/AssignmentIndentation:
139
+ Enabled: false
140
+
141
+ Layout/EmptyLinesAroundBlockBody:
142
+ Enabled: false
143
+
144
+ Layout/EmptyLinesAroundClassBody:
145
+ Enabled: false
146
+
147
+ Layout/MultilineMethodCallIndentation:
148
+ EnforcedStyle: indented
149
+ IndentationWidth: 4
150
+
151
+ Layout/MultilineOperationIndentation:
152
+ EnforcedStyle: indented
153
+ IndentationWidth: 4
154
+
155
+ Layout/CaseIndentation:
156
+ Enabled: false
157
+
158
+ Layout/ElseAlignment:
159
+ Enabled: false
160
+
161
+ Layout/EndAlignment:
162
+ EnforcedStyleAlignWith: variable
163
+
164
+ ########################################
165
+ # Naming Cops
166
+
167
+ Naming/FileName:
168
+ Enabled: false
169
+
170
+ ########################################
171
+ # Security Cops
172
+
173
+ Security/Eval:
174
+ Enabled: true
175
+
176
+ ########################################
177
+ # Lint Cops
178
+
179
+ Lint/AssignmentInCondition:
180
+ Enabled: false
181
+
182
+ ########################################
183
+ # Metrics Cops
184
+
185
+ # I don't care about the complexity for this simple gem
186
+ Metrics/AbcSize:
187
+ Enabled: false
188
+
189
+ Metrics/CyclomaticComplexity:
190
+ Enabled: false
191
+
192
+ Metrics/PerceivedComplexity:
193
+ Enabled: false
194
+
195
+ Metrics/MethodLength:
196
+ Enabled: false
197
+
198
+ Metrics/ClassLength:
199
+ Max: 120
200
+
201
+ Metrics/BlockLength:
202
+ Enabled: true
203
+ Exclude:
204
+ - spec/**/*
205
+ - lib/tasks/**/*.rake
206
+ - config/routes.rb
207
+ - config/environments/*.rb
208
+
209
+ ########################################
210
+ # Rspec Cops
211
+
212
+ RSpec/MultipleExpectations:
213
+ Enabled: false
214
+
215
+ RSpec/IndexedLet:
216
+ Enabled: false
217
+
218
+ RSpec/MultipleMemoizedHelpers:
219
+ Enabled: false
220
+
221
+ RSpec/ExampleLength:
222
+ Enabled: false
223
+
224
+ RSpec/ContextWording:
225
+ Enabled: false
226
+
227
+ RSpec/NestedGroups:
228
+ Enabled: false
229
+
230
+ RSpec/AnyInstance:
231
+ Enabled: false
232
+
233
+ ########################################
234
+ # Bundler Cops
235
+
236
+ Bundler/OrderedGems:
237
+ Enabled: false
238
+
239
+ ########################################
240
+ # Gemspec Cops
241
+
242
+ Gemspec/DevelopmentDependencies:
243
+ EnforcedStyle: gemspec
244
+ Include: ['**/*.gemspec']
245
+
246
+
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.1.3
data/CHANGELOG ADDED
@@ -0,0 +1,6 @@
1
+ *0.2.3* (February 20, 2024)
2
+
3
+ * Update gem for modern use
4
+ * Fix rubocop issues
5
+
6
+
@@ -0,0 +1,42 @@
1
+ # Jsonapi Rspec Code of Conduct
2
+
3
+ The Jsonapi Rspec project strongly values contributors from anywhere, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, physical appearance, body size, race, ethnicity, age, religion, or nationality. As a result, the Jsonapi Rspec team has agreed to and enforces this code of conduct in order to provide a harassment-free experience for everyone who participates in the development of Jsonapi Rspec.
4
+
5
+ ### Summary
6
+
7
+ Just Be Nice!!!
8
+
9
+ Harassment in code and discussion or violation of physical boundaries is completely unacceptable anywhere in the Jsonapi Rspec codebase, issue trackers, chat rooms, mailing lists, meetups, and any other events. Violators will be warned and then blocked or banned by the core team at or before the 3rd violation.
10
+
11
+ ### In Detail
12
+
13
+ Harassment includes offensive verbal comments related to level of experience, gender, gender identity and expression, sexual orientation, disability, physical appearance, body size, race, ethnicity, age, religion, nationality, the use of sexualized language or imagery, deliberate intimidation, stalking, sustained disruption, and unwelcome sexual attention.
14
+
15
+ Individuals asked to stop any harassing behavior are expected to comply immediately.
16
+
17
+ Maintainers, including the core team, are also subject to the anti-harassment policy.
18
+
19
+ If anyone engages in abusive, harassing, or otherwise unacceptable behavior, including maintainers, we may take appropriate action, up to and including warning the offender, deletion of comments, removal from the project’s codebase and communication systems, and escalation to GitHub support.
20
+
21
+ If you are being harassed, notice that someone else is being harassed, or have any other concerns, please contact [Chris Blackburn](mailto:87a1779b@opayq.com).
22
+
23
+ We expect everyone to follow these rules anywhere in the Jsonapi Rspec codebase, issue trackers, IRC channel, group chat, and mailing lists.
24
+
25
+ This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
26
+
27
+ Finally, don't forget that it is human to make mistakes! We all do. Let’s work together to help each other, resolve issues, and learn from the mistakes that we will all inevitably make from time to time.
28
+
29
+ ### Thanks
30
+
31
+ Thanks to the [JSConf Code of Conduct](http://jsconf.com/codeofconduct.html) and [Fedora Code of Conduct](http://fedoraproject.org/code-of-conduct) for inspiration and ideas.
32
+
33
+ ### License
34
+
35
+ <p class="license" xmlns:dct="http://purl.org/dc/terms/" xmlns:vcard="http://www.w3.org/2001/vcard-rdf/3.0#">
36
+ To the extent possible under law, <a rel="dct:publisher" href="https://github.com/midwire/jsonapi_rspec">The Jsonapi Rspec Team</a> has waived all copyright and related or neighboring rights to the <span property="dct:title">Jsonapi Rspec Code of Conduct</span>. This work is published from the <span property="vcard:Country" datatype="dct:ISO3166" content="US" about="https://github.com/midwire/jsonapi_rspec">United States.</span>
37
+ <br>
38
+ <br>
39
+ <a rel="license" href="http://creativecommons.org/publicdomain/zero/1.0/">
40
+ <img src="http://i.creativecommons.org/p/zero/1.0/88x31.png" style="border-style: none;" alt="CC0">
41
+ </a>
42
+ </p>
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,25 @@
1
+ ## How to contribute to jsonapi_rspec
2
+
3
+ #### **Did you find a bug?**
4
+
5
+ * **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/midwire/jsonapi_rspec/issues).
6
+
7
+ * If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/midwire/jsonapi_rspec/issues/new). Be sure to include a **title and clear description**, as much relevant information as possible, and a **code sample** or an **executable test case** demonstrating the expected behavior that is not occurring.
8
+
9
+ #### **Did you write a patch that fixes a bug?**
10
+
11
+ * Open a new GitHub pull request with the patch.
12
+
13
+ * Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable.
14
+
15
+ * Before submitting, please read run [Rubocop](http://batsov.com/rubocop/) on your code. If your PR fails our Rubocop convensions defined in `.rubocop.yml`, it will likely be rejected on those grounds.
16
+
17
+ * Ensure that you write RSpec tests that cover any new or modified code. PR's without spec coverage will likely be rejected.
18
+
19
+ #### **Did you fix whitespace, format code, or make a purely cosmetic patch?**
20
+
21
+ Changes that are cosmetic in nature and do not add anything substantial to the stability, functionality, or testability of Jsonapi Rspec will generally not be accepted.
22
+
23
+ Thanks for any contributions!
24
+
25
+ --Midwire
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
data/ISSUE_TEMPLATE.md ADDED
@@ -0,0 +1,9 @@
1
+ ### Expected Behavior
2
+
3
+ ### Actual Behavior
4
+
5
+ ### Steps to reproduce the problem
6
+
7
+ ---
8
+ * Current Version:
9
+ * Operating System:
@@ -1,6 +1,6 @@
1
- The MIT License (MIT)
1
+ ## The MIT License (MIT)
2
2
 
3
- Copyright (c) 2017 Chris Blackburn
3
+ ##### Copyright (c) 2017 Midwire Technologies, LLC
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -12,10 +12,10 @@ furnished to do so, subject to the following conditions:
12
12
  The above copyright notice and this permission notice shall be included in
13
13
  all copies or substantial portions of the Software.
14
14
 
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ **_THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
16
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
17
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
18
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
21
+ THE SOFTWARE._**
@@ -0,0 +1,5 @@
1
+ - [ ] I wrote specs to cover new or modified code in this PR
2
+ - [ ] I ran `rake spec` locally and ALL specs pass
3
+
4
+ Related Issue: # <please-add-issue-number-here>
5
+ Description: <please-add-a-comprehensive-description-of-fix/feature>
data/README.md CHANGED
@@ -28,19 +28,36 @@ And then execute:
28
28
  In your controller specs:
29
29
 
30
30
  ```ruby
31
- my_model = MyModel.create(...)
32
- get :show, params: { id: my_model.id }
33
- expect(response).to be_jsonapi_response_for(my_model)
31
+ describe 'GET index' do
32
+ before do
33
+ get :index
34
+ end
35
+
36
+ it 'returns a json:api response' do
37
+ expect(response).to be_jsonapi_response
38
+ end
39
+ end
40
+ ```
41
+
42
+ ```ruby
43
+ describe 'POST create' do
44
+ context 'with valid content data' do
45
+ it 'responds with valid json' do
46
+ post :create, params: valid_params
47
+ expect(response).to be_jsonapi_response_for(Content.last)
48
+ end
49
+ end
50
+ end
34
51
  ```
35
52
 
36
- It currently tests for required json:api sections and matching attributes for the passed model instance.
53
+ It currently tests for compliant json:api sections and matching attributes for the passed model instance.
37
54
  ```
38
55
  {
39
- "jsonapi": "version 1.1", // does not check
40
- "data":{ // checks if exists and is a hash
41
- "id":"123", // checks if this matches the object.id
42
- "type":"tags", // checks if exists and is the matching type for object
43
- "attributes":{ // checks each attrib. against object attributes
56
+ "jsonapi": "version 1.1", // does not check
57
+ "data":{ // checks if exists and is a hash
58
+ "id":"123", // checks if this matches the object.id
59
+ "type":"tags", // checks if exists and is the matching type for object
60
+ "attributes":{ // checks each attr. against object attributes
44
61
  "string_attribute":"Category",
45
62
  "datetime_attribute":"2017-10-13T19:33:54+00:00",
46
63
  "time_attribute":"2017-10-14 17:12:45 -0500",
@@ -50,12 +67,12 @@ It currently tests for required json:api sections and matching attributes for th
50
67
  "fixnum_attribute":11,
51
68
  "float_attribute":11.11,
52
69
  "bignum_attribute":9999999999999999999999999999999,
53
- "links":{ // does not check
70
+ "links":{ // does not check
54
71
  "self":"http://test.host/api/v1/tag_types.123"
55
72
  }
56
73
  }
57
74
  },
58
- "included": [{ // does not check
75
+ "included": [{ // does not check
59
76
  "type": "users",
60
77
  "id": 9,
61
78
  "attributes": {
@@ -67,26 +84,30 @@ It currently tests for required json:api sections and matching attributes for th
67
84
  "self": "http://example.com/users/9"
68
85
  }
69
86
  }],
70
- "meta":{ // does not check for existance by default
71
- "copyright":"Copyright 2017 Chris Blackburn", // required if meta tag exists
72
- "version":"v1" // required if meta tag exists
87
+ "meta":{ // checks are configurable
88
+ "copyright":"Copyright 2017 Chris Blackburn",
89
+ "version":"v1"
73
90
  }
74
91
  }
75
92
  ```
76
93
 
94
+ ### Checks
95
+
96
+ * Empty response - `response.empty?`
97
+ * Nil response - `response.nil?`
98
+ * Error response - catches if the response is an error when expecting a matching object response.
99
+ * Missing a required top level section - must include 'data', 'errors' or 'meta'
100
+ * Conflicting top level section - 'included' is invalid without a 'data' section
101
+ * Unexpected top level key - catches invalid top level keys
102
+ * Invalid data section - 'data' section must be an Array (collection) or Hash (single-object)
103
+ * Data type mismatch - 'data:type' doesn't match the object type
104
+ * Object ID mismatch - 'data:id' doesn't match the object ID
105
+ * Missing meta - if configured (see Configuration below) reports missing 'meta' section
106
+ * Validates data attributes - checks for matching data attributes including their variable types. For example if an Integer is expected, a String fails.
107
+
77
108
  ### Possible Failure Messages
78
109
 
79
- * "Attribute: :#{attr_name} with a value of '#{json_val}'(#{json_val.class.name}) does not match object: '#{obj_val}'(#{obj_val.class.name})
80
- * "Expected '#{value}' to match object id: '#{object_id}'"
81
- * "Expected data:type '#{data_type}' to match: '#{object_type}'"
82
- * "Fix 'match_attribute?' method to handle: '#{obj_val_class_name}'" - [please file an issue](https://github.com/midwire/jsonapi_rspec/issues/new) if you get this one.
83
- * "The 'data' section is missing or invalid"
84
- * "The 'meta' section is missing or invalid"
85
- * "The 'meta:copyright' is missing or invalid - regex: '/^Copyright.+\\d{4}/'"
86
- * "The 'meta:version' is missing"
87
- * "Unexpected key in response: '#{key}'"
88
- * 'Expected response to match an object instance but it is an empty string'
89
- * 'Response is an error'
110
+ [See failure_messages.rb](https://github.com/midwire/jsonapi_rspec/blob/develop/lib/jsonapi_rspec/failure_messages.rb).
90
111
 
91
112
  [See the specs](https://github.com/midwire/jsonapi_rspec/blob/develop/spec/lib/jsonapi_rspec/be_json_api_response_for_spec.rb) for more details.
92
113
 
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
4
 
3
5
  require 'rspec/core/rake_task'
data/SUPPORT.md ADDED
@@ -0,0 +1,6 @@
1
+ # Jsonapi Rspec Support
2
+
3
+ As noted in our [license](LICENSE.md), jsonapi_rspec is provided "as is", without any kind of warranty.
4
+
5
+ Having said that, we desire to support jsonapi_rspec as well as possible given current and ongoing professional commitments. If you experience any kind of bug or issue that is blocking your workflow, please [file an Issue](https://github.com/midwire/jsonapi_rspec/issues/new) on GitHub.
6
+
@@ -1,5 +1,6 @@
1
+ # frozen_string_literal: true
1
2
 
2
- lib = File.expand_path('../lib', __FILE__)
3
+ lib = File.expand_path('lib', __dir__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'jsonapi_rspec/version'
5
6
 
@@ -7,27 +8,30 @@ Gem::Specification.new do |spec|
7
8
  spec.name = 'jsonapi_rspec'
8
9
  spec.version = JsonapiRspec::VERSION
9
10
  spec.authors = ['Chris Blackburn']
10
- spec.email = ['chris@midwiretech.com']
11
+ spec.email = ['bogus@example.com']
11
12
 
12
13
  spec.summary = 'Provides RSpec matchers for json:api related specs'
13
14
  spec.description = spec.summary
14
15
  spec.homepage = 'https://github.com/midwire/jsonapi_rspec'
15
16
  spec.license = 'MIT'
16
17
 
17
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
- f.match(%r{^(test|spec|features)/})
18
+ spec.required_ruby_version = Gem::Requirement.new(">= #{Bundler.root.join('.ruby-version').read.strip}")
19
+ spec.metadata['rubygems_mfa_required'] = 'true'
20
+
21
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
22
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
19
23
  end
20
24
  spec.bindir = 'exe'
21
25
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
26
  spec.require_paths = ['lib']
23
27
 
24
- spec.add_development_dependency 'bundler', '~> 1.15.4'
25
- spec.add_development_dependency 'rake', '~> 10.0'
26
- spec.add_development_dependency 'rspec', '~> 3.0'
27
- spec.add_development_dependency 'pry-nav', '~> 0.2.4'
28
+ spec.add_development_dependency 'bundler'
29
+ spec.add_development_dependency 'midwire_common'
30
+ spec.add_development_dependency 'pry'
28
31
  spec.add_development_dependency 'rack'
32
+ spec.add_development_dependency 'rake'
33
+ spec.add_development_dependency 'rspec'
29
34
  spec.add_development_dependency 'simplecov'
30
- spec.add_development_dependency 'midwire_common', '~> 0.1'
31
35
 
32
36
  spec.add_dependency 'activesupport', '>= 4.2.8'
33
37
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rspec/matchers'
2
4
 
3
5
  require_relative 'string'
@@ -24,9 +26,7 @@ class BeJsonApiResponse
24
26
  return false unless required_top_level_sections?
25
27
  return false if conflicting_sections?
26
28
 
27
- if JsonapiRspec.configuration.meta_required
28
- return false unless valid_meta_section?
29
- end
29
+ return false if JsonapiRspec.configuration.meta_required && !valid_meta_section?
30
30
 
31
31
  @parsed_response.each_key do |key|
32
32
  case key.to_sym
@@ -41,7 +41,7 @@ class BeJsonApiResponse
41
41
  when :links
42
42
  next # TODO: handle links objects
43
43
  else
44
- return set_failure_message(FailureMessages::UNEXPECTED_TOP_LVL_KEY % key)
44
+ return failure_message(FailureMessages::UNEXPECTED_TOP_LVL_KEY % key)
45
45
  end
46
46
  end
47
47
 
@@ -56,7 +56,7 @@ class BeJsonApiResponse
56
56
  #
57
57
  # @return [Boolean] always returns false
58
58
  #
59
- def set_failure_message(msg)
59
+ def failure_message(msg)
60
60
  @failure_message = "#{FailureMessages::GENERAL_PREFIX} #{msg}"
61
61
  false
62
62
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rspec/matchers'
2
4
  require 'active_support/all'
3
5
 
@@ -18,11 +20,27 @@ require_relative 'string'
18
20
  class BeJsonApiResponseFor
19
21
  include JsonapiRspec
20
22
 
23
+ # Initialize an instance of the BeJsonApiResponseFor class
24
+ #
25
+ # @param [Object] object_instance Any instantiated object that responds to the
26
+ # attribute-related method calls passed in by the json:api
27
+ # @param [String] plural_form Sometimes the ActiveSupport::Inflector has
28
+ # problems with pluralizing certain strings. This allows setting of the
29
+ # plural form directly. It should be the lowercase, dasherized plural form of the
30
+ # passed object_instance.
31
+ #
21
32
  def initialize(object_instance, plural_form = nil)
22
33
  @object_instance = object_instance
23
34
  @plural_form = plural_form
24
35
  end
25
36
 
37
+ # Gets called by RSpec or by the camel_cased syntactical method below.
38
+ #
39
+ # @param [Rack::Response] response A type of Rack::Response or any object that
40
+ # responds to the :body method.
41
+ #
42
+ # @return [Boolean] true if it matches, false if not
43
+ #
26
44
  def matches?(response)
27
45
  return false unless valid_response?(response)
28
46
 
@@ -30,9 +48,8 @@ class BeJsonApiResponseFor
30
48
 
31
49
  return false if response_is_error?
32
50
  return false unless valid_data_section?
33
- if JsonapiRspec.configuration.meta_required
34
- return false unless valid_meta_section?
35
- end
51
+
52
+ return false if JsonapiRspec.configuration.meta_required && !valid_meta_section?
36
53
 
37
54
  @parsed_response.each do |key, value|
38
55
  case key.to_sym
@@ -47,7 +64,7 @@ class BeJsonApiResponseFor
47
64
  when :links
48
65
  next # TODO: handle links objects
49
66
  else
50
- return set_failure_message(FailureMessages::UNEXPECTED_TOP_LVL_KEY % key)
67
+ return failure_message(FailureMessages::UNEXPECTED_TOP_LVL_KEY % key)
51
68
  end
52
69
  end
53
70
 
@@ -62,39 +79,54 @@ class BeJsonApiResponseFor
62
79
  #
63
80
  # @return [Boolean] always returns false
64
81
  #
65
- def set_failure_message(msg)
82
+ def failure_message(msg)
66
83
  @failure_message = "#{FailureMessages::OBJECT_PREFIX} #{msg}"
67
84
  false
68
85
  end
69
86
 
87
+ # Check the json:api data:type against the plural form of the passed
88
+ # object instance.
89
+ #
90
+ # @param [String] data_type The json:api data:type.
91
+ #
92
+ # @return [Boolean] True if matches, false if not
93
+ #
70
94
  def valid_type?(data_type)
71
95
  object_type = @plural_form ||
72
- @object_instance.class.name.pluralize.underscore.dasherize
96
+ @object_instance.class.name.pluralize.underscore.dasherize
73
97
  unless data_type == object_type
74
- return set_failure_message(
98
+ return failure_message(
75
99
  format(FailureMessages::DATA_TYPE_MISMATCH, data_type, object_type)
76
100
  )
77
101
  end
78
102
  true
79
103
  end
80
104
 
105
+ # Match an object's attribute value to the json:api value
106
+ #
107
+ # @param [String] attr_name A String or Symbol of the object's attribute
108
+ # @param [String] json_val Typically a String but could be any value type
109
+ # that is legal JSON
110
+ #
111
+ # @return [Boolean] true if the values match, false if not
112
+ #
81
113
  def match_attribute?(attr_name, json_val)
82
114
  obj_val = @object_instance.send(attr_name.to_sym)
83
115
  obj_val_class_name = obj_val.class.name
84
116
 
85
- case obj_val_class_name
117
+ matched = case obj_val_class_name
86
118
  when 'Float'
87
- matched = obj_val == json_val.to_f
119
+ obj_val == json_val.to_f
88
120
  when 'DateTime'
89
- matched = obj_val.to_i == DateTime.parse(json_val).to_i
121
+ obj_val.to_i == DateTime.parse(json_val).to_i
90
122
  when 'Time'
91
- matched = obj_val.to_i == Time.parse(json_val).to_i
123
+ obj_val.to_i == Time.parse(json_val).to_i
92
124
  else
93
- matched = obj_val == json_val
125
+ obj_val == json_val
94
126
  end
95
127
 
96
128
  unless matched
97
- return set_failure_message(
129
+ return failure_message(
98
130
  <<-STRING.here_with_pipe!(' ')
99
131
  |Attribute: :#{attr_name}
100
132
  |with a value of '#{json_val}'(#{json_val.class.name})
@@ -105,13 +137,19 @@ class BeJsonApiResponseFor
105
137
  true
106
138
  end
107
139
 
140
+ # Match the jsonapi values to the object instance.
141
+ #
142
+ # @param [Hash] values A Ruby Hash of parsed jsonapi values
143
+ #
144
+ # @return [Boolean] True if match, false if not.
145
+ #
108
146
  def match_object?(values)
109
147
  values.each do |key, value|
110
148
  case key.to_sym
111
149
  when :id
112
150
  object_id = @object_instance.send(key)
113
151
  unless object_id == value.to_i
114
- return set_failure_message(
152
+ return failure_message(
115
153
  format(FailureMessages::OBJECT_ID_MISMATCH, value, object_id)
116
154
  )
117
155
  end
@@ -134,6 +172,8 @@ class BeJsonApiResponseFor
134
172
  end
135
173
  end
136
174
 
175
+ # This is the syntactic sugar matcher method.
176
+ #
137
177
  # Usage:
138
178
  # expect(response).to be_jsonapi_response_for(object_instance)
139
179
  #
@@ -1,9 +1,16 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module JsonapiRspec
4
+ # Class Configuration provides a config object for certain options
5
+ #
6
+ # @author Chris Blackburn <87a1779b@opayq.com>
7
+ #
2
8
  class Configuration
3
- attr_accessor :meta_required
9
+ attr_accessor :meta_required, :required_meta_sections
4
10
 
5
11
  def initialize
6
12
  @meta_required = false
13
+ @required_meta_sections = [] # :copyright, :version, etc.
7
14
  end
8
15
  end
9
16
  end
@@ -1,16 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Module FailureMessages provides a list of defined failure messages.
4
+ #
5
+ # @author Chris Blackburn <87a1779b@opayq.com>
6
+ #
1
7
  module FailureMessages
2
- GENERAL_PREFIX = 'Expected a json:api compliant success response but'.freeze
3
- OBJECT_PREFIX = 'Expected a json:api response for an object instance but'.freeze
8
+ GENERAL_PREFIX = 'Expected a json:api compliant success response but'
9
+ OBJECT_PREFIX = 'Expected a json:api response for an object instance but'
4
10
 
5
- ERROR = 'it is an error'.freeze
6
- EMPTY = 'it is empty'.freeze
7
- NIL = 'it is nil'.freeze
11
+ ERROR = 'it is an error'
12
+ EMPTY = 'it is empty'
13
+ NIL = 'it is nil'
8
14
 
9
- MISSING_REQ_TOP_LVL = 'it is missing a required top-level section'.freeze
10
- CONFLICTING_TOP_LVL = "it cannot contain 'included' without a 'data' section".freeze
11
- UNEXPECTED_TOP_LVL_KEY = "it has an unexpected key: '%s'".freeze
12
- INVALID_DATA_SECTION = "the 'data' section must be a Hash or an Array".freeze
13
- DATA_TYPE_MISMATCH = "data:type '%s' doesn't match: '%s'".freeze
14
- OBJECT_ID_MISMATCH = "data:id '%s' doesn't match object id: '%s'".freeze
15
- MISSING_META = "the 'meta' section is missing or invalid".freeze
15
+ MISSING_REQ_TOP_LVL = 'it is missing a required top-level section'
16
+ CONFLICTING_TOP_LVL = "it cannot contain 'included' without a 'data' section"
17
+ UNEXPECTED_TOP_LVL_KEY = "it has an unexpected key: '%s'"
18
+ INVALID_DATA_SECTION = "the 'data' section must be a Hash or an Array"
19
+ DATA_TYPE_MISMATCH = "data:type '%s' doesn't match: '%s'"
20
+ OBJECT_ID_MISMATCH = "data:id '%s' doesn't match object id: '%s'"
21
+ MISSING_META = "the 'meta' section is missing or invalid"
16
22
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class String
2
4
  # Helper for the heredoc functionality. Allows pipe '|' delimeted heredocs
3
5
  # with a parameterized delimeter.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module JsonapiRspec
2
- VERSION = '0.2.2'.freeze
4
+ VERSION = '0.2.3'.freeze
3
5
  end
data/lib/jsonapi_rspec.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'jsonapi_rspec/version'
2
4
  require 'jsonapi_rspec/failure_messages'
3
5
  require 'jsonapi_rspec/be_json_api_response'
@@ -17,6 +19,10 @@ module JsonapiRspec
17
19
  end
18
20
  end
19
21
 
22
+ # Called by RSpec when an the json:api response doesn't match the object instance
23
+ #
24
+ # @return [String] The failure message to display in the RSpec output
25
+ #
20
26
  def failure_message
21
27
  "#{@failure_message} - parsed response: #{pretty_response}"
22
28
  end
@@ -28,54 +34,84 @@ module JsonapiRspec
28
34
 
29
35
  private
30
36
 
37
+ # Generate a nicely formatted version of the json:api response for output
38
+ #
39
+ # @return [String] Formatted JSON
40
+ #
31
41
  def pretty_response
32
42
  JSON.pretty_generate(@parsed_response)
33
43
  rescue JSON::GeneratorError
34
44
  @parsed_response.to_s
35
45
  end
36
46
 
47
+ # Determine if the passed response is empty or nil.
48
+ #
49
+ # @param [Rack::Response] response Any object that responds to the :body method
50
+ #
51
+ # @return [Boolean] True if valid, false if not
52
+ #
37
53
  def valid_response?(response)
38
54
  return set_failure_message(FailureMessages::EMPTY) if response.body == ''
39
55
  return set_failure_message(FailureMessages::NIL) if response.body.nil?
56
+
40
57
  true
41
58
  end
42
59
 
60
+ # Determine if the json:api response contains the required top-level sections.
61
+ #
62
+ # @return [Boolean] True if the required sections exist, false if not
63
+ #
43
64
  def required_top_level_sections?
44
- valid = @parsed_response.dig('data') || @parsed_response.dig('errors') || @parsed_response.dig('meta')
65
+ valid = @parsed_response['data'] || @parsed_response['errors'] || @parsed_response['meta']
45
66
  return set_failure_message(FailureMessages::MISSING_REQ_TOP_LVL) unless valid
67
+
46
68
  true
47
69
  end
48
70
 
71
+ # Determine if the json:api response contains conflicting top-level sections
72
+ #
73
+ # @return [Boolean] True if the response has an 'included' section but no 'data', false if not
74
+ #
49
75
  def conflicting_sections?
50
76
  conflicting = false
51
- if @parsed_response.dig('included')
52
- # must have a data section
53
- if @parsed_response.dig('data').nil?
54
- conflicting = true
55
- set_failure_message(FailureMessages::CONFLICTING_TOP_LVL)
56
- end
77
+ # must have a data section
78
+ if @parsed_response['included'] && @parsed_response['data'].nil?
79
+ conflicting = true
80
+ set_failure_message(FailureMessages::CONFLICTING_TOP_LVL)
57
81
  end
58
82
  conflicting
59
83
  end
60
84
 
85
+ # Check the json:api response for a 'meta' section. This is configurable.
86
+ #
87
+ # @return [Boolean] True if the meta section exists and is a Hash, false if not
88
+ #
61
89
  def valid_meta_section?
62
- meta = @parsed_response.dig('meta')
90
+ meta = @parsed_response['meta']
63
91
  return set_failure_message(FailureMessages::MISSING_META) unless meta.is_a?(Hash)
92
+
64
93
  true
65
94
  end
66
95
 
96
+ # Determine if the json:api response is an error response.
97
+ #
98
+ # @return [Boolean] True if the response is an error response, false if not
99
+ #
67
100
  def response_is_error?
68
- is_error = !@parsed_response.dig('errors').nil?
101
+ is_error = !@parsed_response['errors'].nil?
69
102
  set_failure_message(FailureMessages::ERROR) if is_error
70
103
  is_error
71
104
  end
72
105
 
106
+ # Determine if the json:api response contains a valid 'data' section.
107
+ #
108
+ # @return [Boolean] True if the section exists and is value, false if not.
109
+ #
73
110
  def valid_data_section?
74
- data_section = @parsed_response.dig('data')
111
+ data_section = @parsed_response['data']
75
112
  valid = data_section.is_a?(Hash) || data_section.is_a?(Array)
76
- unless valid
77
- return set_failure_message(FailureMessages::INVALID_DATA_SECTION)
78
- end
113
+ return set_failure_message(FailureMessages::INVALID_DATA_SECTION) unless valid
114
+
79
115
  true
80
116
  end
81
117
 
metadata CHANGED
@@ -1,73 +1,73 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsonapi_rspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Blackburn
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-10-20 00:00:00.000000000 Z
11
+ date: 2024-02-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 1.15.4
19
+ version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 1.15.4
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: midwire_common
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rspec
42
+ name: pry
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '3.0'
47
+ version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '3.0'
54
+ version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: pry-nav
56
+ name: rack
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: 0.2.4
61
+ version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: 0.2.4
68
+ version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: rack
70
+ name: rake
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -81,7 +81,7 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: simplecov
84
+ name: rspec
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
@@ -95,19 +95,19 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: midwire_common
98
+ name: simplecov
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - "~>"
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
- version: '0.1'
103
+ version: '0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - "~>"
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
- version: '0.1'
110
+ version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: activesupport
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -124,19 +124,26 @@ dependencies:
124
124
  version: 4.2.8
125
125
  description: Provides RSpec matchers for json:api related specs
126
126
  email:
127
- - chris@midwiretech.com
127
+ - bogus@example.com
128
128
  executables: []
129
129
  extensions: []
130
130
  extra_rdoc_files: []
131
131
  files:
132
132
  - ".gitignore"
133
133
  - ".rspec"
134
+ - ".rubocop.yml"
135
+ - ".ruby-version"
134
136
  - ".travis.yml"
137
+ - CHANGELOG
138
+ - CODE_OF_CONDUCT.md
139
+ - CONTRIBUTING.md
135
140
  - Gemfile
136
- - Gemfile.lock
137
- - LICENSE.txt
141
+ - ISSUE_TEMPLATE.md
142
+ - LICENSE.md
143
+ - PULL_REQUEST_TEMPLATE.md
138
144
  - README.md
139
145
  - Rakefile
146
+ - SUPPORT.md
140
147
  - bin/console
141
148
  - bin/setup
142
149
  - jsonapi_rspec.gemspec
@@ -150,7 +157,8 @@ files:
150
157
  homepage: https://github.com/midwire/jsonapi_rspec
151
158
  licenses:
152
159
  - MIT
153
- metadata: {}
160
+ metadata:
161
+ rubygems_mfa_required: 'true'
154
162
  post_install_message:
155
163
  rdoc_options: []
156
164
  require_paths:
@@ -159,15 +167,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
159
167
  requirements:
160
168
  - - ">="
161
169
  - !ruby/object:Gem::Version
162
- version: '0'
170
+ version: 3.1.3
163
171
  required_rubygems_version: !ruby/object:Gem::Requirement
164
172
  requirements:
165
173
  - - ">="
166
174
  - !ruby/object:Gem::Version
167
175
  version: '0'
168
176
  requirements: []
169
- rubyforge_project:
170
- rubygems_version: 2.5.1
177
+ rubygems_version: 3.3.26
171
178
  signing_key:
172
179
  specification_version: 4
173
180
  summary: Provides RSpec matchers for json:api related specs
data/Gemfile.lock DELETED
@@ -1,71 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- jsonapi_rspec (0.2.2)
5
- activesupport (>= 4.2.8)
6
-
7
- GEM
8
- remote: https://rubygems.org/
9
- specs:
10
- activesupport (5.1.4)
11
- concurrent-ruby (~> 1.0, >= 1.0.2)
12
- i18n (~> 0.7)
13
- minitest (~> 5.1)
14
- tzinfo (~> 1.1)
15
- coderay (1.1.2)
16
- concurrent-ruby (1.0.5)
17
- diff-lcs (1.3)
18
- docile (1.1.5)
19
- i18n (0.8.6)
20
- json (2.1.0)
21
- method_source (0.8.2)
22
- midwire_common (0.3.0)
23
- thor (~> 0.19)
24
- minitest (5.10.3)
25
- pry (0.10.4)
26
- coderay (~> 1.1.0)
27
- method_source (~> 0.8.1)
28
- slop (~> 3.4)
29
- pry-nav (0.2.4)
30
- pry (>= 0.9.10, < 0.11.0)
31
- rack (2.0.3)
32
- rake (10.5.0)
33
- rspec (3.6.0)
34
- rspec-core (~> 3.6.0)
35
- rspec-expectations (~> 3.6.0)
36
- rspec-mocks (~> 3.6.0)
37
- rspec-core (3.6.0)
38
- rspec-support (~> 3.6.0)
39
- rspec-expectations (3.6.0)
40
- diff-lcs (>= 1.2.0, < 2.0)
41
- rspec-support (~> 3.6.0)
42
- rspec-mocks (3.6.0)
43
- diff-lcs (>= 1.2.0, < 2.0)
44
- rspec-support (~> 3.6.0)
45
- rspec-support (3.6.0)
46
- simplecov (0.15.1)
47
- docile (~> 1.1.0)
48
- json (>= 1.8, < 3)
49
- simplecov-html (~> 0.10.0)
50
- simplecov-html (0.10.2)
51
- slop (3.6.0)
52
- thor (0.20.0)
53
- thread_safe (0.3.6)
54
- tzinfo (1.2.3)
55
- thread_safe (~> 0.1)
56
-
57
- PLATFORMS
58
- ruby
59
-
60
- DEPENDENCIES
61
- bundler (~> 1.15.4)
62
- jsonapi_rspec!
63
- midwire_common (~> 0.1)
64
- pry-nav (~> 0.2.4)
65
- rack
66
- rake (~> 10.0)
67
- rspec (~> 3.0)
68
- simplecov
69
-
70
- BUNDLED WITH
71
- 1.16.0.pre.3