equalizer 0.0.1

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.
@@ -0,0 +1,208 @@
1
+ # encoding: utf-8
2
+
3
+ $LOAD_PATH.unshift(File.expand_path('../../../lib', __FILE__))
4
+
5
+ # original code by Ashley Moran:
6
+ # http://aviewfromafar.net/2007/11/1/rake-task-for-heckling-your-specs
7
+
8
+ begin
9
+ require 'pathname'
10
+ require 'heckle'
11
+ require 'mspec'
12
+ require 'mspec/utils/name_map'
13
+
14
+ SKIP_METHODS = %w[ blank_slate_method_added ].freeze
15
+
16
+ class NameMap
17
+ def file_name(method, constant)
18
+ map = MAP[method]
19
+ name = if map
20
+ map[constant] || map[:default]
21
+ else
22
+ method.gsub(/[?!=]\z/, '')
23
+ end
24
+ "#{name}_spec.rb"
25
+ end
26
+ end
27
+
28
+ namespace :metrics do
29
+ desc 'Heckle each module and class'
30
+ task :heckle => :coverage do
31
+ unless Ruby2Ruby::VERSION == '1.2.2'
32
+ raise "ruby2ruby version #{Ruby2Ruby::VERSION} may not work properly, 1.2.2 *only* is recommended for use with heckle"
33
+ end
34
+
35
+ require 'equalizer'
36
+
37
+ root_module_regexp = Regexp.union('Equalizer')
38
+
39
+ spec_dir = Pathname('spec/unit')
40
+
41
+ NameMap::MAP.each do |op, method|
42
+ next if method.kind_of?(Hash)
43
+ NameMap::MAP[op] = { :default => method }
44
+ end
45
+
46
+ aliases = Hash.new { |h,mod| h[mod] = Hash.new { |h,method| h[method] = method } }
47
+ map = NameMap.new
48
+
49
+ heckle_caught_modules = Hash.new { |hash, key| hash[key] = [] }
50
+ uncovered_methods = 0
51
+
52
+ ObjectSpace.each_object(Module) do |mod|
53
+ next unless mod.name =~ /\A#{root_module_regexp}(?::|\z)/
54
+
55
+ spec_prefix = spec_dir.join(mod.name.underscore)
56
+
57
+ specs = []
58
+
59
+ # get the public class methods
60
+ metaclass = class << mod; self end
61
+ ancestors = metaclass.ancestors
62
+
63
+ spec_class_methods = mod.singleton_methods(false)
64
+
65
+ spec_class_methods.reject! do |method|
66
+ %w[ yaml_new yaml_tag_subclasses? included nesting constants ].include?(method.to_s)
67
+ end
68
+
69
+ if mod.ancestors.include?(Singleton)
70
+ spec_class_methods.reject! { |method| method.to_s == 'instance' }
71
+ end
72
+
73
+ # get the protected and private class methods
74
+ other_class_methods = metaclass.protected_instance_methods(false) |
75
+ metaclass.private_instance_methods(false)
76
+
77
+ ancestors.each do |ancestor|
78
+ other_class_methods -= ancestor.protected_instance_methods(false) |
79
+ ancestor.private_instance_methods(false)
80
+ end
81
+
82
+ other_class_methods.reject! do |method|
83
+ method.to_s == 'allocate' || SKIP_METHODS.include?(method.to_s)
84
+ end
85
+
86
+ other_class_methods.reject! do |method|
87
+ next unless spec_class_methods.any? { |specced| specced.to_s == $1 }
88
+
89
+ spec_class_methods << method
90
+ end
91
+
92
+ spec_class_methods -= other_class_methods
93
+
94
+ # get the instances methods
95
+ spec_methods = mod.public_instance_methods(false)
96
+
97
+ other_methods = mod.protected_instance_methods(false) |
98
+ mod.private_instance_methods(false)
99
+
100
+ other_methods.reject! do |method|
101
+ next unless spec_methods.any? { |specced| specced.to_s == $1 }
102
+
103
+ spec_methods << method
104
+ end
105
+
106
+ # map the class methods to spec files
107
+ spec_class_methods.each do |method|
108
+ method = aliases[mod.name][method]
109
+ next if SKIP_METHODS.include?(method.to_s)
110
+
111
+ spec_file = spec_prefix.join('class_methods').join(map.file_name(method, mod.name))
112
+
113
+ unless spec_file.file?
114
+ raise "No spec file #{spec_file} for #{mod}.#{method}"
115
+ end
116
+
117
+ specs << [ ".#{method}", [ spec_file ] ]
118
+ end
119
+
120
+ # map the instance methods to spec files
121
+ spec_methods.each do |method|
122
+ method = aliases[mod.name][method]
123
+ next if SKIP_METHODS.include?(method.to_s)
124
+
125
+ spec_file = spec_prefix.join(map.file_name(method, mod.name))
126
+
127
+ unless spec_file.file?
128
+ raise "No spec file #{spec_file} for #{mod}##{method}"
129
+ end
130
+
131
+ specs << [ "##{method}", [ spec_file ] ]
132
+ end
133
+
134
+ # non-public methods are considered covered if they can be mutated
135
+ # and any spec fails for the current or descendant modules
136
+ other_methods.each do |method|
137
+ descedant_specs = []
138
+
139
+ ObjectSpace.each_object(Module) do |descedant|
140
+ next unless descedant.name =~ /\A#{root_module_regexp}(?::|\z)/ && mod >= descedant
141
+ descedant_spec_prefix = spec_dir.join(descedant.name.underscore)
142
+ descedant_specs << descedant_spec_prefix
143
+
144
+ if method.to_s == 'initialize'
145
+ descedant_specs.concat(Pathname.glob(descedant_spec_prefix.join('class_methods/new_spec.rb')))
146
+ end
147
+ end
148
+
149
+ specs << [ "##{method}", descedant_specs ]
150
+ end
151
+
152
+ other_class_methods.each do |method|
153
+ descedant_specs = []
154
+
155
+ ObjectSpace.each_object(Module) do |descedant|
156
+ next unless descedant.name =~ /\A#{root_module_regexp}(?::|\z)/ && mod >= descedant
157
+ descedant_specs << spec_dir.join(descedant.name.underscore).join('class_methods')
158
+ end
159
+
160
+ specs << [ ".#{method}", descedant_specs ]
161
+ end
162
+
163
+ specs.sort.each do |(method, spec_files)|
164
+ puts "Heckling #{mod}#{method}"
165
+ IO.popen("spec #{spec_files.join(' ')} --heckle '#{mod}#{method}'") do |pipe|
166
+ while line = pipe.gets
167
+ case line = line.chomp
168
+ when "The following mutations didn't cause test failures:"
169
+ heckle_caught_modules[mod.name] << method
170
+ uncovered_methods += 1
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end
176
+
177
+ if uncovered_methods > 0
178
+ error_message_lines = [ "*************\n" ]
179
+
180
+ error_message_lines << "Heckle found #{uncovered_methods} " \
181
+ "method#{"s" unless uncovered_methods == 1} " \
182
+ "where mutations didn't cause spec violations\n"
183
+
184
+ heckle_caught_modules.each do |mod, methods|
185
+ error_message_lines << "#{mod} contains the following " \
186
+ 'poorly-specified methods:'
187
+ methods.each do |method|
188
+ error_message_lines << " - #{method}"
189
+ end
190
+ error_message_lines << ''
191
+ end
192
+
193
+ error_message_lines << 'Get your act together and come back ' \
194
+ 'when your specs are doing their job!'
195
+
196
+ raise error_message_lines.join("\n")
197
+ else
198
+ puts 'Well done! Your code withstood a heckling.'
199
+ end
200
+ end
201
+ end
202
+ rescue LoadError
203
+ namespace :metrics do
204
+ task :heckle => :coverage do
205
+ $stderr.puts 'Heckle or mspec is not available. In order to run heckle, you must: gem install heckle mspec'
206
+ end
207
+ end
208
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+
3
+ begin
4
+ require 'metric_fu'
5
+ require 'json'
6
+
7
+ # XXX: temporary hack until metric_fu is fixed
8
+ MetricFu::Saikuro.class_eval { include FileUtils }
9
+
10
+ MetricFu::Configuration.run do |config|
11
+ config.rcov = {
12
+ :environment => 'test',
13
+ :test_files => %w[ spec/**/*_spec.rb ],
14
+ :rcov_opts => %w[
15
+ --sort coverage
16
+ --no-html
17
+ --text-coverage
18
+ --no-color
19
+ --profile
20
+ --exclude spec/,^/
21
+ --include lib:spec
22
+ ],
23
+ }
24
+ end
25
+ rescue LoadError
26
+ namespace :metrics do
27
+ task :all do
28
+ $stderr.puts 'metric_fu is not available. In order to run metrics:all, you must: gem install metric_fu'
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+
3
+ begin
4
+ require 'reek/rake/task'
5
+
6
+ RBX_18_MODE = RUBY_VERSION < '1.9' && defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
7
+
8
+ namespace :metrics do
9
+ Reek::Rake::Task.new do |t|
10
+ # reek has some problems under rbx in 1.8 mode that cause the underlying
11
+ # script to raise an exception. Rather than halt the "rake ci" process due
12
+ # to one bug, we choose to ignore it in this specific case until reek can be
13
+ # fixed.
14
+ t.fail_on_error = ! RBX_18_MODE # always true, except under rbx 18 mode
15
+ end
16
+ end
17
+ rescue LoadError
18
+ task :reek do
19
+ $stderr.puts 'Reek is not available. In order to run reek, you must: gem install reek'
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ begin
4
+ require 'roodi'
5
+ require 'rake/tasklib'
6
+ require 'roodi_task'
7
+
8
+ namespace :metrics do
9
+ RoodiTask.new do |t|
10
+ t.verbose = false
11
+ t.config = File.expand_path('../../../config/roodi.yml', __FILE__)
12
+ t.patterns = %w[ lib/**/*.rb ]
13
+ end
14
+ end
15
+ rescue LoadError
16
+ task :roodi do
17
+ $stderr.puts 'Roodi is not available. In order to run roodi, you must: gem install roodi'
18
+ end
19
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ begin
4
+ require 'yardstick/rake/measurement'
5
+ require 'yardstick/rake/verify'
6
+ require 'yaml'
7
+
8
+ config = YAML.load_file(File.expand_path('../../../config/yardstick.yml', __FILE__))
9
+
10
+ namespace :metrics do
11
+ # yardstick_measure task
12
+ Yardstick::Rake::Measurement.new
13
+
14
+ # verify_measurements task
15
+ Yardstick::Rake::Verify.new do |verify|
16
+ verify.threshold = config.fetch('threshold')
17
+ end
18
+ end
19
+ rescue LoadError
20
+ %w[ yardstick_measure verify_measurements ].each do |name|
21
+ task name.to_s do
22
+ $stderr.puts "Yardstick is not available. In order to run #{name}, you must: gem install yardstick"
23
+ end
24
+ end
25
+ end
data/tasks/spec.rake ADDED
@@ -0,0 +1,60 @@
1
+ # encoding: utf-8
2
+
3
+ spec_defaults = lambda do |spec|
4
+ spec.ruby_opts = %w[ -r./spec/support/config_alias ]
5
+ spec.spec_opts << '--options' << 'spec/spec.opts'
6
+ end
7
+
8
+ begin
9
+ require 'spec/rake/spectask'
10
+
11
+ desc 'Run all specs'
12
+ task :spec => %w[ spec:unit spec:integration ]
13
+
14
+ namespace :spec do
15
+ desc 'Run unit specs'
16
+ Spec::Rake::SpecTask.new(:unit) do |unit|
17
+ spec_defaults.call(unit)
18
+ unit.pattern = 'spec/unit/**/*_spec.rb'
19
+ end
20
+
21
+ desc 'Run integration specs'
22
+ Spec::Rake::SpecTask.new(:integration) do |integration|
23
+ spec_defaults.call(integration)
24
+ integration.pattern = 'spec/integration/**/*_spec.rb'
25
+ end
26
+ end
27
+ rescue LoadError
28
+ %w[ spec spec:unit spec:integration ].each do |name|
29
+ task name do
30
+ $stderr.puts "rspec is not available. In order to run #{name}, you must: gem install rspec"
31
+ end
32
+ end
33
+ end
34
+
35
+ namespace :metrics do
36
+ begin
37
+ if RUBY_VERSION < '1.9'
38
+ desc 'Generate code coverage'
39
+ Spec::Rake::SpecTask.new(:coverage) do |rcov|
40
+ spec_defaults.call(rcov)
41
+ rcov.rcov = true
42
+ rcov.pattern = 'spec/unit/**/*_spec.rb'
43
+ rcov.rcov_opts = File.read('spec/rcov.opts').split(/\s+/)
44
+ end
45
+ else
46
+ desc 'Generate code coverage'
47
+ task :coverage do
48
+ ENV['COVERAGE'] = 'true'
49
+ Rake::Task['spec:unit'].execute
50
+ end
51
+ end
52
+ rescue LoadError
53
+ task :coverage do
54
+ lib = RUBY_VERSION < '1.9' ? 'rcov' : 'simplecov'
55
+ $stderr.puts "coverage is not available. In order to run #{lib}, you must: gem install #{lib}"
56
+ end
57
+ end
58
+ end
59
+
60
+ task :test => :spec
data/tasks/yard.rake ADDED
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ begin
4
+ require 'yard'
5
+
6
+ YARD::Rake::YardocTask.new
7
+ rescue LoadError
8
+ task :yard do
9
+ $stderr.puts 'YARD is not available. In order to run yard, you must: gem install yard'
10
+ end
11
+ end
metadata ADDED
@@ -0,0 +1,172 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: equalizer
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Dan Kubb
14
+ - Markus Schirp
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2012-11-22 00:00:00 Z
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: backports
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 31
30
+ segments:
31
+ - 2
32
+ - 6
33
+ - 4
34
+ version: 2.6.4
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: adamantium
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 25
46
+ segments:
47
+ - 0
48
+ - 0
49
+ - 3
50
+ version: 0.0.3
51
+ type: :runtime
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: rake
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ hash: 75
62
+ segments:
63
+ - 10
64
+ - 0
65
+ - 2
66
+ version: 10.0.2
67
+ type: :development
68
+ version_requirements: *id003
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ prerelease: false
72
+ requirement: &id004 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ hash: 31
78
+ segments:
79
+ - 1
80
+ - 3
81
+ - 2
82
+ version: 1.3.2
83
+ type: :development
84
+ version_requirements: *id004
85
+ description: Module to define equality, equivalence and inspection methods
86
+ email:
87
+ - dan.kubb@gmail.com
88
+ - mbj@seonic.net
89
+ executables: []
90
+
91
+ extensions: []
92
+
93
+ extra_rdoc_files:
94
+ - LICENSE
95
+ - README.md
96
+ - TODO
97
+ files:
98
+ - .gitignore
99
+ - .rvmrc
100
+ - .travis.yml
101
+ - Gemfile
102
+ - Guardfile
103
+ - LICENSE
104
+ - README.md
105
+ - Rakefile
106
+ - TODO
107
+ - config/flay.yml
108
+ - config/flog.yml
109
+ - config/roodi.yml
110
+ - config/site.reek
111
+ - config/yardstick.yml
112
+ - equalizer.gemspec
113
+ - lib/equalizer.rb
114
+ - lib/equalizer/version.rb
115
+ - spec/rcov.opts
116
+ - spec/shared/command_method_behavior.rb
117
+ - spec/shared/each_method_behaviour.rb
118
+ - spec/shared/hash_method_behavior.rb
119
+ - spec/shared/idempotent_method_behavior.rb
120
+ - spec/shared/invertible_method_behaviour.rb
121
+ - spec/spec.opts
122
+ - spec/spec_helper.rb
123
+ - spec/support/config_alias.rb
124
+ - spec/unit/equalizer/class_method/new_spec.rb
125
+ - spec/unit/equalizer/methods/eql_spec.rb
126
+ - spec/unit/equalizer/methods/equal_value_spec.rb
127
+ - tasks/metrics/ci.rake
128
+ - tasks/metrics/flay.rake
129
+ - tasks/metrics/flog.rake
130
+ - tasks/metrics/heckle.rake
131
+ - tasks/metrics/metric_fu.rake
132
+ - tasks/metrics/reek.rake
133
+ - tasks/metrics/roodi.rake
134
+ - tasks/metrics/yardstick.rake
135
+ - tasks/spec.rake
136
+ - tasks/yard.rake
137
+ homepage: https://github.com/dkubb/equalizer
138
+ licenses: []
139
+
140
+ post_install_message:
141
+ rdoc_options: []
142
+
143
+ require_paths:
144
+ - lib
145
+ required_ruby_version: !ruby/object:Gem::Requirement
146
+ none: false
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ hash: 3
151
+ segments:
152
+ - 0
153
+ version: "0"
154
+ required_rubygems_version: !ruby/object:Gem::Requirement
155
+ none: false
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ hash: 3
160
+ segments:
161
+ - 0
162
+ version: "0"
163
+ requirements: []
164
+
165
+ rubyforge_project:
166
+ rubygems_version: 1.8.24
167
+ signing_key:
168
+ specification_version: 3
169
+ summary: Module to define equality, equivalence and inspection methods
170
+ test_files: []
171
+
172
+ has_rdoc: