yaks 0.6.0.alpha.1 → 0.6.0

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 (65) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +46 -0
  3. data/lib/yaks/attributes.rb +45 -0
  4. data/lib/yaks/collection_resource.rb +1 -45
  5. data/lib/yaks/config/dsl.rb +15 -6
  6. data/lib/yaks/config.rb +1 -1
  7. data/lib/yaks/configurable.rb +20 -0
  8. data/lib/yaks/default_policy.rb +0 -8
  9. data/lib/yaks/errors.rb +3 -0
  10. data/lib/yaks/format/hal.rb +13 -2
  11. data/lib/yaks/format/halo.rb +29 -0
  12. data/lib/yaks/mapper/association.rb +18 -13
  13. data/lib/yaks/mapper/association_mapper.rb +1 -1
  14. data/lib/yaks/mapper/attribute.rb +1 -3
  15. data/lib/yaks/mapper/class_methods.rb +24 -16
  16. data/lib/yaks/mapper/config.rb +13 -28
  17. data/lib/yaks/mapper/control.rb +38 -0
  18. data/lib/yaks/mapper/has_many.rb +4 -8
  19. data/lib/yaks/mapper/link.rb +10 -2
  20. data/lib/yaks/mapper.rb +11 -2
  21. data/lib/yaks/resource/control.rb +11 -0
  22. data/lib/yaks/resource/link.rb +1 -7
  23. data/lib/yaks/resource.rb +9 -13
  24. data/lib/yaks/runner.rb +2 -4
  25. data/lib/yaks/serializer.rb +12 -0
  26. data/lib/yaks/stateful_builder.rb +54 -0
  27. data/lib/yaks/version.rb +1 -1
  28. data/lib/yaks.rb +16 -7
  29. data/spec/acceptance/acceptance_spec.rb +14 -4
  30. data/spec/acceptance/models.rb +9 -0
  31. data/spec/integration/map_to_resource_spec.rb +1 -1
  32. data/spec/json/confucius.halo.json +80 -0
  33. data/spec/spec_helper.rb +5 -0
  34. data/spec/support/shared_contexts.rb +1 -1
  35. data/spec/unit/yaks/attributes_spec.rb +65 -0
  36. data/spec/unit/yaks/collection_mapper_spec.rb +1 -1
  37. data/spec/unit/yaks/collection_resource_spec.rb +7 -25
  38. data/spec/unit/yaks/config/dsl_spec.rb +5 -0
  39. data/spec/unit/yaks/config_spec.rb +2 -1
  40. data/spec/unit/yaks/configurable_spec.rb +25 -0
  41. data/spec/unit/yaks/default_policy_spec.rb +1 -7
  42. data/spec/unit/yaks/format/collection_json_spec.rb +1 -1
  43. data/spec/unit/yaks/format/hal_spec.rb +2 -2
  44. data/spec/unit/yaks/format/html_spec.rb +5 -0
  45. data/spec/unit/yaks/format/json_api_spec.rb +1 -1
  46. data/spec/unit/yaks/format_spec.rb +1 -5
  47. data/spec/unit/yaks/mapper/association_mapper_spec.rb +2 -2
  48. data/spec/unit/yaks/mapper/association_spec.rb +27 -3
  49. data/spec/unit/yaks/mapper/class_methods_spec.rb +17 -1
  50. data/spec/unit/yaks/mapper/config_spec.rb +16 -8
  51. data/spec/unit/yaks/mapper/has_many_spec.rb +15 -2
  52. data/spec/unit/yaks/mapper/has_one_spec.rb +1 -1
  53. data/spec/unit/yaks/mapper/link_spec.rb +12 -2
  54. data/spec/unit/yaks/mapper_spec.rb +51 -22
  55. data/spec/unit/yaks/resource/link_spec.rb +2 -1
  56. data/spec/unit/yaks/resource_spec.rb +16 -9
  57. data/spec/unit/yaks/runner_spec.rb +22 -2
  58. data/spec/unit/yaks/serializer_spec.rb +20 -0
  59. data/spec/unit/yaks/stateful_builder_spec.rb +41 -0
  60. data/yaks.gemspec +1 -0
  61. metadata +39 -11
  62. data/lib/yaks/fp/hash_updatable.rb +0 -19
  63. data/lib/yaks/fp/updatable.rb +0 -17
  64. data/spec/unit/yaks/fp/hash_updatable_spec.rb +0 -22
  65. data/spec/unit/yaks/fp/updatable_spec.rb +0 -22
data/lib/yaks/runner.rb CHANGED
@@ -56,7 +56,7 @@ module Yaks
56
56
 
57
57
  def primitivizer
58
58
  ->(input) do
59
- if format_class.serializer == :json
59
+ if format_class.serializer.equal? :json
60
60
  primitivize.call(input)
61
61
  else
62
62
  input
@@ -73,9 +73,7 @@ module Yaks
73
73
  memoize :format_name
74
74
 
75
75
  def serializer
76
- serializers.fetch(format_class.serializer) do
77
- policy.serializer_for_format(format_class)
78
- end
76
+ serializers.fetch(format_class.serializer)
79
77
  end
80
78
  memoize :serializer
81
79
 
@@ -0,0 +1,12 @@
1
+ module Yaks
2
+ module Serializer
3
+ def self.register(format, serializer)
4
+ raise "Serializer for #{format} already registered" if all.key? format
5
+ all[format] = serializer
6
+ end
7
+
8
+ def self.all
9
+ @serializers ||= {json: JSON.method(:pretty_generate)}
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,54 @@
1
+ module Yaks
2
+ # State monad-ish thing.
3
+ #
4
+ # Generate a DSL syntax for immutable classes.
5
+ #
6
+ # @example
7
+ #
8
+ # # This code
9
+ # Control.create(:search)
10
+ # .method("POST")
11
+ # .href("/search")
12
+ #
13
+ # # Can be written as
14
+ # StatefulBuilder.new(Control, [:method, :href]).create(:search) do
15
+ # method "POST"
16
+ # href "/search"
17
+ # end
18
+ #
19
+ class StatefulBuilder < BasicObject
20
+ def create(*args, &block)
21
+ @state = @klass.create(*args)
22
+ instance_eval(&block)
23
+ @state
24
+ end
25
+
26
+ def initialize(klass, methods)
27
+ @klass = klass
28
+ StatefulMethods.new(methods).send(:extend_object, self)
29
+ end
30
+
31
+ def validate_state(method_name, args)
32
+ unless @state.instance_of?(@klass)
33
+ ::Kernel.raise(
34
+ IllegalState,
35
+ "#{@klass}##{method_name}(#{args.map(&:inspect).join(', ')}) "\
36
+ "returned #{@state.inspect}. Expected instance of #{@klass}"
37
+ )
38
+ end
39
+ end
40
+
41
+ class StatefulMethods < ::Module
42
+ def initialize(methods)
43
+ methods.each { |name| define_stateful_method(name) }
44
+ end
45
+
46
+ def define_stateful_method(method_name)
47
+ define_method method_name do |*args, &block|
48
+ @state = @state.public_send(method_name, *args, &block)
49
+ validate_state(method_name, args)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
data/lib/yaks/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Yaks
2
- VERSION = '0.6.0.alpha.1'
2
+ VERSION = '0.6.0'
3
3
  end
data/lib/yaks.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  require 'forwardable'
4
4
  require 'set'
5
5
  require 'pathname'
6
+ require 'json'
6
7
 
7
8
  require 'anima'
8
9
  require 'concord'
@@ -11,11 +12,13 @@ require 'uri_template'
11
12
  require 'rack/accept'
12
13
 
13
14
  require 'yaks/util'
15
+ require 'yaks/configurable'
14
16
  require 'yaks/fp'
15
- require 'yaks/fp/updatable'
16
- require 'yaks/fp/hash_updatable'
17
17
  require 'yaks/fp/callable'
18
18
  require 'yaks/primitivize'
19
+ require 'yaks/attributes'
20
+ require 'yaks/stateful_builder'
21
+ require 'yaks/errors'
19
22
 
20
23
  require 'yaks/default_policy'
21
24
 
@@ -41,19 +44,25 @@ require 'yaks/null_resource'
41
44
  require 'yaks/resource/link'
42
45
  require 'yaks/collection_resource'
43
46
 
44
- require 'yaks/mapper/class_methods'
45
- require 'yaks/mapper'
46
- require 'yaks/mapper/attribute'
47
- require 'yaks/mapper/link'
48
47
  require 'yaks/mapper/association'
49
- require 'yaks/mapper/association_mapper'
50
48
  require 'yaks/mapper/has_one'
51
49
  require 'yaks/mapper/has_many'
50
+ require 'yaks/mapper/attribute'
51
+ require 'yaks/mapper/link'
52
+ require 'yaks/mapper/control'
52
53
  require 'yaks/mapper/config'
54
+ require 'yaks/mapper/class_methods'
55
+ require 'yaks/mapper'
56
+ require 'yaks/mapper/association_mapper'
53
57
  require 'yaks/collection_mapper'
54
58
 
59
+ require 'yaks/resource/control'
60
+
61
+ require 'yaks/serializer'
62
+
55
63
  require 'yaks/format'
56
64
  require 'yaks/format/hal'
65
+ require 'yaks/format/halo'
57
66
  require 'yaks/format/json_api'
58
67
  require 'yaks/format/collection_json'
59
68
 
@@ -6,7 +6,7 @@ require 'acceptance/json_shared_examples'
6
6
  RSpec.describe Yaks::Format::Hal do
7
7
  yaks_rel_template = Yaks.new do
8
8
  format_options :hal, plural_links: ['http://literature.example.com/rels/quotes']
9
- rel_template "http://literature.example.com/rel/{association_name}"
9
+ rel_template "http://literature.example.com/rel/{rel}"
10
10
  skip :serialize
11
11
  end
12
12
 
@@ -18,8 +18,18 @@ RSpec.describe Yaks::Format::Hal do
18
18
  skip :serialize
19
19
  end
20
20
 
21
- include_examples 'JSON output format' , yaks_rel_template , :hal , 'confucius'
22
- include_examples 'JSON output format' , yaks_policy_dsl , :hal , 'confucius'
21
+ include_examples 'JSON output format', yaks_rel_template, :hal, 'confucius'
22
+ include_examples 'JSON output format', yaks_policy_dsl, :hal, 'confucius'
23
+ end
24
+
25
+ RSpec.describe Yaks::Format::Halo do
26
+ yaks = Yaks.new do
27
+ default_format :halo
28
+ rel_template "http://literature.example.com/rel/{rel}"
29
+ skip :serialize
30
+ end
31
+
32
+ include_examples 'JSON output format', yaks, :halo, 'confucius'
23
33
  end
24
34
 
25
35
  RSpec.describe Yaks::Format::JsonAPI do
@@ -28,7 +38,7 @@ RSpec.describe Yaks::Format::JsonAPI do
28
38
  skip :serialize
29
39
  end
30
40
 
31
- include_examples 'JSON output format' , config , :json_api , 'confucius'
41
+ include_examples 'JSON output format', config, :json_api, 'confucius'
32
42
  end
33
43
 
34
44
  RSpec.describe Yaks::Format::CollectionJson do
@@ -28,6 +28,15 @@ class ScholarMapper < LiteratureBaseMapper
28
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
+ control :search do
32
+ title 'Find a Scholar'
33
+ method 'POST'
34
+ media_type 'application/x-www-form-urlencoded'
35
+
36
+ field :name, label: 'Scholar Name', type: 'text'
37
+ field :pinyin, label: 'Hanyu Pinyin', type: 'text'
38
+ end
39
+
31
40
  def downcased_pinyin
32
41
  object.pinyin.downcase
33
42
  end
@@ -10,7 +10,7 @@ RSpec.describe 'Mapping domain models to Resource objects' do
10
10
  it { should be_a Yaks::Resource }
11
11
  its(:type) { should eql 'friend' }
12
12
  its(:attributes) { should eql(id: 1, name: 'john') }
13
- its(:links) { should eql [ Yaks::Resource::Link.new(:copyright, '/api/copyright/2024', {}) ] }
13
+ its(:links) { should eql [ Yaks::Resource::Link.new(rel: :copyright, uri: '/api/copyright/2024') ] }
14
14
 
15
15
  its(:subresources) {
16
16
  should eq(
@@ -0,0 +1,80 @@
1
+ {
2
+ "id": 9,
3
+ "name": "孔子",
4
+ "pinyin": "Kongzi",
5
+ "latinized": "Confucius",
6
+ "_links": {
7
+ "self": { "href": "http://literature.example.com/authors/kongzi" },
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
+ "title": "Search for quotes"
13
+ }
14
+ },
15
+ "_embedded": {
16
+ "http://literature.example.com/rel/works": [
17
+ {
18
+ "id": 11,
19
+ "chinese_name": "論語",
20
+ "english_name": "Analects",
21
+ "_links": {
22
+ "self": { "href": "http://literature.example.com/work/11" },
23
+ "profile": { "href": "http://literature.example.com/profiles/work" }
24
+ },
25
+ "_embedded": {
26
+ "http://literature.example.com/rel/quotes": [
27
+ {
28
+ "id": 17,
29
+ "chinese": "廄焚。子退朝,曰:“傷人乎?” 不問馬。"
30
+ },
31
+ {
32
+ "id": 18,
33
+ "chinese": "子曰:“其恕乎!己所不欲、勿施於人。”"
34
+ }
35
+ ],
36
+ "http://literature.example.com/rel/era": {
37
+ "id": 99,
38
+ "name": "Zhou Dynasty"
39
+ }
40
+ }
41
+ },
42
+ {
43
+ "id": 12,
44
+ "chinese_name": "易經",
45
+ "english_name": "Commentaries to the Yi-jing",
46
+ "_links": {
47
+ "self": { "href": "http://literature.example.com/work/12" },
48
+ "profile": { "href": "http://literature.example.com/profiles/work" }
49
+ },
50
+ "_embedded": {
51
+ "http://literature.example.com/rel/quotes": [],
52
+ "http://literature.example.com/rel/era": null
53
+ }
54
+ }
55
+ ]
56
+ },
57
+ "_controls": {
58
+ "search": {
59
+ "name": "search",
60
+ "href": null,
61
+ "title": "Find a Scholar",
62
+ "method": "POST",
63
+ "media_type": "application/x-www-form-urlencoded",
64
+ "fields": [
65
+ {
66
+ "name": "name",
67
+ "label": "Scholar Name",
68
+ "type": "text",
69
+ "value": null
70
+ },
71
+ {
72
+ "name": "pinyin",
73
+ "label": "Hanyu Pinyin",
74
+ "type": "text",
75
+ "value": null
76
+ }
77
+ ]
78
+ }
79
+ }
80
+ }
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  require 'rspec/its'
2
2
  require 'bogus/rspec'
3
+ require 'timeout'
3
4
 
4
5
  require 'yaks'
6
+ require 'yaks-html'
5
7
  require 'virtus'
6
8
 
7
9
  require 'fixture_helpers'
@@ -22,6 +24,9 @@ RSpec.configure do |rspec|
22
24
  rspec.backtrace_exclusion_patterns = [] if ENV['FULLSTACK']
23
25
  rspec.disable_monkey_patching!
24
26
  rspec.raise_errors_for_deprecations!
27
+ rspec.around(:each) do |example|
28
+ Timeout.timeout(1, &example)
29
+ end
25
30
  end
26
31
 
27
32
  Bogus.configure do |bogus|
@@ -31,7 +31,7 @@ RSpec.shared_context 'plant collection resource' do
31
31
  [ :oak , :self , 'http://api.example.com/plants/15/oak' ],
32
32
  [ :passiflora , :self , 'http://api.example.com/plants/33/passiflora' ],
33
33
  ].each do |name, type, uri|
34
- let(:"#{name}_#{type}_link") { Yaks::Resource::Link.new(type, uri, {}) }
34
+ let(:"#{name}_#{type}_link") { Yaks::Resource::Link.new(rel: type, uri: uri) }
35
35
  end
36
36
 
37
37
  let(:plain_grass) do
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Yaks::Attributes do
4
+ subject { Class.new { include Yaks::Attributes.new(:foo, bar: 3) } }
5
+
6
+ it 'should have a hash-based constructor' do
7
+ expect(subject.new(foo: 3, bar: 4).bar).to equal 4
8
+ end
9
+
10
+ it 'should have defaults constructor' do
11
+ expect(subject.new(foo: 3).bar).to equal 3
12
+ end
13
+
14
+ it 'should allow updating through attribute methods' do
15
+ expect(subject.new(foo: 3).foo(4).to_h).to eql(foo: 4, bar: 3)
16
+ end
17
+
18
+ it 'should add an #append_to method' do
19
+ expect(subject.new(foo: [6]).append_to(:foo, 7, 8).foo).to eql [6, 7, 8]
20
+ end
21
+
22
+ context 'with all defaults' do
23
+ subject { Class.new { include Yaks::Attributes.new(foo: 5, bar: 3) } }
24
+
25
+ it 'should be able to construct without arguments' do
26
+ expect(subject.new.to_h).to eql(foo: 5, bar: 3)
27
+ end
28
+ end
29
+
30
+ context 'without any defaults' do
31
+ subject { Class.new { include Yaks::Attributes.new(:foo, :bar) } }
32
+
33
+ it 'should allow setting all attributes' do
34
+ expect(subject.new(foo: 5, bar: 6).bar).to equal 6
35
+ end
36
+
37
+ it 'should expect all attributes' do
38
+ expect { subject.new(foo: 5) }.to raise_exception
39
+ end
40
+ end
41
+
42
+ context 'when extending' do
43
+ subject { Class.new(super()) { include attributes.add(baz: 7) } }
44
+
45
+ it 'should make the new attributes available' do
46
+ expect(subject.new(foo: 3, baz: 6).baz).to equal 6
47
+ end
48
+
49
+ it 'should make the old attributes available' do
50
+ expect(subject.new(foo: 3, baz: 6).foo).to equal 3
51
+ end
52
+
53
+ context 'without any defaults' do
54
+ subject { Class.new(super()) { include attributes.add(:bax) } }
55
+
56
+ it 'should allow setting all attributes' do
57
+ expect(subject.new(foo: 5, bar: 6, bax: 7).bax).to equal 7
58
+ end
59
+
60
+ it 'should expect all attributes' do
61
+ expect { subject.new(foo: 5, bar: 6) }.to raise_exception
62
+ end
63
+ end
64
+ end
65
+ end
@@ -108,7 +108,7 @@ RSpec.describe Yaks::CollectionMapper do
108
108
  it 'should map the links' do
109
109
  expect(mapper.call(collection)).to eql Yaks::CollectionResource.new(
110
110
  type: 'the_type',
111
- links: [ Yaks::Resource::Link.new(:self, 'http://api.example.com/orders', {}) ],
111
+ links: [ Yaks::Resource::Link.new(rel: :self, uri: 'http://api.example.com/orders') ],
112
112
  attributes: { },
113
113
  members: [],
114
114
  collection_rel: 'rel:the_types'
@@ -21,14 +21,14 @@ RSpec.describe Yaks::CollectionResource do
21
21
  {
22
22
  type: 'order',
23
23
  links: [
24
- Yaks::Resource::Link.new('http://rels/summary', 'http://order/10/summary', {}),
25
- Yaks::Resource::Link.new(:profile, 'http://rels/collection', {})
24
+ Yaks::Resource::Link.new(rel: 'http://rels/summary', uri: 'http://order/10/summary'),
25
+ Yaks::Resource::Link.new(rel: :profile, uri: 'http://rels/collection')
26
26
  ],
27
27
  attributes: { total: 10.00 },
28
28
  members: [
29
29
  Yaks::Resource.new(
30
30
  type: 'order',
31
- links: [Yaks::Resource::Link.new(:self, 'http://order/10', {})],
31
+ links: [Yaks::Resource::Link.new(rel: :self, uri: 'http://order/10')],
32
32
  attributes: { customer: 'John Doe', price: 10.00 }
33
33
  )
34
34
  ],
@@ -38,40 +38,22 @@ RSpec.describe Yaks::CollectionResource do
38
38
 
39
39
  its(:type) { should eql 'order' }
40
40
  its(:links) { should eql [
41
- Yaks::Resource::Link.new('http://rels/summary', 'http://order/10/summary', {}),
42
- Yaks::Resource::Link.new(:profile, 'http://rels/collection', {})
41
+ Yaks::Resource::Link.new(rel: 'http://rels/summary', uri: 'http://order/10/summary'),
42
+ Yaks::Resource::Link.new(rel: :profile, uri: 'http://rels/collection')
43
43
  ]
44
44
  }
45
45
  its(:attributes) { should eql( total: 10.00 ) }
46
46
  its(:members) { should eql [
47
47
  Yaks::Resource.new(
48
48
  type: 'order',
49
- links: [Yaks::Resource::Link.new(:self, 'http://order/10', {})],
49
+ links: [Yaks::Resource::Link.new(rel: :self, uri: 'http://order/10')],
50
50
  attributes: { customer: 'John Doe', price: 10.00 }
51
51
  )
52
52
  ]
53
53
  }
54
54
  its(:collection_rel) { should eq 'http://api.example.org/rels/orders'}
55
55
 
56
- its(:subresources) { should eql(
57
- 'http://api.example.org/rels/orders' => Yaks::CollectionResource.new(
58
- type: 'order',
59
- attributes: { total: 10.00 },
60
- links: [
61
- Yaks::Resource::Link.new('http://rels/summary', 'http://order/10/summary', {}),
62
- Yaks::Resource::Link.new(:profile, 'http://rels/collection', {})
63
- ],
64
- members: [
65
- Yaks::Resource.new(
66
- type: 'order',
67
- links: [Yaks::Resource::Link.new(:self, 'http://order/10', {})],
68
- attributes: { customer: 'John Doe', price: 10.00 }
69
- )
70
- ],
71
- collection_rel: 'http://api.example.org/rels/orders'
72
- )
73
- )
74
- }
56
+ its(:subresources) { should eql({}) }
75
57
 
76
58
  end
77
59
  end
@@ -61,6 +61,11 @@ RSpec.describe Yaks::Config::DSL do
61
61
  specify { expect(yaks_config.policy_options[:rel_template]).to eql 'rels:{rel}' }
62
62
  end
63
63
 
64
+ describe '#serializer' do
65
+ configure { serializer(:json) { |i| "foo #{i}" } }
66
+ specify { expect(yaks_config.serializers[:json].call(7)).to eql 'foo 7' }
67
+ end
68
+
64
69
  describe '#json_serializer' do
65
70
  configure { json_serializer { |i| "foo #{i}" } }
66
71
  specify { expect(yaks_config.serializers[:json].call(7)).to eql 'foo 7' }
@@ -14,7 +14,8 @@ RSpec.describe Yaks::Config do
14
14
  its(:default_format) { should equal :hal }
15
15
  its(:policy_class) { should < Yaks::DefaultPolicy }
16
16
  its(:primitivize) { should be_a Yaks::Primitivize }
17
- its(:serializers) { should eql({}) }
17
+ its(:serializers) { should eql(Yaks::Serializer.all) }
18
+ its(:serializers) { should_not equal(Yaks::Serializer.all) }
18
19
  its(:hooks) { should eql([]) }
19
20
 
20
21
  it 'should have empty format options' do
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Yaks::Configurable do
4
+ class Creatable
5
+ def self.create(*args, &block)
6
+ ["->", *args, block.call]
7
+ end
8
+ end
9
+
10
+ subject do
11
+ Class.new do
12
+ include Yaks::Attributes.new(foo: []), Yaks::Configurable
13
+
14
+ config_method :bar, append_to: :foo, create: Creatable
15
+ end
16
+ end
17
+
18
+ it 'should generate the config method' do
19
+ expect(
20
+ subject.new.bar(1,2,3) { 4 }
21
+ .bar(:baz) { :booz }
22
+ .foo
23
+ ).to eql [["->", 1, 2, 3, 4], ["->", :baz, :booz]]
24
+ end
25
+ end
@@ -4,7 +4,7 @@ RSpec.describe Yaks::DefaultPolicy do
4
4
  subject(:policy) { described_class.new( options ) }
5
5
 
6
6
  let(:options) { {} }
7
- let(:association) { Yaks::Mapper::HasMany.new(name: 'shoes', collectionMapper: nil) }
7
+ let(:association) { Yaks::Mapper::HasMany.create('shoes') }
8
8
 
9
9
  describe '#initialize' do
10
10
  it 'should work without arguments' do
@@ -61,10 +61,4 @@ RSpec.describe Yaks::DefaultPolicy do
61
61
  end
62
62
  end
63
63
 
64
- describe '#serializer_for_format' do
65
- specify {
66
- expect(policy.serializer_for_format(Yaks::Format::JsonAPI).call('foo' => [1,2])).to eql "{\n \"foo\": [\n 1,\n 2\n ]\n}"
67
- }
68
- end
69
-
70
64
  end
@@ -13,7 +13,7 @@ RSpec.describe Yaks::Format::CollectionJson do
13
13
  let(:resource) {
14
14
  Yaks::Resource.new(
15
15
  attributes: {foo: 'fooval', bar: 'barval'},
16
- links: [Yaks::Resource::Link.new('the_rel', 'the_uri', {})]
16
+ links: [Yaks::Resource::Link.new(rel: 'the_rel', uri: 'the_uri')]
17
17
  )
18
18
  }
19
19
 
@@ -18,8 +18,8 @@ RSpec.describe Yaks::Format::Hal do
18
18
  Yaks::Resource.new(
19
19
  attributes: {foo: 'fooval', bar: 'barval'},
20
20
  links: [
21
- Yaks::Resource::Link.new('my_plural_rel', 'the_uri1', {}),
22
- Yaks::Resource::Link.new('my_plural_rel', 'the_uri2', {})
21
+ Yaks::Resource::Link.new(rel: 'my_plural_rel', uri: 'the_uri1'),
22
+ Yaks::Resource::Link.new(rel: 'my_plural_rel', uri: 'the_uri2')
23
23
  ]
24
24
  )
25
25
  }
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ # RSpec.describe Yaks::Format::HTML do
4
+
5
+ # end
@@ -22,7 +22,7 @@ RSpec.describe Yaks::Format::JsonAPI do
22
22
  href: '/the/href'
23
23
  },
24
24
  links: [
25
- Yaks::Resource::Link.new(:self, '/the/self/link', {})
25
+ Yaks::Resource::Link.new(rel: :self, uri: '/the/self/link')
26
26
  ]
27
27
  )
28
28
  }
@@ -27,11 +27,7 @@ RSpec.describe Yaks::Format do
27
27
 
28
28
  describe '.mime_types' do
29
29
  specify do
30
- expect(Yaks::Format.mime_types).to eql(
31
- collection_json: "application/vnd.collection+json",
32
- hal: "application/hal+json",
33
- json_api: "application/vnd.api+json"
34
- )
30
+ expect(Yaks::Format.mime_types.values_at(:collection_json, :hal, :json_api)).to eql(["application/vnd.collection+json", "application/hal+json", "application/vnd.api+json"])
35
31
  end
36
32
  end
37
33
  end
@@ -26,8 +26,8 @@ RSpec.describe Yaks::Mapper::AssociationMapper do
26
26
  expect(association_mapper.call(Yaks::Resource.new)).to eql Yaks::Resource.new(
27
27
  links: [
28
28
  Yaks::Resource::Link.new(
29
- 'rels:the_rel',
30
- 'http://this/is_where_the_associated_thing_can_be_found', {}
29
+ rel: 'rels:the_rel',
30
+ uri: 'http://this/is_where_the_associated_thing_can_be_found'
31
31
  )
32
32
  ]
33
33
  )
@@ -6,7 +6,7 @@ RSpec.describe Yaks::Mapper::Association do
6
6
  subject(:association) do
7
7
  described_class.new(
8
8
  name: name,
9
- mapper: mapper,
9
+ item_mapper: mapper,
10
10
  rel: rel,
11
11
  href: href,
12
12
  link_if: link_if
@@ -20,13 +20,13 @@ RSpec.describe Yaks::Mapper::Association do
20
20
  let(:link_if) { Yaks::Undefined }
21
21
 
22
22
  its(:name) { should equal :shoes }
23
- its(:child_mapper) { should equal Yaks::Mapper }
23
+ its(:item_mapper) { should equal Yaks::Mapper }
24
24
 
25
25
  context 'with a minimal constructor' do
26
26
  subject(:association) { described_class.new(name: :foo) }
27
27
 
28
28
  its(:name) { should be :foo }
29
- its(:child_mapper) { should be Yaks::Undefined }
29
+ its(:item_mapper) { should be Yaks::Undefined }
30
30
  its(:rel) { should be Yaks::Undefined }
31
31
  its(:href) { should be Yaks::Undefined }
32
32
  its(:link_if) { should be Yaks::Undefined }
@@ -132,4 +132,28 @@ RSpec.describe Yaks::Mapper::Association do
132
132
  end
133
133
  end
134
134
  end
135
+
136
+ describe '.create' do
137
+ it 'should take a name' do
138
+ expect(described_class.create(:foo).name).to be :foo
139
+ end
140
+
141
+ it 'should optionally take a mapper' do
142
+ expect(described_class.create(:foo, mapper: :bar).item_mapper).to be :bar
143
+ end
144
+
145
+ it 'should take other options' do
146
+ expect(described_class.create(:foo, mapper: :bar, href: 'xxx').href).to eql 'xxx'
147
+ end
148
+
149
+ it 'should respect attribute defaults' do
150
+ expect(described_class.create(:foo, href: 'xxx').item_mapper).to be Yaks::Undefined
151
+ end
152
+
153
+ it 'should not munge the options hash' do
154
+ opts = {mapper: :foo}
155
+ described_class.create(:foo, opts)
156
+ expect(opts).to eql(mapper: :foo)
157
+ end
158
+ end
135
159
  end