yaks 0.7.6 → 0.7.7

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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +17 -0
  3. data/Rakefile +58 -38
  4. data/lib/yaks.rb +3 -4
  5. data/lib/yaks/attributes.rb +23 -10
  6. data/lib/yaks/config.rb +4 -0
  7. data/lib/yaks/configurable.rb +16 -21
  8. data/lib/yaks/format.rb +1 -1
  9. data/lib/yaks/format/collection_json.rb +9 -0
  10. data/lib/yaks/format/halo.rb +16 -13
  11. data/lib/yaks/html5_forms.rb +22 -1
  12. data/lib/yaks/mapper.rb +5 -5
  13. data/lib/yaks/mapper/attribute.rb +1 -1
  14. data/lib/yaks/mapper/class_methods.rb +3 -1
  15. data/lib/yaks/mapper/config.rb +9 -16
  16. data/lib/yaks/mapper/form.rb +41 -0
  17. data/lib/yaks/mapper/form/field.rb +62 -0
  18. data/lib/yaks/null_resource.rb +1 -1
  19. data/lib/yaks/resource.rb +7 -3
  20. data/lib/yaks/resource/form.rb +31 -0
  21. data/lib/yaks/runner.rb +11 -11
  22. data/lib/yaks/stateful_builder.rb +11 -7
  23. data/lib/yaks/util.rb +3 -2
  24. data/lib/yaks/version.rb +1 -1
  25. data/spec/acceptance/models.rb +1 -1
  26. data/spec/json/confucius.halo.json +2 -4
  27. data/spec/json/plant_collection.collection.json +4 -0
  28. data/spec/unit/yaks/attributes_spec.rb +79 -0
  29. data/spec/unit/yaks/configurable_spec.rb +32 -2
  30. data/spec/unit/yaks/format/collection_json_spec.rb +59 -27
  31. data/spec/unit/yaks/format/halo_spec.rb +3 -0
  32. data/spec/unit/yaks/mapper/{control → form}/field_spec.rb +3 -3
  33. data/spec/unit/yaks/mapper/{control_spec.rb → form_spec.rb} +12 -12
  34. data/spec/unit/yaks/mapper_spec.rb +10 -10
  35. data/spec/unit/yaks/null_resource_spec.rb +50 -7
  36. data/spec/unit/yaks/resource_spec.rb +4 -4
  37. data/spec/unit/yaks/runner_spec.rb +38 -2
  38. data/spec/unit/yaks/util_spec.rb +42 -0
  39. metadata +20 -58
  40. data/lib/yaks/mapper/control.rb +0 -82
  41. data/lib/yaks/resource/control.rb +0 -11
@@ -9,9 +9,11 @@ RSpec.describe Yaks::Configurable do
9
9
 
10
10
  subject do
11
11
  Class.new do
12
- include Yaks::Attributes.new(foo: []), Yaks::Configurable
12
+ extend Yaks::Configurable
13
+ include Yaks::Attributes.new(foo: [])
13
14
 
14
15
  config_method :bar, append_to: :foo, create: Creatable
16
+ config_method :baz, append_to: :foo, create: Creatable, defaults: {bar: 'baz'}
15
17
  end
16
18
  end
17
19
 
@@ -20,6 +22,34 @@ RSpec.describe Yaks::Configurable do
20
22
  subject.new.bar(1,2,3) { 4 }
21
23
  .bar(:baz) { :booz }
22
24
  .foo
23
- ).to eql [["->", 1, 2, 3, 4], ["->", :baz, :booz]]
25
+ ).to eql [["->", 1, 2, 3, {}, 4], ["->", :baz, {}, :booz]]
26
+ end
27
+
28
+ it 'should allow setting defaults' do
29
+ expect(
30
+ subject.new.baz(1,2,3, foo: 'bar') { 4 }
31
+ .foo
32
+ ).to eql [["->", 1, 2, 3, {foo: 'bar', bar: 'baz'}, 4]]
33
+ end
34
+
35
+ it 'should allow overriding defaults' do
36
+ expect(
37
+ subject.new.baz(1,2,3, bar: 'qux') { 4 }
38
+ .foo
39
+ ).to eql [["->", 1, 2, 3, {bar: 'qux'}, 4]]
40
+ end
41
+
42
+ it 'should be able to take an already instantiated object of the right type' do
43
+ instance = Creatable.new
44
+ expect(
45
+ subject.new.bar(instance).foo
46
+ ).to eql [instance]
47
+ end
48
+
49
+ it 'should only take the instance verbatim if it is the only argument' do
50
+ instance = Creatable.new
51
+ expect(
52
+ subject.new.bar(instance, 1) {}.foo
53
+ ).to eql [["->", instance, 1, {}, nil]]
24
54
  end
25
55
  end
@@ -9,33 +9,65 @@ RSpec.describe Yaks::Format::CollectionJson do
9
9
  it { should deep_eql(load_json_fixture('plant_collection.collection')) }
10
10
  end
11
11
 
12
- context 'with a link without title' do
13
- let(:resource) {
14
- Yaks::Resource.new(
15
- attributes: {foo: 'fooval', bar: 'barval'},
16
- links: [Yaks::Resource::Link.new(rel: 'the_rel', uri: 'the_uri')]
17
- )
18
- }
19
-
20
- subject {
21
- Yaks::Primitivize.create.call(described_class.new.call(resource))
22
- }
23
-
24
- it 'should not render a name' do
25
- should deep_eql(
26
- "collection" => {
27
- "version" => "1.0",
28
- "items" => [
29
- {
30
- "data" => [
31
- { "name"=>"foo", "value"=>"fooval" },
32
- { "name"=>"bar", "value"=>"barval" }
33
- ],
34
- "links" => [{"rel"=>"the_rel", "href"=>"the_uri"}]
35
- }
36
- ]
37
- }
38
- )
12
+ context 'link' do
13
+ context 'without title' do
14
+ let(:resource) {
15
+ Yaks::Resource.new(
16
+ attributes: {foo: 'fooval', bar: 'barval'},
17
+ links: [Yaks::Resource::Link.new(rel: 'the_rel', uri: 'the_uri')]
18
+ )
19
+ }
20
+
21
+ subject {
22
+ Yaks::Primitivize.create.call(described_class.new.call(resource))
23
+ }
24
+
25
+ it 'should not render a name' do
26
+ should deep_eql(
27
+ "collection" => {
28
+ "version" => "1.0",
29
+ "items" => [
30
+ {
31
+ "data" => [
32
+ { "name"=>"foo", "value"=>"fooval" },
33
+ { "name"=>"bar", "value"=>"barval" }
34
+ ],
35
+ "links" => [{"rel"=>"the_rel", "href"=>"the_uri"}]
36
+ }
37
+ ]
38
+ }
39
+ )
40
+ end
41
+ end
42
+
43
+ context 'with a title' do
44
+ let(:resource) {
45
+ Yaks::Resource.new(
46
+ attributes: {foo: 'fooval', bar: 'barval'},
47
+ links: [Yaks::Resource::Link.new(options: {title: 'the_name'}, rel: 'the_rel', uri: 'the_uri')]
48
+ )
49
+ }
50
+
51
+ subject {
52
+ Yaks::Primitivize.create.call(described_class.new.call(resource))
53
+ }
54
+
55
+ it 'should render a name' do
56
+ should deep_eql(
57
+ "collection" => {
58
+ "version" => "1.0",
59
+ "items" => [
60
+ {
61
+ "data" => [
62
+ { "name"=>"foo", "value"=>"fooval" },
63
+ { "name"=>"bar", "value"=>"barval" }
64
+ ],
65
+ "links" => [{"name"=>"the_name", "rel"=>"the_rel", "href"=>"the_uri"}]
66
+ }
67
+ ]
68
+ }
69
+ )
70
+ end
39
71
  end
40
72
  end
41
73
  end
@@ -0,0 +1,3 @@
1
+
2
+ RSpec.describe Yaks::Format::Halo do
3
+ end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- RSpec.describe Yaks::Mapper::Control::Field do
3
+ RSpec.describe Yaks::Mapper::Form::Field do
4
4
  include_context 'yaks context'
5
5
 
6
6
  let(:field) { described_class.new( full_args ) }
@@ -31,8 +31,8 @@ RSpec.describe Yaks::Mapper::Control::Field do
31
31
  end
32
32
 
33
33
  describe '#to_resource_field' do
34
- it 'creates a Yaks::Resource::Control::Field with the same attributes' do
35
- expect(field.to_resource(mapper)).to eql Yaks::Resource::Control::Field.new(full_args)
34
+ it 'creates a Yaks::Resource::Form::Field with the same attributes' do
35
+ expect(field.to_resource(mapper)).to eql Yaks::Resource::Form::Field.new(full_args)
36
36
  end
37
37
  end
38
38
  end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
- RSpec.describe Yaks::Mapper::Control do
4
- let(:control) { described_class.new( full_args ) }
3
+ RSpec.describe Yaks::Mapper::Form do
4
+ let(:form) { described_class.new( full_args ) }
5
5
  let(:name) { :the_name }
6
6
  let(:full_args) { {name: name}.merge(args) }
7
7
  let(:args) {
@@ -18,7 +18,7 @@ RSpec.describe Yaks::Mapper::Control do
18
18
  describe '.create' do
19
19
  it 'should create an instance, first arg is the name' do
20
20
 
21
- expect( described_class.create(name, args) ).to eql control
21
+ expect( described_class.create(name, args) ).to eql form
22
22
  end
23
23
 
24
24
  it 'should have a name of nil when ommitted' do
@@ -27,20 +27,20 @@ RSpec.describe Yaks::Mapper::Control do
27
27
  end
28
28
 
29
29
  describe '#add_to_resource' do
30
- let(:resource) { control.add_to_resource(Yaks::Resource.new, Yaks::Mapper.new(nil), nil) }
30
+ let(:resource) { form.add_to_resource(Yaks::Resource.new, Yaks::Mapper.new(nil), nil) }
31
31
 
32
- it 'should add a control to the resource' do
33
- expect(resource.controls.length).to be 1
32
+ it 'should add a form to the resource' do
33
+ expect(resource.forms.length).to be 1
34
34
  end
35
35
 
36
- it 'should create a Yaks::Resource::Control with corresponding fields' do
37
- expect(resource.controls.first).to eql Yaks::Resource::Control.new( full_args )
36
+ it 'should create a Yaks::Resource::Form with corresponding fields' do
37
+ expect(resource.forms.first).to eql Yaks::Resource::Form.new( full_args )
38
38
  end
39
39
 
40
40
  context 'with fields' do
41
41
  let(:fields) {
42
42
  [
43
- Yaks::Mapper::Control::Field.new(
43
+ Yaks::Mapper::Form::Field.new(
44
44
  name: 'field name',
45
45
  label: 'field label',
46
46
  type: 'text',
@@ -49,9 +49,9 @@ RSpec.describe Yaks::Mapper::Control do
49
49
  ]
50
50
  }
51
51
 
52
- it 'should map to Yaks::Resource::Control::Field instances' do
53
- expect(resource.controls.first.fields).to eql [
54
- Yaks::Resource::Control::Field.new(
52
+ it 'should map to Yaks::Resource::Form::Field instances' do
53
+ expect(resource.forms.first.fields).to eql [
54
+ Yaks::Resource::Form::Field.new(
55
55
  name: 'field name',
56
56
  label: 'field label',
57
57
  type: 'text',
@@ -202,24 +202,24 @@ RSpec.describe Yaks::Mapper do
202
202
  end
203
203
  end
204
204
 
205
- context 'with a control' do
205
+ context 'with a form' do
206
206
  before do
207
207
  mapper_class.module_eval do
208
- control :foo_control do
208
+ form :foo_form do
209
209
  field :bar_field, label: 'a label', type: 'number', value: 7
210
210
  end
211
211
  end
212
212
  end
213
213
 
214
- it 'should render the control' do
214
+ it 'should render the form' do
215
215
  expect(mapper.call(fake))
216
216
  .to eql Yaks::Resource.new(
217
217
  type: 'foo',
218
- controls: [
219
- Yaks::Resource::Control.new(
220
- name: :foo_control,
218
+ forms: [
219
+ Yaks::Resource::Form.new(
220
+ name: :foo_form,
221
221
  fields: [
222
- Yaks::Resource::Control::Field.new(
222
+ Yaks::Resource::Form::Field.new(
223
223
  name: :bar_field,
224
224
  label: 'a label',
225
225
  type: 'number',
@@ -316,9 +316,9 @@ RSpec.describe Yaks::Mapper do
316
316
  it_should_behave_like 'something that can be added to a resource'
317
317
  end
318
318
 
319
- describe '#map_controls' do
320
- let(:object) { fake('Control') }
321
- before { mapper.config(mapper.config.append_to(:controls, object)) }
319
+ describe '#map_forms' do
320
+ let(:object) { fake('Form') }
321
+ before { mapper.config(mapper.config.append_to(:forms, object)) }
322
322
  it_should_behave_like 'something that can be added to a resource'
323
323
  end
324
324
 
@@ -3,18 +3,20 @@ require 'spec_helper'
3
3
  RSpec.describe Yaks::NullResource do
4
4
  subject(:null_resource) { described_class.new }
5
5
 
6
- its(:attributes) { should eq({}) }
7
- its(:links) { should eq [] }
8
- its(:subresources) { should eq [] }
6
+ its(:attributes) { should eql({}) }
7
+ its(:links) { should eql [] }
8
+ its(:rels) { should eql [] }
9
+ its(:subresources) { should eql [] }
9
10
  its(:collection?) { should be false }
10
11
  its(:null_resource?) { should be true }
12
+ its(:seq) { should eql [] }
11
13
 
12
14
  it { should respond_to :[] }
13
15
 
14
16
  its(:type) { should be_nil }
15
17
 
16
18
  describe '#each' do
17
- its(:each) { should be_a Enumerator }
19
+ its(:each) { should be_a Enumerator }
18
20
 
19
21
  it 'should not yield anything' do
20
22
  null_resource.each { fail }
@@ -42,9 +44,9 @@ RSpec.describe Yaks::NullResource do
42
44
  )
43
45
  end
44
46
 
45
- it 'should not allow adding controls' do
46
- expect { null_resource.add_control(nil) }.to raise_error(
47
- Yaks::UnsupportedOperationError, "Operation add_control not supported on Yaks::NullResource"
47
+ it 'should not allow adding forms' do
48
+ expect { null_resource.add_form(nil) }.to raise_error(
49
+ Yaks::UnsupportedOperationError, "Operation add_form not supported on Yaks::NullResource"
48
50
  )
49
51
  end
50
52
 
@@ -53,4 +55,45 @@ RSpec.describe Yaks::NullResource do
53
55
  Yaks::UnsupportedOperationError, "Operation add_subresource not supported on Yaks::NullResource"
54
56
  )
55
57
  end
58
+
59
+ describe '#initialize' do
60
+ it 'should have defaults for everything' do
61
+ expect( described_class.new.to_h ).to eql({
62
+ type: nil,
63
+ rels: [],
64
+ links: [],
65
+ attributes: {},
66
+ subresources: [],
67
+ forms: [],
68
+ collection: false})
69
+ end
70
+
71
+ it 'should allow setting rels' do
72
+ expect( described_class.new(rels: [:self]).rels ).to eql [:self]
73
+ end
74
+
75
+ it 'should allow setting the collection flag' do
76
+ expect( described_class.new(collection: true).collection ).to be true
77
+ end
78
+
79
+ it 'should not allow attributes in the contstructor' do
80
+ expect( described_class.new(attributes: {foo: :bar}).attributes ).to eql({})
81
+ end
82
+ end
83
+
84
+ describe '#map' do
85
+ context 'when a collection' do
86
+ it 'should always return []' do
87
+ expect( described_class.new(collection: true).map{} ).to eql []
88
+ end
89
+ end
90
+
91
+ context 'when not a collection' do
92
+ it 'should raise an error' do
93
+ expect { null_resource.map{} }.to raise_error(
94
+ Yaks::UnsupportedOperationError, "Operation map not supported on Yaks::NullResource"
95
+ )
96
+ end
97
+ end
98
+ end
56
99
  end
@@ -105,10 +105,10 @@ RSpec.describe Yaks::Resource do
105
105
  end
106
106
  end
107
107
 
108
- describe '#add_control' do
109
- it 'should append to the controls' do
110
- expect(resource.add_control(:a_control))
111
- .to eq Yaks::Resource.new(controls: [:a_control])
108
+ describe '#add_form' do
109
+ it 'should append to the forms' do
110
+ expect(resource.add_form(:a_form))
111
+ .to eq Yaks::Resource.new(forms: [:a_form])
112
112
  end
113
113
  end
114
114
 
@@ -120,6 +120,26 @@ RSpec.describe Yaks::Runner do
120
120
  expect(formatter).to be_a Yaks::Format::JsonAPI
121
121
  expect(formatter.send(:options)).to eql(format_option: [:foo])
122
122
  end
123
+
124
+ it 'should memoize' do
125
+ expect(runner.formatter).to be runner.formatter
126
+ end
127
+ end
128
+
129
+ describe '#env' do
130
+ describe 'when env is set in the options' do
131
+ let(:options) { { env: 123 } }
132
+
133
+ it 'returns the env passed in' do
134
+ expect(runner.env).to be 123
135
+ end
136
+ end
137
+
138
+ describe 'when no env is given' do
139
+ it 'falls back to an empty hash' do
140
+ expect(runner.env).to eql({})
141
+ end
142
+ end
123
143
  end
124
144
 
125
145
  describe '#insert_hooks' do
@@ -273,8 +293,24 @@ RSpec.describe Yaks::Runner do
273
293
  end
274
294
  end
275
295
 
276
- it 'should memoize' do
277
- expect(runner.formatter).to be runner.formatter
296
+ describe '#hooks' do
297
+ before do
298
+ Yaks::Config::DSL.new(config) do
299
+ after(:map, :this_happens_after_map)
300
+ end
301
+ end
302
+
303
+ it 'should contain the hooks from the config' do
304
+ expect(runner.hooks).to eql [[:after, :map, :this_happens_after_map, nil]]
305
+ end
306
+
307
+ context 'with extra blocks in the options' do
308
+ let(:options) { { hooks: [[:foo]] } }
309
+
310
+ it 'should combine the hooks' do
311
+ expect(runner.hooks).to eql [[:after, :map, :this_happens_after_map, nil], [:foo]]
312
+ end
313
+ end
278
314
  end
279
315
 
280
316
  end
@@ -27,6 +27,14 @@ RSpec.describe Yaks::Util do
27
27
  it 'should work with method objects' do
28
28
  expect(Resolve('foo'.method(:upcase))).to eql 'FOO'
29
29
  end
30
+
31
+ it 'should resolve a symbol to itself' do
32
+ expect(Resolve(:foo)).to eql :foo
33
+ end
34
+
35
+ it 'should resolve custom callables by calling to_proc first' do
36
+ expect(Resolve(fake(to_proc: ->{->{3}}))).to eql 3
37
+ end
30
38
  end
31
39
 
32
40
  describe '#camelize' do
@@ -46,4 +54,38 @@ RSpec.describe Yaks::Util do
46
54
  expect(slice_hash({a: 1, b:2, c:3}, :a, :c, :d)).to eql(a: 1, c:3)
47
55
  end
48
56
  end
57
+
58
+ end
59
+
60
+ RSpec.describe Yaks::Util::Deprecated do
61
+ let(:klass) {
62
+ Class.new do
63
+ extend Yaks::Util::Deprecated
64
+
65
+ def self.to_s ; 'FancyClass' end
66
+ def foo(x); "#{x}yz#{yield}" end
67
+ deprecated_alias :bar, :foo
68
+ end
69
+ }
70
+
71
+ def capture_stderr
72
+ stderr, $stderr = $stderr, StringIO.new
73
+ yield
74
+ io, $stderr = $stderr, stderr
75
+ io.string
76
+ end
77
+
78
+ it 'should set up an alias' do
79
+ capture_stderr do
80
+ expect(klass.new.bar('x') { 'a' }).to eql 'xyza'
81
+ end
82
+ end
83
+
84
+ it 'should output a warning' do
85
+ expect(
86
+ capture_stderr do
87
+ expect(klass.new.bar('x') {'a'}).to eql 'xyza'
88
+ end
89
+ ).to match /WARNING: FancyClass#bar is deprecated, use `foo'\. at \/.*util_spec.rb:#{__LINE__ - 2}:in/
90
+ end
49
91
  end