memoizable 0.4.1 → 0.5.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 +5 -5
- data/CHANGELOG.md +100 -0
- data/LICENSE.md +1 -1
- data/README.md +20 -35
- data/lib/memoizable/instance_methods.rb +7 -10
- data/lib/memoizable/memory.rb +99 -26
- data/lib/memoizable/method_builder.rb +29 -31
- data/lib/memoizable/module_methods.rb +9 -45
- data/lib/memoizable/version.rb +3 -5
- data/lib/memoizable.rb +10 -12
- metadata +14 -81
- data/Rakefile +0 -10
- data/memoizable.gemspec +0 -24
- data/spec/integration/serializable_spec.rb +0 -34
- data/spec/shared/call_super_shared_spec.rb +0 -23
- data/spec/shared/command_method_behavior.rb +0 -7
- data/spec/spec_helper.rb +0 -32
- data/spec/unit/memoizable/class_methods/included_spec.rb +0 -18
- data/spec/unit/memoizable/fixtures/classes.rb +0 -41
- data/spec/unit/memoizable/instance_methods/freeze_spec.rb +0 -27
- data/spec/unit/memoizable/instance_methods/memoize_spec.rb +0 -40
- data/spec/unit/memoizable/memory_spec.rb +0 -24
- data/spec/unit/memoizable/method_builder/call_spec.rb +0 -93
- data/spec/unit/memoizable/method_builder/class_methods/new_spec.rb +0 -34
- data/spec/unit/memoizable/method_builder/original_method_spec.rb +0 -31
- data/spec/unit/memoizable/module_methods/included_spec.rb +0 -23
- data/spec/unit/memoizable/module_methods/memoize_spec.rb +0 -123
- data/spec/unit/memoizable/module_methods/memoized_predicate_spec.rb +0 -28
- data/spec/unit/memoizable/module_methods/unmemoized_instance_method_spec.rb +0 -43
data/lib/memoizable.rb
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require 'thread_safe'
|
|
3
|
+
require "monitor"
|
|
5
4
|
|
|
6
|
-
require
|
|
7
|
-
require
|
|
8
|
-
require
|
|
9
|
-
require
|
|
10
|
-
require
|
|
5
|
+
require "memoizable/instance_methods"
|
|
6
|
+
require "memoizable/method_builder"
|
|
7
|
+
require "memoizable/module_methods"
|
|
8
|
+
require "memoizable/memory"
|
|
9
|
+
require "memoizable/version"
|
|
11
10
|
|
|
12
11
|
# Allow methods to be memoized
|
|
13
12
|
module Memoizable
|
|
14
|
-
include InstanceMethods
|
|
13
|
+
include Memoizable::InstanceMethods
|
|
15
14
|
|
|
16
15
|
# Default freezer
|
|
17
|
-
Freezer =
|
|
16
|
+
Freezer = ->(value) { value.freeze }.freeze # rubocop:disable Style/SymbolProc
|
|
18
17
|
|
|
19
18
|
# Hook called when module is included
|
|
20
19
|
#
|
|
@@ -29,5 +28,4 @@ module Memoizable
|
|
|
29
28
|
descendant.extend(ModuleMethods)
|
|
30
29
|
end
|
|
31
30
|
private_class_method :included
|
|
32
|
-
|
|
33
|
-
end # Memoizable
|
|
31
|
+
end
|
metadata
CHANGED
|
@@ -1,93 +1,41 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: memoizable
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dan Kubb
|
|
8
|
-
- Erik
|
|
9
|
-
autorequire:
|
|
8
|
+
- Erik Berlin
|
|
10
9
|
bindir: bin
|
|
11
10
|
cert_chain: []
|
|
12
|
-
date:
|
|
13
|
-
dependencies:
|
|
14
|
-
- !ruby/object:Gem::Dependency
|
|
15
|
-
name: thread_safe
|
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
|
17
|
-
requirements:
|
|
18
|
-
- - "~>"
|
|
19
|
-
- !ruby/object:Gem::Version
|
|
20
|
-
version: 0.2.0
|
|
21
|
-
type: :runtime
|
|
22
|
-
prerelease: false
|
|
23
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
24
|
-
requirements:
|
|
25
|
-
- - "~>"
|
|
26
|
-
- !ruby/object:Gem::Version
|
|
27
|
-
version: 0.2.0
|
|
28
|
-
- !ruby/object:Gem::Dependency
|
|
29
|
-
name: bundler
|
|
30
|
-
requirement: !ruby/object:Gem::Requirement
|
|
31
|
-
requirements:
|
|
32
|
-
- - "~>"
|
|
33
|
-
- !ruby/object:Gem::Version
|
|
34
|
-
version: '1.3'
|
|
35
|
-
- - ">="
|
|
36
|
-
- !ruby/object:Gem::Version
|
|
37
|
-
version: 1.3.5
|
|
38
|
-
type: :development
|
|
39
|
-
prerelease: false
|
|
40
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
41
|
-
requirements:
|
|
42
|
-
- - "~>"
|
|
43
|
-
- !ruby/object:Gem::Version
|
|
44
|
-
version: '1.3'
|
|
45
|
-
- - ">="
|
|
46
|
-
- !ruby/object:Gem::Version
|
|
47
|
-
version: 1.3.5
|
|
11
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
48
13
|
description: Memoize method return values
|
|
49
14
|
email:
|
|
50
15
|
- dan.kubb@gmail.com
|
|
51
16
|
- sferik@gmail.com
|
|
52
17
|
executables: []
|
|
53
18
|
extensions: []
|
|
54
|
-
extra_rdoc_files:
|
|
55
|
-
- CONTRIBUTING.md
|
|
56
|
-
- LICENSE.md
|
|
57
|
-
- README.md
|
|
19
|
+
extra_rdoc_files: []
|
|
58
20
|
files:
|
|
21
|
+
- CHANGELOG.md
|
|
59
22
|
- CONTRIBUTING.md
|
|
60
23
|
- LICENSE.md
|
|
61
24
|
- README.md
|
|
62
|
-
- Rakefile
|
|
63
25
|
- lib/memoizable.rb
|
|
64
26
|
- lib/memoizable/instance_methods.rb
|
|
65
27
|
- lib/memoizable/memory.rb
|
|
66
28
|
- lib/memoizable/method_builder.rb
|
|
67
29
|
- lib/memoizable/module_methods.rb
|
|
68
30
|
- lib/memoizable/version.rb
|
|
69
|
-
- memoizable.gemspec
|
|
70
|
-
- spec/integration/serializable_spec.rb
|
|
71
|
-
- spec/shared/call_super_shared_spec.rb
|
|
72
|
-
- spec/shared/command_method_behavior.rb
|
|
73
|
-
- spec/spec_helper.rb
|
|
74
|
-
- spec/unit/memoizable/class_methods/included_spec.rb
|
|
75
|
-
- spec/unit/memoizable/fixtures/classes.rb
|
|
76
|
-
- spec/unit/memoizable/instance_methods/freeze_spec.rb
|
|
77
|
-
- spec/unit/memoizable/instance_methods/memoize_spec.rb
|
|
78
|
-
- spec/unit/memoizable/memory_spec.rb
|
|
79
|
-
- spec/unit/memoizable/method_builder/call_spec.rb
|
|
80
|
-
- spec/unit/memoizable/method_builder/class_methods/new_spec.rb
|
|
81
|
-
- spec/unit/memoizable/method_builder/original_method_spec.rb
|
|
82
|
-
- spec/unit/memoizable/module_methods/included_spec.rb
|
|
83
|
-
- spec/unit/memoizable/module_methods/memoize_spec.rb
|
|
84
|
-
- spec/unit/memoizable/module_methods/memoized_predicate_spec.rb
|
|
85
|
-
- spec/unit/memoizable/module_methods/unmemoized_instance_method_spec.rb
|
|
86
31
|
homepage: https://github.com/dkubb/memoizable
|
|
87
32
|
licenses:
|
|
88
33
|
- MIT
|
|
89
|
-
metadata:
|
|
90
|
-
|
|
34
|
+
metadata:
|
|
35
|
+
homepage_uri: https://github.com/dkubb/memoizable
|
|
36
|
+
source_code_uri: https://github.com/dkubb/memoizable
|
|
37
|
+
changelog_uri: https://github.com/dkubb/memoizable/blob/main/CHANGELOG.md
|
|
38
|
+
rubygems_mfa_required: 'true'
|
|
91
39
|
rdoc_options: []
|
|
92
40
|
require_paths:
|
|
93
41
|
- lib
|
|
@@ -95,29 +43,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
95
43
|
requirements:
|
|
96
44
|
- - ">="
|
|
97
45
|
- !ruby/object:Gem::Version
|
|
98
|
-
version: '
|
|
46
|
+
version: '3.2'
|
|
99
47
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
100
48
|
requirements:
|
|
101
49
|
- - ">="
|
|
102
50
|
- !ruby/object:Gem::Version
|
|
103
51
|
version: '0'
|
|
104
52
|
requirements: []
|
|
105
|
-
|
|
106
|
-
rubygems_version: 2.2.2
|
|
107
|
-
signing_key:
|
|
53
|
+
rubygems_version: 4.0.7
|
|
108
54
|
specification_version: 4
|
|
109
55
|
summary: Memoize method return values
|
|
110
|
-
test_files:
|
|
111
|
-
- spec/unit/memoizable/class_methods/included_spec.rb
|
|
112
|
-
- spec/unit/memoizable/fixtures/classes.rb
|
|
113
|
-
- spec/unit/memoizable/instance_methods/freeze_spec.rb
|
|
114
|
-
- spec/unit/memoizable/instance_methods/memoize_spec.rb
|
|
115
|
-
- spec/unit/memoizable/memory_spec.rb
|
|
116
|
-
- spec/unit/memoizable/method_builder/call_spec.rb
|
|
117
|
-
- spec/unit/memoizable/method_builder/class_methods/new_spec.rb
|
|
118
|
-
- spec/unit/memoizable/method_builder/original_method_spec.rb
|
|
119
|
-
- spec/unit/memoizable/module_methods/included_spec.rb
|
|
120
|
-
- spec/unit/memoizable/module_methods/memoize_spec.rb
|
|
121
|
-
- spec/unit/memoizable/module_methods/memoized_predicate_spec.rb
|
|
122
|
-
- spec/unit/memoizable/module_methods/unmemoized_instance_method_spec.rb
|
|
123
|
-
- spec/integration/serializable_spec.rb
|
|
56
|
+
test_files: []
|
data/Rakefile
DELETED
data/memoizable.gemspec
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
require File.expand_path('../lib/memoizable/version', __FILE__)
|
|
4
|
-
|
|
5
|
-
Gem::Specification.new do |gem|
|
|
6
|
-
gem.name = 'memoizable'
|
|
7
|
-
gem.version = Memoizable::VERSION.dup
|
|
8
|
-
gem.authors = ['Dan Kubb', 'Erik Michaels-Ober']
|
|
9
|
-
gem.email = ['dan.kubb@gmail.com', 'sferik@gmail.com']
|
|
10
|
-
gem.description = 'Memoize method return values'
|
|
11
|
-
gem.summary = gem.description
|
|
12
|
-
gem.homepage = 'https://github.com/dkubb/memoizable'
|
|
13
|
-
gem.license = 'MIT'
|
|
14
|
-
|
|
15
|
-
gem.require_paths = %w[lib]
|
|
16
|
-
gem.files = %w[CONTRIBUTING.md LICENSE.md README.md Rakefile memoizable.gemspec]
|
|
17
|
-
gem.files += Dir.glob('{lib,spec}/**/*.rb')
|
|
18
|
-
gem.test_files = Dir.glob('spec/{unit,integration}/**/*.rb')
|
|
19
|
-
gem.extra_rdoc_files = Dir.glob('**/*.md')
|
|
20
|
-
|
|
21
|
-
gem.add_runtime_dependency('thread_safe', '~> 0.2.0')
|
|
22
|
-
|
|
23
|
-
gem.add_development_dependency('bundler', '~> 1.3', '>= 1.3.5')
|
|
24
|
-
end
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
require 'spec_helper'
|
|
4
|
-
|
|
5
|
-
class Serializable
|
|
6
|
-
include Memoizable
|
|
7
|
-
|
|
8
|
-
def random_number
|
|
9
|
-
rand(10000)
|
|
10
|
-
end
|
|
11
|
-
memoize :random_number
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
describe 'A serializable object' do
|
|
15
|
-
let(:serializable) do
|
|
16
|
-
Serializable.new
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
before do
|
|
20
|
-
serializable.random_number # Call the memoized method to trigger lazy memoization
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
it 'is serializable with Marshal' do
|
|
24
|
-
expect { Marshal.dump(serializable) }.not_to raise_error
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
it 'is deserializable with Marshal' do
|
|
28
|
-
serialized = Marshal.dump(serializable)
|
|
29
|
-
deserialized = Marshal.load(serialized)
|
|
30
|
-
|
|
31
|
-
expect(deserialized).to be_an_instance_of(Serializable)
|
|
32
|
-
expect(deserialized.random_number).to eql(serializable.random_number)
|
|
33
|
-
end
|
|
34
|
-
end
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
shared_examples 'it calls super' do |method|
|
|
4
|
-
around do |example|
|
|
5
|
-
# Restore original method after each example
|
|
6
|
-
original = "original_#{method}"
|
|
7
|
-
superclass.class_eval do
|
|
8
|
-
alias_method original, method
|
|
9
|
-
example.call
|
|
10
|
-
undef_method method
|
|
11
|
-
alias_method method, original
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
it "delegates to the superclass ##{method} method" do
|
|
16
|
-
# This is the most succinct approach I could think of to test whether the
|
|
17
|
-
# superclass method is called. All of the built-in rspec helpers did not
|
|
18
|
-
# seem to work for this.
|
|
19
|
-
called = false
|
|
20
|
-
superclass.class_eval { define_method(method) { |_| called = true } }
|
|
21
|
-
expect { subject }.to change { called }.from(false).to(true)
|
|
22
|
-
end
|
|
23
|
-
end
|
data/spec/spec_helper.rb
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
require 'simplecov'
|
|
4
|
-
require 'coveralls'
|
|
5
|
-
|
|
6
|
-
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
|
7
|
-
SimpleCov::Formatter::HTMLFormatter,
|
|
8
|
-
Coveralls::SimpleCov::Formatter
|
|
9
|
-
]
|
|
10
|
-
SimpleCov.start do
|
|
11
|
-
command_name 'spec'
|
|
12
|
-
|
|
13
|
-
add_filter 'config'
|
|
14
|
-
add_filter 'spec'
|
|
15
|
-
add_filter 'vendor'
|
|
16
|
-
|
|
17
|
-
minimum_coverage 100
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
require 'memoizable'
|
|
21
|
-
require 'rspec'
|
|
22
|
-
|
|
23
|
-
# Require spec support files and shared behavior
|
|
24
|
-
Dir[File.expand_path('../{support,shared}/**/*.rb', __FILE__)].each do |file|
|
|
25
|
-
require file.chomp('.rb')
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
RSpec.configure do |config|
|
|
29
|
-
config.expect_with :rspec do |expect_with|
|
|
30
|
-
expect_with.syntax = :expect
|
|
31
|
-
end
|
|
32
|
-
end
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
require 'spec_helper'
|
|
4
|
-
|
|
5
|
-
describe Memoizable, '.included' do
|
|
6
|
-
subject { object.class_eval { include Memoizable } }
|
|
7
|
-
|
|
8
|
-
let(:object) { Class.new }
|
|
9
|
-
let(:superclass) { Module }
|
|
10
|
-
|
|
11
|
-
it_behaves_like 'it calls super', :included
|
|
12
|
-
|
|
13
|
-
it 'extends the descendant with module methods' do
|
|
14
|
-
subject
|
|
15
|
-
extended_modules = class << object; included_modules end
|
|
16
|
-
expect(extended_modules).to include(Memoizable::ModuleMethods)
|
|
17
|
-
end
|
|
18
|
-
end
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
module Fixture
|
|
4
|
-
class Object
|
|
5
|
-
include Memoizable
|
|
6
|
-
|
|
7
|
-
def required_arguments(foo)
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def optional_arguments(foo = nil)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def test
|
|
14
|
-
'test'
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def zero_arity
|
|
18
|
-
caller
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def one_arity(arg)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def public_method
|
|
25
|
-
caller
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
protected
|
|
29
|
-
|
|
30
|
-
def protected_method
|
|
31
|
-
caller
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
private
|
|
35
|
-
|
|
36
|
-
def private_method
|
|
37
|
-
caller
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
end # class Object
|
|
41
|
-
end # module Fixture
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
require 'spec_helper'
|
|
4
|
-
require File.expand_path('../../fixtures/classes', __FILE__)
|
|
5
|
-
|
|
6
|
-
describe Memoizable::InstanceMethods, '#freeze' do
|
|
7
|
-
subject { object.freeze }
|
|
8
|
-
|
|
9
|
-
let(:described_class) { Class.new(Fixture::Object) }
|
|
10
|
-
|
|
11
|
-
before do
|
|
12
|
-
described_class.memoize(:test)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
let(:object) { described_class.allocate }
|
|
16
|
-
|
|
17
|
-
it_should_behave_like 'a command method'
|
|
18
|
-
|
|
19
|
-
it 'freezes the object' do
|
|
20
|
-
expect { subject }.to change(object, :frozen?).from(false).to(true)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
it 'allows methods not yet called to be memoized' do
|
|
24
|
-
subject
|
|
25
|
-
expect(object.test).to be(object.test)
|
|
26
|
-
end
|
|
27
|
-
end
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
require 'spec_helper'
|
|
4
|
-
require File.expand_path('../../fixtures/classes', __FILE__)
|
|
5
|
-
|
|
6
|
-
describe Memoizable::InstanceMethods, '#memoize' do
|
|
7
|
-
subject { object.memoize(method => value) }
|
|
8
|
-
|
|
9
|
-
let(:described_class) { Class.new(Fixture::Object) }
|
|
10
|
-
let(:object) { described_class.new }
|
|
11
|
-
let(:method) { :test }
|
|
12
|
-
|
|
13
|
-
before do
|
|
14
|
-
described_class.memoize(method)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
context 'when the method is not memoized' do
|
|
18
|
-
let(:value) { String.new }
|
|
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_should_behave_like 'a command method'
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
context 'when the method is already memoized' do
|
|
29
|
-
let(:value) { double }
|
|
30
|
-
let(:original) { nil }
|
|
31
|
-
|
|
32
|
-
before do
|
|
33
|
-
object.memoize(method => original)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
it 'raises an exception' do
|
|
37
|
-
expect { subject }.to raise_error(ArgumentError)
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe Memoizable::Memory do
|
|
4
|
-
let(:memory) { Memoizable::Memory.new }
|
|
5
|
-
|
|
6
|
-
context "serialization" do
|
|
7
|
-
let(:deserialized) { Marshal.load(Marshal.dump(memory)) }
|
|
8
|
-
|
|
9
|
-
it 'is serializable with Marshal' do
|
|
10
|
-
expect { Marshal.dump(memory) }.not_to raise_error
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
it 'is deserializable with Marshal' do
|
|
14
|
-
expect(deserialized).to be_an_instance_of(Memoizable::Memory)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
it 'mantains the same class of cache when deserialized' do
|
|
18
|
-
original_cache = memory.instance_variable_get(:@memory)
|
|
19
|
-
deserialized_cache = deserialized.instance_variable_get(:@memory)
|
|
20
|
-
|
|
21
|
-
expect(deserialized_cache.class).to eql(original_cache.class)
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
require 'spec_helper'
|
|
4
|
-
require File.expand_path('../../fixtures/classes', __FILE__)
|
|
5
|
-
|
|
6
|
-
describe Memoizable::MethodBuilder, '#call' do
|
|
7
|
-
subject { object.call }
|
|
8
|
-
|
|
9
|
-
let(:object) { described_class.new(descendant, method_name, freezer) }
|
|
10
|
-
let(:freezer) { lambda { |object| object.freeze } }
|
|
11
|
-
let(:instance) { descendant.new }
|
|
12
|
-
|
|
13
|
-
let(:descendant) do
|
|
14
|
-
Class.new do
|
|
15
|
-
include Memoizable
|
|
16
|
-
|
|
17
|
-
def public_method
|
|
18
|
-
__method__.to_s
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def protected_method
|
|
22
|
-
__method__.to_s
|
|
23
|
-
end
|
|
24
|
-
protected :protected_method
|
|
25
|
-
|
|
26
|
-
def private_method
|
|
27
|
-
__method__.to_s
|
|
28
|
-
end
|
|
29
|
-
private :private_method
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
shared_examples_for 'Memoizable::MethodBuilder#call' do
|
|
34
|
-
it_should_behave_like 'a command method'
|
|
35
|
-
|
|
36
|
-
it 'creates a method that is memoized' do
|
|
37
|
-
subject
|
|
38
|
-
expect(instance.send(method_name)).to be(instance.send(method_name))
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
it 'creates a method that returns the expected value' do
|
|
42
|
-
subject
|
|
43
|
-
expect(instance.send(method_name)).to eql(method_name.to_s)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
it 'creates a method that returns a frozen value' do
|
|
47
|
-
subject
|
|
48
|
-
expect(descendant.new.send(method_name)).to be_frozen
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
it 'creates a method that does not accept a block' do
|
|
52
|
-
subject
|
|
53
|
-
expect { descendant.new.send(method_name) {} }.to raise_error(
|
|
54
|
-
described_class::BlockNotAllowedError,
|
|
55
|
-
"Cannot pass a block to #{descendant}##{method_name}, it is memoized"
|
|
56
|
-
)
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
context 'public method' do
|
|
61
|
-
let(:method_name) { :public_method }
|
|
62
|
-
|
|
63
|
-
it_should_behave_like 'Memoizable::MethodBuilder#call'
|
|
64
|
-
|
|
65
|
-
it 'creates a public memoized method' do
|
|
66
|
-
subject
|
|
67
|
-
expect(descendant).to be_public_method_defined(method_name)
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
context 'protected method' do
|
|
72
|
-
let(:method_name) { :protected_method }
|
|
73
|
-
|
|
74
|
-
it_should_behave_like 'Memoizable::MethodBuilder#call'
|
|
75
|
-
|
|
76
|
-
it 'creates a protected memoized method' do
|
|
77
|
-
subject
|
|
78
|
-
expect(descendant).to be_protected_method_defined(method_name)
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
context 'private method' do
|
|
84
|
-
let(:method_name) { :private_method }
|
|
85
|
-
|
|
86
|
-
it_should_behave_like 'Memoizable::MethodBuilder#call'
|
|
87
|
-
|
|
88
|
-
it 'creates a private memoized method' do
|
|
89
|
-
subject
|
|
90
|
-
expect(descendant).to be_private_method_defined(method_name)
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
end
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
require 'spec_helper'
|
|
4
|
-
require File.expand_path('../../../fixtures/classes', __FILE__)
|
|
5
|
-
|
|
6
|
-
describe Memoizable::MethodBuilder, '.new' do
|
|
7
|
-
subject { described_class.new(descendant, method_name, freezer) }
|
|
8
|
-
|
|
9
|
-
let(:descendant) { Fixture::Object }
|
|
10
|
-
let(:freezer) { lambda { |object| object.freeze } }
|
|
11
|
-
|
|
12
|
-
context 'with a zero arity method' do
|
|
13
|
-
let(:method_name) { :zero_arity }
|
|
14
|
-
|
|
15
|
-
it { should be_instance_of(described_class) }
|
|
16
|
-
|
|
17
|
-
it 'sets the original method' do
|
|
18
|
-
# original method is not memoized
|
|
19
|
-
method = subject.original_method.bind(descendant.new)
|
|
20
|
-
expect(method.call).to_not be(method.call)
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
context 'with a one arity method' do
|
|
25
|
-
let(:method_name) { :one_arity }
|
|
26
|
-
|
|
27
|
-
it 'raises an exception' do
|
|
28
|
-
expect { subject }.to raise_error(
|
|
29
|
-
described_class::InvalidArityError,
|
|
30
|
-
'Cannot memoize Fixture::Object#one_arity, its arity is 1'
|
|
31
|
-
)
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
require 'spec_helper'
|
|
4
|
-
|
|
5
|
-
describe Memoizable::MethodBuilder, '#original_method' do
|
|
6
|
-
subject { object.original_method }
|
|
7
|
-
|
|
8
|
-
let(:object) { described_class.new(descendant, method_name, freezer) }
|
|
9
|
-
let(:method_name) { :foo }
|
|
10
|
-
let(:freezer) { lambda { |object| object.freeze } }
|
|
11
|
-
|
|
12
|
-
let(:descendant) do
|
|
13
|
-
Class.new do
|
|
14
|
-
def initialize
|
|
15
|
-
@foo = 0
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def foo
|
|
19
|
-
@foo += 1
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
it { should be_instance_of(UnboundMethod) }
|
|
25
|
-
|
|
26
|
-
it 'returns the original method' do
|
|
27
|
-
# original method is not memoized
|
|
28
|
-
method = subject.bind(descendant.new)
|
|
29
|
-
expect(method.call).to_not be(method.call)
|
|
30
|
-
end
|
|
31
|
-
end
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
require 'spec_helper'
|
|
4
|
-
|
|
5
|
-
describe Memoizable::ModuleMethods, '#included' do
|
|
6
|
-
subject { descendant.instance_exec(object) { |mod| include mod } }
|
|
7
|
-
|
|
8
|
-
let(:object) { Module.new.extend(described_class) }
|
|
9
|
-
let(:descendant) { Class.new }
|
|
10
|
-
let(:superclass) { Module }
|
|
11
|
-
|
|
12
|
-
before do
|
|
13
|
-
# Prevent Module.included from being called through inheritance
|
|
14
|
-
Memoizable.stub(:included)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
it_behaves_like 'it calls super', :included
|
|
18
|
-
|
|
19
|
-
it 'includes Memoizable into the descendant' do
|
|
20
|
-
subject
|
|
21
|
-
expect(descendant.included_modules).to include(Memoizable)
|
|
22
|
-
end
|
|
23
|
-
end
|