draper 0.10.0 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +0 -1
- data/Gemfile +3 -3
- data/Rakefile +8 -8
- data/Readme.markdown +41 -22
- data/doc/css/full_list.css +2 -2
- data/doc/css/style.css +30 -30
- data/doc/js/app.js +10 -10
- data/doc/js/full_list.js +8 -8
- data/draper.gemspec +2 -2
- data/lib/draper.rb +1 -1
- data/lib/draper/base.rb +65 -22
- data/lib/draper/decorated_enumerable_proxy.rb +6 -1
- data/lib/draper/model_support.rb +2 -2
- data/lib/draper/railtie.rb +19 -0
- data/lib/draper/system.rb +7 -4
- data/lib/draper/version.rb +1 -1
- data/lib/generators/draper/decorator/decorator_generator.rb +26 -4
- data/lib/generators/draper/decorator/templates/decorator.rb +2 -2
- data/lib/generators/{rspec → draper/decorator}/templates/decorator_spec.rb +1 -1
- data/lib/generators/{test_unit → draper/decorator}/templates/decorator_test.rb +1 -1
- data/lib/generators/draper/install/install_generator.rb +6 -6
- data/lib/generators/rails/decorator_generator.rb +3 -3
- data/performance/bechmark.rb +5 -5
- data/performance/decorators.rb +4 -4
- data/performance/models.rb +2 -2
- data/spec/draper/base_spec.rb +176 -10
- data/spec/draper/helper_support_spec.rb +1 -1
- data/spec/draper/model_support_spec.rb +23 -14
- data/spec/draper/view_context_spec.rb +4 -4
- data/spec/generators/draper/decorator/decorator_generator_spec.rb +81 -1
- data/spec/generators/draper/install/install_generator_spec.rb +5 -5
- data/spec/spec_helper.rb +3 -0
- data/spec/support/samples/application_controller.rb +8 -11
- data/spec/support/samples/decorator_with_allows.rb +1 -1
- data/spec/support/samples/decorator_with_application_helper.rb +5 -5
- data/spec/support/samples/decorator_with_denies.rb +1 -1
- data/spec/support/samples/decorator_with_multiple_allows.rb +4 -0
- data/spec/support/samples/product.rb +28 -7
- data/spec/support/samples/some_thing.rb +2 -0
- data/spec/support/samples/some_thing_decorator.rb +3 -0
- metadata +62 -37
- data/lib/generators/rspec/decorator_generator.rb +0 -11
- data/lib/generators/test_unit/decorator_generator.rb +0 -11
- data/spec/generators/rspec/decorator_generator_spec.rb +0 -22
- data/spec/generators/test_unit/decorator_generator_spec.rb +0 -22
data/performance/models.rb
CHANGED
@@ -3,7 +3,7 @@ class Product < ActiveRecord::Base
|
|
3
3
|
def self.sample_class_method
|
4
4
|
"sample class method"
|
5
5
|
end
|
6
|
-
|
6
|
+
|
7
7
|
def hello_world
|
8
8
|
"Hello, World"
|
9
9
|
end
|
@@ -13,7 +13,7 @@ class FastProduct < ActiveRecord::Base
|
|
13
13
|
def self.sample_class_method
|
14
14
|
"sample class method"
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
def hello_world
|
18
18
|
"Hello, World"
|
19
19
|
end
|
data/spec/draper/base_spec.rb
CHANGED
@@ -54,6 +54,44 @@ describe Draper::Base do
|
|
54
54
|
end.should_not raise_error
|
55
55
|
end
|
56
56
|
|
57
|
+
context("accepts ActiveRecord like :class_name option too") do
|
58
|
+
it "accepts constants for :class" do
|
59
|
+
expect do
|
60
|
+
class CustomDecorator < Draper::Base
|
61
|
+
decorates :product, :class => Product
|
62
|
+
end
|
63
|
+
CustomDecorator.model_class.should == Product
|
64
|
+
end.should_not raise_error
|
65
|
+
end
|
66
|
+
|
67
|
+
it "accepts constants for :class_name" do
|
68
|
+
expect do
|
69
|
+
class CustomDecorator < Draper::Base
|
70
|
+
decorates :product, :class_name => Product
|
71
|
+
end
|
72
|
+
CustomDecorator.model_class.should == Product
|
73
|
+
end.should_not raise_error
|
74
|
+
end
|
75
|
+
|
76
|
+
it "accepts strings for :class" do
|
77
|
+
expect do
|
78
|
+
class CustomDecorator < Draper::Base
|
79
|
+
decorates :product, :class => 'Product'
|
80
|
+
end
|
81
|
+
CustomDecorator.model_class.should == Product
|
82
|
+
end.should_not raise_error
|
83
|
+
end
|
84
|
+
|
85
|
+
it "accepts strings for :class_name" do
|
86
|
+
expect do
|
87
|
+
class CustomDecorator < Draper::Base
|
88
|
+
decorates :product, :class_name => 'Product'
|
89
|
+
end
|
90
|
+
CustomDecorator.model_class.should == Product
|
91
|
+
end.should_not raise_error
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
57
95
|
it "creates a named accessor for the wrapped model" do
|
58
96
|
pd = ProductDecorator.new(source)
|
59
97
|
pd.send(:product).should == source
|
@@ -75,22 +113,31 @@ describe Draper::Base do
|
|
75
113
|
end
|
76
114
|
|
77
115
|
context(".decorates_association") do
|
78
|
-
context "for collection associations" do
|
116
|
+
context "for ActiveModel collection associations" do
|
79
117
|
before(:each){ subject.class_eval{ decorates_association :similar_products } }
|
80
118
|
it "causes the association's method to return a collection of wrapped objects" do
|
81
119
|
subject.similar_products.each{ |decorated| decorated.should be_instance_of(ProductDecorator) }
|
82
120
|
end
|
83
121
|
end
|
84
122
|
|
85
|
-
context "for
|
123
|
+
context "for Plain Old Ruby Object collection associations" do
|
124
|
+
before(:each){ subject.class_eval{ decorates_association :poro_similar_products } }
|
125
|
+
it "causes the association's method to return a collection of wrapped objects" do
|
126
|
+
subject.poro_similar_products.each{ |decorated| decorated.should be_instance_of(ProductDecorator) }
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context "for an ActiveModel singular association" do
|
86
131
|
before(:each){ subject.class_eval{ decorates_association :previous_version } }
|
87
132
|
it "causes the association's method to return a single wrapped object if the association is singular" do
|
88
133
|
subject.previous_version.should be_instance_of(ProductDecorator)
|
89
134
|
end
|
135
|
+
end
|
90
136
|
|
91
|
-
|
92
|
-
|
93
|
-
|
137
|
+
context "for a Plain Old Ruby Object singular association" do
|
138
|
+
before(:each){ subject.class_eval{ decorates_association :poro_previous_version } }
|
139
|
+
it "causes the association's method to return a single wrapped object" do
|
140
|
+
subject.poro_previous_version.should be_instance_of(ProductDecorator)
|
94
141
|
end
|
95
142
|
end
|
96
143
|
|
@@ -100,6 +147,23 @@ describe Draper::Base do
|
|
100
147
|
subject.previous_version.should be_instance_of(SpecificProductDecorator)
|
101
148
|
end
|
102
149
|
end
|
150
|
+
|
151
|
+
context "for a polymorphic association" do
|
152
|
+
before(:each){ subject.class_eval{ decorates_association :thing, :polymorphic => true } }
|
153
|
+
it "causes the association to be decorated with the right decorator" do
|
154
|
+
subject.thing.should be_instance_of(SomeThingDecorator)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
context "when the association is nil" do
|
159
|
+
before(:each) do
|
160
|
+
subject.class_eval{ decorates_association :previous_version }
|
161
|
+
source.stub(:previous_version){ nil }
|
162
|
+
end
|
163
|
+
it "causes the association's method to return nil" do
|
164
|
+
subject.previous_version.should be_nil
|
165
|
+
end
|
166
|
+
end
|
103
167
|
end
|
104
168
|
|
105
169
|
context('.decorates_associations') do
|
@@ -119,6 +183,13 @@ describe Draper::Base do
|
|
119
183
|
end
|
120
184
|
end
|
121
185
|
|
186
|
+
context(".source / .to_source") do
|
187
|
+
it "should return the wrapped object" do
|
188
|
+
subject.to_source == source
|
189
|
+
subject.source == source
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
122
193
|
context("selecting methods") do
|
123
194
|
it "echos the methods of the wrapped class except default exclusions" do
|
124
195
|
source.methods.each do |method|
|
@@ -178,6 +249,34 @@ describe Draper::Base do
|
|
178
249
|
end
|
179
250
|
end
|
180
251
|
|
252
|
+
context ".find_by_(x)" do
|
253
|
+
it "runs the similarly named finder" do
|
254
|
+
Product.should_receive(:find_by_name)
|
255
|
+
ProductDecorator.find_by_name("apples")
|
256
|
+
end
|
257
|
+
|
258
|
+
it "returns a decorated result" do
|
259
|
+
ProductDecorator.find_by_name("apples").should be_kind_of(ProductDecorator)
|
260
|
+
end
|
261
|
+
|
262
|
+
it "runs complex finders" do
|
263
|
+
Product.should_receive(:find_by_name_and_size)
|
264
|
+
ProductDecorator.find_by_name_and_size("apples", "large")
|
265
|
+
end
|
266
|
+
|
267
|
+
it "accepts an options hash" do
|
268
|
+
Product.should_receive(:find_by_name_and_size).with("apples", "large", {:role => :admin})
|
269
|
+
ProductDecorator.find_by_name_and_size("apples", "large", {:role => :admin})
|
270
|
+
end
|
271
|
+
|
272
|
+
it "uses the options hash in the decorator instantiation" do
|
273
|
+
pending "Figure out an implementation that supports multiple args (find_by_name_and_count_and_size) plus an options hash"
|
274
|
+
Product.should_receive(:find_by_name_and_size).with("apples", "large", {:role => :admin})
|
275
|
+
pd = ProductDecorator.find_by_name_and_size("apples", "large", {:role => :admin})
|
276
|
+
pd.context[:role].should == :admin
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
181
280
|
context ".decorate" do
|
182
281
|
context "without any context" do
|
183
282
|
subject { Draper::Base.decorate(source) }
|
@@ -196,6 +295,25 @@ describe Draper::Base do
|
|
196
295
|
let(:source) { Product.new }
|
197
296
|
|
198
297
|
it { should be_instance_of(Draper::Base) }
|
298
|
+
|
299
|
+
context "when the input is already decorated" do
|
300
|
+
it "does not perform double-decoration" do
|
301
|
+
decorated = ProductDecorator.decorate(source)
|
302
|
+
ProductDecorator.decorate(decorated).object_id.should == decorated.object_id
|
303
|
+
end
|
304
|
+
|
305
|
+
it "overwrites options with provided options" do
|
306
|
+
first_run = ProductDecorator.decorate(source, :context => {:role => :user})
|
307
|
+
second_run = ProductDecorator.decorate(first_run, :context => {:role => :admin})
|
308
|
+
second_run.context[:role].should == :admin
|
309
|
+
end
|
310
|
+
|
311
|
+
it "leaves existing options if none are supplied" do
|
312
|
+
first_run = ProductDecorator.decorate(source, :context => {:role => :user})
|
313
|
+
second_run = ProductDecorator.decorate(first_run)
|
314
|
+
second_run.context[:role].should == :user
|
315
|
+
end
|
316
|
+
end
|
199
317
|
end
|
200
318
|
end
|
201
319
|
|
@@ -219,6 +337,14 @@ describe Draper::Base do
|
|
219
337
|
end
|
220
338
|
end
|
221
339
|
|
340
|
+
context "with options" do
|
341
|
+
let(:options) {{ :more => "settings" }}
|
342
|
+
|
343
|
+
subject { Draper::Base.decorate(source, options ) }
|
344
|
+
|
345
|
+
its(:options) { should eq(options) }
|
346
|
+
end
|
347
|
+
|
222
348
|
context "does not infer collections by default" do
|
223
349
|
subject { Draper::Base.decorate(source).to_ary }
|
224
350
|
|
@@ -352,10 +478,10 @@ describe Draper::Base do
|
|
352
478
|
subject = ProductDecorator.decorate(paged_array)
|
353
479
|
subject[0].should be_instance_of ProductDecorator
|
354
480
|
end
|
355
|
-
|
481
|
+
|
356
482
|
context "pretends to be of kind of wrapped collection class" do
|
357
483
|
subject { ProductDecorator.decorate(paged_array) }
|
358
|
-
|
484
|
+
|
359
485
|
it "#kind_of? DecoratedEnumerableProxy" do
|
360
486
|
subject.should be_kind_of Draper::DecoratedEnumerableProxy
|
361
487
|
end
|
@@ -383,6 +509,13 @@ describe Draper::Base do
|
|
383
509
|
collection.first.context.should == :admin
|
384
510
|
end
|
385
511
|
end
|
512
|
+
|
513
|
+
context(".source / .to_source") do
|
514
|
+
it "should return the wrapped object" do
|
515
|
+
subject.to_source == source
|
516
|
+
subject.source == source
|
517
|
+
end
|
518
|
+
end
|
386
519
|
end
|
387
520
|
|
388
521
|
describe "a sample usage with denies" do
|
@@ -408,6 +541,8 @@ describe Draper::Base do
|
|
408
541
|
describe "a sample usage with allows" do
|
409
542
|
let(:subject_with_allows){ DecoratorWithAllows.new(source) }
|
410
543
|
|
544
|
+
let(:subject_with_multiple_allows){ DecoratorWithMultipleAllows.new(source) }
|
545
|
+
|
411
546
|
it "should echo the allowed method" do
|
412
547
|
subject_with_allows.should respond_to(:goodnight_moon)
|
413
548
|
end
|
@@ -415,6 +550,15 @@ describe Draper::Base do
|
|
415
550
|
it "should echo _only_ the allowed method" do
|
416
551
|
subject_with_allows.should_not respond_to(:hello_world)
|
417
552
|
end
|
553
|
+
|
554
|
+
it "should echo the combined allowed methods" do
|
555
|
+
subject_with_multiple_allows.should respond_to(:goodnight_moon)
|
556
|
+
subject_with_multiple_allows.should respond_to(:hello_world)
|
557
|
+
end
|
558
|
+
|
559
|
+
it "should echo _only_ the combined allowed methods" do
|
560
|
+
subject_with_multiple_allows.should_not respond_to(:title)
|
561
|
+
end
|
418
562
|
end
|
419
563
|
|
420
564
|
describe "invalid usages of allows and denies" do
|
@@ -479,8 +623,14 @@ describe Draper::Base do
|
|
479
623
|
it "should be able to use the pluralize helper" do
|
480
624
|
decorator.sample_truncate.should == "Once..."
|
481
625
|
end
|
626
|
+
|
627
|
+
it "should be able to use l rather than helpers.l" do
|
628
|
+
now = Time.now
|
629
|
+
decorator.helpers.should_receive(:localize).with(now)
|
630
|
+
decorator.l now
|
631
|
+
end
|
482
632
|
end
|
483
|
-
|
633
|
+
|
484
634
|
describe "#method_missing" do
|
485
635
|
context "when #hello_world is called for the first time" do
|
486
636
|
it "hits method missing" do
|
@@ -488,7 +638,7 @@ describe Draper::Base do
|
|
488
638
|
subject.hello_world
|
489
639
|
end
|
490
640
|
end
|
491
|
-
|
641
|
+
|
492
642
|
context "when #hello_world is called again" do
|
493
643
|
before { subject.hello_world }
|
494
644
|
it "proxies method directly after first hit" do
|
@@ -496,10 +646,26 @@ describe Draper::Base do
|
|
496
646
|
subject.hello_world
|
497
647
|
end
|
498
648
|
end
|
649
|
+
|
650
|
+
context "when the delegated method calls a non-existant method" do
|
651
|
+
it 'should not try to delegate to non-existant methods to not confuse Kernel#Array' do
|
652
|
+
Array(subject).should be_kind_of(Array)
|
653
|
+
end
|
654
|
+
|
655
|
+
it "raises the correct NoMethodError" do
|
656
|
+
begin
|
657
|
+
subject.some_action
|
658
|
+
rescue NoMethodError => e
|
659
|
+
e.name.should_not == :some_action
|
660
|
+
else
|
661
|
+
fail("No exception raised")
|
662
|
+
end
|
663
|
+
end
|
664
|
+
end
|
499
665
|
end
|
500
666
|
|
501
667
|
describe "#kind_of?" do
|
502
|
-
context "pretends to be of kind of model class" do
|
668
|
+
context "pretends to be of kind of model class" do
|
503
669
|
it "#kind_of? decorator class" do
|
504
670
|
subject.should be_kind_of subject.class
|
505
671
|
end
|
@@ -8,7 +8,7 @@ describe Draper::HelperSupport do
|
|
8
8
|
output = ApplicationController.decorate(@product){|p| p.model.object_id }
|
9
9
|
output.should == @product.object_id
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
it 'uses #capture so Rails only renders the content once' do
|
13
13
|
ApplicationController.decorate(@product){|p| p.model.object_id }
|
14
14
|
ApplicationController.capture_triggered.should be
|
@@ -11,29 +11,38 @@ describe Draper::ModelSupport do
|
|
11
11
|
a = Product.new.decorator { |d| d.awesome_title }
|
12
12
|
a.should eql "Awesome Title"
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
it 'should be aliased to .decorate' do
|
16
16
|
subject.decorator.model.should == subject.decorate.model
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
describe
|
21
|
-
|
22
|
-
|
20
|
+
describe Draper::ModelSupport::ClassMethods do
|
21
|
+
shared_examples_for "a call to Draper::ModelSupport::ClassMethods#decorate" do
|
22
|
+
subject { klass.limit }
|
23
|
+
|
24
|
+
its(:decorate) { should be_kind_of(Draper::DecoratedEnumerableProxy) }
|
23
25
|
|
24
|
-
|
25
|
-
|
26
|
-
|
26
|
+
it "should decorate the collection" do
|
27
|
+
subject.decorate.size.should == 1
|
28
|
+
subject.decorate.to_ary[0].model.should be_a(klass)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should return a new instance each time it is called" do
|
32
|
+
subject.decorate.should_not == subject.decorate
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#decorate - decorate collections of AR objects' do
|
37
|
+
let(:klass) { Product }
|
38
|
+
|
39
|
+
it_should_behave_like "a call to Draper::ModelSupport::ClassMethods#decorate"
|
27
40
|
end
|
28
|
-
end
|
29
41
|
|
30
|
-
|
31
|
-
|
32
|
-
its(:decorate) { should be_kind_of(Draper::DecoratedEnumerableProxy) }
|
42
|
+
describe '#decorate - decorate collections of namespaced AR objects' do
|
43
|
+
let(:klass) { Namespace::Product }
|
33
44
|
|
34
|
-
|
35
|
-
subject.decorate.size.should == 1
|
36
|
-
subject.decorate.to_ary[0].model.should be_a(Namespace::Product)
|
45
|
+
it_should_behave_like "a call to Draper::ModelSupport::ClassMethods#decorate"
|
37
46
|
end
|
38
47
|
end
|
39
48
|
end
|
@@ -4,19 +4,19 @@ describe Draper::ViewContext do
|
|
4
4
|
let (:app_controller) do
|
5
5
|
ApplicationController
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
let (:app_controller_instance) do
|
9
9
|
app_controller.new
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
it "implements #set_current_view_context" do
|
13
13
|
app_controller_instance.should respond_to(:set_current_view_context)
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
it "calls #before_filter with #set_current_view_context" do
|
17
17
|
app_controller.before_filters.should include(:set_current_view_context)
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
it "raises an exception if the view_context is fetched without being set" do
|
21
21
|
Draper::ViewContext.current = nil
|
22
22
|
expect {app_controller.current_view_context}.should raise_exception(Exception)
|
@@ -9,6 +9,49 @@ describe Draper::DecoratorGenerator do
|
|
9
9
|
|
10
10
|
before { prepare_destination }
|
11
11
|
|
12
|
+
context 'decorator context' do
|
13
|
+
before { run_generator ["product"] }
|
14
|
+
|
15
|
+
describe 'app/decorators/product_decorator.rb' do
|
16
|
+
subject { file('app/decorators/product_decorator.rb') }
|
17
|
+
it { should exist }
|
18
|
+
it { should contain "class ProductDecorator < ApplicationDecorator" }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'default test framework' do
|
23
|
+
before { run_generator ["product"] }
|
24
|
+
|
25
|
+
describe 'spec/decorators/product_decorator_spec.rb' do
|
26
|
+
subject { file('spec/decorators/product_decorator_spec.rb') }
|
27
|
+
it { should exist }
|
28
|
+
it { should contain "describe ProductDecorator" }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'using rspec' do
|
33
|
+
before { run_generator ["product", "-t=rspec"] }
|
34
|
+
|
35
|
+
describe 'spec/decorators/product_decorator_spec.rb' do
|
36
|
+
subject { file('spec/decorators/product_decorator_spec.rb') }
|
37
|
+
it { should exist }
|
38
|
+
it { should contain "describe ProductDecorator" }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'using rspec' do
|
43
|
+
before { run_generator ["product", "-t=test_unit"] }
|
44
|
+
|
45
|
+
describe 'test/decorators/product_decorator_test.rb' do
|
46
|
+
subject { file('test/decorators/product_decorator_test.rb') }
|
47
|
+
it { should exist }
|
48
|
+
it { should contain "class ProductDecoratorTest < ActiveSupport::TestCase" }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
=begin
|
12
55
|
describe 'no arguments' do
|
13
56
|
before { run_generator %w(products) }
|
14
57
|
|
@@ -17,6 +60,43 @@ describe Draper::DecoratorGenerator do
|
|
17
60
|
it { should exist }
|
18
61
|
it { should contain "class ProductsDecorator < ApplicationDecorator" }
|
19
62
|
end
|
63
|
+
end
|
64
|
+
|
20
65
|
|
66
|
+
context 'simple' do
|
67
|
+
before { run_generator %w(products) }
|
68
|
+
|
69
|
+
describe 'app/decorators/products_decorator.rb' do
|
70
|
+
subject { file('app/decorators/products_decorator.rb') }
|
71
|
+
it { should exist }
|
72
|
+
it { should contain "class ProductsDecorator < ApplicationDecorator" }
|
73
|
+
end
|
21
74
|
end
|
22
|
-
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
context 'using rspec' do
|
81
|
+
|
82
|
+
describe 'app/decorators/products_decorator.rb' do
|
83
|
+
subject { file('app/decorators/products_decorator.rb') }
|
84
|
+
it { should exist }
|
85
|
+
it { should contain "class ProductsDecorator < ApplicationDecorator" }
|
86
|
+
end
|
87
|
+
|
88
|
+
shared_examples_for "ApplicationDecoratorGenerator" do
|
89
|
+
describe 'app/decorators/application_decorator.rb' do
|
90
|
+
subject { file('app/decorators/application_decorator.rb') }
|
91
|
+
it { should exist }
|
92
|
+
it { should contain "class ApplicationDecorator < Draper::Base" }
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe 'spec/decorators/application_decorator_spec.rb' do
|
97
|
+
subject { file('spec/decorators/application_decorator_spec.rb') }
|
98
|
+
it { should exist }
|
99
|
+
it { should contain "describe ApplicationDecorator do" }
|
100
|
+
end
|
101
|
+
end
|
102
|
+
=end
|