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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +65 -5
  4. data/README.md +38 -8
  5. data/Rakefile +33 -0
  6. data/lib/yaks/breaking_changes.rb +22 -0
  7. data/lib/yaks/collection_mapper.rb +18 -21
  8. data/lib/yaks/collection_resource.rb +19 -5
  9. data/lib/yaks/config/dsl.rb +78 -0
  10. data/lib/yaks/config.rb +37 -63
  11. data/lib/yaks/default_policy.rb +27 -9
  12. data/lib/yaks/{serializer → format}/collection_json.rb +7 -3
  13. data/lib/yaks/{serializer → format}/hal.rb +14 -4
  14. data/lib/yaks/{serializer → format}/json_api.rb +22 -4
  15. data/lib/yaks/{serializer.rb → format.rb} +5 -5
  16. data/lib/yaks/fp/hash_updatable.rb +17 -0
  17. data/lib/yaks/fp/updatable.rb +15 -0
  18. data/lib/yaks/mapper/association.rb +24 -21
  19. data/lib/yaks/mapper/association_mapper.rb +42 -0
  20. data/lib/yaks/mapper/attribute.rb +17 -0
  21. data/lib/yaks/mapper/class_methods.rb +0 -1
  22. data/lib/yaks/mapper/config.rb +8 -28
  23. data/lib/yaks/mapper/has_many.rb +8 -3
  24. data/lib/yaks/mapper/has_one.rb +1 -1
  25. data/lib/yaks/mapper/link.rb +13 -13
  26. data/lib/yaks/mapper.rb +28 -32
  27. data/lib/yaks/null_resource.rb +1 -0
  28. data/lib/yaks/resource.rb +15 -5
  29. data/lib/yaks/version.rb +1 -1
  30. data/lib/yaks.rb +16 -10
  31. data/spec/acceptance/acceptance_spec.rb +16 -17
  32. data/spec/acceptance/json_shared_examples.rb +8 -0
  33. data/spec/acceptance/models.rb +2 -2
  34. data/spec/integration/map_to_resource_spec.rb +3 -3
  35. data/spec/json/confucius.collection.json +39 -0
  36. data/spec/json/confucius.hal.json +7 -4
  37. data/spec/json/confucius.json_api.json +1 -1
  38. data/spec/spec_helper.rb +6 -0
  39. data/spec/support/classes_for_policy_testing.rb +36 -0
  40. data/spec/support/shared_contexts.rb +1 -1
  41. data/spec/unit/yaks/collection_mapper_spec.rb +34 -9
  42. data/spec/unit/yaks/collection_resource_spec.rb +4 -4
  43. data/spec/unit/yaks/config/dsl_spec.rb +91 -0
  44. data/spec/unit/yaks/config_spec.rb +10 -6
  45. data/spec/unit/yaks/default_policy/derive_mapper_from_object_spec.rb +80 -0
  46. data/spec/unit/yaks/default_policy_spec.rb +50 -0
  47. data/spec/unit/yaks/{serializer → format}/hal_spec.rb +1 -1
  48. data/spec/unit/yaks/format/json_api_spec.rb +42 -0
  49. data/spec/unit/yaks/format_spec.rb +12 -0
  50. data/spec/unit/yaks/fp/hash_updatable_spec.rb +22 -0
  51. data/spec/unit/yaks/fp/updatable_spec.rb +22 -0
  52. data/spec/unit/yaks/mapper/association_mapper_spec.rb +60 -0
  53. data/spec/unit/yaks/mapper/association_spec.rb +96 -41
  54. data/spec/unit/yaks/mapper/attribute_spec.rb +20 -0
  55. data/spec/unit/yaks/mapper/class_methods_spec.rb +49 -10
  56. data/spec/unit/yaks/mapper/config_spec.rb +25 -50
  57. data/spec/unit/yaks/mapper/has_many_spec.rb +33 -5
  58. data/spec/unit/yaks/mapper/has_one_spec.rb +32 -17
  59. data/spec/unit/yaks/mapper/link_spec.rb +44 -12
  60. data/spec/unit/yaks/mapper_spec.rb +45 -17
  61. data/spec/unit/yaks/resource_spec.rb +41 -7
  62. data/yaks.gemspec +7 -1
  63. metadata +72 -21
  64. data/examples/hal01.rb +0 -126
  65. data/examples/jsonapi01.rb +0 -68
  66. data/examples/jsonapi02.rb +0 -62
  67. data/examples/jsonapi03.rb +0 -86
  68. data/spec/support/serializers.rb +0 -14
  69. 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
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- RSpec.describe Yaks::Serializer::Hal do
3
+ RSpec.describe Yaks::Format::Hal do
4
4
  include_context 'plant collection resource'
5
5
 
6
6
  subject { Yaks::Primitivize.create.call(described_class.new.call(resource)) }
@@ -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
- include Yaks::FP
4
+ include_context 'yaks context'
5
5
 
6
- let(:name) { :shoes }
7
- let(:mapper) { Yaks::Mapper }
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(:collection_mapper) { Yaks::Undefined }
10
- let(:parent_mapper) { Yaks::Undefined }
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) { should equal :shoes }
22
+ its(:name) { should equal :shoes }
23
+ its(:child_mapper) { should equal Yaks::Mapper }
17
24
 
18
- subject(:association) do
19
- described_class.new(name, mapper, rel, collection_mapper)
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
- describe '#create_subresource' do
23
- subject(:resource_pair) do
24
- association.create_subresource(parent_mapper, lookup, context)
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
- context 'with a rel specified' do
28
- let(:rel) { 'http://api.com/rels/shoes' }
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
- it 'should use the specified rel' do
31
- expect(resource_pair[0]).to eql 'http://api.com/rels/shoes'
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 'without a rel specified' do
36
- it 'should infer a rel based on policy' do
37
- expect(policy)
38
- .to receive(:derive_rel_from_association)
39
- .with(parent_mapper, association)
40
- .and_return('http://api.com/rel/derived')
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
- expect(resource_pair[0]).to eql 'http://api.com/rel/derived'
74
+ it 'should return falsey' do
75
+ expect(render_as_link?).to be_falsey
43
76
  end
44
77
  end
45
78
 
46
- let(:lookup) { { shoes: 'unmapped resource' } }
79
+ context 'with an Undefined link_if' do
80
+ let(:link_if) { Yaks::Undefined }
47
81
 
48
- it 'should delegate to the map_resource method, to be overridden in child classes' do
49
- expect(association)
50
- .to receive(:map_resource)
51
- .with('unmapped resource', context)
52
- .and_return('mapped resource')
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
- expect(resource_pair[1]).to eql 'mapped resource'
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 '#association_mapper' do
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.association_mapper(nil)).to equal :a_specific_mapper_class
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
- it 'should derive a mapper based on policy' do
71
- expect(policy)
72
- .to receive(:derive_mapper_from_association)
73
- .with(association)
74
- .and_return(:a_derived_mapper_class)
124
+ before do
125
+ stub(policy).derive_mapper_from_association(association) {
126
+ :a_derived_mapper_class
127
+ }
128
+ end
75
129
 
76
- expect(association.association_mapper(policy)).to equal :a_derived_mapper_class
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 { Class.new { extend Yaks::Mapper::ClassMethods } }
5
-
6
- describe 'attributes' do
7
- before do
8
- subject.attributes(:foo, :bar)
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( subject.attributes ).to eq [:foo, :bar]
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(:child) { Class.new(subject) }
17
- before { child.attributes(:baz) }
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(child.attributes).to eq [:foo, :bar, :baz]
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(subject.attributes).to eq [:foo, :bar]
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