yaks 0.6.0.alpha.1 → 0.6.0

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