adamantium 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.
- checksums.yaml +6 -14
- data/.gitignore +37 -4
- data/.rubocop.yml +6 -0
- data/.travis.yml +11 -8
- data/Gemfile.devtools +27 -13
- data/README.md +7 -7
- data/adamantium.gemspec +4 -4
- data/config/flay.yml +2 -2
- data/config/flog.yml +1 -1
- data/config/reek.yml +2 -1
- data/config/rubocop.yml +6 -8
- data/lib/adamantium.rb +30 -91
- data/lib/adamantium/class_methods.rb +2 -2
- data/lib/adamantium/freezer.rb +10 -8
- data/lib/adamantium/module_methods.rb +15 -129
- data/lib/adamantium/version.rb +2 -2
- data/spec/spec_helper.rb +6 -3
- data/spec/unit/adamantium/fixtures/classes.rb +6 -0
- data/spec/unit/adamantium/freeze_spec.rb +0 -15
- data/spec/unit/adamantium/freezer/deep/class_methods/freeze_spec.rb +1 -1
- data/spec/unit/adamantium/memoize_spec.rb +6 -29
- data/spec/unit/adamantium/module_methods/included_spec.rb +29 -5
- data/spec/unit/adamantium/module_methods/memoize_spec.rb +8 -13
- data/spec/unit/adamantium/transform_spec.rb +35 -0
- data/spec/unit/adamantium/transform_unless_spec.rb +37 -0
- metadata +21 -22
- data/spec/unit/adamantium/class_methods/included_spec.rb +0 -40
- data/spec/unit/adamantium/memoized_spec.rb +0 -29
- data/spec/unit/adamantium/module_methods/original_instance_method_spec.rb +0 -36
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
NjU3MDcxN2UzNzU1ZWZlYzEyY2VkMzgzNWJiNTFhNDc0MmMzNWZhNzJkOGYy
|
10
|
-
YTRkNjhkMTRiMmIyMzAwZjk0Yjk2NDJlMmZjODY3NTVhNTNlZDcwZDgwMjMx
|
11
|
-
ODRjYjZmOGE4OTZlODNmNTIwMDJiYzE0N2ViNmE2NmQ5YjFiNTM=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
ODY0NDUyODM1YTg3OTMwMWJlMTU4YzFhNzUzZmY1NGE1NWE0ZTQzMmRiMDEz
|
14
|
-
ZWExY2RhY2Y4YWQ3MTI1MjBlODRhODlhNWE2Y2ZlYjMxMmI5YjgzYWNhM2Uy
|
15
|
-
YTY0NWMwYjNmYzc1ZjcxMWU1OThlMWQyNjgwYWE0NzM2YWZiZjk=
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4675912f9a7cb3eb823638436c1be23e6753d24b
|
4
|
+
data.tar.gz: cbf0680ce697e2da134bc86d83582a1928952d8e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 81ab12f754e252929d3074a9a85f53af07a3a93d8db946beac48124f6f03c7528741d1716e221fb07eac9daf95031e9e2847aa72509135fd017a71a1dcfbbb53
|
7
|
+
data.tar.gz: 5c7246f7aaab383bd952af49971a6046dc953f96a2553e8c2e7539191bb53408a9fb0ebb71e215714d5250aa8fef426d7330dded7c090b13ba38883e45b84fa0
|
data/.gitignore
CHANGED
@@ -1,4 +1,37 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
## MAC OS
|
2
|
+
.DS_Store
|
3
|
+
|
4
|
+
## TEXTMATE
|
5
|
+
*.tmproj
|
6
|
+
tmtags
|
7
|
+
|
8
|
+
## EMACS
|
9
|
+
*~
|
10
|
+
\#*
|
11
|
+
.\#*
|
12
|
+
|
13
|
+
## VIM
|
14
|
+
*.sw[op]
|
15
|
+
|
16
|
+
## Rubinius
|
17
|
+
*.rbc
|
18
|
+
.rbx
|
19
|
+
|
20
|
+
## PROJECT::GENERAL
|
21
|
+
*.gem
|
22
|
+
coverage
|
23
|
+
profiling
|
24
|
+
turbulence
|
25
|
+
rdoc
|
26
|
+
pkg
|
27
|
+
tmp
|
28
|
+
doc
|
29
|
+
log
|
30
|
+
.yardoc
|
31
|
+
measurements
|
32
|
+
|
33
|
+
## BUNDLER
|
34
|
+
.bundle
|
35
|
+
Gemfile.lock
|
36
|
+
|
37
|
+
## PROJECT::SPECIFIC
|
data/.rubocop.yml
ADDED
data/.travis.yml
CHANGED
@@ -1,23 +1,26 @@
|
|
1
1
|
language: ruby
|
2
2
|
before_install: gem install bundler
|
3
3
|
bundler_args: --without yard guard benchmarks
|
4
|
-
script: "bundle exec rake ci"
|
4
|
+
script: "bundle exec rake ci:metrics"
|
5
5
|
rvm:
|
6
6
|
- 1.9.3
|
7
7
|
- 2.0.0
|
8
|
+
- 2.1.0
|
8
9
|
- ruby-head
|
9
|
-
- rbx
|
10
|
+
- rbx
|
10
11
|
matrix:
|
11
12
|
include:
|
12
13
|
- rvm: jruby-19mode
|
13
|
-
env: JRUBY_OPTS="$JRUBY_OPTS --debug"
|
14
|
+
env: JRUBY_OPTS="$JRUBY_OPTS --debug" # for simplecov
|
15
|
+
- rvm: jruby-20mode
|
16
|
+
env: JRUBY_OPTS="$JRUBY_OPTS --debug" # for simplecov
|
17
|
+
- rvm: jruby-21mode
|
18
|
+
env: JRUBY_OPTS="$JRUBY_OPTS --debug" # for simplecov
|
14
19
|
- rvm: jruby-head
|
15
|
-
env: JRUBY_OPTS="$JRUBY_OPTS --debug"
|
20
|
+
env: JRUBY_OPTS="$JRUBY_OPTS --debug" # for simplecov
|
16
21
|
allow_failures:
|
17
|
-
- rvm: 1.
|
18
|
-
|
19
|
-
- rvm: ruby-head # travis broken
|
20
|
-
- rvm: rbx-19mode # mutant fails
|
22
|
+
- rvm: 2.1.0 # buggy runtime
|
23
|
+
fast_finish: true
|
21
24
|
notifications:
|
22
25
|
irc:
|
23
26
|
channels:
|
data/Gemfile.devtools
CHANGED
@@ -4,21 +4,24 @@ group :development do
|
|
4
4
|
gem 'rake', '~> 10.1.0'
|
5
5
|
gem 'rspec', '~> 2.14.1'
|
6
6
|
gem 'yard', '~> 0.8.7'
|
7
|
+
|
8
|
+
platform :rbx do
|
9
|
+
gem 'rubysl-singleton', '~> 2.0.0'
|
10
|
+
end
|
7
11
|
end
|
8
12
|
|
9
13
|
group :yard do
|
10
|
-
gem 'kramdown', '~> 1.
|
14
|
+
gem 'kramdown', '~> 1.3.0'
|
11
15
|
end
|
12
16
|
|
13
17
|
group :guard do
|
14
|
-
gem 'guard', '~>
|
15
|
-
gem 'guard-bundler', '~>
|
16
|
-
gem 'guard-rspec', '~>
|
17
|
-
gem 'guard-rubocop', '~> 0.
|
18
|
-
# gem 'guard-mutant', '~> 0.0.1'
|
18
|
+
gem 'guard', '~> 2.3.0'
|
19
|
+
gem 'guard-bundler', '~> 2.0.0'
|
20
|
+
gem 'guard-rspec', '~> 4.2.0'
|
21
|
+
gem 'guard-rubocop', '~> 1.0.0'
|
19
22
|
|
20
23
|
# file system change event handling
|
21
|
-
gem 'listen', '~>
|
24
|
+
gem 'listen', '~> 2.4.0'
|
22
25
|
gem 'rb-fchange', '~> 0.0.6', require: false
|
23
26
|
gem 'rb-fsevent', '~> 0.9.3', require: false
|
24
27
|
gem 'rb-inotify', '~> 0.9.0', require: false
|
@@ -30,18 +33,29 @@ group :guard do
|
|
30
33
|
end
|
31
34
|
|
32
35
|
group :metrics do
|
33
|
-
gem 'coveralls', '~> 0.
|
36
|
+
gem 'coveralls', '~> 0.7.0'
|
34
37
|
gem 'flay', '~> 2.4.0'
|
35
|
-
gem 'flog', '~> 4.
|
38
|
+
gem 'flog', '~> 4.2.0'
|
36
39
|
gem 'reek', '~> 1.3.2'
|
37
|
-
gem 'rubocop', '~> 0.
|
38
|
-
gem 'simplecov', '~> 0.
|
39
|
-
gem 'yardstick', '~> 0.9.
|
40
|
+
gem 'rubocop', '~> 0.16.0'
|
41
|
+
gem 'simplecov', '~> 0.8.2'
|
42
|
+
gem 'yardstick', '~> 0.9.9'
|
43
|
+
|
44
|
+
platforms :mri do
|
45
|
+
gem 'mutant', '~> 0.3.4'
|
46
|
+
end
|
40
47
|
|
41
48
|
platforms :ruby_19, :ruby_20 do
|
42
|
-
# gem 'mutant', git: 'https://github.com/mbj/mutant.git'
|
43
49
|
gem 'yard-spellcheck', '~> 0.1.5'
|
44
50
|
end
|
51
|
+
|
52
|
+
platform :rbx do
|
53
|
+
gem 'json', '~> 1.8.1'
|
54
|
+
gem 'racc', '~> 1.4'
|
55
|
+
gem 'rubysl-logger', '~> 2.0.0'
|
56
|
+
gem 'rubysl-open-uri', '~> 2.0.0'
|
57
|
+
gem 'rubysl-prettyprint', '~> 2.0.2'
|
58
|
+
end
|
45
59
|
end
|
46
60
|
|
47
61
|
group :benchmarks do
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
adamantium
|
2
2
|
==========
|
3
3
|
|
4
|
-
Create immutable objects
|
4
|
+
Create immutable objects with ease.
|
5
5
|
|
6
6
|
[][gem]
|
7
7
|
[][travis]
|
@@ -16,7 +16,7 @@ Create immutable objects
|
|
16
16
|
[coveralls]: https://coveralls.io/r/dkubb/adamantium
|
17
17
|
|
18
18
|
This is a small standalone gem featuring a module ripped out from [axiom](https://github.com/dkubb/axiom).
|
19
|
-
It allows to make objects immutable in
|
19
|
+
It allows you to make objects immutable in a simple, unobtrusive way.
|
20
20
|
|
21
21
|
Examples
|
22
22
|
--------
|
@@ -70,7 +70,7 @@ class Example
|
|
70
70
|
end
|
71
71
|
memoize :buffer, freezer: :noop
|
72
72
|
|
73
|
-
# Memoized method with
|
73
|
+
# Memoized method with shallow frozen value
|
74
74
|
# Example:
|
75
75
|
#
|
76
76
|
# object = Example.new
|
@@ -86,12 +86,12 @@ class Example
|
|
86
86
|
end
|
87
87
|
|
88
88
|
class FlatExample
|
89
|
-
# Inclusion of Adamantium::Flat defaults
|
90
|
-
# for memoizer and constructor
|
89
|
+
# Inclusion of Adamantium::Flat defaults to shallow frozen
|
90
|
+
# behavior for memoizer and constructor
|
91
91
|
|
92
92
|
include Adamantium::Flat
|
93
93
|
|
94
|
-
#
|
94
|
+
# Instance is frozen but attribute is not
|
95
95
|
# object = FlatExample.new
|
96
96
|
# object.frozen? # => true
|
97
97
|
# object.attribute.frozen? # => false
|
@@ -100,7 +100,7 @@ class FlatExample
|
|
100
100
|
end
|
101
101
|
attr_reader :attribute
|
102
102
|
|
103
|
-
# Memoized method with flat frozen value (default)
|
103
|
+
# Memoized method with flat frozen value (default with Adamantium::Flat)
|
104
104
|
# Example:
|
105
105
|
#
|
106
106
|
# object = Example.new
|
data/adamantium.gemspec
CHANGED
@@ -10,15 +10,15 @@ Gem::Specification.new do |gem|
|
|
10
10
|
gem.description = 'Immutable extensions to objects'
|
11
11
|
gem.summary = gem.description
|
12
12
|
gem.homepage = 'https://github.com/dkubb/adamantium'
|
13
|
-
gem.
|
13
|
+
gem.license = 'MIT'
|
14
14
|
|
15
15
|
gem.require_paths = %w[lib]
|
16
16
|
gem.files = `git ls-files`.split("\n")
|
17
17
|
gem.test_files = `git ls-files -- spec/{unit,integration}`.split("\n")
|
18
18
|
gem.extra_rdoc_files = %w[LICENSE README.md CONTRIBUTING.md TODO]
|
19
19
|
|
20
|
-
gem.add_runtime_dependency('ice_nine',
|
21
|
-
gem.add_runtime_dependency('
|
20
|
+
gem.add_runtime_dependency('ice_nine', '~> 0.11.0')
|
21
|
+
gem.add_runtime_dependency('memoizable', '~> 0.4.0')
|
22
22
|
|
23
|
-
gem.add_development_dependency('bundler', '~> 1.
|
23
|
+
gem.add_development_dependency('bundler', '~> 1.5', '>= 1.5.2')
|
24
24
|
end
|
data/config/flay.yml
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
---
|
2
|
-
threshold:
|
3
|
-
total_score:
|
2
|
+
threshold: 4
|
3
|
+
total_score: 28
|
data/config/flog.yml
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
---
|
2
|
-
threshold:
|
2
|
+
threshold: 15.0
|
data/config/reek.yml
CHANGED
data/config/rubocop.yml
CHANGED
@@ -1,10 +1,4 @@
|
|
1
|
-
|
2
|
-
Includes:
|
3
|
-
- '**/*.rake'
|
4
|
-
- 'Gemfile'
|
5
|
-
- 'Gemfile.devtools'
|
6
|
-
Excludes:
|
7
|
-
- '**/vendor/**'
|
1
|
+
inherit_from: ../.rubocop.yml
|
8
2
|
|
9
3
|
# Avoid parameter lists longer than five parameters.
|
10
4
|
ParameterLists:
|
@@ -29,7 +23,7 @@ CollectionMethods:
|
|
29
23
|
# sections of code and visually separate them. When the keyword is at the same
|
30
24
|
# level I think it sort of blends in with the def keywords and makes it harder
|
31
25
|
# to scan the code and see where the sections are.
|
32
|
-
|
26
|
+
AccessModifierIndentation:
|
33
27
|
Enabled: false
|
34
28
|
|
35
29
|
# Limit line length
|
@@ -55,3 +49,7 @@ ConstantName:
|
|
55
49
|
# Not all trivial readers/writers can be defined with attr_* methods
|
56
50
|
TrivialAccessors:
|
57
51
|
Enabled: false
|
52
|
+
|
53
|
+
# Allow empty lines around body
|
54
|
+
EmptyLinesAroundBody:
|
55
|
+
Enabled: false
|
data/lib/adamantium.rb
CHANGED
@@ -1,14 +1,11 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
require 'ice_nine'
|
4
|
-
require '
|
4
|
+
require 'memoizable'
|
5
5
|
|
6
6
|
# Allows objects to be made immutable
|
7
7
|
module Adamantium
|
8
8
|
|
9
|
-
# Storage for memoized methods
|
10
|
-
Memory = Class.new(ThreadSafe::Hash)
|
11
|
-
|
12
9
|
# Defaults to less strict defaults
|
13
10
|
module Flat
|
14
11
|
|
@@ -17,7 +14,6 @@ module Adamantium
|
|
17
14
|
# @return [Freezer::Flat]
|
18
15
|
#
|
19
16
|
# @api private
|
20
|
-
#
|
21
17
|
def freezer
|
22
18
|
Freezer::Flat
|
23
19
|
end
|
@@ -31,8 +27,10 @@ module Adamantium
|
|
31
27
|
# @api private
|
32
28
|
def self.included(descendant)
|
33
29
|
super
|
34
|
-
descendant.
|
35
|
-
|
30
|
+
descendant.instance_exec(self) do |mod|
|
31
|
+
include Adamantium
|
32
|
+
extend mod
|
33
|
+
end
|
36
34
|
end
|
37
35
|
private_class_method :included
|
38
36
|
|
@@ -47,58 +45,22 @@ module Adamantium
|
|
47
45
|
#
|
48
46
|
# @api private
|
49
47
|
def self.included(descendant)
|
50
|
-
descendant.extend ModuleMethods
|
51
|
-
descendant.extend ClassMethods if descendant.kind_of?(Class)
|
52
|
-
self
|
53
|
-
end
|
54
|
-
|
55
|
-
# Freeze the object
|
56
|
-
#
|
57
|
-
# @example
|
58
|
-
# object.freeze # object is now frozen
|
59
|
-
#
|
60
|
-
# @return [Object]
|
61
|
-
#
|
62
|
-
# @api public
|
63
|
-
def freeze
|
64
|
-
memory # initialize memory
|
65
48
|
super
|
49
|
+
descendant.class_eval do
|
50
|
+
include Memoizable
|
51
|
+
extend ModuleMethods
|
52
|
+
extend ClassMethods if kind_of?(Class)
|
53
|
+
end
|
66
54
|
end
|
55
|
+
private_class_method :included
|
67
56
|
|
68
|
-
#
|
69
|
-
#
|
70
|
-
# @example
|
71
|
-
# hash = object.memoized(:hash)
|
72
|
-
#
|
73
|
-
# @param [Symbol] name
|
74
|
-
# the method name
|
57
|
+
# Alias to the original dup method
|
75
58
|
#
|
76
59
|
# @return [Object]
|
77
60
|
#
|
78
|
-
# @api
|
79
|
-
|
80
|
-
|
81
|
-
end
|
82
|
-
|
83
|
-
# Sets a memoized value for a method
|
84
|
-
#
|
85
|
-
# @example
|
86
|
-
# object.memoize(:hash, 12345)
|
87
|
-
#
|
88
|
-
# @param [Symbol] name
|
89
|
-
# the method name
|
90
|
-
# @param [Object] value
|
91
|
-
# the value to memoize
|
92
|
-
#
|
93
|
-
# @return [self]
|
94
|
-
#
|
95
|
-
# @api public
|
96
|
-
def memoize(name, value)
|
97
|
-
unless memory.key?(name)
|
98
|
-
store_memory(name, freeze_object(value))
|
99
|
-
end
|
100
|
-
self
|
101
|
-
end
|
61
|
+
# @api private
|
62
|
+
alias_method :__adamantium_dup__, :dup
|
63
|
+
private :__adamantium_dup__
|
102
64
|
|
103
65
|
# A noop #dup for immutable objects
|
104
66
|
#
|
@@ -112,57 +74,34 @@ module Adamantium
|
|
112
74
|
self
|
113
75
|
end
|
114
76
|
|
115
|
-
|
116
|
-
|
117
|
-
# The memoized method results
|
118
|
-
#
|
119
|
-
# @return [Hash]
|
120
|
-
#
|
121
|
-
# @api private
|
122
|
-
def memory
|
123
|
-
@__memory ||= Memory.new
|
124
|
-
end
|
77
|
+
protected
|
125
78
|
|
126
|
-
#
|
127
|
-
#
|
128
|
-
# @param [Object] object
|
129
|
-
# an object to be frozen
|
79
|
+
# Transform the object with the provided block
|
130
80
|
#
|
131
81
|
# @return [Object]
|
132
82
|
#
|
133
|
-
# @api
|
134
|
-
def
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
# Return class level freezer
|
139
|
-
#
|
140
|
-
# @return [#call]
|
141
|
-
#
|
142
|
-
# @api private
|
143
|
-
def freezer
|
144
|
-
self.class.freezer
|
83
|
+
# @api public
|
84
|
+
def transform(&block)
|
85
|
+
copy = __adamantium_dup__
|
86
|
+
copy.instance_eval(&block)
|
87
|
+
self.class.freezer.freeze(copy)
|
145
88
|
end
|
146
89
|
|
147
|
-
#
|
90
|
+
# Transform the object with the provided block if the condition is false
|
148
91
|
#
|
149
|
-
# @param [
|
150
|
-
# the method name
|
151
|
-
# @param [Object] value
|
152
|
-
# the value to memoize
|
92
|
+
# @param [Boolean] condition
|
153
93
|
#
|
154
|
-
# @return [
|
155
|
-
#
|
156
|
-
# @return [value]
|
94
|
+
# @return [Object]
|
157
95
|
#
|
158
|
-
# @api
|
159
|
-
def
|
160
|
-
|
96
|
+
# @api public
|
97
|
+
def transform_unless(condition, &block)
|
98
|
+
condition ? self : transform(&block)
|
161
99
|
end
|
162
100
|
|
163
|
-
end #
|
101
|
+
end # Adamantium
|
164
102
|
|
165
103
|
require 'adamantium/module_methods'
|
166
104
|
require 'adamantium/class_methods'
|
167
105
|
require 'adamantium/freezer'
|
168
106
|
require 'adamantium/mutable'
|
107
|
+
require 'adamantium/version'
|
data/lib/adamantium/freezer.rb
CHANGED
@@ -80,7 +80,7 @@ module Adamantium
|
|
80
80
|
#
|
81
81
|
# @api private
|
82
82
|
def self.freeze(value)
|
83
|
-
IceNine.deep_freeze(value)
|
83
|
+
IceNine.deep_freeze!(value)
|
84
84
|
end
|
85
85
|
|
86
86
|
public_class_method :call
|
@@ -94,6 +94,12 @@ module Adamantium
|
|
94
94
|
# Error raised when memoizer options contain unknown keys
|
95
95
|
class OptionError < RuntimeError; end
|
96
96
|
|
97
|
+
@freezers = {
|
98
|
+
noop: Noop,
|
99
|
+
deep: Deep,
|
100
|
+
flat: Flat,
|
101
|
+
}.freeze
|
102
|
+
|
97
103
|
# Return freezer for name
|
98
104
|
#
|
99
105
|
# @param [Symbol] name
|
@@ -103,12 +109,8 @@ module Adamantium
|
|
103
109
|
#
|
104
110
|
# @api private
|
105
111
|
def self.get(name)
|
106
|
-
|
107
|
-
|
108
|
-
when :deep then Deep
|
109
|
-
when :flat then Flat
|
110
|
-
else
|
111
|
-
raise UnknownFreezerError, "Freezer with name #{name.inspect} is unknown"
|
112
|
+
@freezers.fetch(name) do
|
113
|
+
fail UnknownFreezerError, "Freezer with name #{name.inspect} is unknown"
|
112
114
|
end
|
113
115
|
end
|
114
116
|
|
@@ -128,7 +130,7 @@ module Adamantium
|
|
128
130
|
def self.parse(options)
|
129
131
|
keys = options.keys - [:freezer]
|
130
132
|
unless keys.empty?
|
131
|
-
|
133
|
+
fail OptionError, "Unknown option key(s) for memoizer #{keys.inspect}"
|
132
134
|
end
|
133
135
|
get(options.fetch(:freezer)) if options.key?(:freezer)
|
134
136
|
end
|
@@ -5,25 +5,11 @@ module Adamantium
|
|
5
5
|
# Methods mixed in to adamantium modules
|
6
6
|
module ModuleMethods
|
7
7
|
|
8
|
-
# Hook called when module is included
|
9
|
-
#
|
10
|
-
# @param [Module] mod
|
11
|
-
# the module including ModuleMethods
|
12
|
-
#
|
13
|
-
# @return [self]
|
14
|
-
#
|
15
|
-
# @api private
|
16
|
-
def included(mod)
|
17
|
-
Adamantium.included(mod)
|
18
|
-
self
|
19
|
-
end
|
20
|
-
|
21
8
|
# Return default deep freezer
|
22
9
|
#
|
23
10
|
# @return [Freezer::Deep]
|
24
11
|
#
|
25
12
|
# @api private
|
26
|
-
#
|
27
13
|
def freezer
|
28
14
|
Freezer::Deep
|
29
15
|
end
|
@@ -46,135 +32,35 @@ module Adamantium
|
|
46
32
|
self
|
47
33
|
end
|
48
34
|
|
49
|
-
|
50
|
-
#
|
51
|
-
# @example
|
52
|
-
# class Foo
|
53
|
-
# include Adamantium
|
54
|
-
#
|
55
|
-
# def bar
|
56
|
-
# end
|
57
|
-
# memoize :bar
|
58
|
-
#
|
59
|
-
# end
|
60
|
-
#
|
61
|
-
# Foo.memoized?(:bar) # true
|
62
|
-
# Foo.memoized?(:baz) # false, does not care if method acutally exists
|
63
|
-
#
|
64
|
-
# @param [Symbol] name
|
65
|
-
#
|
66
|
-
# @return [true]
|
67
|
-
# if method is memoized
|
68
|
-
#
|
69
|
-
# @return [false]
|
70
|
-
# otherwise
|
71
|
-
#
|
72
|
-
# @api private
|
73
|
-
#
|
74
|
-
def memoized?(name)
|
75
|
-
memoized_methods.key?(name)
|
76
|
-
end
|
35
|
+
private
|
77
36
|
|
78
|
-
#
|
79
|
-
#
|
80
|
-
# @example
|
81
|
-
#
|
82
|
-
# class Foo
|
83
|
-
# include Adamantium
|
84
|
-
#
|
85
|
-
# def bar
|
86
|
-
# end
|
87
|
-
# memoize :bar
|
88
|
-
#
|
89
|
-
# end
|
90
|
-
#
|
91
|
-
# Foo.original_instance_method(:bar) #=> UnboundMethod, where source_location still points to original!
|
92
|
-
#
|
93
|
-
# @param [Symbol] name
|
94
|
-
#
|
95
|
-
# @return [UnboundMethod]
|
96
|
-
# if method was memoized before
|
37
|
+
# Hook called when module is included
|
97
38
|
#
|
98
|
-
# @
|
99
|
-
#
|
39
|
+
# @param [Module] descendant
|
40
|
+
# the module including ModuleMethods
|
100
41
|
#
|
101
|
-
# @
|
42
|
+
# @return [self]
|
102
43
|
#
|
103
|
-
|
104
|
-
|
44
|
+
# @api private
|
45
|
+
def included(descendant)
|
46
|
+
super
|
47
|
+
descendant.module_eval { include Adamantium }
|
105
48
|
end
|
106
49
|
|
107
|
-
private
|
108
|
-
|
109
50
|
# Memoize the named method
|
110
51
|
#
|
111
|
-
# @param [
|
52
|
+
# @param [Symbol] method_name
|
112
53
|
# a method name to memoize
|
113
54
|
# @param [#call] freezer
|
114
|
-
# a
|
55
|
+
# a callable object to freeze the value
|
115
56
|
#
|
116
57
|
# @return [undefined]
|
117
58
|
#
|
118
59
|
# @api private
|
119
60
|
def memoize_method(method_name, freezer)
|
120
|
-
|
121
|
-
|
122
|
-
raise ArgumentError, 'Cannot memoize method with nonzero arity'
|
123
|
-
end
|
124
|
-
memoized_methods[method_name] = method
|
125
|
-
visibility = method_visibility(method_name)
|
126
|
-
define_memoize_method(method, freezer)
|
127
|
-
send(visibility, method_name)
|
128
|
-
end
|
129
|
-
|
130
|
-
# Return original method registry
|
131
|
-
#
|
132
|
-
# @return [Hash<Symbol, UnboundMethod>]
|
133
|
-
#
|
134
|
-
# @api private
|
135
|
-
#
|
136
|
-
def memoized_methods
|
137
|
-
@memoized_methods ||= ThreadSafe::Hash.new do |_, name|
|
138
|
-
raise ArgumentError, "No method #{name.inspect} was memoized"
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
# Define a memoized method that delegates to the original method
|
143
|
-
#
|
144
|
-
# @param [UnboundMethod] method
|
145
|
-
# the method to memoize
|
146
|
-
# @param [#call] freezer
|
147
|
-
# a freezer for memoized values
|
148
|
-
#
|
149
|
-
# @return [undefined]
|
150
|
-
#
|
151
|
-
# @api private
|
152
|
-
def define_memoize_method(method, freezer)
|
153
|
-
method_name = method.name.to_sym
|
154
|
-
undef_method(method_name)
|
155
|
-
define_method(method_name) do ||
|
156
|
-
memory.fetch(method_name) do
|
157
|
-
value = method.bind(self).call
|
158
|
-
frozen = freezer.call(value)
|
159
|
-
store_memory(method_name, frozen)
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
# Return the method visibility of a method
|
165
|
-
#
|
166
|
-
# @param [String, Symbol] method
|
167
|
-
# the name of the method
|
168
|
-
#
|
169
|
-
# @return [Symbol]
|
170
|
-
#
|
171
|
-
# @api private
|
172
|
-
def method_visibility(method)
|
173
|
-
if private_method_defined?(method) then :private
|
174
|
-
elsif protected_method_defined?(method) then :protected
|
175
|
-
else :public
|
176
|
-
end
|
61
|
+
memoized_methods[method_name] = Memoizable::MethodBuilder
|
62
|
+
.new(self, method_name, freezer).call
|
177
63
|
end
|
178
64
|
|
179
|
-
end #
|
180
|
-
end #
|
65
|
+
end # ModuleMethods
|
66
|
+
end # Adamantium
|
data/lib/adamantium/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -12,9 +12,12 @@ if ENV['COVERAGE'] == 'true'
|
|
12
12
|
]
|
13
13
|
|
14
14
|
SimpleCov.start do
|
15
|
-
command_name
|
16
|
-
|
17
|
-
add_filter
|
15
|
+
command_name 'spec:unit'
|
16
|
+
|
17
|
+
add_filter 'config'
|
18
|
+
add_filter 'spec'
|
19
|
+
add_filter 'vendor'
|
20
|
+
|
18
21
|
minimum_coverage 100
|
19
22
|
end
|
20
23
|
end
|
@@ -4,6 +4,8 @@ module AdamantiumSpecs
|
|
4
4
|
class Object
|
5
5
|
include Adamantium
|
6
6
|
|
7
|
+
public :transform, :transform_unless
|
8
|
+
|
7
9
|
def argumented(foo)
|
8
10
|
end
|
9
11
|
|
@@ -15,6 +17,10 @@ module AdamantiumSpecs
|
|
15
17
|
caller
|
16
18
|
end
|
17
19
|
|
20
|
+
def eql?(other)
|
21
|
+
kind_of?(other.class)
|
22
|
+
end
|
23
|
+
|
18
24
|
protected
|
19
25
|
|
20
26
|
def protected_method
|
@@ -22,12 +22,6 @@ describe Adamantium, '#freeze' do
|
|
22
22
|
.from(false)
|
23
23
|
.to(true)
|
24
24
|
end
|
25
|
-
|
26
|
-
it 'sets a memoization instance variable' do
|
27
|
-
expect(object).to_not be_instance_variable_defined(:@__memory)
|
28
|
-
subject
|
29
|
-
expect(object.instance_variable_get(:@__memory)).to be_instance_of(Adamantium::Memory)
|
30
|
-
end
|
31
25
|
end
|
32
26
|
|
33
27
|
context 'with a frozen object' do
|
@@ -38,14 +32,5 @@ describe Adamantium, '#freeze' do
|
|
38
32
|
it 'does not change the frozen state of the object' do
|
39
33
|
expect { subject }.to_not change(object, :frozen?)
|
40
34
|
end
|
41
|
-
|
42
|
-
it 'does not change the memoization instance variable' do
|
43
|
-
expect { subject }.to_not change { object.instance_variable_get(:@__memory) }
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'does not set an instance variable for memoization' do
|
47
|
-
expect(object.instance_variable_get(:@__memory)).to be_instance_of(Adamantium::Memory)
|
48
|
-
subject
|
49
|
-
end
|
50
35
|
end
|
51
36
|
end
|
@@ -9,7 +9,7 @@ describe Adamantium::Freezer::Deep, '.freeze' do
|
|
9
9
|
let(:value) { double('Value') }
|
10
10
|
|
11
11
|
it 'should deep freeze value' do
|
12
|
-
IceNine.should_receive(:deep_freeze).with(value).and_return(value)
|
12
|
+
IceNine.should_receive(:deep_freeze!).with(value).and_return(value)
|
13
13
|
should be(value)
|
14
14
|
end
|
15
15
|
end
|
@@ -4,7 +4,7 @@ require 'spec_helper'
|
|
4
4
|
require File.expand_path('../fixtures/classes', __FILE__)
|
5
5
|
|
6
6
|
describe Adamantium, '#memoize' do
|
7
|
-
subject { object.memoize(method
|
7
|
+
subject { object.memoize(method => value) }
|
8
8
|
|
9
9
|
let(:described_class) { Class.new(AdamantiumSpecs::Object) }
|
10
10
|
let(:object) { described_class.new }
|
@@ -14,33 +14,12 @@ describe Adamantium, '#memoize' do
|
|
14
14
|
described_class.memoize(method)
|
15
15
|
end
|
16
16
|
|
17
|
-
context 'when the
|
18
|
-
let(:value) { String.new.freeze }
|
19
|
-
|
20
|
-
it 'sets the memoized value for the method to the value' do
|
21
|
-
subject
|
22
|
-
expect(object.send(method)).to be(value)
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'creates a method that returns a frozen value' do
|
26
|
-
subject
|
27
|
-
expect(object.send(method)).to be_frozen
|
28
|
-
end
|
29
|
-
|
30
|
-
it_should_behave_like 'a command method'
|
31
|
-
end
|
32
|
-
|
33
|
-
context 'when the value is not frozen' do
|
17
|
+
context 'when the method is not memoized' do
|
34
18
|
let(:value) { String.new }
|
35
19
|
|
36
20
|
it 'sets the memoized value for the method to the value' do
|
37
21
|
subject
|
38
|
-
expect(object.send(method)).to
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'creates a method that returns a frozen value' do
|
42
|
-
subject
|
43
|
-
expect(object.send(method)).to be_frozen
|
22
|
+
expect(object.send(method)).to be(value)
|
44
23
|
end
|
45
24
|
|
46
25
|
it_should_behave_like 'a command method'
|
@@ -51,13 +30,11 @@ describe Adamantium, '#memoize' do
|
|
51
30
|
let(:original) { nil }
|
52
31
|
|
53
32
|
before do
|
54
|
-
object.memoize(method
|
33
|
+
object.memoize(method => original)
|
55
34
|
end
|
56
35
|
|
57
|
-
it '
|
58
|
-
expect { subject }.
|
36
|
+
it 'raises an exception' do
|
37
|
+
expect { subject }.to raise_error(ArgumentError)
|
59
38
|
end
|
60
|
-
|
61
|
-
it_should_behave_like 'a command method'
|
62
39
|
end
|
63
40
|
end
|
@@ -1,16 +1,40 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
|
-
require File.expand_path('../../fixtures/classes', __FILE__)
|
5
4
|
|
6
5
|
describe Adamantium::ModuleMethods, '#included' do
|
7
|
-
subject {
|
6
|
+
subject { descendant.instance_exec(object) { |mod| include mod } }
|
8
7
|
|
9
|
-
let(:object)
|
8
|
+
let(:object) { Module.new.extend(described_class) }
|
9
|
+
let(:descendant) { Class.new }
|
10
|
+
let(:superclass) { Module }
|
10
11
|
|
11
12
|
before do
|
12
|
-
|
13
|
+
# Prevent Module.included from being called through inheritance
|
14
|
+
Adamantium.stub(:included)
|
13
15
|
end
|
14
16
|
|
15
|
-
|
17
|
+
around do |example|
|
18
|
+
# Restore included method after each example
|
19
|
+
superclass.class_eval do
|
20
|
+
alias_method :original_included, :included
|
21
|
+
example.call
|
22
|
+
undef_method :included
|
23
|
+
alias_method :included, :original_included
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'delegates to the superclass #included method' do
|
28
|
+
# This is the most succinct approach I could think of to test whether the
|
29
|
+
# superclass#included method is called. All of the built-in rspec helpers
|
30
|
+
# did not seem to work for this.
|
31
|
+
included = false
|
32
|
+
superclass.class_eval { define_method(:included) { |_| included = true } }
|
33
|
+
expect { subject }.to change { included }.from(false).to(true)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'includes Adamantium into the descendant' do
|
37
|
+
subject
|
38
|
+
expect(descendant.included_modules).to include(Adamantium)
|
39
|
+
end
|
16
40
|
end
|
@@ -9,19 +9,17 @@ shared_examples_for 'memoizes method' do
|
|
9
9
|
instance = object.new
|
10
10
|
expect(instance.send(method)).to be(instance.send(method))
|
11
11
|
end
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
-
subject
|
15
|
-
instance = object.new
|
16
|
-
expect(instance.send(method)).to be(instance.send(method))
|
17
|
-
end
|
18
|
-
|
14
|
+
shared_examples_for 'wraps original method' do
|
19
15
|
it 'creates a method with an arity of 0' do
|
20
16
|
subject
|
21
17
|
expect(object.new.method(method).arity).to be_zero
|
22
18
|
end
|
23
19
|
|
24
20
|
context 'when the initializer calls the memoized method' do
|
21
|
+
it_should_behave_like 'memoizes method'
|
22
|
+
|
25
23
|
before do
|
26
24
|
method = self.method
|
27
25
|
object.send(:define_method, :initialize) { send(method) }
|
@@ -31,11 +29,6 @@ shared_examples_for 'memoizes method' do
|
|
31
29
|
subject
|
32
30
|
expect { object.new }.to_not raise_error
|
33
31
|
end
|
34
|
-
|
35
|
-
it 'memoizes the methdod inside the initializer' do
|
36
|
-
subject
|
37
|
-
expect(object.new.memoized(method)).to_not be_nil
|
38
|
-
end
|
39
32
|
end
|
40
33
|
end
|
41
34
|
|
@@ -56,7 +49,7 @@ describe Adamantium::ModuleMethods, '#memoize' do
|
|
56
49
|
let(:method) { :argumented }
|
57
50
|
|
58
51
|
it 'should raise error' do
|
59
|
-
expect { subject }.to raise_error(ArgumentError,
|
52
|
+
expect { subject }.to raise_error(ArgumentError, "Cannot memoize #{object}#argumented, its arity is 1")
|
60
53
|
end
|
61
54
|
end
|
62
55
|
|
@@ -65,7 +58,7 @@ describe Adamantium::ModuleMethods, '#memoize' do
|
|
65
58
|
let(:options) { { freezer: :noop } }
|
66
59
|
|
67
60
|
it_should_behave_like 'a command method'
|
68
|
-
it_should_behave_like '
|
61
|
+
it_should_behave_like 'wraps original method'
|
69
62
|
|
70
63
|
it 'is still a public method' do
|
71
64
|
should be_public_method_defined(method)
|
@@ -82,6 +75,7 @@ describe Adamantium::ModuleMethods, '#memoize' do
|
|
82
75
|
|
83
76
|
it_should_behave_like 'a command method'
|
84
77
|
it_should_behave_like 'memoizes method'
|
78
|
+
it_should_behave_like 'wraps original method'
|
85
79
|
|
86
80
|
it 'creates a method that returns a frozen value' do
|
87
81
|
subject
|
@@ -94,6 +88,7 @@ describe Adamantium::ModuleMethods, '#memoize' do
|
|
94
88
|
|
95
89
|
it_should_behave_like 'a command method'
|
96
90
|
it_should_behave_like 'memoizes method'
|
91
|
+
it_should_behave_like 'wraps original method'
|
97
92
|
|
98
93
|
it 'is still a public method' do
|
99
94
|
should be_public_method_defined(method)
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require File.expand_path('../fixtures/classes', __FILE__)
|
5
|
+
|
6
|
+
describe Adamantium, '#transform' do
|
7
|
+
let(:object) { described_class.new }
|
8
|
+
let(:described_class) { AdamantiumSpecs::Object }
|
9
|
+
|
10
|
+
it 'returns a copy of the object' do
|
11
|
+
transformed = object.transform {}
|
12
|
+
expect(transformed).to_not be(object)
|
13
|
+
expect(transformed).to eql(object)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'freezes the copy' do
|
17
|
+
expect(object.transform {}).to be_frozen
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'yields the copy to the block' do
|
21
|
+
expect { |block| object.transform(&block) }
|
22
|
+
.to yield_with_args(described_class)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'evaluates the block within the context of the copy' do
|
26
|
+
copy = nil
|
27
|
+
expect(object.transform { copy = self }).to be(copy)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'evaluates the block with an unfrozen copy' do
|
31
|
+
frozen_in_block = nil
|
32
|
+
expect { object.transform { frozen_in_block = frozen? } }
|
33
|
+
.to change { frozen_in_block }.from(nil).to(false)
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require File.expand_path('../fixtures/classes', __FILE__)
|
5
|
+
|
6
|
+
describe Adamantium, '#transform_unless' do
|
7
|
+
let(:object) { described_class.new }
|
8
|
+
let(:described_class) { AdamantiumSpecs::Object }
|
9
|
+
|
10
|
+
context 'when the condition is true' do
|
11
|
+
let(:condition) { true }
|
12
|
+
|
13
|
+
it 'does not evaluate the block' do
|
14
|
+
expect { |block| object.transform_unless(condition, &block) }
|
15
|
+
.not_to yield_control
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'returns the object' do
|
19
|
+
expect(object.transform_unless(condition) {}).to be(object)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when the condition is false' do
|
24
|
+
let(:condition) { false }
|
25
|
+
|
26
|
+
it 'evaluates the block' do
|
27
|
+
expect { |block| object.transform_unless(condition, &block) }
|
28
|
+
.to yield_control
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'returns a copy of the object' do
|
32
|
+
transformed = object.transform_unless(condition) {}
|
33
|
+
expect(transformed).to_not be(object)
|
34
|
+
expect(transformed).to eql(object)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: adamantium
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Kubb
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2014-01-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ice_nine
|
@@ -17,48 +17,48 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - ~>
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version:
|
20
|
+
version: 0.11.0
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - ~>
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version:
|
27
|
+
version: 0.11.0
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
|
-
name:
|
29
|
+
name: memoizable
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
32
|
- - ~>
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: 0.
|
34
|
+
version: 0.4.0
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
39
|
- - ~>
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: 0.
|
41
|
+
version: 0.4.0
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: bundler
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
46
|
- - ~>
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version: '1.
|
49
|
-
- -
|
48
|
+
version: '1.5'
|
49
|
+
- - '>='
|
50
50
|
- !ruby/object:Gem::Version
|
51
|
-
version: 1.
|
51
|
+
version: 1.5.2
|
52
52
|
type: :development
|
53
53
|
prerelease: false
|
54
54
|
version_requirements: !ruby/object:Gem::Requirement
|
55
55
|
requirements:
|
56
56
|
- - ~>
|
57
57
|
- !ruby/object:Gem::Version
|
58
|
-
version: '1.
|
59
|
-
- -
|
58
|
+
version: '1.5'
|
59
|
+
- - '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 1.
|
61
|
+
version: 1.5.2
|
62
62
|
description: Immutable extensions to objects
|
63
63
|
email:
|
64
64
|
- dan.kubb@gmail.com
|
@@ -73,6 +73,7 @@ extra_rdoc_files:
|
|
73
73
|
files:
|
74
74
|
- .gitignore
|
75
75
|
- .rspec
|
76
|
+
- .rubocop.yml
|
76
77
|
- .ruby-gemset
|
77
78
|
- .travis.yml
|
78
79
|
- CONTRIBUTING.md
|
@@ -103,7 +104,6 @@ files:
|
|
103
104
|
- spec/rcov.opts
|
104
105
|
- spec/spec_helper.rb
|
105
106
|
- spec/support/config_alias.rb
|
106
|
-
- spec/unit/adamantium/class_methods/included_spec.rb
|
107
107
|
- spec/unit/adamantium/class_methods/new_spec.rb
|
108
108
|
- spec/unit/adamantium/dup_spec.rb
|
109
109
|
- spec/unit/adamantium/fixtures/classes.rb
|
@@ -117,14 +117,14 @@ files:
|
|
117
117
|
- spec/unit/adamantium/freezer/flat/class_methods/call_spec.rb
|
118
118
|
- spec/unit/adamantium/freezer/flat/class_methods/freeze_spec.rb
|
119
119
|
- spec/unit/adamantium/memoize_spec.rb
|
120
|
-
- spec/unit/adamantium/memoized_spec.rb
|
121
120
|
- spec/unit/adamantium/module_methods/freezer_spec.rb
|
122
121
|
- spec/unit/adamantium/module_methods/included_spec.rb
|
123
122
|
- spec/unit/adamantium/module_methods/memoize_spec.rb
|
124
123
|
- spec/unit/adamantium/module_methods/memoized_predicate_spec.rb
|
125
|
-
- spec/unit/adamantium/module_methods/original_instance_method_spec.rb
|
126
124
|
- spec/unit/adamantium/mutable/freeze_spec.rb
|
127
125
|
- spec/unit/adamantium/mutable/frozen_predicate_spec.rb
|
126
|
+
- spec/unit/adamantium/transform_spec.rb
|
127
|
+
- spec/unit/adamantium/transform_unless_spec.rb
|
128
128
|
homepage: https://github.com/dkubb/adamantium
|
129
129
|
licenses:
|
130
130
|
- MIT
|
@@ -135,23 +135,22 @@ require_paths:
|
|
135
135
|
- lib
|
136
136
|
required_ruby_version: !ruby/object:Gem::Requirement
|
137
137
|
requirements:
|
138
|
-
- -
|
138
|
+
- - '>='
|
139
139
|
- !ruby/object:Gem::Version
|
140
140
|
version: '0'
|
141
141
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
|
-
- -
|
143
|
+
- - '>='
|
144
144
|
- !ruby/object:Gem::Version
|
145
145
|
version: '0'
|
146
146
|
requirements: []
|
147
147
|
rubyforge_project:
|
148
|
-
rubygems_version: 2.
|
148
|
+
rubygems_version: 2.1.11
|
149
149
|
signing_key:
|
150
150
|
specification_version: 4
|
151
151
|
summary: Immutable extensions to objects
|
152
152
|
test_files:
|
153
153
|
- spec/integration/adamantium_spec.rb
|
154
|
-
- spec/unit/adamantium/class_methods/included_spec.rb
|
155
154
|
- spec/unit/adamantium/class_methods/new_spec.rb
|
156
155
|
- spec/unit/adamantium/dup_spec.rb
|
157
156
|
- spec/unit/adamantium/fixtures/classes.rb
|
@@ -165,12 +164,12 @@ test_files:
|
|
165
164
|
- spec/unit/adamantium/freezer/flat/class_methods/call_spec.rb
|
166
165
|
- spec/unit/adamantium/freezer/flat/class_methods/freeze_spec.rb
|
167
166
|
- spec/unit/adamantium/memoize_spec.rb
|
168
|
-
- spec/unit/adamantium/memoized_spec.rb
|
169
167
|
- spec/unit/adamantium/module_methods/freezer_spec.rb
|
170
168
|
- spec/unit/adamantium/module_methods/included_spec.rb
|
171
169
|
- spec/unit/adamantium/module_methods/memoize_spec.rb
|
172
170
|
- spec/unit/adamantium/module_methods/memoized_predicate_spec.rb
|
173
|
-
- spec/unit/adamantium/module_methods/original_instance_method_spec.rb
|
174
171
|
- spec/unit/adamantium/mutable/freeze_spec.rb
|
175
172
|
- spec/unit/adamantium/mutable/frozen_predicate_spec.rb
|
173
|
+
- spec/unit/adamantium/transform_spec.rb
|
174
|
+
- spec/unit/adamantium/transform_unless_spec.rb
|
176
175
|
has_rdoc:
|
@@ -1,40 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
describe Adamantium, '.included' do
|
6
|
-
let(:object) { described_class }
|
7
|
-
|
8
|
-
subject { object.included(target) }
|
9
|
-
|
10
|
-
let(:included_modules) do
|
11
|
-
target.singleton_class.included_modules
|
12
|
-
end
|
13
|
-
|
14
|
-
before { subject }
|
15
|
-
|
16
|
-
context 'when target is a module' do
|
17
|
-
let(:target) { Module.new }
|
18
|
-
|
19
|
-
it_should_behave_like 'a command method'
|
20
|
-
|
21
|
-
it 'includes Adamantium::ModuleMethods' do
|
22
|
-
expect(included_modules).to include(Adamantium::ModuleMethods)
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'does not include Adamantium::ClassMethods' do
|
26
|
-
expect(included_modules).to_not include(Adamantium::ClassMethods)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
context 'when target is a class' do
|
31
|
-
let(:target) { Class.new }
|
32
|
-
|
33
|
-
it 'includes Adamantium::{Class,Module}Methods' do
|
34
|
-
expect(included_modules).to include(Adamantium::ModuleMethods)
|
35
|
-
expect(included_modules).to include(Adamantium::ClassMethods)
|
36
|
-
end
|
37
|
-
|
38
|
-
it_should_behave_like 'a command method'
|
39
|
-
end
|
40
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
require File.expand_path('../fixtures/classes', __FILE__)
|
5
|
-
|
6
|
-
describe Adamantium, '#memoized' do
|
7
|
-
subject { object.memoized(method) }
|
8
|
-
|
9
|
-
let(:described_class) { Class.new(AdamantiumSpecs::Object) }
|
10
|
-
let(:method) { :test }
|
11
|
-
let(:value) { String.new.freeze }
|
12
|
-
let(:object) { described_class.new }
|
13
|
-
|
14
|
-
before do
|
15
|
-
described_class.memoize(method)
|
16
|
-
end
|
17
|
-
|
18
|
-
context 'when a method is memoized' do
|
19
|
-
before do
|
20
|
-
object.memoize(method, value)
|
21
|
-
end
|
22
|
-
|
23
|
-
it { should equal(value) }
|
24
|
-
end
|
25
|
-
|
26
|
-
context 'when a method is not memoized' do
|
27
|
-
it { should be_nil }
|
28
|
-
end
|
29
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
describe Adamantium::ModuleMethods, '#original_instance_method' do
|
6
|
-
subject { object.original_instance_method(name).source_location }
|
7
|
-
|
8
|
-
let(:object) do
|
9
|
-
Class.new do
|
10
|
-
include Adamantium
|
11
|
-
|
12
|
-
def foo; end
|
13
|
-
|
14
|
-
const_set(:ORIGINAL, instance_method(:foo).source_location)
|
15
|
-
|
16
|
-
memoize :foo
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
context 'when the method was memoized' do
|
21
|
-
let(:name) { :foo }
|
22
|
-
|
23
|
-
it 'returns the original method' do
|
24
|
-
should eql(object::ORIGINAL)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
context 'when the method was not memoized' do
|
29
|
-
let(:name) { :bar }
|
30
|
-
|
31
|
-
it 'raises an exception' do
|
32
|
-
expect { subject }
|
33
|
-
.to raise_error(ArgumentError, 'No method :bar was memoized')
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|