drape 1.0.0.beta1
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.
- checksums.yaml +7 -0
- data/.codeclimate.yml +27 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/.rubocop.yml +1159 -0
- data/.travis.yml +14 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +230 -0
- data/CONTRIBUTING.md +20 -0
- data/Gemfile +16 -0
- data/Guardfile +26 -0
- data/LICENSE +7 -0
- data/README.md +592 -0
- data/Rakefile +76 -0
- data/drape.gemspec +31 -0
- data/gemfiles/5.0.gemfile +8 -0
- data/lib/drape.rb +63 -0
- data/lib/drape/automatic_delegation.rb +55 -0
- data/lib/drape/collection_decorator.rb +102 -0
- data/lib/drape/decoratable.rb +93 -0
- data/lib/drape/decoratable/equality.rb +26 -0
- data/lib/drape/decorated_association.rb +33 -0
- data/lib/drape/decorates_assigned.rb +44 -0
- data/lib/drape/decorator.rb +282 -0
- data/lib/drape/delegation.rb +13 -0
- data/lib/drape/factory.rb +91 -0
- data/lib/drape/finders.rb +36 -0
- data/lib/drape/helper_proxy.rb +43 -0
- data/lib/drape/helper_support.rb +5 -0
- data/lib/drape/lazy_helpers.rb +13 -0
- data/lib/drape/railtie.rb +69 -0
- data/lib/drape/tasks/test.rake +9 -0
- data/lib/drape/test/devise_helper.rb +30 -0
- data/lib/drape/test/minitest_integration.rb +6 -0
- data/lib/drape/test/rspec_integration.rb +20 -0
- data/lib/drape/test_case.rb +42 -0
- data/lib/drape/undecorate.rb +9 -0
- data/lib/drape/version.rb +3 -0
- data/lib/drape/view_context.rb +104 -0
- data/lib/drape/view_context/build_strategy.rb +46 -0
- data/lib/drape/view_helpers.rb +34 -0
- data/lib/generators/controller_override.rb +17 -0
- data/lib/generators/mini_test/decorator_generator.rb +20 -0
- data/lib/generators/mini_test/templates/decorator_spec.rb +4 -0
- data/lib/generators/mini_test/templates/decorator_test.rb +4 -0
- data/lib/generators/rails/decorator_generator.rb +36 -0
- data/lib/generators/rails/templates/decorator.rb +19 -0
- data/lib/generators/rspec/decorator_generator.rb +9 -0
- data/lib/generators/rspec/templates/decorator_spec.rb +4 -0
- data/lib/generators/test_unit/decorator_generator.rb +9 -0
- data/lib/generators/test_unit/templates/decorator_test.rb +4 -0
- data/spec/draper/collection_decorator_spec.rb +305 -0
- data/spec/draper/decoratable/equality_spec.rb +10 -0
- data/spec/draper/decoratable_spec.rb +203 -0
- data/spec/draper/decorated_association_spec.rb +85 -0
- data/spec/draper/decorates_assigned_spec.rb +70 -0
- data/spec/draper/decorator_spec.rb +828 -0
- data/spec/draper/factory_spec.rb +250 -0
- data/spec/draper/finders_spec.rb +165 -0
- data/spec/draper/helper_proxy_spec.rb +61 -0
- data/spec/draper/lazy_helpers_spec.rb +21 -0
- data/spec/draper/undecorate_spec.rb +19 -0
- data/spec/draper/view_context/build_strategy_spec.rb +116 -0
- data/spec/draper/view_context_spec.rb +160 -0
- data/spec/draper/view_helpers_spec.rb +8 -0
- data/spec/dummy/.gitignore +21 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/config/manifest.js +3 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +16 -0
- data/spec/dummy/app/assets/javascripts/cable.js +13 -0
- data/spec/dummy/app/assets/javascripts/channels/.keep +0 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
- data/spec/dummy/app/channels/application_cable/connection.rb +5 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/controllers/posts_controller.rb +21 -0
- data/spec/dummy/app/decorators/mongoid_post_decorator.rb +4 -0
- data/spec/dummy/app/decorators/post_decorator.rb +59 -0
- data/spec/dummy/app/helpers/application_helper.rb +5 -0
- data/spec/dummy/app/jobs/application_job.rb +2 -0
- data/spec/dummy/app/mailers/application_mailer.rb +4 -0
- data/spec/dummy/app/mailers/post_mailer.rb +18 -0
- data/spec/dummy/app/models/admin.rb +5 -0
- data/spec/dummy/app/models/application_record.rb +3 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/models/mongoid_post.rb +5 -0
- data/spec/dummy/app/models/post.rb +3 -0
- data/spec/dummy/app/models/user.rb +5 -0
- data/spec/dummy/app/views/layouts/application.html.erb +9 -0
- data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/spec/dummy/app/views/post_mailer/decorated_email.html.erb +31 -0
- data/spec/dummy/app/views/posts/_post.html.erb +40 -0
- data/spec/dummy/app/views/posts/show.html.erb +1 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +9 -0
- data/spec/dummy/bin/rake +9 -0
- data/spec/dummy/bin/setup +34 -0
- data/spec/dummy/bin/spring +15 -0
- data/spec/dummy/bin/update +29 -0
- data/spec/dummy/config.ru +5 -0
- data/spec/dummy/config/application.rb +21 -0
- data/spec/dummy/config/boot.rb +2 -0
- data/spec/dummy/config/cable.yml +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +51 -0
- data/spec/dummy/config/environments/production.rb +91 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/active_record_belongs_to_required_by_default.rb +6 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +6 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/callback_terminator.rb +6 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/spec/dummy/config/initializers/devise.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/per_form_csrf_tokens.rb +4 -0
- data/spec/dummy/config/initializers/request_forgery_protection.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/ssl_options.rb +4 -0
- data/spec/dummy/config/initializers/to_time_preserves_timezone.rb +10 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/mongoid.yml +16 -0
- data/spec/dummy/config/puma.rb +47 -0
- data/spec/dummy/config/routes.rb +8 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/config/spring.rb +6 -0
- data/spec/dummy/db/migrate/20121019115657_create_posts.rb +7 -0
- data/spec/dummy/db/schema.rb +19 -0
- data/spec/dummy/db/seeds.rb +2 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/lib/tasks/.keep +0 -0
- data/spec/dummy/lib/tasks/test.rake +16 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/spec/dummy/public/apple-touch-icon.png +0 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/robots.txt +5 -0
- data/spec/dummy/spec/decorators/active_model_serializers_spec.rb +12 -0
- data/spec/dummy/spec/decorators/devise_spec.rb +64 -0
- data/spec/dummy/spec/decorators/helpers_spec.rb +21 -0
- data/spec/dummy/spec/decorators/post_decorator_spec.rb +66 -0
- data/spec/dummy/spec/decorators/spec_type_spec.rb +7 -0
- data/spec/dummy/spec/decorators/view_context_spec.rb +22 -0
- data/spec/dummy/spec/mailers/post_mailer_spec.rb +33 -0
- data/spec/dummy/spec/models/mongoid_post_spec.rb +8 -0
- data/spec/dummy/spec/models/post_spec.rb +6 -0
- data/spec/dummy/spec/shared_examples/decoratable.rb +26 -0
- data/spec/dummy/spec/spec_helper.rb +8 -0
- data/spec/dummy/test/controllers/.keep +0 -0
- data/spec/dummy/test/fixtures/.keep +0 -0
- data/spec/dummy/test/fixtures/files/.keep +0 -0
- data/spec/dummy/test/helpers/.keep +0 -0
- data/spec/dummy/test/integration/.keep +0 -0
- data/spec/dummy/test/mailers/.keep +0 -0
- data/spec/dummy/test/models/.keep +0 -0
- data/spec/dummy/test/test_helper.rb +10 -0
- data/spec/dummy/vendor/assets/javascripts/.keep +0 -0
- data/spec/dummy/vendor/assets/stylesheets/.keep +0 -0
- data/spec/generators/controller/controller_generator_spec.rb +24 -0
- data/spec/generators/decorator/decorator_generator_spec.rb +94 -0
- data/spec/integration/integration_spec.rb +68 -0
- data/spec/performance/active_record.rb +4 -0
- data/spec/performance/benchmark.rb +57 -0
- data/spec/performance/decorators.rb +41 -0
- data/spec/performance/models.rb +20 -0
- data/spec/spec_helper.rb +41 -0
- data/spec/support/dummy_app.rb +88 -0
- data/spec/support/matchers/have_text.rb +50 -0
- data/spec/support/shared_examples/decoratable_equality.rb +40 -0
- data/spec/support/shared_examples/view_helpers.rb +39 -0
- metadata +497 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Drape
|
|
4
|
+
describe Factory do
|
|
5
|
+
describe '#initialize' do
|
|
6
|
+
it 'accepts valid options' do
|
|
7
|
+
valid_options = { with: Decorator, context: { foo: 'bar' } }
|
|
8
|
+
expect { Factory.new(valid_options) }.not_to raise_error
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it 'rejects invalid options' do
|
|
12
|
+
expect { Factory.new(foo: 'bar') }.to raise_error ArgumentError, /Unknown key/
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe '#decorate' do
|
|
17
|
+
context 'when object is nil' do
|
|
18
|
+
it 'returns nil' do
|
|
19
|
+
factory = Factory.new
|
|
20
|
+
|
|
21
|
+
expect(factory.decorate(nil)).to be_nil
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'calls a worker' do
|
|
26
|
+
factory = Factory.new
|
|
27
|
+
worker = ->(*) { :decorated }
|
|
28
|
+
|
|
29
|
+
Factory::Worker.should_receive(:new).and_return(worker)
|
|
30
|
+
expect(factory.decorate(double)).to be :decorated
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'passes the object to the worker' do
|
|
34
|
+
factory = Factory.new
|
|
35
|
+
object = double
|
|
36
|
+
|
|
37
|
+
Factory::Worker.should_receive(:new).with(anything, object).and_return(->(*) {})
|
|
38
|
+
factory.decorate(object)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
context 'when the :with option was given' do
|
|
42
|
+
it 'passes the decorator class to the worker' do
|
|
43
|
+
decorator_class = double
|
|
44
|
+
factory = Factory.new(with: decorator_class)
|
|
45
|
+
|
|
46
|
+
Factory::Worker.should_receive(:new).with(decorator_class, anything).and_return(->(*) {})
|
|
47
|
+
factory.decorate(double)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
context 'when the :with option was omitted' do
|
|
52
|
+
it 'passes nil to the worker' do
|
|
53
|
+
factory = Factory.new
|
|
54
|
+
|
|
55
|
+
Factory::Worker.should_receive(:new).with(nil, anything).and_return(->(*) {})
|
|
56
|
+
factory.decorate(double)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it 'passes options to the call' do
|
|
61
|
+
factory = Factory.new
|
|
62
|
+
worker = ->(*) {}
|
|
63
|
+
Factory::Worker.stub new: worker
|
|
64
|
+
options = { foo: 'bar' }
|
|
65
|
+
|
|
66
|
+
worker.should_receive(:call).with(options)
|
|
67
|
+
factory.decorate(double, options)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
context 'when the :context option was given' do
|
|
71
|
+
it 'sets the passed context' do
|
|
72
|
+
factory = Factory.new(context: { foo: 'bar' })
|
|
73
|
+
worker = ->(*) {}
|
|
74
|
+
Factory::Worker.stub new: worker
|
|
75
|
+
|
|
76
|
+
worker.should_receive(:call).with(baz: 'qux', context: { foo: 'bar' })
|
|
77
|
+
factory.decorate(double, { baz: 'qux' })
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it 'is overridden by explicitly-specified context' do
|
|
81
|
+
factory = Factory.new(context: { foo: 'bar' })
|
|
82
|
+
worker = ->(*) {}
|
|
83
|
+
Factory::Worker.stub new: worker
|
|
84
|
+
|
|
85
|
+
worker.should_receive(:call).with(context: { baz: 'qux' })
|
|
86
|
+
factory.decorate(double, context: { baz: 'qux' })
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
describe Factory::Worker do
|
|
93
|
+
describe '#call' do
|
|
94
|
+
it 'calls the decorator method' do
|
|
95
|
+
object = double
|
|
96
|
+
options = { foo: 'bar' }
|
|
97
|
+
worker = Factory::Worker.new(double, object)
|
|
98
|
+
decorator = ->(*) {}
|
|
99
|
+
allow(worker).to receive(:decorator) { decorator }
|
|
100
|
+
|
|
101
|
+
decorator.should_receive(:call).with(object, options).and_return(:decorated)
|
|
102
|
+
expect(worker.call(options)).to be :decorated
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
context 'when the :context option is callable' do
|
|
106
|
+
it 'calls it' do
|
|
107
|
+
worker = Factory::Worker.new(double, double)
|
|
108
|
+
decorator = ->(*) {}
|
|
109
|
+
worker.stub decorator: decorator
|
|
110
|
+
context = { foo: 'bar' }
|
|
111
|
+
|
|
112
|
+
decorator.should_receive(:call).with(anything, context: context)
|
|
113
|
+
worker.call(context: -> { context })
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it 'receives arguments from the :context_args option' do
|
|
117
|
+
worker = Factory::Worker.new(double, double)
|
|
118
|
+
worker.stub decorator: ->(*) {}
|
|
119
|
+
context = -> {}
|
|
120
|
+
|
|
121
|
+
context.should_receive(:call).with(:foo, :bar)
|
|
122
|
+
worker.call(context: context, context_args: [:foo, :bar])
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it 'wraps non-arrays passed to :context_args' do
|
|
126
|
+
worker = Factory::Worker.new(double, double)
|
|
127
|
+
worker.stub decorator: ->(*) {}
|
|
128
|
+
context = -> {}
|
|
129
|
+
hash = { foo: 'bar' }
|
|
130
|
+
|
|
131
|
+
context.should_receive(:call).with(hash)
|
|
132
|
+
worker.call(context: context, context_args: hash)
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
context 'when the :context option is not callable' do
|
|
137
|
+
it "doesn't call it" do
|
|
138
|
+
worker = Factory::Worker.new(double, double)
|
|
139
|
+
decorator = ->(*) {}
|
|
140
|
+
worker.stub decorator: decorator
|
|
141
|
+
context = { foo: 'bar' }
|
|
142
|
+
|
|
143
|
+
decorator.should_receive(:call).with(anything, context: context)
|
|
144
|
+
worker.call(context: context)
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it 'does not pass the :context_args option to the decorator' do
|
|
149
|
+
worker = Factory::Worker.new(double, double)
|
|
150
|
+
decorator = ->(*) {}
|
|
151
|
+
worker.stub decorator: decorator
|
|
152
|
+
|
|
153
|
+
decorator.should_receive(:call).with(anything, foo: 'bar')
|
|
154
|
+
worker.call(foo: 'bar', context_args: [])
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
describe '#decorator' do
|
|
159
|
+
context 'for a singular object' do
|
|
160
|
+
context 'when decorator_class is specified' do
|
|
161
|
+
it 'returns the .decorate method from the decorator' do
|
|
162
|
+
decorator_class = Class.new(Decorator)
|
|
163
|
+
worker = Factory::Worker.new(decorator_class, double)
|
|
164
|
+
|
|
165
|
+
expect(worker.decorator).to eq decorator_class.method(:decorate)
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
context 'when decorator_class is unspecified' do
|
|
170
|
+
context 'and the object is decoratable' do
|
|
171
|
+
it "returns the object's #decorate method" do
|
|
172
|
+
object = double
|
|
173
|
+
options = { foo: 'bar' }
|
|
174
|
+
worker = Factory::Worker.new(nil, object)
|
|
175
|
+
|
|
176
|
+
object.should_receive(:decorate).with(options).and_return(:decorated)
|
|
177
|
+
expect(worker.decorator.call(object, options)).to be :decorated
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
context 'and the object is not decoratable' do
|
|
182
|
+
it 'raises an error' do
|
|
183
|
+
object = double
|
|
184
|
+
worker = Factory::Worker.new(nil, object)
|
|
185
|
+
|
|
186
|
+
expect { worker.decorator }.to raise_error UninferrableDecoratorError
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
context 'when the object is a struct' do
|
|
192
|
+
it 'returns a singular decorator' do
|
|
193
|
+
object = Struct.new(:stuff).new('things')
|
|
194
|
+
|
|
195
|
+
decorator_class = Class.new(Decorator)
|
|
196
|
+
worker = Factory::Worker.new(decorator_class, object)
|
|
197
|
+
|
|
198
|
+
expect(worker.decorator).to eq decorator_class.method(:decorate)
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
context 'for a collection object' do
|
|
204
|
+
context 'when decorator_class is a CollectionDecorator' do
|
|
205
|
+
it 'returns the .decorate method from the collection decorator' do
|
|
206
|
+
decorator_class = Class.new(CollectionDecorator)
|
|
207
|
+
worker = Factory::Worker.new(decorator_class, [])
|
|
208
|
+
|
|
209
|
+
expect(worker.decorator).to eq decorator_class.method(:decorate)
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
context 'when decorator_class is a Decorator' do
|
|
214
|
+
it 'returns the .decorate_collection method from the decorator' do
|
|
215
|
+
decorator_class = Class.new(Decorator)
|
|
216
|
+
worker = Factory::Worker.new(decorator_class, [])
|
|
217
|
+
|
|
218
|
+
expect(worker.decorator).to eq decorator_class.method(:decorate_collection)
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
context 'when decorator_class is unspecified' do
|
|
223
|
+
context 'and the object is decoratable' do
|
|
224
|
+
it "returns the .decorate_collection method from the object's decorator" do
|
|
225
|
+
object = []
|
|
226
|
+
decorator_class = Class.new(Decorator)
|
|
227
|
+
allow(object).to receive(:decorator_class) { decorator_class }
|
|
228
|
+
allow(object).to receive(:decorate) { nil }
|
|
229
|
+
worker = Factory::Worker.new(nil, object)
|
|
230
|
+
|
|
231
|
+
decorator_class
|
|
232
|
+
.should_receive(:decorate_collection).with(object, foo: 'bar', with: nil)
|
|
233
|
+
.and_return(:decorated)
|
|
234
|
+
|
|
235
|
+
expect(worker.decorator.call(object, foo: 'bar')).to be :decorated
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
context 'and the object is not decoratable' do
|
|
240
|
+
it 'returns the .decorate method from CollectionDecorator' do
|
|
241
|
+
worker = Factory::Worker.new(nil, [])
|
|
242
|
+
|
|
243
|
+
expect(worker.decorator).to eq CollectionDecorator.method(:decorate)
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
end
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Drape
|
|
4
|
+
describe Finders do
|
|
5
|
+
protect_class ProductDecorator
|
|
6
|
+
before { ProductDecorator.decorates_finders }
|
|
7
|
+
|
|
8
|
+
describe '.find' do
|
|
9
|
+
it 'proxies to the model class' do
|
|
10
|
+
Product.should_receive(:find).with(1)
|
|
11
|
+
ProductDecorator.find(1)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'decorates the result' do
|
|
15
|
+
found = Product.new
|
|
16
|
+
Product.stub(:find).and_return(found)
|
|
17
|
+
decorator = ProductDecorator.find(1)
|
|
18
|
+
expect(decorator).to be_a ProductDecorator
|
|
19
|
+
expect(decorator.object).to be found
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'passes context to the decorator' do
|
|
23
|
+
Product.stub(:find)
|
|
24
|
+
context = { some: 'context' }
|
|
25
|
+
decorator = ProductDecorator.find(1, context: context)
|
|
26
|
+
|
|
27
|
+
expect(decorator.context).to be context
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
describe '.find_by_(x)' do
|
|
32
|
+
it 'proxies to the model class' do
|
|
33
|
+
Product.should_receive(:find_by_name).with('apples')
|
|
34
|
+
ProductDecorator.find_by_name('apples')
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'decorates the result' do
|
|
38
|
+
found = Product.new
|
|
39
|
+
Product.stub(:find_by_name).and_return(found)
|
|
40
|
+
decorator = ProductDecorator.find_by_name('apples')
|
|
41
|
+
expect(decorator).to be_a ProductDecorator
|
|
42
|
+
expect(decorator.object).to be found
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it 'proxies complex ProductDecorators' do
|
|
46
|
+
Product.should_receive(:find_by_name_and_size).with('apples', 'large')
|
|
47
|
+
ProductDecorator.find_by_name_and_size('apples', 'large')
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'proxies find_last_by_(x) ProductDecorators' do
|
|
51
|
+
Product.should_receive(:find_last_by_name_and_size).with('apples', 'large')
|
|
52
|
+
ProductDecorator.find_last_by_name_and_size('apples', 'large')
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'proxies find_or_initialize_by_(x) ProductDecorators' do
|
|
56
|
+
Product.should_receive(:find_or_initialize_by_name_and_size).with('apples', 'large')
|
|
57
|
+
ProductDecorator.find_or_initialize_by_name_and_size('apples', 'large')
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it 'proxies find_or_create_by_(x) ProductDecorators' do
|
|
61
|
+
Product.should_receive(:find_or_create_by_name_and_size).with('apples', 'large')
|
|
62
|
+
ProductDecorator.find_or_create_by_name_and_size('apples', 'large')
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it 'passes context to the decorator' do
|
|
66
|
+
Product.stub(:find_by_name_and_size)
|
|
67
|
+
context = { some: 'context' }
|
|
68
|
+
decorator = ProductDecorator.find_by_name_and_size('apples', 'large', context: context)
|
|
69
|
+
|
|
70
|
+
expect(decorator.context).to be context
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
describe '.find_all_by_' do
|
|
75
|
+
it 'proxies to the model class' do
|
|
76
|
+
Product.should_receive(:find_all_by_name_and_size).with('apples', 'large').and_return([])
|
|
77
|
+
ProductDecorator.find_all_by_name_and_size('apples', 'large')
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it 'decorates the result' do
|
|
81
|
+
found = [Product.new, Product.new]
|
|
82
|
+
Product.stub(:find_all_by_name).and_return(found)
|
|
83
|
+
decorator = ProductDecorator.find_all_by_name('apples')
|
|
84
|
+
|
|
85
|
+
expect(decorator).to be_a Drape::CollectionDecorator
|
|
86
|
+
expect(decorator.decorator_class).to be ProductDecorator
|
|
87
|
+
expect(decorator).to eq found
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it 'passes context to the decorator' do
|
|
91
|
+
Product.stub(:find_all_by_name)
|
|
92
|
+
context = { some: 'context' }
|
|
93
|
+
decorator = ProductDecorator.find_all_by_name('apples', context: context)
|
|
94
|
+
|
|
95
|
+
expect(decorator.context).to be context
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
describe '.all' do
|
|
100
|
+
it 'returns a decorated collection' do
|
|
101
|
+
found = [Product.new, Product.new]
|
|
102
|
+
Product.stub all: found
|
|
103
|
+
decorator = ProductDecorator.all
|
|
104
|
+
|
|
105
|
+
expect(decorator).to be_a Drape::CollectionDecorator
|
|
106
|
+
expect(decorator.decorator_class).to be ProductDecorator
|
|
107
|
+
expect(decorator).to eq found
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it 'passes context to the decorator' do
|
|
111
|
+
Product.stub(:all)
|
|
112
|
+
context = { some: 'context' }
|
|
113
|
+
decorator = ProductDecorator.all(context: context)
|
|
114
|
+
|
|
115
|
+
expect(decorator.context).to be context
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
describe '.first' do
|
|
120
|
+
it 'proxies to the model class' do
|
|
121
|
+
Product.should_receive(:first)
|
|
122
|
+
ProductDecorator.first
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it 'decorates the result' do
|
|
126
|
+
first = Product.new
|
|
127
|
+
Product.stub(:first).and_return(first)
|
|
128
|
+
decorator = ProductDecorator.first
|
|
129
|
+
expect(decorator).to be_a ProductDecorator
|
|
130
|
+
expect(decorator.object).to be first
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it 'passes context to the decorator' do
|
|
134
|
+
Product.stub(:first)
|
|
135
|
+
context = { some: 'context' }
|
|
136
|
+
decorator = ProductDecorator.first(context: context)
|
|
137
|
+
|
|
138
|
+
expect(decorator.context).to be context
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
describe '.last' do
|
|
143
|
+
it 'proxies to the model class' do
|
|
144
|
+
Product.should_receive(:last)
|
|
145
|
+
ProductDecorator.last
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it 'decorates the result' do
|
|
149
|
+
last = Product.new
|
|
150
|
+
Product.stub(:last).and_return(last)
|
|
151
|
+
decorator = ProductDecorator.last
|
|
152
|
+
expect(decorator).to be_a ProductDecorator
|
|
153
|
+
expect(decorator.object).to be last
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
it 'passes context to the decorator' do
|
|
157
|
+
Product.stub(:last)
|
|
158
|
+
context = { some: 'context' }
|
|
159
|
+
decorator = ProductDecorator.last(context: context)
|
|
160
|
+
|
|
161
|
+
expect(decorator.context).to be context
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Drape
|
|
4
|
+
describe HelperProxy do
|
|
5
|
+
describe '#initialize' do
|
|
6
|
+
it 'sets the view context' do
|
|
7
|
+
view_context = double
|
|
8
|
+
helper_proxy = HelperProxy.new(view_context)
|
|
9
|
+
|
|
10
|
+
expect(helper_proxy.send(:view_context)).to be view_context
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
describe '#method_missing' do
|
|
15
|
+
protect_class HelperProxy
|
|
16
|
+
|
|
17
|
+
it 'proxies methods to the view context' do
|
|
18
|
+
view_context = double
|
|
19
|
+
helper_proxy = HelperProxy.new(view_context)
|
|
20
|
+
|
|
21
|
+
view_context.stub(:foo) { |arg| arg }
|
|
22
|
+
expect(helper_proxy.foo(:passed)).to be :passed
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'passes blocks' do
|
|
26
|
+
view_context = double
|
|
27
|
+
helper_proxy = HelperProxy.new(view_context)
|
|
28
|
+
|
|
29
|
+
view_context.stub(:foo) { |&block| block.call }
|
|
30
|
+
expect(helper_proxy.foo { :yielded }).to be :yielded
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'defines the method for better performance' do
|
|
34
|
+
helper_proxy = HelperProxy.new(double(foo: 'bar'))
|
|
35
|
+
|
|
36
|
+
expect(HelperProxy.instance_methods).not_to include :foo
|
|
37
|
+
helper_proxy.foo
|
|
38
|
+
expect(HelperProxy.instance_methods).to include :foo
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe '#respond_to_missing?' do
|
|
43
|
+
it 'allows #method to be called on the view context' do
|
|
44
|
+
helper_proxy = HelperProxy.new(double(foo: 'bar'))
|
|
45
|
+
|
|
46
|
+
expect(helper_proxy.respond_to?(:foo)).to be_truthy
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
describe 'proxying methods which are overriding' do
|
|
51
|
+
it 'proxies :capture' do
|
|
52
|
+
view_context = double
|
|
53
|
+
helper_proxy = HelperProxy.new(view_context)
|
|
54
|
+
|
|
55
|
+
allow(view_context).to receive(:capture) { |*args, &block| [*args, block.call] }
|
|
56
|
+
expect(helper_proxy.capture(:first_arg, :second_arg) { :yielded })
|
|
57
|
+
.to be_eql [:first_arg, :second_arg, :yielded]
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|