Skip to content

Commit 6e45eb0

Browse files
author
Lee Richmond
committed
Improve subclass customization
1 parent 20cb865 commit 6e45eb0

File tree

4 files changed

+151
-0
lines changed

4 files changed

+151
-0
lines changed

lib/jsonapi_compliable/base.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,10 @@ def jsonapi(&blk)
101101
if !self._jsonapi_compliable
102102
dsl = JsonapiCompliable::DSL.new
103103
self._jsonapi_compliable = dsl
104+
else
105+
self._jsonapi_compliable = self._jsonapi_compliable.copy
104106
end
107+
105108
self._jsonapi_compliable.instance_eval(&blk)
106109
end
107110
end

lib/jsonapi_compliable/dsl.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,21 @@ class DSL
88
:pagination
99

1010
def initialize
11+
clear!
12+
end
13+
14+
def copy
15+
instance = self.class.new
16+
instance.sideloads = sideloads.deep_dup
17+
instance.filters = filters.deep_dup
18+
instance.default_filters = default_filters.deep_dup
19+
instance.extra_fields = extra_fields.deep_dup
20+
instance.sorting = sorting.deep_dup
21+
instance.pagination = pagination.deep_dup
22+
instance
23+
end
24+
25+
def clear!
1126
@sideloads = {}
1227
@filters = {}
1328
@default_filters = {}

spec/dsl_spec.rb

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
require 'spec_helper'
2+
3+
RSpec.describe JsonapiCompliable::DSL do
4+
let(:instance) { described_class.new }
5+
6+
describe '#copy' do
7+
let(:copy) { instance.copy }
8+
9+
it 'returns a new instance' do
10+
expect(copy).to be_a(described_class)
11+
expect(copy.object_id).to_not eq(instance.object_id)
12+
end
13+
14+
it 'copies sideloads' do
15+
instance.sideloads = { foo: 'bar' }
16+
expect(copy.sideloads).to eq(foo: 'bar')
17+
expect(copy.sideloads.object_id).to_not eq(instance.sideloads.object_id)
18+
end
19+
20+
it 'copies filters' do
21+
instance.filters = { foo: 'bar' }
22+
expect(copy.filters).to eq(foo: 'bar')
23+
expect(copy.filters.object_id).to_not eq(instance.filters.object_id)
24+
end
25+
26+
it 'copies default filters' do
27+
instance.default_filters = { foo: 'bar' }
28+
expect(copy.default_filters).to eq(foo: 'bar')
29+
expect(copy.default_filters.object_id).to_not eq(instance.default_filters.object_id)
30+
end
31+
32+
it 'copies extra fields' do
33+
instance.extra_fields = { foo: 'bar' }
34+
expect(copy.extra_fields).to eq(foo: 'bar')
35+
expect(copy.extra_fields.object_id).to_not eq(instance.extra_fields.object_id)
36+
end
37+
38+
it 'copies sorting' do
39+
instance.sorting = 'a'
40+
expect(copy.sorting).to eq(instance.sorting)
41+
expect(copy.sorting.object_id).to_not eq(instance.sorting.object_id)
42+
end
43+
44+
it 'copies pagination' do
45+
instance.pagination = 'a'
46+
expect(copy.pagination).to eq(instance.pagination)
47+
expect(copy.pagination.object_id).to_not eq(instance.pagination.object_id)
48+
end
49+
end
50+
51+
describe '#clear' do
52+
before do
53+
instance.sideloads = { foo: 'bar' }
54+
instance.filters = { foo: 'bar' }
55+
instance.default_filters = { foo: 'bar' }
56+
instance.extra_fields = { foo: 'bar' }
57+
instance.sorting = 'a'
58+
instance.pagination = 'a'
59+
end
60+
61+
it 'resets sideloads' do
62+
expect {
63+
instance.clear!
64+
}.to change { instance.sideloads }.to({})
65+
end
66+
67+
it 'resets filters' do
68+
expect {
69+
instance.clear!
70+
}.to change { instance.filters }.to({})
71+
end
72+
73+
it 'resets default filters' do
74+
expect {
75+
instance.clear!
76+
}.to change { instance.default_filters }.to({})
77+
end
78+
79+
it 'resets extra fields' do
80+
expect {
81+
instance.clear!
82+
}.to change { instance.extra_fields }.to({})
83+
end
84+
85+
it 'resets sorting' do
86+
expect {
87+
instance.clear!
88+
}.to change { instance.sorting }.to(nil)
89+
end
90+
91+
it 'resets pagination' do
92+
expect {
93+
instance.clear!
94+
}.to change { instance.pagination }.to(nil)
95+
end
96+
end
97+
end

spec/jsonapi_compliable_spec.rb

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,42 @@ def index
1010
end
1111
end
1212

13+
describe '.jsonapi' do
14+
let(:subclass1) do
15+
Class.new(controller.class) do
16+
jsonapi do
17+
allow_filter :id
18+
allow_filter :foo
19+
end
20+
end
21+
end
22+
23+
let(:subclass2) do
24+
Class.new(subclass1) do
25+
jsonapi do
26+
allow_filter :foo do |scope, value|
27+
'foo'
28+
end
29+
end
30+
end
31+
end
32+
33+
context 'when subclassing and customizing' do
34+
it 'preserves values from superclass' do
35+
expect(subclass2._jsonapi_compliable.filters[:id]).to_not be_nil
36+
end
37+
38+
it 'does not alter superclass when overriding' do
39+
expect(subclass1._jsonapi_compliable)
40+
.to_not eq(subclass2._jsonapi_compliable)
41+
expect(subclass1._jsonapi_compliable.filters[:id].object_id)
42+
.to_not eq(subclass2._jsonapi_compliable.filters[:id].object_id)
43+
expect(subclass1._jsonapi_compliable.filters[:foo][:filter]).to be_nil
44+
expect(subclass2._jsonapi_compliable.filters[:foo][:filter]).to_not be_nil
45+
end
46+
end
47+
end
48+
1349
describe '#render_ams' do
1450
it 'is able to override options' do
1551
author = Author.create!(first_name: 'Stephen', last_name: 'King')

0 commit comments

Comments
 (0)