ice_nine 0.1.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/.gitignore +37 -0
- data/.pelusa.yml +9 -0
- data/.rvmrc +1 -0
- data/.travis.yml +17 -0
- data/.yardopts +1 -0
- data/Gemfile +32 -0
- data/LICENSE +20 -0
- data/README.md +54 -0
- data/Rakefile +9 -0
- data/TODO +3 -0
- data/config/flay.yml +3 -0
- data/config/flog.yml +2 -0
- data/config/roodi.yml +16 -0
- data/config/site.reek +91 -0
- data/config/yardstick.yml +2 -0
- data/ice_nine.gemspec +21 -0
- data/lib/ice_nine.rb +65 -0
- data/lib/ice_nine/freezer.rb +95 -0
- data/lib/ice_nine/freezer/array.rb +26 -0
- data/lib/ice_nine/freezer/hash.rb +30 -0
- data/lib/ice_nine/freezer/no_freeze.rb +48 -0
- data/lib/ice_nine/freezer/range.rb +29 -0
- data/lib/ice_nine/freezer/struct.rb +29 -0
- data/lib/ice_nine/version.rb +5 -0
- data/spec/rcov.opts +7 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/unit/ice_nine/class_methods/deep_freeze_spec.rb +193 -0
- data/spec/unit/ice_nine/freezer/array/class_methods/deep_freeze_spec.rb +27 -0
- data/spec/unit/ice_nine/freezer/class_methods/deep_freeze_spec.rb +30 -0
- data/spec/unit/ice_nine/freezer/class_methods/element_reference_spec.rb +85 -0
- data/spec/unit/ice_nine/freezer/false_class/class_methods/deep_freeze_spec.rb +22 -0
- data/spec/unit/ice_nine/freezer/hash/class_methods/deep_freeze_spec.rb +40 -0
- data/spec/unit/ice_nine/freezer/nil_class/class_methods/deep_freeze_spec.rb +22 -0
- data/spec/unit/ice_nine/freezer/no_freeze/class_methods/deep_freeze_spec.rb +19 -0
- data/spec/unit/ice_nine/freezer/numeric/class_methods/deep_freeze_spec.rb +24 -0
- data/spec/unit/ice_nine/freezer/range/class_methods/deep_freeze_spec.rb +30 -0
- data/spec/unit/ice_nine/freezer/struct/class_methods/deep_freeze_spec.rb +27 -0
- data/spec/unit/ice_nine/freezer/symbol/class_methods/deep_freeze_spec.rb +22 -0
- data/spec/unit/ice_nine/freezer/true_class/class_methods/deep_freeze_spec.rb +22 -0
- data/tasks/metrics/ci.rake +7 -0
- data/tasks/metrics/flay.rake +43 -0
- data/tasks/metrics/flog.rake +46 -0
- data/tasks/metrics/heckle.rake +210 -0
- data/tasks/metrics/metric_fu.rake +31 -0
- data/tasks/metrics/reek.rake +11 -0
- data/tasks/metrics/roodi.rake +17 -0
- data/tasks/metrics/yardstick.rake +25 -0
- data/tasks/spec.rake +46 -0
- data/tasks/yard.rake +11 -0
- metadata +150 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module IceNine
|
4
|
+
class Freezer
|
5
|
+
|
6
|
+
# A freezer class for handling Array objects
|
7
|
+
class Array < self
|
8
|
+
|
9
|
+
# Deep Freeze an Array
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# array = IceNine:Freezer::Array.deep_freeze(%w[ a b c ])
|
13
|
+
# array.select(&:frozen?) # => [ 'a', 'b', 'c' ]
|
14
|
+
#
|
15
|
+
# @param [Array] array
|
16
|
+
#
|
17
|
+
# @return [Array]
|
18
|
+
#
|
19
|
+
# @api public
|
20
|
+
def self.deep_freeze(array)
|
21
|
+
super array.each(&:freeze)
|
22
|
+
end
|
23
|
+
|
24
|
+
end # class Array
|
25
|
+
end # class Freezer
|
26
|
+
end # module IceNine
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module IceNine
|
4
|
+
class Freezer
|
5
|
+
|
6
|
+
# A freezer class for handling Hash objects
|
7
|
+
class Hash < self
|
8
|
+
|
9
|
+
# Deep Freeze a Hash
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# hash = IceNine::Freezer::Hash.deep_freeze('a' => '1', 'b' => '2')
|
13
|
+
# hash.keys.select(&:frozen?) # => [ 'a', 'b' ]
|
14
|
+
# hash.values.select(&:frozen?) # => [ '1', '2' ]
|
15
|
+
#
|
16
|
+
# @param [Hash] hash
|
17
|
+
#
|
18
|
+
# @return [Hash]
|
19
|
+
#
|
20
|
+
# @api public
|
21
|
+
def self.deep_freeze(hash)
|
22
|
+
super hash.each { |key, value|
|
23
|
+
IceNine.deep_freeze(key)
|
24
|
+
IceNine.deep_freeze(value)
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
end # class Hash
|
29
|
+
end # class Freezer
|
30
|
+
end # module IceNine
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module IceNine
|
4
|
+
class Freezer
|
5
|
+
|
6
|
+
# A freezer class that does not freeze anything
|
7
|
+
class NoFreeze < self
|
8
|
+
|
9
|
+
# Pass through the object without freezing it
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# object = IceNine::Freezer::NoFreeze.deep_freeze(object)
|
13
|
+
# object.frozen? # => false
|
14
|
+
#
|
15
|
+
# @param [Object] object
|
16
|
+
#
|
17
|
+
# @return [Object]
|
18
|
+
#
|
19
|
+
# @api public
|
20
|
+
def self.deep_freeze(object)
|
21
|
+
object
|
22
|
+
end
|
23
|
+
|
24
|
+
end # class NoFreeze
|
25
|
+
|
26
|
+
# Skip freezing nil objects
|
27
|
+
class NilClass < NoFreeze; end
|
28
|
+
|
29
|
+
# Skip freezing true objects
|
30
|
+
class TrueClass < NoFreeze; end
|
31
|
+
|
32
|
+
# Skip freezing false objects
|
33
|
+
class FalseClass < NoFreeze; end
|
34
|
+
|
35
|
+
# Skip freezing Symbol objects
|
36
|
+
class Symbol < NoFreeze; end
|
37
|
+
|
38
|
+
# Skip freezing Numeric objects
|
39
|
+
class Numeric < NoFreeze; end
|
40
|
+
|
41
|
+
# Skip freezing Rubinius objects
|
42
|
+
class Rubinius < NoFreeze; end
|
43
|
+
|
44
|
+
# Skip freezing Hash::State objects on Rubinius
|
45
|
+
class Hash::State < NoFreeze; end
|
46
|
+
|
47
|
+
end # class Freezer
|
48
|
+
end # module IceNine
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module IceNine
|
4
|
+
class Freezer
|
5
|
+
|
6
|
+
# A freezer class for handling Range objects
|
7
|
+
class Range < self
|
8
|
+
|
9
|
+
# Deep Freeze a Range
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# range = IceNine:Freezer::Range.deep_freeze('a'..'z')
|
13
|
+
# range.begin.frozen? # => true
|
14
|
+
# range.end.frozen? # => true
|
15
|
+
#
|
16
|
+
# @param [Range] range
|
17
|
+
#
|
18
|
+
# @return [Range]
|
19
|
+
#
|
20
|
+
# @api public
|
21
|
+
def self.deep_freeze(range)
|
22
|
+
IceNine.deep_freeze(range.begin)
|
23
|
+
IceNine.deep_freeze(range.end)
|
24
|
+
super range
|
25
|
+
end
|
26
|
+
|
27
|
+
end # class Range
|
28
|
+
end # class Freezer
|
29
|
+
end # module IceNine
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module IceNine
|
4
|
+
class Freezer
|
5
|
+
|
6
|
+
# A freezer class for handling Struct objects
|
7
|
+
class Struct < self
|
8
|
+
|
9
|
+
# Deep Freeze a Struct
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# struct = IceNine:Freezer::Struct.deep_freeze(klass.new('1'))
|
13
|
+
# struct.values.select(&:frozen?) # => [ '1' ]
|
14
|
+
#
|
15
|
+
# @param [Struct] struct
|
16
|
+
#
|
17
|
+
# @return [Struct]
|
18
|
+
#
|
19
|
+
# @todo use super on Struct#each once it returns self in rbx
|
20
|
+
#
|
21
|
+
# @api public
|
22
|
+
def self.deep_freeze(struct)
|
23
|
+
struct.each(&IceNine.method(:deep_freeze))
|
24
|
+
super struct
|
25
|
+
end
|
26
|
+
|
27
|
+
end # class Struct
|
28
|
+
end # class Freezer
|
29
|
+
end # module IceNine
|
data/spec/rcov.opts
ADDED
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'rspec' # try for RSpec 2
|
7
|
+
rescue LoadError
|
8
|
+
require 'spec' # try for RSpec 1
|
9
|
+
RSpec = Spec::Runner
|
10
|
+
end
|
11
|
+
|
12
|
+
# require spec support files and shared behavior
|
13
|
+
Dir[File.expand_path('../shared/**/*.rb', __FILE__)].each { |file| require file }
|
14
|
+
|
15
|
+
RSpec.configure do |config|
|
16
|
+
end
|
17
|
+
|
18
|
+
# change the heckle timeout to be 5 seconds
|
19
|
+
if defined?(::Heckle)
|
20
|
+
class ::Heckle
|
21
|
+
@@timeout = 5
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,193 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'ice_nine'
|
5
|
+
|
6
|
+
describe IceNine, '.deep_freeze' do
|
7
|
+
subject { object.deep_freeze(value) }
|
8
|
+
|
9
|
+
let(:object) { self.class.described_type }
|
10
|
+
|
11
|
+
context 'with an Object' do
|
12
|
+
let(:value) { Object.new }
|
13
|
+
|
14
|
+
before do
|
15
|
+
value.instance_eval { @a = '1' }
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'returns the object' do
|
19
|
+
should be(value)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'freezes the object' do
|
23
|
+
expect { subject }.should change(value, :frozen?).from(false).to(true)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'freezes the instance variables in the Object' do
|
27
|
+
subject.instance_variable_get(:@a).should be_frozen
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'with a circular reference' do
|
31
|
+
before do
|
32
|
+
value.instance_eval { @self = self }
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'returns the object' do
|
36
|
+
should be(value)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'freezes the object' do
|
40
|
+
expect { subject }.should change(value, :frozen?).from(false).to(true)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'freezes the instance variables in the Object' do
|
44
|
+
subject.instance_variable_get(:@a).should be_frozen
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'with an Array' do
|
50
|
+
let(:value) { %w[ a ] }
|
51
|
+
|
52
|
+
it 'returns the object' do
|
53
|
+
should be(value)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'freezes the object' do
|
57
|
+
expect { subject }.should change(value, :frozen?).from(false).to(true)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'freezes each element in the Array' do
|
61
|
+
subject.select(&:frozen?).should == subject
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'with a circular reference' do
|
65
|
+
before do
|
66
|
+
value << value
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'returns the object' do
|
70
|
+
should be(value)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'freezes the object' do
|
74
|
+
expect { subject }.should change(value, :frozen?).from(false).to(true)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'freezes each element in the Array' do
|
78
|
+
subject.select(&:frozen?).should == subject
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'with a Hash' do
|
84
|
+
let(:value) { { Object.new => Object.new } }
|
85
|
+
|
86
|
+
it 'returns the object' do
|
87
|
+
should be(value)
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'freezes the object' do
|
91
|
+
expect { subject }.should change(value, :frozen?).from(false).to(true)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'freezes each key in the Hash' do
|
95
|
+
subject.keys.select(&:frozen?).should == subject.keys
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'freezes each value in the Hash' do
|
99
|
+
subject.values.select(&:frozen?).should == subject.values
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'with a circular reference' do
|
103
|
+
before do
|
104
|
+
value[value] = value
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'returns the object' do
|
108
|
+
should be(value)
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'freezes the object' do
|
112
|
+
expect { subject }.should change(value, :frozen?).from(false).to(true)
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'freezes each key in the Hash' do
|
116
|
+
subject.keys.select(&:frozen?).should == subject.keys
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'freezes each value in the Hash' do
|
120
|
+
subject.values.select(&:frozen?).should == subject.values
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'with a Range' do
|
126
|
+
let(:value) { 'a'..'z' }
|
127
|
+
|
128
|
+
it 'returns the object' do
|
129
|
+
should be(value)
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'freezes the object' do
|
133
|
+
expect { subject }.should change(value, :frozen?).from(false).to(true)
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'freeze the first object in the Range' do
|
137
|
+
subject.begin.should be_frozen
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'freeze the last object in the Range' do
|
141
|
+
subject.end.should be_frozen
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
context 'with a Struct' do
|
146
|
+
let(:value) { klass.new('1') }
|
147
|
+
let(:klass) { Struct.new(:a) }
|
148
|
+
|
149
|
+
it 'returns the object' do
|
150
|
+
should be(value)
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'freezes the object' do
|
154
|
+
expect { subject }.should change(value, :frozen?).from(false).to(true)
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'freezes each value in the Struct' do
|
158
|
+
subject.values.select(&:frozen?).should == subject.values
|
159
|
+
end
|
160
|
+
|
161
|
+
context 'with a circular reference' do
|
162
|
+
before do
|
163
|
+
value.a = value
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'returns the object' do
|
167
|
+
should be(value)
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'freezes the object' do
|
171
|
+
expect { subject }.should change(value, :frozen?).from(false).to(true)
|
172
|
+
end
|
173
|
+
|
174
|
+
it 'freezes each value in the Struct' do
|
175
|
+
subject.values.select(&:frozen?).should == subject.values
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
[ 0.0, 0, 0x7fffffffffffffff, true, false, nil, :symbol ].each do |value|
|
181
|
+
context "with a #{value.class}" do
|
182
|
+
let(:value) { value }
|
183
|
+
|
184
|
+
it 'returns the object' do
|
185
|
+
should be(value)
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'does not freeze the object' do
|
189
|
+
expect { subject }.should_not change(value, :frozen?).from(false)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'ice_nine/freezer'
|
5
|
+
require 'ice_nine/freezer/array'
|
6
|
+
|
7
|
+
describe IceNine::Freezer::Array, '.deep_freeze' do
|
8
|
+
subject { object.deep_freeze(value) }
|
9
|
+
|
10
|
+
let(:object) { described_class }
|
11
|
+
|
12
|
+
context 'with an Array object' do
|
13
|
+
let(:value) { %w[ a ] }
|
14
|
+
|
15
|
+
it 'returns the object' do
|
16
|
+
should be(value)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'freezes the object' do
|
20
|
+
expect { subject }.should change(value, :frozen?).from(false).to(true)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'freezes each element in the Array' do
|
24
|
+
subject.select(&:frozen?).should == subject
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'ice_nine'
|
5
|
+
|
6
|
+
describe IceNine::Freezer, '.deep_freeze' do
|
7
|
+
subject { object.deep_freeze(value) }
|
8
|
+
|
9
|
+
let(:object) { described_class }
|
10
|
+
|
11
|
+
context 'with an Object' do
|
12
|
+
let(:value) { Object.new }
|
13
|
+
|
14
|
+
before do
|
15
|
+
value.instance_eval { @a = '1' }
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'returns the object' do
|
19
|
+
should be(value)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'freezes the object' do
|
23
|
+
expect { subject }.should change(value, :frozen?).from(false).to(true)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'freezes the instance variables in the Object' do
|
27
|
+
subject.instance_variable_get(:@a).should be_frozen
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|