equalizer 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: