yaks 0.4.2 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
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