adamantium 0.0.1 → 0.0.2
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.
- data/.travis.yml +5 -73
- data/Gemfile +2 -10
- data/Rakefile +1 -2
- data/adamantium.gemspec +10 -10
- data/config/flog.yml +1 -1
- data/lib/adamantium.rb +1 -1
- data/lib/adamantium/version.rb +1 -1
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +18 -1
- data/spec/support/config_alias.rb +3 -0
- data/tasks/metrics/ci.rake +5 -3
- data/tasks/metrics/flay.rake +11 -13
- data/tasks/metrics/flog.rake +26 -20
- data/tasks/metrics/heckle.rake +126 -127
- data/tasks/metrics/metric_fu.rake +2 -0
- data/tasks/metrics/reek.rake +11 -5
- data/tasks/metrics/roodi.rake +9 -5
- data/tasks/metrics/yardstick.rake +10 -8
- data/tasks/spec.rake +43 -28
- data/tasks/yard.rake +3 -1
- metadata +109 -80
data/.travis.yml
CHANGED
@@ -1,85 +1,17 @@
|
|
1
1
|
language: ruby
|
2
|
+
bundler_args: --without yard guard metrics
|
2
3
|
script: "bundle exec rake spec"
|
3
4
|
rvm:
|
4
|
-
- ree
|
5
5
|
- 1.8.7
|
6
6
|
- 1.9.2
|
7
7
|
- 1.9.3
|
8
|
-
- ruby-head
|
9
|
-
- rbx-18mode
|
10
|
-
- rbx-19mode
|
11
8
|
- jruby-18mode
|
12
9
|
- jruby-19mode
|
10
|
+
- rbx-18mode
|
11
|
+
- rbx-19mode
|
12
|
+
- ree
|
13
|
+
- ruby-head
|
13
14
|
- jruby-head
|
14
|
-
jdk:
|
15
|
-
- openjdk6
|
16
|
-
- openjdk7
|
17
|
-
- oraclejdk7
|
18
|
-
matrix:
|
19
|
-
exclude:
|
20
|
-
# remove ree from jdk matrix
|
21
|
-
- rvm: ree
|
22
|
-
jdk: openjdk6
|
23
|
-
- rvm: ree
|
24
|
-
jdk: openjdk7
|
25
|
-
- rvm: ree
|
26
|
-
jdk: oraclejdk7
|
27
|
-
|
28
|
-
# remove 1.8.7 from jdk matrix
|
29
|
-
- rvm: 1.8.7
|
30
|
-
jdk: openjdk6
|
31
|
-
- rvm: 1.8.7
|
32
|
-
jdk: openjdk7
|
33
|
-
- rvm: 1.8.7
|
34
|
-
jdk: oraclejdk7
|
35
|
-
|
36
|
-
# remove 1.9.2 from jdk matrix
|
37
|
-
- rvm: 1.9.2
|
38
|
-
jdk: openjdk6
|
39
|
-
- rvm: 1.9.2
|
40
|
-
jdk: openjdk7
|
41
|
-
- rvm: 1.9.2
|
42
|
-
jdk: oraclejdk7
|
43
|
-
|
44
|
-
# remove 1.9.3 from jdk matrix
|
45
|
-
- rvm: 1.9.3
|
46
|
-
jdk: openjdk6
|
47
|
-
- rvm: 1.9.3
|
48
|
-
jdk: openjdk7
|
49
|
-
- rvm: 1.9.3
|
50
|
-
jdk: oraclejdk7
|
51
|
-
|
52
|
-
# remove ruby-head from jdk matrix
|
53
|
-
- rvm: ruby-head
|
54
|
-
jdk: openjdk6
|
55
|
-
- rvm: ruby-head
|
56
|
-
jdk: openjdk7
|
57
|
-
- rvm: ruby-head
|
58
|
-
jdk: oraclejdk7
|
59
|
-
|
60
|
-
# remove rbx-18mode from jdk matrix
|
61
|
-
- rvm: rbx-18mode
|
62
|
-
jdk: openjdk6
|
63
|
-
- rvm: rbx-18mode
|
64
|
-
jdk: openjdk7
|
65
|
-
- rvm: rbx-18mode
|
66
|
-
jdk: oraclejdk7
|
67
|
-
|
68
|
-
# remove rbx-19mode from jdk matrix
|
69
|
-
- rvm: rbx-19mode
|
70
|
-
jdk: openjdk6
|
71
|
-
- rvm: rbx-19mode
|
72
|
-
jdk: openjdk7
|
73
|
-
- rvm: rbx-19mode
|
74
|
-
jdk: oraclejdk7
|
75
|
-
|
76
|
-
# remove jruby-18mode, jruby-19mode and jruby-head from non-jdk matrix
|
77
|
-
- rvm: jruby-18mode
|
78
|
-
jdk:
|
79
|
-
- rvm: jruby-19mode
|
80
|
-
jdk:
|
81
|
-
- rvm: jruby-head
|
82
|
-
jdk:
|
83
15
|
notifications:
|
84
16
|
email:
|
85
17
|
- dan.kubb@gmail.com
|
data/Gemfile
CHANGED
@@ -2,15 +2,7 @@
|
|
2
2
|
|
3
3
|
source 'https://rubygems.org'
|
4
4
|
|
5
|
-
|
6
|
-
gem 'ice_nine', '~> 0.4.0'
|
7
|
-
|
8
|
-
group :development do
|
9
|
-
gem 'jeweler', '~> 1.8.3'
|
10
|
-
gem 'rake', '~> 0.9.2'
|
11
|
-
gem 'rspec', '~> 1.3.2'
|
12
|
-
gem 'yard', '~> 0.8.1'
|
13
|
-
end
|
5
|
+
gemspec
|
14
6
|
|
15
7
|
group :guard do
|
16
8
|
gem 'guard', '~> 1.1.1'
|
@@ -33,7 +25,7 @@ group :metrics do
|
|
33
25
|
gem 'flog', '~> 2.5.1'
|
34
26
|
gem 'reek', '~> 1.2.8', :github => 'dkubb/reek'
|
35
27
|
gem 'roodi', '~> 2.1.0'
|
36
|
-
gem 'yardstick', '~> 0.
|
28
|
+
gem 'yardstick', '~> 0.7.0'
|
37
29
|
gem 'yard-spellcheck', '~> 0.1.5'
|
38
30
|
|
39
31
|
platforms :mri_18 do
|
data/Rakefile
CHANGED
data/adamantium.gemspec
CHANGED
@@ -1,25 +1,25 @@
|
|
1
|
-
#
|
1
|
+
# encoding: utf-8
|
2
2
|
|
3
3
|
require File.expand_path('../lib/adamantium/version', __FILE__)
|
4
4
|
|
5
5
|
Gem::Specification.new do |gem|
|
6
6
|
gem.name = 'adamantium'
|
7
7
|
gem.version = Adamantium::VERSION.dup
|
8
|
-
gem.authors = [
|
9
|
-
gem.email = [
|
8
|
+
gem.authors = ['Dan Kubb', 'Markus Schirp']
|
9
|
+
gem.email = %w[dan.kubb@gmail.com mbj@seonic.net]
|
10
10
|
gem.description = 'Immutable extensions to objects'
|
11
11
|
gem.summary = gem.description
|
12
12
|
gem.homepage = 'https://github.com/dkubb/adamantium'
|
13
13
|
|
14
|
-
gem.require_paths = [
|
15
|
-
gem.files = `git ls-files`.split(
|
16
|
-
gem.test_files = `git ls-files
|
14
|
+
gem.require_paths = %w[lib]
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.test_files = `git ls-files spec/{unit,integration}`.split($/)
|
17
17
|
gem.extra_rdoc_files = %w[LICENSE README.md TODO]
|
18
18
|
|
19
|
-
gem.add_runtime_dependency('backports', '~> 2.6.
|
20
|
-
gem.add_runtime_dependency('ice_nine', '~> 0.
|
19
|
+
gem.add_runtime_dependency('backports', '~> 2.6.4')
|
20
|
+
gem.add_runtime_dependency('ice_nine', '~> 0.5.0')
|
21
21
|
|
22
|
-
gem.add_development_dependency('rake', '~> 0.9.2')
|
22
|
+
gem.add_development_dependency('rake', '~> 0.9.2.2')
|
23
23
|
gem.add_development_dependency('rspec', '~> 1.3.2')
|
24
|
-
gem.add_development_dependency('yard', '~> 0.8.
|
24
|
+
gem.add_development_dependency('yard', '~> 0.8.3')
|
25
25
|
end
|
data/config/flog.yml
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
---
|
2
|
-
threshold:
|
2
|
+
threshold: 23.4
|
data/lib/adamantium.rb
CHANGED
data/lib/adamantium/version.rb
CHANGED
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
CHANGED
@@ -5,7 +5,24 @@ require 'spec'
|
|
5
5
|
require 'spec/autorun'
|
6
6
|
|
7
7
|
# require spec support files and shared behavior
|
8
|
-
Dir[File.expand_path('../{support,shared}/**/*.rb', __FILE__)].each
|
8
|
+
Dir[File.expand_path('../{support,shared}/**/*.rb', __FILE__)].each do |file|
|
9
|
+
require file
|
10
|
+
end
|
9
11
|
|
10
12
|
Spec::Runner.configure do |config|
|
11
13
|
end
|
14
|
+
|
15
|
+
if RUBY_VERSION >= '1.9' and ENV['COVERAGE'] == 'true'
|
16
|
+
require 'simplecov'
|
17
|
+
SimpleCov.start do
|
18
|
+
command_name 'spec:unit'
|
19
|
+
add_filter 'spec'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# change the heckle timeout to be 5 seconds
|
24
|
+
if defined?(::Heckle)
|
25
|
+
class ::Heckle
|
26
|
+
@@timeout = 5
|
27
|
+
end
|
28
|
+
end
|
data/tasks/metrics/ci.rake
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
desc 'Run metrics with Heckle'
|
2
|
-
task :ci => %w[ ci:metrics heckle ]
|
4
|
+
task :ci => %w[ ci:metrics metrics:heckle ]
|
3
5
|
|
4
6
|
namespace :ci do
|
5
|
-
desc 'Run metrics'
|
6
|
-
task :metrics => %w[ verify_measurements flog flay reek
|
7
|
+
desc 'Run metrics (except heckle) and spec'
|
8
|
+
task :metrics => %w[ spec metrics:verify_measurements metrics:flog metrics:flay metrics:reek metrics:roodi ]
|
7
9
|
end
|
data/tasks/metrics/flay.rake
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
begin
|
2
|
-
|
3
|
-
|
4
|
-
require 'yaml'
|
4
|
+
require 'flay'
|
5
|
+
require 'yaml'
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
config = YAML.load_file(File.expand_path('../../../config/flay.yml', __FILE__)).freeze
|
8
|
+
threshold = config.fetch('threshold').to_i
|
9
|
+
total_score = config.fetch('total_score').to_f
|
10
|
+
files = Flay.expand_dirs_to_files(config.fetch('path', 'lib')).sort
|
10
11
|
|
12
|
+
namespace :metrics do
|
11
13
|
# original code by Marty Andrews:
|
12
14
|
# http://blog.martyandrews.net/2009/05/enforcing-ruby-code-quality.html
|
13
15
|
desc 'Analyze for code duplication'
|
@@ -16,7 +18,7 @@ begin
|
|
16
18
|
flay = Flay.new(:fuzzy => false, :verbose => false, :mass => 0)
|
17
19
|
flay.process(*files)
|
18
20
|
|
19
|
-
max = flay.masses.map { |hash, mass| mass.to_f / flay.hashes[hash].size }.max
|
21
|
+
max = (flay.masses.map { |hash, mass| mass.to_f / flay.hashes[hash].size }.max) || 0
|
20
22
|
unless max >= threshold
|
21
23
|
raise "Adjust flay threshold down to #{max}"
|
22
24
|
end
|
@@ -35,13 +37,9 @@ begin
|
|
35
37
|
raise "#{flay.masses.size} chunks of code have a duplicate mass > #{threshold}"
|
36
38
|
end
|
37
39
|
end
|
38
|
-
else
|
39
|
-
task :flay do
|
40
|
-
$stderr.puts 'Flay has inconsistend results accros ruby implementations. It is only enabled on 1.8.7, fix and remove guard'
|
41
|
-
end
|
42
40
|
end
|
43
41
|
rescue LoadError
|
44
42
|
task :flay do
|
45
|
-
|
43
|
+
$stderr.puts 'Flay is not available. In order to run flay, you must: gem install flay'
|
46
44
|
end
|
47
45
|
end
|
data/tasks/metrics/flog.rake
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
begin
|
2
4
|
require 'flog'
|
3
5
|
require 'yaml'
|
@@ -11,33 +13,37 @@ begin
|
|
11
13
|
config = YAML.load_file(File.expand_path('../../../config/flog.yml', __FILE__)).freeze
|
12
14
|
threshold = config.fetch('threshold').to_f.round_to(1)
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
flog
|
19
|
-
|
20
|
-
|
21
|
-
totals = flog.totals.select { |name, score| name[-5, 5] != '#none' }.
|
22
|
-
map { |name, score| [ name, score.round_to(1) ] }.
|
23
|
-
sort_by { |name, score| score }
|
16
|
+
namespace :metrics do
|
17
|
+
# original code by Marty Andrews:
|
18
|
+
# http://blog.martyandrews.net/2009/05/enforcing-ruby-code-quality.html
|
19
|
+
desc 'Analyze for code complexity'
|
20
|
+
task :flog do
|
21
|
+
flog = Flog.new
|
22
|
+
flog.flog Array(config.fetch('path', 'lib'))
|
24
23
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
end
|
24
|
+
totals = flog.totals.select { |name, score| name[-5, 5] != '#none' }.
|
25
|
+
map { |name, score| [ name, score.round_to(1) ] }.
|
26
|
+
sort_by { |name, score| score }
|
29
27
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
28
|
+
if totals.any?
|
29
|
+
max = totals.last[1]
|
30
|
+
unless max >= threshold
|
31
|
+
raise "Adjust flog score down to #{max}"
|
32
|
+
end
|
34
33
|
end
|
35
34
|
|
36
|
-
|
35
|
+
bad_methods = totals.select { |name, score| score > threshold }
|
36
|
+
if bad_methods.any?
|
37
|
+
bad_methods.reverse_each do |name, score|
|
38
|
+
puts '%8.1f: %s' % [ score, name ]
|
39
|
+
end
|
40
|
+
|
41
|
+
raise "#{bad_methods.size} methods have a flog complexity > #{threshold}"
|
42
|
+
end
|
37
43
|
end
|
38
44
|
end
|
39
45
|
rescue LoadError
|
40
46
|
task :flog do
|
41
|
-
|
47
|
+
$stderr.puts 'Flog is not available. In order to run flog, you must: gem install flog'
|
42
48
|
end
|
43
49
|
end
|
data/tasks/metrics/heckle.rake
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
$LOAD_PATH.unshift(File.expand_path('../../../lib', __FILE__))
|
2
4
|
|
3
5
|
# original code by Ashley Moran:
|
@@ -5,8 +7,6 @@ $LOAD_PATH.unshift(File.expand_path('../../../lib', __FILE__))
|
|
5
7
|
|
6
8
|
begin
|
7
9
|
require 'pathname'
|
8
|
-
require 'backports'
|
9
|
-
require 'active_support/inflector'
|
10
10
|
require 'heckle'
|
11
11
|
require 'mspec'
|
12
12
|
require 'mspec/utils/name_map'
|
@@ -19,190 +19,189 @@ begin
|
|
19
19
|
name = if map
|
20
20
|
map[constant] || map[:default]
|
21
21
|
else
|
22
|
-
method.
|
23
|
-
gsub('?','_ques').
|
24
|
-
gsub('!','_bang').
|
25
|
-
gsub('=','_assign')
|
22
|
+
method.gsub(/[?!=]\z/, '')
|
26
23
|
end
|
27
24
|
"#{name}_spec.rb"
|
28
25
|
end
|
29
26
|
end
|
30
27
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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
|
36
34
|
|
37
|
-
|
35
|
+
require 'adamantium'
|
38
36
|
|
39
|
-
|
37
|
+
root_module_regexp = Regexp.union('Adamantium')
|
40
38
|
|
41
|
-
|
39
|
+
spec_dir = Pathname('spec/unit')
|
42
40
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
41
|
+
NameMap::MAP.each do |op, method|
|
42
|
+
next if method.kind_of?(Hash)
|
43
|
+
NameMap::MAP[op] = { :default => method }
|
44
|
+
end
|
47
45
|
|
48
|
-
|
49
|
-
|
46
|
+
aliases = Hash.new { |h,mod| h[mod] = Hash.new { |h,method| h[method] = method } }
|
47
|
+
map = NameMap.new
|
50
48
|
|
51
|
-
|
52
|
-
|
49
|
+
heckle_caught_modules = Hash.new { |hash, key| hash[key] = [] }
|
50
|
+
unhandled_mutations = 0
|
53
51
|
|
54
|
-
|
55
|
-
|
52
|
+
ObjectSpace.each_object(Module) do |mod|
|
53
|
+
next unless mod.name =~ /\A#{root_module_regexp}(?::|\z)/
|
56
54
|
|
57
|
-
|
55
|
+
spec_prefix = spec_dir.join(mod.name.underscore)
|
58
56
|
|
59
|
-
|
57
|
+
specs = []
|
60
58
|
|
61
|
-
|
62
|
-
|
63
|
-
|
59
|
+
# get the public class methods
|
60
|
+
metaclass = class << mod; self end
|
61
|
+
ancestors = metaclass.ancestors
|
64
62
|
|
65
|
-
|
63
|
+
spec_class_methods = mod.singleton_methods(false)
|
66
64
|
|
67
|
-
|
68
|
-
|
69
|
-
|
65
|
+
spec_class_methods.reject! do |method|
|
66
|
+
%w[ yaml_new yaml_tag_subclasses? included nesting constants ].include?(method.to_s)
|
67
|
+
end
|
70
68
|
|
71
|
-
|
72
|
-
|
73
|
-
|
69
|
+
if mod.ancestors.include?(Singleton)
|
70
|
+
spec_class_methods.reject! { |method| method.to_s == 'instance' }
|
71
|
+
end
|
74
72
|
|
75
|
-
|
76
|
-
|
77
|
-
|
73
|
+
# get the protected and private class methods
|
74
|
+
other_class_methods = metaclass.protected_instance_methods(false) |
|
75
|
+
metaclass.private_instance_methods(false)
|
78
76
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
77
|
+
ancestors.each do |ancestor|
|
78
|
+
other_class_methods -= ancestor.protected_instance_methods(false) |
|
79
|
+
ancestor.private_instance_methods(false)
|
80
|
+
end
|
83
81
|
|
84
|
-
|
85
|
-
|
86
|
-
|
82
|
+
other_class_methods.reject! do |method|
|
83
|
+
method.to_s == 'allocate' || SKIP_METHODS.include?(method.to_s)
|
84
|
+
end
|
87
85
|
|
88
|
-
|
89
|
-
|
86
|
+
other_class_methods.reject! do |method|
|
87
|
+
next unless spec_class_methods.any? { |specced| specced.to_s == $1 }
|
90
88
|
|
91
|
-
|
92
|
-
|
89
|
+
spec_class_methods << method
|
90
|
+
end
|
93
91
|
|
94
|
-
|
95
|
-
spec_methods = mod.public_instance_methods(false)
|
92
|
+
spec_class_methods -= other_class_methods
|
96
93
|
|
97
|
-
|
98
|
-
|
94
|
+
# get the instances methods
|
95
|
+
spec_methods = mod.public_instance_methods(false)
|
99
96
|
|
100
|
-
|
101
|
-
|
97
|
+
other_methods = mod.protected_instance_methods(false) |
|
98
|
+
mod.private_instance_methods(false)
|
102
99
|
|
103
|
-
|
104
|
-
|
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
105
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
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
110
|
|
111
|
-
|
111
|
+
spec_file = spec_prefix.join('class_methods').join(map.file_name(method, mod.name))
|
112
112
|
|
113
|
-
|
114
|
-
|
115
|
-
|
113
|
+
unless spec_file.file?
|
114
|
+
raise "No spec file #{spec_file} for #{mod}.#{method}"
|
115
|
+
end
|
116
|
+
|
117
|
+
specs << [ ".#{method}", [ spec_file ] ]
|
116
118
|
end
|
117
119
|
|
118
|
-
|
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)
|
120
124
|
|
121
|
-
|
122
|
-
spec_methods.each do |method|
|
123
|
-
method = aliases[mod.name][method]
|
124
|
-
next if SKIP_METHODS.include?(method.to_s)
|
125
|
+
spec_file = spec_prefix.join(map.file_name(method, mod.name))
|
125
126
|
|
126
|
-
|
127
|
+
unless spec_file.file?
|
128
|
+
raise "No spec file #{spec_file} for #{mod}##{method}"
|
129
|
+
end
|
127
130
|
|
128
|
-
|
129
|
-
raise "No spec file #{spec_file} for #{mod}##{method}"
|
130
|
-
next
|
131
|
+
specs << [ "##{method}", [ spec_file ] ]
|
131
132
|
end
|
132
133
|
|
133
|
-
|
134
|
-
|
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 = []
|
135
138
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
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
|
140
143
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
descedant_specs << descedant_spec_prefix
|
145
|
-
|
146
|
-
if method.to_s == 'initialize'
|
147
|
-
descedant_specs.concat(Pathname.glob(descedant_spec_prefix.join('class_methods/new_spec.rb')))
|
144
|
+
if method.to_s == 'initialize'
|
145
|
+
descedant_specs.concat(Pathname.glob(descedant_spec_prefix.join('class_methods/new_spec.rb')))
|
146
|
+
end
|
148
147
|
end
|
148
|
+
|
149
|
+
specs << [ "##{method}", descedant_specs ]
|
149
150
|
end
|
150
151
|
|
151
|
-
|
152
|
-
|
152
|
+
other_class_methods.each do |method|
|
153
|
+
descedant_specs = []
|
153
154
|
|
154
|
-
|
155
|
-
|
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
|
156
159
|
|
157
|
-
|
158
|
-
next unless descedant.name =~ /\A#{root_module_regexp}(?::|\z)/ && mod >= descedant
|
159
|
-
descedant_specs << spec_dir.join(descedant.name.underscore).join('class_methods')
|
160
|
+
specs << [ ".#{method}", descedant_specs ]
|
160
161
|
end
|
161
162
|
|
162
|
-
specs
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
when '+++ mutation'
|
173
|
-
unhandled_mutations += 1
|
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
|
+
when '+++ mutation'
|
171
|
+
unhandled_mutations += 1
|
172
|
+
end
|
174
173
|
end
|
175
174
|
end
|
176
175
|
end
|
177
176
|
end
|
178
|
-
end
|
179
177
|
|
180
|
-
|
181
|
-
|
178
|
+
if unhandled_mutations > 0
|
179
|
+
error_message_lines = [ "*************\n" ]
|
182
180
|
|
183
|
-
|
184
|
-
|
185
|
-
|
181
|
+
error_message_lines << "Heckle found #{unhandled_mutations} " \
|
182
|
+
"mutation#{"s" unless unhandled_mutations == 1} " \
|
183
|
+
"that didn't cause spec violations\n"
|
186
184
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
185
|
+
heckle_caught_modules.each do |mod, methods|
|
186
|
+
error_message_lines << "#{mod} contains the following " \
|
187
|
+
'poorly-specified methods:'
|
188
|
+
methods.each do |method|
|
189
|
+
error_message_lines << " - #{method}"
|
190
|
+
end
|
191
|
+
error_message_lines << ''
|
192
192
|
end
|
193
|
-
error_message_lines << ''
|
194
|
-
end
|
195
193
|
|
196
|
-
|
197
|
-
|
194
|
+
error_message_lines << 'Get your act together and come back ' \
|
195
|
+
'when your specs are doing their job!'
|
198
196
|
|
199
|
-
|
200
|
-
|
201
|
-
|
197
|
+
raise error_message_lines.join("\n")
|
198
|
+
else
|
199
|
+
puts 'Well done! Your code withstood a heckling.'
|
200
|
+
end
|
202
201
|
end
|
203
202
|
end
|
204
203
|
rescue LoadError
|
205
|
-
task :heckle => :
|
204
|
+
task :heckle => :coverage do
|
206
205
|
$stderr.puts 'Heckle or mspec is not available. In order to run heckle, you must: gem install heckle mspec'
|
207
206
|
end
|
208
207
|
end
|
data/tasks/metrics/reek.rake
CHANGED
@@ -1,12 +1,18 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
begin
|
2
4
|
require 'reek/rake/task'
|
3
5
|
|
4
|
-
|
5
|
-
|
6
|
-
|
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
|
7
15
|
end
|
8
|
-
else
|
9
|
-
Reek::Rake::Task.new
|
10
16
|
end
|
11
17
|
rescue LoadError
|
12
18
|
task :reek do
|
data/tasks/metrics/roodi.rake
CHANGED
@@ -1,15 +1,19 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
begin
|
2
4
|
require 'roodi'
|
3
5
|
require 'rake/tasklib'
|
4
6
|
require 'roodi_task'
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
10
14
|
end
|
11
15
|
rescue LoadError
|
12
16
|
task :roodi do
|
13
|
-
|
17
|
+
$stderr.puts 'Roodi is not available. In order to run roodi, you must: gem install roodi'
|
14
18
|
end
|
15
19
|
end
|
@@ -1,23 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
begin
|
2
|
-
require 'pathname'
|
3
|
-
require 'yardstick'
|
4
4
|
require 'yardstick/rake/measurement'
|
5
5
|
require 'yardstick/rake/verify'
|
6
6
|
require 'yaml'
|
7
7
|
|
8
8
|
config = YAML.load_file(File.expand_path('../../../config/yardstick.yml', __FILE__))
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
namespace :metrics do
|
11
|
+
# yardstick_measure task
|
12
|
+
Yardstick::Rake::Measurement.new
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
14
|
+
# verify_measurements task
|
15
|
+
Yardstick::Rake::Verify.new do |verify|
|
16
|
+
verify.threshold = config.fetch('threshold')
|
17
|
+
end
|
16
18
|
end
|
17
19
|
rescue LoadError
|
18
20
|
%w[ yardstick_measure verify_measurements ].each do |name|
|
19
21
|
task name.to_s do
|
20
|
-
|
22
|
+
$stderr.puts "Yardstick is not available. In order to run #{name}, you must: gem install yardstick"
|
21
23
|
end
|
22
24
|
end
|
23
25
|
end
|
data/tasks/spec.rake
CHANGED
@@ -1,45 +1,60 @@
|
|
1
|
-
|
1
|
+
# encoding: utf-8
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
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
7
|
|
8
|
-
|
9
|
-
|
10
|
-
RakeTask = Spec::Rake::SpecTask
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
8
|
+
begin
|
9
|
+
require 'spec/rake/spectask'
|
14
10
|
|
15
|
-
desc '
|
11
|
+
desc 'Run all specs'
|
16
12
|
task :spec => %w[ spec:unit spec:integration ]
|
17
13
|
|
18
14
|
namespace :spec do
|
19
|
-
|
20
|
-
|
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'
|
21
19
|
end
|
22
20
|
|
23
|
-
|
24
|
-
|
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
25
|
end
|
26
26
|
end
|
27
27
|
rescue LoadError
|
28
|
-
|
29
|
-
|
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
|
30
32
|
end
|
31
33
|
end
|
32
34
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
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
|
42
57
|
end
|
43
58
|
end
|
44
59
|
|
45
|
-
task :test =>
|
60
|
+
task :test => :spec
|
data/tasks/yard.rake
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
begin
|
2
4
|
require 'yard'
|
3
5
|
|
4
6
|
YARD::Rake::YardocTask.new
|
5
7
|
rescue LoadError
|
6
8
|
task :yard do
|
7
|
-
|
9
|
+
$stderr.puts 'YARD is not available. In order to run yard, you must: gem install yard'
|
8
10
|
end
|
9
11
|
end
|
metadata
CHANGED
@@ -1,108 +1,117 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: adamantium
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
6
11
|
platform: ruby
|
7
|
-
authors:
|
12
|
+
authors:
|
8
13
|
- Dan Kubb
|
9
14
|
- Markus Schirp
|
10
15
|
autorequire:
|
11
16
|
bindir: bin
|
12
17
|
cert_chain: []
|
13
|
-
|
14
|
-
|
15
|
-
|
18
|
+
|
19
|
+
date: 2012-10-26 00:00:00 Z
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
16
22
|
name: backports
|
17
|
-
requirement: !ruby/object:Gem::Requirement
|
18
|
-
none: false
|
19
|
-
requirements:
|
20
|
-
- - ~>
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: 2.6.1
|
23
|
-
type: :runtime
|
24
23
|
prerelease: false
|
25
|
-
|
26
|
-
none: false
|
27
|
-
requirements:
|
28
|
-
- - ~>
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
version: 2.6.1
|
31
|
-
- !ruby/object:Gem::Dependency
|
32
|
-
name: ice_nine
|
33
|
-
requirement: !ruby/object:Gem::Requirement
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
34
25
|
none: false
|
35
|
-
requirements:
|
26
|
+
requirements:
|
36
27
|
- - ~>
|
37
|
-
- !ruby/object:Gem::Version
|
38
|
-
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 31
|
30
|
+
segments:
|
31
|
+
- 2
|
32
|
+
- 6
|
33
|
+
- 4
|
34
|
+
version: 2.6.4
|
39
35
|
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: ice_nine
|
40
39
|
prerelease: false
|
41
|
-
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
42
41
|
none: false
|
43
|
-
requirements:
|
42
|
+
requirements:
|
44
43
|
- - ~>
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
|
47
|
-
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 11
|
46
|
+
segments:
|
47
|
+
- 0
|
48
|
+
- 5
|
49
|
+
- 0
|
50
|
+
version: 0.5.0
|
51
|
+
type: :runtime
|
52
|
+
version_requirements: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
48
54
|
name: rake
|
49
|
-
requirement: !ruby/object:Gem::Requirement
|
50
|
-
none: false
|
51
|
-
requirements:
|
52
|
-
- - ~>
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: 0.9.2
|
55
|
-
type: :development
|
56
55
|
prerelease: false
|
57
|
-
|
56
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
58
57
|
none: false
|
59
|
-
requirements:
|
58
|
+
requirements:
|
60
59
|
- - ~>
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
- !ruby/object:Gem::Version
|
70
|
-
version: 1.3.2
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
hash: 11
|
62
|
+
segments:
|
63
|
+
- 0
|
64
|
+
- 9
|
65
|
+
- 2
|
66
|
+
- 2
|
67
|
+
version: 0.9.2.2
|
71
68
|
type: :development
|
69
|
+
version_requirements: *id003
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: rspec
|
72
72
|
prerelease: false
|
73
|
-
|
73
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
74
74
|
none: false
|
75
|
-
requirements:
|
75
|
+
requirements:
|
76
76
|
- - ~>
|
77
|
-
- !ruby/object:Gem::Version
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
hash: 31
|
79
|
+
segments:
|
80
|
+
- 1
|
81
|
+
- 3
|
82
|
+
- 2
|
78
83
|
version: 1.3.2
|
79
|
-
- !ruby/object:Gem::Dependency
|
80
|
-
name: yard
|
81
|
-
requirement: !ruby/object:Gem::Requirement
|
82
|
-
none: false
|
83
|
-
requirements:
|
84
|
-
- - ~>
|
85
|
-
- !ruby/object:Gem::Version
|
86
|
-
version: 0.8.1
|
87
84
|
type: :development
|
85
|
+
version_requirements: *id004
|
86
|
+
- !ruby/object:Gem::Dependency
|
87
|
+
name: yard
|
88
88
|
prerelease: false
|
89
|
-
|
89
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
90
90
|
none: false
|
91
|
-
requirements:
|
91
|
+
requirements:
|
92
92
|
- - ~>
|
93
|
-
- !ruby/object:Gem::Version
|
94
|
-
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
hash: 57
|
95
|
+
segments:
|
96
|
+
- 0
|
97
|
+
- 8
|
98
|
+
- 3
|
99
|
+
version: 0.8.3
|
100
|
+
type: :development
|
101
|
+
version_requirements: *id005
|
95
102
|
description: Immutable extensions to objects
|
96
|
-
email:
|
103
|
+
email:
|
97
104
|
- dan.kubb@gmail.com
|
98
105
|
- mbj@seonic.net
|
99
106
|
executables: []
|
107
|
+
|
100
108
|
extensions: []
|
101
|
-
|
109
|
+
|
110
|
+
extra_rdoc_files:
|
102
111
|
- LICENSE
|
103
112
|
- README.md
|
104
113
|
- TODO
|
105
|
-
files:
|
114
|
+
files:
|
106
115
|
- .gitignore
|
107
116
|
- .rvmrc
|
108
117
|
- .travis.yml
|
@@ -126,7 +135,9 @@ files:
|
|
126
135
|
- spec/shared/hash_method_behavior.rb
|
127
136
|
- spec/shared/idempotent_method_behavior.rb
|
128
137
|
- spec/shared/invertible_method_behaviour.rb
|
138
|
+
- spec/spec.opts
|
129
139
|
- spec/spec_helper.rb
|
140
|
+
- spec/support/config_alias.rb
|
130
141
|
- spec/unit/adamantium/class_methods/freeze_object_spec.rb
|
131
142
|
- spec/unit/adamantium/class_methods/new_spec.rb
|
132
143
|
- spec/unit/adamantium/dup_spec.rb
|
@@ -148,27 +159,45 @@ files:
|
|
148
159
|
- tasks/yard.rake
|
149
160
|
homepage: https://github.com/dkubb/adamantium
|
150
161
|
licenses: []
|
162
|
+
|
151
163
|
post_install_message:
|
152
164
|
rdoc_options: []
|
153
|
-
|
165
|
+
|
166
|
+
require_paths:
|
154
167
|
- lib
|
155
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
168
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
156
169
|
none: false
|
157
|
-
requirements:
|
158
|
-
- -
|
159
|
-
- !ruby/object:Gem::Version
|
160
|
-
|
161
|
-
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
hash: 3
|
174
|
+
segments:
|
175
|
+
- 0
|
176
|
+
version: "0"
|
177
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
162
178
|
none: false
|
163
|
-
requirements:
|
164
|
-
- -
|
165
|
-
- !ruby/object:Gem::Version
|
166
|
-
|
179
|
+
requirements:
|
180
|
+
- - ">="
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
hash: 3
|
183
|
+
segments:
|
184
|
+
- 0
|
185
|
+
version: "0"
|
167
186
|
requirements: []
|
187
|
+
|
168
188
|
rubyforge_project:
|
169
189
|
rubygems_version: 1.8.24
|
170
190
|
signing_key:
|
171
191
|
specification_version: 3
|
172
192
|
summary: Immutable extensions to objects
|
173
|
-
test_files:
|
193
|
+
test_files:
|
194
|
+
- spec/unit/adamantium/class_methods/freeze_object_spec.rb
|
195
|
+
- spec/unit/adamantium/class_methods/new_spec.rb
|
196
|
+
- spec/unit/adamantium/dup_spec.rb
|
197
|
+
- spec/unit/adamantium/fixtures/classes.rb
|
198
|
+
- spec/unit/adamantium/freeze_spec.rb
|
199
|
+
- spec/unit/adamantium/memoize_spec.rb
|
200
|
+
- spec/unit/adamantium/memoized_spec.rb
|
201
|
+
- spec/unit/adamantium/module_methods/included_spec.rb
|
202
|
+
- spec/unit/adamantium/module_methods/memoize_spec.rb
|
174
203
|
has_rdoc:
|