-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Apply collection detection in Decanter::Base (#119)
* Add rspec config option * Add collection detection as separate module * Only test core module in decanter_core_spec * Add specs for collection detection * Revert extensions changes * Bump patch * Fix invalid spec * Update documentation * Remove unnecessary require * Force collection option to be nil or a boolean
- Loading branch information
Showing
11 changed files
with
129 additions
and
114 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,9 @@ | ||
require 'decanter/core' | ||
require 'decanter/collection_detection' | ||
|
||
module Decanter | ||
class Base | ||
include Core | ||
include CollectionDetection | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
module Decanter | ||
module CollectionDetection | ||
def self.included(base) | ||
base.extend(ClassMethods) | ||
end | ||
|
||
module ClassMethods | ||
def decant(args, **options) | ||
return super(args) unless collection?(args, options[:is_collection]) | ||
|
||
args.map { |resource| super(resource) } | ||
end | ||
|
||
private | ||
|
||
# leveraging the approach used in the [fast JSON API gem](https://github.com/Netflix/fast_jsonapi#collection-serialization) | ||
def collection?(args, collection_option = nil) | ||
raise(ArgumentError, "#{name}: Unknown collection option value: #{collection_option}") unless [true, false, nil].include? collection_option | ||
|
||
return collection_option unless collection_option.nil? | ||
|
||
args.respond_to?(:size) && !args.respond_to?(:each_pair) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
module Decanter | ||
VERSION = '3.5.0'.freeze | ||
VERSION = '3.5.1'.freeze | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
require 'spec_helper' | ||
|
||
describe Decanter::CollectionDetection do | ||
let(:base_decanter) { | ||
stub_const('BaseDecanter', Class.new) | ||
} | ||
|
||
let(:decanter) { | ||
stub_const('TripDecanter', base_decanter.new) | ||
TripDecanter.class_eval { include Decanter::CollectionDetection } | ||
} | ||
let(:args) { { destination: 'Hawaii' } } | ||
|
||
before(:each) { | ||
allow(base_decanter).to receive(:decant) | ||
} | ||
|
||
describe '#decant' do | ||
context 'when args are a single hash' do | ||
it 'calls decant on the entire element' do | ||
decanter.decant(args) | ||
expect(base_decanter).to have_received(:decant).once.with(args) | ||
end | ||
end | ||
|
||
context 'when no collection option is passed' do | ||
context 'and args are a collection' do | ||
let(:args) { [{ destination: 'Hawaii' }, { destination: 'Denver' }] } | ||
|
||
it 'calls decant with each element' do | ||
decanter.decant(args) | ||
expect(base_decanter).to have_received(:decant).with(args.first) | ||
expect(base_decanter).to have_received(:decant).with(args.second) | ||
end | ||
end | ||
|
||
context 'and args are not a collection' do | ||
let(:args) { { "0": [{ destination: 'Hawaii' }] } } | ||
it 'calls decant on the entire element' do | ||
decanter.decant(args) | ||
expect(base_decanter).to have_received(:decant).once.with(args) | ||
end | ||
end | ||
end | ||
|
||
context 'when the collection option is passed' do | ||
let(:fake_collection) { double('fake_collection') } | ||
let(:args) { fake_collection } | ||
|
||
before(:each) do | ||
allow(fake_collection).to receive(:map).and_yield(1).and_yield(2) | ||
end | ||
|
||
context 'and the value is true' do | ||
it 'is considered a collection' do | ||
decanter.decant(args, is_collection: true) | ||
expect(base_decanter).to have_received(:decant).with(1) | ||
expect(base_decanter).to have_received(:decant).with(2) | ||
end | ||
end | ||
|
||
context 'and the value is false' do | ||
it 'is not considered a collection' do | ||
decanter.decant(args, is_collection: false) | ||
expect(base_decanter).to have_received(:decant).once.with(args) | ||
end | ||
end | ||
|
||
context 'and the value is truthy' do | ||
it 'raises an error' do | ||
expect { decanter.decant(args, is_collection: 'yes') }.to raise_error(ArgumentError) | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters