adamantium 0.0.2 → 0.0.3
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 +1 -1
- data/Gemfile +11 -6
- data/README.md +85 -14
- data/config/flay.yml +1 -1
- data/config/flog.yml +1 -1
- data/config/site.reek +2 -1
- data/lib/adamantium.rb +59 -144
- data/lib/adamantium/class_methods.rb +20 -0
- data/lib/adamantium/freezer.rb +139 -0
- data/lib/adamantium/module_methods.rb +103 -0
- data/lib/adamantium/version.rb +1 -1
- data/spec/integration/adamantium_spec.rb +63 -0
- data/spec/unit/adamantium/dup_spec.rb +1 -1
- data/spec/unit/adamantium/flat/freezer_spec.rb +15 -0
- data/spec/unit/adamantium/freezer/class_methods/get_spec.rb +33 -0
- data/spec/unit/adamantium/freezer/class_methods/parse_spec.rb +31 -0
- data/spec/unit/adamantium/freezer/deep/class_methods/call_spec.rb +81 -0
- data/spec/unit/adamantium/freezer/deep/class_methods/freeze_spec.rb +14 -0
- data/spec/unit/adamantium/{class_methods/freeze_object_spec.rb → freezer/flat/class_methods/call_spec.rb} +10 -2
- data/spec/unit/adamantium/freezer/flat/class_methods/freeze_spec.rb +14 -0
- data/spec/unit/adamantium/memoize_spec.rb +2 -2
- data/spec/unit/adamantium/memoized_spec.rb +3 -3
- data/spec/unit/adamantium/module_methods/freezer_spec.rb +15 -0
- data/spec/unit/adamantium/module_methods/memoize_spec.rb +68 -7
- data/tasks/metrics/ci.rake +1 -1
- data/tasks/metrics/heckle.rake +10 -9
- metadata +25 -6
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -21,12 +21,17 @@ platform :jruby do
|
|
21
21
|
end
|
22
22
|
|
23
23
|
group :metrics do
|
24
|
-
gem 'flay',
|
25
|
-
gem 'flog',
|
26
|
-
gem 'reek',
|
27
|
-
gem 'roodi',
|
28
|
-
gem 'yardstick',
|
29
|
-
gem '
|
24
|
+
gem 'flay', '~> 1.4.2'
|
25
|
+
gem 'flog', '~> 2.5.1'
|
26
|
+
gem 'reek', '~> 1.2.8', :github => 'dkubb/reek'
|
27
|
+
gem 'roodi', '~> 2.1.0'
|
28
|
+
gem 'yardstick', '~> 0.7.0'
|
29
|
+
gem 'simplecov'
|
30
|
+
|
31
|
+
platforms :ruby_18, :ruby_19 do
|
32
|
+
# this indirectly depends on ffi which does not build on ruby-head
|
33
|
+
gem 'yard-spellcheck', '~> 0.1.5'
|
34
|
+
end
|
30
35
|
|
31
36
|
platforms :mri_18 do
|
32
37
|
gem 'arrayfields', '~> 4.7.4' # for metric_fu
|
data/README.md
CHANGED
@@ -26,24 +26,95 @@ Examples
|
|
26
26
|
require 'adamantium'
|
27
27
|
require 'securerandom'
|
28
28
|
|
29
|
-
class
|
29
|
+
class Example
|
30
|
+
# Inclusion of Adamantium defaults to deep freeze behavior
|
31
|
+
# of constructor and memoizer
|
32
|
+
|
30
33
|
include Adamantium
|
31
34
|
|
32
|
-
|
33
|
-
|
35
|
+
# Instance and attributes (ivars) are frozen per default
|
36
|
+
# Example:
|
37
|
+
#
|
38
|
+
# object = Example.new
|
39
|
+
# object.frozen? # => true
|
40
|
+
# object.attribute.frozen? # => true
|
41
|
+
#
|
42
|
+
def initialize
|
43
|
+
@attribute = "foo bar"
|
34
44
|
end
|
35
|
-
|
36
|
-
|
45
|
+
attr_reader :attribute
|
46
|
+
|
47
|
+
# Memoized method with deeply frozen value (default)
|
48
|
+
# Example:
|
49
|
+
#
|
50
|
+
# object = Example.new
|
51
|
+
# object.random => ["abcdef"]
|
52
|
+
# object.random => ["abcdef"]
|
53
|
+
# object.random.frozen? => true
|
54
|
+
# object.random[0].frozen? => true
|
55
|
+
#
|
56
|
+
def random
|
57
|
+
[SecureRandom.hex(6)]
|
58
|
+
end
|
59
|
+
memoize :random
|
60
|
+
|
61
|
+
# Memoized method with non frozen value
|
62
|
+
# Example:
|
63
|
+
#
|
64
|
+
# object = Example.new
|
65
|
+
# object.buffer # => <StringIO:abcdef>
|
66
|
+
# object.buffer # => <StringIO:abcdef>
|
67
|
+
# object.buffer.frozen? # => false
|
68
|
+
#
|
69
|
+
def buffer
|
70
|
+
StringIO.new
|
71
|
+
end
|
72
|
+
memoize :buffer, :freezer => :noop
|
73
|
+
|
74
|
+
# Memoized method with nondeeply frozen value
|
75
|
+
# Example:
|
76
|
+
#
|
77
|
+
# object = Example.new
|
78
|
+
# object.random2 => ["abcdef"]
|
79
|
+
# object.random2 => ["abcdef"]
|
80
|
+
# object.random2.frozen? => true
|
81
|
+
# object.random2[0].frozen? => false
|
82
|
+
#
|
83
|
+
def random2
|
84
|
+
[SecureRandom.hex(6)]
|
85
|
+
end
|
86
|
+
memoize :random2, :freezer => :flat
|
37
87
|
end
|
38
88
|
|
39
|
-
|
40
|
-
|
41
|
-
#
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
#
|
46
|
-
|
89
|
+
class FlatExample
|
90
|
+
# Inclusion of Adamantium::Flat defaults do non deep frozen behavior
|
91
|
+
# for memoizer and constructor
|
92
|
+
|
93
|
+
include Adamantium::Flat
|
94
|
+
|
95
|
+
# Instace is frozen but attribute is not
|
96
|
+
# object = FlatExample.new
|
97
|
+
# object.frozen? # => true
|
98
|
+
# object.attribute.frozen? # => false
|
99
|
+
def initialize
|
100
|
+
@attribute = "foo bar"
|
101
|
+
end
|
102
|
+
attr_reader :attribute
|
103
|
+
|
104
|
+
# Memoized method with flat frozen value (default)
|
105
|
+
# Example:
|
106
|
+
#
|
107
|
+
# object = Example.new
|
108
|
+
# object.random => ["abcdef"]
|
109
|
+
# object.random => ["abcdef"]
|
110
|
+
# object.random.frozen? => true
|
111
|
+
# object.random[0].frozen? => false
|
112
|
+
#
|
113
|
+
def random
|
114
|
+
[SecureRandom.hex(6)]
|
115
|
+
end
|
116
|
+
memoize :random
|
117
|
+
end
|
47
118
|
```
|
48
119
|
|
49
120
|
Credits
|
@@ -68,7 +139,7 @@ License
|
|
68
139
|
-------
|
69
140
|
|
70
141
|
Copyright (c) 2009-2012 Dan Kubb
|
71
|
-
Copyright (c) 2012 Markus Schirp
|
142
|
+
Copyright (c) 2012 Markus Schirp
|
72
143
|
|
73
144
|
Permission is hereby granted, free of charge, to any person obtaining
|
74
145
|
a copy of this software and associated documentation files (the
|
data/config/flay.yml
CHANGED
data/config/flog.yml
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
---
|
2
|
-
threshold:
|
2
|
+
threshold: 21.1
|
data/config/site.reek
CHANGED
data/lib/adamantium.rb
CHANGED
@@ -6,6 +6,35 @@ module Adamantium
|
|
6
6
|
# Storage for memoized methods
|
7
7
|
Memory = Class.new(::Hash)
|
8
8
|
|
9
|
+
# Defaults to less strict defaults
|
10
|
+
module Flat
|
11
|
+
|
12
|
+
# Return flat freezer
|
13
|
+
#
|
14
|
+
# @return [Freezer::Flat]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
#
|
18
|
+
def freezer
|
19
|
+
Freezer::Flat
|
20
|
+
end
|
21
|
+
|
22
|
+
# Hook called when module is included
|
23
|
+
#
|
24
|
+
# @param [Class,Module] descendant
|
25
|
+
#
|
26
|
+
# @return [self]
|
27
|
+
#
|
28
|
+
# @api private
|
29
|
+
def self.included(descendant)
|
30
|
+
super
|
31
|
+
descendant.send(:include, Adamantium)
|
32
|
+
descendant.extend(self)
|
33
|
+
|
34
|
+
self
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
9
38
|
# Hook called when module is included
|
10
39
|
#
|
11
40
|
# @param [Module] descendant
|
@@ -15,51 +44,11 @@ module Adamantium
|
|
15
44
|
#
|
16
45
|
# @api private
|
17
46
|
def self.included(descendant)
|
18
|
-
super
|
19
47
|
descendant.extend ModuleMethods if descendant.kind_of?(Module)
|
20
48
|
descendant.extend ClassMethods if descendant.kind_of?(Class)
|
21
49
|
self
|
22
50
|
end
|
23
51
|
|
24
|
-
# Attempt to freeze an object
|
25
|
-
#
|
26
|
-
# @example using a value object
|
27
|
-
# Adamantium.freeze_object(12345) # => noop
|
28
|
-
#
|
29
|
-
# @example using a normal object
|
30
|
-
# Adamantium.freeze_object({}) # => duplicate & freeze object
|
31
|
-
#
|
32
|
-
# @param [Object] object
|
33
|
-
# the object to freeze
|
34
|
-
#
|
35
|
-
# @return [Object]
|
36
|
-
# if supported, the frozen object, otherwise the object directly
|
37
|
-
#
|
38
|
-
# @api public
|
39
|
-
def self.freeze_object(object)
|
40
|
-
case object
|
41
|
-
when Numeric, TrueClass, FalseClass, NilClass, Symbol
|
42
|
-
object
|
43
|
-
else
|
44
|
-
freeze_value(object)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
# Returns a frozen value
|
49
|
-
#
|
50
|
-
# @param [Object] value
|
51
|
-
# a value to freeze
|
52
|
-
#
|
53
|
-
# @return [Object]
|
54
|
-
# if frozen, the value directly, otherwise a frozen copy of the value
|
55
|
-
#
|
56
|
-
# @api private
|
57
|
-
def self.freeze_value(value)
|
58
|
-
value.frozen? ? value : IceNine.deep_freeze(value.dup)
|
59
|
-
end
|
60
|
-
|
61
|
-
private_class_method :freeze_value
|
62
|
-
|
63
52
|
# Freeze the object
|
64
53
|
#
|
65
54
|
# @example
|
@@ -102,7 +91,10 @@ module Adamantium
|
|
102
91
|
#
|
103
92
|
# @api public
|
104
93
|
def memoize(name, value)
|
105
|
-
|
94
|
+
unless memory.key?(name)
|
95
|
+
store_memory(name, freeze_object(value))
|
96
|
+
end
|
97
|
+
|
106
98
|
self
|
107
99
|
end
|
108
100
|
|
@@ -129,6 +121,27 @@ private
|
|
129
121
|
@__memory ||= Memory.new
|
130
122
|
end
|
131
123
|
|
124
|
+
# Freeze object
|
125
|
+
#
|
126
|
+
# @param [Object] object
|
127
|
+
# an object to be frozen
|
128
|
+
#
|
129
|
+
# @return [Object]
|
130
|
+
#
|
131
|
+
# @api private
|
132
|
+
def freeze_object(object)
|
133
|
+
freezer.call(object)
|
134
|
+
end
|
135
|
+
|
136
|
+
# Return class level freezer
|
137
|
+
#
|
138
|
+
# @return [#call]
|
139
|
+
#
|
140
|
+
# @api private
|
141
|
+
def freezer
|
142
|
+
self.class.freezer
|
143
|
+
end
|
144
|
+
|
132
145
|
# Store the value in memory
|
133
146
|
#
|
134
147
|
# @param [Symbol] name
|
@@ -142,108 +155,10 @@ private
|
|
142
155
|
#
|
143
156
|
# @api private
|
144
157
|
def store_memory(name, value)
|
145
|
-
memory[name] =
|
158
|
+
memory[name] = value
|
146
159
|
end
|
147
|
-
|
148
|
-
# Methods mixed in to adamantium modules
|
149
|
-
module ModuleMethods
|
150
|
-
|
151
|
-
# Hook called when module is included
|
152
|
-
#
|
153
|
-
# @param [Module] mod
|
154
|
-
# the module including ModuleMethods
|
155
|
-
#
|
156
|
-
# @return [self]
|
157
|
-
#
|
158
|
-
# @api private
|
159
|
-
def included(mod)
|
160
|
-
Adamantium.included(mod)
|
161
|
-
self
|
162
|
-
end
|
163
|
-
|
164
|
-
# Memoize a list of methods
|
165
|
-
#
|
166
|
-
# @example
|
167
|
-
# memoize :hash
|
168
|
-
#
|
169
|
-
# @param [Array<#to_s>] methods
|
170
|
-
# a list of methods to memoize
|
171
|
-
#
|
172
|
-
# @return [self]
|
173
|
-
#
|
174
|
-
# @api public
|
175
|
-
def memoize(*methods)
|
176
|
-
methods.each { |method| memoize_method(method) }
|
177
|
-
self
|
178
|
-
end
|
179
|
-
|
180
|
-
private
|
181
|
-
|
182
|
-
# Memoize the named method
|
183
|
-
#
|
184
|
-
# @param [#to_s] method
|
185
|
-
# a method to memoize
|
186
|
-
#
|
187
|
-
# @return [undefined]
|
188
|
-
#
|
189
|
-
# @api private
|
190
|
-
def memoize_method(method)
|
191
|
-
visibility = method_visibility(method)
|
192
|
-
define_memoize_method(method)
|
193
|
-
send(visibility, method)
|
194
|
-
end
|
195
|
-
|
196
|
-
# Define a memoized method that delegates to the original method
|
197
|
-
#
|
198
|
-
# @param [Symbol] method
|
199
|
-
# the name of the method
|
200
|
-
#
|
201
|
-
# @return [undefined]
|
202
|
-
#
|
203
|
-
# @api private
|
204
|
-
def define_memoize_method(method)
|
205
|
-
original = instance_method(method)
|
206
|
-
undef_method(method)
|
207
|
-
define_method(method) do |*args|
|
208
|
-
if memory.key?(method)
|
209
|
-
memoized(method)
|
210
|
-
else
|
211
|
-
store_memory(method, original.bind(self).call(*args))
|
212
|
-
end
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
# Return the method visibility of a method
|
217
|
-
#
|
218
|
-
# @param [String, Symbol] method
|
219
|
-
# the name of the method
|
220
|
-
#
|
221
|
-
# @return [String]
|
222
|
-
#
|
223
|
-
# @api private
|
224
|
-
def method_visibility(method)
|
225
|
-
if private_method_defined?(method) then 'private'
|
226
|
-
elsif protected_method_defined?(method) then 'protected'
|
227
|
-
else 'public'
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
231
|
-
end # module ModuleMethods
|
232
|
-
|
233
|
-
# Methods mixed in to adamantium classes
|
234
|
-
module ClassMethods
|
235
|
-
|
236
|
-
# Instantiate a new frozen object
|
237
|
-
#
|
238
|
-
# @example
|
239
|
-
# object = AdamantiumClass.new # object is frozen
|
240
|
-
#
|
241
|
-
# @return [Object]
|
242
|
-
#
|
243
|
-
# @api public
|
244
|
-
def new(*)
|
245
|
-
IceNine.deep_freeze(super)
|
246
|
-
end
|
247
|
-
|
248
|
-
end # module ClassMethods
|
249
160
|
end # module Adamantium
|
161
|
+
|
162
|
+
require 'adamantium/module_methods'
|
163
|
+
require 'adamantium/class_methods'
|
164
|
+
require 'adamantium/freezer'
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Adamantium
|
2
|
+
|
3
|
+
# Methods mixed in to adamantium classes
|
4
|
+
module ClassMethods
|
5
|
+
|
6
|
+
# Instantiate a new frozen object
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# object = AdamantiumClass.new # object is frozen
|
10
|
+
#
|
11
|
+
# @return [Object]
|
12
|
+
#
|
13
|
+
# @api public
|
14
|
+
def new(*)
|
15
|
+
freezer.freeze(super)
|
16
|
+
end
|
17
|
+
|
18
|
+
end # module ClassMethods
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
module Adamantium
|
2
|
+
|
3
|
+
# Abstract base class for freezers
|
4
|
+
#
|
5
|
+
# TODO: Use dkubb/abstract_class?
|
6
|
+
#
|
7
|
+
# Better pattern for singleton inheritance/shared code
|
8
|
+
class Freezer
|
9
|
+
|
10
|
+
private_class_method :new
|
11
|
+
|
12
|
+
# Attempt to freeze an object
|
13
|
+
#
|
14
|
+
# @example using a value object
|
15
|
+
# Adamantium.freeze_object(12345) # => noop
|
16
|
+
#
|
17
|
+
# @example using a normal object
|
18
|
+
# Adamantium.freeze_object({}) # => duplicate & freeze object
|
19
|
+
#
|
20
|
+
# @param [Object] object
|
21
|
+
# the object to freeze
|
22
|
+
#
|
23
|
+
# @return [Object]
|
24
|
+
# if supported, the frozen object, otherwise the object directly
|
25
|
+
#
|
26
|
+
# @api public
|
27
|
+
def self.call(object)
|
28
|
+
case object
|
29
|
+
when Numeric, TrueClass, FalseClass, NilClass, Symbol, Class, Module
|
30
|
+
object
|
31
|
+
else
|
32
|
+
freeze_value(object)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private_class_method :call
|
37
|
+
|
38
|
+
# Returns a frozen value
|
39
|
+
#
|
40
|
+
# @param [Object] value
|
41
|
+
# a value to freeze
|
42
|
+
#
|
43
|
+
# @return [Object]
|
44
|
+
# if frozen, the value directly, otherwise a frozen copy of the value
|
45
|
+
#
|
46
|
+
# @api private
|
47
|
+
def self.freeze_value(value)
|
48
|
+
value.frozen? ? value : freeze(value.dup)
|
49
|
+
end
|
50
|
+
|
51
|
+
private_class_method :freeze_value
|
52
|
+
|
53
|
+
# Freezer that does not deep freeze
|
54
|
+
class Flat < self
|
55
|
+
|
56
|
+
# Freeze value
|
57
|
+
#
|
58
|
+
# @param [Object] value
|
59
|
+
#
|
60
|
+
# @return [undefined]
|
61
|
+
#
|
62
|
+
# @api private
|
63
|
+
def self.freeze(value)
|
64
|
+
value.freeze
|
65
|
+
end
|
66
|
+
public_class_method :call
|
67
|
+
end
|
68
|
+
|
69
|
+
# Freezer that does deep freeze
|
70
|
+
class Deep < self
|
71
|
+
|
72
|
+
# Deep freeze value
|
73
|
+
#
|
74
|
+
# @param [Object] value
|
75
|
+
#
|
76
|
+
# @return [undefined]
|
77
|
+
#
|
78
|
+
# @api private
|
79
|
+
def self.freeze(value)
|
80
|
+
IceNine.deep_freeze(value)
|
81
|
+
end
|
82
|
+
public_class_method :call
|
83
|
+
end
|
84
|
+
|
85
|
+
Noop = lambda { |object| object }.freeze
|
86
|
+
|
87
|
+
# Error raised when freezer cannot be found
|
88
|
+
class UnknownFreezerError < RuntimeError; end
|
89
|
+
|
90
|
+
# Error raised when memoizer options contain unknown keys
|
91
|
+
class OptionError < RuntimeError; end
|
92
|
+
|
93
|
+
# Return freezer for name
|
94
|
+
#
|
95
|
+
# @param [Symbol] name
|
96
|
+
# a freezer name
|
97
|
+
#
|
98
|
+
# @return [#call]
|
99
|
+
#
|
100
|
+
# @api private
|
101
|
+
def self.get(name)
|
102
|
+
case name
|
103
|
+
when :noop
|
104
|
+
Noop
|
105
|
+
when :deep
|
106
|
+
Deep
|
107
|
+
when :flat
|
108
|
+
Flat
|
109
|
+
else
|
110
|
+
raise UnknownFreezerError, "Freezer with name #{name.inspect} is unknown"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Parse freezer options
|
115
|
+
#
|
116
|
+
# @param [Hash] options
|
117
|
+
# an options hash
|
118
|
+
#
|
119
|
+
# @return [#call]
|
120
|
+
# if freezer option was present
|
121
|
+
#
|
122
|
+
# @return [nil]
|
123
|
+
# otherwise
|
124
|
+
#
|
125
|
+
# @api private
|
126
|
+
#
|
127
|
+
def self.parse(options)
|
128
|
+
keys = options.keys - [:freezer]
|
129
|
+
|
130
|
+
unless keys.empty?
|
131
|
+
raise OptionError, "Unknown option key(s) for memoizer #{keys.inspect}"
|
132
|
+
end
|
133
|
+
|
134
|
+
return unless options.key?(:freezer)
|
135
|
+
|
136
|
+
get(options.fetch(:freezer))
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module Adamantium
|
2
|
+
|
3
|
+
# Methods mixed in to adamantium modules
|
4
|
+
module ModuleMethods
|
5
|
+
|
6
|
+
# Hook called when module is included
|
7
|
+
#
|
8
|
+
# @param [Module] mod
|
9
|
+
# the module including ModuleMethods
|
10
|
+
#
|
11
|
+
# @return [self]
|
12
|
+
#
|
13
|
+
# @api private
|
14
|
+
def included(mod)
|
15
|
+
Adamantium.included(mod)
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
# Return default deep freezer
|
20
|
+
#
|
21
|
+
# @return [Freezer::Deep]
|
22
|
+
#
|
23
|
+
# @api private
|
24
|
+
#
|
25
|
+
def freezer
|
26
|
+
Freezer::Deep
|
27
|
+
end
|
28
|
+
|
29
|
+
# Memoize a list of methods
|
30
|
+
#
|
31
|
+
# @example
|
32
|
+
# memoize :hash
|
33
|
+
#
|
34
|
+
# @param [Array<#to_s>] methods
|
35
|
+
# a list of methods to memoize
|
36
|
+
#
|
37
|
+
# @return [self]
|
38
|
+
#
|
39
|
+
# @api public
|
40
|
+
def memoize(*methods)
|
41
|
+
options = methods.last.kind_of?(Hash) ? methods.pop : {}
|
42
|
+
method_freezer = Freezer.parse(options) || freezer
|
43
|
+
methods.each { |method| memoize_method(method, method_freezer) }
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
# Memoize the named method
|
50
|
+
#
|
51
|
+
# @param [#to_s] method
|
52
|
+
# a method to memoize
|
53
|
+
# @param [#call] freezer
|
54
|
+
# a freezer for memoized values
|
55
|
+
#
|
56
|
+
# @return [undefined]
|
57
|
+
#
|
58
|
+
# @api private
|
59
|
+
def memoize_method(method, freezer)
|
60
|
+
visibility = method_visibility(method)
|
61
|
+
define_memoize_method(method, freezer)
|
62
|
+
send(visibility, method)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Define a memoized method that delegates to the original method
|
66
|
+
#
|
67
|
+
# @param [Symbol] method
|
68
|
+
# the name of the method
|
69
|
+
# @param [#call] freezer
|
70
|
+
# a freezer for memoized values
|
71
|
+
#
|
72
|
+
# @return [undefined]
|
73
|
+
#
|
74
|
+
# @api private
|
75
|
+
def define_memoize_method(method, freezer)
|
76
|
+
original = instance_method(method)
|
77
|
+
undef_method(method)
|
78
|
+
define_method(method) do |*args|
|
79
|
+
memory.fetch(method) do
|
80
|
+
value = original.bind(self).call(*args)
|
81
|
+
frozen = freezer.call(value)
|
82
|
+
store_memory(method, frozen)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Return the method visibility of a method
|
88
|
+
#
|
89
|
+
# @param [String, Symbol] method
|
90
|
+
# the name of the method
|
91
|
+
#
|
92
|
+
# @return [Symbol]
|
93
|
+
#
|
94
|
+
# @api private
|
95
|
+
def method_visibility(method)
|
96
|
+
if private_method_defined?(method) then :private
|
97
|
+
elsif protected_method_defined?(method) then :protected
|
98
|
+
else :public
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
end # module ModuleMethods
|
103
|
+
end # module Adamantium
|
data/lib/adamantium/version.rb
CHANGED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Adamantium do
|
4
|
+
let(:class_under_test) do
|
5
|
+
mixin = self.mixin
|
6
|
+
|
7
|
+
Class.new do
|
8
|
+
include mixin
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@attribute = Object.new
|
12
|
+
end
|
13
|
+
attr_reader :attribute
|
14
|
+
|
15
|
+
def memoized
|
16
|
+
[Object.new]
|
17
|
+
end
|
18
|
+
memoize :memoized
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'inherited' do
|
23
|
+
let(:mixin) { Adamantium::Flat }
|
24
|
+
|
25
|
+
subject { Class.new(class_under_test).new }
|
26
|
+
|
27
|
+
it 'should return memoized value' do
|
28
|
+
subject.memoized
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'default' do
|
33
|
+
let(:mixin) { Adamantium }
|
34
|
+
|
35
|
+
subject { class_under_test.new }
|
36
|
+
|
37
|
+
it 'should deep freeze instance and attributes' do
|
38
|
+
should be_frozen
|
39
|
+
subject.attribute.should be_frozen
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should deep freeze memoized values' do
|
43
|
+
subject.memoized.should be_frozen
|
44
|
+
subject.memoized[0].should be_frozen
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'flat' do
|
49
|
+
let(:mixin) { Adamantium::Flat }
|
50
|
+
|
51
|
+
subject { class_under_test.new }
|
52
|
+
|
53
|
+
it 'should freeze only instance' do
|
54
|
+
should be_frozen
|
55
|
+
subject.attribute.should_not be_frozen
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should flat freeze memoized values' do
|
59
|
+
subject.memoized.should be_frozen
|
60
|
+
subject.memoized[0].should_not be_frozen
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Adamantium::ClassMethods, '#freezer' do
|
4
|
+
let(:object) do
|
5
|
+
Class.new do
|
6
|
+
include Adamantium::Flat
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
subject { object.freezer }
|
11
|
+
|
12
|
+
it { should be(Adamantium::Freezer::Flat) }
|
13
|
+
|
14
|
+
it_should_behave_like 'an idempotent method'
|
15
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Adamantium::Freezer, '.get' do
|
4
|
+
subject { object.get(name) }
|
5
|
+
|
6
|
+
let(:object) { described_class }
|
7
|
+
|
8
|
+
context 'with :deep' do
|
9
|
+
let(:name) { :deep }
|
10
|
+
|
11
|
+
it { should be(Adamantium::Freezer::Deep) }
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'with :noop' do
|
15
|
+
let(:name) { :noop }
|
16
|
+
|
17
|
+
it { should be(Adamantium::Freezer::Noop) }
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'with :flat' do
|
21
|
+
let(:name) { :flat }
|
22
|
+
|
23
|
+
it { should be(Adamantium::Freezer::Flat) }
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'with unknown name' do
|
27
|
+
let(:name) { :other }
|
28
|
+
|
29
|
+
it 'should raise error' do
|
30
|
+
expect { subject }.to raise_error(described_class::UnknownFreezerError, 'Freezer with name :other is unknown')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Adamantium::Freezer, '.parse' do
|
4
|
+
subject { object.parse(options) }
|
5
|
+
|
6
|
+
let(:object) { described_class }
|
7
|
+
let(:freezer) { mock('Freezer') }
|
8
|
+
|
9
|
+
context 'with empty options' do
|
10
|
+
let(:options) { {} }
|
11
|
+
it { should be(nil) }
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'with :freezer key' do
|
15
|
+
let(:options) { { :freezer => name } }
|
16
|
+
let(:name) { mock('Name') }
|
17
|
+
|
18
|
+
it 'should get freezer' do
|
19
|
+
described_class.should_receive(:get).with(name).and_return(freezer)
|
20
|
+
should be(freezer)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'with any other key' do
|
25
|
+
let(:options) { { :other => :key } }
|
26
|
+
|
27
|
+
it 'should raise error' do
|
28
|
+
expect { subject }.to raise_error(described_class::OptionError, 'Unknown option key(s) for memoizer [:other]')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Adamantium::Freezer::Deep, '.call' do
|
6
|
+
subject { object.call(value) }
|
7
|
+
|
8
|
+
let(:object) { self.class.described_type }
|
9
|
+
|
10
|
+
context 'with a numeric value' do
|
11
|
+
let(:value) { 1 }
|
12
|
+
|
13
|
+
it { should equal(value) }
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'with a true value' do
|
17
|
+
let(:value) { true }
|
18
|
+
|
19
|
+
it { should equal(value) }
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'with a false value' do
|
23
|
+
let(:value) { false }
|
24
|
+
|
25
|
+
it { should equal(value) }
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'with a nil value' do
|
29
|
+
let(:value) { nil }
|
30
|
+
|
31
|
+
it { should equal(value) }
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'with a symbol value' do
|
35
|
+
let(:value) { :symbol }
|
36
|
+
|
37
|
+
it { should equal(value) }
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'with a frozen value' do
|
41
|
+
let(:value) { String.new.freeze }
|
42
|
+
|
43
|
+
it { should equal(value) }
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'with a module value' do
|
47
|
+
let(:value) { Module.new }
|
48
|
+
|
49
|
+
it { should equal(value) }
|
50
|
+
|
51
|
+
it { should_not be_frozen }
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'with a class value' do
|
55
|
+
let(:value) { Class.new }
|
56
|
+
|
57
|
+
it { should equal(value) }
|
58
|
+
|
59
|
+
it { should_not be_frozen }
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'with an unfrozen value' do
|
63
|
+
let(:value) { String.new }
|
64
|
+
|
65
|
+
it { should_not equal(value) }
|
66
|
+
|
67
|
+
it { should be_instance_of(String) }
|
68
|
+
|
69
|
+
it { should == value }
|
70
|
+
|
71
|
+
it { should be_frozen }
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'with a composed value' do
|
75
|
+
let(:value) { [String.new] }
|
76
|
+
|
77
|
+
it 'does freeze inner values' do
|
78
|
+
subject.first.should be_frozen
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Adamantium::Freezer::Deep, '.freeze' do
|
4
|
+
subject { object.freeze(value) }
|
5
|
+
|
6
|
+
let(:object) { described_class }
|
7
|
+
|
8
|
+
let(:value) { mock('Value') }
|
9
|
+
|
10
|
+
it 'should deep freeze value' do
|
11
|
+
IceNine.should_receive(:deep_freeze).with(value).and_return(value)
|
12
|
+
should be(value)
|
13
|
+
end
|
14
|
+
end
|
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
describe Adamantium, '.
|
6
|
-
subject { object.
|
5
|
+
describe Adamantium::Freezer::Flat, '.call' do
|
6
|
+
subject { object.call(value) }
|
7
7
|
|
8
8
|
let(:object) { self.class.described_type }
|
9
9
|
|
@@ -54,4 +54,12 @@ describe Adamantium, '.freeze_object' do
|
|
54
54
|
|
55
55
|
it { should be_frozen }
|
56
56
|
end
|
57
|
+
|
58
|
+
context 'with a composed value' do
|
59
|
+
let(:value) { [String.new] }
|
60
|
+
|
61
|
+
it 'does NOT freeze inner values' do
|
62
|
+
subject.first.should_not be_frozen
|
63
|
+
end
|
64
|
+
end
|
57
65
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Adamantium::Freezer::Flat, '.freeze' do
|
4
|
+
subject { object.freeze(value) }
|
5
|
+
|
6
|
+
let(:object) { described_class }
|
7
|
+
|
8
|
+
let(:value) { mock('Value') }
|
9
|
+
|
10
|
+
it 'should freeze value' do
|
11
|
+
value.should_receive(:freeze).and_return(value)
|
12
|
+
should be(value)
|
13
|
+
end
|
14
|
+
end
|
@@ -7,8 +7,8 @@ describe Adamantium, '#memoize' do
|
|
7
7
|
subject { object.memoize(method, value) }
|
8
8
|
|
9
9
|
let(:described_class) { Class.new(AdamantiumSpecs::Object) }
|
10
|
-
let(:object) { described_class.new
|
11
|
-
let(:method) { :test
|
10
|
+
let(:object) { described_class.new }
|
11
|
+
let(:method) { :test }
|
12
12
|
|
13
13
|
before do
|
14
14
|
described_class.memoize(method)
|
@@ -7,9 +7,9 @@ describe Adamantium, '#memoized' do
|
|
7
7
|
subject { object.memoized(method) }
|
8
8
|
|
9
9
|
let(:described_class) { Class.new(AdamantiumSpecs::Object) }
|
10
|
-
let(:method) { :test
|
11
|
-
let(:value) { String.new.freeze
|
12
|
-
let(:object) { described_class.new
|
10
|
+
let(:method) { :test }
|
11
|
+
let(:value) { String.new.freeze }
|
12
|
+
let(:object) { described_class.new }
|
13
13
|
|
14
14
|
before do
|
15
15
|
described_class.memoize(method)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Adamantium::ModuleMethods, '#freezer' do
|
4
|
+
let(:object) do
|
5
|
+
Class.new do
|
6
|
+
include Adamantium
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
subject { object.freezer }
|
11
|
+
|
12
|
+
it { should be(Adamantium::Freezer::Deep) }
|
13
|
+
|
14
|
+
it_should_behave_like 'an idempotent method'
|
15
|
+
end
|
@@ -10,19 +10,29 @@ shared_examples_for 'memoizes method' do
|
|
10
10
|
instance.send(method).should equal(instance.send(method))
|
11
11
|
end
|
12
12
|
|
13
|
-
it 'creates a method that returns a
|
13
|
+
it 'creates a method that returns a same value' do
|
14
14
|
subject
|
15
|
-
object.new
|
15
|
+
instance = object.new
|
16
|
+
first = instance.send(method)
|
17
|
+
second = instance.send(method)
|
18
|
+
first.should be(second)
|
16
19
|
end
|
17
20
|
|
18
21
|
specification = proc do
|
19
22
|
subject
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
+
if method != :some_state
|
24
|
+
file, line = object.new.send(method).first.split(':')[0, 2]
|
25
|
+
File.expand_path(file).should eql(File.expand_path('../../../../../lib/adamantium/module_methods.rb', __FILE__))
|
26
|
+
line.to_i.should eql(80)
|
27
|
+
end
|
23
28
|
end
|
24
29
|
|
25
30
|
it 'sets the file and line number properly' do
|
31
|
+
# Exclude example for methot that does not return caller
|
32
|
+
if method == :some_method
|
33
|
+
return
|
34
|
+
end
|
35
|
+
|
26
36
|
if RUBY_PLATFORM.include?('java')
|
27
37
|
pending('Kernel#caller returns the incorrect line number in JRuby', &specification)
|
28
38
|
else
|
@@ -49,9 +59,45 @@ shared_examples_for 'memoizes method' do
|
|
49
59
|
end
|
50
60
|
|
51
61
|
describe Adamantium::ModuleMethods, '#memoize' do
|
52
|
-
subject { object.memoize(method) }
|
62
|
+
subject { object.memoize(method, options) }
|
63
|
+
let(:options) { {} }
|
64
|
+
|
65
|
+
let(:object) do
|
66
|
+
Class.new(AdamantiumSpecs::Object) do
|
67
|
+
def some_state
|
68
|
+
Object.new
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'with :noop freezer option' do
|
74
|
+
let(:method) { :some_state }
|
75
|
+
let(:options) { { :freezer => :noop } }
|
76
|
+
|
77
|
+
it_should_behave_like 'a command method'
|
78
|
+
it_should_behave_like 'memoizes method'
|
79
|
+
|
80
|
+
it 'is still a public method' do
|
81
|
+
should be_public_method_defined(method)
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'creates a method that returns a non frozen value' do
|
85
|
+
subject
|
86
|
+
object.new.send(method).should_not be_frozen
|
87
|
+
end
|
88
|
+
end
|
53
89
|
|
54
|
-
|
90
|
+
context 'memoized method that returns generated values' do
|
91
|
+
let(:method) { :some_state }
|
92
|
+
|
93
|
+
it_should_behave_like 'a command method'
|
94
|
+
it_should_behave_like 'memoizes method'
|
95
|
+
|
96
|
+
it 'creates a method that returns a frozen value' do
|
97
|
+
subject
|
98
|
+
object.new.send(method).should be_frozen
|
99
|
+
end
|
100
|
+
end
|
55
101
|
|
56
102
|
context 'public method' do
|
57
103
|
let(:method) { :public_method }
|
@@ -62,6 +108,11 @@ describe Adamantium::ModuleMethods, '#memoize' do
|
|
62
108
|
it 'is still a public method' do
|
63
109
|
should be_public_method_defined(method)
|
64
110
|
end
|
111
|
+
|
112
|
+
it 'creates a method that returns a frozen value' do
|
113
|
+
subject
|
114
|
+
object.new.send(method).should be_frozen
|
115
|
+
end
|
65
116
|
end
|
66
117
|
|
67
118
|
context 'protected method' do
|
@@ -73,6 +124,11 @@ describe Adamantium::ModuleMethods, '#memoize' do
|
|
73
124
|
it 'is still a protected method' do
|
74
125
|
should be_protected_method_defined(method)
|
75
126
|
end
|
127
|
+
|
128
|
+
it 'creates a method that returns a frozen value' do
|
129
|
+
subject
|
130
|
+
object.new.send(method).should be_frozen
|
131
|
+
end
|
76
132
|
end
|
77
133
|
|
78
134
|
context 'private method' do
|
@@ -84,5 +140,10 @@ describe Adamantium::ModuleMethods, '#memoize' do
|
|
84
140
|
it 'is still a private method' do
|
85
141
|
should be_private_method_defined(method)
|
86
142
|
end
|
143
|
+
|
144
|
+
it 'creates a method that returns a frozen value' do
|
145
|
+
subject
|
146
|
+
object.new.send(method).should be_frozen
|
147
|
+
end
|
87
148
|
end
|
88
149
|
end
|
data/tasks/metrics/ci.rake
CHANGED
@@ -5,5 +5,5 @@ task :ci => %w[ ci:metrics metrics:heckle ]
|
|
5
5
|
|
6
6
|
namespace :ci do
|
7
7
|
desc 'Run metrics (except heckle) and spec'
|
8
|
-
task :metrics => %w[ spec metrics:verify_measurements metrics:flog metrics:flay metrics:reek metrics:roodi ]
|
8
|
+
task :metrics => %w[ spec metrics:verify_measurements metrics:flog metrics:flay metrics:reek metrics:roodi metrics:all ]
|
9
9
|
end
|
data/tasks/metrics/heckle.rake
CHANGED
@@ -47,7 +47,7 @@ begin
|
|
47
47
|
map = NameMap.new
|
48
48
|
|
49
49
|
heckle_caught_modules = Hash.new { |hash, key| hash[key] = [] }
|
50
|
-
|
50
|
+
uncovered_methods = 0
|
51
51
|
|
52
52
|
ObjectSpace.each_object(Module) do |mod|
|
53
53
|
next unless mod.name =~ /\A#{root_module_regexp}(?::|\z)/
|
@@ -167,20 +167,19 @@ begin
|
|
167
167
|
case line = line.chomp
|
168
168
|
when "The following mutations didn't cause test failures:"
|
169
169
|
heckle_caught_modules[mod.name] << method
|
170
|
-
|
171
|
-
unhandled_mutations += 1
|
170
|
+
uncovered_methods += 1
|
172
171
|
end
|
173
172
|
end
|
174
173
|
end
|
175
174
|
end
|
176
175
|
end
|
177
176
|
|
178
|
-
if
|
177
|
+
if uncovered_methods > 0
|
179
178
|
error_message_lines = [ "*************\n" ]
|
180
179
|
|
181
|
-
error_message_lines << "Heckle found #{
|
182
|
-
"
|
183
|
-
"
|
180
|
+
error_message_lines << "Heckle found #{uncovered_methods} " \
|
181
|
+
"method#{"s" unless uncovered_methods == 1} " \
|
182
|
+
"where mutations didn't cause spec violations\n"
|
184
183
|
|
185
184
|
heckle_caught_modules.each do |mod, methods|
|
186
185
|
error_message_lines << "#{mod} contains the following " \
|
@@ -201,7 +200,9 @@ begin
|
|
201
200
|
end
|
202
201
|
end
|
203
202
|
rescue LoadError
|
204
|
-
|
205
|
-
|
203
|
+
namespace :metrics do
|
204
|
+
task :heckle => :coverage do
|
205
|
+
$stderr.puts 'Heckle or mspec is not available. In order to run heckle, you must: gem install heckle mspec'
|
206
|
+
end
|
206
207
|
end
|
207
208
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: adamantium
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 3
|
10
|
+
version: 0.0.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Dan Kubb
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2012-
|
19
|
+
date: 2012-11-14 00:00:00 Z
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
22
|
name: backports
|
@@ -128,7 +128,11 @@ files:
|
|
128
128
|
- config/site.reek
|
129
129
|
- config/yardstick.yml
|
130
130
|
- lib/adamantium.rb
|
131
|
+
- lib/adamantium/class_methods.rb
|
132
|
+
- lib/adamantium/freezer.rb
|
133
|
+
- lib/adamantium/module_methods.rb
|
131
134
|
- lib/adamantium/version.rb
|
135
|
+
- spec/integration/adamantium_spec.rb
|
132
136
|
- spec/rcov.opts
|
133
137
|
- spec/shared/command_method_behavior.rb
|
134
138
|
- spec/shared/each_method_behaviour.rb
|
@@ -138,13 +142,20 @@ files:
|
|
138
142
|
- spec/spec.opts
|
139
143
|
- spec/spec_helper.rb
|
140
144
|
- spec/support/config_alias.rb
|
141
|
-
- spec/unit/adamantium/class_methods/freeze_object_spec.rb
|
142
145
|
- spec/unit/adamantium/class_methods/new_spec.rb
|
143
146
|
- spec/unit/adamantium/dup_spec.rb
|
144
147
|
- spec/unit/adamantium/fixtures/classes.rb
|
148
|
+
- spec/unit/adamantium/flat/freezer_spec.rb
|
145
149
|
- spec/unit/adamantium/freeze_spec.rb
|
150
|
+
- spec/unit/adamantium/freezer/class_methods/get_spec.rb
|
151
|
+
- spec/unit/adamantium/freezer/class_methods/parse_spec.rb
|
152
|
+
- spec/unit/adamantium/freezer/deep/class_methods/call_spec.rb
|
153
|
+
- spec/unit/adamantium/freezer/deep/class_methods/freeze_spec.rb
|
154
|
+
- spec/unit/adamantium/freezer/flat/class_methods/call_spec.rb
|
155
|
+
- spec/unit/adamantium/freezer/flat/class_methods/freeze_spec.rb
|
146
156
|
- spec/unit/adamantium/memoize_spec.rb
|
147
157
|
- spec/unit/adamantium/memoized_spec.rb
|
158
|
+
- spec/unit/adamantium/module_methods/freezer_spec.rb
|
148
159
|
- spec/unit/adamantium/module_methods/included_spec.rb
|
149
160
|
- spec/unit/adamantium/module_methods/memoize_spec.rb
|
150
161
|
- tasks/metrics/ci.rake
|
@@ -191,13 +202,21 @@ signing_key:
|
|
191
202
|
specification_version: 3
|
192
203
|
summary: Immutable extensions to objects
|
193
204
|
test_files:
|
194
|
-
- spec/
|
205
|
+
- spec/integration/adamantium_spec.rb
|
195
206
|
- spec/unit/adamantium/class_methods/new_spec.rb
|
196
207
|
- spec/unit/adamantium/dup_spec.rb
|
197
208
|
- spec/unit/adamantium/fixtures/classes.rb
|
209
|
+
- spec/unit/adamantium/flat/freezer_spec.rb
|
198
210
|
- spec/unit/adamantium/freeze_spec.rb
|
211
|
+
- spec/unit/adamantium/freezer/class_methods/get_spec.rb
|
212
|
+
- spec/unit/adamantium/freezer/class_methods/parse_spec.rb
|
213
|
+
- spec/unit/adamantium/freezer/deep/class_methods/call_spec.rb
|
214
|
+
- spec/unit/adamantium/freezer/deep/class_methods/freeze_spec.rb
|
215
|
+
- spec/unit/adamantium/freezer/flat/class_methods/call_spec.rb
|
216
|
+
- spec/unit/adamantium/freezer/flat/class_methods/freeze_spec.rb
|
199
217
|
- spec/unit/adamantium/memoize_spec.rb
|
200
218
|
- spec/unit/adamantium/memoized_spec.rb
|
219
|
+
- spec/unit/adamantium/module_methods/freezer_spec.rb
|
201
220
|
- spec/unit/adamantium/module_methods/included_spec.rb
|
202
221
|
- spec/unit/adamantium/module_methods/memoize_spec.rb
|
203
222
|
has_rdoc:
|