draper 0.18.0 → 1.1.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.
- data/.gitignore +3 -0
- data/.travis.yml +11 -0
- data/.yardopts +1 -1
- data/CHANGELOG.md +164 -0
- data/CONTRIBUTING.md +15 -0
- data/Gemfile +34 -0
- data/LICENSE +7 -0
- data/README.md +416 -0
- data/Rakefile +53 -31
- data/draper.gemspec +11 -9
- data/lib/draper/automatic_delegation.rb +50 -0
- data/lib/draper/collection_decorator.rb +107 -0
- data/lib/draper/decoratable/equality.rb +14 -0
- data/lib/draper/decoratable.rb +79 -0
- data/lib/draper/decorated_association.rb +74 -0
- data/lib/draper/decorator.rb +235 -0
- data/lib/draper/delegation.rb +13 -0
- data/lib/draper/finders.rb +37 -0
- data/lib/draper/helper_proxy.rb +36 -0
- data/lib/draper/lazy_helpers.rb +10 -6
- data/lib/draper/railtie.rb +27 -21
- data/lib/draper/tasks/test.rake +22 -0
- data/lib/draper/test/devise_helper.rb +30 -0
- data/lib/draper/test/minitest_integration.rb +2 -3
- data/lib/draper/test/rspec_integration.rb +7 -13
- data/lib/draper/test_case.rb +53 -0
- data/lib/draper/version.rb +1 -1
- data/lib/draper/view_context/build_strategy.rb +48 -0
- data/lib/draper/view_context.rb +81 -24
- data/lib/draper/view_helpers.rb +37 -0
- data/lib/draper.rb +50 -8
- data/lib/generators/decorator/decorator_generator.rb +10 -2
- data/lib/generators/decorator/templates/decorator.rb +12 -27
- data/lib/generators/mini_test/decorator_generator.rb +20 -0
- data/lib/generators/mini_test/templates/decorator_spec.rb +4 -0
- data/lib/generators/mini_test/templates/decorator_test.rb +4 -0
- data/lib/generators/test_unit/templates/decorator_test.rb +1 -1
- data/spec/draper/collection_decorator_spec.rb +259 -0
- data/spec/draper/decoratable/equality_spec.rb +10 -0
- data/spec/draper/decoratable_spec.rb +167 -0
- data/spec/draper/decorated_association_spec.rb +145 -0
- data/spec/draper/decorator_spec.rb +598 -0
- data/spec/draper/finders_spec.rb +166 -0
- data/spec/draper/helper_proxy_spec.rb +42 -0
- data/spec/draper/view_context/build_strategy_spec.rb +116 -0
- data/spec/draper/view_context_spec.rb +154 -0
- data/spec/draper/view_helpers_spec.rb +8 -0
- data/spec/dummy/.rspec +2 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +4 -0
- data/spec/dummy/app/controllers/localized_urls.rb +5 -0
- data/spec/dummy/app/controllers/posts_controller.rb +18 -0
- data/spec/dummy/app/decorators/post_decorator.rb +56 -0
- data/spec/dummy/app/helpers/application_helper.rb +5 -0
- data/spec/dummy/app/mailers/application_mailer.rb +3 -0
- data/spec/dummy/app/mailers/post_mailer.rb +19 -0
- data/spec/dummy/app/models/admin.rb +5 -0
- data/spec/dummy/app/models/mongoid_post.rb +5 -0
- data/spec/dummy/app/models/post.rb +3 -0
- data/spec/dummy/app/models/user.rb +5 -0
- data/spec/dummy/app/views/layouts/application.html.erb +11 -0
- data/spec/dummy/app/views/post_mailer/decorated_email.html.erb +1 -0
- data/spec/dummy/app/views/posts/_post.html.erb +34 -0
- data/spec/dummy/app/views/posts/show.html.erb +1 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/config/application.rb +70 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +33 -0
- data/spec/dummy/config/environments/production.rb +57 -0
- data/spec/dummy/config/environments/test.rb +31 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +8 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/mongoid.yml +80 -0
- data/spec/dummy/config/routes.rb +9 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/migrate/20121019115657_create_posts.rb +8 -0
- data/spec/dummy/db/schema.rb +21 -0
- data/spec/dummy/db/seeds.rb +2 -0
- data/spec/dummy/fast_spec/post_decorator_spec.rb +38 -0
- data/spec/dummy/lib/tasks/test.rake +16 -0
- data/spec/dummy/log/.gitkeep +0 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/dummy/spec/decorators/devise_spec.rb +64 -0
- data/spec/dummy/spec/decorators/helpers_spec.rb +21 -0
- data/spec/dummy/spec/decorators/post_decorator_spec.rb +46 -0
- data/spec/dummy/spec/decorators/spec_type_spec.rb +7 -0
- data/spec/dummy/spec/decorators/view_context_spec.rb +22 -0
- data/spec/dummy/spec/mailers/post_mailer_spec.rb +33 -0
- data/spec/dummy/spec/models/mongoid_post_spec.rb +10 -0
- data/spec/dummy/spec/models/post_spec.rb +14 -0
- data/spec/dummy/spec/spec_helper.rb +9 -0
- data/spec/dummy/test/decorators/minitest/devise_test.rb +64 -0
- data/spec/dummy/test/decorators/minitest/helpers_test.rb +21 -0
- data/spec/dummy/test/decorators/minitest/spec_type_test.rb +52 -0
- data/spec/dummy/test/decorators/minitest/view_context_test.rb +24 -0
- data/spec/dummy/test/decorators/test_unit/devise_test.rb +64 -0
- data/spec/dummy/test/decorators/test_unit/helpers_test.rb +21 -0
- data/spec/dummy/test/decorators/test_unit/view_context_test.rb +24 -0
- data/spec/dummy/test/minitest_helper.rb +4 -0
- data/spec/dummy/test/test_helper.rb +3 -0
- data/spec/generators/decorator/decorator_generator_spec.rb +48 -7
- data/spec/integration/integration_spec.rb +58 -0
- data/{performance → spec/performance}/decorators.rb +2 -4
- data/spec/spec_helper.rb +25 -43
- data/spec/support/dummy_app.rb +85 -0
- data/spec/support/matchers/have_text.rb +50 -0
- data/spec/support/shared_examples/decoratable_equality.rb +40 -0
- data/spec/support/shared_examples/view_helpers.rb +39 -0
- metadata +253 -87
- data/CHANGELOG.markdown +0 -57
- data/Readme.markdown +0 -387
- data/lib/draper/active_model_support.rb +0 -27
- data/lib/draper/base.rb +0 -312
- data/lib/draper/decorated_enumerable_proxy.rb +0 -90
- data/lib/draper/model_support.rb +0 -25
- data/lib/draper/rspec_integration.rb +0 -2
- data/lib/draper/system.rb +0 -18
- data/spec/draper/base_spec.rb +0 -873
- data/spec/draper/decorated_enumerable_proxy_spec.rb +0 -45
- data/spec/draper/model_support_spec.rb +0 -48
- data/spec/minitest-rails/spec_type_spec.rb +0 -63
- data/spec/support/samples/active_record.rb +0 -17
- data/spec/support/samples/decorator.rb +0 -5
- data/spec/support/samples/decorator_with_allows.rb +0 -3
- data/spec/support/samples/decorator_with_application_helper.rb +0 -25
- data/spec/support/samples/decorator_with_denies.rb +0 -3
- data/spec/support/samples/decorator_with_denies_all.rb +0 -3
- data/spec/support/samples/decorator_with_multiple_allows.rb +0 -4
- data/spec/support/samples/decorator_with_special_methods.rb +0 -13
- data/spec/support/samples/enumerable_proxy.rb +0 -3
- data/spec/support/samples/namespaced_product.rb +0 -51
- data/spec/support/samples/namespaced_product_decorator.rb +0 -7
- data/spec/support/samples/non_active_model_product.rb +0 -2
- data/spec/support/samples/product.rb +0 -80
- data/spec/support/samples/product_decorator.rb +0 -7
- data/spec/support/samples/products_decorator.rb +0 -10
- data/spec/support/samples/sequel_product.rb +0 -13
- data/spec/support/samples/some_thing.rb +0 -2
- data/spec/support/samples/some_thing_decorator.rb +0 -3
- data/spec/support/samples/specific_product_decorator.rb +0 -4
- data/spec/support/samples/widget.rb +0 -2
- data/spec/support/samples/widget_decorator.rb +0 -2
- /data/{performance → spec/performance}/active_record.rb +0 -0
- /data/{performance/bechmark.rb → spec/performance/benchmark.rb} +0 -0
- /data/{performance → spec/performance}/models.rb +0 -0
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
require "./performance/models"
|
|
2
|
-
class ProductDecorator < Draper::
|
|
3
|
-
decorates :product
|
|
2
|
+
class ProductDecorator < Draper::Decorator
|
|
4
3
|
|
|
5
4
|
def awesome_title
|
|
6
5
|
"Awesome Title"
|
|
@@ -21,8 +20,7 @@ class ProductDecorator < Draper::Base
|
|
|
21
20
|
|
|
22
21
|
end
|
|
23
22
|
|
|
24
|
-
class FastProductDecorator < Draper::
|
|
25
|
-
decorates :product
|
|
23
|
+
class FastProductDecorator < Draper::Decorator
|
|
26
24
|
|
|
27
25
|
def awesome_title
|
|
28
26
|
"Awesome Title"
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,54 +1,36 @@
|
|
|
1
1
|
require 'bundler/setup'
|
|
2
|
-
require '
|
|
3
|
-
require 'rails'
|
|
4
|
-
|
|
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
|
-
|
|
2
|
+
require 'draper'
|
|
30
3
|
require 'action_controller'
|
|
31
4
|
require 'action_controller/test_case'
|
|
32
5
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
6
|
+
RSpec.configure do |config|
|
|
7
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
|
8
|
+
config.expect_with(:rspec) {|c| c.syntax = :expect}
|
|
9
|
+
config.order = :random
|
|
37
10
|
end
|
|
38
11
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
end
|
|
12
|
+
class Model; include Draper::Decoratable; end
|
|
13
|
+
|
|
14
|
+
class Product < Model; end
|
|
15
|
+
class ProductDecorator < Draper::Decorator; end
|
|
16
|
+
class ProductsDecorator < Draper::CollectionDecorator; end
|
|
17
|
+
|
|
18
|
+
class ProductPresenter < Draper::Decorator; end
|
|
43
19
|
|
|
44
|
-
class
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
end
|
|
48
|
-
|
|
20
|
+
class OtherDecorator < Draper::Decorator; end
|
|
21
|
+
|
|
22
|
+
module Namespaced
|
|
23
|
+
class Product < Model; end
|
|
24
|
+
class ProductDecorator < Draper::Decorator; end
|
|
25
|
+
|
|
26
|
+
class OtherDecorator < Draper::Decorator; end
|
|
49
27
|
end
|
|
50
28
|
|
|
29
|
+
# After each example, revert changes made to the class
|
|
30
|
+
def protect_class(klass)
|
|
31
|
+
before { stub_const klass.name, Class.new(klass) }
|
|
32
|
+
end
|
|
51
33
|
|
|
52
|
-
|
|
53
|
-
|
|
34
|
+
def protect_module(mod)
|
|
35
|
+
before { stub_const mod.name, mod.dup }
|
|
54
36
|
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
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
shared_examples_for "decoration-aware #==" do |subject|
|
|
2
|
+
it "is true for itself" do
|
|
3
|
+
expect(subject == subject).to be_true
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
it "is false for another object" do
|
|
7
|
+
expect(subject == Object.new).to be_false
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it "is true for a decorated version of itself" do
|
|
11
|
+
decorated = double(source: subject, decorated?: true)
|
|
12
|
+
|
|
13
|
+
expect(subject == decorated).to be_true
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "is false for a decorated other object" do
|
|
17
|
+
decorated = double(source: Object.new, decorated?: true)
|
|
18
|
+
|
|
19
|
+
expect(subject == decorated).to be_false
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "is false for a decoratable object with a `source` association" do
|
|
23
|
+
decoratable = double(source: subject, decorated?: false)
|
|
24
|
+
|
|
25
|
+
expect(subject == decoratable).to be_false
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "is false for an undecoratable object with a `source` association" do
|
|
29
|
+
undecoratable = double(source: subject)
|
|
30
|
+
|
|
31
|
+
expect(subject == undecoratable).to be_false
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "is true for a multiply-decorated version of itself" do
|
|
35
|
+
decorated = double(source: subject, decorated?: true)
|
|
36
|
+
redecorated = double(source: decorated, decorated?: true)
|
|
37
|
+
|
|
38
|
+
expect(subject == redecorated).to be_true
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
shared_examples_for "view helpers" do |subject|
|
|
2
|
+
describe "#helpers" do
|
|
3
|
+
it "returns the current view context" do
|
|
4
|
+
Draper::ViewContext.stub current: :current_view_context
|
|
5
|
+
expect(subject.helpers).to be :current_view_context
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it "is aliased to #h" do
|
|
9
|
+
Draper::ViewContext.stub 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
|
+
subject.stub helpers: double
|
|
17
|
+
subject.helpers.should_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
|
+
subject.stub helpers: double
|
|
23
|
+
subject.helpers.should_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
|
+
Draper::ViewContext.stub 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
|
+
Draper::ViewContext.stub current: :current_view_context
|
|
36
|
+
expect(subject.class.h).to be :current_view_context
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|