Add automatic key formatting. (#15)

This commit is contained in:
Lucas Hosseini 2017-07-15 04:17:28 +02:00 committed by GitHub
parent 4d1ed42095
commit e66d9c42fb
3 changed files with 107 additions and 4 deletions

View File

@ -10,12 +10,14 @@ module JSONAPI
attr_accessor :type_block, :id_block, :attr_blocks,
:has_one_rel_blocks, :has_many_rel_blocks,
:default_attr_block, :default_has_one_rel_block,
:default_has_many_rel_block
:default_has_many_rel_block,
:key_formatter
end
self.attr_blocks = {}
self.has_one_rel_blocks = {}
self.has_many_rel_blocks = {}
self.key_formatter = proc { |k| k }
def self.inherited(klass)
super
@ -27,6 +29,7 @@ module JSONAPI
klass.default_attr_block = default_attr_block
klass.default_has_one_rel_block = default_has_one_rel_block
klass.default_has_many_rel_block = default_has_many_rel_block
klass.key_formatter = key_formatter
end
def self.call(payload)
@ -95,7 +98,7 @@ module JSONAPI
block = self.class.attr_blocks[key] || self.class.default_attr_block
return {} unless block
hash = block.call(val, key)
hash = block.call(val, self.class.key_formatter.call(key))
register_mappings(hash.keys, "/data/attributes/#{key}")
hash
end
@ -122,7 +125,7 @@ module JSONAPI
id = val['data'] && val['data']['id']
type = val['data'] && val['data']['type']
hash = block.call(val, id, type, key)
hash = block.call(val, id, type, self.class.key_formatter.call(key))
register_mappings(hash.keys, "/data/relationships/#{key}")
hash
end
@ -136,7 +139,7 @@ module JSONAPI
ids = val['data'].map { |ri| ri['id'] }
types = val['data'].map { |ri| ri['type'] }
hash = block.call(val, ids, types, key)
hash = block.call(val, ids, types, self.class.key_formatter.call(key))
register_mappings(hash.keys, "/data/relationships/#{key}")
hash
end

View File

@ -47,6 +47,10 @@ module JSONAPI
self.default_has_many_rel_block = block || DEFAULT_HAS_MANY_BLOCK
end
end
def key_format(callable = nil, &block)
self.key_formatter = callable || block
end
end
end
end

View File

@ -0,0 +1,96 @@
require 'spec_helper'
describe JSONAPI::Deserializable::Resource, '.key_format' do
subject { klass.call(payload) }
let(:payload) do
{
'data' => {
'type' => 'foo',
'attributes' => { 'foo' => 'bar', 'foo-bar' => 'baz' },
'relationships' => {
'baz' => {
'data' => nil
},
'bar-baz' => {
'data' => []
}
}
}
}
end
context 'when all fields are whitelisted' do
context 'when a key formatter is provided as a block' do
let(:klass) do
Class.new(JSONAPI::Deserializable::Resource) do
key_format { |k| k.capitalize }
attributes
has_many
has_one
end
end
it 'formats keys accordingly' do
is_expected.to eq(Foo: 'bar', 'Foo-bar'.to_sym => 'baz',
Baz_id: nil, Baz_type: nil,
'Bar-baz_ids'.to_sym => [],
'Bar-baz_types'.to_sym => [])
end
end
context 'when a key formatter is provided as a callable' do
let(:klass) do
Class.new(JSONAPI::Deserializable::Resource) do
key_format ->(k) { k.capitalize }
attributes
has_many
has_one
end
end
it 'formats keys accordingly' do
is_expected.to eq(Foo: 'bar', 'Foo-bar'.to_sym => 'baz',
Baz_id: nil, Baz_type: nil,
'Bar-baz_ids'.to_sym => [],
'Bar-baz_types'.to_sym => [])
end
end
end
context 'when certain fields are whitelisted' do
let(:klass) do
Class.new(JSONAPI::Deserializable::Resource) do
key_format { |k| k.capitalize }
attributes :foo
has_one :baz
end
end
it 'formats keys accordingly' do
is_expected.to eq(Foo: 'bar',
Baz_id: nil, Baz_type: nil)
end
end
context 'when inheriting' do
let(:klass) do
superclass = Class.new(JSONAPI::Deserializable::Resource) do
key_format { |k| k.capitalize }
end
Class.new(superclass) do
attributes
has_many
has_one
end
end
it 'formats keys accordingly' do
is_expected.to eq(Foo: 'bar', 'Foo-bar'.to_sym => 'baz',
Baz_id: nil, Baz_type: nil,
'Bar-baz_ids'.to_sym => [],
'Bar-baz_types'.to_sym => [])
end
end
end