Rename `source` to `object`

Closes #501
This commit is contained in:
Andrew Haines 2013-04-30 14:10:52 +01:00
parent 807a50cfa5
commit 4b933ef39d
21 changed files with 228 additions and 206 deletions

View File

@ -82,7 +82,7 @@ class ArticleDecorator < Draper::Decorator
end
def published_at
source.published_at.strftime("%A, %B %e")
object.published_at.strftime("%A, %B %e")
end
end
```
@ -173,12 +173,12 @@ never have to type `h.` again.
When writing decorator methods you'll usually need to access the wrapped model.
While you may choose to use delegation ([covered below](#delegating-methods))
for convenience, you can always use the `source` (or its alias `model`):
for convenience, you can always use the `object` (or its alias `model`):
```ruby
class ArticleDecorator < Draper::Decorator
def published_at
source.published_at.strftime("%A, %B %e")
object.published_at.strftime("%A, %B %e")
end
end
```
@ -250,7 +250,7 @@ Some pagination gems add methods to `ActiveRecord::Relation`. For example,
[Kaminari](https://github.com/amatsuda/kaminari)'s `paginate` helper method
requires the collection to implement `current_page`, `total_pages`, and
`limit_value`. To expose these on a collection decorator, you can delegate to
the `source`:
the `object`:
```ruby
class PaginatingDecorator < Draper::CollectionDecorator
@ -260,7 +260,7 @@ end
The `delegate` method used here is the same as that added by [Active
Support](http://api.rubyonrails.org/classes/Module.html#method-i-delegate),
except that the `:to` option is not required; it defaults to `:source` when
except that the `:to` option is not required; it defaults to `:object` when
omitted.
[will_paginate](https://github.com/mislav/will_paginate) needs you to
@ -444,7 +444,7 @@ end
### Delegating Methods
When your decorator calls `delegate_all`, any method called on the decorator not
defined in the decorator itself will be delegated to the decorated source. This
defined in the decorator itself will be delegated to the decorated object. This
is a very permissive interface.
If you want to strictly control which methods are called within views, you can
@ -456,8 +456,8 @@ class ArticleDecorator < Draper::Decorator
end
```
We omit the `:to` argument here as it defaults to the `source` object. You could
choose to delegate methods to other places like this:
We omit the `:to` argument here as it defaults to the `object` being decorated.
You could choose to delegate methods to other places like this:
```ruby
class ArticleDecorator < Draper::Decorator

View File

@ -18,7 +18,7 @@ module Draper
# @private
def delegatable?(method)
source.respond_to?(method)
object.respond_to?(method)
end
module ClassMethods

View File

@ -15,7 +15,7 @@ module Draper
array_methods = Array.instance_methods - Object.instance_methods
delegate :==, :as_json, *array_methods, to: :decorated_collection
# @param [Enumerable] source
# @param [Enumerable] object
# collection to decorate.
# @option options [Class, nil] :with (nil)
# the decorator class used to decorate each item. When `nil`, each item's
@ -23,9 +23,9 @@ module Draper
# @option options [Hash] :context ({})
# extra data to be stored in the collection decorator and used in
# user-defined methods, and passed to each item's decorator.
def initialize(source, options = {})
def initialize(object, options = {})
options.assert_valid_keys(:with, :context)
@source = source
@object = object
@decorator_class = options[:with]
@context = options.fetch(:context, {})
end
@ -36,7 +36,7 @@ module Draper
# @return [Array] the decorated items.
def decorated_collection
@decorated_collection ||= source.map{|item| decorate_item(item)}
@decorated_collection ||= object.map{|item| decorate_item(item)}
end
# Delegated to the decorated collection when using the block form
@ -47,12 +47,12 @@ module Draper
decorated_collection.find(*args, &block)
else
ActiveSupport::Deprecation.warn("Using ActiveRecord's `find` on a CollectionDecorator is deprecated. Call `find` on a model, and then decorate the result", caller)
decorate_item(source.find(*args))
decorate_item(object.find(*args))
end
end
def to_s
"#<#{self.class.name} of #{decorator_class || "inferred decorators"} for #{source.inspect}>"
"#<#{self.class.name} of #{decorator_class || "inferred decorators"} for #{object.inspect}>"
end
def context=(value)
@ -80,7 +80,7 @@ module Draper
protected
# @return the collection being decorated.
attr_reader :source
attr_reader :object
# Decorates the given item.
def decorate_item(item)

View File

@ -73,7 +73,7 @@ module Draper
#
# @return [Boolean]
def ===(other)
super || (other.respond_to?(:source) && super(other.source))
super || (other.respond_to?(:object) && super(other.object))
end
end

View File

@ -19,7 +19,7 @@ module Draper
# @private
def self.test_for_decorator(object, other)
other.respond_to?(:decorated?) && other.decorated? &&
other.respond_to?(:source) && test(object, other.source)
other.respond_to?(:object) && test(object, other.object)
end
end
end

View File

@ -25,7 +25,7 @@ module Draper
attr_reader :factory, :owner, :association, :scope
def decorate
associated = owner.source.send(association)
associated = owner.object.send(association)
associated = associated.send(scope) if scope
@decorated = factory.decorate(associated, context_args: owner.context)

View File

@ -8,9 +8,10 @@ module Draper
include ActiveModel::Serializers::Xml
# @return the object being decorated.
attr_reader :source
alias_method :model, :source
alias_method :to_source, :source
attr_reader :object
alias_method :model, :object
alias_method :source, :object # TODO: deprecate this
alias_method :to_source, :object # TODO: deprecate this
# @return [Hash] extra data to be used in user-defined methods.
attr_accessor :context
@ -21,16 +22,16 @@ module Draper
# decorator to an instance of itself will create a decorator with the same
# source as the original, rather than redecorating the other instance.
#
# @param [Object] source
# @param [Object] object
# object to decorate.
# @option options [Hash] :context ({})
# extra data to be stored in the decorator and used in user-defined
# methods.
def initialize(source, options = {})
def initialize(object, options = {})
options.assert_valid_keys(:context)
@source = source
@object = object
@context = options.fetch(:context, {})
handle_multiple_decoration(options) if source.instance_of?(self.class)
handle_multiple_decoration(options) if object.instance_of?(self.class)
end
class << self
@ -126,22 +127,22 @@ module Draper
# maps to `ProductsDecorator`), but otherwise defaults to
# {Draper::CollectionDecorator}.
#
# @param [Object] source
# @param [Object] object
# collection to decorate.
# @option options [Class, nil] :with (self)
# the decorator class used to decorate each item. When `nil`, it is
# inferred from each item.
# @option options [Hash] :context
# extra data to be stored in the collection decorator.
def self.decorate_collection(source, options = {})
def self.decorate_collection(object, options = {})
options.assert_valid_keys(:with, :context)
collection_decorator_class.new(source, options.reverse_merge(with: self))
collection_decorator_class.new(object, options.reverse_merge(with: self))
end
# @return [Array<Class>] the list of decorators that have been applied to
# the object.
def applied_decorators
chain = source.respond_to?(:applied_decorators) ? source.applied_decorators : []
chain = object.respond_to?(:applied_decorators) ? object.applied_decorators : []
chain << self.class
end
@ -159,29 +160,29 @@ module Draper
true
end
# Compares the source with a possibly-decorated object.
# Compares the source object with a possibly-decorated object.
#
# @return [Boolean]
def ==(other)
Draper::Decoratable::Equality.test(source, other)
Draper::Decoratable::Equality.test(object, other)
end
# Checks if `self.kind_of?(klass)` or `source.kind_of?(klass)`
# Checks if `self.kind_of?(klass)` or `object.kind_of?(klass)`
#
# @param [Class] klass
def kind_of?(klass)
super || source.kind_of?(klass)
super || object.kind_of?(klass)
end
alias_method :is_a?, :kind_of?
# Checks if `self.instance_of?(klass)` or `source.instance_of?(klass)`
# Checks if `self.instance_of?(klass)` or `object.instance_of?(klass)`
#
# @param [Class] klass
def instance_of?(klass)
super || source.instance_of?(klass)
super || object.instance_of?(klass)
end
# In case source is nil
# In case object is nil
delegate :present?, :blank?
# ActiveModel compatibility
@ -190,10 +191,10 @@ module Draper
self
end
# @return [Hash] the source's attributes, sliced to only include those
# @return [Hash] the object's attributes, sliced to only include those
# implemented by the decorator.
def attributes
source.attributes.select {|attribute, _| respond_to?(attribute) }
object.attributes.select {|attribute, _| respond_to?(attribute) }
end
# ActiveModel compatibility
@ -233,9 +234,9 @@ module Draper
end
def handle_multiple_decoration(options)
if source.applied_decorators.last == self.class
@context = source.context unless options.has_key?(:context)
@source = source.source
if object.applied_decorators.last == self.class
@context = object.context unless options.has_key?(:context)
@object = object.object
else
warn "Reapplying #{self.class} decorator to target that is already decorated with it. Call stack:\n#{caller(1).join("\n")}"
end

View File

@ -2,12 +2,12 @@ module Draper
module Delegation
# @overload delegate(*methods, options = {})
# Overrides {http://api.rubyonrails.org/classes/Module.html#method-i-delegate Module.delegate}
# to make `:source` the default delegation target.
# to make `:object` the default delegation target.
#
# @return [void]
def delegate(*methods)
options = methods.extract_options!
super *methods, options.reverse_merge(to: :source)
super *methods, options.reverse_merge(to: :object)
end
end
end

View File

@ -18,7 +18,7 @@ module Draper
# Decorates an object, inferring whether to create a singular or collection
# decorator from the type of object passed.
#
# @param [Object] source
# @param [Object] object
# object to decorate.
# @option options [Hash] context
# extra data to be stored in the decorator. Overrides any context passed
@ -26,9 +26,9 @@ module Draper
# @option options [Object, Array] context_args (nil)
# argument(s) to be passed to the context proc.
# @return [Decorator, CollectionDecorator] the decorated object.
def decorate(source, options = {})
return nil if source.nil?
Worker.new(decorator_class, source).call(options.reverse_merge(default_options))
def decorate(object, options = {})
return nil if object.nil?
Worker.new(decorator_class, object).call(options.reverse_merge(default_options))
end
private
@ -37,32 +37,32 @@ module Draper
# @private
class Worker
def initialize(decorator_class, source)
def initialize(decorator_class, object)
@decorator_class = decorator_class
@source = source
@object = object
end
def call(options)
update_context options
decorator.call(source, options)
decorator.call(object, options)
end
def decorator
return decorator_method(decorator_class) if decorator_class
return source_decorator if decoratable?
return object_decorator if decoratable?
return decorator_method(Draper::CollectionDecorator) if collection?
raise Draper::UninferrableDecoratorError.new(source.class)
raise Draper::UninferrableDecoratorError.new(object.class)
end
private
attr_reader :decorator_class, :source
attr_reader :decorator_class, :object
def source_decorator
def object_decorator
if collection?
->(source, options) { source.decorator_class.decorate_collection(source, options.reverse_merge(with: nil))}
->(object, options) { object.decorator_class.decorate_collection(object, options.reverse_merge(with: nil))}
else
->(source, options) { source.decorate(options) }
->(object, options) { object.decorate(options) }
end
end
@ -75,11 +75,11 @@ module Draper
end
def collection?
source.respond_to?(:first)
object.respond_to?(:first)
end
def decoratable?
source.respond_to?(:decorate)
object.respond_to?(:decorate)
end
def update_context(options)

View File

@ -11,7 +11,7 @@ class <%= class_name %>
#
# def created_at
# helpers.content_tag :span, class: 'time' do
# source.created_at.strftime("%a %m/%d/%y")
# object.created_at.strftime("%a %m/%d/%y")
# end
# end

View File

@ -84,8 +84,8 @@ module Draper
collection = [Product.new, Product.new]
decorator = CollectionDecorator.new(collection)
decorator.zip collection do |item, source|
expect(item.source).to be source
decorator.zip collection do |item, object|
expect(item.object).to be object
end
end
@ -109,8 +109,8 @@ module Draper
describe ".delegate" do
protect_class ProductsDecorator
it "defaults the :to option to :source" do
Object.should_receive(:delegate).with(:foo, :bar, to: :source)
it "defaults the :to option to :object" do
Object.should_receive(:delegate).with(:foo, :bar, to: :object)
ProductsDecorator.delegate :foo, :bar
end
@ -131,12 +131,12 @@ module Draper
end
context "without a block" do
it "decorates source.find" do
source = []
it "decorates object.find" do
object = []
found = stub(decorate: :decorated)
decorator = CollectionDecorator.new(source)
decorator = CollectionDecorator.new(object)
source.should_receive(:find).and_return(found)
object.should_receive(:find).and_return(found)
ActiveSupport::Deprecation.silence do
expect(decorator.find(1)).to be :decorated
end
@ -162,17 +162,17 @@ module Draper
end
describe "#==" do
context "when comparing to a collection decorator with the same source" do
context "when comparing to a collection decorator with the same object" do
it "returns true" do
source = [Product.new, Product.new]
decorator = CollectionDecorator.new(source)
other = ProductsDecorator.new(source)
object = [Product.new, Product.new]
decorator = CollectionDecorator.new(object)
other = ProductsDecorator.new(object)
expect(decorator == other).to be_true
end
end
context "when comparing to a collection decorator with a different source" do
context "when comparing to a collection decorator with a different object" do
it "returns false" do
decorator = CollectionDecorator.new([Product.new, Product.new])
other = ProductsDecorator.new([Product.new, Product.new])
@ -183,9 +183,9 @@ module Draper
context "when comparing to a collection of the same items" do
it "returns true" do
source = [Product.new, Product.new]
decorator = CollectionDecorator.new(source)
other = source.dup
object = [Product.new, Product.new]
decorator = CollectionDecorator.new(object)
other = object.dup
expect(decorator == other).to be_true
end
@ -201,10 +201,10 @@ module Draper
end
context "when the decorated collection has been modified" do
it "is no longer equal to the source" do
source = [Product.new, Product.new]
decorator = CollectionDecorator.new(source)
other = source.dup
it "is no longer equal to the object" do
object = [Product.new, Product.new]
decorator = CollectionDecorator.new(object)
other = object.dup
decorator << Product.new.decorate
expect(decorator == other).to be_false

View File

@ -10,7 +10,7 @@ module Draper
decorator = product.decorate
expect(decorator).to be_a ProductDecorator
expect(decorator.source).to be product
expect(decorator.object).to be product
end
it "accepts context" do
@ -89,19 +89,19 @@ module Draper
end
it "is true for a decorated instance" do
decorator = double(source: Product.new)
decorator = double(object: Product.new)
expect(Product === decorator).to be_true
end
it "is true for a decorated derived instance" do
decorator = double(source: Class.new(Product).new)
decorator = double(object: Class.new(Product).new)
expect(Product === decorator).to be_true
end
it "is false for a decorated unrelated instance" do
decorator = double(source: Model.new)
decorator = double(object: Model.new)
expect(Product === decorator).to be_false
end

View File

@ -43,8 +43,8 @@ module Draper
Factory.stub new: factory
associated = double
owner_context = {foo: "bar"}
source = double(association: associated)
owner = double(source: source, context: owner_context)
object = double(association: associated)
owner = double(object: object, context: owner_context)
decorated_association = DecoratedAssociation.new(owner, :association, {})
decorated = double
@ -55,7 +55,7 @@ module Draper
it "memoizes" do
factory = double
Factory.stub new: factory
owner = double(source: double(association: double), context: {})
owner = double(object: double(association: double), context: {})
decorated_association = DecoratedAssociation.new(owner, :association, {})
decorated = double
@ -69,8 +69,8 @@ module Draper
factory = double
Factory.stub new: factory
scoped = double
source = double(association: double(applied_scope: scoped))
owner = double(source: source, context: {})
object = double(association: double(applied_scope: scoped))
owner = double(object: object, context: {})
decorated_association = DecoratedAssociation.new(owner, :association, scope: :applied_scope)
decorated = double

View File

@ -41,15 +41,15 @@ module Draper
describe "the generated method" do
it "decorates the instance variable" do
source = double
object = double
factory = double
Factory.stub new: factory
controller_class.decorates_assigned :article
controller = controller_class.new
controller.instance_variable_set "@article", source
controller.instance_variable_set "@article", object
factory.should_receive(:decorate).with(source, context_args: controller).and_return(:decorated)
factory.should_receive(:decorate).with(object, context_args: controller).and_return(:decorated)
expect(controller.article).to be :decorated
end

View File

@ -17,11 +17,11 @@ module Draper
end
end
it "sets the source" do
source = Model.new
decorator = Decorator.new(source)
it "sets the object" do
object = Model.new
decorator = Decorator.new(object)
expect(decorator.source).to be source
expect(decorator.object).to be object
end
it "stores context" do
@ -32,12 +32,12 @@ module Draper
end
context "when decorating an instance of itself" do
it "applies to the source instead" do
source = Model.new
decorated = Decorator.new(source)
it "applies to the object instead" do
object = Model.new
decorated = Decorator.new(object)
redecorated = Decorator.new(decorated)
expect(redecorated.source).to be source
expect(redecorated.object).to be object
end
context "with context" do
@ -65,7 +65,7 @@ module Draper
decorated = OtherDecorator.new(Model.new)
redecorated = Decorator.new(decorated)
expect(redecorated.source).to be decorated
expect(redecorated.object).to be decorated
end
context "when it has been applied previously" do
@ -85,7 +85,7 @@ module Draper
Object.any_instance.stub(:warn)
redecorated = Decorator.decorate(decorated)
expect(redecorated.source).to be decorated
expect(redecorated.object).to be decorated
end
end
end
@ -116,10 +116,10 @@ module Draper
context "without a custom collection decorator" do
it "creates a CollectionDecorator using itself for each item" do
source = [Model.new]
object = [Model.new]
CollectionDecorator.should_receive(:new).with(source, with: Decorator)
Decorator.decorate_collection(source)
CollectionDecorator.should_receive(:new).with(object, with: Decorator)
Decorator.decorate_collection(object)
end
it "passes options to the collection decorator" do
@ -132,10 +132,10 @@ module Draper
context "with a custom collection decorator" do
it "creates a custom collection decorator using itself for each item" do
source = [Model.new]
object = [Model.new]
ProductsDecorator.should_receive(:new).with(source, with: ProductDecorator)
ProductDecorator.decorate_collection(source)
ProductsDecorator.should_receive(:new).with(object, with: ProductDecorator)
ProductDecorator.decorate_collection(object)
end
it "passes options to the collection decorator" do
@ -319,14 +319,35 @@ module Draper
end
end
describe "#source" do
describe "#object" do
it "returns the wrapped object" do
source = Model.new
decorator = Decorator.new(source)
object = Model.new
decorator = Decorator.new(object)
expect(decorator.source).to be source
expect(decorator.model).to be source
expect(decorator.to_source).to be source
expect(decorator.object).to be object
expect(decorator.model).to be object
expect(decorator.to_source).to be object
end
it "is aliased to #model" do
object = Model.new
decorator = Decorator.new(object)
expect(decorator.model).to be object
end
it "is aliased to #source" do
object = Model.new
decorator = Decorator.new(object)
expect(decorator.source).to be object
end
it "is aliased to #to_source" do
object = Model.new
decorator = Decorator.new(object)
expect(decorator.to_source).to be object
end
end
@ -339,7 +360,7 @@ module Draper
end
describe "#to_param" do
it "delegates to the source" do
it "delegates to the object" do
decorator = Decorator.new(double(to_param: :delegated))
expect(decorator.to_param).to be :delegated
@ -347,7 +368,7 @@ module Draper
end
describe "#present?" do
it "delegates to the source" do
it "delegates to the object" do
decorator = Decorator.new(double(present?: :delegated))
expect(decorator.present?).to be :delegated
@ -355,7 +376,7 @@ module Draper
end
describe "#blank?" do
it "delegates to the source" do
it "delegates to the object" do
decorator = Decorator.new(double(blank?: :delegated))
expect(decorator.blank?).to be :delegated
@ -363,7 +384,7 @@ module Draper
end
describe "#to_partial_path" do
it "delegates to the source" do
it "delegates to the object" do
decorator = Decorator.new(double(to_partial_path: :delegated))
expect(decorator.to_partial_path).to be :delegated
@ -371,7 +392,7 @@ module Draper
end
describe "#attributes" do
it "returns only the source's attributes that are implemented by the decorator" do
it "returns only the object's attributes that are implemented by the decorator" do
decorator = Decorator.new(double(attributes: {foo: "bar", baz: "qux"}))
decorator.stub(:foo)
@ -388,35 +409,35 @@ module Draper
end
describe "#==" do
it "works for a source that does not include Decoratable" do
source = Object.new
decorator = Decorator.new(source)
it "works for a object that does not include Decoratable" do
object = Object.new
decorator = Decorator.new(object)
expect(decorator).to eq Decorator.new(source)
expect(decorator).to eq Decorator.new(object)
end
it "works for a multiply-decorated source that does not include Decoratable" do
source = Object.new
decorator = Decorator.new(source)
it "works for a multiply-decorated object that does not include Decoratable" do
object = Object.new
decorator = Decorator.new(object)
expect(decorator).to eq ProductDecorator.new(Decorator.new(source))
expect(decorator).to eq ProductDecorator.new(Decorator.new(object))
end
it "is true when source #== is true" do
source = Model.new
decorator = Decorator.new(source)
other = double(source: Model.new)
it "is true when object #== is true" do
object = Model.new
decorator = Decorator.new(object)
other = double(object: Model.new)
source.should_receive(:==).with(other).and_return(true)
object.should_receive(:==).with(other).and_return(true)
expect(decorator == other).to be_true
end
it "is false when source #== is false" do
source = Model.new
decorator = Decorator.new(source)
other = double(source: Model.new)
it "is false when object #== is false" do
object = Model.new
decorator = Decorator.new(object)
other = double(object: Model.new)
source.should_receive(:==).with(other).and_return(false)
object.should_receive(:==).with(other).and_return(false)
expect(decorator == other).to be_false
end
@ -441,8 +462,8 @@ module Draper
describe ".delegate" do
protect_class Decorator
it "defaults the :to option to :source" do
Object.should_receive(:delegate).with(:foo, :bar, to: :source)
it "defaults the :to option to :object" do
Object.should_receive(:delegate).with(:foo, :bar, to: :object)
Decorator.delegate :foo, :bar
end
@ -458,7 +479,7 @@ module Draper
before { Decorator.delegate_all }
describe "#method_missing" do
it "delegates missing methods that exist on the source" do
it "delegates missing methods that exist on the object" do
decorator = Decorator.new(double(hello_world: :delegated))
expect(decorator.hello_world).to be :delegated
@ -473,9 +494,9 @@ module Draper
end
it "passes blocks to delegated methods" do
source = Model.new
source.stub(:hello_world).and_return{|*args, &block| block.call}
decorator = Decorator.new(source)
object = Model.new
object.stub(:hello_world).and_return{|*args, &block| block.call}
decorator = Decorator.new(object)
expect(decorator.hello_world{:yielded}).to be :yielded
end
@ -487,21 +508,21 @@ module Draper
end
it "delegates already-delegated methods" do
source = Class.new{ delegate :bar, to: :foo }.new
source.stub foo: double(bar: :delegated)
decorator = Decorator.new(source)
object = Class.new{ delegate :bar, to: :foo }.new
object.stub foo: double(bar: :delegated)
decorator = Decorator.new(object)
expect(decorator.bar).to be :delegated
end
it "does not delegate private methods" do
source = Class.new{ private; def hello_world; end }.new
decorator = Decorator.new(source)
object = Class.new{ private; def hello_world; end }.new
decorator = Decorator.new(object)
expect{decorator.hello_world}.to raise_error NoMethodError
end
it "does not delegate methods that do not exist on the source" do
it "does not delegate methods that do not exist on the object" do
decorator = Decorator.new(Model.new)
expect(decorator.methods).not_to include :hello_world
@ -542,7 +563,7 @@ module Draper
expect(decorator).to respond_to :hello_world
end
it "returns true for the source's methods" do
it "returns true for the object's methods" do
decorator = Decorator.new(double(hello_world: :delegated))
expect(decorator).to respond_to :hello_world
@ -556,9 +577,9 @@ module Draper
expect(decorator.respond_to?(:hello_world, true)).to be_true
end
it "returns false for the source's private methods" do
source = Class.new{private; def hello_world; end}.new
decorator = Decorator.new(source)
it "returns false for the object's private methods" do
object = Class.new{private; def hello_world; end}.new
decorator = Decorator.new(object)
expect(decorator.respond_to?(:hello_world, true)).to be_false
end
@ -596,8 +617,8 @@ module Draper
describe "#respond_to_missing?" do
it "allows #method to be called on delegated methods" do
source = Class.new{def hello_world; end}.new
decorator = Decorator.new(source)
object = Class.new{def hello_world; end}.new
decorator = Decorator.new(object)
expect { decorator.method(:hello_world) }.not_to raise_error NameError
expect(decorator.method(:hello_world)).not_to be_nil

View File

@ -15,7 +15,7 @@ module Draper
end
describe "#decorate" do
context "when source is nil" do
context "when object is nil" do
it "returns nil" do
factory = Factory.new
@ -31,12 +31,12 @@ module Draper
expect(factory.decorate(double)).to be :decorated
end
it "passes the source to the worker" do
it "passes the object to the worker" do
factory = Factory.new
source = double
object = double
Factory::Worker.should_receive(:new).with(anything(), source).and_return(->(*){})
factory.decorate(source)
Factory::Worker.should_receive(:new).with(anything(), object).and_return(->(*){})
factory.decorate(object)
end
context "when the :with option was given" do
@ -95,13 +95,13 @@ module Draper
describe "#call" do
it "calls the decorator method" do
source = double
object = double
options = {foo: "bar"}
worker = Factory::Worker.new(double, source)
worker = Factory::Worker.new(double, object)
decorator = ->(*){}
worker.stub decorator: decorator
decorator.should_receive(:call).with(source, options).and_return(:decorated)
decorator.should_receive(:call).with(object, options).and_return(:decorated)
expect(worker.call(options)).to be :decorated
end
@ -159,7 +159,7 @@ module Draper
end
describe "#decorator" do
context "for a singular source" do
context "for a singular object" do
context "when decorator_class is specified" do
it "returns the .decorate method from the decorator" do
decorator_class = Class.new(Decorator)
@ -170,21 +170,21 @@ module Draper
end
context "when decorator_class is unspecified" do
context "and the source is decoratable" do
it "returns the source's #decorate method" do
source = double
context "and the object is decoratable" do
it "returns the object's #decorate method" do
object = double
options = {foo: "bar"}
worker = Factory::Worker.new(nil, source)
worker = Factory::Worker.new(nil, object)
source.should_receive(:decorate).with(options).and_return(:decorated)
expect(worker.decorator.call(source, options)).to be :decorated
object.should_receive(:decorate).with(options).and_return(:decorated)
expect(worker.decorator.call(object, options)).to be :decorated
end
end
context "and the source is not decoratable" do
context "and the object is not decoratable" do
it "raises an error" do
source = double
worker = Factory::Worker.new(nil, source)
object = double
worker = Factory::Worker.new(nil, object)
expect{worker.decorator}.to raise_error UninferrableDecoratorError
end
@ -192,7 +192,7 @@ module Draper
end
end
context "for a collection source" do
context "for a collection object" do
context "when decorator_class is a CollectionDecorator" do
it "returns the .decorate method from the collection decorator" do
decorator_class = Class.new(CollectionDecorator)
@ -212,20 +212,20 @@ module Draper
end
context "when decorator_class is unspecified" do
context "and the source is decoratable" do
it "returns the .decorate_collection method from the source's decorator" do
source = []
context "and the object is decoratable" do
it "returns the .decorate_collection method from the object's decorator" do
object = []
decorator_class = Class.new(Decorator)
source.stub decorator_class: decorator_class
source.stub decorate: nil
worker = Factory::Worker.new(nil, source)
object.stub decorator_class: decorator_class
object.stub decorate: nil
worker = Factory::Worker.new(nil, object)
decorator_class.should_receive(:decorate_collection).with(source, foo: "bar", with: nil).and_return(:decorated)
expect(worker.decorator.call(source, foo: "bar")).to be :decorated
decorator_class.should_receive(:decorate_collection).with(object, foo: "bar", with: nil).and_return(:decorated)
expect(worker.decorator.call(object, foo: "bar")).to be :decorated
end
end
context "and the source is not decoratable" do
context "and the object is not decoratable" do
it "returns the .decorate method from CollectionDecorator" do
worker = Factory::Worker.new(nil, [])

View File

@ -16,7 +16,7 @@ module Draper
Product.stub(:find).and_return(found)
decorator = ProductDecorator.find(1)
expect(decorator).to be_a ProductDecorator
expect(decorator.source).to be found
expect(decorator.object).to be found
end
it "passes context to the decorator" do
@ -39,7 +39,7 @@ module Draper
Product.stub(:find_by_name).and_return(found)
decorator = ProductDecorator.find_by_name("apples")
expect(decorator).to be_a ProductDecorator
expect(decorator.source).to be found
expect(decorator.object).to be found
end
it "proxies complex ProductDecorators" do
@ -127,7 +127,7 @@ module Draper
Product.stub(:first).and_return(first)
decorator = ProductDecorator.first
expect(decorator).to be_a ProductDecorator
expect(decorator.source).to be first
expect(decorator.object).to be first
end
it "passes context to the decorator" do
@ -150,7 +150,7 @@ module Draper
Product.stub(:last).and_return(last)
decorator = ProductDecorator.last
expect(decorator).to be_a ProductDecorator
expect(decorator.source).to be last
expect(decorator.object).to be last
end
it "passes context to the decorator" do

View File

@ -15,7 +15,7 @@ class PostDecorator < Draper::Decorator
end
def path_with_model
h.post_path(source)
h.post_path(object)
end
def path_with_id
@ -23,7 +23,7 @@ class PostDecorator < Draper::Decorator
end
def url_with_model
h.post_url(source)
h.post_url(object)
end
def url_with_id

View File

@ -9,8 +9,8 @@ Draper::ViewContext.test_strategy :fast
Post = Struct.new(:id) { extend ActiveModel::Naming }
describe PostDecorator do
let(:decorator) { PostDecorator.new(source) }
let(:source) { Post.new(42) }
let(:decorator) { PostDecorator.new(object) }
let(:object) { Post.new(42) }
it "can use built-in helpers" do
expect(decorator.truncated).to eq "Once upon a..."

View File

@ -1,8 +1,8 @@
require 'spec_helper'
describe PostDecorator do
let(:decorator) { PostDecorator.new(source) }
let(:source) { Post.create }
let(:decorator) { PostDecorator.new(object) }
let(:object) { Post.create }
it "can use built-in helpers" do
expect(decorator.truncated).to eq "Once upon a..."
@ -17,23 +17,23 @@ describe PostDecorator do
end
it "can use path helpers with its model" do
expect(decorator.path_with_model).to eq "/en/posts/#{source.id}"
expect(decorator.path_with_model).to eq "/en/posts/#{object.id}"
end
it "can use path helpers with its id" do
expect(decorator.path_with_id).to eq "/en/posts/#{source.id}"
expect(decorator.path_with_id).to eq "/en/posts/#{object.id}"
end
it "can use url helpers with its model" do
expect(decorator.url_with_model).to eq "http://www.example.com:12345/en/posts/#{source.id}"
expect(decorator.url_with_model).to eq "http://www.example.com:12345/en/posts/#{object.id}"
end
it "can use url helpers with its id" do
expect(decorator.url_with_id).to eq "http://www.example.com:12345/en/posts/#{source.id}"
expect(decorator.url_with_id).to eq "http://www.example.com:12345/en/posts/#{object.id}"
end
it "can be passed implicitly to url_for" do
expect(decorator.link).to eq "<a href=\"/en/posts/#{source.id}\">#{source.id}</a>"
expect(decorator.link).to eq "<a href=\"/en/posts/#{object.id}\">#{object.id}</a>"
end
it "serializes overriden attributes" do

View File

@ -8,32 +8,32 @@ shared_examples_for "decoration-aware #==" do |subject|
end
it "is true for a decorated version of itself" do
decorated = double(source: subject, decorated?: true)
decorated = double(object: subject, decorated?: true)
expect(subject == decorated).to be_true
end
it "is false for a decorated other object" do
decorated = double(source: Object.new, decorated?: true)
decorated = double(object: Object.new, decorated?: true)
expect(subject == decorated).to be_false
end
it "is false for a decoratable object with a `source` association" do
decoratable = double(source: subject, decorated?: false)
it "is false for a decoratable object with a `object` association" do
decoratable = double(object: subject, decorated?: false)
expect(subject == decoratable).to be_false
end
it "is false for an undecoratable object with a `source` association" do
undecoratable = double(source: subject)
it "is false for an undecoratable object with a `object` association" do
undecoratable = double(object: subject)
expect(subject == undecoratable).to be_false
end
it "is true for a multiply-decorated version of itself" do
decorated = double(source: subject, decorated?: true)
redecorated = double(source: decorated, decorated?: true)
decorated = double(object: subject, decorated?: true)
redecorated = double(object: decorated, decorated?: true)
expect(subject == redecorated).to be_true
end