draper_new 3.0.0

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 (144) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +15 -0
  5. data/.yardopts +1 -0
  6. data/CHANGELOG.md +230 -0
  7. data/CONTRIBUTING.md +20 -0
  8. data/Gemfile +16 -0
  9. data/Guardfile +26 -0
  10. data/LICENSE +7 -0
  11. data/README.md +587 -0
  12. data/Rakefile +69 -0
  13. data/draper_new.gemspec +31 -0
  14. data/gemfiles/4.0.gemfile +3 -0
  15. data/gemfiles/4.1.gemfile +3 -0
  16. data/gemfiles/4.2.6.gemfile +3 -0
  17. data/gemfiles/4.2.gemfile +3 -0
  18. data/lib/draper.rb +63 -0
  19. data/lib/draper/automatic_delegation.rb +56 -0
  20. data/lib/draper/collection_decorator.rb +100 -0
  21. data/lib/draper/decoratable.rb +96 -0
  22. data/lib/draper/decoratable/equality.rb +26 -0
  23. data/lib/draper/decorated_association.rb +35 -0
  24. data/lib/draper/decorates_assigned.rb +44 -0
  25. data/lib/draper/decorator.rb +293 -0
  26. data/lib/draper/delegation.rb +13 -0
  27. data/lib/draper/factory.rb +91 -0
  28. data/lib/draper/finders.rb +37 -0
  29. data/lib/draper/helper_proxy.rb +44 -0
  30. data/lib/draper/helper_support.rb +5 -0
  31. data/lib/draper/lazy_helpers.rb +15 -0
  32. data/lib/draper/railtie.rb +70 -0
  33. data/lib/draper/tasks/test.rake +22 -0
  34. data/lib/draper/test/devise_helper.rb +30 -0
  35. data/lib/draper/test/minitest_integration.rb +6 -0
  36. data/lib/draper/test/rspec_integration.rb +20 -0
  37. data/lib/draper/test_case.rb +42 -0
  38. data/lib/draper/undecorate.rb +9 -0
  39. data/lib/draper/version.rb +3 -0
  40. data/lib/draper/view_context.rb +104 -0
  41. data/lib/draper/view_context/build_strategy.rb +48 -0
  42. data/lib/draper/view_helpers.rb +37 -0
  43. data/lib/generators/controller_override.rb +17 -0
  44. data/lib/generators/mini_test/decorator_generator.rb +20 -0
  45. data/lib/generators/mini_test/templates/decorator_spec.rb +4 -0
  46. data/lib/generators/mini_test/templates/decorator_test.rb +4 -0
  47. data/lib/generators/rails/decorator_generator.rb +36 -0
  48. data/lib/generators/rails/templates/decorator.rb +19 -0
  49. data/lib/generators/rspec/decorator_generator.rb +9 -0
  50. data/lib/generators/rspec/templates/decorator_spec.rb +4 -0
  51. data/lib/generators/test_unit/decorator_generator.rb +9 -0
  52. data/lib/generators/test_unit/templates/decorator_test.rb +4 -0
  53. data/spec/draper/collection_decorator_spec.rb +307 -0
  54. data/spec/draper/decoratable/equality_spec.rb +10 -0
  55. data/spec/draper/decoratable_spec.rb +202 -0
  56. data/spec/draper/decorated_association_spec.rb +84 -0
  57. data/spec/draper/decorates_assigned_spec.rb +71 -0
  58. data/spec/draper/decorator_spec.rb +816 -0
  59. data/spec/draper/factory_spec.rb +251 -0
  60. data/spec/draper/finders_spec.rb +166 -0
  61. data/spec/draper/helper_proxy_spec.rb +61 -0
  62. data/spec/draper/lazy_helpers_spec.rb +21 -0
  63. data/spec/draper/undecorate_spec.rb +19 -0
  64. data/spec/draper/view_context/build_strategy_spec.rb +116 -0
  65. data/spec/draper/view_context_spec.rb +154 -0
  66. data/spec/draper/view_helpers_spec.rb +8 -0
  67. data/spec/dummy/.rspec +2 -0
  68. data/spec/dummy/Rakefile +7 -0
  69. data/spec/dummy/app/controllers/application_controller.rb +4 -0
  70. data/spec/dummy/app/controllers/localized_urls.rb +5 -0
  71. data/spec/dummy/app/controllers/posts_controller.rb +20 -0
  72. data/spec/dummy/app/decorators/mongoid_post_decorator.rb +4 -0
  73. data/spec/dummy/app/decorators/post_decorator.rb +60 -0
  74. data/spec/dummy/app/helpers/application_helper.rb +5 -0
  75. data/spec/dummy/app/mailers/application_mailer.rb +3 -0
  76. data/spec/dummy/app/mailers/post_mailer.rb +19 -0
  77. data/spec/dummy/app/models/admin.rb +5 -0
  78. data/spec/dummy/app/models/mongoid_post.rb +5 -0
  79. data/spec/dummy/app/models/post.rb +3 -0
  80. data/spec/dummy/app/models/user.rb +5 -0
  81. data/spec/dummy/app/views/layouts/application.html.erb +11 -0
  82. data/spec/dummy/app/views/post_mailer/decorated_email.html.erb +1 -0
  83. data/spec/dummy/app/views/posts/_post.html.erb +40 -0
  84. data/spec/dummy/app/views/posts/show.html.erb +1 -0
  85. data/spec/dummy/bin/rails +4 -0
  86. data/spec/dummy/config.ru +4 -0
  87. data/spec/dummy/config/application.rb +71 -0
  88. data/spec/dummy/config/boot.rb +5 -0
  89. data/spec/dummy/config/database.yml +25 -0
  90. data/spec/dummy/config/environment.rb +5 -0
  91. data/spec/dummy/config/environments/development.rb +33 -0
  92. data/spec/dummy/config/environments/production.rb +57 -0
  93. data/spec/dummy/config/environments/test.rb +31 -0
  94. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  95. data/spec/dummy/config/initializers/inflections.rb +15 -0
  96. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  97. data/spec/dummy/config/initializers/secret_token.rb +8 -0
  98. data/spec/dummy/config/initializers/session_store.rb +8 -0
  99. data/spec/dummy/config/locales/en.yml +5 -0
  100. data/spec/dummy/config/mongoid.yml +79 -0
  101. data/spec/dummy/config/routes.rb +9 -0
  102. data/spec/dummy/db/migrate/20121019115657_create_posts.rb +8 -0
  103. data/spec/dummy/db/schema.rb +21 -0
  104. data/spec/dummy/db/seeds.rb +2 -0
  105. data/spec/dummy/fast_spec/post_decorator_spec.rb +37 -0
  106. data/spec/dummy/lib/tasks/test.rake +16 -0
  107. data/spec/dummy/public/404.html +26 -0
  108. data/spec/dummy/public/422.html +26 -0
  109. data/spec/dummy/public/500.html +25 -0
  110. data/spec/dummy/public/favicon.ico +0 -0
  111. data/spec/dummy/script/rails +6 -0
  112. data/spec/dummy/spec/decorators/active_model_serializers_spec.rb +16 -0
  113. data/spec/dummy/spec/decorators/devise_spec.rb +64 -0
  114. data/spec/dummy/spec/decorators/helpers_spec.rb +21 -0
  115. data/spec/dummy/spec/decorators/post_decorator_spec.rb +66 -0
  116. data/spec/dummy/spec/decorators/spec_type_spec.rb +7 -0
  117. data/spec/dummy/spec/decorators/view_context_spec.rb +22 -0
  118. data/spec/dummy/spec/mailers/post_mailer_spec.rb +33 -0
  119. data/spec/dummy/spec/models/mongoid_post_spec.rb +8 -0
  120. data/spec/dummy/spec/models/post_spec.rb +6 -0
  121. data/spec/dummy/spec/shared_examples/decoratable.rb +24 -0
  122. data/spec/dummy/spec/spec_helper.rb +8 -0
  123. data/spec/dummy/test/decorators/minitest/devise_test.rb +64 -0
  124. data/spec/dummy/test/decorators/minitest/helpers_test.rb +21 -0
  125. data/spec/dummy/test/decorators/minitest/spec_type_test.rb +52 -0
  126. data/spec/dummy/test/decorators/minitest/view_context_test.rb +24 -0
  127. data/spec/dummy/test/decorators/test_unit/devise_test.rb +64 -0
  128. data/spec/dummy/test/decorators/test_unit/helpers_test.rb +21 -0
  129. data/spec/dummy/test/decorators/test_unit/view_context_test.rb +24 -0
  130. data/spec/dummy/test/minitest_helper.rb +2 -0
  131. data/spec/dummy/test/test_helper.rb +3 -0
  132. data/spec/generators/controller/controller_generator_spec.rb +22 -0
  133. data/spec/generators/decorator/decorator_generator_spec.rb +92 -0
  134. data/spec/integration/integration_spec.rb +66 -0
  135. data/spec/performance/active_record.rb +4 -0
  136. data/spec/performance/benchmark.rb +55 -0
  137. data/spec/performance/decorators.rb +45 -0
  138. data/spec/performance/models.rb +20 -0
  139. data/spec/spec_helper.rb +41 -0
  140. data/spec/support/dummy_app.rb +85 -0
  141. data/spec/support/matchers/have_text.rb +50 -0
  142. data/spec/support/shared_examples/decoratable_equality.rb +40 -0
  143. data/spec/support/shared_examples/view_helpers.rb +39 -0
  144. metadata +420 -0
@@ -0,0 +1,37 @@
1
+ module Draper
2
+ # Provides the {#helpers} method used in {Decorator} and {CollectionDecorator}
3
+ # to call the Rails helpers.
4
+ module ViewHelpers
5
+ extend ActiveSupport::Concern
6
+
7
+ module ClassMethods
8
+
9
+ # Access the helpers proxy to call built-in and user-defined
10
+ # Rails helpers from a class context.
11
+ #
12
+ # @return [HelperProxy] the helpers proxy
13
+ def helpers
14
+ Draper::ViewContext.current
15
+ end
16
+ alias_method :h, :helpers
17
+
18
+ end
19
+
20
+ # Access the helpers proxy to call built-in and user-defined
21
+ # Rails helpers. Aliased to `h` for convenience.
22
+ #
23
+ # @return [HelperProxy] the helpers proxy
24
+ def helpers
25
+ Draper::ViewContext.current
26
+ end
27
+ alias_method :h, :helpers
28
+
29
+ # Alias for `helpers.localize`, since localize is something that's used
30
+ # quite often. Further aliased to `l` for convenience.
31
+ def localize(*args)
32
+ helpers.localize(*args)
33
+ end
34
+ alias_method :l, :localize
35
+
36
+ end
37
+ end
@@ -0,0 +1,17 @@
1
+ require "rails/generators"
2
+ require "rails/generators/rails/controller/controller_generator"
3
+ require "rails/generators/rails/scaffold_controller/scaffold_controller_generator"
4
+
5
+ module Rails
6
+ module Generators
7
+ class ControllerGenerator
8
+ hook_for :decorator, default: true do |generator|
9
+ invoke generator, [name.singularize]
10
+ end
11
+ end
12
+
13
+ class ScaffoldControllerGenerator
14
+ hook_for :decorator, default: true
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ require 'generators/mini_test'
2
+
3
+ module MiniTest
4
+ module Generators
5
+ class DecoratorGenerator < Base
6
+ def self.source_root
7
+ File.expand_path('../templates', __FILE__)
8
+ end
9
+
10
+ class_option :spec, :type => :boolean, :default => false, :desc => "Use MiniTest::Spec DSL"
11
+
12
+ check_class_collision suffix: "DecoratorTest"
13
+
14
+ def create_test_file
15
+ template_type = options[:spec] ? "spec" : "test"
16
+ template "decorator_#{template_type}.rb", File.join("test/decorators", class_path, "#{singular_name}_decorator_test.rb")
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,4 @@
1
+ require 'test_helper'
2
+
3
+ describe <%= class_name %>Decorator do
4
+ end
@@ -0,0 +1,4 @@
1
+ require 'test_helper'
2
+
3
+ class <%= class_name %>DecoratorTest < Draper::TestCase
4
+ end
@@ -0,0 +1,36 @@
1
+ module Rails
2
+ module Generators
3
+ class DecoratorGenerator < NamedBase
4
+ source_root File.expand_path("../templates", __FILE__)
5
+ check_class_collision suffix: "Decorator"
6
+
7
+ class_option :parent, type: :string, desc: "The parent class for the generated decorator"
8
+
9
+ def create_decorator_file
10
+ template 'decorator.rb', File.join('app/decorators', class_path, "#{file_name}_decorator.rb")
11
+ end
12
+
13
+ hook_for :test_framework
14
+
15
+ private
16
+
17
+ def parent_class_name
18
+ options.fetch("parent") do
19
+ begin
20
+ require 'application_decorator'
21
+ ApplicationDecorator
22
+ rescue LoadError
23
+ "Draper::Decorator"
24
+ end
25
+ end
26
+ end
27
+
28
+ # Rails 3.0.X compatibility, stolen from https://github.com/jnunemaker/mongomapper/pull/385/files#L1R32
29
+ unless methods.include?(:module_namespacing)
30
+ def module_namespacing
31
+ yield if block_given?
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,19 @@
1
+ <%- module_namespacing do -%>
2
+ <%- if parent_class_name.present? -%>
3
+ class <%= class_name %>Decorator < <%= parent_class_name %>
4
+ <%- else -%>
5
+ class <%= class_name %>
6
+ <%- end -%>
7
+ delegate_all
8
+
9
+ # Define presentation-specific methods here. Helpers are accessed through
10
+ # `helpers` (aka `h`). You can override attributes, for example:
11
+ #
12
+ # def created_at
13
+ # helpers.content_tag :span, class: 'time' do
14
+ # object.created_at.strftime("%a %m/%d/%y")
15
+ # end
16
+ # end
17
+
18
+ end
19
+ <% end -%>
@@ -0,0 +1,9 @@
1
+ module Rspec
2
+ class DecoratorGenerator < ::Rails::Generators::NamedBase
3
+ source_root File.expand_path('../templates', __FILE__)
4
+
5
+ def create_spec_file
6
+ template 'decorator_spec.rb', File.join('spec/decorators', class_path, "#{singular_name}_decorator_spec.rb")
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe <%= class_name %>Decorator do
4
+ end
@@ -0,0 +1,9 @@
1
+ module TestUnit
2
+ class DecoratorGenerator < ::Rails::Generators::NamedBase
3
+ source_root File.expand_path('../templates', __FILE__)
4
+
5
+ def create_test_file
6
+ template 'decorator_test.rb', File.join('test/decorators', class_path, "#{singular_name}_decorator_test.rb")
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ require 'test_helper'
2
+
3
+ class <%= class_name %>DecoratorTest < Draper::TestCase
4
+ end
@@ -0,0 +1,307 @@
1
+ require 'spec_helper'
2
+ require 'support/shared_examples/view_helpers'
3
+
4
+ module Draper
5
+ describe CollectionDecorator do
6
+ it_behaves_like "view helpers", CollectionDecorator.new([])
7
+
8
+ describe "#initialize" do
9
+ describe "options validation" do
10
+
11
+ it "does not raise error on valid options" do
12
+ valid_options = {with: Decorator, context: {}}
13
+ expect{CollectionDecorator.new([], valid_options)}.not_to raise_error
14
+ end
15
+
16
+ it "raises error on invalid options" do
17
+ expect{CollectionDecorator.new([], foo: "bar")}.to raise_error ArgumentError, /Unknown key/
18
+ end
19
+ end
20
+ end
21
+
22
+ context "with context" do
23
+ it "stores the context itself" do
24
+ context = {some: "context"}
25
+ decorator = CollectionDecorator.new([], context: context)
26
+
27
+ expect(decorator.context).to be context
28
+ end
29
+
30
+ it "passes context to the individual decorators" do
31
+ context = {some: "context"}
32
+ decorator = CollectionDecorator.new([Product.new, Product.new], context: context)
33
+
34
+ decorator.each do |item|
35
+ expect(item.context).to be context
36
+ end
37
+ end
38
+ end
39
+
40
+ describe "#context=" do
41
+ it "updates the stored context" do
42
+ decorator = CollectionDecorator.new([], context: {some: "context"})
43
+ new_context = {other: "context"}
44
+
45
+ decorator.context = new_context
46
+ expect(decorator.context).to be new_context
47
+ end
48
+
49
+ context "when the collection is already decorated" do
50
+ it "updates the items' context" do
51
+ decorator = CollectionDecorator.new([Product.new, Product.new], context: {some: "context"})
52
+ decorator.decorated_collection # trigger decoration
53
+ new_context = {other: "context"}
54
+
55
+ decorator.context = new_context
56
+ decorator.each do |item|
57
+ expect(item.context).to be new_context
58
+ end
59
+ end
60
+ end
61
+
62
+ context "when the collection has not yet been decorated" do
63
+ it "does not trigger decoration" do
64
+ decorator = CollectionDecorator.new([])
65
+
66
+ decorator.should_not_receive(:decorated_collection)
67
+ decorator.context = {other: "context"}
68
+ end
69
+
70
+ it "sets context after decoration is triggered" do
71
+ decorator = CollectionDecorator.new([Product.new, Product.new], context: {some: "context"})
72
+ new_context = {other: "context"}
73
+
74
+ decorator.context = new_context
75
+ decorator.each do |item|
76
+ expect(item.context).to be new_context
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ describe "item decoration" do
83
+ it "sets decorated items' source models" do
84
+ collection = [Product.new, Product.new]
85
+ decorator = CollectionDecorator.new(collection)
86
+
87
+ decorator.zip collection do |item, object|
88
+ expect(item.object).to be object
89
+ end
90
+ end
91
+
92
+ context "when the :with option was given" do
93
+ it "uses the :with option" do
94
+ decorator = CollectionDecorator.new([Product.new], with: OtherDecorator).first
95
+
96
+ expect(decorator).to be_decorated_with OtherDecorator
97
+ end
98
+ end
99
+
100
+ context "when the :with option was not given" do
101
+ it "infers the item decorator from each item" do
102
+ decorator = CollectionDecorator.new([double(decorate: :inferred_decorator)]).first
103
+
104
+ expect(decorator).to be :inferred_decorator
105
+ end
106
+ end
107
+ end
108
+
109
+ describe ".delegate" do
110
+ protect_class ProductsDecorator
111
+
112
+ it "defaults the :to option to :object" do
113
+ Object.should_receive(:delegate).with(:foo, :bar, to: :object)
114
+ ProductsDecorator.delegate :foo, :bar
115
+ end
116
+
117
+ it "does not overwrite the :to option if supplied" do
118
+ Object.should_receive(:delegate).with(:foo, :bar, to: :baz)
119
+ ProductsDecorator.delegate :foo, :bar, to: :baz
120
+ end
121
+ end
122
+
123
+ describe "#find" do
124
+ context "with a block" do
125
+ it "decorates Enumerable#find" do
126
+ decorator = CollectionDecorator.new([])
127
+
128
+ decorator.decorated_collection.should_receive(:find).and_return(:delegated)
129
+ expect(decorator.find{|p| p.title == "title"}).to be :delegated
130
+ end
131
+ end
132
+
133
+ context "without a block" do
134
+ it "decorates object.find" do
135
+ object = []
136
+ found = double(decorate: :decorated)
137
+ decorator = CollectionDecorator.new(object)
138
+
139
+ object.should_receive(:find).and_return(found)
140
+ ActiveSupport::Deprecation.silence do
141
+ expect(decorator.find(1)).to be :decorated
142
+ end
143
+ end
144
+ end
145
+ end
146
+
147
+ describe "#to_ary" do
148
+ # required for `render @collection` in Rails
149
+ it "delegates to the decorated collection" do
150
+ decorator = CollectionDecorator.new([])
151
+
152
+ decorator.decorated_collection.should_receive(:to_ary).and_return(:delegated)
153
+ expect(decorator.to_ary).to be :delegated
154
+ end
155
+ end
156
+
157
+ it "delegates array methods to the decorated collection" do
158
+ decorator = CollectionDecorator.new([])
159
+
160
+ decorator.decorated_collection.should_receive(:[]).with(42).and_return(:delegated)
161
+ expect(decorator[42]).to be :delegated
162
+ end
163
+
164
+ describe "#==" do
165
+ context "when comparing to a collection decorator with the same object" do
166
+ it "returns true" do
167
+ object = [Product.new, Product.new]
168
+ decorator = CollectionDecorator.new(object)
169
+ other = ProductsDecorator.new(object)
170
+
171
+ expect(decorator == other).to be_truthy
172
+ end
173
+ end
174
+
175
+ context "when comparing to a collection decorator with a different object" do
176
+ it "returns false" do
177
+ decorator = CollectionDecorator.new([Product.new, Product.new])
178
+ other = ProductsDecorator.new([Product.new, Product.new])
179
+
180
+ expect(decorator == other).to be_falsey
181
+ end
182
+ end
183
+
184
+ context "when comparing to a collection of the same items" do
185
+ it "returns true" do
186
+ object = [Product.new, Product.new]
187
+ decorator = CollectionDecorator.new(object)
188
+ other = object.dup
189
+
190
+ expect(decorator == other).to be_truthy
191
+ end
192
+ end
193
+
194
+ context "when comparing to a collection of different items" do
195
+ it "returns false" do
196
+ decorator = CollectionDecorator.new([Product.new, Product.new])
197
+ other = [Product.new, Product.new]
198
+
199
+ expect(decorator == other).to be_falsey
200
+ end
201
+ end
202
+
203
+ context "when the decorated collection has been modified" do
204
+ it "is no longer equal to the object" do
205
+ object = [Product.new, Product.new]
206
+ decorator = CollectionDecorator.new(object)
207
+ other = object.dup
208
+
209
+ decorator << Product.new.decorate
210
+ expect(decorator == other).to be_falsey
211
+ end
212
+ end
213
+ end
214
+
215
+ describe "#to_s" do
216
+ context "when :with option was given" do
217
+ it "returns a string representation of the collection decorator" do
218
+ decorator = CollectionDecorator.new(["a", "b", "c"], with: ProductDecorator)
219
+
220
+ expect(decorator.to_s).to eq '#<Draper::CollectionDecorator of ProductDecorator for ["a", "b", "c"]>'
221
+ end
222
+ end
223
+
224
+ context "when :with option was not given" do
225
+ it "returns a string representation of the collection decorator" do
226
+ decorator = CollectionDecorator.new(["a", "b", "c"])
227
+
228
+ expect(decorator.to_s).to eq '#<Draper::CollectionDecorator of inferred decorators for ["a", "b", "c"]>'
229
+ end
230
+ end
231
+
232
+ context "for a custom subclass" do
233
+ it "uses the custom class name" do
234
+ decorator = ProductsDecorator.new([])
235
+
236
+ expect(decorator.to_s).to match /ProductsDecorator/
237
+ end
238
+ end
239
+ end
240
+
241
+ describe '#object' do
242
+ it 'returns the underlying collection' do
243
+ collection = [Product.new]
244
+ decorator = ProductsDecorator.new(collection)
245
+
246
+ expect(decorator.object).to eq collection
247
+ end
248
+ end
249
+
250
+ describe '#decorated?' do
251
+ it 'returns true' do
252
+ decorator = ProductsDecorator.new([Product.new])
253
+
254
+ expect(decorator).to be_decorated
255
+ end
256
+ end
257
+
258
+ describe '#decorated_with?' do
259
+ it "checks if a decorator has been applied to a collection" do
260
+ decorator = ProductsDecorator.new([Product.new])
261
+
262
+ expect(decorator).to be_decorated_with ProductsDecorator
263
+ expect(decorator).not_to be_decorated_with OtherDecorator
264
+ end
265
+ end
266
+
267
+ describe '#kind_of?' do
268
+ it 'asks the kind of its decorated collection' do
269
+ decorator = ProductsDecorator.new([])
270
+ decorator.decorated_collection.should_receive(:kind_of?).with(Array).and_return("true")
271
+ expect(decorator.kind_of?(Array)).to eq "true"
272
+ end
273
+
274
+ context 'when asking the underlying collection returns false' do
275
+ it 'asks the CollectionDecorator instance itself' do
276
+ decorator = ProductsDecorator.new([])
277
+ decorator.decorated_collection.stub(:kind_of?).with(::Draper::CollectionDecorator).and_return(false)
278
+ expect(decorator.kind_of?(::Draper::CollectionDecorator)).to be true
279
+ end
280
+ end
281
+ end
282
+
283
+ describe '#is_a?' do
284
+ it 'aliases to #kind_of?' do
285
+ decorator = ProductsDecorator.new([])
286
+ expect(decorator.method(:kind_of?)).to eq decorator.method(:is_a?)
287
+ end
288
+ end
289
+
290
+ describe "#replace" do
291
+ it "replaces the decorated collection" do
292
+ decorator = CollectionDecorator.new([Product.new])
293
+ replacement = [:foo, :bar]
294
+
295
+ decorator.replace replacement
296
+ expect(decorator).to match_array replacement
297
+ end
298
+
299
+ it "returns itself" do
300
+ decorator = CollectionDecorator.new([Product.new])
301
+
302
+ expect(decorator.replace([:foo, :bar])).to be decorator
303
+ end
304
+ end
305
+
306
+ end
307
+ end