draper 4.0.2 → 4.0.5

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 (131) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -2
  3. data/CHANGELOG.md +24 -0
  4. data/README.md +26 -7
  5. data/lib/draper/automatic_delegation.rb +14 -4
  6. data/lib/draper/collection_decorator.rb +0 -6
  7. data/lib/draper/compatibility/broadcastable.rb +24 -0
  8. data/lib/draper/compatibility/global_id.rb +9 -5
  9. data/lib/draper/decoratable/collection_proxy.rb +15 -0
  10. data/lib/draper/decoratable.rb +7 -2
  11. data/lib/draper/decorator.rb +2 -18
  12. data/lib/draper/query_methods.rb +1 -1
  13. data/lib/draper/railtie.rb +14 -5
  14. data/lib/draper/version.rb +1 -1
  15. data/lib/draper/view_context/build_strategy.rb +1 -9
  16. data/lib/draper.rb +0 -6
  17. metadata +16 -235
  18. data/.github/PULL_REQUEST_TEMPLATE.md +0 -24
  19. data/.github/workflows/ci.yml +0 -55
  20. data/.gitignore +0 -18
  21. data/Gemfile +0 -24
  22. data/bin/bundle +0 -114
  23. data/bin/rake +0 -29
  24. data/draper.gemspec +0 -34
  25. data/spec/draper/collection_decorator_spec.rb +0 -291
  26. data/spec/draper/configuration_spec.rb +0 -49
  27. data/spec/draper/decoratable/equality_spec.rb +0 -10
  28. data/spec/draper/decoratable_spec.rb +0 -235
  29. data/spec/draper/decorated_association_spec.rb +0 -82
  30. data/spec/draper/decorates_assigned_spec.rb +0 -71
  31. data/spec/draper/decorator_spec.rb +0 -872
  32. data/spec/draper/draper_spec.rb +0 -25
  33. data/spec/draper/factory_spec.rb +0 -247
  34. data/spec/draper/finders_spec.rb +0 -166
  35. data/spec/draper/helper_proxy_spec.rb +0 -61
  36. data/spec/draper/lazy_helpers_spec.rb +0 -21
  37. data/spec/draper/query_methods/load_strategy_spec.rb +0 -26
  38. data/spec/draper/query_methods_spec.rb +0 -70
  39. data/spec/draper/undecorate_chain_spec.rb +0 -20
  40. data/spec/draper/undecorate_spec.rb +0 -19
  41. data/spec/draper/view_context/build_strategy_spec.rb +0 -132
  42. data/spec/draper/view_context_spec.rb +0 -182
  43. data/spec/draper/view_helpers_spec.rb +0 -8
  44. data/spec/dummy/.rspec +0 -2
  45. data/spec/dummy/Rakefile +0 -7
  46. data/spec/dummy/app/assets/config/manifest.js +0 -3
  47. data/spec/dummy/app/controllers/application_controller.rb +0 -2
  48. data/spec/dummy/app/controllers/base_controller.rb +0 -4
  49. data/spec/dummy/app/controllers/localized_urls.rb +0 -5
  50. data/spec/dummy/app/controllers/posts_controller.rb +0 -20
  51. data/spec/dummy/app/decorators/mongoid_post_decorator.rb +0 -4
  52. data/spec/dummy/app/decorators/post_decorator.rb +0 -60
  53. data/spec/dummy/app/helpers/application_helper.rb +0 -5
  54. data/spec/dummy/app/jobs/publish_post_job.rb +0 -7
  55. data/spec/dummy/app/mailers/application_mailer.rb +0 -3
  56. data/spec/dummy/app/mailers/post_mailer.rb +0 -19
  57. data/spec/dummy/app/models/admin.rb +0 -5
  58. data/spec/dummy/app/models/application_record.rb +0 -3
  59. data/spec/dummy/app/models/mongoid_post.rb +0 -5
  60. data/spec/dummy/app/models/post.rb +0 -3
  61. data/spec/dummy/app/models/user.rb +0 -5
  62. data/spec/dummy/app/views/layouts/application.html.erb +0 -11
  63. data/spec/dummy/app/views/post_mailer/decorated_email.html.erb +0 -1
  64. data/spec/dummy/app/views/posts/_post.html.erb +0 -42
  65. data/spec/dummy/app/views/posts/show.html.erb +0 -1
  66. data/spec/dummy/bin/rails +0 -4
  67. data/spec/dummy/config/application.rb +0 -68
  68. data/spec/dummy/config/boot.rb +0 -5
  69. data/spec/dummy/config/database.yml +0 -25
  70. data/spec/dummy/config/environment.rb +0 -5
  71. data/spec/dummy/config/environments/development.rb +0 -35
  72. data/spec/dummy/config/environments/production.rb +0 -59
  73. data/spec/dummy/config/environments/test.rb +0 -35
  74. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
  75. data/spec/dummy/config/initializers/draper.rb +0 -3
  76. data/spec/dummy/config/initializers/filter_parameter_logging.rb +0 -4
  77. data/spec/dummy/config/initializers/inflections.rb +0 -15
  78. data/spec/dummy/config/initializers/mime_types.rb +0 -5
  79. data/spec/dummy/config/initializers/secret_token.rb +0 -8
  80. data/spec/dummy/config/initializers/session_store.rb +0 -8
  81. data/spec/dummy/config/locales/en.yml +0 -5
  82. data/spec/dummy/config/mongoid.yml +0 -142
  83. data/spec/dummy/config/routes.rb +0 -9
  84. data/spec/dummy/config/storage.yml +0 -7
  85. data/spec/dummy/config.ru +0 -4
  86. data/spec/dummy/db/migrate/20121019115657_create_posts.rb +0 -8
  87. data/spec/dummy/db/schema.rb +0 -21
  88. data/spec/dummy/db/seeds.rb +0 -2
  89. data/spec/dummy/fast_spec/post_decorator_spec.rb +0 -37
  90. data/spec/dummy/lib/tasks/test.rake +0 -16
  91. data/spec/dummy/log/.gitkeep +0 -0
  92. data/spec/dummy/public/404.html +0 -26
  93. data/spec/dummy/public/422.html +0 -26
  94. data/spec/dummy/public/500.html +0 -25
  95. data/spec/dummy/public/favicon.ico +0 -0
  96. data/spec/dummy/script/rails +0 -6
  97. data/spec/dummy/spec/decorators/active_model_serializers_spec.rb +0 -12
  98. data/spec/dummy/spec/decorators/devise_spec.rb +0 -55
  99. data/spec/dummy/spec/decorators/helpers_spec.rb +0 -21
  100. data/spec/dummy/spec/decorators/post_decorator_spec.rb +0 -64
  101. data/spec/dummy/spec/decorators/spec_type_spec.rb +0 -7
  102. data/spec/dummy/spec/decorators/view_context_spec.rb +0 -22
  103. data/spec/dummy/spec/jobs/publish_post_job_spec.rb +0 -9
  104. data/spec/dummy/spec/mailers/post_mailer_spec.rb +0 -25
  105. data/spec/dummy/spec/models/application_spec.rb +0 -7
  106. data/spec/dummy/spec/models/mongoid_post_spec.rb +0 -8
  107. data/spec/dummy/spec/models/post_spec.rb +0 -15
  108. data/spec/dummy/spec/shared_examples/decoratable.rb +0 -22
  109. data/spec/dummy/spec/spec_helper.rb +0 -8
  110. data/spec/dummy/test/decorators/minitest/devise_test.rb +0 -55
  111. data/spec/dummy/test/decorators/minitest/helpers_test.rb +0 -21
  112. data/spec/dummy/test/decorators/minitest/spec_type_test.rb +0 -52
  113. data/spec/dummy/test/decorators/minitest/view_context_test.rb +0 -24
  114. data/spec/dummy/test/decorators/test_unit/devise_test.rb +0 -55
  115. data/spec/dummy/test/decorators/test_unit/helpers_test.rb +0 -21
  116. data/spec/dummy/test/decorators/test_unit/view_context_test.rb +0 -24
  117. data/spec/dummy/test/minitest_helper.rb +0 -2
  118. data/spec/dummy/test/test_helper.rb +0 -3
  119. data/spec/generators/controller/controller_generator_spec.rb +0 -23
  120. data/spec/generators/decorator/decorator_generator_spec.rb +0 -93
  121. data/spec/generators/install/install_generator_spec.rb +0 -19
  122. data/spec/integration/integration_spec.rb +0 -70
  123. data/spec/performance/active_record.rb +0 -4
  124. data/spec/performance/benchmark.rb +0 -55
  125. data/spec/performance/decorators.rb +0 -45
  126. data/spec/performance/models.rb +0 -20
  127. data/spec/spec_helper.rb +0 -50
  128. data/spec/support/dummy_app.rb +0 -85
  129. data/spec/support/matchers/have_text.rb +0 -50
  130. data/spec/support/shared_examples/decoratable_equality.rb +0 -40
  131. data/spec/support/shared_examples/view_helpers.rb +0 -39
@@ -1,70 +0,0 @@
1
- require 'spec_helper'
2
- require 'support/dummy_app'
3
- require 'support/matchers/have_text'
4
- SimpleCov.command_name 'test:integration'
5
-
6
- app = DummyApp.new(ENV["RAILS_ENV"])
7
- spec_types = {
8
- view: ["/posts/1", "PostsController"],
9
- mailer: ["/posts/1/mail", "PostMailer"]
10
- }
11
-
12
- app.start_server do
13
- spec_types.each do |type, (path, controller)|
14
- page = app.get(path)
15
-
16
- describe "in a #{type}" do
17
- it "runs in the correct environment" do
18
- expect(page).to have_text(app.environment).in("#environment")
19
- end
20
-
21
- it "uses the correct view context controller" do
22
- expect(page).to have_text(controller).in("#controller")
23
- end
24
-
25
- it "can use built-in helpers" do
26
- expect(page).to have_text("Once upon a...").in("#truncated")
27
- end
28
-
29
- it "can use built-in private helpers" do
30
- # Nokogiri unescapes text!
31
- expect(page).to have_text("<script>danger</script>").in("#html_escaped")
32
- end
33
-
34
- it "can use user-defined helpers from app/helpers" do
35
- expect(page).to have_text("Hello, world!").in("#hello_world")
36
- end
37
-
38
- it "can use user-defined helpers from the controller" do
39
- expect(page).to have_text("Goodnight, moon!").in("#goodnight_moon")
40
- end
41
-
42
- # _path helpers aren't available in mailers
43
- if type == :view
44
- it "can be passed to path helpers" do
45
- expect(page).to have_text("/en/posts/1").in("#path_with_decorator")
46
- end
47
-
48
- it "can use path helpers with a model" do
49
- expect(page).to have_text("/en/posts/1").in("#path_with_model")
50
- end
51
-
52
- it "can use path helpers with an id" do
53
- expect(page).to have_text("/en/posts/1").in("#path_with_id")
54
- end
55
- end
56
-
57
- it "can be passed to url helpers" do
58
- expect(page).to have_text("http://www.example.com:12345/en/posts/1").in("#url_with_decorator")
59
- end
60
-
61
- it "can use url helpers with a model" do
62
- expect(page).to have_text("http://www.example.com:12345/en/posts/1").in("#url_with_model")
63
- end
64
-
65
- it "can use url helpers with an id" do
66
- expect(page).to have_text("http://www.example.com:12345/en/posts/1").in("#url_with_id")
67
- end
68
- end
69
- end
70
- end
@@ -1,4 +0,0 @@
1
- module ActiveRecord
2
- class Base
3
- end
4
- end
@@ -1,55 +0,0 @@
1
- require 'rubygems'
2
- ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
3
- require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
4
- Bundler.require :default
5
-
6
- require "benchmark"
7
- require "draper"
8
- require "./performance/models"
9
- require "./performance/decorators"
10
-
11
- Benchmark.bm do |bm|
12
- puts "\n[ Exclusivelly using #method_missing for model delegation ]"
13
- [ 1_000, 10_000, 100_000 ].each do |i|
14
- puts "\n[ #{i} ]"
15
- bm.report("#new ") do
16
- i.times do |n|
17
- ProductDecorator.decorate(Product.new)
18
- end
19
- end
20
-
21
- bm.report("#hello_world ") do
22
- i.times do |n|
23
- ProductDecorator.decorate(Product.new).hello_world
24
- end
25
- end
26
-
27
- bm.report("#sample_class_method ") do
28
- i.times do |n|
29
- ProductDecorator.decorate(Product.new).class.sample_class_method
30
- end
31
- end
32
- end
33
-
34
- puts "\n[ Defining methods on method_missing first hit ]"
35
- [ 1_000, 10_000, 100_000 ].each do |i|
36
- puts "\n[ #{i} ]"
37
- bm.report("#new ") do
38
- i.times do |n|
39
- FastProductDecorator.decorate(FastProduct.new)
40
- end
41
- end
42
-
43
- bm.report("#hello_world ") do
44
- i.times do |n|
45
- FastProductDecorator.decorate(FastProduct.new).hello_world
46
- end
47
- end
48
-
49
- bm.report("#sample_class_method ") do
50
- i.times do |n|
51
- FastProductDecorator.decorate(FastProduct.new).class.sample_class_method
52
- end
53
- end
54
- end
55
- end
@@ -1,45 +0,0 @@
1
- require "./performance/models"
2
- class ProductDecorator < Draper::Decorator
3
-
4
- def awesome_title
5
- "Awesome Title"
6
- end
7
-
8
- # Original #method_missing
9
- def method_missing(method, *args, &block)
10
- if allow?(method)
11
- begin
12
- model.send(method, *args, &block)
13
- rescue NoMethodError
14
- super
15
- end
16
- else
17
- super
18
- end
19
- end
20
-
21
- end
22
-
23
- class FastProductDecorator < Draper::Decorator
24
-
25
- def awesome_title
26
- "Awesome Title"
27
- end
28
-
29
- # Modified #method_missing
30
- def method_missing(method, *args, &block)
31
- if allow?(method)
32
- begin
33
- self.class.send :define_method, method do |*args, &block|
34
- model.send(method, *args, &block)
35
- end
36
- self.send(method, *args, &block)
37
- rescue NoMethodError
38
- super
39
- end
40
- else
41
- super
42
- end
43
- end
44
-
45
- end
@@ -1,20 +0,0 @@
1
- require "./performance/active_record"
2
- class Product < ActiveRecord::Base
3
- def self.sample_class_method
4
- "sample class method"
5
- end
6
-
7
- def hello_world
8
- "Hello, World"
9
- end
10
- end
11
-
12
- class FastProduct < ActiveRecord::Base
13
- def self.sample_class_method
14
- "sample class method"
15
- end
16
-
17
- def hello_world
18
- "Hello, World"
19
- end
20
- end
data/spec/spec_helper.rb DELETED
@@ -1,50 +0,0 @@
1
- require 'simplecov'
2
- SimpleCov.start do
3
- add_filter 'spec'
4
- add_group 'Draper', 'lib/draper'
5
- add_group 'Generators', 'lib/generators'
6
- end
7
-
8
- require 'bundler/setup'
9
- require 'draper'
10
- require 'action_controller'
11
- require 'action_controller/test_case'
12
-
13
- RSpec.configure do |config|
14
- config.expect_with(:rspec) {|c| c.syntax = :expect}
15
- config.order = :random
16
- config.mock_with :rspec do |mocks|
17
- mocks.yield_receiver_to_any_instance_implementation_blocks = true
18
- end
19
- end
20
-
21
- class Model; include Draper::Decoratable; end
22
-
23
- class Product < Model; end
24
- class SpecialProduct < Product; end
25
- class Other < Model; end
26
- class Person < Model; end
27
- class Child < Person; end
28
- class ProductDecorator < Draper::Decorator; end
29
- class ProductsDecorator < Draper::CollectionDecorator; end
30
-
31
- class OtherDecorator < Draper::Decorator; end
32
-
33
- module Namespaced
34
- class Product < Model; end
35
- class ProductDecorator < Draper::Decorator; end
36
- ProductsDecorator = Class.new(Draper::CollectionDecorator)
37
- class OtherDecorator < Draper::Decorator; end
38
- end
39
-
40
- ApplicationController = Class.new(ActionController::Base)
41
- CustomController = Class.new(ActionController::Base)
42
-
43
- # After each example, revert changes made to the class
44
- def protect_class(klass)
45
- before { stub_const klass.name, Class.new(klass) }
46
- end
47
-
48
- def protect_module(mod)
49
- before { stub_const mod.name, mod.dup }
50
- end
@@ -1,85 +0,0 @@
1
- require 'socket'
2
- require 'net/http'
3
-
4
- # Adapted from code by Jon Leighton
5
- # https://github.com/jonleighton/focused_controller/blob/ec7ccf1/test/acceptance/app_test.rb
6
-
7
- class DummyApp
8
-
9
- def initialize(environment)
10
- raise ArgumentError, "Environment must be development or production" unless ["development", "production"].include?(environment.to_s)
11
- @environment = environment
12
- end
13
-
14
- attr_reader :environment
15
-
16
- def url
17
- "http://#{localhost}:#{port}"
18
- end
19
-
20
- def get(path)
21
- Net::HTTP.get(URI(url + path))
22
- end
23
-
24
- def within_app(&block)
25
- Dir.chdir(root, &block)
26
- end
27
-
28
- def start_server
29
- within_app do
30
- IO.popen("bundle exec rails s -e #{@environment} -p #{port} 2>&1") do |out|
31
- start = Time.now
32
- started = false
33
- output = ""
34
- timeout = 60.0
35
-
36
- while !started && !out.eof? && Time.now - start <= timeout
37
- output << read_output(out)
38
- sleep 0.1
39
-
40
- begin
41
- TCPSocket.new(localhost, port)
42
- rescue Errno::ECONNREFUSED
43
- else
44
- started = true
45
- end
46
- end
47
-
48
- raise "Server failed to start:\n#{output}" unless started
49
-
50
- yield
51
-
52
- Process.kill("KILL", out.pid)
53
- File.delete("tmp/pids/server.pid")
54
- end
55
- end
56
- end
57
-
58
- private
59
-
60
- def root
61
- File.expand_path("../../dummy", __FILE__)
62
- end
63
-
64
- def localhost
65
- "127.0.0.1"
66
- end
67
-
68
- def port
69
- @port ||= begin
70
- server = TCPServer.new(localhost, 0)
71
- server.addr[1]
72
- ensure
73
- server.close if server
74
- end
75
- end
76
-
77
- def read_output(stream)
78
- read = IO.select([stream], [], [stream], 0.1)
79
- output = ""
80
- loop { output << stream.read_nonblock(1024) } if read
81
- output
82
- rescue Errno::EAGAIN, Errno::EWOULDBLOCK, EOFError
83
- output
84
- end
85
- end
@@ -1,50 +0,0 @@
1
- require 'capybara'
2
-
3
- module HaveTextMatcher
4
- def have_text(text)
5
- HaveText.new(text)
6
- end
7
-
8
- class HaveText
9
- def initialize(text)
10
- @text = text
11
- end
12
-
13
- def in(css)
14
- @css = css
15
- self
16
- end
17
-
18
- def matches?(subject)
19
- @subject = Capybara.string(subject)
20
-
21
- @subject.has_css?(@css || "*", text: @text)
22
- end
23
-
24
- def failure_message
25
- "expected to find #{@text.inspect} #{within}"
26
- end
27
-
28
- def failure_message_when_negated
29
- "expected not to find #{@text.inspect} #{within}"
30
- end
31
-
32
- private
33
-
34
- def within
35
- if @css && @subject.has_css?(@css)
36
- "within\n#{@subject.find(@css).native}"
37
- else
38
- "#{inside} within\n#{@subject.native}"
39
- end
40
- end
41
-
42
- def inside
43
- @css ? "inside #{@css.inspect}" : "anywhere"
44
- end
45
- end
46
- end
47
-
48
- RSpec.configure do |config|
49
- config.include HaveTextMatcher
50
- end
@@ -1,40 +0,0 @@
1
- shared_examples_for "decoration-aware #==" do |subject|
2
- it "is true for itself" do
3
- expect(subject == subject).to be_truthy
4
- end
5
-
6
- it "is false for another object" do
7
- expect(subject == Object.new).to be_falsey
8
- end
9
-
10
- it "is true for a decorated version of itself" do
11
- decorated = double(object: subject, decorated?: true)
12
-
13
- expect(subject == decorated).to be_truthy
14
- end
15
-
16
- it "is false for a decorated other object" do
17
- decorated = double(object: Object.new, decorated?: true)
18
-
19
- expect(subject == decorated).to be_falsey
20
- end
21
-
22
- it "is false for a decoratable object with a `object` association" do
23
- decoratable = double(object: subject, decorated?: false)
24
-
25
- expect(subject == decoratable).to be_falsey
26
- end
27
-
28
- it "is false for an undecoratable object with a `object` association" do
29
- undecoratable = double(object: subject)
30
-
31
- expect(subject == undecoratable).to be_falsey
32
- end
33
-
34
- it "is true for a multiply-decorated version of itself" do
35
- decorated = double(object: subject, decorated?: true)
36
- redecorated = double(object: decorated, decorated?: true)
37
-
38
- expect(subject == redecorated).to be_truthy
39
- end
40
- end
@@ -1,39 +0,0 @@
1
- shared_examples_for "view helpers" do |subject|
2
- describe "#helpers" do
3
- it "returns the current view context" do
4
- allow(Draper::ViewContext).to receive_messages current: :current_view_context
5
- expect(subject.helpers).to be :current_view_context
6
- end
7
-
8
- it "is aliased to #h" do
9
- allow(Draper::ViewContext).to receive_messages current: :current_view_context
10
- expect(subject.h).to be :current_view_context
11
- end
12
- end
13
-
14
- describe "#localize" do
15
- it "delegates to #helpers" do
16
- allow(subject).to receive(:helpers).and_return(double)
17
- expect(subject.helpers).to receive(:localize).with(:an_object, some: "parameter")
18
- subject.localize(:an_object, some: "parameter")
19
- end
20
-
21
- it "is aliased to #l" do
22
- allow(subject).to receive_messages helpers: double
23
- expect(subject.helpers).to receive(:localize).with(:an_object, some: "parameter")
24
- subject.l(:an_object, some: "parameter")
25
- end
26
- end
27
-
28
- describe ".helpers" do
29
- it "returns the current view context" do
30
- allow(Draper::ViewContext).to receive_messages current: :current_view_context
31
- expect(subject.class.helpers).to be :current_view_context
32
- end
33
-
34
- it "is aliased to .h" do
35
- allow(Draper::ViewContext).to receive(:current).and_return(:current_view_context)
36
- expect(subject.class.h).to be :current_view_context
37
- end
38
- end
39
- end