ice_nine 0.1.0 → 0.2.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.
- data/Gemfile +16 -9
- data/README.md +7 -0
- data/config/flay.yml +1 -1
- data/config/roodi.yml +3 -3
- data/config/site.reek +1 -1
- data/lib/ice_nine.rb +9 -36
- data/lib/ice_nine/core_ext/object.rb +28 -0
- data/lib/ice_nine/freezer.rb +19 -46
- data/lib/ice_nine/freezer/array.rb +3 -3
- data/lib/ice_nine/freezer/hash.rb +3 -3
- data/lib/ice_nine/freezer/object.rb +41 -0
- data/lib/ice_nine/freezer/range.rb +1 -1
- data/lib/ice_nine/freezer/struct.rb +3 -3
- data/lib/ice_nine/support/recursion_guard.rb +45 -0
- data/lib/ice_nine/version.rb +1 -1
- data/spec/spec_helper.rb +13 -9
- data/spec/unit/ice_nine/class_methods/deep_freeze_spec.rb +3 -3
- data/spec/unit/ice_nine/freezer/array/class_methods/deep_freeze_spec.rb +1 -1
- data/spec/unit/ice_nine/freezer/class_methods/element_reference_spec.rb +1 -1
- data/spec/unit/ice_nine/freezer/numeric/class_methods/deep_freeze_spec.rb +1 -1
- data/spec/unit/ice_nine/freezer/{class_methods → object/class_methods}/deep_freeze_spec.rb +1 -1
- data/spec/unit/ice_nine/recursion_guard/class_methods/guard_spec.rb +33 -0
- data/spec/unit/object/deep_freeze_spec.rb +19 -0
- data/tasks/metrics/heckle.rake +2 -2
- data/tasks/spec.rake +19 -19
- metadata +10 -5
data/Gemfile
CHANGED
@@ -1,18 +1,25 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
source
|
3
|
+
source 'https://rubygems.org'
|
4
4
|
|
5
5
|
gemspec
|
6
6
|
|
7
7
|
group :metrics do
|
8
|
-
gem 'fattr',
|
9
|
-
gem 'arrayfields',
|
10
|
-
gem 'flay',
|
11
|
-
gem 'flog',
|
12
|
-
gem 'map',
|
13
|
-
gem 'reek',
|
14
|
-
gem 'roodi',
|
15
|
-
gem '
|
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', :git => 'git://github.com/dkubb/reek.git'
|
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'
|
22
|
+
end
|
16
23
|
|
17
24
|
platforms :mri_18, :rbx do
|
18
25
|
gem 'heckle', '~> 1.4.3'
|
data/README.md
CHANGED
@@ -7,12 +7,19 @@ Deep Freeze Ruby Objects
|
|
7
7
|
## Usage
|
8
8
|
|
9
9
|
```ruby
|
10
|
+
# Freezes most objects
|
10
11
|
hash = IceNine.deep_freeze('a' => '1')
|
11
12
|
array = IceNine.deep_freeze([ 'a', 'b', 'c' ])
|
12
13
|
range = IceNine.deep_freeze('a'..'z')
|
13
14
|
struct = IceNine.deep_freeze(Struct.new(:a, :b).new('a', 'b'))
|
14
15
|
object = IceNine.deep_freeze(Object.new)
|
15
16
|
user = IceNine.deep_freeze(Application::User.new('dkubb'))
|
17
|
+
|
18
|
+
# Add core extension for Object#deep_freeze (not required by default)
|
19
|
+
require 'ice_nine/core_ext/object'
|
20
|
+
|
21
|
+
object = Object.new
|
22
|
+
object.deep_freeze
|
16
23
|
```
|
17
24
|
|
18
25
|
## Installation
|
data/config/flay.yml
CHANGED
data/config/roodi.yml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
|
-
AbcMetricMethodCheck: { score:
|
2
|
+
AbcMetricMethodCheck: { score: 1 }
|
3
3
|
AssignmentInConditionalCheck: { }
|
4
4
|
CaseMissingElseCheck: { }
|
5
5
|
ClassLineCountCheck: { line_count: 88 }
|
6
6
|
ClassNameCheck: { pattern: !ruby/regexp /\A(?:[A-Z]+|[A-Z][a-z](?:[A-Z]?[a-z])+)\z/ }
|
7
7
|
ClassVariableCheck: { }
|
8
8
|
CyclomaticComplexityBlockCheck: { complexity: 3 }
|
9
|
-
CyclomaticComplexityMethodCheck: { complexity:
|
9
|
+
CyclomaticComplexityMethodCheck: { complexity: 1 }
|
10
10
|
EmptyRescueBodyCheck: { }
|
11
11
|
ForLoopCheck: { }
|
12
|
-
MethodLineCountCheck: { line_count:
|
12
|
+
MethodLineCountCheck: { line_count: 1 }
|
13
13
|
MethodNameCheck: { pattern: !ruby/regexp /\A(?:[a-z\d](?:_?[a-z\d])+[?!=]?|\[\]=?|==|<=>|<<|[+*&|-])\z/ }
|
14
14
|
ModuleLineCountCheck: { line_count: 92 }
|
15
15
|
ModuleNameCheck: { pattern: !ruby/regexp /\A(?:[A-Z]+|[A-Z][a-z](?:[A-Z]?[a-z])+)\z/ }
|
data/config/site.reek
CHANGED
data/lib/ice_nine.rb
CHANGED
@@ -1,12 +1,19 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
require 'ice_nine/support/recursion_guard'
|
6
|
+
|
3
7
|
require 'ice_nine/freezer'
|
8
|
+
require 'ice_nine/freezer/object'
|
9
|
+
|
4
10
|
require 'ice_nine/freezer/array'
|
5
11
|
require 'ice_nine/freezer/hash'
|
6
|
-
require 'ice_nine/freezer/no_freeze'
|
7
12
|
require 'ice_nine/freezer/range'
|
8
13
|
require 'ice_nine/freezer/struct'
|
9
14
|
|
15
|
+
require 'ice_nine/freezer/no_freeze'
|
16
|
+
|
10
17
|
require 'ice_nine/version'
|
11
18
|
|
12
19
|
# Base IceNine module
|
@@ -23,43 +30,9 @@ module IceNine
|
|
23
30
|
#
|
24
31
|
# @api public
|
25
32
|
def self.deep_freeze(object)
|
26
|
-
|
33
|
+
RecursionGuard.guard(object.object_id) do
|
27
34
|
Freezer[object.class].deep_freeze(object)
|
28
35
|
end
|
29
|
-
object
|
30
36
|
end
|
31
37
|
|
32
|
-
# Guard the system from recursive freezing
|
33
|
-
#
|
34
|
-
# @param [String] key
|
35
|
-
#
|
36
|
-
# @return [undefined]
|
37
|
-
#
|
38
|
-
# @api private
|
39
|
-
def self.recursion_guard(key)
|
40
|
-
thread = Thread.current
|
41
|
-
return if thread[key]
|
42
|
-
begin
|
43
|
-
thread[key] = true
|
44
|
-
yield
|
45
|
-
ensure
|
46
|
-
thread[key] = nil
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
private_class_method :recursion_guard
|
51
|
-
|
52
|
-
# Create a unique key to guard against recursively deep freezing the object
|
53
|
-
#
|
54
|
-
# @param [#object_id]
|
55
|
-
#
|
56
|
-
# @return [String]
|
57
|
-
#
|
58
|
-
# @api private
|
59
|
-
def self.recursion_guard_key(object)
|
60
|
-
"__ice_nine_deep_freeze_#{object.object_id}"
|
61
|
-
end
|
62
|
-
|
63
|
-
private_class_method :recursion_guard_key
|
64
|
-
|
65
38
|
end # module IceNine
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module IceNine
|
4
|
+
|
5
|
+
# Core Ruby extensions
|
6
|
+
module CoreExt
|
7
|
+
|
8
|
+
# Extend Object with deep freezing
|
9
|
+
module Object
|
10
|
+
|
11
|
+
# Deep freeze an object
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# object = object.deep_freeze
|
15
|
+
#
|
16
|
+
# @return [self]
|
17
|
+
#
|
18
|
+
# @api public
|
19
|
+
def deep_freeze
|
20
|
+
IceNine.deep_freeze(self)
|
21
|
+
end
|
22
|
+
|
23
|
+
end #module Object
|
24
|
+
end # module CoreExt
|
25
|
+
end # module IceNine
|
26
|
+
|
27
|
+
# Add Object#deep_freeze
|
28
|
+
Object.instance_eval { include IceNine::CoreExt::Object }
|
data/lib/ice_nine/freezer.rb
CHANGED
@@ -6,9 +6,9 @@ module IceNine
|
|
6
6
|
class Freezer
|
7
7
|
|
8
8
|
# Configure const_get and const_defined? to not search ancestors
|
9
|
-
SKIP_ANCESTORS = (RUBY_VERSION < '1.9' ? [] : [
|
9
|
+
SKIP_ANCESTORS = (RUBY_VERSION < '1.9' ? [] : [false]).freeze
|
10
10
|
|
11
|
-
#
|
11
|
+
# Look up the Freezer descendant by object type
|
12
12
|
#
|
13
13
|
# @example
|
14
14
|
# freezer_class = IceNine::Freezer[mod]
|
@@ -20,52 +20,38 @@ module IceNine
|
|
20
20
|
# @api public
|
21
21
|
def self.[](mod)
|
22
22
|
mod.ancestors.each do |ancestor|
|
23
|
-
|
24
|
-
freezer = find(name) unless name.empty? # skip anonymous modules
|
23
|
+
freezer = find(ancestor.name.to_s)
|
25
24
|
return freezer if freezer
|
26
25
|
end
|
27
26
|
end
|
28
27
|
|
29
|
-
#
|
28
|
+
# Find a Freezer descendant by name
|
30
29
|
#
|
31
|
-
# @
|
32
|
-
# object = IceNine.deep_freeze(Object.new)
|
33
|
-
#
|
34
|
-
# @param [Object] object
|
35
|
-
#
|
36
|
-
# @return [Object]
|
37
|
-
#
|
38
|
-
# @api public
|
39
|
-
def self.deep_freeze(object)
|
40
|
-
freeze_instance_variables(object)
|
41
|
-
object.freeze
|
42
|
-
end
|
43
|
-
|
44
|
-
# Find a Freezer subclass by name
|
45
|
-
#
|
46
|
-
# @param [String] mod_name
|
30
|
+
# @param [String] name
|
47
31
|
#
|
48
32
|
# @return [Class<Freezer>]
|
33
|
+
# returned if a matching freezer is found
|
34
|
+
# @return [nil]
|
35
|
+
# returned if no matching freezer is found
|
49
36
|
#
|
50
37
|
# @api private
|
51
|
-
def self.find(
|
52
|
-
|
53
|
-
|
54
|
-
|
38
|
+
def self.find(name)
|
39
|
+
freezer = name.split('::').reduce(self) do |mod, const|
|
40
|
+
mod.const_lookup(const) or break mod
|
41
|
+
end
|
42
|
+
freezer if freezer < self # only return a descendant freezer
|
55
43
|
end
|
56
44
|
|
57
|
-
|
58
|
-
protected :find
|
59
|
-
end
|
45
|
+
private_class_method :find
|
60
46
|
|
61
|
-
#
|
47
|
+
# Look up a constant in the namespace
|
62
48
|
#
|
63
49
|
# @param [String] namespace
|
64
50
|
#
|
65
51
|
# @return [Module]
|
66
|
-
# returned if a matching
|
52
|
+
# returned if a matching constant is found
|
67
53
|
# @return [nil]
|
68
|
-
# returned if no
|
54
|
+
# returned if no matching constant is found
|
69
55
|
#
|
70
56
|
# @api private
|
71
57
|
def self.const_lookup(namespace)
|
@@ -74,22 +60,9 @@ module IceNine
|
|
74
60
|
end
|
75
61
|
end
|
76
62
|
|
77
|
-
|
78
|
-
|
79
|
-
# Handle freezing the object's instance variables
|
80
|
-
#
|
81
|
-
# @param [Object] object
|
82
|
-
#
|
83
|
-
# @return [undefined]
|
84
|
-
#
|
85
|
-
# @api private
|
86
|
-
def self.freeze_instance_variables(object)
|
87
|
-
object.instance_variables.each do |ivar_name|
|
88
|
-
IceNine.deep_freeze(object.instance_variable_get(ivar_name))
|
89
|
-
end
|
63
|
+
class << self
|
64
|
+
protected :const_lookup
|
90
65
|
end
|
91
66
|
|
92
|
-
private_class_method :freeze_instance_variables
|
93
|
-
|
94
67
|
end # class Freezer
|
95
68
|
end # module IceNine
|
@@ -4,13 +4,13 @@ module IceNine
|
|
4
4
|
class Freezer
|
5
5
|
|
6
6
|
# A freezer class for handling Array objects
|
7
|
-
class Array <
|
7
|
+
class Array < Object
|
8
8
|
|
9
9
|
# Deep Freeze an Array
|
10
10
|
#
|
11
11
|
# @example
|
12
|
-
# array = IceNine:Freezer::Array.deep_freeze(%w[
|
13
|
-
# array.select(&:frozen?) # => [
|
12
|
+
# array = IceNine:Freezer::Array.deep_freeze(%w[a b c])
|
13
|
+
# array.select(&:frozen?) # => ['a', 'b', 'c']
|
14
14
|
#
|
15
15
|
# @param [Array] array
|
16
16
|
#
|
@@ -4,14 +4,14 @@ module IceNine
|
|
4
4
|
class Freezer
|
5
5
|
|
6
6
|
# A freezer class for handling Hash objects
|
7
|
-
class Hash <
|
7
|
+
class Hash < Object
|
8
8
|
|
9
9
|
# Deep Freeze a Hash
|
10
10
|
#
|
11
11
|
# @example
|
12
12
|
# hash = IceNine::Freezer::Hash.deep_freeze('a' => '1', 'b' => '2')
|
13
|
-
# hash.keys.select(&:frozen?) # => [
|
14
|
-
# hash.values.select(&:frozen?) # => [
|
13
|
+
# hash.keys.select(&:frozen?) # => ['a', 'b']
|
14
|
+
# hash.values.select(&:frozen?) # => ['1', '2']
|
15
15
|
#
|
16
16
|
# @param [Hash] hash
|
17
17
|
#
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module IceNine
|
4
|
+
class Freezer
|
5
|
+
|
6
|
+
# A freezer class for handling Object instances
|
7
|
+
class Object < self
|
8
|
+
|
9
|
+
# Deep Freeze an object
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# object = IceNine.deep_freeze(Object.new)
|
13
|
+
#
|
14
|
+
# @param [Object] object
|
15
|
+
#
|
16
|
+
# @return [Object]
|
17
|
+
#
|
18
|
+
# @api public
|
19
|
+
def self.deep_freeze(object)
|
20
|
+
freeze_instance_variables(object)
|
21
|
+
object.freeze
|
22
|
+
end
|
23
|
+
|
24
|
+
# Handle freezing the object's instance variables
|
25
|
+
#
|
26
|
+
# @param [Object] object
|
27
|
+
#
|
28
|
+
# @return [undefined]
|
29
|
+
#
|
30
|
+
# @api private
|
31
|
+
def self.freeze_instance_variables(object)
|
32
|
+
object.instance_variables.each do |ivar_name|
|
33
|
+
IceNine.deep_freeze(object.instance_variable_get(ivar_name))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private_class_method :freeze_instance_variables
|
38
|
+
|
39
|
+
end # class Object
|
40
|
+
end # class Freezer
|
41
|
+
end # module IceNine
|
@@ -4,19 +4,19 @@ module IceNine
|
|
4
4
|
class Freezer
|
5
5
|
|
6
6
|
# A freezer class for handling Struct objects
|
7
|
-
class Struct <
|
7
|
+
class Struct < Object
|
8
8
|
|
9
9
|
# Deep Freeze a Struct
|
10
10
|
#
|
11
11
|
# @example
|
12
12
|
# struct = IceNine:Freezer::Struct.deep_freeze(klass.new('1'))
|
13
|
-
# struct.values.select(&:frozen?) # => [
|
13
|
+
# struct.values.select(&:frozen?) # => ['1']
|
14
14
|
#
|
15
15
|
# @param [Struct] struct
|
16
16
|
#
|
17
17
|
# @return [Struct]
|
18
18
|
#
|
19
|
-
# @todo use super on Struct#each once it returns self in
|
19
|
+
# @todo use super on Struct#each once it returns self in Rubinius
|
20
20
|
#
|
21
21
|
# @api public
|
22
22
|
def self.deep_freeze(struct)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module IceNine
|
4
|
+
|
5
|
+
# Protect against infinite recursion
|
6
|
+
module RecursionGuard
|
7
|
+
|
8
|
+
# Guard against recursively calling a block with the same object
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# IceNine::RecursionGuard.guard(object_id) do
|
12
|
+
# logic_which_may_recursively_call_the_containing_method
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# @param [Integer] object_id
|
16
|
+
#
|
17
|
+
# @return [Object]
|
18
|
+
#
|
19
|
+
# @api public
|
20
|
+
def self.guard(object_id)
|
21
|
+
objects = guarded_objects(caller.first)
|
22
|
+
return if objects.include?(object_id)
|
23
|
+
begin
|
24
|
+
objects << object_id
|
25
|
+
yield
|
26
|
+
ensure
|
27
|
+
objects.delete(object_id)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# The current objects guarded at a specific location in the source
|
32
|
+
#
|
33
|
+
# @param [String] location
|
34
|
+
#
|
35
|
+
# @return [Set<Integer>]
|
36
|
+
#
|
37
|
+
# @api private
|
38
|
+
def self.guarded_objects(location)
|
39
|
+
Thread.current[location] ||= Set.new
|
40
|
+
end
|
41
|
+
|
42
|
+
private_class_method :guarded_objects
|
43
|
+
|
44
|
+
end # RecursionGuard
|
45
|
+
end # module IceNine
|
data/lib/ice_nine/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,18 +1,22 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'spec'
|
4
|
+
require 'spec/autorun'
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
require 'spec' # try for RSpec 1
|
9
|
-
RSpec = Spec::Runner
|
6
|
+
# require spec support files and shared behavior
|
7
|
+
Dir[File.expand_path('../shared/**/*.rb', __FILE__)].each do |file|
|
8
|
+
require file
|
10
9
|
end
|
11
10
|
|
12
|
-
|
13
|
-
|
11
|
+
Spec::Runner.configure do |config|
|
12
|
+
end
|
14
13
|
|
15
|
-
|
14
|
+
if RUBY_VERSION >= '1.9' and ENV['COVERAGE'] == 'true'
|
15
|
+
require 'simplecov'
|
16
|
+
SimpleCov.start do
|
17
|
+
command_name 'spec:unit'
|
18
|
+
add_filter 'spec'
|
19
|
+
end
|
16
20
|
end
|
17
21
|
|
18
22
|
# change the heckle timeout to be 5 seconds
|
@@ -6,7 +6,7 @@ require 'ice_nine'
|
|
6
6
|
describe IceNine, '.deep_freeze' do
|
7
7
|
subject { object.deep_freeze(value) }
|
8
8
|
|
9
|
-
let(:object) {
|
9
|
+
let(:object) { IceNine }
|
10
10
|
|
11
11
|
context 'with an Object' do
|
12
12
|
let(:value) { Object.new }
|
@@ -47,7 +47,7 @@ describe IceNine, '.deep_freeze' do
|
|
47
47
|
end
|
48
48
|
|
49
49
|
context 'with an Array' do
|
50
|
-
let(:value) { %w[
|
50
|
+
let(:value) { %w[a] }
|
51
51
|
|
52
52
|
it 'returns the object' do
|
53
53
|
should be(value)
|
@@ -177,7 +177,7 @@ describe IceNine, '.deep_freeze' do
|
|
177
177
|
end
|
178
178
|
end
|
179
179
|
|
180
|
-
[
|
180
|
+
[0.0, 0, 0x7fffffffffffffff, true, false, nil, :symbol].each do |value|
|
181
181
|
context "with a #{value.class}" do
|
182
182
|
let(:value) { value }
|
183
183
|
|
@@ -8,7 +8,7 @@ describe IceNine::Freezer::Numeric, '.deep_freeze' do
|
|
8
8
|
|
9
9
|
let(:object) { described_class }
|
10
10
|
|
11
|
-
[
|
11
|
+
[0.0, 0, 0x7fffffffffffffff].each do |value|
|
12
12
|
context "with a #{value.class} object" do
|
13
13
|
let(:value) { value }
|
14
14
|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'ice_nine/support/recursion_guard'
|
5
|
+
|
6
|
+
describe IceNine::RecursionGuard, '.guard' do
|
7
|
+
subject { object.guard(object_id, &method(:block)) }
|
8
|
+
|
9
|
+
let(:object) { IceNine::RecursionGuard }
|
10
|
+
let(:object_id) { 1 }
|
11
|
+
let(:return_value) { stub('return_value') }
|
12
|
+
|
13
|
+
context 'when the block is not recursive' do
|
14
|
+
def block
|
15
|
+
return_value
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'returns the expected value' do
|
19
|
+
should equal(return_value)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when the block is recursive' do
|
24
|
+
def block
|
25
|
+
subject.should be_nil
|
26
|
+
return_value
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'returns the expected value' do
|
30
|
+
should equal(return_value)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'ice_nine'
|
5
|
+
require 'ice_nine/core_ext/object'
|
6
|
+
|
7
|
+
describe Object, '#deep_freeze' do
|
8
|
+
subject { object.deep_freeze }
|
9
|
+
|
10
|
+
let(:object) { Object.new }
|
11
|
+
|
12
|
+
it 'returns the object' do
|
13
|
+
should be(object)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'freezes the object' do
|
17
|
+
expect { subject }.should change(object, :frozen?).from(false).to(true)
|
18
|
+
end
|
19
|
+
end
|
data/tasks/metrics/heckle.rake
CHANGED
@@ -12,7 +12,7 @@ begin
|
|
12
12
|
require 'mspec'
|
13
13
|
require 'mspec/utils/name_map'
|
14
14
|
|
15
|
-
SKIP_METHODS = %w[ blank_slate_method_added ].freeze
|
15
|
+
SKIP_METHODS = %w[ blank_slate_method_added guarded_objects ].freeze
|
16
16
|
|
17
17
|
class NameMap
|
18
18
|
def file_name(method, constant)
|
@@ -27,7 +27,7 @@ begin
|
|
27
27
|
end
|
28
28
|
|
29
29
|
desc 'Heckle each module and class'
|
30
|
-
task :heckle => :
|
30
|
+
task :heckle => :coverage do
|
31
31
|
unless Ruby2Ruby::VERSION == '1.2.2'
|
32
32
|
raise "ruby2ruby version #{Ruby2Ruby::VERSION} may not work properly, 1.2.2 *only* is recommended for use with heckle"
|
33
33
|
end
|
data/tasks/spec.rake
CHANGED
@@ -1,27 +1,17 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
begin
|
4
|
-
|
5
|
-
require 'rspec/core/rake_task'
|
6
|
-
rescue LoadError
|
7
|
-
require 'spec/rake/spectask'
|
8
|
-
|
9
|
-
module RSpec
|
10
|
-
module Core
|
11
|
-
RakeTask = Spec::Rake::SpecTask
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
4
|
+
require 'spec/rake/spectask'
|
15
5
|
|
16
6
|
desc 'Run all specs'
|
17
7
|
task :spec => %w[ spec:unit spec:integration ]
|
18
8
|
|
19
9
|
namespace :spec do
|
20
|
-
|
10
|
+
Spec::Rake::SpecTask.new(:integration) do |t|
|
21
11
|
t.pattern = 'spec/integration/**/*_spec.rb'
|
22
12
|
end
|
23
13
|
|
24
|
-
|
14
|
+
Spec::Rake::SpecTask.new(:unit) do |t|
|
25
15
|
t.pattern = 'spec/unit/**/*_spec.rb'
|
26
16
|
end
|
27
17
|
end
|
@@ -32,14 +22,24 @@ rescue LoadError
|
|
32
22
|
end
|
33
23
|
|
34
24
|
begin
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
25
|
+
if RUBY_VERSION < '1.9'
|
26
|
+
desc 'Generate code coverage'
|
27
|
+
Spec::Rake::SpecTask.new(:coverage) do |t|
|
28
|
+
t.rcov = true
|
29
|
+
t.pattern = 'spec/unit/**/*_spec.rb'
|
30
|
+
t.rcov_opts = File.read('spec/rcov.opts').split(/\s+/)
|
31
|
+
end
|
32
|
+
else
|
33
|
+
desc 'Generate code coverage'
|
34
|
+
task :coverage do
|
35
|
+
ENV['COVERAGE'] = 'true'
|
36
|
+
Rake::Task['spec:unit'].execute
|
37
|
+
end
|
39
38
|
end
|
40
39
|
rescue LoadError
|
41
|
-
task :
|
42
|
-
|
40
|
+
task :coverage do
|
41
|
+
lib = RUBY_VERSION < '1.9' ? 'rcov' : 'simplecov'
|
42
|
+
abort "coverage is not available. In order to run #{lib}, you must: gem install #{lib}"
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ice_nine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 2
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Dan Kubb
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-03-
|
18
|
+
date: 2012-03-27 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: rake
|
@@ -79,29 +79,34 @@ files:
|
|
79
79
|
- config/yardstick.yml
|
80
80
|
- ice_nine.gemspec
|
81
81
|
- lib/ice_nine.rb
|
82
|
+
- lib/ice_nine/core_ext/object.rb
|
82
83
|
- lib/ice_nine/freezer.rb
|
83
84
|
- lib/ice_nine/freezer/array.rb
|
84
85
|
- lib/ice_nine/freezer/hash.rb
|
85
86
|
- lib/ice_nine/freezer/no_freeze.rb
|
87
|
+
- lib/ice_nine/freezer/object.rb
|
86
88
|
- lib/ice_nine/freezer/range.rb
|
87
89
|
- lib/ice_nine/freezer/struct.rb
|
90
|
+
- lib/ice_nine/support/recursion_guard.rb
|
88
91
|
- lib/ice_nine/version.rb
|
89
92
|
- spec/rcov.opts
|
90
93
|
- spec/spec.opts
|
91
94
|
- spec/spec_helper.rb
|
92
95
|
- spec/unit/ice_nine/class_methods/deep_freeze_spec.rb
|
93
96
|
- spec/unit/ice_nine/freezer/array/class_methods/deep_freeze_spec.rb
|
94
|
-
- spec/unit/ice_nine/freezer/class_methods/deep_freeze_spec.rb
|
95
97
|
- spec/unit/ice_nine/freezer/class_methods/element_reference_spec.rb
|
96
98
|
- spec/unit/ice_nine/freezer/false_class/class_methods/deep_freeze_spec.rb
|
97
99
|
- spec/unit/ice_nine/freezer/hash/class_methods/deep_freeze_spec.rb
|
98
100
|
- spec/unit/ice_nine/freezer/nil_class/class_methods/deep_freeze_spec.rb
|
99
101
|
- spec/unit/ice_nine/freezer/no_freeze/class_methods/deep_freeze_spec.rb
|
100
102
|
- spec/unit/ice_nine/freezer/numeric/class_methods/deep_freeze_spec.rb
|
103
|
+
- spec/unit/ice_nine/freezer/object/class_methods/deep_freeze_spec.rb
|
101
104
|
- spec/unit/ice_nine/freezer/range/class_methods/deep_freeze_spec.rb
|
102
105
|
- spec/unit/ice_nine/freezer/struct/class_methods/deep_freeze_spec.rb
|
103
106
|
- spec/unit/ice_nine/freezer/symbol/class_methods/deep_freeze_spec.rb
|
104
107
|
- spec/unit/ice_nine/freezer/true_class/class_methods/deep_freeze_spec.rb
|
108
|
+
- spec/unit/ice_nine/recursion_guard/class_methods/guard_spec.rb
|
109
|
+
- spec/unit/object/deep_freeze_spec.rb
|
105
110
|
- tasks/metrics/ci.rake
|
106
111
|
- tasks/metrics/flay.rake
|
107
112
|
- tasks/metrics/flog.rake
|