draper 3.0.0.pre1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +16 -0
  3. data/.github/PULL_REQUEST_TEMPLATE.md +24 -0
  4. data/.rubocop.yml +11 -0
  5. data/.travis.yml +3 -2
  6. data/CHANGELOG.md +20 -0
  7. data/Guardfile +5 -5
  8. data/README.md +27 -5
  9. data/Rakefile +1 -2
  10. data/draper.gemspec +1 -0
  11. data/lib/draper.rb +7 -2
  12. data/lib/draper/automatic_delegation.rb +5 -3
  13. data/lib/draper/collection_decorator.rb +1 -11
  14. data/lib/draper/compatibility/api_only.rb +23 -0
  15. data/lib/draper/configuration.rb +15 -0
  16. data/lib/draper/decoratable.rb +2 -2
  17. data/lib/draper/decorator.rb +4 -12
  18. data/lib/draper/finders.rb +0 -0
  19. data/lib/draper/helper_proxy.rb +1 -8
  20. data/lib/draper/railtie.rb +12 -13
  21. data/lib/draper/tasks/test.rake +1 -1
  22. data/lib/draper/test/devise_helper.rb +1 -8
  23. data/lib/draper/test/minitest_integration.rb +0 -0
  24. data/lib/draper/test/rspec_integration.rb +0 -0
  25. data/lib/draper/undecorate.rb +8 -0
  26. data/lib/draper/version.rb +1 -1
  27. data/lib/draper/view_context.rb +3 -19
  28. data/lib/draper/view_context/build_strategy.rb +11 -2
  29. data/lib/generators/controller_override.rb +2 -2
  30. data/lib/generators/draper/install_generator.rb +14 -0
  31. data/lib/generators/draper/templates/application_decorator.rb +8 -0
  32. data/lib/generators/mini_test/decorator_generator.rb +1 -1
  33. data/lib/generators/rails/decorator_generator.rb +1 -8
  34. data/lib/generators/rspec/templates/decorator_spec.rb +1 -1
  35. data/spec/draper/collection_decorator_spec.rb +11 -26
  36. data/spec/draper/configuration_spec.rb +25 -0
  37. data/spec/draper/decoratable_spec.rb +28 -13
  38. data/spec/draper/decorated_association_spec.rb +9 -9
  39. data/spec/draper/decorates_assigned_spec.rb +6 -6
  40. data/spec/draper/decorator_spec.rb +104 -89
  41. data/spec/draper/draper_spec.rb +24 -0
  42. data/spec/draper/factory_spec.rb +24 -24
  43. data/spec/draper/finders_spec.rb +21 -21
  44. data/spec/draper/helper_proxy_spec.rb +2 -2
  45. data/spec/draper/lazy_helpers_spec.rb +2 -2
  46. data/spec/draper/undecorate_chain_spec.rb +20 -0
  47. data/spec/draper/view_context/build_strategy_spec.rb +26 -10
  48. data/spec/draper/view_context_spec.rb +49 -21
  49. data/spec/dummy/app/controllers/base_controller.rb +4 -0
  50. data/spec/dummy/app/controllers/posts_controller.rb +2 -2
  51. data/spec/dummy/app/decorators/post_decorator.rb +0 -0
  52. data/spec/dummy/config/boot.rb +1 -1
  53. data/spec/dummy/config/initializers/draper.rb +3 -0
  54. data/spec/dummy/db/schema.rb +4 -4
  55. data/spec/dummy/fast_spec/post_decorator_spec.rb +1 -1
  56. data/spec/dummy/lib/tasks/test.rake +1 -1
  57. data/spec/dummy/spec/decorators/devise_spec.rb +0 -9
  58. data/spec/dummy/spec/decorators/post_decorator_spec.rb +2 -2
  59. data/spec/dummy/test/decorators/minitest/devise_test.rb +0 -9
  60. data/spec/dummy/test/decorators/minitest/view_context_test.rb +3 -3
  61. data/spec/dummy/test/decorators/test_unit/devise_test.rb +0 -9
  62. data/spec/generators/controller/controller_generator_spec.rb +3 -3
  63. data/spec/generators/decorator/decorator_generator_spec.rb +11 -10
  64. data/spec/generators/install/install_generator_spec.rb +19 -0
  65. data/spec/spec_helper.rb +4 -3
  66. data/spec/support/shared_examples/view_helpers.rb +8 -8
  67. metadata +38 -7
  68. data/spec/dummy/app/controllers/application_controller.rb +0 -4
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ require 'support/shared_examples/view_helpers'
3
+
4
+ module Draper
5
+ describe Draper do
6
+ describe '.setup_action_controller' do
7
+ it 'includes api only compatability if base is ActionController::API' do
8
+ base = ActionController::API
9
+
10
+ Draper.setup_action_controller(base)
11
+
12
+ expect(base.included_modules).to include(Draper::Compatibility::ApiOnly)
13
+ end
14
+
15
+ it 'does not include api only compatibility if base ActionController::Base' do
16
+ base = ActionController::Base
17
+
18
+ Draper.setup_action_controller(base)
19
+
20
+ expect(base.included_modules).not_to include(Draper::Compatibility::ApiOnly)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -27,7 +27,7 @@ module Draper
27
27
  factory = Factory.new
28
28
  worker = ->(*){ :decorated }
29
29
 
30
- Factory::Worker.should_receive(:new).and_return(worker)
30
+ expect(Factory::Worker).to receive(:new).and_return(worker)
31
31
  expect(factory.decorate(double)).to be :decorated
32
32
  end
33
33
 
@@ -35,7 +35,7 @@ module Draper
35
35
  factory = Factory.new
36
36
  object = double
37
37
 
38
- Factory::Worker.should_receive(:new).with(anything(), object).and_return(->(*){})
38
+ expect(Factory::Worker).to receive(:new).with(anything(), object).and_return(->(*){})
39
39
  factory.decorate(object)
40
40
  end
41
41
 
@@ -44,7 +44,7 @@ module Draper
44
44
  decorator_class = double
45
45
  factory = Factory.new(with: decorator_class)
46
46
 
47
- Factory::Worker.should_receive(:new).with(decorator_class, anything()).and_return(->(*){})
47
+ expect(Factory::Worker).to receive(:new).with(decorator_class, anything()).and_return(->(*){})
48
48
  factory.decorate(double)
49
49
  end
50
50
  end
@@ -53,7 +53,7 @@ module Draper
53
53
  it "passes nil to the worker" do
54
54
  factory = Factory.new
55
55
 
56
- Factory::Worker.should_receive(:new).with(nil, anything()).and_return(->(*){})
56
+ expect(Factory::Worker).to receive(:new).with(nil, anything()).and_return(->(*){})
57
57
  factory.decorate(double)
58
58
  end
59
59
  end
@@ -61,10 +61,10 @@ module Draper
61
61
  it "passes options to the call" do
62
62
  factory = Factory.new
63
63
  worker = ->(*){}
64
- Factory::Worker.stub new: worker
64
+ allow(Factory::Worker).to receive(:new).and_return(worker)
65
65
  options = {foo: "bar"}
66
66
 
67
- worker.should_receive(:call).with(options)
67
+ allow(worker).to receive(:call).with(options)
68
68
  factory.decorate(double, options)
69
69
  end
70
70
 
@@ -72,18 +72,18 @@ module Draper
72
72
  it "sets the passed context" do
73
73
  factory = Factory.new(context: {foo: "bar"})
74
74
  worker = ->(*){}
75
- Factory::Worker.stub new: worker
75
+ allow(Factory::Worker).to receive_messages new: worker
76
76
 
77
- worker.should_receive(:call).with(baz: "qux", context: {foo: "bar"})
77
+ expect(worker).to receive(:call).with(baz: "qux", context: {foo: "bar"})
78
78
  factory.decorate(double, {baz: "qux"})
79
79
  end
80
80
 
81
81
  it "is overridden by explicitly-specified context" do
82
82
  factory = Factory.new(context: {foo: "bar"})
83
83
  worker = ->(*){}
84
- Factory::Worker.stub new: worker
84
+ allow(Factory::Worker).to receive_messages new: worker
85
85
 
86
- worker.should_receive(:call).with(context: {baz: "qux"})
86
+ expect(worker).to receive(:call).with(context: {baz: "qux"})
87
87
  factory.decorate(double, context: {baz: "qux"})
88
88
  end
89
89
  end
@@ -99,9 +99,9 @@ module Draper
99
99
  options = {foo: "bar"}
100
100
  worker = Factory::Worker.new(double, object)
101
101
  decorator = ->(*){}
102
- allow(worker).to receive(:decorator){ decorator }
102
+ allow(worker).to receive(:decorator){ decorator }
103
103
 
104
- decorator.should_receive(:call).with(object, options).and_return(:decorated)
104
+ allow(decorator).to receive(:call).with(object, options).and_return(:decorated)
105
105
  expect(worker.call(options)).to be :decorated
106
106
  end
107
107
 
@@ -109,29 +109,29 @@ module Draper
109
109
  it "calls it" do
110
110
  worker = Factory::Worker.new(double, double)
111
111
  decorator = ->(*){}
112
- worker.stub decorator: decorator
112
+ allow(worker).to receive_messages decorator: decorator
113
113
  context = {foo: "bar"}
114
114
 
115
- decorator.should_receive(:call).with(anything(), context: context)
115
+ expect(decorator).to receive(:call).with(anything(), context: context)
116
116
  worker.call(context: ->{ context })
117
117
  end
118
118
 
119
119
  it "receives arguments from the :context_args option" do
120
120
  worker = Factory::Worker.new(double, double)
121
- worker.stub decorator: ->(*){}
121
+ allow(worker).to receive_messages decorator: ->(*){}
122
122
  context = ->{}
123
123
 
124
- context.should_receive(:call).with(:foo, :bar)
124
+ expect(context).to receive(:call).with(:foo, :bar)
125
125
  worker.call(context: context, context_args: [:foo, :bar])
126
126
  end
127
127
 
128
128
  it "wraps non-arrays passed to :context_args" do
129
129
  worker = Factory::Worker.new(double, double)
130
- worker.stub decorator: ->(*){}
130
+ allow(worker).to receive_messages decorator: ->(*){}
131
131
  context = ->{}
132
132
  hash = {foo: "bar"}
133
133
 
134
- context.should_receive(:call).with(hash)
134
+ expect(context).to receive(:call).with(hash)
135
135
  worker.call(context: context, context_args: hash)
136
136
  end
137
137
  end
@@ -140,10 +140,10 @@ module Draper
140
140
  it "doesn't call it" do
141
141
  worker = Factory::Worker.new(double, double)
142
142
  decorator = ->(*){}
143
- worker.stub decorator: decorator
143
+ allow(worker).to receive_messages decorator: decorator
144
144
  context = {foo: "bar"}
145
145
 
146
- decorator.should_receive(:call).with(anything(), context: context)
146
+ expect(decorator).to receive(:call).with(anything(), context: context)
147
147
  worker.call(context: context)
148
148
  end
149
149
  end
@@ -151,9 +151,9 @@ module Draper
151
151
  it "does not pass the :context_args option to the decorator" do
152
152
  worker = Factory::Worker.new(double, double)
153
153
  decorator = ->(*){}
154
- worker.stub decorator: decorator
154
+ allow(worker).to receive_messages decorator: decorator
155
155
 
156
- decorator.should_receive(:call).with(anything(), foo: "bar")
156
+ expect(decorator).to receive(:call).with(anything(), foo: "bar")
157
157
  worker.call(foo: "bar", context_args: [])
158
158
  end
159
159
  end
@@ -176,7 +176,7 @@ module Draper
176
176
  options = {foo: "bar"}
177
177
  worker = Factory::Worker.new(nil, object)
178
178
 
179
- object.should_receive(:decorate).with(options).and_return(:decorated)
179
+ expect(object).to receive(:decorate).with(options).and_return(:decorated)
180
180
  expect(worker.decorator.call(object, options)).to be :decorated
181
181
  end
182
182
  end
@@ -231,7 +231,7 @@ module Draper
231
231
  allow(object).to receive(:decorate){ nil }
232
232
  worker = Factory::Worker.new(nil, object)
233
233
 
234
- decorator_class.should_receive(:decorate_collection).with(object, foo: "bar", with: nil).and_return(:decorated)
234
+ expect(decorator_class).to receive(:decorate_collection).with(object, foo: "bar", with: nil).and_return(:decorated)
235
235
  expect(worker.decorator.call(object, foo: "bar")).to be :decorated
236
236
  end
237
237
  end
@@ -7,20 +7,20 @@ module Draper
7
7
 
8
8
  describe ".find" do
9
9
  it "proxies to the model class" do
10
- Product.should_receive(:find).with(1)
10
+ expect(Product).to receive(:find).with(1)
11
11
  ProductDecorator.find(1)
12
12
  end
13
13
 
14
14
  it "decorates the result" do
15
15
  found = Product.new
16
- Product.stub(:find).and_return(found)
16
+ allow(Product).to receive(:find).and_return(found)
17
17
  decorator = ProductDecorator.find(1)
18
18
  expect(decorator).to be_a ProductDecorator
19
19
  expect(decorator.object).to be found
20
20
  end
21
21
 
22
22
  it "passes context to the decorator" do
23
- Product.stub(:find)
23
+ allow(Product).to receive(:find)
24
24
  context = {some: "context"}
25
25
  decorator = ProductDecorator.find(1, context: context)
26
26
 
@@ -30,40 +30,40 @@ module Draper
30
30
 
31
31
  describe ".find_by_(x)" do
32
32
  it "proxies to the model class" do
33
- Product.should_receive(:find_by_name).with("apples")
33
+ expect(Product).to receive(:find_by_name).with("apples")
34
34
  ProductDecorator.find_by_name("apples")
35
35
  end
36
36
 
37
37
  it "decorates the result" do
38
38
  found = Product.new
39
- Product.stub(:find_by_name).and_return(found)
39
+ allow(Product).to receive(:find_by_name).and_return(found)
40
40
  decorator = ProductDecorator.find_by_name("apples")
41
41
  expect(decorator).to be_a ProductDecorator
42
42
  expect(decorator.object).to be found
43
43
  end
44
44
 
45
45
  it "proxies complex ProductDecorators" do
46
- Product.should_receive(:find_by_name_and_size).with("apples", "large")
46
+ expect(Product).to receive(:find_by_name_and_size).with("apples", "large")
47
47
  ProductDecorator.find_by_name_and_size("apples", "large")
48
48
  end
49
49
 
50
50
  it "proxies find_last_by_(x) ProductDecorators" do
51
- Product.should_receive(:find_last_by_name_and_size).with("apples", "large")
51
+ expect(Product).to receive(:find_last_by_name_and_size).with("apples", "large")
52
52
  ProductDecorator.find_last_by_name_and_size("apples", "large")
53
53
  end
54
54
 
55
55
  it "proxies find_or_initialize_by_(x) ProductDecorators" do
56
- Product.should_receive(:find_or_initialize_by_name_and_size).with("apples", "large")
56
+ expect(Product).to receive(:find_or_initialize_by_name_and_size).with("apples", "large")
57
57
  ProductDecorator.find_or_initialize_by_name_and_size("apples", "large")
58
58
  end
59
59
 
60
60
  it "proxies find_or_create_by_(x) ProductDecorators" do
61
- Product.should_receive(:find_or_create_by_name_and_size).with("apples", "large")
61
+ expect(Product).to receive(:find_or_create_by_name_and_size).with("apples", "large")
62
62
  ProductDecorator.find_or_create_by_name_and_size("apples", "large")
63
63
  end
64
64
 
65
65
  it "passes context to the decorator" do
66
- Product.stub(:find_by_name_and_size)
66
+ allow(Product).to receive(:find_by_name_and_size)
67
67
  context = {some: "context"}
68
68
  decorator = ProductDecorator.find_by_name_and_size("apples", "large", context: context)
69
69
 
@@ -73,13 +73,13 @@ module Draper
73
73
 
74
74
  describe ".find_all_by_" do
75
75
  it "proxies to the model class" do
76
- Product.should_receive(:find_all_by_name_and_size).with("apples", "large").and_return([])
76
+ expect(Product).to receive(:find_all_by_name_and_size).with("apples", "large").and_return([])
77
77
  ProductDecorator.find_all_by_name_and_size("apples", "large")
78
78
  end
79
79
 
80
80
  it "decorates the result" do
81
81
  found = [Product.new, Product.new]
82
- Product.stub(:find_all_by_name).and_return(found)
82
+ allow(Product).to receive(:find_all_by_name).and_return(found)
83
83
  decorator = ProductDecorator.find_all_by_name("apples")
84
84
 
85
85
  expect(decorator).to be_a Draper::CollectionDecorator
@@ -88,7 +88,7 @@ module Draper
88
88
  end
89
89
 
90
90
  it "passes context to the decorator" do
91
- Product.stub(:find_all_by_name)
91
+ allow(Product).to receive(:find_all_by_name)
92
92
  context = {some: "context"}
93
93
  decorator = ProductDecorator.find_all_by_name("apples", context: context)
94
94
 
@@ -99,7 +99,7 @@ module Draper
99
99
  describe ".all" do
100
100
  it "returns a decorated collection" do
101
101
  found = [Product.new, Product.new]
102
- Product.stub all: found
102
+ allow(Product).to receive_messages all: found
103
103
  decorator = ProductDecorator.all
104
104
 
105
105
  expect(decorator).to be_a Draper::CollectionDecorator
@@ -108,7 +108,7 @@ module Draper
108
108
  end
109
109
 
110
110
  it "passes context to the decorator" do
111
- Product.stub(:all)
111
+ allow(Product).to receive(:all)
112
112
  context = {some: "context"}
113
113
  decorator = ProductDecorator.all(context: context)
114
114
 
@@ -118,20 +118,20 @@ module Draper
118
118
 
119
119
  describe ".first" do
120
120
  it "proxies to the model class" do
121
- Product.should_receive(:first)
121
+ expect(Product).to receive(:first)
122
122
  ProductDecorator.first
123
123
  end
124
124
 
125
125
  it "decorates the result" do
126
126
  first = Product.new
127
- Product.stub(:first).and_return(first)
127
+ allow(Product).to receive(:first).and_return(first)
128
128
  decorator = ProductDecorator.first
129
129
  expect(decorator).to be_a ProductDecorator
130
130
  expect(decorator.object).to be first
131
131
  end
132
132
 
133
133
  it "passes context to the decorator" do
134
- Product.stub(:first)
134
+ allow(Product).to receive(:first)
135
135
  context = {some: "context"}
136
136
  decorator = ProductDecorator.first(context: context)
137
137
 
@@ -141,20 +141,20 @@ module Draper
141
141
 
142
142
  describe ".last" do
143
143
  it "proxies to the model class" do
144
- Product.should_receive(:last)
144
+ expect(Product).to receive(:last)
145
145
  ProductDecorator.last
146
146
  end
147
147
 
148
148
  it "decorates the result" do
149
149
  last = Product.new
150
- Product.stub(:last).and_return(last)
150
+ allow(Product).to receive(:last).and_return(last)
151
151
  decorator = ProductDecorator.last
152
152
  expect(decorator).to be_a ProductDecorator
153
153
  expect(decorator.object).to be last
154
154
  end
155
155
 
156
156
  it "passes context to the decorator" do
157
- Product.stub(:last)
157
+ allow(Product).to receive(:last)
158
158
  context = {some: "context"}
159
159
  decorator = ProductDecorator.last(context: context)
160
160
 
@@ -18,7 +18,7 @@ module Draper
18
18
  view_context = double
19
19
  helper_proxy = HelperProxy.new(view_context)
20
20
 
21
- view_context.stub(:foo) { |arg| arg }
21
+ allow(view_context).to receive(:foo) { |arg| arg }
22
22
  expect(helper_proxy.foo(:passed)).to be :passed
23
23
  end
24
24
 
@@ -26,7 +26,7 @@ module Draper
26
26
  view_context = double
27
27
  helper_proxy = HelperProxy.new(view_context)
28
28
 
29
- view_context.stub(:foo) { |&block| block.call }
29
+ allow(view_context).to receive(:foo) { |&block| block.call }
30
30
  expect(helper_proxy.foo{:yielded}).to be :yielded
31
31
  end
32
32
 
@@ -8,12 +8,12 @@ module Draper
8
8
  end
9
9
 
10
10
  it "proxies methods to #helpers" do
11
- decorator.helpers.stub(:foo) { |arg| arg }
11
+ allow(decorator.helpers).to receive(:foo) { |arg| arg }
12
12
  expect(decorator.foo(:passed)).to be :passed
13
13
  end
14
14
 
15
15
  it "passes blocks" do
16
- decorator.helpers.stub(:foo) { |&block| block.call }
16
+ allow(decorator.helpers).to receive(:foo) { |&block| block.call }
17
17
  expect(decorator.foo{:yielded}).to be :yielded
18
18
  end
19
19
  end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe Draper, '.undecorate_chain' do
4
+ let!(:object) { Model.new }
5
+ let!(:decorated_inner) { Class.new(Draper::Decorator).new(object) }
6
+ let!(:decorated_outer) { Class.new(Draper::Decorator).new(decorated_inner) }
7
+
8
+ it 'undecorates full chain of decorated objects' do
9
+ expect(Draper.undecorate_chain(decorated_outer)).to equal object
10
+ end
11
+
12
+ it 'passes a non-decorated object through' do
13
+ expect(Draper.undecorate_chain(object)).to equal object
14
+ end
15
+
16
+ it 'passes a non-decorator object through' do
17
+ object = Object.new
18
+ expect(Draper.undecorate_chain(object)).to equal object
19
+ end
20
+ end
@@ -14,7 +14,7 @@ module Draper
14
14
  context "when a current controller is set" do
15
15
  it "returns the controller's view context" do
16
16
  view_context = fake_view_context
17
- ViewContext.stub controller: fake_controller(view_context)
17
+ allow(ViewContext).to receive_messages controller: fake_controller(view_context)
18
18
  strategy = ViewContext::BuildStrategy::Full.new
19
19
 
20
20
  expect(strategy.call).to be view_context
@@ -23,31 +23,47 @@ module Draper
23
23
 
24
24
  context "when a current controller is not set" do
25
25
  it "uses ApplicationController" do
26
- view_context = fake_view_context
27
- stub_const "ApplicationController", double(new: fake_controller(view_context))
28
- strategy = ViewContext::BuildStrategy::Full.new
29
-
30
- expect(strategy.call).to be view_context
26
+ expect(Draper::ViewContext.controller).to be_nil
27
+ view_context = ViewContext::BuildStrategy::Full.new.call
28
+ expect(view_context.controller).to eq Draper::ViewContext.controller
29
+ expect(view_context.controller).to be_an ApplicationController
31
30
  end
32
31
  end
33
32
 
34
33
  it "adds a request if one is not defined" do
35
34
  controller = Class.new(ActionController::Base).new
36
- ViewContext.stub controller: controller
35
+ allow(ViewContext).to receive_messages controller: controller
37
36
  strategy = ViewContext::BuildStrategy::Full.new
38
37
 
39
38
  expect(controller.request).to be_nil
40
39
  strategy.call
41
40
  expect(controller.request).to be_an ActionController::TestRequest
42
- expect(controller.params).to eq({})
41
+ expect(controller.params).to be_empty
43
42
 
44
43
  # sanity checks
45
44
  expect(controller.view_context.request).to be controller.request
46
45
  expect(controller.view_context.params).to be controller.params
47
46
  end
48
47
 
48
+ it "compatible with rails 5.1 change on ActionController::TestRequest.create method" do
49
+ ActionController::TestRequest.class_eval do
50
+ if ActionController::TestRequest.method(:create).parameters.first == []
51
+ def create controller_class
52
+ create
53
+ end
54
+ end
55
+ end
56
+ controller = Class.new(ActionController::Base).new
57
+ allow(ViewContext).to receive_messages controller: controller
58
+ strategy = ViewContext::BuildStrategy::Full.new
59
+
60
+ expect(controller.request).to be_nil
61
+ strategy.call
62
+ expect(controller.request).to be_an ActionController::TestRequest
63
+ end
64
+
49
65
  it "adds methods to the view context from the constructor block" do
50
- ViewContext.stub controller: fake_controller
66
+ allow(ViewContext).to receive(:controller).and_return(fake_controller)
51
67
  strategy = ViewContext::BuildStrategy::Full.new do
52
68
  def a_helper_method; end
53
69
  end
@@ -57,7 +73,7 @@ module Draper
57
73
 
58
74
  it "includes modules into the view context from the constructor block" do
59
75
  view_context = Object.new
60
- ViewContext.stub controller: fake_controller(view_context)
76
+ allow(ViewContext).to receive(:controller).and_return(fake_controller(view_context))
61
77
  helpers = Module.new do
62
78
  def a_helper_method; end
63
79
  end