yaks 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +158 -56
  3. data/Rakefile +1 -3
  4. data/ataru_setup.rb +72 -0
  5. data/find_missing_tests.rb +34 -0
  6. data/lib/yaks.rb +8 -10
  7. data/lib/yaks/breaking_changes.rb +4 -6
  8. data/lib/yaks/builder.rb +1 -1
  9. data/lib/yaks/changelog.rb +1 -1
  10. data/lib/yaks/collection_mapper.rb +8 -5
  11. data/lib/yaks/collection_resource.rb +0 -1
  12. data/lib/yaks/config.rb +17 -7
  13. data/lib/yaks/configurable.rb +20 -14
  14. data/lib/yaks/default_policy.rb +82 -33
  15. data/lib/yaks/format.rb +7 -3
  16. data/lib/yaks/format/collection_json.rb +4 -4
  17. data/lib/yaks/format/hal.rb +1 -2
  18. data/lib/yaks/format/halo.rb +2 -4
  19. data/lib/yaks/format/json_api.rb +46 -27
  20. data/lib/yaks/html5_forms.rb +0 -2
  21. data/lib/yaks/mapper.rb +5 -5
  22. data/lib/yaks/mapper/association.rb +7 -7
  23. data/lib/yaks/mapper/association_mapper.rb +2 -0
  24. data/lib/yaks/mapper/attribute.rb +10 -4
  25. data/lib/yaks/mapper/config.rb +2 -2
  26. data/lib/yaks/mapper/form.rb +4 -10
  27. data/lib/yaks/mapper/form/config.rb +16 -17
  28. data/lib/yaks/mapper/form/dynamic_field.rb +1 -1
  29. data/lib/yaks/mapper/form/field.rb +16 -7
  30. data/lib/yaks/mapper/form/field/option.rb +5 -4
  31. data/lib/yaks/mapper/form/fieldset.rb +1 -1
  32. data/lib/yaks/mapper/form/legend.rb +18 -0
  33. data/lib/yaks/mapper/has_many.rb +1 -0
  34. data/lib/yaks/mapper/link.rb +7 -4
  35. data/lib/yaks/null_resource.rb +4 -5
  36. data/lib/yaks/pipeline.rb +2 -2
  37. data/lib/yaks/primitivize.rb +3 -2
  38. data/lib/yaks/reader/hal.rb +12 -13
  39. data/lib/yaks/reader/json_api.rb +50 -33
  40. data/lib/yaks/resource.rb +6 -7
  41. data/lib/yaks/resource/form.rb +2 -12
  42. data/lib/yaks/resource/form/field.rb +4 -3
  43. data/lib/yaks/resource/form/field/option.rb +1 -1
  44. data/lib/yaks/resource/form/fieldset.rb +1 -1
  45. data/lib/yaks/resource/form/legend.rb +18 -0
  46. data/lib/yaks/resource/has_fields.rb +13 -7
  47. data/lib/yaks/resource/link.rb +1 -1
  48. data/lib/yaks/runner.rb +5 -2
  49. data/lib/yaks/serializer.rb +2 -3
  50. data/lib/yaks/util.rb +7 -8
  51. data/lib/yaks/version.rb +1 -1
  52. data/spec/acceptance/acceptance_spec.rb +53 -38
  53. data/spec/acceptance/json_shared_examples.rb +45 -12
  54. data/spec/acceptance/models.rb +1 -1
  55. data/spec/integration/dynamic_form_fields_spec.rb +0 -1
  56. data/spec/integration/fieldset_spec.rb +18 -20
  57. data/spec/integration/map_to_resource_spec.rb +6 -6
  58. data/spec/json/{confucius.collection.json → confucius.collection_json.json} +0 -0
  59. data/spec/json/confucius.json_api.json +43 -27
  60. data/spec/json/list_of_quotes.collection_json.json +43 -0
  61. data/spec/json/list_of_quotes.hal.json +18 -0
  62. data/spec/json/list_of_quotes.json_api.json +25 -0
  63. data/spec/json/youtypeitwepostit.collection_json.json +45 -0
  64. data/spec/spec_helper.rb +4 -3
  65. data/spec/support/classes_for_policy_testing.rb +38 -14
  66. data/spec/support/deep_eql.rb +21 -18
  67. data/spec/support/pet_mapper.rb +2 -0
  68. data/spec/support/shared_contexts.rb +9 -9
  69. data/spec/unit/yaks/builder_spec.rb +41 -18
  70. data/spec/unit/yaks/collection_mapper_spec.rb +22 -19
  71. data/spec/unit/yaks/collection_resource_spec.rb +16 -8
  72. data/spec/unit/yaks/config_spec.rb +215 -19
  73. data/spec/unit/yaks/configurable_spec.rb +66 -7
  74. data/spec/unit/yaks/default_policy/derive_mapper_from_collection_spec.rb +47 -0
  75. data/spec/unit/yaks/default_policy/derive_mapper_from_item_spec.rb +114 -0
  76. data/spec/unit/yaks/default_policy/derive_mapper_from_object_spec.rb +29 -71
  77. data/spec/unit/yaks/default_policy_spec.rb +4 -5
  78. data/spec/unit/yaks/format/collection_json_spec.rb +35 -36
  79. data/spec/unit/yaks/format/hal_spec.rb +3 -3
  80. data/spec/unit/yaks/format/json_api_spec.rb +109 -68
  81. data/spec/unit/yaks/format_spec.rb +34 -0
  82. data/spec/unit/yaks/fp/callable_spec.rb +5 -3
  83. data/spec/unit/yaks/mapper/association_mapper_spec.rb +22 -4
  84. data/spec/unit/yaks/mapper/association_spec.rb +23 -11
  85. data/spec/unit/yaks/mapper/attribute_spec.rb +46 -7
  86. data/spec/unit/yaks/mapper/config_spec.rb +2 -3
  87. data/spec/unit/yaks/mapper/form/config_spec.rb +95 -0
  88. data/spec/unit/yaks/mapper/form/dynamic_field_spec.rb +30 -0
  89. data/spec/unit/yaks/mapper/form/field/option_spec.rb +48 -4
  90. data/spec/unit/yaks/mapper/form/field_spec.rb +43 -2
  91. data/spec/unit/yaks/mapper/form/fieldset_spec.rb +67 -8
  92. data/spec/unit/yaks/mapper/form/legend_spec.rb +52 -0
  93. data/spec/unit/yaks/mapper/form_spec.rb +84 -23
  94. data/spec/unit/yaks/mapper/has_many_spec.rb +39 -36
  95. data/spec/unit/yaks/mapper/has_one_spec.rb +28 -20
  96. data/spec/unit/yaks/mapper/link_spec.rb +68 -16
  97. data/spec/unit/yaks/mapper_spec.rb +118 -30
  98. data/spec/unit/yaks/null_resource_spec.rb +83 -52
  99. data/spec/unit/yaks/pipeline_spec.rb +101 -74
  100. data/spec/unit/yaks/primitivize_spec.rb +25 -6
  101. data/spec/unit/yaks/resource/form/field_spec.rb +5 -5
  102. data/spec/unit/yaks/resource/form/fieldset_spec.rb +7 -0
  103. data/spec/unit/yaks/resource/form/legend_spec.rb +8 -0
  104. data/spec/unit/yaks/resource/form_spec.rb +17 -37
  105. data/spec/unit/yaks/resource/has_fields_spec.rb +44 -3
  106. data/spec/unit/yaks/resource/link_spec.rb +11 -6
  107. data/spec/unit/yaks/resource_spec.rb +87 -98
  108. data/spec/unit/yaks/runner_spec.rb +112 -28
  109. data/spec/unit/yaks/serializer_spec.rb +1 -1
  110. data/spec/unit/yaks/util_spec.rb +30 -10
  111. data/spec/yaml/list_of_quotes.yaml +13 -0
  112. data/yaks.gemspec +21 -13
  113. metadata +129 -41
  114. data/lib/yaks/attributes.rb +0 -86
  115. data/lib/yaks/fp.rb +0 -26
  116. data/lib/yaks/identifier/link_relation.rb +0 -17
  117. data/resources/iana-link-relations.csv +0 -152
  118. data/spec/json/youtypeitwepostit.collection.json +0 -45
  119. data/spec/unit/yaks/attributes_spec.rb +0 -178
  120. data/spec/unit/yaks/fp_spec.rb +0 -29
@@ -8,23 +8,30 @@ RSpec.describe Yaks::Mapper do
8
8
 
9
9
  let(:instance) { fake(foo: 'hello', bar: 'world') }
10
10
 
11
- its(:env) { should equal rack_env }
11
+ describe "#initialize" do
12
+ it "should store the context" do
13
+ expect(mapper.context).to equal yaks_context
14
+ end
15
+ end
12
16
 
13
- describe '#call' do
14
- context 'with attributes' do
15
- before do
16
- mapper_class.attributes :foo, :bar
17
- end
17
+ describe "#env" do
18
+ its(:env) { should equal rack_env }
19
+ end
20
+
21
+ describe "#policy" do
22
+ it "should pull it out of the context" do
23
+ expect(mapper.policy).to equal policy
24
+ end
25
+ end
18
26
 
27
+ describe '#call' do
28
+ shared_examples "a mapper with attributes" do
19
29
  it 'should make the configured attributes available on the instance' do
20
- expect(mapper.attributes).to eq [
21
- Yaks::Mapper::Attribute.new(:foo),
22
- Yaks::Mapper::Attribute.new(:bar)
23
- ]
30
+ expect(mapper.attributes).to eq attributes
24
31
  end
25
32
 
26
- it 'should load them from the model' do
27
- expect(resource.attributes).to eq(foo: 'hello', bar: 'world')
33
+ it 'should load attributes from the model' do
34
+ expect(resource.attributes).to eq(attributes_from_model)
28
35
  end
29
36
 
30
37
  context 'with attribute filtering' do
@@ -37,11 +44,55 @@ RSpec.describe Yaks::Mapper do
37
44
  end
38
45
 
39
46
  it 'should only map the non-filtered attributes' do
40
- expect(resource.attributes).to eq(:bar => 'world')
47
+ expect(resource.attributes).to eq(non_filtered_attributes)
48
+ end
49
+ end
50
+ end
51
+
52
+ context "with attribute" do
53
+ let(:attributes) { [ Yaks::Mapper::Attribute.create(:foo) ] }
54
+ let(:attributes_from_model) { {foo: 'hello'} }
55
+ let(:non_filtered_attributes) { {} }
56
+
57
+ context "called without block" do
58
+ before do
59
+ mapper_class.attribute :foo
60
+ end
61
+
62
+ it_behaves_like "a mapper with attributes"
63
+ end
64
+
65
+ context "called with a block" do
66
+ let(:block) { proc { object.bar } }
67
+ let(:attributes) { [ Yaks::Mapper::Attribute.create(:foo, &block) ] }
68
+ let(:attributes_from_model) { {foo: 'world'} }
69
+
70
+ before do
71
+ mapper_class.attribute :foo, &block
41
72
  end
73
+
74
+ it_behaves_like "a mapper with attributes"
42
75
  end
43
76
  end
44
77
 
78
+ context 'with attributes' do
79
+ let(:attributes) do
80
+ [
81
+ Yaks::Mapper::Attribute.create(:foo),
82
+ Yaks::Mapper::Attribute.create(:bar)
83
+ ]
84
+ end
85
+
86
+ let(:attributes_from_model) { {foo: 'hello', bar: 'world'} }
87
+ let(:non_filtered_attributes) { {bar: 'world'} }
88
+
89
+ before do
90
+ mapper_class.attributes :foo, :bar
91
+ end
92
+
93
+ it_behaves_like "a mapper with attributes"
94
+ end
95
+
45
96
  context 'with links' do
46
97
  before do
47
98
  mapper_class.link :profile, 'http://foo/bar'
@@ -85,8 +136,8 @@ RSpec.describe Yaks::Mapper do
85
136
 
86
137
  describe 'has_one' do
87
138
  let(:has_one_opts) do
88
- { mapper: widget_mapper,
89
- rel: 'http://foo.bar/rels/widgets' }
139
+ {mapper: widget_mapper,
140
+ rel: 'http://foo.bar/rels/widgets'}
90
141
  end
91
142
 
92
143
  before do
@@ -94,22 +145,21 @@ RSpec.describe Yaks::Mapper do
94
145
  mapper_class.has_one(:widget, has_one_opts)
95
146
  end
96
147
 
97
-
98
148
  it 'should have the subresource in the resource' do
99
- expect(resource.subresources).to eq([Yaks::Resource.new(type: 'widget', attributes: {:type => 'super_widget'}, rels: ['http://foo.bar/rels/widgets'])])
149
+ expect(resource.subresources).to eq([Yaks::Resource.new(type: 'widget', attributes: {type: 'super_widget'}, rels: ['http://foo.bar/rels/widgets'])])
100
150
  end
101
151
 
102
152
  context 'with explicit mapper and rel' do
103
153
  it 'should delegate to the given mapper' do
104
154
  expect(resource.subresources).to eq([
105
- Yaks::Resource.new(type: 'widget', attributes: {:type => 'super_widget'}, rels: ['http://foo.bar/rels/widgets'])
155
+ Yaks::Resource.new(type: 'widget', attributes: {type: 'super_widget'}, rels: ['http://foo.bar/rels/widgets'])
106
156
  ])
107
157
  end
108
158
  end
109
159
 
110
160
  context 'with unspecified mapper' do
111
161
  let(:has_one_opts) do
112
- { rel: 'http://foo.bar/rels/widgets' }
162
+ {rel: 'http://foo.bar/rels/widgets'}
113
163
  end
114
164
 
115
165
  before do
@@ -120,14 +170,14 @@ RSpec.describe Yaks::Mapper do
120
170
 
121
171
  it 'should derive the mapper based on policy' do
122
172
  expect(resource.subresources).to eq([
123
- Yaks::Resource.new(type: 'widget', attributes: {:type => 'super_widget'}, rels: ['http://foo.bar/rels/widgets'])
173
+ Yaks::Resource.new(type: 'widget', attributes: {type: 'super_widget'}, rels: ['http://foo.bar/rels/widgets'])
124
174
  ])
125
175
  end
126
176
  end
127
177
 
128
178
  context 'with unspecified rel' do
129
179
  let(:has_one_opts) do
130
- { mapper: widget_mapper }
180
+ {mapper: widget_mapper}
131
181
  end
132
182
 
133
183
  before do
@@ -138,7 +188,7 @@ RSpec.describe Yaks::Mapper do
138
188
 
139
189
  it 'should derive the rel based on policy' do
140
190
  expect(resource.subresources).to eq([
141
- Yaks::Resource.new(type: 'widget', attributes: {:type => 'super_widget'}, rels: ['http://rel/rel'])
191
+ Yaks::Resource.new(type: 'widget', attributes: {type: 'super_widget'}, rels: ['http://rel/rel'])
142
192
  ])
143
193
  end
144
194
  end
@@ -226,6 +276,9 @@ RSpec.describe Yaks::Mapper do
226
276
  end
227
277
  end
228
278
 
279
+ it "should optionally take a rack env" do
280
+ expect { mapper.call(fake, {}) }.to_not raise_error
281
+ end
229
282
  end # describe '#call'
230
283
 
231
284
  describe '.mapper_name' do
@@ -283,7 +336,7 @@ RSpec.describe Yaks::Mapper do
283
336
  let(:attribute) { fake('Attribute') }
284
337
 
285
338
  it 'should receive a context' do
286
- stub(attribute).add_to_resource(any_args) {|r,_,_| Yaks::Resource.new}
339
+ stub(attribute).add_to_resource(any_args) {|_r, _, _| Yaks::Resource.new}
287
340
 
288
341
  mapper.config.attributes[0..-1] = [attribute]
289
342
  mapper.call(instance)
@@ -294,7 +347,7 @@ RSpec.describe Yaks::Mapper do
294
347
 
295
348
  shared_examples 'something that can be added to a resource' do
296
349
  it 'should receive a context' do
297
- stub(object).add_to_resource(any_args) {|r,_,_| Yaks::Resource.new}
350
+ stub(object).add_to_resource(any_args) {|_r, _, _| Yaks::Resource.new}
298
351
 
299
352
  mapper.call(instance)
300
353
 
@@ -314,6 +367,12 @@ RSpec.describe Yaks::Mapper do
314
367
  it_should_behave_like 'something that can be added to a resource'
315
368
  end
316
369
 
370
+ describe "#map_forms" do
371
+ let(:object) { fake('Form') }
372
+ before { mapper_class.config = mapper.config.append_to(:forms, object) }
373
+ it_should_behave_like "something that can be added to a resource"
374
+ end
375
+
317
376
  describe '#mapper_stack' do
318
377
  let(:yaks_context) { super().merge(mapper_stack: [:foo]) }
319
378
 
@@ -322,14 +381,36 @@ RSpec.describe Yaks::Mapper do
322
381
  end
323
382
  end
324
383
 
384
+ describe "#expand_value" do
385
+ it "should immediately return plain values" do
386
+ expect(mapper.expand_value(:foo)).to equal :foo
387
+ end
388
+
389
+ it "should resolve lambdas in the context of the mapper" do
390
+ expect(mapper.expand_value(->{ self })).to be_a Yaks::Mapper
391
+ end
392
+ end
393
+
325
394
  describe '#expand_uri' do
326
395
  let(:template) { '/foo/bar/{x}/{y}' }
327
- let(:expand) { true }
396
+ let(:expand) { true }
397
+ let(:args) { [template, expand] }
328
398
 
329
- subject(:expanded) { mapper.expand_uri(template, expand) }
399
+ subject(:expanded) { mapper.expand_uri(*args) }
330
400
 
331
401
  before do
332
- mapper.call( Struct.new(:x, :y) { def foo ; '/foo/foo' ; end }.new(6, 7) )
402
+ mapper.call(Struct.new(:x, :y) {
403
+ def foo
404
+ '/foo/foo'
405
+ end
406
+ }.new(6, 7))
407
+ end
408
+
409
+ context "with full expansion" do
410
+ let(:args) { [template] }
411
+ it "should expand all template variables" do
412
+ expect(expanded).to eq "/foo/bar/6/7"
413
+ end
333
414
  end
334
415
 
335
416
  context 'with expansion turned off' do
@@ -341,7 +422,7 @@ RSpec.describe Yaks::Mapper do
341
422
  end
342
423
 
343
424
  context 'with a URI without expansion variables' do
344
- let(:template) { '/orders' }
425
+ let(:args) { ['/orders'] }
345
426
 
346
427
  it 'should return the link as is' do
347
428
  expect(expanded).to eq '/orders'
@@ -357,12 +438,19 @@ RSpec.describe Yaks::Mapper do
357
438
  end
358
439
 
359
440
  context 'with a symbol for a template' do
360
- let(:template) { -> { object.foo } }
441
+ let(:args) { [->{ object.foo }] }
361
442
 
362
443
  it 'should use the lookup mechanism for finding the link' do
363
444
  expect(expanded).to eq '/foo/foo'
364
445
  end
365
446
  end
366
- end
367
447
 
448
+ context "with a nil uri" do
449
+ let(:args) { [nil] }
450
+
451
+ it "should return nil" do
452
+ expect(expanded).to be_nil
453
+ end
454
+ end
455
+ end
368
456
  end
@@ -1,88 +1,119 @@
1
1
  RSpec.describe Yaks::NullResource do
2
2
  subject(:null_resource) { described_class.new }
3
3
 
4
- its(:attributes) { should eql({}) }
5
- its(:links) { should eql [] }
6
- its(:rels) { should eql [] }
7
- its(:subresources) { should eql [] }
8
- its(:collection?) { should be false }
9
- its(:null_resource?) { should be true }
10
- its(:seq) { should eql [] }
11
-
12
- it { should respond_to :[] }
4
+ describe '#initialize' do
5
+ it 'should have defaults for everything' do
6
+ expect(described_class.new.to_h).to eql(
7
+ type: nil,
8
+ rels: [],
9
+ links: [],
10
+ attributes: {},
11
+ subresources: [],
12
+ forms: [],
13
+ collection: false
14
+ )
15
+ end
13
16
 
14
- its(:type) { should be_nil }
17
+ it 'should allow setting rels' do
18
+ expect(described_class.new(rels: [:self]).rels).to eql [:self]
19
+ end
15
20
 
16
- describe '#each' do
17
- its(:each) { should be_a Enumerator }
21
+ it 'should allow setting the collection flag' do
22
+ expect(described_class.new(collection: true).collection).to be true
23
+ end
18
24
 
19
- it 'should not yield anything' do
20
- null_resource.each { fail }
25
+ it 'should not allow attributes in the contstructor' do
26
+ expect(described_class.new(attributes: {foo: :bar}).attributes).to eql({})
21
27
  end
22
28
  end
23
29
 
24
- it 'should contain nothing' do
25
- expect( null_resource[:key] ).to be_nil
30
+ describe "#attributes" do
31
+ its(:attributes) { should eql({}) }
26
32
  end
27
33
 
28
- context 'when a collection' do
29
- subject(:null_resource) { described_class.new( collection: true ) }
30
- its(:collection?) { should be true }
34
+ describe "#links" do
35
+ its(:links) { should eql [] }
31
36
  end
32
37
 
33
- it 'should not allow updating attributes' do
34
- expect { null_resource.merge_attributes({}) }.to raise_error(
35
- Yaks::UnsupportedOperationError, "Operation merge_attributes not supported on Yaks::NullResource"
36
- )
38
+ describe "#rels" do
39
+ its(:rels) { should eql [] }
37
40
  end
38
41
 
39
- it 'should not allow adding links' do
40
- expect { null_resource.add_link(nil) }.to raise_error(
41
- Yaks::UnsupportedOperationError, "Operation add_link not supported on Yaks::NullResource"
42
- )
42
+ describe "#subresources" do
43
+ its(:subresources) { should eql [] }
43
44
  end
44
45
 
45
- it 'should not allow adding forms' do
46
- expect { null_resource.add_form(nil) }.to raise_error(
47
- Yaks::UnsupportedOperationError, "Operation add_form not supported on Yaks::NullResource"
48
- )
46
+ describe "#collection?" do
47
+ its(:collection?) { should be false }
48
+
49
+ context 'when a collection' do
50
+ subject(:null_resource) { described_class.new(collection: true) }
51
+ its(:collection?) { should be true }
52
+ end
49
53
  end
50
54
 
51
- it 'should not allow adding subresources' do
52
- expect { null_resource.add_subresource(nil) }.to raise_error(
53
- Yaks::UnsupportedOperationError, "Operation add_subresource not supported on Yaks::NullResource"
54
- )
55
+ describe "#null_resource?" do
56
+ its(:null_resource?) { should be true }
55
57
  end
56
58
 
57
- describe '#initialize' do
58
- it 'should have defaults for everything' do
59
- expect( described_class.new.to_h ).to eql({
60
- type: nil,
61
- rels: [],
62
- links: [],
63
- attributes: {},
64
- subresources: [],
65
- forms: [],
66
- collection: false})
59
+ describe "#seq" do
60
+ its(:seq) { should eql [] }
61
+ end
62
+
63
+ describe "#[]" do
64
+ it 'should contain nothing' do
65
+ expect(null_resource[:key]).to be_nil
67
66
  end
67
+ end
68
68
 
69
- it 'should allow setting rels' do
70
- expect( described_class.new(rels: [:self]).rels ).to eql [:self]
69
+ describe "#type" do
70
+ its(:type) { should be_nil }
71
+ end
72
+
73
+ describe '#each' do
74
+ its(:each) { should be_a Enumerator }
75
+
76
+ it 'should not yield anything' do
77
+ null_resource.each { raise }
71
78
  end
79
+ end
72
80
 
73
- it 'should allow setting the collection flag' do
74
- expect( described_class.new(collection: true).collection ).to be true
81
+ describe "#merge_attributes" do
82
+ it 'should not allow updating attributes' do
83
+ expect { null_resource.merge_attributes({}) }.to raise_error(
84
+ Yaks::UnsupportedOperationError, "Operation merge_attributes not supported on Yaks::NullResource"
85
+ )
75
86
  end
87
+ end
76
88
 
77
- it 'should not allow attributes in the contstructor' do
78
- expect( described_class.new(attributes: {foo: :bar}).attributes ).to eql({})
89
+ describe "#add_link" do
90
+ it 'should not allow adding links' do
91
+ expect { null_resource.add_link(nil) }.to raise_error(
92
+ Yaks::UnsupportedOperationError, "Operation add_link not supported on Yaks::NullResource"
93
+ )
94
+ end
95
+ end
96
+
97
+ describe "#add_form" do
98
+ it 'should not allow adding forms' do
99
+ expect { null_resource.add_form(nil) }.to raise_error(
100
+ Yaks::UnsupportedOperationError, "Operation add_form not supported on Yaks::NullResource"
101
+ )
102
+ end
103
+ end
104
+
105
+ describe "#add_subresource" do
106
+ it 'should not allow adding subresources' do
107
+ expect { null_resource.add_subresource(nil) }.to raise_error(
108
+ Yaks::UnsupportedOperationError, "Operation add_subresource not supported on Yaks::NullResource"
109
+ )
79
110
  end
80
111
  end
81
112
 
82
113
  describe '#map' do
83
114
  context 'when a collection' do
84
115
  it 'should always return []' do
85
- expect( described_class.new(collection: true).map{} ).to eql []
116
+ expect(described_class.new(collection: true).map{}).to eql []
86
117
  end
87
118
  end
88
119
 
@@ -2,12 +2,12 @@ RSpec.describe Yaks::Pipeline do
2
2
  subject(:pipeline) { described_class.new(steps) }
3
3
  let(:steps) {
4
4
  [
5
- [:step1, ->(i, e) { i + 1 }],
6
- [:step2, ->(i, e) { i + 10 }],
7
- [:step3, ->(i, e) { i + e[:foo] }],
5
+ [:step1, ->(i, _e) { i + 1 }],
6
+ [:step2, ->(i, _e) { i + 10 }],
7
+ [:step3, ->(i, e) { i + e[:foo] }]
8
8
  ]
9
9
  }
10
- let(:env) {{ foo: 100 }}
10
+ let(:env) {{foo: 100}}
11
11
 
12
12
  describe '#call' do
13
13
  it 'should call steps in turn, passing in the last result and env' do
@@ -19,7 +19,7 @@ RSpec.describe Yaks::Pipeline do
19
19
  let(:hooks) { [] }
20
20
 
21
21
  describe 'before' do
22
- let(:hooks) { [[:before, :step2, :before_step2, ->(i, e) { i - (i % 100) }]] }
22
+ let(:hooks) { [[:before, :step2, :before_step2, ->(i, _e) { i - (i % 100) }]] }
23
23
 
24
24
  it 'should insert a hook before the step' do
25
25
  expect(pipeline.insert_hooks(hooks).call(1000, env)).to equal 1110
@@ -27,7 +27,7 @@ RSpec.describe Yaks::Pipeline do
27
27
  end
28
28
 
29
29
  describe 'after' do
30
- let(:hooks) { [[:after, :step2, :after_step2, ->(i, e) { i - (i % 100) }]] }
30
+ let(:hooks) { [[:after, :step2, :after_step2, ->(i, _e) { i - (i % 100) }]] }
31
31
 
32
32
  it 'should insert a hook after the step' do
33
33
  expect(pipeline.insert_hooks(hooks).call(1000, env)).to equal 1100
@@ -53,7 +53,7 @@ RSpec.describe Yaks::Pipeline do
53
53
  describe 'multiple hooks' do
54
54
  let(:hooks) {
55
55
  [
56
- [:after, :step2, :after_step2, ->(i, e) { i % 10 }],
56
+ [:after, :step2, :after_step2, ->(i, _e) { i % 10 }],
57
57
  [:skip, :step3]
58
58
  ]
59
59
  }
@@ -65,76 +65,103 @@ RSpec.describe Yaks::Pipeline do
65
65
 
66
66
  it 'should return a pipeline with the right step names' do
67
67
  expect(pipeline
68
- .insert_hooks([[:before, :step2, :step1_1, ->(i, e) { i+1 }]])
69
- .insert_hooks([[:before, :step1_1, :step1_0, ->(i, e) { i+10 }]])
70
- .insert_hooks([[:after, :step1_1, :step1_2, ->(i, e) { i+100 }]])
71
- .insert_hooks([[:around, :step1_1, :step1_1_0, ->(i, e, &b) { b.call(i, e)+1000 }]])
72
- .insert_hooks([[:around, :step1_2, :step1_3, ->(i, e, &b) { b.call(i, e)+1000 }]])
73
- .insert_hooks([[:after, :step1_3, :step1_4, ->(i, e) { i + 10000 }]])
68
+ .insert_hooks([[:before, :step2, :step1_1, ->(i, _e) { i + 1 }]])
69
+ .insert_hooks([[:before, :step1_1, :step1_0, ->(i, _e) { i + 10 }]])
70
+ .insert_hooks([[:after, :step1_1, :step1_2, ->(i, _e) { i + 100 }]])
71
+ .insert_hooks([[:around, :step1_1, :step1_1_0, ->(i, e, &b) { b.call(i, e) + 1000 }]])
72
+ .insert_hooks([[:around, :step1_2, :step1_3, ->(i, e, &b) { b.call(i, e) + 1000 }]])
73
+ .insert_hooks([[:after, :step1_3, :step1_4, ->(i, _e) { i + 10_000 }]])
74
74
  .call(1000, env)
75
- ).to equal 13222
75
+ ).to equal 13_222
76
76
  end
77
+ end
78
+
79
+ let(:fake_step) {
80
+ Class.new do
81
+ include Attribs.new(:transitive, :call, inverse: nil)
82
+ alias_method :transitive?, :transitive
83
+ end
84
+ }
85
+
86
+ let(:transitive_step) {
87
+ fake_step.new(transitive: true, inverse: ->(_x, _env) {}, call: "t")
88
+ }
89
+
90
+ let(:intransitive_step) {
91
+ fake_step.new(transitive: false, call: "i")
92
+ }
77
93
 
94
+ subject(:pipeline) { described_class.new(steps) }
95
+
96
+ describe '#transitive?' do
97
+ context 'with transitive steps' do
98
+ let(:steps) { [[:name1, transitive_step]] }
99
+ it 'should be transitive' do
100
+ expect(pipeline.transitive?).to be true
101
+ end
102
+ end
78
103
  end
79
- end
80
104
 
105
+ describe '#inverse' do
106
+ end
107
+ end
81
108
 
82
- # describe 'after' do
83
- # let(:hooks) { proc { after(:format) { :after_format_impl } } }
84
-
85
- # it 'should insert a hook after the step' do
86
- # expect(runner.steps.map(&:first)).to eql [
87
- # :map, :format, :after_format, :primitivize, :serialize
88
- # ]
89
- # expect(runner.steps[1].last).to be runner.formatter
90
- # expect(runner.steps[2].last.call).to be :after_format_impl
91
- # end
92
- # end
93
-
94
- # describe 'around' do
95
- # let(:hooks) do
96
- # proc {
97
- # around(:serialize) do |res, env, &block|
98
- # "serialized[#{env}][#{block.call(res, env)}]"
99
- # end
100
- # }
101
- # end
102
-
103
- # it 'should insert a hook around the step' do
104
- # expect(runner.steps.map(&:first)).to eql [
105
- # :map, :format, :primitivize, :serialize
106
- # ]
107
- # expect(runner.steps.assoc(:serialize).last.call(["res1"], "env1")).to eql(
108
- # "serialized[env1][[\n \"res1\"\n]]"
109
- # )
110
- # end
111
- # end
112
-
113
- # describe 'around' do
114
- # let(:hooks) { ->(*) { skip(:serialize) } }
115
-
116
- # it 'should skip a certain step' do
117
- # expect(runner.steps.map(&:first)).to eql [
118
- # :map, :format, :primitivize
119
- # ]
120
- # end
121
- # end
122
-
123
- # describe 'multiple hooks' do
124
- # let(:hooks) {
125
- # proc {
126
- # after(:format) { :after_format_impl }
127
- # skip(:serialize)
128
- # }
129
- # }
130
-
131
- # it 'should insert the hooks' do
132
- # expect(runner.steps.map(&:first)).to eql [
133
- # :map, :format, :after_format, :primitivize
134
- # ]
135
- # end
136
-
137
- # it 'should pass on unchanged steps' do
138
- # expect(runner.steps.assoc(:map)[1]).to eql runner.mapper
139
- # end
140
- # end
109
+ # describe 'after' do
110
+ # let(:hooks) { proc { after(:format) { :after_format_impl } } }
111
+
112
+ # it 'should insert a hook after the step' do
113
+ # expect(runner.steps.map(&:first)).to eql [
114
+ # :map, :format, :after_format, :primitivize, :serialize
115
+ # ]
116
+ # expect(runner.steps[1].last).to be runner.formatter
117
+ # expect(runner.steps[2].last.call).to be :after_format_impl
118
+ # end
119
+ # end
120
+
121
+ # describe 'around' do
122
+ # let(:hooks) do
123
+ # proc {
124
+ # around(:serialize) do |res, env, &block|
125
+ # "serialized[#{env}][#{block.call(res, env)}]"
126
+ # end
127
+ # }
128
+ # end
129
+
130
+ # it 'should insert a hook around the step' do
131
+ # expect(runner.steps.map(&:first)).to eql [
132
+ # :map, :format, :primitivize, :serialize
133
+ # ]
134
+ # expect(runner.steps.assoc(:serialize).last.call(["res1"], "env1")).to eql(
135
+ # "serialized[env1][[\n \"res1\"\n]]"
136
+ # )
137
+ # end
138
+ # end
139
+
140
+ # describe 'around' do
141
+ # let(:hooks) { ->(*) { skip(:serialize) } }
142
+
143
+ # it 'should skip a certain step' do
144
+ # expect(runner.steps.map(&:first)).to eql [
145
+ # :map, :format, :primitivize
146
+ # ]
147
+ # end
148
+ # end
149
+
150
+ # describe 'multiple hooks' do
151
+ # let(:hooks) {
152
+ # proc {
153
+ # after(:format) { :after_format_impl }
154
+ # skip(:serialize)
155
+ # }
156
+ # }
157
+
158
+ # it 'should insert the hooks' do
159
+ # expect(runner.steps.map(&:first)).to eql [
160
+ # :map, :format, :after_format, :primitivize
161
+ # ]
162
+ # end
163
+
164
+ # it 'should pass on unchanged steps' do
165
+ # expect(runner.steps.assoc(:map)[1]).to eql runner.mapper
166
+ # end
167
+ # end