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
@@ -7,7 +7,7 @@ module Draper
7
7
  let(:controller) { Class.new(base) { include ViewContext } }
8
8
 
9
9
  it "saves the superclass's view context" do
10
- ViewContext.should_receive(:current=).with(:controller_view_context)
10
+ expect(ViewContext).to receive(:current=).with(:controller_view_context)
11
11
  controller.new.view_context
12
12
  end
13
13
 
@@ -18,7 +18,7 @@ module Draper
18
18
 
19
19
  describe ".controller" do
20
20
  it "returns the stored controller from RequestStore" do
21
- RequestStore.stub store: {current_controller: :stored_controller}
21
+ allow(RequestStore).to receive_messages store: {current_controller: :stored_controller}
22
22
 
23
23
  expect(ViewContext.controller).to be :stored_controller
24
24
  end
@@ -27,34 +27,62 @@ module Draper
27
27
  describe ".controller=" do
28
28
  it "stores a controller in RequestStore" do
29
29
  store = {}
30
- RequestStore.stub store: store
30
+ allow(RequestStore).to receive_messages store: store
31
31
 
32
32
  ViewContext.controller = :stored_controller
33
33
  expect(store[:current_controller]).to be :stored_controller
34
34
  end
35
+
36
+ it "cleans context when controller changes" do
37
+ store = {
38
+ current_controller: :stored_controller,
39
+ current_view_context: :stored_view_context
40
+ }
41
+
42
+ allow(RequestStore).to receive_messages store: store
43
+
44
+ ViewContext.controller = :other_stored_controller
45
+
46
+ expect(store).to include(current_controller: :other_stored_controller)
47
+ expect(store).not_to include(:current_view_context)
48
+ end
49
+
50
+ it "doesn't clean context when controller is the same" do
51
+ store = {
52
+ current_controller: :stored_controller,
53
+ current_view_context: :stored_view_context
54
+ }
55
+
56
+ allow(RequestStore).to receive_messages store: store
57
+
58
+ ViewContext.controller = :stored_controller
59
+
60
+ expect(store).to include(current_controller: :stored_controller)
61
+ expect(store).to include(current_view_context: :stored_view_context)
62
+ end
35
63
  end
36
64
 
37
65
  describe ".current" do
38
66
  it "returns the stored view context from RequestStore" do
39
- RequestStore.stub store: {current_view_context: :stored_view_context}
67
+ allow(RequestStore).to receive_messages store: {current_view_context: :stored_view_context}
40
68
 
41
69
  expect(ViewContext.current).to be :stored_view_context
42
70
  end
43
71
 
44
72
  context "when no view context is stored" do
45
73
  it "builds a view context" do
46
- RequestStore.stub store: {}
47
- ViewContext.stub build_strategy: ->{ :new_view_context }
48
- HelperProxy.stub(:new).with(:new_view_context).and_return(:new_helper_proxy)
74
+ allow(RequestStore).to receive_messages store: {}
75
+ allow(ViewContext).to receive_messages build_strategy: ->{ :new_view_context }
76
+ allow(HelperProxy).to receive(:new).with(:new_view_context).and_return(:new_helper_proxy)
49
77
 
50
78
  expect(ViewContext.current).to be :new_helper_proxy
51
79
  end
52
80
 
53
81
  it "stores the built view context" do
54
82
  store = {}
55
- RequestStore.stub store: store
56
- ViewContext.stub build_strategy: ->{ :new_view_context }
57
- HelperProxy.stub(:new).with(:new_view_context).and_return(:new_helper_proxy)
83
+ allow(RequestStore).to receive_messages store: store
84
+ allow(ViewContext).to receive_messages build_strategy: ->{ :new_view_context }
85
+ allow(HelperProxy).to receive(:new).with(:new_view_context).and_return(:new_helper_proxy)
58
86
 
59
87
  ViewContext.current
60
88
  expect(store[:current_view_context]).to be :new_helper_proxy
@@ -65,8 +93,8 @@ module Draper
65
93
  describe ".current=" do
66
94
  it "stores a helper proxy for the view context in RequestStore" do
67
95
  store = {}
68
- RequestStore.stub store: store
69
- HelperProxy.stub(:new).with(:stored_view_context).and_return(:stored_helper_proxy)
96
+ allow(RequestStore).to receive_messages store: store
97
+ allow(HelperProxy).to receive(:new).with(:stored_view_context).and_return(:stored_helper_proxy)
70
98
 
71
99
  ViewContext.current = :stored_view_context
72
100
  expect(store[:current_view_context]).to be :stored_helper_proxy
@@ -76,7 +104,7 @@ module Draper
76
104
  describe ".clear!" do
77
105
  it "clears the stored controller and view controller" do
78
106
  store = {current_controller: :stored_controller, current_view_context: :stored_view_context}
79
- RequestStore.stub store: store
107
+ allow(RequestStore).to receive_messages store: store
80
108
 
81
109
  ViewContext.clear!
82
110
  expect(store).not_to have_key :current_controller
@@ -86,7 +114,7 @@ module Draper
86
114
 
87
115
  describe ".build" do
88
116
  it "returns a new view context using the build strategy" do
89
- ViewContext.stub build_strategy: ->{ :new_view_context }
117
+ allow(ViewContext).to receive_messages build_strategy: ->{ :new_view_context }
90
118
 
91
119
  expect(ViewContext.build).to be :new_view_context
92
120
  end
@@ -94,17 +122,17 @@ module Draper
94
122
 
95
123
  describe ".build!" do
96
124
  it "returns a helper proxy for the new view context" do
97
- ViewContext.stub build_strategy: ->{ :new_view_context }
98
- HelperProxy.stub(:new).with(:new_view_context).and_return(:new_helper_proxy)
125
+ allow(ViewContext).to receive_messages build_strategy: ->{ :new_view_context }
126
+ allow(HelperProxy).to receive(:new).with(:new_view_context).and_return(:new_helper_proxy)
99
127
 
100
128
  expect(ViewContext.build!).to be :new_helper_proxy
101
129
  end
102
130
 
103
131
  it "stores the helper proxy" do
104
132
  store = {}
105
- RequestStore.stub store: store
106
- ViewContext.stub build_strategy: ->{ :new_view_context }
107
- HelperProxy.stub(:new).with(:new_view_context).and_return(:new_helper_proxy)
133
+ allow(RequestStore).to receive_messages store: store
134
+ allow(ViewContext).to receive_messages build_strategy: ->{ :new_view_context }
135
+ allow(HelperProxy).to receive(:new).with(:new_view_context).and_return(:new_helper_proxy)
108
136
 
109
137
  ViewContext.build!
110
138
  expect(store[:current_view_context]).to be :new_helper_proxy
@@ -131,7 +159,7 @@ module Draper
131
159
  end
132
160
 
133
161
  it "passes a block to the strategy" do
134
- ViewContext::BuildStrategy::Fast.stub(:new) { |&block| block.call }
162
+ allow(ViewContext::BuildStrategy::Fast).to receive(:new) { |&block| block.call }
135
163
 
136
164
  expect(ViewContext.test_strategy(:fast){:passed}).to be :passed
137
165
  end
@@ -144,7 +172,7 @@ module Draper
144
172
  end
145
173
 
146
174
  it "passes a block to the strategy" do
147
- ViewContext::BuildStrategy::Full.stub(:new) { |&block| block.call }
175
+ allow(ViewContext::BuildStrategy::Full).to receive(:new) { |&block| block.call }
148
176
 
149
177
  expect(ViewContext.test_strategy(:full){:passed}).to be :passed
150
178
  end
@@ -0,0 +1,4 @@
1
+ class BaseController < ActionController::Base
2
+ include LocalizedUrls
3
+ protect_from_forgery
4
+ end
@@ -1,4 +1,4 @@
1
- class PostsController < ApplicationController
1
+ class PostsController < BaseController
2
2
  decorates_assigned :post
3
3
 
4
4
  def show
@@ -8,7 +8,7 @@ class PostsController < ApplicationController
8
8
  def mail
9
9
  post = Post.find(params[:id])
10
10
  email = PostMailer.decorated_email(post).deliver
11
- render text: email.body
11
+ render html: email.body.to_s.html_safe
12
12
  end
13
13
 
14
14
  private
@@ -2,4 +2,4 @@ require 'rubygems'
2
2
 
3
3
  ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__)
4
4
 
5
- require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
5
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
@@ -0,0 +1,3 @@
1
+ Draper.configure do |config|
2
+ config.default_controller = BaseController
3
+ end
@@ -11,11 +11,11 @@
11
11
  #
12
12
  # It's strongly recommended to check this file into your version control system.
13
13
 
14
- ActiveRecord::Schema.define(:version => 20121019115657) do
14
+ ActiveRecord::Schema.define(version: 20121019115657) do
15
15
 
16
- create_table "posts", :force => true do |t|
17
- t.datetime "created_at", :null => false
18
- t.datetime "updated_at", :null => false
16
+ create_table "posts", force: true do |t|
17
+ t.datetime "created_at", null: false
18
+ t.datetime "updated_at", null: false
19
19
  end
20
20
 
21
21
  end
@@ -32,6 +32,6 @@ describe PostDecorator do
32
32
  end
33
33
 
34
34
  it "can't be passed implicitly to url_for" do
35
- expect{decorator.link}.to raise_error
35
+ expect{decorator.link}.to raise_error ArgumentError
36
36
  end
37
37
  end
@@ -13,4 +13,4 @@ RSpec::Core::RakeTask.new :fast_spec do |t|
13
13
  t.pattern = "fast_spec/**/*_spec.rb"
14
14
  end
15
15
 
16
- task :default => [:test, :spec, :fast_spec]
16
+ task default: [:test, :spec, :fast_spec]
@@ -51,14 +51,5 @@ if defined?(Devise)
51
51
 
52
52
  expect(helper.current_user).to be_nil
53
53
  end
54
-
55
- it "is backwards-compatible" do
56
- user = double("User")
57
- ActiveSupport::Deprecation.silence do
58
- sign_in user
59
- end
60
-
61
- expect(helper.current_user).to be user
62
- end
63
54
  end
64
55
  end
@@ -58,7 +58,7 @@ describe PostDecorator do
58
58
  expect(xml).to have_css "post > updated-at", text: "overridden"
59
59
  end
60
60
 
61
- it "uses a test view context from ApplicationController" do
62
- expect(Draper::ViewContext.current.controller).to be_an ApplicationController
61
+ it "uses a test view context from BaseController" do
62
+ expect(Draper::ViewContext.current.controller).to be_an BaseController
63
63
  end
64
64
  end
@@ -51,14 +51,5 @@ if defined?(Devise)
51
51
 
52
52
  assert helper.current_user.nil?
53
53
  end
54
-
55
- it "is backwards-compatible" do
56
- user = Object.new
57
- ActiveSupport::Deprecation.silence do
58
- sign_in user
59
- end
60
-
61
- assert_same user, helper.current_user
62
- end
63
54
  end
64
55
  end
@@ -13,12 +13,12 @@ describe "A decorator test" do
13
13
  it_does_not_leak_view_context
14
14
  end
15
15
 
16
- describe "A controller test" do
17
- subject{ Class.new(ActionController::Base) }
16
+ describe "A controller decorator test" do
17
+ subject { Class.new(ActionController::Base) }
18
18
 
19
19
  it_does_not_leak_view_context
20
20
  end
21
21
 
22
- describe "A mailer test" do
22
+ describe "A mailer decorator test" do
23
23
  it_does_not_leak_view_context
24
24
  end
@@ -51,14 +51,5 @@ if defined?(Devise)
51
51
 
52
52
  assert helper.current_user.nil?
53
53
  end
54
-
55
- def test_backwards_compatibility
56
- user = Object.new
57
- ActiveSupport::Deprecation.silence do
58
- sign_in user
59
- end
60
-
61
- assert_same user, helper.current_user
62
- end
63
54
  end
64
55
  end
@@ -1,5 +1,5 @@
1
1
  require 'spec_helper'
2
- require 'rails'
2
+ require 'dummy/config/environment'
3
3
  require 'ammeter/init'
4
4
  require 'generators/controller_override'
5
5
  require 'generators/rails/decorator_generator'
@@ -16,7 +16,7 @@ describe Rails::Generators::ControllerGenerator do
16
16
  describe "naming" do
17
17
  before { run_generator %w(YourModels) }
18
18
 
19
- it { should contain "class YourModelDecorator" }
19
+ it { is_expected.to contain "class YourModelDecorator" }
20
20
  end
21
21
  end
22
- end
22
+ end
@@ -1,5 +1,5 @@
1
1
  require 'spec_helper'
2
- require 'rails'
2
+ require 'dummy/config/environment'
3
3
  require 'ammeter/init'
4
4
  require 'generators/rails/decorator_generator'
5
5
 
@@ -15,31 +15,32 @@ describe Rails::Generators::DecoratorGenerator do
15
15
  describe "naming" do
16
16
  before { run_generator %w(YourModel) }
17
17
 
18
- it { should contain "class YourModelDecorator" }
18
+ it { is_expected.to contain "class YourModelDecorator" }
19
19
  end
20
20
 
21
21
  describe "namespacing" do
22
22
  subject { file("app/decorators/namespace/your_model_decorator.rb") }
23
23
  before { run_generator %w(Namespace::YourModel) }
24
24
 
25
- it { should contain "class Namespace::YourModelDecorator" }
25
+ it { is_expected.to contain "class Namespace::YourModelDecorator" }
26
26
  end
27
27
 
28
28
  describe "inheritance" do
29
29
  context "by default" do
30
30
  before { run_generator %w(YourModel) }
31
31
 
32
- it { should contain "class YourModelDecorator < Draper::Decorator" }
32
+ it { is_expected.to contain "class YourModelDecorator < Draper::Decorator" }
33
33
  end
34
34
 
35
35
  context "with the --parent option" do
36
36
  before { run_generator %w(YourModel --parent=FooDecorator) }
37
37
 
38
- it { should contain "class YourModelDecorator < FooDecorator" }
38
+ it { is_expected.to contain "class YourModelDecorator < FooDecorator" }
39
39
  end
40
40
 
41
41
  context "with an ApplicationDecorator" do
42
42
  before do
43
+ allow_any_instance_of(Object).to receive(:require)
43
44
  allow_any_instance_of(Object).to receive(:require).with("application_decorator").and_return(
44
45
  stub_const "ApplicationDecorator", Class.new
45
46
  )
@@ -47,7 +48,7 @@ describe Rails::Generators::DecoratorGenerator do
47
48
 
48
49
  before { run_generator %w(YourModel) }
49
50
 
50
- it { should contain "class YourModelDecorator < ApplicationDecorator" }
51
+ it { is_expected.to contain "class YourModelDecorator < ApplicationDecorator" }
51
52
  end
52
53
  end
53
54
  end
@@ -59,14 +60,14 @@ describe Rails::Generators::DecoratorGenerator do
59
60
  describe "naming" do
60
61
  before { run_generator %w(YourModel -t=rspec) }
61
62
 
62
- it { should contain "describe YourModelDecorator" }
63
+ it { is_expected.to contain "describe YourModelDecorator" }
63
64
  end
64
65
 
65
66
  describe "namespacing" do
66
67
  subject { file("spec/decorators/namespace/your_model_decorator_spec.rb") }
67
68
  before { run_generator %w(Namespace::YourModel -t=rspec) }
68
69
 
69
- it { should contain "describe Namespace::YourModelDecorator" }
70
+ it { is_expected.to contain "describe Namespace::YourModelDecorator" }
70
71
  end
71
72
  end
72
73
  end
@@ -78,14 +79,14 @@ describe Rails::Generators::DecoratorGenerator do
78
79
  describe "naming" do
79
80
  before { run_generator %w(YourModel -t=test_unit) }
80
81
 
81
- it { should contain "class YourModelDecoratorTest < Draper::TestCase" }
82
+ it { is_expected.to contain "class YourModelDecoratorTest < Draper::TestCase" }
82
83
  end
83
84
 
84
85
  describe "namespacing" do
85
86
  subject { file("test/decorators/namespace/your_model_decorator_test.rb") }
86
87
  before { run_generator %w(Namespace::YourModel -t=test_unit) }
87
88
 
88
- it { should contain "class Namespace::YourModelDecoratorTest < Draper::TestCase" }
89
+ it { is_expected.to contain "class Namespace::YourModelDecoratorTest < Draper::TestCase" }
89
90
  end
90
91
  end
91
92
  end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+ require 'dummy/config/environment'
3
+ require 'ammeter/init'
4
+ require 'generators/draper/install_generator'
5
+
6
+ describe Draper::Generators::InstallGenerator do
7
+ destination File.expand_path('../tmp', __FILE__)
8
+
9
+ before { prepare_destination }
10
+ after(:all) { FileUtils.rm_rf destination_root }
11
+
12
+ describe 'the application decorator' do
13
+ subject { file('app/decorators/application_decorator.rb') }
14
+
15
+ before { run_generator }
16
+
17
+ it { is_expected.to contain 'class ApplicationDecorator' }
18
+ end
19
+ end
@@ -19,17 +19,18 @@ class Other < Model; end
19
19
  class ProductDecorator < Draper::Decorator; end
20
20
  class ProductsDecorator < Draper::CollectionDecorator; end
21
21
 
22
- class ProductPresenter < Draper::Decorator; end
23
-
24
22
  class OtherDecorator < Draper::Decorator; end
25
23
 
26
24
  module Namespaced
27
25
  class Product < Model; end
28
26
  class ProductDecorator < Draper::Decorator; end
29
-
27
+ ProductsDecorator = Class.new(Draper::CollectionDecorator)
30
28
  class OtherDecorator < Draper::Decorator; end
31
29
  end
32
30
 
31
+ ApplicationController = Class.new(ActionController::Base)
32
+ CustomController = Class.new(ActionController::Base)
33
+
33
34
  # After each example, revert changes made to the class
34
35
  def protect_class(klass)
35
36
  before { stub_const klass.name, Class.new(klass) }
@@ -1,38 +1,38 @@
1
1
  shared_examples_for "view helpers" do |subject|
2
2
  describe "#helpers" do
3
3
  it "returns the current view context" do
4
- Draper::ViewContext.stub current: :current_view_context
4
+ allow(Draper::ViewContext).to receive_messages current: :current_view_context
5
5
  expect(subject.helpers).to be :current_view_context
6
6
  end
7
7
 
8
8
  it "is aliased to #h" do
9
- Draper::ViewContext.stub current: :current_view_context
9
+ allow(Draper::ViewContext).to receive_messages current: :current_view_context
10
10
  expect(subject.h).to be :current_view_context
11
11
  end
12
12
  end
13
13
 
14
14
  describe "#localize" do
15
15
  it "delegates to #helpers" do
16
- subject.stub helpers: double
17
- subject.helpers.should_receive(:localize).with(:an_object, some: "parameter")
16
+ allow(subject).to receive(:helpers).and_return(double)
17
+ expect(subject.helpers).to receive(:localize).with(:an_object, some: "parameter")
18
18
  subject.localize(:an_object, some: "parameter")
19
19
  end
20
20
 
21
21
  it "is aliased to #l" do
22
- subject.stub helpers: double
23
- subject.helpers.should_receive(:localize).with(:an_object, some: "parameter")
22
+ allow(subject).to receive_messages helpers: double
23
+ expect(subject.helpers).to receive(:localize).with(:an_object, some: "parameter")
24
24
  subject.l(:an_object, some: "parameter")
25
25
  end
26
26
  end
27
27
 
28
28
  describe ".helpers" do
29
29
  it "returns the current view context" do
30
- Draper::ViewContext.stub current: :current_view_context
30
+ allow(Draper::ViewContext).to receive_messages current: :current_view_context
31
31
  expect(subject.class.helpers).to be :current_view_context
32
32
  end
33
33
 
34
34
  it "is aliased to .h" do
35
- Draper::ViewContext.stub current: :current_view_context
35
+ allow(Draper::ViewContext).to receive(:current).and_return(:current_view_context)
36
36
  expect(subject.class.h).to be :current_view_context
37
37
  end
38
38
  end