Use dkubb/equalizer and remove vendored version

This commit is contained in:
Markus Schirp 2012-09-15 23:04:10 +02:00
parent 3de69d832d
commit 933364b800
9 changed files with 7 additions and 400 deletions

View file

@ -5,6 +5,7 @@ gemspec
gem 'immutable', :git => 'https://github.com/dkubb/immutable.git', :branch => :experimental
gem 'descendants_tracker', :git => 'https://github.com/dkubb/descendants_tracker.git'
gem 'abstract_class', :git => 'https://github.com/dkubb/abstract_class.git'
gem 'equalizer', :git => 'https://github.com/dkubb/equalizer.git'
gem 'to_source', :git => 'https://github.com/mbj/to_source.git'
group :development do

View file

@ -3,20 +3,19 @@ require 'ice_nine'
require 'abstract_class'
require 'descendants_tracker'
require 'securerandom'
require 'equalizer'
require 'to_source'
require 'ice_nine'
require 'ice_nine/core_ext/object'
require 'backports'
require 'diff/lcs'
require 'diff/lcs/hunk'
require 'pp'
# Library namespace
module Mutant
end
require 'mutant/support/method_object'
require 'mutant/support/equalizer'
require 'mutant/helper'
require 'mutant/random'
require 'mutant/mutator'

View file

@ -1,125 +0,0 @@
# encoding: utf-8
module Mutant
# Define equality, equivalence and inspection methods
class Equalizer < Module
# Initialize an Equalizer with the given keys
#
# Will use the keys with which it is initialized to define #cmp?,
# #hash, and #inspect
#
# @param [Array<Symbol>] *keys
#
# @return [undefined]
#
# @api private
def initialize(*keys)
@keys = Immutable.freeze_object(keys)
define_methods
include_comparison_methods
end
private
# Define the equalizer methods based on #keys
#
# @return [undefined]
#
# @api private
def define_methods
define_cmp_method
define_hash_method
define_inspect_method
end
# Define an #cmp? method based on the instance's values identified by #keys
#
# @return [undefined]
#
# @api private
def define_cmp_method
keys = @keys
define_method(:cmp?) do |comparator, other|
keys.all? { |key| send(key).send(comparator, other.send(key)) }
end
private :cmp?
end
# Define a #hash method based on the instance's values identified by #keys
#
# @return [undefined]
#
# @api private
def define_hash_method
keys = @keys
define_method(:hash) do
keys.map { |key| send(key).hash }.reduce(self.class.hash, :^)
end
end
# Define an inspect method that reports the values of the instance's keys
#
# @return [undefined]
#
# @api private
def define_inspect_method
keys = @keys
define_method(:inspect) do
klass = self.class
name = klass.name || klass.inspect
"#<#{name}#{keys.map { |key| " #{key}=#{send(key).inspect}" }.join}>"
end
end
# Include the #eql? and #== methods
#
# @return [undefined]
#
# @api private
def include_comparison_methods
module_eval do
include Methods, Immutable
memoize :hash
end
end
# The comparison methods
module Methods
# Compare the object with other object for equality
#
# @example
# object.eql?(other) # => true or false
#
# @param [Object] other
# the other object to compare with
#
# @return [Boolean]
#
# @api public
def eql?(other)
instance_of?(other.class) and cmp?(__method__, other)
end
# Compare the object with other object for equivalency
#
# @example
# object == other # => true or false
#
# @param [Object] other
# the other object to compare with
#
# @return [Boolean]
#
# @api public
def ==(other)
other = coerce(other) if respond_to?(:coerce, true)
return false unless self.class <=> other.class
cmp?(__method__, other)
end
end # module Methods
end # class Equalizer
end # module Mutant

View file

@ -21,6 +21,7 @@ Gem::Specification.new do |gem|
gem.add_runtime_dependency('descendants_tracker', '~> 0.0.1')
gem.add_runtime_dependency('backports', '~> 2.6')
gem.add_runtime_dependency('immutable', '~> 0.0.1')
gem.add_runtime_dependency('equalizer', '~> 0.0.1')
gem.add_runtime_dependency('abstract_class', '~> 0.0.1')
gem.add_runtime_dependency('diff-lcs', '~> 1.1.3')
end

View file

@ -1,6 +1,10 @@
require 'spec_helper'
describe Mutant, 'runner' do
before do
pending
end
around do |example|
Dir.chdir(TestApp.root) do
example.run

View file

@ -1,138 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Equalizer, '.new' do
let(:object) { described_class }
let(:name) { 'User' }
let(:klass) { ::Class.new }
context 'with no keys' do
subject { object.new }
before do
# specify the class #name method
klass.stub(:name).and_return(name)
klass.send(:include, subject)
end
let(:instance) { klass.new }
it { should be_instance_of(object) }
it 'defines #hash and #inspect methods dynamically' do
subject.public_instance_methods(false).map(&:to_s).should =~ %w[ hash inspect ]
end
describe '#eql?' do
context 'when the objects are similar' do
let(:other) { instance.dup }
it { instance.eql?(other).should be(true) }
end
context 'when the objects are different' do
let(:other) { stub('other') }
it { instance.eql?(other).should be(false) }
end
end
describe '#==' do
context 'when the objects are similar' do
let(:other) { instance.dup }
it { (instance == other).should be(true) }
end
context 'when the objects are different' do
let(:other) { stub('other') }
it { (instance == other).should be(false) }
end
end
describe '#hash' do
it { instance.hash.should eql(klass.hash) }
it 'memoizes the hash code' do
instance.hash.should eql(instance.memoized(:hash))
end
end
describe '#inspect' do
it { instance.inspect.should eql('#<User>') }
end
end
context 'with keys' do
subject { object.new(*keys) }
let(:keys) { [ :first_name ].freeze }
let(:first_name) { 'John' }
let(:instance) { klass.new(first_name) }
let(:klass) do
::Class.new do
attr_reader :first_name
def initialize(first_name)
@first_name = first_name
end
end
end
before do
# specify the class #inspect method
klass.stub(:name).and_return(nil)
klass.stub(:inspect).and_return(name)
klass.send(:include, subject)
end
it { should be_instance_of(object) }
it 'defines #hash and #inspect methods dynamically' do
subject.public_instance_methods(false).map(&:to_s).should =~ %w[ hash inspect ]
end
describe '#eql?' do
context 'when the objects are similar' do
let(:other) { instance.dup }
it { instance.eql?(other).should be(true) }
end
context 'when the objects are different' do
let(:other) { stub('other') }
it { instance.eql?(other).should be(false) }
end
end
describe '#==' do
context 'when the objects are similar' do
let(:other) { instance.dup }
it { (instance == other).should be(true) }
end
context 'when the objects are different' do
let(:other) { stub('other') }
it { (instance == other).should be(false) }
end
end
describe '#hash' do
it { instance.hash.should eql(klass.hash ^ first_name.hash) }
it 'memoizes the hash code' do
instance.hash.should eql(instance.memoized(:hash))
end
end
describe '#inspect' do
it { instance.inspect.should eql('#<User first_name="John">') }
end
end
end

View file

@ -1,49 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Equalizer::Methods, '#eql?' do
subject { object.eql?(other) }
let(:object) { described_class.new }
let(:described_class) do
Class.new do
include Mutant::Equalizer::Methods
def cmp?(comparator, other)
!!(comparator and other)
end
end
end
context 'with the same object' do
let(:other) { object }
it { should be(true) }
it 'is symmetric' do
should eql(other.eql?(object))
end
end
context 'with an equivalent object' do
let(:other) { object.dup }
it { should be(true) }
it 'is symmetric' do
should eql(other.eql?(object))
end
end
context 'with an equivalent object of a subclass' do
let(:other) { Class.new(described_class).new }
it { should be(false) }
it 'is symmetric' do
should eql(other.eql?(object))
end
end
end

View file

@ -1,85 +0,0 @@
# encoding: utf-8
require 'spec_helper'
describe Mutant::Equalizer::Methods, '#==' do
subject { object == other }
let(:object) { described_class.new(true) }
let(:described_class) do
Class.new do
include Mutant::Equalizer::Methods
attr_reader :boolean
def initialize(boolean)
@boolean = boolean
end
def cmp?(comparator, other)
boolean.send(comparator, other.boolean)
end
end
end
context 'with the same object' do
let(:other) { object }
it { should be(true) }
it 'is symmetric' do
should eql(other == object)
end
end
context 'with an equivalent object' do
let(:other) { object.dup }
it { should be(true) }
it 'is symmetric' do
should eql(other == object)
end
end
context 'with an equivalent object of a subclass' do
let(:other) { Class.new(described_class).new(true) }
it { should be(true) }
it 'is symmetric' do
should eql(other == object)
end
end
context 'with an object of another class' do
let(:other) { Class.new.new }
it { should be(false) }
it 'is symmetric' do
should eql(other == object)
end
end
context 'with an equivalent object after coercion' do
let(:other) { Object.new }
before do
# declare a private #coerce method
described_class.class_eval do
def coerce(other)
self.class.new(!!other)
end
private :coerce
end
end
it { should be(true) }
it 'is not symmetric' do
should_not eql(other == object)
end
end
end

View file

@ -25,7 +25,6 @@ describe Mutant::Matcher::ObjectSpace, '#each' do
it_should_behave_like 'an #each method'
it 'should yield subjects' do
expect { subject }.to change { yields }.from([]).to([subject_a, subject_b])
end