Skip to content

add have_jsonapi_errors matcher with chainable expectations #6

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
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
2 changes: 2 additions & 0 deletions lib/jsonapi/rspec.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'jsonapi/rspec/errors'
require 'jsonapi/rspec/id'
require 'jsonapi/rspec/type'
require 'jsonapi/rspec/attributes'
Expand All @@ -8,6 +9,7 @@

module JSONAPI
module RSpec
include Errors
include Id
include Type
include Attributes
Expand Down
135 changes: 135 additions & 0 deletions lib/jsonapi/rspec/errors.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
module JSONAPI
module RSpec
module Errors
IncompatibleSourcesError = Class.new(StandardError)

::RSpec::Matchers.define :have_jsonapi_errors do
match do |actual|
actual ||= {}

if @pointer && @parameter
fail IncompatibleSourcesError.new('Only one source per example')
end

errors = actual['errors'] || {}

on_parameter = true
on_pointer = true
if @check_on_parameter || @check_on_pointer
source_type = 'pointer' if @pointer
source_type = 'parameter' if @parameter
errors.keep_if do |e|
!e['source'].nil? &&
e['source'][source_type] == (@pointer || @parameter)
end

if errors.empty?
on_parameter = false if @parameter
on_pointer = false if @pointer
end
end

errors_present = actual.key?('errors')
# Use these values to see if we need to run the check.
# If the value is set to true the test will run
correct_count = !@check_with_count
with_ids = !@check_with_ids
with_about_link = !@check_with_about_link
with_status = !@check_with_status
with_code = !@check_with_code
with_title = !@check_with_title
with_detail = !@check_with_detail
with_source = !@check_with_source
with_meta = !@check_with_meta

correct_count ||= errors.count == @count

with_ids ||= errors.map { |e| e['id'] }.count == errors.count

with_about_link ||=
errors.map { |e| e['links']['about'] }.include?(@about_link)

with_status ||= errors.map { |e| e['status'] }.include?(@status)

with_code ||= errors.map { |e| e['code'] }.include?(@code)

with_title ||= errors.map { |e| e['title'] }.include?(@title)

with_detail ||= errors.map { |e| e['detail'] }.include?(@detail)

with_source ||= errors.map { |e| e['source'] }.any?

with_meta ||= errors.map { |e| e['meta'] }.include?(@meta)

[
errors_present,
on_parameter,
on_pointer,
correct_count,
with_ids,
with_about_link,
with_status,
with_code,
with_title,
with_detail,
with_source,
with_meta
].all?(true)
end

chain :count do |count|
@check_with_count = true
@count = count
end

chain :with_ids do
@check_with_ids = true
end

chain :with_about_link do |about_link|
@check_with_about_link = true
@about_link = about_link
end

chain :with_status do |status|
@check_with_status = true
@status = status
end

chain :with_code do |code|
@check_with_code = true
@code = code
end

chain :with_title do |title|
@check_with_title = true
@title = title
end

chain :with_detail do |detail|
@check_with_detail = true
@detail = detail
end

chain :with_source do
@check_with_source = true
end

chain :on_pointer do |pointer|
@check_on_pointer = true
@pointer = pointer
end

chain :on_parameter do |parameter|
@check_on_parameter = true
@parameter = parameter
end

chain :with_meta do |meta|
@check_with_meta = true
@meta = meta
end
end
end
end
end
175 changes: 175 additions & 0 deletions spec/errors_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
require 'spec_helper'
RSpec.describe JSONAPI::RSpec, '#have_jsonapi_error' do
let(:id) { '1' }
let(:about_link) { 'http://about.me' }
let(:status) { '200' }
let(:code) { 'bad_thing' }
let(:title) { 'A bad thing happened' }
let(:detail) { 'The thing was bad' }
let(:source) { pointer_source }
let(:pointer) { '/data/attribute/title' }
let(:pointer_source) { { 'pointer' => pointer } }
let(:parameter) { 'page' }
let(:parameter_source) { { 'parameter' => parameter } }
let(:meta) do
{
"copyright" => "Copyright 2015 Example Corp.",
"authors" => [
"Yehuda Katz",
"Steve Klabnik",
"Dan Gebhardt",
"Tyler Kellen"
]
}
end

subject do
{
'errors' => [
{
'id' => id,
'links' => { 'about' => about_link },
'status' => status,
'code' => code,
'title' => title,
'detail' => detail,
'source' => source,
'meta' => meta
}
]
}
end

it 'succeeds when errors key is present' do
is_expected.to have_jsonapi_errors
end

it 'fails when errors key is absent' do
expect({}).to_not have_jsonapi_errors
end

context 'chained methods' do
describe '#count(count)' do
it 'succeeds when errors count == count' do
is_expected.to have_jsonapi_errors.count(1)
end

it 'fails when errors exclude ids' do
expect({}).to_not have_jsonapi_errors.count(1)
end
end

describe '#with_ids' do
it 'succeeds when errors include ids' do
is_expected.to have_jsonapi_errors.with_ids
end

it 'fails when errors exclude ids' do
expect({}).to_not have_jsonapi_errors.with_ids
end
end

describe '#with_about_link(about_link)' do
it 'succeeds when errors include about links' do
is_expected.to have_jsonapi_errors.with_about_link(about_link)
end

it 'fails when errors exclude about_link' do
expect({}).to_not have_jsonapi_errors.with_about_link(about_link)
end
end

describe '#with_status(status)' do
it 'succeeds when errors include about links' do
is_expected.to have_jsonapi_errors.with_status(status)
end

it 'fails when errors exclude status' do
expect({}).to_not have_jsonapi_errors.with_status(status)
end
end

describe '#with_code(code)' do
it 'succeeds when errors include about links' do
is_expected.to have_jsonapi_errors.with_code(code)
end

it 'fails when errors exclude code' do
expect({}).to_not have_jsonapi_errors.with_code(code)
end
end

describe '#with_title(title)' do
it 'succeeds when errors include about links' do
is_expected.to have_jsonapi_errors.with_title(title)
end

it 'fails when errors exclude title' do
expect({}).to_not have_jsonapi_errors.with_title(title)
end
end

describe '#with_detail(detail)' do
it 'succeeds when errors include about links' do
is_expected.to have_jsonapi_errors.with_detail(detail)
end

it 'fails when errors exclude detail' do
expect({}).to_not have_jsonapi_errors.with_detail(detail)
end
end

describe '#with_source' do
it 'succeeds when errors include about links' do
is_expected.to have_jsonapi_errors.with_source
end

it 'fails when errors exclude source' do
expect({}).to_not have_jsonapi_errors.with_source
end
end

describe '#on_pointer(pointer)' do
let!(:source) { pointer_source }

it 'succeeds when errors include about links' do
is_expected.to have_jsonapi_errors.on_pointer(pointer)
end

it 'fails when errors exclude pointer_source' do
expect({}).to_not have_jsonapi_errors.on_pointer(pointer)
end
end

describe '#on_parameter(parameter)' do
let!(:source) { parameter_source }

it 'succeeds when errors include about links' do
is_expected.to have_jsonapi_errors.on_parameter(parameter)
end

it 'fails when errors exclude parameter_source' do
expect({}).to_not have_jsonapi_errors.on_parameter(parameter)
end
end

describe '#with_meta(meta)' do
it 'succeeds when errors include about links' do
is_expected.to have_jsonapi_errors.with_meta(meta)
end

it 'fails when errors exclude meta' do
expect({}).to_not have_jsonapi_errors.with_meta(meta)
end
end

describe '#on_parameter and #on_pointer' do
it 'raises a warning' do
expect {
expect({}).to have_jsonapi_errors.
on_pointer(pointer).on_parameter(parameter)
}.to raise_error(JSONAPI::RSpec::Errors::IncompatibleSourcesError)
end
end
end
end
1 change: 1 addition & 0 deletions spec/id_spec.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'spec_helper'
RSpec.describe JSONAPI::RSpec, '#have_id' do
it 'succeeds when id matches' do
expect('id' => 'foo').to have_id('foo')
Expand Down
1 change: 1 addition & 0 deletions spec/jsonapi_object_spec.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'spec_helper'
RSpec.describe JSONAPI::RSpec, '#have_jsonapi_object' do
context 'when providing no value' do
it 'succeeds when jsonapi object is present' do
Expand Down
1 change: 1 addition & 0 deletions spec/meta_spec.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'spec_helper'
RSpec.describe JSONAPI::RSpec, '#have_meta' do
context 'when providing no value' do
it 'succeeds when meta is present' do
Expand Down
1 change: 1 addition & 0 deletions spec/type_spec.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'spec_helper'
RSpec.describe JSONAPI::RSpec, '#have_type' do
it 'succeeds when type matches' do
expect('type' => 'foo').to have_type('foo')
Expand Down