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
data/lib/yaks/resource.rb CHANGED
@@ -1,11 +1,12 @@
1
1
  module Yaks
2
2
  class Resource
3
3
  include Equalizer.new(:type, :links, :attributes, :subresources)
4
+ include FP::HashUpdatable.new(:type, :links, :attributes, :subresources)
4
5
  include Enumerable
5
6
 
6
7
  attr_reader :type, :attributes, :links, :subresources
7
8
 
8
- def initialize(options)
9
+ def initialize(options = {})
9
10
  @type = options.fetch(:type, nil)
10
11
  @attributes = options.fetch(:attributes, {})
11
12
  @links = options.fetch(:links, [])
@@ -16,16 +17,13 @@ module Yaks
16
17
  attributes[attr]
17
18
  end
18
19
 
19
- # def type
20
- # end
21
-
22
20
  def each
23
21
  return to_enum unless block_given?
24
22
  yield self
25
23
  end
26
24
 
27
25
  def self_link
28
- links.find do |link|
26
+ links.reverse.find do |link|
29
27
  link.rel.equal? :self
30
28
  end
31
29
  end
@@ -37,5 +35,17 @@ module Yaks
37
35
  def null_resource?
38
36
  false
39
37
  end
38
+
39
+ def update_attributes(new_attrs)
40
+ update(attributes: @attributes.merge(new_attrs))
41
+ end
42
+
43
+ def add_link(link)
44
+ update(links: @links + [link])
45
+ end
46
+
47
+ def add_subresource(rel, subresource)
48
+ update(subresources: @subresources.merge(rel => subresource))
49
+ end
40
50
  end
41
51
  end
data/lib/yaks/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Yaks
2
- VERSION = '0.4.2'
2
+ VERSION = '0.4.3'
3
3
  end
data/lib/yaks.rb CHANGED
@@ -11,19 +11,21 @@ require 'rack/accept'
11
11
 
12
12
  require 'yaks/util'
13
13
  require 'yaks/fp'
14
+ require 'yaks/fp/updatable'
15
+ require 'yaks/fp/hash_updatable'
14
16
  require 'yaks/primitivize'
15
17
 
16
18
  require 'yaks/default_policy'
17
19
 
18
20
  module Yaks
21
+ # A PORO
19
22
  Undefined = Object.new
23
+ # Set the Root constant as the gems root path
20
24
  Root = Pathname(__FILE__).join('../..')
21
25
 
22
- YAKS_DEFAULT_OPTIONS = {
23
- singular_links: [:self, :profile]
24
- }
25
-
26
26
  class << self
27
+ # @param [Proc] blk
28
+ # @return [Yaks::Config]
27
29
  def new(&blk)
28
30
  Yaks::Config.new(&blk)
29
31
  end
@@ -37,17 +39,21 @@ require 'yaks/null_resource'
37
39
  require 'yaks/resource/link'
38
40
  require 'yaks/collection_resource'
39
41
 
42
+ require 'yaks/mapper/class_methods'
43
+ require 'yaks/mapper'
44
+ require 'yaks/mapper/attribute'
40
45
  require 'yaks/mapper/link'
41
46
  require 'yaks/mapper/association'
47
+ require 'yaks/mapper/association_mapper'
42
48
  require 'yaks/mapper/has_one'
43
49
  require 'yaks/mapper/has_many'
44
50
  require 'yaks/mapper/config'
45
- require 'yaks/mapper/class_methods'
46
- require 'yaks/mapper'
47
51
  require 'yaks/collection_mapper'
48
52
 
49
- require 'yaks/serializer'
50
- require 'yaks/serializer/hal'
51
- require 'yaks/serializer/json_api'
52
- require 'yaks/serializer/collection_json'
53
+ require 'yaks/format'
54
+ require 'yaks/format/hal'
55
+ require 'yaks/format/json_api'
56
+ require 'yaks/format/collection_json'
57
+
58
+ require 'yaks/config/dsl'
53
59
  require 'yaks/config'
@@ -1,23 +1,17 @@
1
1
  require 'spec_helper'
2
2
 
3
- require_relative './models'
3
+ require 'acceptance/models'
4
+ require 'acceptance/json_shared_examples'
4
5
 
5
- RSpec.shared_examples_for 'JSON output format' do |yaks, format, name|
6
- let(:input) { load_yaml_fixture(name) }
7
- let(:output) { load_json_fixture("#{name}.#{format}") }
8
-
9
- subject { yaks.serialize(input) }
10
-
11
- it { should deep_eql output }
12
- end
13
-
14
- RSpec.describe Yaks::Serializer::Hal do
6
+ RSpec.describe Yaks::Format::Hal do
15
7
  yaks_rel_template = Yaks.new do
8
+ format_options :hal, plural_links: ['http://literature.example.com/rels/quotes']
16
9
  rel_template "http://literature.example.com/rel/{association_name}"
17
10
  end
18
11
 
19
12
  yaks_policy_dsl = Yaks.new do
20
- derive_rel_from_association do |mapper, association|
13
+ format_options :hal, plural_links: ['http://literature.example.com/rels/quotes']
14
+ derive_rel_from_association do |association|
21
15
  "http://literature.example.com/rel/#{association.name}"
22
16
  end
23
17
  end
@@ -26,7 +20,7 @@ RSpec.describe Yaks::Serializer::Hal do
26
20
  include_examples 'JSON output format' , yaks_policy_dsl , :hal , 'confucius'
27
21
  end
28
22
 
29
- RSpec.describe Yaks::Serializer::JsonApi do
23
+ RSpec.describe Yaks::Format::JsonApi do
30
24
  config = Yaks.new do
31
25
  default_format :json_api
32
26
  end
@@ -34,11 +28,16 @@ RSpec.describe Yaks::Serializer::JsonApi do
34
28
  include_examples 'JSON output format' , config , :json_api , 'confucius'
35
29
  end
36
30
 
37
- RSpec.describe Yaks::Serializer::CollectionJson do
38
- config = Yaks.new do
31
+ RSpec.describe Yaks::Format::CollectionJson do
32
+ youtypeit_yaks = Yaks.new do
33
+ default_format :collection_json
34
+ namespace Youtypeitwepostit
35
+ end
36
+
37
+ confucius_yaks = Yaks.new do
39
38
  default_format :collection_json
40
- mapper_namespace Youtypeitwepostit
41
39
  end
42
40
 
43
- include_examples 'JSON output format' , config , :collection , 'youtypeitwepostit'
41
+ include_examples 'JSON output format', youtypeit_yaks, :collection, 'youtypeitwepostit'
42
+ include_examples 'JSON output format', confucius_yaks, :collection, 'confucius'
44
43
  end
@@ -0,0 +1,8 @@
1
+ RSpec.shared_examples_for 'JSON output format' do |yaks, format, name|
2
+ let(:input) { load_yaml_fixture(name) }
3
+ let(:output) { load_json_fixture("#{name}.#{format}") }
4
+
5
+ subject { yaks.serialize(input) }
6
+
7
+ it { should deep_eql output }
8
+ end
@@ -17,7 +17,7 @@ class Era
17
17
  end
18
18
 
19
19
  class LiteratureBaseMapper < Yaks::Mapper
20
- link :profile, 'http://literature.example.com/profiles/{mapper_name}'
20
+ link :profile, 'http://literature.example.com/profiles/{mapper_name}', expand: true
21
21
  link :self, 'http://literature.example.com/{mapper_name}/{id}'
22
22
  end
23
23
 
@@ -25,7 +25,7 @@ class ScholarMapper < LiteratureBaseMapper
25
25
  attributes :id, :name, :pinyin, :latinized
26
26
  has_many :works
27
27
 
28
- link 'http://literature.example.com/rels/quotes', 'http://literature.example.com/quotes/?author={downcased_pinyin}&q={query}', expand: [:downcased_pinyin]
28
+ link 'http://literature.example.com/rels/quotes', 'http://literature.example.com/quotes/?author={downcased_pinyin}&q={query}', expand: [:downcased_pinyin], title: 'Search for quotes'
29
29
  link :self, 'http://literature.example.com/authors/{downcased_pinyin}'
30
30
 
31
31
  def downcased_pinyin
@@ -14,14 +14,14 @@ RSpec.describe 'Mapping domain models to Resource objects' do
14
14
 
15
15
  its(:subresources) {
16
16
  should eq(
17
- "rel:src=friend&dest=pet_peeve" => Yaks::Resource.new(type:'pet_peeve', attributes: {id: 4, type: 'parsing with regexps'}),
18
- "rel:src=friend&dest=pets" => Yaks::CollectionResource.new(
17
+ "rel:pet_peeve" => Yaks::Resource.new(type:'pet_peeve', attributes: {id: 4, type: 'parsing with regexps'}),
18
+ "rel:pets" => Yaks::CollectionResource.new(
19
19
  type: 'pet',
20
20
  members: [
21
21
  Yaks::Resource.new(type: 'pet', attributes: {:id => 2, :species => "dog", :name => "boingboing"}),
22
22
  Yaks::Resource.new(type: 'pet', attributes: {:id => 3, :species => "cat", :name => "wassup"})
23
23
  ],
24
- members_rel: 'rel:src=collection&dest=pets'
24
+ collection_rel: 'rel:pets'
25
25
  )
26
26
  )
27
27
  }
@@ -0,0 +1,39 @@
1
+ {
2
+ "collection": {
3
+ "version": "1.0",
4
+ "href": "http://literature.example.com/authors/kongzi",
5
+ "items": [
6
+ {
7
+ "href": "http://literature.example.com/authors/kongzi",
8
+ "data": [
9
+ {
10
+ "name": "id",
11
+ "value": 9
12
+ },
13
+ {
14
+ "name": "name",
15
+ "value": "孔子"
16
+ },
17
+ {
18
+ "name": "pinyin",
19
+ "value": "Kongzi"
20
+ },
21
+ {
22
+ "name": "latinized",
23
+ "value": "Confucius"
24
+ }
25
+ ],
26
+ "links": [
27
+ {
28
+ "rel": "profile",
29
+ "href": "http://literature.example.com/profiles/scholar"
30
+ },
31
+ {
32
+ "rel": "http://literature.example.com/rels/quotes",
33
+ "href": "http://literature.example.com/quotes/?author=kongzi&q={query}"
34
+ }
35
+ ]
36
+ }
37
+ ]
38
+ }
39
+ }
@@ -6,10 +6,13 @@
6
6
  "_links": {
7
7
  "self": { "href": "http://literature.example.com/authors/kongzi" },
8
8
  "profile": { "href": "http://literature.example.com/profiles/scholar" },
9
- "http://literature.example.com/rels/quotes": {
10
- "href": "http://literature.example.com/quotes/?author=kongzi&q={query}",
11
- "templated": true
12
- }
9
+ "http://literature.example.com/rels/quotes": [
10
+ {
11
+ "href": "http://literature.example.com/quotes/?author=kongzi&q={query}",
12
+ "templated": true,
13
+ "title": "Search for quotes"
14
+ }
15
+ ]
13
16
  },
14
17
  "_embedded": {
15
18
  "http://literature.example.com/rel/works": [
@@ -2,7 +2,7 @@
2
2
  "scholars": [
3
3
  {
4
4
  "id": 9,
5
- "href": "http://literature.example.com/scholar/9",
5
+ "href": "http://literature.example.com/authors/kongzi",
6
6
  "name": "孔子",
7
7
  "pinyin": "Kongzi",
8
8
  "latinized": "Confucius",
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'rspec/its'
2
+ require 'bogus/rspec'
2
3
 
3
4
  require 'yaks'
4
5
  require 'virtus'
@@ -13,6 +14,7 @@ require_relative 'support/fixtures'
13
14
  require_relative 'support/shared_contexts'
14
15
  require_relative 'support/youtypeit_models_mappers'
15
16
  require_relative 'support/deep_eql'
17
+ require_relative 'support/classes_for_policy_testing'
16
18
 
17
19
 
18
20
  RSpec.configure do |rspec|
@@ -21,3 +23,7 @@ RSpec.configure do |rspec|
21
23
  #rspec.disable_monkey_patching!
22
24
  rspec.raise_errors_for_deprecations!
23
25
  end
26
+
27
+ Bogus.configure do |bogus|
28
+ bogus.search_modules << Yaks
29
+ end
@@ -0,0 +1,36 @@
1
+ # Used by Yaks::DefaultPolicy* tests to test various name inference schemes
2
+
3
+ class SoyMapper ; end
4
+ class Soy ; end
5
+ class Wheat ; end
6
+
7
+ module MyMappers
8
+ class SoyMapper ; end
9
+ end
10
+
11
+ class SoyCollectionMapper ; end
12
+
13
+ module Namespace
14
+ module Nested
15
+ class Rye ; end
16
+ end
17
+
18
+ class RyeMapper ; end
19
+ class RyeCollectionMapper ; end
20
+
21
+ class CollectionMapper ; end
22
+
23
+ class ShoeMapper ; end
24
+ end
25
+
26
+ module DislikesCollectionMapper
27
+ def self.const_get(const)
28
+ raise "not a NameError" if const.to_s == 'CollectionMapper'
29
+ end
30
+ end
31
+
32
+ module DislikesOtherMappers
33
+ def self.const_get(const)
34
+ raise "not a NameError" if const.to_s != 'CollectionMapper'
35
+ end
36
+ end
@@ -3,7 +3,7 @@ RSpec.shared_context 'collection resource' do
3
3
  Yaks::CollectionResource.new(
4
4
  links: links,
5
5
  members: members,
6
- members_rel: 'http://api.example.com/rels/plants'
6
+ collection_rel: 'http://api.example.com/rels/plants'
7
7
  )
8
8
  end
9
9
  let(:links) { [] }
@@ -7,14 +7,15 @@ RSpec.describe Yaks::CollectionMapper do
7
7
  let(:mapper_class) { described_class }
8
8
 
9
9
  let(:context) {
10
- { member_mapper: member_mapper,
10
+ { item_mapper: item_mapper,
11
11
  policy: policy,
12
12
  env: {},
13
13
  mapper_stack: []
14
14
  }
15
15
  }
16
+
16
17
  let(:collection) { [] }
17
- let(:member_mapper) { Class.new(Yaks::Mapper) { type 'the_type' } }
18
+ let(:item_mapper) { Class.new(Yaks::Mapper) { type 'the_type' } }
18
19
  let(:policy) { Yaks::DefaultPolicy.new }
19
20
 
20
21
  it 'should map the collection' do
@@ -23,13 +24,13 @@ RSpec.describe Yaks::CollectionMapper do
23
24
  links: [],
24
25
  attributes: {},
25
26
  members: [],
26
- members_rel: 'rel:src=collection&dest=the_types'
27
+ collection_rel: 'rel:the_types'
27
28
  )
28
29
  end
29
30
 
30
31
  context 'with members' do
31
32
  let(:collection) { [boingboing, wassup]}
32
- let(:member_mapper) { PetMapper }
33
+ let(:item_mapper) { PetMapper }
33
34
 
34
35
  it 'should map the members' do
35
36
  expect(mapper.call(collection)).to eql Yaks::CollectionResource.new(
@@ -40,7 +41,31 @@ RSpec.describe Yaks::CollectionMapper do
40
41
  Yaks::Resource.new(type: 'pet', attributes: {:id => 2, :species => "dog", :name => "boingboing"}),
41
42
  Yaks::Resource.new(type: 'pet', attributes: {:id => 3, :species => "cat", :name => "wassup"})
42
43
  ],
43
- members_rel: 'rel:src=collection&dest=pets'
44
+ collection_rel: 'rel:pets'
45
+ )
46
+ end
47
+ end
48
+
49
+ context 'without an item_mapper in the context' do
50
+ let(:context) {
51
+ {
52
+ policy: policy,
53
+ env: {},
54
+ mapper_stack: []
55
+ }
56
+ }
57
+ let(:collection) { [boingboing, wassup]}
58
+
59
+ it 'should infer the item mapper' do
60
+ expect(mapper.call(collection)).to eql Yaks::CollectionResource.new(
61
+ type: nil,
62
+ links: [],
63
+ attributes: {},
64
+ members: [
65
+ Yaks::Resource.new(type: 'pet', attributes: {:id => 2, :species => "dog", :name => "boingboing"}),
66
+ Yaks::Resource.new(type: 'pet', attributes: {:id => 3, :species => "cat", :name => "wassup"})
67
+ ],
68
+ collection_rel: 'collection'
44
69
  )
45
70
  end
46
71
  end
@@ -65,7 +90,7 @@ RSpec.describe Yaks::CollectionMapper do
65
90
  links: [],
66
91
  attributes: { foo: 123, bar: 'pi la~~~' },
67
92
  members: [],
68
- members_rel: 'rel:src=collection&dest=the_types'
93
+ collection_rel: 'rel:the_types'
69
94
  )
70
95
  end
71
96
  end
@@ -83,7 +108,7 @@ RSpec.describe Yaks::CollectionMapper do
83
108
  links: [ Yaks::Resource::Link.new(:self, 'http://api.example.com/orders', {}) ],
84
109
  attributes: { },
85
110
  members: [],
86
- members_rel: 'rel:src=collection&dest=the_types'
111
+ collection_rel: 'rel:the_types'
87
112
  )
88
113
  end
89
114
  end
@@ -100,7 +125,7 @@ RSpec.describe Yaks::CollectionMapper do
100
125
  end
101
126
 
102
127
  let(:collection) { [boingboing, wassup]}
103
- let(:member_mapper) { PetMapper }
128
+ let(:item_mapper) { PetMapper }
104
129
 
105
130
  it 'should use the redefined collection method' do
106
131
  expect(mapper.call(collection)).to eql Yaks::CollectionResource.new(
@@ -110,7 +135,7 @@ RSpec.describe Yaks::CollectionMapper do
110
135
  members: [
111
136
  Yaks::Resource.new(type: 'pet', attributes: {:id => 3, :species => "cat", :name => "wassup"})
112
137
  ],
113
- members_rel: 'rel:src=collection&dest=pets'
138
+ collection_rel: 'rel:pets'
114
139
  )
115
140
  end
116
141
  end
@@ -13,7 +13,7 @@ RSpec.describe Yaks::CollectionResource do
13
13
  its(:attributes) { should eql({}) }
14
14
  its(:members) { should eql [] }
15
15
  its(:subresources) { should eql({}) }
16
- its(:members_rel) { should eql('members') }
16
+ its(:collection_rel) { should eql('members') }
17
17
  end
18
18
 
19
19
  context 'with a full constructor' do
@@ -32,7 +32,7 @@ RSpec.describe Yaks::CollectionResource do
32
32
  attributes: { customer: 'John Doe', price: 10.00 }
33
33
  )
34
34
  ],
35
- members_rel: 'http://api.example.org/rels/orders'
35
+ collection_rel: 'http://api.example.org/rels/orders'
36
36
  }
37
37
  }
38
38
 
@@ -51,7 +51,7 @@ RSpec.describe Yaks::CollectionResource do
51
51
  )
52
52
  ]
53
53
  }
54
- its(:members_rel) { should eq 'http://api.example.org/rels/orders'}
54
+ its(:collection_rel) { should eq 'http://api.example.org/rels/orders'}
55
55
 
56
56
  its(:subresources) { should eql(
57
57
  'http://api.example.org/rels/orders' => Yaks::CollectionResource.new(
@@ -68,7 +68,7 @@ RSpec.describe Yaks::CollectionResource do
68
68
  attributes: { customer: 'John Doe', price: 10.00 }
69
69
  )
70
70
  ],
71
- members_rel: 'http://api.example.org/rels/orders'
71
+ collection_rel: 'http://api.example.org/rels/orders'
72
72
  )
73
73
  )
74
74
  }
@@ -0,0 +1,91 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Yaks::Config::DSL do
4
+ subject!(:dsl) { described_class.new(yaks_config, &config_block) }
5
+
6
+ let(:yaks_config) { Yaks::Config.new }
7
+ let(:config_block) { nil }
8
+
9
+ def self.configure(&blk)
10
+ let(:config_block) { blk }
11
+ end
12
+
13
+ describe '#initialize' do
14
+ its(:config) { should equal yaks_config }
15
+
16
+ it 'should set a default policy' do
17
+ expect(yaks_config.policy_class.new).to be_a_kind_of Yaks::DefaultPolicy
18
+ end
19
+
20
+ it 'should execute the given block in instance scope' do
21
+ dsl = described_class.new(yaks_config) do
22
+ @config = :foo
23
+ end
24
+ expect(dsl.config).to be :foo
25
+ end
26
+
27
+ describe 'policy redefinitions' do
28
+ configure do
29
+ derive_type_from_mapper_class do |mapper_class|
30
+ :inside_redefined_policy_method
31
+ end
32
+ end
33
+
34
+ it 'should delegate and redefine' do
35
+ expect(yaks_config.policy.derive_type_from_mapper_class(nil)).to be :inside_redefined_policy_method
36
+ end
37
+
38
+ it 'should not change the original class definition' do
39
+ expect(Yaks::DefaultPolicy.new.derive_type_from_mapper_class(fake(name: 'FooMapper'))).to eql 'foo'
40
+ end
41
+ end
42
+ end
43
+
44
+ describe '#format_options' do
45
+ configure { format_options :hal, singular_link: [:self] }
46
+ specify { expect(yaks_config.format_options[:hal].should eq(singular_link: [:self])) }
47
+ end
48
+
49
+ describe '#default_format' do
50
+ configure { default_format :json_api }
51
+ specify { expect(yaks_config.default_format).to be :json_api }
52
+ end
53
+
54
+ describe '#policy' do
55
+ configure { policy 'MyPolicyClass' }
56
+ specify { expect(yaks_config.policy_class).to eql 'MyPolicyClass' }
57
+ end
58
+
59
+ describe '#rel_template' do
60
+ configure { rel_template 'rels:{rel}' }
61
+ specify { expect(yaks_config.policy_options[:rel_template]).to eql 'rels:{rel}' }
62
+ end
63
+
64
+ describe '#mapper_namespace' do
65
+ configure { mapper_namespace RSpec }
66
+ specify { expect(yaks_config.policy_options[:namespace]).to eql RSpec }
67
+ end
68
+
69
+ describe '#map_to_primitive' do
70
+ Foo = Class.new do
71
+ attr_reader :foo
72
+
73
+ def initialize(foo)
74
+ @foo = foo
75
+ end
76
+ end
77
+
78
+ configure { map_to_primitive(Foo) {|c| c.foo } }
79
+ specify { expect(yaks_config.primitivize.call({:abc => Foo.new('hello')})).to eql 'abc' => 'hello' }
80
+ end
81
+
82
+ describe '#after' do
83
+ configure do
84
+ after {|x| x + 1}
85
+ after {|x| x + 10}
86
+ end
87
+ it 'should register the block' do
88
+ expect(yaks_config.steps.inject(0) {|memo, step| step.call(memo)}).to be 11
89
+ end
90
+ end
91
+ end
@@ -56,7 +56,7 @@ RSpec.describe Yaks::Config do
56
56
 
57
57
  describe '#serialize' do
58
58
  configure do
59
- rel_template 'http://api.mysuperfriends.com/{dest}'
59
+ rel_template 'http://api.mysuperfriends.com/{rel}'
60
60
  format_options :hal, plural_links: [:copyright]
61
61
  end
62
62
 
@@ -102,7 +102,7 @@ RSpec.describe Yaks::Config do
102
102
  end
103
103
  end
104
104
 
105
- context 'passing in a rack env' do
105
+ describe '#format_class' do
106
106
  configure do
107
107
  default_format :collection_json
108
108
  end
@@ -111,19 +111,23 @@ RSpec.describe Yaks::Config do
111
111
  { 'HTTP_ACCEPT' => 'application/hal+json;q=0.8, application/vnd.api+json' }
112
112
  }
113
113
 
114
- it 'should detect serializer based on accept header' do
114
+ it 'should fall back to the default when no HTTP_ACCEPT key is present' do
115
+ expect(config.format_class({}, {})).to equal Yaks::Format::CollectionJson
116
+ end
117
+
118
+ it 'should detect format based on accept header' do
115
119
  rack_env = { 'HTTP_ACCEPT' => 'application/hal+json;q=0.8, application/vnd.api+json' }
116
- expect(config.serializer_class({}, rack_env)).to equal Yaks::Serializer::JsonApi
120
+ expect(config.format_class({}, rack_env)).to equal Yaks::Format::JsonApi
117
121
  end
118
122
 
119
123
  it 'should know to pick the best match' do
120
124
  rack_env = { 'HTTP_ACCEPT' => 'application/hal+json;q=0.8, application/vnd.api+json;q=0.7' }
121
- expect(config.serializer_class({}, rack_env)).to equal Yaks::Serializer::Hal
125
+ expect(config.format_class({}, rack_env)).to equal Yaks::Format::Hal
122
126
  end
123
127
 
124
128
  it 'should fall back to the default when no mime type is recognized' do
125
129
  rack_env = { 'HTTP_ACCEPT' => 'text/html, application/json' }
126
- expect(config.serializer_class({}, rack_env)).to equal Yaks::Serializer::CollectionJson
130
+ expect(config.format_class({}, rack_env)).to equal Yaks::Format::CollectionJson
127
131
  end
128
132
  end
129
133
  end