ice_nine 0.5.0 → 0.6.0

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.
@@ -1,5 +1,6 @@
1
1
  language: ruby
2
- bundler_args: --without guard metrics
2
+ before_install: gem install bundler
3
+ bundler_args: --without yard guard
3
4
  script: "bundle exec rake spec"
4
5
  rvm:
5
6
  - 1.8.7
data/Gemfile CHANGED
@@ -4,36 +4,55 @@ source 'https://rubygems.org'
4
4
 
5
5
  gemspec
6
6
 
7
- group :metrics do
8
- gem 'fattr', '~> 2.2.1'
9
- gem 'arrayfields', '~> 4.7.4'
10
- gem 'flay', '~> 1.4.3'
11
- gem 'flog', '~> 2.5.3'
12
- gem 'map', '~> 5.4.0'
13
- gem 'reek', '~> 1.2.8', :github => 'dkubb/reek'
14
- gem 'roodi', '~> 2.1.0'
15
- gem 'tailor', '~> 0.1.5'
16
- gem 'yardstick', '~> 0.4.0'
17
- gem 'yard-spellcheck', '~> 0.1.4'
18
-
19
- platforms :mri_19 do
20
- gem 'cane', '~> 1.1.0'
21
- gem 'simplecov', '~> 0.6.1'
7
+ group :yard do
8
+ gem 'redcarpet', '~> 2.2.2', :platforms => [ :mri, :rbx ]
9
+ end
10
+
11
+ group :guard do
12
+ gem 'guard', '~> 1.5.4'
13
+ gem 'guard-bundler', '~> 1.0.0'
14
+ gem 'guard-rspec', '~> 1.2.1'
15
+ end
16
+
17
+ group :benchmarks do
18
+ gem 'rbench', '~> 0.2.3'
19
+ end
20
+
21
+ platform :jruby do
22
+ group :jruby do
23
+ gem 'jruby-openssl', '~> 0.8.2'
22
24
  end
25
+ end
26
+
27
+ group :metrics do
28
+ gem 'flay', '~> 1.4.3'
29
+ gem 'flog', '~> 2.5.3'
30
+ gem 'reek', '~> 1.2.8', :github => 'dkubb/reek'
31
+ gem 'roodi', '~> 2.1.0'
32
+ gem 'yardstick', '~> 0.8.0'
23
33
 
24
- platforms :mri_18, :rbx do
25
- gem 'heckle', '~> 1.4.3'
26
- gem 'json', '~> 1.6.6'
27
- gem 'mspec', '~> 1.5.17'
28
- gem 'ruby2ruby', '= 1.2.2'
34
+ platforms :ruby_18, :ruby_19 do
35
+ # this indirectly depends on ffi which does not build on ruby-head
36
+ gem 'yard-spellcheck', '~> 0.1.5'
29
37
  end
30
38
 
31
39
  platforms :mri_18 do
32
- gem 'metric_fu', '~> 2.1.1'
33
- gem 'rcov', '~> 1.0.0'
40
+ gem 'arrayfields', '~> 4.7.4' # for metric_fu
41
+ gem 'fattr', '~> 2.2.0' # for metric_fu
42
+ gem 'heckle', '~> 1.4.3'
43
+ gem 'json', '~> 1.7.3' # for metric_fu rake task
44
+ gem 'map', '~> 6.2.0' # for metric_fu
45
+ gem 'metric_fu', '~> 2.1.1'
46
+ gem 'mspec', '~> 1.5.17'
47
+ gem 'rcov', '~> 1.0.0'
48
+ gem 'ruby2ruby', '= 1.2.2' # for heckle
49
+ end
50
+
51
+ platforms :ruby_19 do
52
+ gem 'simplecov', '~> 0.7.1'
34
53
  end
35
54
 
36
55
  platforms :rbx do
37
- gem 'pelusa', '~> 0.2.0'
56
+ gem 'pelusa', '~> 0.2.2'
38
57
  end
39
58
  end
data/Rakefile CHANGED
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'rubygems'
4
3
  require 'rake'
5
4
 
6
5
  FileList['tasks/**/*.rake'].each { |task| import task }
@@ -4,18 +4,19 @@ require File.expand_path('../lib/ice_nine/version', __FILE__)
4
4
 
5
5
  Gem::Specification.new do |gem|
6
6
  gem.name = 'ice_nine'
7
- gem.version = IceNine::VERSION
8
- gem.authors = [ 'Dan Kubb' ]
9
- gem.email = [ 'dan.kubb@gmail.com' ]
7
+ gem.version = IceNine::VERSION.dup
8
+ gem.authors = ['Dan Kubb']
9
+ gem.email = %w[dan.kubb@gmail.com]
10
10
  gem.description = 'Deep Freeze Ruby Objects'
11
11
  gem.summary = gem.description
12
12
  gem.homepage = 'https://github.com/dkubb/ice_nine'
13
13
 
14
- gem.require_paths = %w[ lib ]
15
- gem.files = `git ls-files`.split("\n")
16
- gem.test_files = `git ls-files -- {spec}/*`.split("\n")
17
- gem.extra_rdoc_files = %w[ LICENSE README.md TODO ]
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
+ gem.extra_rdoc_files = %w[LICENSE README.md TODO]
18
18
 
19
- gem.add_development_dependency('rake', '~> 0.9.2.2')
19
+ gem.add_development_dependency('rake', '~> 10.0.3')
20
20
  gem.add_development_dependency('rspec', '~> 1.3.2')
21
+ gem.add_development_dependency('yard', '~> 0.8.3')
21
22
  end
@@ -16,7 +16,6 @@ require 'ice_nine/freezer/nil_class'
16
16
  require 'ice_nine/freezer/numeric'
17
17
  require 'ice_nine/freezer/range'
18
18
  require 'ice_nine/freezer/rubinius'
19
- require 'ice_nine/freezer/string'
20
19
  require 'ice_nine/freezer/struct'
21
20
  require 'ice_nine/freezer/symbol'
22
21
  require 'ice_nine/freezer/true_class'
@@ -37,5 +37,7 @@ module IceNine
37
37
  private_class_method :freeze_instance_variables
38
38
 
39
39
  end # class Object
40
+
41
+ BasicObject = Object
40
42
  end # class Freezer
41
43
  end # module IceNine
@@ -3,6 +3,6 @@
3
3
  module IceNine
4
4
 
5
5
  # Current gem version
6
- VERSION = '0.5.0'
6
+ VERSION = '0.6.0'
7
7
 
8
8
  end # module IceNine
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
  require 'ice_nine'
5
+ require 'delegate'
5
6
 
6
7
  describe IceNine, '.deep_freeze' do
7
8
  subject { object.deep_freeze(value) }
@@ -142,6 +143,44 @@ describe IceNine, '.deep_freeze' do
142
143
  end
143
144
  end
144
145
 
146
+ context 'with a String' do
147
+ let(:value) { '' }
148
+
149
+ before do
150
+ value.instance_eval { @a = '1' }
151
+ end
152
+
153
+ it 'returns the object' do
154
+ should be(value)
155
+ end
156
+
157
+ it 'freezes the object' do
158
+ expect { subject }.should change(value, :frozen?).from(false).to(true)
159
+ end
160
+
161
+ it 'freezes the instance variables in the String' do
162
+ subject.instance_variable_get(:@a).should be_frozen
163
+ end
164
+
165
+ context 'with a circular reference' do
166
+ before do
167
+ value.instance_eval { @self = self }
168
+ end
169
+
170
+ it 'returns the object' do
171
+ should be(value)
172
+ end
173
+
174
+ it 'freezes the object' do
175
+ expect { subject }.should change(value, :frozen?).from(false).to(true)
176
+ end
177
+
178
+ it 'freezes the instance variables in the String' do
179
+ subject.instance_variable_get(:@a).should be_frozen
180
+ end
181
+ end
182
+ end
183
+
145
184
  context 'with a Struct' do
146
185
  let(:value) { klass.new(%w[ 1 2 ]) }
147
186
  let(:klass) { Struct.new(:a) }
@@ -177,6 +216,44 @@ describe IceNine, '.deep_freeze' do
177
216
  end
178
217
  end
179
218
 
219
+ context 'with an SimpleDelegator' do
220
+ let(:value) { SimpleDelegator.new(nil) }
221
+
222
+ before do
223
+ value.instance_eval { @a = '1' }
224
+ end
225
+
226
+ it 'returns the object' do
227
+ should be(value)
228
+ end
229
+
230
+ it 'freezes the object' do
231
+ expect { subject }.should change(value, :frozen?).from(false).to(true)
232
+ end
233
+
234
+ it 'freezes the instance variables in the SimpleDelegator' do
235
+ subject.instance_variable_get(:@a).should be_frozen
236
+ end
237
+
238
+ context 'with a circular reference' do
239
+ before do
240
+ value.instance_eval { @self = self }
241
+ end
242
+
243
+ it 'returns the object' do
244
+ should be(value)
245
+ end
246
+
247
+ it 'freezes the object' do
248
+ expect { subject }.should change(value, :frozen?).from(false).to(true)
249
+ end
250
+
251
+ it 'freezes the instance variables in the SimpleDelegator' do
252
+ subject.instance_variable_get(:@a).should be_frozen
253
+ end
254
+ end
255
+ end
256
+
180
257
  [0.0, 0, 0x7fffffffffffffff, true, false, nil, :symbol].each do |value|
181
258
  context "with a #{value.class}" do
182
259
  let(:value) { value }
@@ -4,7 +4,7 @@ require 'spec'
4
4
  require 'spec/autorun'
5
5
 
6
6
  # require spec support files and shared behavior
7
- Dir[File.expand_path('../shared/**/*.rb', __FILE__)].each do |file|
7
+ Dir[File.expand_path('../{support,shared}/**/*.rb', __FILE__)].each do |file|
8
8
  require file
9
9
  end
10
10
 
@@ -1,3 +1,3 @@
1
1
  require 'rbconfig'
2
2
 
3
- ::Config = RbConfig
3
+ ::Config = RbConfig unless defined?(::Config)
@@ -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 roodi metrics:all ]
7
+ desc 'Run metrics (except heckle) and spec'
8
+ task :metrics => %w[ spec metrics:verify_measurements metrics:flog metrics:flay metrics:reek metrics:roodi metrics:all ]
7
9
  end
@@ -7,37 +7,39 @@ begin
7
7
  config = YAML.load_file(File.expand_path('../../../config/flay.yml', __FILE__)).freeze
8
8
  threshold = config.fetch('threshold').to_i
9
9
  total_score = config.fetch('total_score').to_f
10
- files = Flay.expand_dirs_to_files(config.fetch('path', 'lib'))
10
+ files = Flay.expand_dirs_to_files(config.fetch('path', 'lib')).sort
11
11
 
12
- # original code by Marty Andrews:
13
- # http://blog.martyandrews.net/2009/05/enforcing-ruby-code-quality.html
14
- desc 'Analyze for code duplication'
15
- task :flay do
16
- # run flay once without a threshold to ensure the max mass matches the threshold
17
- flay = Flay.new(:fuzzy => false, :verbose => false, :mass => 0)
18
- flay.process(*files)
12
+ namespace :metrics do
13
+ # original code by Marty Andrews:
14
+ # http://blog.martyandrews.net/2009/05/enforcing-ruby-code-quality.html
15
+ desc 'Analyze for code duplication'
16
+ task :flay do
17
+ # run flay once without a threshold to ensure the max mass matches the threshold
18
+ flay = Flay.new(:fuzzy => false, :verbose => false, :mass => 0)
19
+ flay.process(*files)
19
20
 
20
- max = flay.masses.map { |hash, mass| mass.to_f / flay.hashes[hash].size }.max
21
- unless max.nil? || max >= threshold
22
- raise "Adjust flay threshold down to #{max}"
23
- end
21
+ max = (flay.masses.map { |hash, mass| mass.to_f / flay.hashes[hash].size }.max) || 0
22
+ unless max >= threshold
23
+ raise "Adjust flay threshold down to #{max}"
24
+ end
24
25
 
25
- total = flay.masses.reduce(0.0) { |total, (hash, mass)| total + (mass.to_f / flay.hashes[hash].size) }
26
- unless total == total_score
27
- raise "Flay total is now #{total}, but expected #{total_score}"
28
- end
26
+ total = flay.masses.reduce(0.0) { |total, (hash, mass)| total + (mass.to_f / flay.hashes[hash].size) }
27
+ unless total == total_score
28
+ raise "Flay total is now #{total}, but expected #{total_score}"
29
+ end
29
30
 
30
- # run flay a second time with the threshold set
31
- flay = Flay.new(:fuzzy => false, :verbose => false, :mass => threshold.succ)
32
- flay.process(*files)
31
+ # run flay a second time with the threshold set
32
+ flay = Flay.new(:fuzzy => false, :verbose => false, :mass => threshold.succ)
33
+ flay.process(*files)
33
34
 
34
- if flay.masses.any?
35
- flay.report
36
- raise "#{flay.masses.size} chunks of code have a duplicate mass > #{threshold}"
35
+ if flay.masses.any?
36
+ flay.report
37
+ raise "#{flay.masses.size} chunks of code have a duplicate mass > #{threshold}"
38
+ end
37
39
  end
38
40
  end
39
41
  rescue LoadError
40
42
  task :flay do
41
- abort 'Flay is not available. In order to run flay, you must: gem install flay'
43
+ $stderr.puts 'Flay is not available. In order to run flay, you must: gem install flay'
42
44
  end
43
45
  end
@@ -13,34 +13,37 @@ begin
13
13
  config = YAML.load_file(File.expand_path('../../../config/flog.yml', __FILE__)).freeze
14
14
  threshold = config.fetch('threshold').to_f.round_to(1)
15
15
 
16
- # original code by Marty Andrews:
17
- # http://blog.martyandrews.net/2009/05/enforcing-ruby-code-quality.html
18
- desc 'Analyze for code complexity'
19
- task :flog do
20
- flog = Flog.new
21
- flog.flog Array(config.fetch('path', 'lib'))
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'))
23
+
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 }
27
+
28
+ if totals.any?
29
+ max = totals.last[1]
30
+ unless max >= threshold
31
+ raise "Adjust flog score down to #{max}"
32
+ end
33
+ end
22
34
 
23
- totals = flog.totals.select { |name, score| name[-5, 5] != '#none' }.
24
- map { |name, score| [ name, score.round_to(1) ] }.
25
- sort_by { |name, score| score }
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
26
40
 
27
- last = totals.last
28
- max = last[1] if last
29
- unless max.nil? || max >= threshold
30
- raise "Adjust flog score down to #{max}"
31
- end
32
-
33
- bad_methods = totals.select { |name, score| score > threshold }
34
- if bad_methods.any?
35
- bad_methods.reverse_each do |name, score|
36
- puts '%8.1f: %s' % [ score, name ]
41
+ raise "#{bad_methods.size} methods have a flog complexity > #{threshold}"
37
42
  end
38
-
39
- raise "#{bad_methods.size} methods have a flog complexity > #{threshold}"
40
43
  end
41
44
  end
42
45
  rescue LoadError
43
46
  task :flog do
44
- abort 'Flog is not available. In order to run flog, you must: gem install flog'
47
+ $stderr.puts 'Flog is not available. In order to run flog, you must: gem install flog'
45
48
  end
46
49
  end
@@ -7,7 +7,6 @@ $LOAD_PATH.unshift(File.expand_path('../../../lib', __FILE__))
7
7
 
8
8
  begin
9
9
  require 'pathname'
10
- require 'active_support/inflector'
11
10
  require 'heckle'
12
11
  require 'mspec'
13
12
  require 'mspec/utils/name_map'
@@ -26,185 +25,183 @@ begin
26
25
  end
27
26
  end
28
27
 
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
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
34
 
35
- require 'ice_nine'
35
+ require 'ice_nine'
36
36
 
37
- root_module_regexp = Regexp.union(
38
- 'IceNine'
39
- )
37
+ root_module_regexp = Regexp.union('IceNine')
40
38
 
41
- spec_dir = Pathname('spec/unit')
39
+ spec_dir = Pathname('spec/unit')
42
40
 
43
- NameMap::MAP.each do |op, method|
44
- next if method.kind_of?(Hash)
45
- NameMap::MAP[op] = { :default => method }
46
- end
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
- aliases = Hash.new { |h,mod| h[mod] = Hash.new { |h,method| h[method] = method } }
49
- map = NameMap.new
46
+ aliases = Hash.new { |h,mod| h[mod] = Hash.new { |h,method| h[method] = method } }
47
+ map = NameMap.new
50
48
 
51
- heckle_caught_modules = Hash.new { |hash, key| hash[key] = [] }
52
- unhandled_mutations = 0
49
+ heckle_caught_modules = Hash.new { |hash, key| hash[key] = [] }
50
+ unhandled_mutations = 0
53
51
 
54
- ObjectSpace.each_object(Module) do |mod|
55
- next unless mod.name =~ /\A#{root_module_regexp}(?::|\z)/
52
+ ObjectSpace.each_object(Module) do |mod|
53
+ next unless mod.name =~ /\A#{root_module_regexp}(?::|\z)/
56
54
 
57
- spec_prefix = spec_dir.join(mod.name.underscore)
55
+ spec_prefix = spec_dir.join(mod.name.underscore)
58
56
 
59
- specs = []
57
+ specs = []
60
58
 
61
- # get the public class methods
62
- metaclass = class << mod; self end
63
- ancestors = metaclass.ancestors
59
+ # get the public class methods
60
+ metaclass = class << mod; self end
61
+ ancestors = metaclass.ancestors
64
62
 
65
- spec_class_methods = mod.singleton_methods(false)
63
+ spec_class_methods = mod.singleton_methods(false)
66
64
 
67
- spec_class_methods.reject! do |method|
68
- %w[ yaml_new yaml_tag_subclasses? included nesting constants ].include?(method.to_s)
69
- end
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
- if mod.ancestors.include?(Singleton)
72
- spec_class_methods.reject! { |method| method.to_s == 'instance' }
73
- end
69
+ if mod.ancestors.include?(Singleton)
70
+ spec_class_methods.reject! { |method| method.to_s == 'instance' }
71
+ end
74
72
 
75
- # get the protected and private class methods
76
- other_class_methods = metaclass.protected_instance_methods(false) |
77
- metaclass.private_instance_methods(false)
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
- ancestors.each do |ancestor|
80
- other_class_methods -= ancestor.protected_instance_methods(false) |
81
- ancestor.private_instance_methods(false)
82
- end
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
- other_class_methods.reject! do |method|
85
- method.to_s == 'allocate' || SKIP_METHODS.include?(method.to_s)
86
- end
82
+ other_class_methods.reject! do |method|
83
+ method.to_s == 'allocate' || SKIP_METHODS.include?(method.to_s)
84
+ end
87
85
 
88
- other_class_methods.reject! do |method|
89
- next unless spec_class_methods.any? { |specced| specced.to_s == $1 }
86
+ other_class_methods.reject! do |method|
87
+ next unless spec_class_methods.any? { |specced| specced.to_s == $1 }
90
88
 
91
- spec_class_methods << method
92
- end
89
+ spec_class_methods << method
90
+ end
93
91
 
94
- spec_class_methods -= other_class_methods
92
+ spec_class_methods -= other_class_methods
95
93
 
96
- # get the instances methods
97
- spec_methods = mod.public_instance_methods(false)
94
+ # get the instances methods
95
+ spec_methods = mod.public_instance_methods(false)
98
96
 
99
- other_methods = mod.protected_instance_methods(false) |
100
- mod.private_instance_methods(false)
97
+ other_methods = mod.protected_instance_methods(false) |
98
+ mod.private_instance_methods(false)
101
99
 
102
- other_methods.reject! do |method|
103
- next unless spec_methods.any? { |specced| specced.to_s == $1 }
100
+ other_methods.reject! do |method|
101
+ next unless spec_methods.any? { |specced| specced.to_s == $1 }
104
102
 
105
- spec_methods << method
106
- end
103
+ spec_methods << method
104
+ end
107
105
 
108
- # map the class methods to spec files
109
- spec_class_methods.each do |method|
110
- method = aliases[mod.name][method]
111
- next if SKIP_METHODS.include?(method.to_s)
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)
112
110
 
113
- spec_file = spec_prefix.join('class_methods').join(map.file_name(method, mod.name))
111
+ spec_file = spec_prefix.join('class_methods').join(map.file_name(method, mod.name))
114
112
 
115
- unless spec_file.file?
116
- raise "No spec file #{spec_file} for #{mod}.#{method}"
117
- next
113
+ unless spec_file.file?
114
+ raise "No spec file #{spec_file} for #{mod}.#{method}"
115
+ end
116
+
117
+ specs << [ ".#{method}", [ spec_file ] ]
118
118
  end
119
119
 
120
- specs << [ ".#{method}", [ spec_file ] ]
121
- end
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)
122
124
 
123
- # map the instance methods to spec files
124
- spec_methods.each do |method|
125
- method = aliases[mod.name][method]
126
- next if SKIP_METHODS.include?(method.to_s)
125
+ spec_file = spec_prefix.join(map.file_name(method, mod.name))
127
126
 
128
- spec_file = spec_prefix.join(map.file_name(method, mod.name))
127
+ unless spec_file.file?
128
+ raise "No spec file #{spec_file} for #{mod}##{method}"
129
+ end
129
130
 
130
- unless spec_file.file?
131
- raise "No spec file #{spec_file} for #{mod}##{method}"
132
- next
131
+ specs << [ "##{method}", [ spec_file ] ]
133
132
  end
134
133
 
135
- specs << [ "##{method}", [ spec_file ] ]
136
- end
137
-
138
- # non-public methods are considered covered if they can be mutated
139
- # and any spec fails for the current or descendant modules
140
- other_methods.each do |method|
141
- descedant_specs = []
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 = []
142
138
 
143
- ObjectSpace.each_object(Module) do |descedant|
144
- next unless descedant.name =~ /\A#{root_module_regexp}(?::|\z)/ && mod >= descedant
145
- descedant_spec_prefix = spec_dir.join(descedant.name.underscore)
146
- descedant_specs << descedant_spec_prefix
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
147
143
 
148
- if method.to_s == 'initialize'
149
- 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
150
147
  end
148
+
149
+ specs << [ "##{method}", descedant_specs ]
151
150
  end
152
151
 
153
- specs << [ "##{method}", descedant_specs ]
154
- end
152
+ other_class_methods.each do |method|
153
+ descedant_specs = []
155
154
 
156
- other_class_methods.each do |method|
157
- descedant_specs = []
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
158
159
 
159
- ObjectSpace.each_object(Module) do |descedant|
160
- next unless descedant.name =~ /\A#{root_module_regexp}(?::|\z)/ && mod >= descedant
161
- descedant_specs << spec_dir.join(descedant.name.underscore).join('class_methods')
160
+ specs << [ ".#{method}", descedant_specs ]
162
161
  end
163
162
 
164
- specs << [ ".#{method}", descedant_specs ]
165
- end
166
-
167
- specs.sort.each do |(method, spec_files)|
168
- puts "Heckling #{mod}#{method}"
169
- IO.popen("spec #{spec_files.join(' ')} --heckle '#{mod}#{method}'") do |pipe|
170
- while line = pipe.gets
171
- case line = line.chomp
172
- when "The following mutations didn't cause test failures:"
173
- heckle_caught_modules[mod.name] << method
174
- when '+++ mutation'
175
- 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
176
173
  end
177
174
  end
178
175
  end
179
176
  end
180
- end
181
177
 
182
- if unhandled_mutations > 0
183
- error_message_lines = [ "*************\n" ]
178
+ if unhandled_mutations > 0
179
+ error_message_lines = [ "*************\n" ]
184
180
 
185
- error_message_lines << "Heckle found #{unhandled_mutations} " \
186
- "mutation#{"s" unless unhandled_mutations == 1} " \
187
- "that didn't cause spec violations\n"
181
+ error_message_lines << "Heckle found #{unhandled_mutations} " \
182
+ "mutation#{"s" unless unhandled_mutations == 1} " \
183
+ "that didn't cause spec violations\n"
188
184
 
189
- heckle_caught_modules.each do |mod, methods|
190
- error_message_lines << "#{mod} contains the following " \
191
- 'poorly-specified methods:'
192
- methods.each do |method|
193
- error_message_lines << " - #{method}"
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 << ''
194
192
  end
195
- error_message_lines << ''
196
- end
197
193
 
198
- error_message_lines << 'Get your act together and come back ' \
199
- 'when your specs are doing their job!'
194
+ error_message_lines << 'Get your act together and come back ' \
195
+ 'when your specs are doing their job!'
200
196
 
201
- raise error_message_lines.join("\n")
202
- else
203
- puts 'Well done! Your code withstood a heckling.'
197
+ raise error_message_lines.join("\n")
198
+ else
199
+ puts 'Well done! Your code withstood a heckling.'
200
+ end
204
201
  end
205
202
  end
206
203
  rescue LoadError
207
- task :heckle do
208
- abort 'Heckle or mspec is not available. In order to run heckle, you must: gem install heckle mspec'
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'
209
206
  end
210
207
  end
@@ -25,7 +25,7 @@ begin
25
25
  rescue LoadError
26
26
  namespace :metrics do
27
27
  task :all do
28
- abort 'metric_fu is not available. In order to run metrics:all, you must: gem install metric_fu'
28
+ $stderr.puts 'metric_fu is not available. In order to run metrics:all, you must: gem install metric_fu'
29
29
  end
30
30
  end
31
31
  end
@@ -3,9 +3,19 @@
3
3
  begin
4
4
  require 'reek/rake/task'
5
5
 
6
- Reek::Rake::Task.new
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
7
17
  rescue LoadError
8
18
  task :reek do
9
- abort "Reek is not available. In order to run reek, you must: gem install reek"
19
+ $stderr.puts 'Reek is not available. In order to run reek, you must: gem install reek'
10
20
  end
11
21
  end
@@ -5,13 +5,15 @@ begin
5
5
  require 'rake/tasklib'
6
6
  require 'roodi_task'
7
7
 
8
- RoodiTask.new do |t|
9
- t.verbose = false
10
- t.config = File.expand_path('../../../config/roodi.yml', __FILE__)
11
- t.patterns = %w[ lib/**/*.rb ]
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
12
14
  end
13
15
  rescue LoadError
14
16
  task :roodi do
15
- abort 'Roodi is not available. In order to run roodi, you must: gem install roodi'
17
+ $stderr.puts 'Roodi is not available. In order to run roodi, you must: gem install roodi'
16
18
  end
17
19
  end
@@ -1,25 +1,25 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  begin
4
- require 'pathname'
5
- require 'yardstick'
6
4
  require 'yardstick/rake/measurement'
7
5
  require 'yardstick/rake/verify'
8
6
  require 'yaml'
9
7
 
10
8
  config = YAML.load_file(File.expand_path('../../../config/yardstick.yml', __FILE__))
11
9
 
12
- # yardstick_measure task
13
- Yardstick::Rake::Measurement.new
10
+ namespace :metrics do
11
+ # yardstick_measure task
12
+ Yardstick::Rake::Measurement.new
14
13
 
15
- # verify_measurements task
16
- Yardstick::Rake::Verify.new do |verify|
17
- verify.threshold = config.fetch('threshold')
14
+ # verify_measurements task
15
+ Yardstick::Rake::Verify.new do |verify|
16
+ verify.threshold = config.fetch('threshold')
17
+ end
18
18
  end
19
19
  rescue LoadError
20
20
  %w[ yardstick_measure verify_measurements ].each do |name|
21
21
  task name.to_s do
22
- abort "Yardstick is not available. In order to run #{name}, you must: gem install yardstick"
22
+ $stderr.puts "Yardstick is not available. In order to run #{name}, you must: gem install yardstick"
23
23
  end
24
24
  end
25
25
  end
@@ -1,5 +1,10 @@
1
1
  # encoding: utf-8
2
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
+
3
8
  begin
4
9
  require 'spec/rake/spectask'
5
10
 
@@ -7,42 +12,49 @@ begin
7
12
  task :spec => %w[ spec:unit spec:integration ]
8
13
 
9
14
  namespace :spec do
10
- Spec::Rake::SpecTask.new(:integration) do |t|
11
- t.ruby_opts = %w[ -r./spec/support/config_alias ]
12
- t.pattern = 'spec/integration/**/*_spec.rb'
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'
13
19
  end
14
20
 
15
- Spec::Rake::SpecTask.new(:unit) do |t|
16
- t.ruby_opts = %w[ -r./spec/support/config_alias ]
17
- t.pattern = 'spec/unit/**/*_spec.rb'
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'
18
25
  end
19
26
  end
20
27
  rescue LoadError
21
- task :spec do
22
- abort 'rspec is not available. In order to run spec, you must: gem install rspec'
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
23
32
  end
24
33
  end
25
34
 
26
- begin
27
- if RUBY_VERSION < '1.9'
28
- desc 'Generate code coverage'
29
- Spec::Rake::SpecTask.new(:coverage) do |t|
30
- t.rcov = true
31
- t.pattern = 'spec/unit/**/*_spec.rb'
32
- t.rcov_opts = File.read('spec/rcov.opts').split(/\s+/)
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
33
51
  end
34
- else
35
- desc 'Generate code coverage'
52
+ rescue LoadError
36
53
  task :coverage do
37
- ENV['COVERAGE'] = 'true'
38
- Rake::Task['spec:unit'].execute
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}"
39
56
  end
40
57
  end
41
- rescue LoadError
42
- task :coverage do
43
- lib = RUBY_VERSION < '1.9' ? 'rcov' : 'simplecov'
44
- abort "coverage is not available. In order to run #{lib}, you must: gem install #{lib}"
45
- end
46
58
  end
47
59
 
48
- task :test => 'spec'
60
+ task :test => :spec
@@ -6,6 +6,6 @@ begin
6
6
  YARD::Rake::YardocTask.new
7
7
  rescue LoadError
8
8
  task :yard do
9
- abort 'YARD is not available. In order to run yard, you must: gem install yard'
9
+ $stderr.puts 'YARD is not available. In order to run yard, you must: gem install yard'
10
10
  end
11
11
  end
metadata CHANGED
@@ -1,58 +1,82 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: ice_nine
3
- version: !ruby/object:Gem::Version
4
- version: 0.5.0
3
+ version: !ruby/object:Gem::Version
4
+ hash: 7
5
5
  prerelease:
6
+ segments:
7
+ - 0
8
+ - 6
9
+ - 0
10
+ version: 0.6.0
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Dan Kubb
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2012-10-25 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
17
+
18
+ date: 2012-12-20 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
15
21
  name: rake
16
- requirement: !ruby/object:Gem::Requirement
17
- none: false
18
- requirements:
19
- - - ~>
20
- - !ruby/object:Gem::Version
21
- version: 0.9.2.2
22
- type: :development
23
22
  prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
23
+ requirement: &id001 !ruby/object:Gem::Requirement
25
24
  none: false
26
- requirements:
25
+ requirements:
27
26
  - - ~>
28
- - !ruby/object:Gem::Version
29
- version: 0.9.2.2
30
- - !ruby/object:Gem::Dependency
27
+ - !ruby/object:Gem::Version
28
+ hash: 73
29
+ segments:
30
+ - 10
31
+ - 0
32
+ - 3
33
+ version: 10.0.3
34
+ type: :development
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
31
37
  name: rspec
32
- requirement: !ruby/object:Gem::Requirement
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
33
40
  none: false
34
- requirements:
41
+ requirements:
35
42
  - - ~>
36
- - !ruby/object:Gem::Version
43
+ - !ruby/object:Gem::Version
44
+ hash: 31
45
+ segments:
46
+ - 1
47
+ - 3
48
+ - 2
37
49
  version: 1.3.2
38
50
  type: :development
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
53
+ name: yard
39
54
  prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
55
+ requirement: &id003 !ruby/object:Gem::Requirement
41
56
  none: false
42
- requirements:
57
+ requirements:
43
58
  - - ~>
44
- - !ruby/object:Gem::Version
45
- version: 1.3.2
59
+ - !ruby/object:Gem::Version
60
+ hash: 57
61
+ segments:
62
+ - 0
63
+ - 8
64
+ - 3
65
+ version: 0.8.3
66
+ type: :development
67
+ version_requirements: *id003
46
68
  description: Deep Freeze Ruby Objects
47
- email:
69
+ email:
48
70
  - dan.kubb@gmail.com
49
71
  executables: []
72
+
50
73
  extensions: []
51
- extra_rdoc_files:
74
+
75
+ extra_rdoc_files:
52
76
  - LICENSE
53
77
  - README.md
54
78
  - TODO
55
- files:
79
+ files:
56
80
  - .gitignore
57
81
  - .pelusa.yml
58
82
  - .rvmrc
@@ -82,7 +106,6 @@ files:
82
106
  - lib/ice_nine/freezer/object.rb
83
107
  - lib/ice_nine/freezer/range.rb
84
108
  - lib/ice_nine/freezer/rubinius.rb
85
- - lib/ice_nine/freezer/string.rb
86
109
  - lib/ice_nine/freezer/struct.rb
87
110
  - lib/ice_nine/freezer/symbol.rb
88
111
  - lib/ice_nine/freezer/true_class.rb
@@ -120,27 +143,37 @@ files:
120
143
  - tasks/yard.rake
121
144
  homepage: https://github.com/dkubb/ice_nine
122
145
  licenses: []
146
+
123
147
  post_install_message:
124
148
  rdoc_options: []
125
- require_paths:
149
+
150
+ require_paths:
126
151
  - lib
127
- required_ruby_version: !ruby/object:Gem::Requirement
152
+ required_ruby_version: !ruby/object:Gem::Requirement
128
153
  none: false
129
- requirements:
130
- - - ! '>='
131
- - !ruby/object:Gem::Version
132
- version: '0'
133
- required_rubygems_version: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - ">="
156
+ - !ruby/object:Gem::Version
157
+ hash: 3
158
+ segments:
159
+ - 0
160
+ version: "0"
161
+ required_rubygems_version: !ruby/object:Gem::Requirement
134
162
  none: false
135
- requirements:
136
- - - ! '>='
137
- - !ruby/object:Gem::Version
138
- version: '0'
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ hash: 3
167
+ segments:
168
+ - 0
169
+ version: "0"
139
170
  requirements: []
171
+
140
172
  rubyforge_project:
141
173
  rubygems_version: 1.8.24
142
174
  signing_key:
143
175
  specification_version: 3
144
176
  summary: Deep Freeze Ruby Objects
145
177
  test_files: []
178
+
146
179
  has_rdoc:
@@ -1,10 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module IceNine
4
- class Freezer
5
-
6
- # A freezer class for handling String objects
7
- class String < Object; end
8
-
9
- end # class Freezer
10
- end # module IceNine