yaks 0.4.2 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +65 -5
- data/README.md +38 -8
- data/Rakefile +33 -0
- data/lib/yaks/breaking_changes.rb +22 -0
- data/lib/yaks/collection_mapper.rb +18 -21
- data/lib/yaks/collection_resource.rb +19 -5
- data/lib/yaks/config/dsl.rb +78 -0
- data/lib/yaks/config.rb +37 -63
- data/lib/yaks/default_policy.rb +27 -9
- data/lib/yaks/{serializer → format}/collection_json.rb +7 -3
- data/lib/yaks/{serializer → format}/hal.rb +14 -4
- data/lib/yaks/{serializer → format}/json_api.rb +22 -4
- data/lib/yaks/{serializer.rb → format.rb} +5 -5
- data/lib/yaks/fp/hash_updatable.rb +17 -0
- data/lib/yaks/fp/updatable.rb +15 -0
- data/lib/yaks/mapper/association.rb +24 -21
- data/lib/yaks/mapper/association_mapper.rb +42 -0
- data/lib/yaks/mapper/attribute.rb +17 -0
- data/lib/yaks/mapper/class_methods.rb +0 -1
- data/lib/yaks/mapper/config.rb +8 -28
- data/lib/yaks/mapper/has_many.rb +8 -3
- data/lib/yaks/mapper/has_one.rb +1 -1
- data/lib/yaks/mapper/link.rb +13 -13
- data/lib/yaks/mapper.rb +28 -32
- data/lib/yaks/null_resource.rb +1 -0
- data/lib/yaks/resource.rb +15 -5
- data/lib/yaks/version.rb +1 -1
- data/lib/yaks.rb +16 -10
- data/spec/acceptance/acceptance_spec.rb +16 -17
- data/spec/acceptance/json_shared_examples.rb +8 -0
- data/spec/acceptance/models.rb +2 -2
- data/spec/integration/map_to_resource_spec.rb +3 -3
- data/spec/json/confucius.collection.json +39 -0
- data/spec/json/confucius.hal.json +7 -4
- data/spec/json/confucius.json_api.json +1 -1
- data/spec/spec_helper.rb +6 -0
- data/spec/support/classes_for_policy_testing.rb +36 -0
- data/spec/support/shared_contexts.rb +1 -1
- data/spec/unit/yaks/collection_mapper_spec.rb +34 -9
- data/spec/unit/yaks/collection_resource_spec.rb +4 -4
- data/spec/unit/yaks/config/dsl_spec.rb +91 -0
- data/spec/unit/yaks/config_spec.rb +10 -6
- data/spec/unit/yaks/default_policy/derive_mapper_from_object_spec.rb +80 -0
- data/spec/unit/yaks/default_policy_spec.rb +50 -0
- data/spec/unit/yaks/{serializer → format}/hal_spec.rb +1 -1
- data/spec/unit/yaks/format/json_api_spec.rb +42 -0
- data/spec/unit/yaks/format_spec.rb +12 -0
- data/spec/unit/yaks/fp/hash_updatable_spec.rb +22 -0
- data/spec/unit/yaks/fp/updatable_spec.rb +22 -0
- data/spec/unit/yaks/mapper/association_mapper_spec.rb +60 -0
- data/spec/unit/yaks/mapper/association_spec.rb +96 -41
- data/spec/unit/yaks/mapper/attribute_spec.rb +20 -0
- data/spec/unit/yaks/mapper/class_methods_spec.rb +49 -10
- data/spec/unit/yaks/mapper/config_spec.rb +25 -50
- data/spec/unit/yaks/mapper/has_many_spec.rb +33 -5
- data/spec/unit/yaks/mapper/has_one_spec.rb +32 -17
- data/spec/unit/yaks/mapper/link_spec.rb +44 -12
- data/spec/unit/yaks/mapper_spec.rb +45 -17
- data/spec/unit/yaks/resource_spec.rb +41 -7
- data/yaks.gemspec +7 -1
- metadata +72 -21
- data/examples/hal01.rb +0 -126
- data/examples/jsonapi01.rb +0 -68
- data/examples/jsonapi02.rb +0 -62
- data/examples/jsonapi03.rb +0 -86
- data/spec/support/serializers.rb +0 -14
- data/spec/unit/yaks/serializer_spec.rb +0 -12
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Yaks::DefaultPolicy, '#derive_mapper_from_object' do
|
4
|
+
subject(:policy) { described_class.new(options) }
|
5
|
+
|
6
|
+
let(:options) { {} }
|
7
|
+
|
8
|
+
context 'for a single instance' do
|
9
|
+
it 'should derive it by name' do
|
10
|
+
expect(policy.derive_mapper_from_object(Soy.new)).to be SoyMapper
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'given a namespace' do
|
14
|
+
let(:options) { {namespace: MyMappers} }
|
15
|
+
|
16
|
+
it 'should look inside the namespace' do
|
17
|
+
expect(policy.derive_mapper_from_object(Soy.new)).to be MyMappers::SoyMapper
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'for array-like objects' do
|
23
|
+
context 'given an empty array' do
|
24
|
+
it 'should return the vanilla CollectionMapper' do
|
25
|
+
expect(policy.derive_mapper_from_object([])).to be Yaks::CollectionMapper
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should find the mapper based on naming' do
|
30
|
+
expect(policy.derive_mapper_from_object([Soy.new])).to be SoyCollectionMapper
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'if no collection mapper with a similar name is defined' do
|
34
|
+
let(:options) { {namespace: Namespace} }
|
35
|
+
|
36
|
+
it 'should look for a CollectionMapper in the namespace' do
|
37
|
+
expect(policy.derive_mapper_from_object([Wheat.new])).to be(
|
38
|
+
Namespace::CollectionMapper
|
39
|
+
)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'for a model class inside a module' do
|
45
|
+
let(:options) { {namespace: Namespace} }
|
46
|
+
|
47
|
+
it 'should take the non-qualified classname, and search the mapper namespace with that' do
|
48
|
+
expect(policy.derive_mapper_from_object(Namespace::Nested::Rye.new)).to be(
|
49
|
+
Namespace::RyeMapper
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should take the non-qualified classname when looking for a collection mapper' do
|
54
|
+
expect(policy.derive_mapper_from_object([Namespace::Nested::Rye.new])).to be(
|
55
|
+
Namespace::RyeCollectionMapper
|
56
|
+
)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'when trying to lookup CollectionMapper results in something other than an NameError' do
|
61
|
+
let(:options) { { namespace: DislikesCollectionMapper } }
|
62
|
+
|
63
|
+
it 'should propagate the error' do
|
64
|
+
expect {
|
65
|
+
policy.derive_mapper_from_object([])
|
66
|
+
}.to raise_error
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'when trying to lookup a specific collection mapper results in something other than an NameError' do
|
71
|
+
let(:options) { { namespace: DislikesOtherMappers } }
|
72
|
+
|
73
|
+
it 'should propagate the error' do
|
74
|
+
expect {
|
75
|
+
policy.derive_mapper_from_object([Namespace::Nested::Rye.new])
|
76
|
+
}.to raise_error
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Yaks::DefaultPolicy do
|
4
|
+
subject(:policy) { described_class.new( options ) }
|
5
|
+
|
6
|
+
let(:options) { {} }
|
7
|
+
let(:association) { Yaks::Mapper::HasMany.new(name: 'shoes', collectionMapper: nil) }
|
8
|
+
|
9
|
+
describe '#initialize' do
|
10
|
+
it 'should work without arguments' do
|
11
|
+
expect(described_class.new.options).to eql described_class::DEFAULTS
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:options) { {foo: :bar} }
|
15
|
+
|
16
|
+
it 'should merge default and given options' do
|
17
|
+
expect(policy.options.values_at(:namespace, :foo)).to eql [Kernel, :bar]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#derive_type_from_mapper_class' do
|
22
|
+
specify do
|
23
|
+
expect(
|
24
|
+
policy.derive_type_from_mapper_class(Namespace::RyeMapper)
|
25
|
+
).to eql 'rye'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#derive_mapper_from_association' do
|
30
|
+
let(:options) { { namespace: Namespace } }
|
31
|
+
|
32
|
+
it 'should derive using the singular association name, and look inside the namespace' do
|
33
|
+
expect(policy.derive_mapper_from_association(association)).to be Namespace::ShoeMapper
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#derive_rel_from_association' do
|
38
|
+
it 'should expand the rel based on the association name' do
|
39
|
+
expect(policy.derive_rel_from_association(association)).to eql 'rel:shoes'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#expand_rel' do
|
44
|
+
let(:options) { { rel_template: 'http://foo/{?rel}' } }
|
45
|
+
it 'should expand the given template' do
|
46
|
+
expect(policy.expand_rel('rockets')).to eql 'http://foo/?rel=rockets'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# Mainly tested through the acceptance tests, here covering a few specific edge cases
|
4
|
+
RSpec.describe Yaks::Format::JsonApi do
|
5
|
+
let(:format) { Yaks::Format::JsonApi.new }
|
6
|
+
|
7
|
+
context 'with no subresources' do
|
8
|
+
let(:resource) { Yaks::Resource.new(type: 'wizard', attributes: {foo: :bar}) }
|
9
|
+
|
10
|
+
it 'should not include a "linked" key' do
|
11
|
+
expect(format.call(resource)).to eql(
|
12
|
+
{'wizards' => [{foo: :bar}]}
|
13
|
+
)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'with both a "href" attribute and a self link' do
|
18
|
+
let(:resource) {
|
19
|
+
Yaks::Resource.new(
|
20
|
+
type: 'wizard',
|
21
|
+
attributes: {
|
22
|
+
href: '/the/href'
|
23
|
+
},
|
24
|
+
links: [
|
25
|
+
Yaks::Resource::Link.new(:self, '/the/self/link', {})
|
26
|
+
]
|
27
|
+
)
|
28
|
+
}
|
29
|
+
|
30
|
+
it 'should give preference to the href attribute' do
|
31
|
+
expect(format.call(resource)).to eql(
|
32
|
+
{'wizards' => [
|
33
|
+
{
|
34
|
+
href: '/the/href'
|
35
|
+
}
|
36
|
+
]
|
37
|
+
}
|
38
|
+
)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Yaks::Format do
|
4
|
+
describe '.by_name' do
|
5
|
+
specify { expect(Yaks::Format.by_name(:hal)).to eql Yaks::Format::Hal }
|
6
|
+
specify { expect(Yaks::Format.by_name(:json_api)).to eql Yaks::Format::JsonApi }
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '.by_mime_type' do
|
10
|
+
specify { expect(Yaks::Format.by_mime_type('application/hal+json')).to eql Yaks::Format::Hal }
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
RSpec.describe Yaks::FP::HashUpdatable do
|
5
|
+
let(:klz) do
|
6
|
+
Class.new do
|
7
|
+
include Equalizer.new(:aa, :bb, :cc)
|
8
|
+
include Yaks::FP::HashUpdatable.new(:aa, :bb, :cc)
|
9
|
+
|
10
|
+
attr_reader :aa, :bb, :cc
|
11
|
+
private :aa
|
12
|
+
|
13
|
+
def initialize(opts)
|
14
|
+
@aa, @bb, @cc = opts.values_at(:aa, :bb, :cc)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should only update the selected fields' do
|
20
|
+
expect(klz.new(aa: 1, bb: 2, cc: 3).update(bb: 7, cc: 9)).to eq klz.new(aa: 1, bb: 7, cc: 9)
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
RSpec.describe Yaks::FP::Updatable do
|
5
|
+
let(:klz) do
|
6
|
+
Class.new do
|
7
|
+
include Equalizer.new(:aa, :bb, :cc)
|
8
|
+
include Yaks::FP::Updatable.new(:aa, :bb, :cc)
|
9
|
+
|
10
|
+
attr_reader :aa, :bb, :cc
|
11
|
+
private :aa
|
12
|
+
|
13
|
+
def initialize(aa, bb, cc)
|
14
|
+
@aa, @bb, @cc = aa, bb, cc
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should only updated the selected fields' do
|
20
|
+
expect(klz.new(1,2,3).update(bb: 7, cc: 9)).to eq klz.new(1,7,9)
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Yaks::Mapper::AssociationMapper do
|
4
|
+
include_context 'yaks context'
|
5
|
+
|
6
|
+
subject(:association_mapper) { described_class.new(parent_mapper, association, yaks_context) }
|
7
|
+
|
8
|
+
let(:parent_mapper_class) { Yaks::Mapper }
|
9
|
+
let(:parent_mapper) { parent_mapper_class.new(yaks_context) }
|
10
|
+
|
11
|
+
fake(:association) { Yaks::Mapper::Association }
|
12
|
+
|
13
|
+
its(:policy) { should be policy }
|
14
|
+
|
15
|
+
let(:mapper_stack) { [:bottom_mapper] }
|
16
|
+
|
17
|
+
describe '#call' do
|
18
|
+
context 'when the association should be rendered as link' do
|
19
|
+
before do
|
20
|
+
stub(association).render_as_link?(parent_mapper) { true }
|
21
|
+
stub(association).map_rel(policy) { 'rels:the_rel' }
|
22
|
+
stub(association).href { 'http://this/is_where_the_associated_thing_can_be_found' }
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should render a link' do
|
26
|
+
expect(association_mapper.call(Yaks::Resource.new)).to eql Yaks::Resource.new(
|
27
|
+
links: [
|
28
|
+
Yaks::Resource::Link.new(
|
29
|
+
'rels:the_rel',
|
30
|
+
'http://this/is_where_the_associated_thing_can_be_found', {}
|
31
|
+
)
|
32
|
+
]
|
33
|
+
)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'when the association should be rendered as a subresource' do
|
38
|
+
before do
|
39
|
+
stub(association).render_as_link?(parent_mapper) { false }
|
40
|
+
stub(association).map_rel(policy) { 'rels:the_rel' }
|
41
|
+
stub(association).name { :the_name }
|
42
|
+
stub(association).map_resource(:the_object, association_mapper.context) { :the_resource }
|
43
|
+
|
44
|
+
stub(parent_mapper).load_association(:the_name) { :the_object }
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should render a link' do
|
48
|
+
expect(association_mapper.call(Yaks::Resource.new)).to eql Yaks::Resource.new(
|
49
|
+
subresources: {
|
50
|
+
'rels:the_rel' => :the_resource
|
51
|
+
}
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should add the mapper to the mapper_stack' do
|
56
|
+
expect(association_mapper.context[:mapper_stack]).to eql [:bottom_mapper, parent_mapper]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -1,79 +1,134 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe Yaks::Mapper::Association do
|
4
|
-
|
4
|
+
include_context 'yaks context'
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
subject(:association) do
|
7
|
+
described_class.new(
|
8
|
+
name: name,
|
9
|
+
mapper: mapper,
|
10
|
+
rel: rel,
|
11
|
+
href: href,
|
12
|
+
link_if: link_if
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:name) { :shoes }
|
17
|
+
let(:mapper) { Yaks::Mapper }
|
8
18
|
let(:rel) { Yaks::Undefined }
|
9
|
-
let(:
|
10
|
-
let(:
|
11
|
-
let(:map_resource) { ->(obj, policy) {} }
|
12
|
-
let(:lookup) { ->(*) {} }
|
13
|
-
let(:policy) { Yaks::DefaultPolicy.new }
|
14
|
-
let(:context) { { policy: policy, env: {} } }
|
19
|
+
let(:href) { Yaks::Undefined }
|
20
|
+
let(:link_if) { Yaks::Undefined }
|
15
21
|
|
16
|
-
its(:name)
|
22
|
+
its(:name) { should equal :shoes }
|
23
|
+
its(:child_mapper) { should equal Yaks::Mapper }
|
17
24
|
|
18
|
-
|
19
|
-
described_class.new(name
|
25
|
+
context 'with a minimal constructor' do
|
26
|
+
subject(:association) { described_class.new(name: :foo) }
|
27
|
+
|
28
|
+
its(:name) { should be :foo }
|
29
|
+
its(:child_mapper) { should be Yaks::Undefined }
|
30
|
+
its(:rel) { should be Yaks::Undefined }
|
31
|
+
its(:href) { should be Yaks::Undefined }
|
32
|
+
its(:link_if) { should be Yaks::Undefined }
|
20
33
|
end
|
21
34
|
|
22
|
-
|
23
|
-
|
24
|
-
|
35
|
+
let(:parent_mapper_class) { Yaks::Mapper }
|
36
|
+
let(:parent_mapper) { parent_mapper_class.new(yaks_context) }
|
37
|
+
|
38
|
+
describe '#add_to_resource' do
|
39
|
+
let(:object) { fake(:shoes => []) }
|
40
|
+
let(:rel) { 'rel:shoes' }
|
41
|
+
before do
|
42
|
+
parent_mapper.call(object)
|
25
43
|
end
|
26
44
|
|
27
|
-
|
28
|
-
|
45
|
+
it 'should delegate to AssociationMapper' do
|
46
|
+
expect(association.add_to_resource(Yaks::Resource.new, parent_mapper, yaks_context)).to eql Yaks::Resource.new(subresources: {'rel:shoes' => nil} )
|
47
|
+
end
|
48
|
+
end
|
29
49
|
|
30
|
-
|
31
|
-
|
50
|
+
describe '#render_as_link?' do
|
51
|
+
let(:href) { '/foo/{bar}/baz' }
|
52
|
+
let(:link_if) { -> { env.fetch('env_entry') == 123 } }
|
53
|
+
let(:rack_env) { { 'env_entry' => 123 } }
|
54
|
+
|
55
|
+
let(:render_as_link?) { association.render_as_link?(parent_mapper) }
|
56
|
+
|
57
|
+
context 'when evaluating to true' do
|
58
|
+
it 'should resolve :link_if in the context of the mapper' do
|
59
|
+
expect(render_as_link?).to be true
|
32
60
|
end
|
33
61
|
end
|
34
62
|
|
35
|
-
context '
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
63
|
+
context 'when evaluating to false' do
|
64
|
+
let(:rack_env) { { 'env_entry' => 0 } }
|
65
|
+
|
66
|
+
it 'should resolve :link_if in the context of the mapper' do
|
67
|
+
expect(render_as_link?).to be false
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'with an Undefined href' do
|
72
|
+
let(:href) { Yaks::Undefined }
|
41
73
|
|
42
|
-
|
74
|
+
it 'should return falsey' do
|
75
|
+
expect(render_as_link?).to be_falsey
|
43
76
|
end
|
44
77
|
end
|
45
78
|
|
46
|
-
|
79
|
+
context 'with an Undefined link_if' do
|
80
|
+
let(:link_if) { Yaks::Undefined }
|
47
81
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
82
|
+
it 'should return falsey' do
|
83
|
+
expect(render_as_link?).to be_falsey
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe '#map_rel' do
|
89
|
+
let(:association_rel) { association.map_rel(policy) }
|
90
|
+
|
91
|
+
context 'with a rel specified' do
|
92
|
+
let(:rel) { 'http://api.com/rels/shoes' }
|
53
93
|
|
54
|
-
|
94
|
+
it 'should use the specified rel' do
|
95
|
+
expect(association_rel).to eql 'http://api.com/rels/shoes'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'without a rel specified' do
|
100
|
+
before do
|
101
|
+
stub(policy).derive_rel_from_association(association) {
|
102
|
+
'http://api.com/rel/derived'
|
103
|
+
}
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should infer a rel based on policy' do
|
107
|
+
expect(association_rel).to eql 'http://api.com/rel/derived'
|
108
|
+
end
|
55
109
|
end
|
56
110
|
end
|
57
111
|
|
58
|
-
describe '#
|
112
|
+
describe '#resolve_association_mapper' do
|
59
113
|
context 'with a specified mapper' do
|
60
114
|
let(:mapper) { :a_specific_mapper_class }
|
61
115
|
|
62
116
|
it 'should return the mapper' do
|
63
|
-
expect(association.
|
117
|
+
expect(association.resolve_association_mapper(nil)).to equal :a_specific_mapper_class
|
64
118
|
end
|
65
119
|
end
|
66
120
|
|
67
121
|
context 'with the mapper undefined' do
|
68
122
|
let(:mapper) { Yaks::Undefined }
|
69
123
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
124
|
+
before do
|
125
|
+
stub(policy).derive_mapper_from_association(association) {
|
126
|
+
:a_derived_mapper_class
|
127
|
+
}
|
128
|
+
end
|
75
129
|
|
76
|
-
|
130
|
+
it 'should derive a mapper based on policy' do
|
131
|
+
expect(association.resolve_association_mapper(policy)).to equal :a_derived_mapper_class
|
77
132
|
end
|
78
133
|
end
|
79
134
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Yaks::Mapper::Attribute do
|
4
|
+
include_context 'yaks context'
|
5
|
+
|
6
|
+
subject(:attribute) { described_class.new(:the_name) }
|
7
|
+
fake(:mapper)
|
8
|
+
|
9
|
+
its(:name) { should be :the_name }
|
10
|
+
|
11
|
+
before do
|
12
|
+
stub(mapper).load_attribute(:the_name) { 123 }
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should add itself to a resource based on a lookup' do
|
16
|
+
expect(attribute.add_to_resource(Yaks::Resource.new, mapper , yaks_context)).to eql(
|
17
|
+
Yaks::Resource.new(attributes: { :the_name => 123 })
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
@@ -1,28 +1,67 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe Yaks::Mapper::ClassMethods do
|
4
|
-
subject
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
subject(:mapper_class) do
|
5
|
+
Class.new do
|
6
|
+
extend Yaks::Mapper::ClassMethods
|
7
|
+
attributes :foo, :bar
|
8
|
+
link :some_rel, 'http://some_link'
|
9
|
+
has_one :thing
|
10
|
+
has_many :thingies
|
9
11
|
end
|
12
|
+
end
|
10
13
|
|
14
|
+
describe 'attributes' do
|
11
15
|
it 'should allow setting them' do
|
12
|
-
expect(
|
16
|
+
expect( mapper_class.attributes ).to eq [
|
17
|
+
Yaks::Mapper::Attribute.new(:foo),
|
18
|
+
Yaks::Mapper::Attribute.new(:bar)
|
19
|
+
]
|
13
20
|
end
|
14
21
|
|
15
22
|
describe 'with inheritance' do
|
16
|
-
let(:
|
17
|
-
|
23
|
+
let(:child_class) do
|
24
|
+
Class.new(mapper_class) do
|
25
|
+
attributes :baz
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
let(:grandchild_class) do
|
30
|
+
Class.new(child_class)
|
31
|
+
end
|
18
32
|
|
19
33
|
it 'should inherit attributes from the parent' do
|
20
|
-
expect(
|
34
|
+
expect(child_class.attributes).to eq [
|
35
|
+
Yaks::Mapper::Attribute.new(:foo),
|
36
|
+
Yaks::Mapper::Attribute.new(:bar),
|
37
|
+
Yaks::Mapper::Attribute.new(:baz)
|
38
|
+
]
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should create a valid config' do
|
42
|
+
expect(grandchild_class.config).to be_a Yaks::Mapper::Config
|
21
43
|
end
|
22
44
|
|
23
45
|
it 'should not alter the parent' do
|
24
|
-
expect(
|
46
|
+
expect(mapper_class.attributes).to eq [
|
47
|
+
Yaks::Mapper::Attribute.new(:foo),
|
48
|
+
Yaks::Mapper::Attribute.new(:bar),
|
49
|
+
]
|
25
50
|
end
|
26
51
|
end
|
27
52
|
end
|
53
|
+
|
54
|
+
it 'should register links' do
|
55
|
+
expect(mapper_class.config.links).to eq [
|
56
|
+
Yaks::Mapper::Link.new(:some_rel, 'http://some_link', {})
|
57
|
+
]
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should register associations' do
|
61
|
+
expect(mapper_class.config.associations).to eq [
|
62
|
+
Yaks::Mapper::HasOne.new(name: :thing),
|
63
|
+
Yaks::Mapper::HasMany.new(name: :thingies)
|
64
|
+
]
|
65
|
+
end
|
66
|
+
|
28
67
|
end
|