equalizer-0.0.10/0000755000175000017500000000000012614500242013447 5ustar praveenpraveenequalizer-0.0.10/CONTRIBUTING.md0000644000175000017500000000202412614500242015676 0ustar praveenpraveenContributing ------------ * If you want your code merged into the mainline, please discuss the proposed changes with me before doing any work on it. This library is still in early development, and the direction it is going may not always be clear. Some features may not be appropriate yet, may need to be deferred until later when the foundation for them is laid, or may be more applicable in a plugin. * Fork the project. * Make your feature addition or bug fix. * Follow this [style guide](https://github.com/dkubb/styleguide). * Add specs for it. This is important so I don't break it in a future version unintentionally. Tests must cover all branches within the code, and code must be fully covered. * Commit, do not mess with Rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull) * Run "rake ci". This must pass and not show any regressions in the metrics for the code to be merged. * Send me a pull request. Bonus points for topic branches. equalizer-0.0.10/.ruby-gemset0000644000175000017500000000001212614500242015704 0ustar praveenpraveenequalizer equalizer-0.0.10/spec/0000755000175000017500000000000012614500242014401 5ustar praveenpraveenequalizer-0.0.10/spec/support/0000755000175000017500000000000012614500242016115 5ustar praveenpraveenequalizer-0.0.10/spec/support/config_alias.rb0000644000175000017500000000012512614500242021056 0ustar praveenpraveen# encoding: utf-8 require 'rbconfig' ::Config = RbConfig unless defined?(::Config) equalizer-0.0.10/spec/unit/0000755000175000017500000000000012614500242015360 5ustar praveenpraveenequalizer-0.0.10/spec/unit/equalizer/0000755000175000017500000000000012614500242017361 5ustar praveenpraveenequalizer-0.0.10/spec/unit/equalizer/universal_spec.rb0000644000175000017500000000752312614500242022737 0ustar praveenpraveen# encoding: utf-8 require 'spec_helper' describe 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 { should be_frozen } it 'defines #hash and #inspect methods dynamically' do expect(subject.public_instance_methods(false).collect(&:to_s).sort). to eql(%w(hash inspect)) end describe '#eql?' do context 'when the objects are similar' do let(:other) { instance.dup } it { expect(instance.eql?(other)).to be(true) } end context 'when the objects are different' do let(:other) { double('other') } it { expect(instance.eql?(other)).to be(false) } end end describe '#==' do context 'when the objects are similar' do let(:other) { instance.dup } it { expect(instance == other).to be(true) } end context 'when the objects are different' do let(:other) { double('other') } it { expect(instance == other).to be(false) } end end describe '#hash' do it 'has the expected arity' do expect(klass.instance_method(:hash).arity).to be(0) end it { expect(instance.hash).to eql([klass].hash) } end describe '#inspect' do it 'has the expected arity' do expect(klass.instance_method(:inspect).arity).to be(0) end it { expect(instance.inspect).to eql('#') } end end context 'with keys' do subject { object.new(*keys) } let(:keys) { [:firstname, :lastname].freeze } let(:firstname) { 'John' } let(:lastname) { 'Doe' } let(:instance) { klass.new(firstname, lastname) } let(:klass) do ::Class.new do attr_reader :firstname, :lastname private :firstname, :lastname def initialize(firstname, lastname) @firstname, @lastname = firstname, lastname 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 { should be_frozen } it 'defines #hash and #inspect methods dynamically' do expect(subject.public_instance_methods(false).collect(&:to_s).sort). to eql(%w(hash inspect)) end describe '#eql?' do context 'when the objects are similar' do let(:other) { instance.dup } it { expect(instance.eql?(other)).to be(true) } end context 'when the objects are different' do let(:other) { double('other') } it { expect(instance.eql?(other)).to be(false) } end end describe '#==' do context 'when the objects are similar' do let(:other) { instance.dup } it { expect(instance == other).to be(true) } end context 'when the objects are different type' do let(:other) { klass.new('Foo', 'Bar') } it { expect(instance == other).to be(false) } end context 'when the objects are from different type' do let(:other) { double('other') } it { expect(instance == other).to be(false) } end end describe '#hash' do it 'returns the expected hash' do expect(instance.hash). to eql([firstname, lastname, klass].hash) end end describe '#inspect' do it 'returns the expected string' do expect(instance.inspect). to eql('#') end end end end equalizer-0.0.10/spec/unit/equalizer/included_spec.rb0000644000175000017500000000310212614500242022503 0ustar praveenpraveen# encoding: utf-8 require 'spec_helper' describe Equalizer, '#included' do subject { descendant.instance_exec(object) { |mod| include mod } } let(:object) { described_class.new } let(:descendant) { Class.new } let(:superclass) { described_class.superclass } before do # Prevent Module.included from being called through inheritance described_class::Methods.stub(:included) end around do |example| # Restore included method after each example superclass.class_eval do alias_method :original_included, :included example.call undef_method :included alias_method :included, :original_included end end it 'delegates to the superclass #included method' do # This is the most succinct approach I could think of to test whether the # superclass#included method is called. All of the built-in rspec helpers # did not seem to work for this. included = false superclass.class_eval do define_method(:included) do |_| # Only set the flag when an Equalizer instance is included. # Otherwise, other module includes (which get triggered internally # in RSpec when `change` is used for the first time, since it uses # autoloading for its matchers) will wrongly set this flag. included = true if self.is_a?(Equalizer) end end expect { subject }.to change { included }.from(false).to(true) end it 'includes methods into the descendant' do subject expect(descendant.included_modules).to include(described_class::Methods) end end equalizer-0.0.10/spec/unit/equalizer/methods/0000755000175000017500000000000012614500242021024 5ustar praveenpraveenequalizer-0.0.10/spec/unit/equalizer/methods/eql_predicate_spec.rb0000644000175000017500000000226512614500242025171 0ustar praveenpraveen# encoding: utf-8 require 'spec_helper' describe Equalizer::Methods, '#eql?' do subject { object.eql?(other) } let(:object) { described_class.new(true) } let(:described_class) do Class.new do include 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.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(true) } it { should be(false) } it 'is symmetric' do should eql(other.eql?(object)) end end context 'with a different object' do let(:other) { described_class.new(false) } it { should be(false) } it 'is symmetric' do should eql(other.eql?(object)) end end end equalizer-0.0.10/spec/unit/equalizer/methods/equality_operator_spec.rb0000644000175000017500000000427012614500242026136 0ustar praveenpraveen# encoding: utf-8 require 'spec_helper' describe Equalizer::Methods, '#==' do subject { object == other } let(:object) { described_class.new(true) } let(:described_class) { Class.new(super_class) } let(:super_class) do Class.new do include 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 a subclass instance having equivalent obervable state' do let(:other) { Class.new(described_class).new(true) } it { should be(true) } it 'is not symmetric' do # the subclass instance should maintain substitutability with the object # (in the LSP sense) the reverse is not true. should_not eql(other == object) end end context 'with a superclass instance having equivalent observable state' do let(:other) { super_class.new(true) } it { should be(false) } it 'is not symmetric' do should_not 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), self] end private :coerce end end it { should be(true) } it 'is not symmetric' do should_not eql(other == object) end end context 'with a different object' do let(:other) { described_class.new(false) } it { should be(false) } it 'is symmetric' do should eql(other == object) end end end equalizer-0.0.10/spec/spec_helper.rb0000644000175000017500000000074512614500242017225 0ustar praveenpraveen# encoding: utf-8 if ENV['COVERAGE'] == 'true' require 'simplecov' require 'coveralls' SimpleCov.formatters = [SimpleCov::Formatter::HTMLFormatter, Coveralls::SimpleCov::Formatter] SimpleCov.start do command_name 'spec:unit' add_filter 'config' add_filter 'spec' add_filter 'vendor' minimum_coverage 100 end end require 'equalizer' RSpec.configure do |config| config.expect_with :rspec do |expect_with| expect_with.syntax = :expect end end equalizer-0.0.10/lib/0000755000175000017500000000000012614500242014215 5ustar praveenpraveenequalizer-0.0.10/lib/equalizer.rb0000644000175000017500000000513612614500242016550 0ustar praveenpraveen# encoding: utf-8 # 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] keys # # @return [undefined] # # @api private def initialize(*keys) @keys = keys define_methods freeze end private # Hook called when module is included # # @param [Module] descendant # the module or class including Equalizer # # @return [self] # # @api private def included(descendant) super descendant.module_eval { include Methods } end # 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.collect(&method(:send)).push(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.collect { |key| " #{key}=#{send(key).inspect}" }.join}>" 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) && 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).first if respond_to?(:coerce, true) other.is_a?(self.class) && cmp?(__method__, other) end end # module Methods end # class Equalizer equalizer-0.0.10/lib/equalizer/0000755000175000017500000000000012614500242016216 5ustar praveenpraveenequalizer-0.0.10/lib/equalizer/version.rb0000644000175000017500000000015612614500242020232 0ustar praveenpraveen# encoding: utf-8 class Equalizer < Module # Gem version VERSION = '0.0.10'.freeze end # class Equalizer equalizer-0.0.10/metadata.yml0000644000175000017500000000402412614500242015752 0ustar praveenpraveen--- !ruby/object:Gem::Specification name: equalizer version: !ruby/object:Gem::Version version: 0.0.10 platform: ruby authors: - Dan Kubb - Markus Schirp autorequire: bindir: bin cert_chain: [] date: 2015-03-20 00:00:00 Z dependencies: - !ruby/object:Gem::Dependency type: :development version_requirements: &id001 !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: "1.3" - - ">=" - !ruby/object:Gem::Version version: 1.3.5 requirement: *id001 prerelease: false name: bundler description: Module to define equality, equivalence and inspection methods email: - dan.kubb@gmail.com - mbj@schirp-dso.com executables: [] extensions: [] extra_rdoc_files: - LICENSE - README.md - CONTRIBUTING.md files: - .gitignore - .rspec - .rubocop.yml - .ruby-gemset - .travis.yml - .yardstick.yml - CONTRIBUTING.md - Gemfile - LICENSE - README.md - Rakefile - config/rubocop.yml - equalizer.gemspec - lib/equalizer.rb - lib/equalizer/version.rb - spec/spec_helper.rb - spec/support/config_alias.rb - spec/unit/equalizer/included_spec.rb - spec/unit/equalizer/methods/eql_predicate_spec.rb - spec/unit/equalizer/methods/equality_operator_spec.rb - spec/unit/equalizer/universal_spec.rb homepage: https://github.com/dkubb/equalizer licenses: - MIT metadata: {} post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 1.8.7 required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: "0" requirements: [] rubyforge_project: rubygems_version: 2.4.6 signing_key: specification_version: 4 summary: Module to define equality, equivalence and inspection methods test_files: - spec/unit/equalizer/included_spec.rb - spec/unit/equalizer/methods/eql_predicate_spec.rb - spec/unit/equalizer/methods/equality_operator_spec.rb - spec/unit/equalizer/universal_spec.rb has_rdoc: equalizer-0.0.10/config/0000755000175000017500000000000012614500242014714 5ustar praveenpraveenequalizer-0.0.10/config/rubocop.yml0000644000175000017500000000151412614500242017111 0ustar praveenpraveenMetrics/BlockNesting: Max: 2 Metrics/LineLength: AllowURI: true Enabled: false Metrics/MethodLength: CountComments: false Max: 15 Metrics/ParameterLists: Max: 4 CountKeywordArgs: true Style/AccessModifierIndentation: EnforcedStyle: outdent Style/CollectionMethods: PreferredMethods: map: 'collect' reduce: 'inject' find: 'detect' find_all: 'select' Style/Documentation: Enabled: false Style/DotPosition: EnforcedStyle: trailing Style/DoubleNegation: Enabled: false Style/EachWithObject: Enabled: false Style/Encoding: Enabled: false Style/HashSyntax: EnforcedStyle: hash_rockets Style/Lambda: Enabled: false Style/RaiseArgs: EnforcedStyle: compact Style/SpaceInsideHashLiteralBraces: EnforcedStyle: no_space Style/TrailingComma: EnforcedStyleForMultiline: 'comma' equalizer-0.0.10/equalizer.gemspec0000644000175000017500000000151612614500242017020 0ustar praveenpraveen# encoding: utf-8 require File.expand_path('../lib/equalizer/version', __FILE__) Gem::Specification.new do |gem| gem.name = 'equalizer' gem.version = Equalizer::VERSION.dup gem.authors = ['Dan Kubb', 'Markus Schirp'] gem.email = %w(dan.kubb@gmail.com mbj@schirp-dso.com) gem.description = 'Module to define equality, equivalence and inspection methods' gem.summary = gem.description gem.homepage = 'https://github.com/dkubb/equalizer' gem.licenses = 'MIT' gem.require_paths = %w(lib) gem.files = `git ls-files`.split("\n") gem.test_files = `git ls-files -- spec/{unit,integration}`.split("\n") gem.extra_rdoc_files = %w(LICENSE README.md CONTRIBUTING.md) gem.required_ruby_version = '>= 1.8.7' gem.add_development_dependency('bundler', '~> 1.3', '>= 1.3.5') end equalizer-0.0.10/README.md0000644000175000017500000000554512614500242014737 0ustar praveenpraveenequalizer ========= Module to define equality, equivalence and inspection methods [![Gem Version](http://img.shields.io/gem/v/equalizer.svg)][gem] [![Build Status](http://img.shields.io/travis/dkubb/equalizer.svg)][travis] [![Dependency Status](http://img.shields.io/gemnasium/dkubb/equalizer.svg)][gemnasium] [![Code Climate](http://img.shields.io/codeclimate/github/dkubb/equalizer.svg)][codeclimate] [![Coverage Status](http://img.shields.io/coveralls/dkubb/equalizer.svg)][coveralls] [gem]: https://rubygems.org/gems/equalizer [travis]: https://travis-ci.org/dkubb/equalizer [gemnasium]: https://gemnasium.com/dkubb/equalizer [codeclimate]: https://codeclimate.com/github/dkubb/equalizer [coveralls]: https://coveralls.io/r/dkubb/equalizer Examples -------- ``` ruby class GeoLocation include Equalizer.new(:latitude, :longitude) attr_reader :latitude, :longitude def initialize(latitude, longitude) @latitude, @longitude = latitude, longitude end end point_a = GeoLocation.new(1, 2) point_b = GeoLocation.new(1, 2) point_c = GeoLocation.new(2, 2) point_a.inspect # => "#" point_a == point_b # => true point_a.hash == point_b.hash # => true point_a.eql?(point_b) # => true point_a.equal?(point_b) # => false point_a == point_c # => false point_a.hash == point_c.hash # => false point_a.eql?(point_c) # => false point_a.equal?(point_c) # => false ``` Supported Ruby Versions ----------------------- This library aims to support and is [tested against][travis] the following Ruby implementations: * Ruby 1.8.7 * Ruby 1.9.3 * Ruby 2.0.0 * Ruby 2.1 * Ruby 2.2 * [JRuby][] * [Rubinius][] * [Ruby Enterprise Edition][ree] [jruby]: http://jruby.org/ [rubinius]: http://rubini.us/ [ree]: http://www.rubyenterpriseedition.com/ If something doesn't work on one of these versions, it's a bug. This library may inadvertently work (or seem to work) on other Ruby versions or implementations, however support will only be provided for the implementations listed above. If you would like this library to support another Ruby version or implementation, you may volunteer to be a maintainer. Being a maintainer entails making sure all tests run and pass on that implementation. When something breaks on your implementation, you will be responsible for providing patches in a timely fashion. If critical issues for a particular implementation exist at the time of a major release, support for that Ruby version may be dropped. Credits ------- * Dan Kubb ([dkubb](https://github.com/dkubb)) * Piotr Solnica ([solnic](https://github.com/solnic)) * Markus Schirp ([mbj](https://github.com/mbj)) * Erik Michaels-Ober ([sferik](https://github.com/sferik)) Contributing ------------- See [CONTRIBUTING.md](CONTRIBUTING.md) for details. Copyright --------- Copyright © 2009-2013 Dan Kubb. See LICENSE for details. equalizer-0.0.10/.yardstick.yml0000644000175000017500000000002312614500242016240 0ustar praveenpraveen--- threshold: 100 equalizer-0.0.10/Rakefile0000644000175000017500000000130712614500242015115 0ustar praveenpraveen# encoding: utf-8 require 'bundler' Bundler::GemHelper.install_tasks require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) task :test => :spec task :default => :spec begin require 'rubocop/rake_task' RuboCop::RakeTask.new do |task| task.options = %w(--config config/rubocop.yml) end rescue LoadError desc 'Run RuboCop' task :rubocop do $stderr.puts 'RuboCop is disabled' end end require 'yardstick/rake/measurement' Yardstick::Rake::Measurement.new do |measurement| measurement.output = 'measurement/report.txt' end require 'yardstick/rake/verify' Yardstick::Rake::Verify.new do |verify| verify.threshold = 100 end task :ci => [:spec, :rubocop, :verify_measurements] equalizer-0.0.10/LICENSE0000644000175000017500000000211612614500242014454 0ustar praveenpraveenCopyright (c) 2009-2013 Dan Kubb Copyright (c) 2012 Markus Schirp (packaging) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. equalizer-0.0.10/Gemfile0000644000175000017500000000074212614500242014745 0ustar praveenpraveen# encoding: utf-8 source 'https://rubygems.org' gem 'rake' group :test do gem 'backports' gem 'coveralls' gem 'json', :platforms => [:ruby_19] gem 'mime-types', '~> 1.25', :platforms => [:jruby, :ruby_18] gem 'rest-client', '~> 1.6.0', :platforms => [:jruby, :ruby_18] gem 'rspec', '~> 3.0' gem 'rubocop', '>= 0.25', :platforms => [:ruby_19, :ruby_20, :ruby_21, :ruby_22] gem 'simplecov', '>= 0.9' gem 'yardstick' end gemspec equalizer-0.0.10/.rspec0000644000175000017500000000011212614500242014556 0ustar praveenpraveen--backtrace --color --format progress --order random --profile --warnings equalizer-0.0.10/.travis.yml0000644000175000017500000000077712614500242015573 0ustar praveenpraveenbefore_install: gem update bundler cache: bundler sudo: false env: global: - JRUBY_OPTS="$JRUBY_OPTS --debug" # for simplecov language: ruby script: "bundle exec rake ci" rvm: - 1.8.7 - 1.9.3 - 2.0.0 - 2.1 - 2.2 - jruby-18mode - jruby-19mode - jruby-head - rbx-2 - ree - ruby-head matrix: allow_failures: - rvm: ruby-head - rvm: jruby-head fast_finish: true notifications: irc: channels: - irc.freenode.org#rom-rb on_success: never on_failure: change equalizer-0.0.10/.rubocop.yml0000644000175000017500000000000012614500242015707 0ustar praveenpraveenequalizer-0.0.10/.gitignore0000644000175000017500000000042212614500242015435 0ustar praveenpraveen## MAC OS .DS_Store ## TEXTMATE *.tmproj tmtags ## EMACS *~ \#* .\#* ## VIM *.swp ## Rubinius *.rbc .rbx ## PROJECT::GENERAL *.gem coverage profiling turbulence rdoc pkg tmp doc log .yardoc measurements ## BUNDLER .bundle Gemfile.lock bin bundle ## PROJECT::SPECIFIC