Skip to content

Instantly share code, notes, and snippets.

@jsuchal
Created December 10, 2012 19:02
Show Gist options
  • Save jsuchal/4252597 to your computer and use it in GitHub Desktop.
Save jsuchal/4252597 to your computer and use it in GitHub Desktop.
class Object
def self.include_with_args(base, *args)
base.included_with_args(self, *args) if base.respond_to?(:included_with_args)
include(base)
end
end
describe 'mixins with args' do
it 'calls hook method with args' do
module AMixin end
class AClassUsingMixinWithArgs; end # make class available
AMixin.should_receive(:included_with_args).with(AClassUsingMixinWithArgs, 1, 2, 3)
class AClassUsingMixinWithArgs
include_with_args AMixin, 1, 2, 3
end
end
it 'adds methods from mixin' do
module MixinWithMethods
def a_method
end
end
class AClassWithMixedInBehavior
include_with_args MixinWithMethods
end
AClassWithMixedInBehavior.new.should respond_to(:a_method)
end
end
require 'core_ext/mixin_with_args'
module DDD
module ValueObject
def self.included_with_args(base, *equality_attributes)
# convert to strings now to prevent excessive casting on equality comparison
names_as_strings = equality_attributes.collect { |n| "@#{n}" }
base.instance_variable_set(:@equality_attributes, names_as_strings)
end
def ==(other)
return false unless other.is_a?(self.class)
self.class.instance_variable_get(:@equality_attributes).each do |attribute|
return false if instance_variable_get(attribute) != other.instance_variable_get(attribute)
end
true
end
end
end
describe DDD::ValueObject do
it 'adds equality method generated from attributes' do
class ExampleRange
include_with_args DDD::ValueObject, :from, :to
def initialize(from, to)
@from, @to = from, to
end
end
ExampleRange.new(1, 2).should eq(ExampleRange.new(1, 2))
ExampleRange.new(1, 2).should_not eq(ExampleRange.new(1, 3))
ExampleRange.new(1, 2).should_not eq(ExampleRange.new(3, 1))
ExampleRange.new(1, 2).should_not eq(1)
end
end
# not directly comparable since this is slower.
# just to show the pure ruby implementation of DDD::ValueObject using a "abstract" method equality_attribute enforcement.
module DDD
module ValueObject
def ==(other)
return false unless other.is_a?(self.class)
equality_attributes.each do |attribute|
return false if instance_variable_get("@#{attribute}") != other.instance_variable_get("@#{attribute}")
end
true
end
def equality_attributes
raise NotImplementedError, "#{self.class} must implement #equality_attributes"
end
end
end
describe DDD::ValueObject do
it 'adds equality method generated from attributes' do
class ExampleRange
include DDD::ValueObject
def initialize(from, to)
@from, @to = from, to
end
def equality_attributes
[:from, :to]
end
end
ExampleRange.new(1, 2).should eq(ExampleRange.new(1, 2))
ExampleRange.new(1, 2).should_not eq(ExampleRange.new(1, 3))
ExampleRange.new(1, 2).should_not eq(ExampleRange.new(3, 1))
ExampleRange.new(1, 2).should_not eq(1)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment