Skip to content

Allow jsonapi-rspec to match Symbol or String based source documents #18

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--require ./spec/spec_helper.rb
44 changes: 44 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
Metrics/BlockLength:
Exclude:
- 'spec/**/*_spec.rb'

require:
- rubocop-performance

Expand All @@ -6,3 +10,43 @@ Style/FrozenStringLiteralComment:

Style/Documentation:
Enabled: false

Layout/EmptyLinesAroundAttributeAccessor:
Enabled: true

Layout/SpaceAroundMethodCallOperator:
Enabled: true

Lint/DeprecatedOpenSSLConstant:
Enabled: true

Lint/MixedRegexpCaptureTypes:
Enabled: true

Lint/RaiseException:
Enabled: true

Lint/StructNewOverride:
Enabled: true

Style/ExponentialNotation:
Enabled: true

Style/HashEachMethods:
Enabled: true

Style/HashTransformKeys:
Enabled: true

Style/HashTransformValues:
Enabled: true

Style/RedundantRegexpCharacterClass:
Enabled: true

Style/RedundantRegexpEscape:
Enabled: true

Style/SlicingWithRange:
Enabled: true

11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,17 @@ Available matchers:
* `expect(document).to have_jsonapi_object`
* `expect(document).to have_jsonapi_object('version' => '1.0')`

### Indifferent Matching
```ruby
# spec/spec_helpers.rb

RSpec.configure do |config|
# ...
config.allow_symbolized_jsonapi = true
end
```
The configuration above allows the RSpec matchers to work with a symbolized jsonapi source document.

## Advanced examples

Checking for an included resource:
Expand Down
11 changes: 11 additions & 0 deletions lib/jsonapi/rspec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
require 'jsonapi/rspec/meta'
require 'jsonapi/rspec/jsonapi_object'

RSpec.configure do |c|
c.add_setting :allow_symbolized_jsonapi, default: false
end

module JSONAPI
module RSpec
include Id
Expand All @@ -16,5 +20,12 @@ module RSpec
include Links
include Meta
include JsonapiObject

def self.as_indifferent_hash(doc)
return doc unless ::RSpec.configuration.allow_symbolized_jsonapi
return doc.with_indifferent_access if doc.respond_to?(:with_indifferent_access)

JSON.parse(JSON.generate(doc))
end
end
end
2 changes: 2 additions & 0 deletions lib/jsonapi/rspec/attributes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module RSpec
module Attributes
::RSpec::Matchers.define :have_attribute do |attr|
match do |actual|
actual = JSONAPI::RSpec.as_indifferent_hash(actual)
(actual['attributes'] || {}).key?(attr.to_s) &&
(!@val_set || actual['attributes'][attr.to_s] == @val)
end
Expand All @@ -15,6 +16,7 @@ module Attributes

::RSpec::Matchers.define :have_jsonapi_attributes do |*attrs|
match do |actual|
actual = JSONAPI::RSpec.as_indifferent_hash(actual)
return false unless actual.key?('attributes')

counted = (attrs.size == actual['attributes'].size) if @exactly
Expand Down
4 changes: 3 additions & 1 deletion lib/jsonapi/rspec/id.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ module JSONAPI
module RSpec
module Id
::RSpec::Matchers.define :have_id do |expected|
match { |actual| actual['id'] == expected }
match do |actual|
JSONAPI::RSpec.as_indifferent_hash(actual)['id'] == expected
end
end
end
end
Expand Down
1 change: 1 addition & 0 deletions lib/jsonapi/rspec/jsonapi_object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module RSpec
module JsonapiObject
::RSpec::Matchers.define :have_jsonapi_object do |val|
match do |actual|
actual = JSONAPI::RSpec.as_indifferent_hash(actual)
actual.key?('jsonapi') &&
(!val || actual['jsonapi'] == val)
end
Expand Down
2 changes: 2 additions & 0 deletions lib/jsonapi/rspec/links.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module RSpec
module Links
::RSpec::Matchers.define :have_link do |link|
match do |actual|
actual = JSONAPI::RSpec.as_indifferent_hash(actual)
actual.key?('links') && actual['links'].key?(link.to_s) &&
(!@val_set || actual['links'][link.to_s] == @val)
end
Expand All @@ -15,6 +16,7 @@ module Links

::RSpec::Matchers.define :have_links do |*links|
match do |actual|
actual = JSONAPI::RSpec.as_indifferent_hash(actual)
return false unless actual.key?('links')

links.all? { |link| actual['links'].key?(link.to_s) }
Expand Down
1 change: 1 addition & 0 deletions lib/jsonapi/rspec/meta.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module RSpec
module Meta
::RSpec::Matchers.define :have_meta do |val|
match do |actual|
actual = JSONAPI::RSpec.as_indifferent_hash(actual)
actual.key?('meta') &&
(!val || actual['meta'] == val)
end
Expand Down
2 changes: 2 additions & 0 deletions lib/jsonapi/rspec/relationships.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module RSpec
module Relationships
::RSpec::Matchers.define :have_relationship do |rel|
match do |actual|
actual = JSONAPI::RSpec.as_indifferent_hash(actual)
return false unless (actual['relationships'] || {}).key?(rel.to_s)

!@data_set || actual['relationships'][rel.to_s]['data'] == @data_val
Expand All @@ -25,6 +26,7 @@ module Relationships

::RSpec::Matchers.define :have_relationships do |*rels|
match do |actual|
actual = JSONAPI::RSpec.as_indifferent_hash(actual)
return false unless actual.key?('relationships')

rels.all? { |rel| actual['relationships'].key?(rel) }
Expand Down
4 changes: 3 additions & 1 deletion lib/jsonapi/rspec/type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ module JSONAPI
module RSpec
module Type
::RSpec::Matchers.define :have_type do |expected|
match { |actual| actual['type'] == expected }
match do |actual|
JSONAPI::RSpec.as_indifferent_hash(actual)['type'] == expected
end
end
end
end
Expand Down
29 changes: 19 additions & 10 deletions spec/jsonapi/attributes_spec.rb
Original file line number Diff line number Diff line change
@@ -1,25 +1,34 @@
require 'spec_helper'

RSpec.describe JSONAPI::RSpec do
let(:doc) do
json_doc =
{
'attributes' => {
'one' => 1,
'two' => 2,
'four' => 3
}
}
end

describe '#have_attribute' do
it { expect(doc).to have_attribute(:one) }
it { expect(doc).not_to have_attribute(:five) }
context 'when attributes is present' do
it { expect(json_doc).to have_attribute(:one) }
it { expect(json_doc).not_to have_attribute(:five) }
end

context 'when attributes is not present' do
it { expect({}).not_to have_attribute(:one) }
end
end

describe '#have_jsonapi_attributes' do
it { expect(doc).to have_jsonapi_attributes(:one, :two) }
it { expect(doc).not_to have_jsonapi_attributes(:two, :five) }
it { expect(doc).to have_jsonapi_attributes(:one, :two, :four).exactly }
it { expect(doc).not_to have_jsonapi_attributes(:one).exactly }
context 'when attributes is present' do
it { expect(json_doc).to have_jsonapi_attributes(:one, 'two') }
it { expect(json_doc).not_to have_jsonapi_attributes(:two, 'five') }
it { expect(json_doc).to have_jsonapi_attributes(:one, :two, 'four').exactly }
it { expect(json_doc).not_to have_jsonapi_attributes(:one).exactly }
end

context 'when attributes is not present' do
it { expect({}).not_to have_jsonapi_attributes(:one, 'two') }
end
end
end
23 changes: 12 additions & 11 deletions spec/jsonapi/id_spec.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
require 'spec_helper'

RSpec.describe JSONAPI::RSpec, '#have_id' do
it 'succeeds when id matches' do
expect('id' => 'foo').to have_id('foo')
end

it 'fails when id mismatches' do
expect('id' => 'foo').not_to have_id('bar')
end
json_doc =
{
'id' => 'foo'
}

it 'fails when id is absent' do
expect({}).not_to have_id('foo')
describe '#have_id' do
context 'when id is present' do
it { expect(json_doc).to have_id('foo') }
it { expect(json_doc).not_to have_id('bar') }
end
context 'when id is not present' do
it { expect({}).not_to have_id('foo') }
end
end
end
38 changes: 15 additions & 23 deletions spec/jsonapi/jsonapi_object_spec.rb
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
require 'spec_helper'
RSpec.describe JSONAPI::RSpec do
json_doc =
{
'jsonapi' => {
'version' => '1.0'
}
}

RSpec.describe JSONAPI::RSpec, '#have_jsonapi_object' do
context 'when providing no value' do
it 'succeeds when jsonapi object is present' do
expect('jsonapi' => { 'version' => '1.0' }).to have_jsonapi_object
describe '#have_jsonapi_object' do
context 'when jsonapi is present' do
it { expect(json_doc).to have_jsonapi_object }
it { expect(json_doc).to have_jsonapi_object('version' => '1.0') }
it { expect(json_doc).not_to have_jsonapi_object('version' => '2.0') }
end

it 'fails when jsonapi object is absent' do
expect({}).not_to have_jsonapi_object
end
end

context 'when providing a value' do
it 'succeeds when jsonapi object matches' do
expect('jsonapi' => { 'version' => '1.0' })
.to have_jsonapi_object('version' => '1.0')
end

it 'fails when jsonapi object mismatches' do
expect('jsonapi' => { 'version' => '2.0' })
.not_to have_jsonapi_object('version' => '1.0')
end

it 'fails when jsonapi object is absent' do
expect({}).not_to have_jsonapi_object('version' => '1.0')
context 'when jsonapi is not present' do
it { expect({}).not_to have_jsonapi_object }
it { expect({}).not_to have_jsonapi_object('version' => '1.0') }
end
end
end
33 changes: 21 additions & 12 deletions spec/jsonapi/links_spec.rb
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
require 'spec_helper'

RSpec.describe JSONAPI::RSpec do
let(:doc) do
json_doc =
{
'links' => {
'self' => 'self_link',
'related' => 'related_link'
}
}
end

context '#have_link' do
it { expect(doc).to have_link(:self) }
it { expect(doc).to have_link(:self).with_value('self_link') }
it { expect(doc).not_to have_link(:self).with_value('any_link') }
it { expect(doc).not_to have_link(:any) }
describe '#have_link' do
context 'when links is present' do
it { expect(json_doc).to have_link(:self) }
it { expect(json_doc).to have_link(:self).with_value('self_link') }
it { expect(json_doc).not_to have_link(:self).with_value('any_link') }
it { expect(json_doc).not_to have_link(:any) }
end

context 'when links is not present' do
it { expect({}).not_to have_link(:self) }
end
end

context '#have_links' do
it { expect(doc).to have_links(:self, :related) }
it { expect(doc).not_to have_links(:self, :other) }
describe '#have_links' do
context 'when links is present' do
it { expect(json_doc).to have_links(:self, 'related') }
it { expect(json_doc).not_to have_links(:self, 'other') }
end

context 'when links is not present' do
it { expect({}).not_to have_links(:self, 'related') }
end
end
end
36 changes: 15 additions & 21 deletions spec/jsonapi/meta_spec.rb
Original file line number Diff line number Diff line change
@@ -1,27 +1,21 @@
require 'spec_helper'
RSpec.describe JSONAPI::RSpec do
json_doc =
{
'meta' => {
'foo' => 'bar'
}
}

RSpec.describe JSONAPI::RSpec, '#have_meta' do
context 'when providing no value' do
it 'succeeds when meta is present' do
expect('meta' => {}).to have_meta
describe '#have_meta' do
context 'when meta is present' do
it { expect(json_doc).to have_meta }
it { expect(json_doc).to have_meta('foo' => 'bar') }
it { expect(json_doc).not_to have_meta('foo' => 'baz') }
end

it 'fails when meta is absent' do
expect({}).not_to have_meta
end
end

context 'when providing a value' do
it 'succeeds when meta matches' do
expect('meta' => { foo: 'bar' }).to have_meta(foo: 'bar')
end

it 'fails when meta mismatches' do
expect('meta' => { foo: 'bar' }).not_to have_meta(bar: 'baz')
end

it 'fails when meta is absent' do
expect({}).not_to have_meta(foo: 'bar')
context 'when meta is not present' do
it { expect({}).not_to have_meta }
it { expect({}).not_to have_meta('foo' => 'bar') }
end
end
end
Loading