draper 0.18.0 → 1.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 (140) hide show
  1. data/.gitignore +3 -0
  2. data/.travis.yml +11 -0
  3. data/.yardopts +1 -1
  4. data/CHANGELOG.md +161 -0
  5. data/CONTRIBUTING.md +11 -0
  6. data/Gemfile +20 -0
  7. data/LICENSE +7 -0
  8. data/README.md +324 -0
  9. data/Rakefile +52 -31
  10. data/draper.gemspec +11 -9
  11. data/lib/draper/automatic_delegation.rb +50 -0
  12. data/lib/draper/collection_decorator.rb +107 -0
  13. data/lib/draper/decoratable.rb +83 -0
  14. data/lib/draper/decorated_association.rb +74 -0
  15. data/lib/draper/decorator.rb +238 -0
  16. data/lib/draper/delegation.rb +13 -0
  17. data/lib/draper/finders.rb +37 -0
  18. data/lib/draper/helper_proxy.rb +17 -0
  19. data/lib/draper/lazy_helpers.rb +10 -6
  20. data/lib/draper/railtie.rb +27 -21
  21. data/lib/draper/tasks/test.rake +22 -0
  22. data/lib/draper/test/devise_helper.rb +34 -0
  23. data/lib/draper/test/minitest_integration.rb +2 -3
  24. data/lib/draper/test/rspec_integration.rb +3 -13
  25. data/lib/draper/test_case.rb +33 -0
  26. data/lib/draper/version.rb +1 -1
  27. data/lib/draper/view_context.rb +12 -17
  28. data/lib/draper/view_helpers.rb +37 -0
  29. data/lib/draper.rb +47 -8
  30. data/lib/generators/decorator/decorator_generator.rb +10 -2
  31. data/lib/generators/decorator/templates/decorator.rb +12 -27
  32. data/lib/generators/mini_test/decorator_generator.rb +20 -0
  33. data/lib/generators/mini_test/templates/decorator_spec.rb +4 -0
  34. data/lib/generators/mini_test/templates/decorator_test.rb +4 -0
  35. data/lib/generators/test_unit/templates/decorator_test.rb +1 -1
  36. data/spec/draper/collection_decorator_spec.rb +286 -0
  37. data/spec/draper/decoratable_spec.rb +192 -0
  38. data/spec/draper/decorated_association_spec.rb +142 -0
  39. data/spec/draper/decorator_spec.rb +624 -0
  40. data/spec/draper/finders_spec.rb +132 -0
  41. data/spec/draper/helper_proxy_spec.rb +12 -0
  42. data/spec/draper/view_helpers_spec.rb +41 -0
  43. data/spec/dummy/.rspec +2 -0
  44. data/spec/dummy/README.rdoc +261 -0
  45. data/spec/dummy/Rakefile +7 -0
  46. data/spec/dummy/app/controllers/application_controller.rb +4 -0
  47. data/spec/dummy/app/controllers/localized_urls.rb +5 -0
  48. data/spec/dummy/app/controllers/posts_controller.rb +11 -0
  49. data/spec/dummy/app/decorators/post_decorator.rb +32 -0
  50. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  51. data/spec/dummy/app/mailers/application_mailer.rb +3 -0
  52. data/spec/dummy/app/mailers/post_mailer.rb +9 -0
  53. data/spec/dummy/app/models/post.rb +3 -0
  54. data/spec/dummy/app/views/layouts/application.html.erb +11 -0
  55. data/spec/dummy/app/views/post_mailer/decorated_email.html.erb +1 -0
  56. data/spec/dummy/app/views/posts/_post.html.erb +19 -0
  57. data/spec/dummy/app/views/posts/show.html.erb +1 -0
  58. data/spec/dummy/config/application.rb +64 -0
  59. data/spec/dummy/config/boot.rb +10 -0
  60. data/spec/dummy/config/database.yml +25 -0
  61. data/spec/dummy/config/environment.rb +5 -0
  62. data/spec/dummy/config/environments/development.rb +34 -0
  63. data/spec/dummy/config/environments/production.rb +55 -0
  64. data/spec/dummy/config/environments/test.rb +32 -0
  65. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  66. data/spec/dummy/config/initializers/inflections.rb +15 -0
  67. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  68. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  69. data/spec/dummy/config/initializers/session_store.rb +8 -0
  70. data/spec/dummy/config/locales/en.yml +5 -0
  71. data/spec/dummy/config/routes.rb +7 -0
  72. data/spec/dummy/config.ru +4 -0
  73. data/spec/dummy/db/migrate/20121019115657_create_posts.rb +8 -0
  74. data/spec/dummy/db/schema.rb +21 -0
  75. data/spec/dummy/db/seeds.rb +2 -0
  76. data/spec/dummy/lib/tasks/test.rake +10 -0
  77. data/spec/dummy/log/.gitkeep +0 -0
  78. data/spec/dummy/mini_test/mini_test_integration_test.rb +46 -0
  79. data/spec/dummy/public/404.html +26 -0
  80. data/spec/dummy/public/422.html +26 -0
  81. data/spec/dummy/public/500.html +25 -0
  82. data/spec/dummy/public/favicon.ico +0 -0
  83. data/spec/dummy/script/rails +6 -0
  84. data/spec/dummy/spec/decorators/post_decorator_spec.rb +26 -0
  85. data/spec/dummy/spec/decorators/rspec_integration_spec.rb +19 -0
  86. data/spec/dummy/spec/mailers/post_mailer_spec.rb +29 -0
  87. data/spec/dummy/spec/models/post_spec.rb +14 -0
  88. data/spec/dummy/spec/spec_helper.rb +8 -0
  89. data/spec/generators/decorator/decorator_generator_spec.rb +47 -7
  90. data/spec/integration/integration_spec.rb +33 -0
  91. data/{performance → spec/performance}/decorators.rb +2 -4
  92. data/spec/spec_helper.rb +20 -45
  93. data/spec/support/action_controller.rb +12 -0
  94. data/spec/support/active_model.rb +7 -0
  95. data/spec/support/active_record.rb +9 -0
  96. data/spec/support/{samples → decorators}/decorator_with_application_helper.rb +1 -1
  97. data/spec/support/decorators/namespaced_product_decorator.rb +5 -0
  98. data/spec/support/decorators/non_active_model_product_decorator.rb +2 -0
  99. data/spec/support/decorators/product_decorator.rb +23 -0
  100. data/spec/support/{samples → decorators}/products_decorator.rb +1 -1
  101. data/spec/support/decorators/some_thing_decorator.rb +2 -0
  102. data/spec/support/{samples → decorators}/specific_product_decorator.rb +0 -2
  103. data/spec/support/dummy_app.rb +85 -0
  104. data/spec/support/matchers/have_text.rb +50 -0
  105. data/spec/support/{samples → models}/namespaced_product.rb +1 -3
  106. data/spec/support/{samples → models}/non_active_model_product.rb +1 -0
  107. data/spec/support/{samples → models}/product.rb +17 -2
  108. data/spec/support/models/some_thing.rb +5 -0
  109. data/spec/support/models/uninferrable_decorator_model.rb +3 -0
  110. metadata +241 -87
  111. data/CHANGELOG.markdown +0 -57
  112. data/Readme.markdown +0 -387
  113. data/lib/draper/active_model_support.rb +0 -27
  114. data/lib/draper/base.rb +0 -312
  115. data/lib/draper/decorated_enumerable_proxy.rb +0 -90
  116. data/lib/draper/model_support.rb +0 -25
  117. data/lib/draper/rspec_integration.rb +0 -2
  118. data/lib/draper/system.rb +0 -18
  119. data/spec/draper/base_spec.rb +0 -873
  120. data/spec/draper/decorated_enumerable_proxy_spec.rb +0 -45
  121. data/spec/draper/model_support_spec.rb +0 -48
  122. data/spec/minitest-rails/spec_type_spec.rb +0 -63
  123. data/spec/support/samples/active_record.rb +0 -17
  124. data/spec/support/samples/decorator.rb +0 -5
  125. data/spec/support/samples/decorator_with_allows.rb +0 -3
  126. data/spec/support/samples/decorator_with_denies.rb +0 -3
  127. data/spec/support/samples/decorator_with_denies_all.rb +0 -3
  128. data/spec/support/samples/decorator_with_multiple_allows.rb +0 -4
  129. data/spec/support/samples/decorator_with_special_methods.rb +0 -13
  130. data/spec/support/samples/enumerable_proxy.rb +0 -3
  131. data/spec/support/samples/namespaced_product_decorator.rb +0 -7
  132. data/spec/support/samples/product_decorator.rb +0 -7
  133. data/spec/support/samples/sequel_product.rb +0 -13
  134. data/spec/support/samples/some_thing.rb +0 -2
  135. data/spec/support/samples/some_thing_decorator.rb +0 -3
  136. /data/{performance → spec/performance}/active_record.rb +0 -0
  137. /data/{performance/bechmark.rb → spec/performance/benchmark.rb} +0 -0
  138. /data/{performance → spec/performance}/models.rb +0 -0
  139. /data/spec/support/{samples → decorators}/widget_decorator.rb +0 -0
  140. /data/spec/support/{samples → models}/widget.rb +0 -0
data/spec/spec_helper.rb CHANGED
@@ -3,52 +3,27 @@ require 'ammeter/init'
3
3
  require 'rails'
4
4
 
5
5
  require 'action_view'
6
- Bundler.require
7
-
8
- require './spec/support/samples/active_record'
9
- require './spec/support/samples/decorator'
10
- require './spec/support/samples/decorator_with_allows'
11
- require './spec/support/samples/decorator_with_multiple_allows'
12
- require './spec/support/samples/decorator_with_application_helper'
13
- require './spec/support/samples/decorator_with_denies'
14
- require './spec/support/samples/decorator_with_denies_all'
15
- require './spec/support/samples/decorator_with_special_methods'
16
- require './spec/support/samples/enumerable_proxy'
17
- require './spec/support/samples/namespaced_product'
18
- require './spec/support/samples/namespaced_product_decorator'
19
- require './spec/support/samples/non_active_model_product'
20
- require './spec/support/samples/product'
21
- require './spec/support/samples/product_decorator'
22
- require './spec/support/samples/products_decorator'
23
- require './spec/support/samples/sequel_product'
24
- require './spec/support/samples/specific_product_decorator'
25
- require './spec/support/samples/some_thing'
26
- require './spec/support/samples/some_thing_decorator'
27
- require './spec/support/samples/widget'
28
- require './spec/support/samples/widget_decorator'
29
-
30
6
  require 'action_controller'
31
7
  require 'action_controller/test_case'
32
8
 
33
- module ActionController
34
- class Base
35
- Draper::System.setup_action_controller(self)
36
- end
37
- end
38
-
39
- module ActiveRecord
40
- class Relation
41
- end
42
- end
43
-
44
- class ApplicationController < ActionController::Base
45
- def hello_world
46
- "Hello, World!"
47
- end
48
- helper_method :hello_world
49
- end
50
-
9
+ Bundler.require
51
10
 
52
- class << Rails
53
- undef application # Avoid silly Rails bug: https://github.com/rails/rails/pull/6429
54
- end
11
+ require 'support/active_model'
12
+ require 'support/active_record'
13
+ require 'support/action_controller'
14
+
15
+ require 'support/models/product'
16
+ require 'support/models/namespaced_product'
17
+ require 'support/models/non_active_model_product'
18
+ require 'support/models/widget'
19
+ require 'support/models/some_thing'
20
+ require 'support/models/uninferrable_decorator_model'
21
+
22
+ require 'support/decorators/product_decorator'
23
+ require 'support/decorators/namespaced_product_decorator'
24
+ require 'support/decorators/non_active_model_product_decorator'
25
+ require 'support/decorators/widget_decorator'
26
+ require 'support/decorators/specific_product_decorator'
27
+ require 'support/decorators/products_decorator'
28
+ require 'support/decorators/some_thing_decorator'
29
+ require 'support/decorators/decorator_with_application_helper'
@@ -0,0 +1,12 @@
1
+ module ActionController
2
+ class Base
3
+ Draper.setup_action_controller(self)
4
+ end
5
+ end
6
+
7
+ class ApplicationController < ActionController::Base
8
+ def hello_world
9
+ "Hello, World!"
10
+ end
11
+ helper_method :hello_world
12
+ end
@@ -0,0 +1,7 @@
1
+ module ActiveModel
2
+ module Serialization
3
+ def serializable_hash
4
+ {overridable: send(:overridable)}
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ module ActiveRecord
2
+ class Base
3
+ end
4
+ end
5
+
6
+ module ActiveRecord
7
+ class Relation
8
+ end
9
+ end
@@ -1,4 +1,4 @@
1
- class DecoratorWithApplicationHelper < Draper::Base
1
+ class DecoratorWithApplicationHelper < Draper::Decorator
2
2
  def uses_hello_world
3
3
  h.hello_world
4
4
  end
@@ -0,0 +1,5 @@
1
+ module Namespace
2
+ class ProductDecorator < Draper::Decorator
3
+ decorates_finders
4
+ end
5
+ end
@@ -0,0 +1,2 @@
1
+ class NonActiveModelProductDecorator
2
+ end
@@ -0,0 +1,23 @@
1
+ class ProductDecorator < Draper::Decorator
2
+ decorates_finders
3
+
4
+ def awesome_title
5
+ "Awesome Title"
6
+ end
7
+
8
+ def overridable
9
+ :overridden
10
+ end
11
+
12
+ def self.overridable
13
+ :overridden
14
+ end
15
+
16
+ def self.my_class_method
17
+ end
18
+
19
+ private
20
+
21
+ def awesome_private_title
22
+ end
23
+ end
@@ -1,4 +1,4 @@
1
- class ProductsDecorator < Draper::DecoratedEnumerableProxy
1
+ class ProductsDecorator < Draper::CollectionDecorator
2
2
 
3
3
  def link_to
4
4
  h.link_to 'sample', "#"
@@ -0,0 +1,2 @@
1
+ class SomeThingDecorator < Draper::Decorator
2
+ end
@@ -1,4 +1,2 @@
1
- require './spec/support/samples/product_decorator'
2
-
3
1
  class SpecificProductDecorator < ProductDecorator
4
2
  end
@@ -0,0 +1,85 @@
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
@@ -0,0 +1,50 @@
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_for_should
25
+ "expected to find #{@text.inspect} #{within}"
26
+ end
27
+
28
+ def failure_message_for_should_not
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,8 +1,6 @@
1
- require './spec/support/samples/product'
2
-
3
1
  module Namespace
4
2
  class Product < ActiveRecord::Base
5
- include Draper::ModelSupport
3
+ include Draper::Decoratable
6
4
 
7
5
  def self.first
8
6
  @@first ||= Namespace::Product.new
@@ -1,2 +1,3 @@
1
1
  class NonActiveModelProduct
2
+ include Draper::Decoratable
2
3
  end
@@ -1,5 +1,8 @@
1
1
  class Product < ActiveRecord::Base
2
- include Draper::ModelSupport
2
+ include Draper::Decoratable
3
+ include ActiveModel::Serialization
4
+
5
+ delegate :delegated_method, to: :thing
3
6
 
4
7
  def self.find_by_name(name)
5
8
  @@dummy ||= Product.new
@@ -22,7 +25,7 @@ class Product < ActiveRecord::Base
22
25
  end
23
26
 
24
27
  def self.model_name
25
- "Product"
28
+ name
26
29
  end
27
30
 
28
31
  def self.find(id)
@@ -77,4 +80,16 @@ class Product < ActiveRecord::Base
77
80
  Product.new
78
81
  end
79
82
 
83
+ def overridable
84
+ :overridable
85
+ end
86
+
87
+ def self.overridable
88
+ :overridable
89
+ end
90
+
91
+ private
92
+
93
+ def private_title
94
+ end
80
95
  end
@@ -0,0 +1,5 @@
1
+ class SomeThing < Product
2
+ def delegated_method
3
+ 'Yay, delegation'
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ class UninferrableDecoratorModel
2
+ include Draper::Decoratable
3
+ end