yaks 0.7.6 → 0.7.7

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