casting 1.0.0 → 1.0.2
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 +4 -4
- data/README.md +41 -0
- data/Rakefile +4 -4
- data/lib/casting/client.rb +12 -13
- data/lib/casting/context.rb +9 -15
- data/lib/casting/delegation.rb +33 -35
- data/lib/casting/enum.rb +13 -0
- data/lib/casting/method_consolidator.rb +5 -5
- data/lib/casting/missing_method_client.rb +16 -17
- data/lib/casting/missing_method_client_class.rb +3 -4
- data/lib/casting/null.rb +8 -2
- data/lib/casting/super_delegate.rb +11 -12
- data/lib/casting/version.rb +1 -1
- data/lib/casting.rb +6 -8
- metadata +5 -26
- data/test/casting_test.rb +0 -89
- data/test/class_refinement_test.rb +0 -119
- data/test/client_test.rb +0 -81
- data/test/context_test.rb +0 -80
- data/test/delegation_test.rb +0 -198
- data/test/method_consolidator_test.rb +0 -81
- data/test/missing_method_client_test.rb +0 -203
- data/test/module_cleanup_test.rb +0 -43
- data/test/null_module_test.rb +0 -43
- data/test/super_test.rb +0 -80
- data/test/test_helper.rb +0 -97
@@ -1,203 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
module One
|
4
|
-
def similar
|
5
|
-
"from One"
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
|
-
module Two
|
10
|
-
def similar
|
11
|
-
"from Two"
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
describe Casting::MissingMethodClient, '#cast_as' do
|
16
|
-
let(:client){
|
17
|
-
test_person.extend(Casting::Client, Casting::MissingMethodClient)
|
18
|
-
}
|
19
|
-
|
20
|
-
it "sets the object's delegate for missing methods" do
|
21
|
-
client.cast_as(TestPerson::Greeter)
|
22
|
-
assert_equal 'hello', client.greet
|
23
|
-
end
|
24
|
-
|
25
|
-
it "delegates to objects of the same type" do
|
26
|
-
# avoid using another client
|
27
|
-
client = test_person
|
28
|
-
client.extend(TestPerson::Greeter)
|
29
|
-
attendant = client.clone
|
30
|
-
client.extend(Casting::Client, Casting::MissingMethodClient)
|
31
|
-
|
32
|
-
client.singleton_class.send(:undef_method, :greet)
|
33
|
-
client.cast_as(attendant)
|
34
|
-
assert_equal 'hello', client.greet
|
35
|
-
end
|
36
|
-
|
37
|
-
it "raises an error when given the client object" do
|
38
|
-
assert_raises(Casting::InvalidAttendant){
|
39
|
-
client.cast_as(client)
|
40
|
-
}
|
41
|
-
end
|
42
|
-
|
43
|
-
it "returns the object for further operation" do
|
44
|
-
jim = test_person.extend(Casting::Client, Casting::MissingMethodClient)
|
45
|
-
|
46
|
-
assert_equal 'hello', jim.cast_as(TestPerson::Greeter).greet
|
47
|
-
end
|
48
|
-
|
49
|
-
it "delegates methods to the last module added containing the method" do
|
50
|
-
jim = test_person.extend(Casting::Client, Casting::MissingMethodClient)
|
51
|
-
|
52
|
-
assert_equal "from Two", jim.cast_as(One, Two).similar
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
describe Casting::MissingMethodClient, '#uncast' do
|
57
|
-
let(:client){
|
58
|
-
test_person.extend(Casting::Client, Casting::MissingMethodClient)
|
59
|
-
}
|
60
|
-
|
61
|
-
it "removes the last added delegate" do
|
62
|
-
client.cast_as(TestPerson::Greeter)
|
63
|
-
assert_equal 'hello', client.greet
|
64
|
-
client.uncast
|
65
|
-
assert_raises(NoMethodError){ client.greet }
|
66
|
-
end
|
67
|
-
|
68
|
-
it "maintains any previously added delegates" do
|
69
|
-
client.cast_as(TestPerson::Verbose)
|
70
|
-
assert_equal 'one,two', client.verbose('one', 'two')
|
71
|
-
client.uncast
|
72
|
-
assert_raises(NoMethodError){ client.verbose('one', 'two') }
|
73
|
-
end
|
74
|
-
|
75
|
-
it "returns the object for further operation" do
|
76
|
-
jim = test_person.extend(Casting::Client, Casting::MissingMethodClient)
|
77
|
-
|
78
|
-
assert_equal 'name from TestPerson', jim.uncast.name
|
79
|
-
end
|
80
|
-
|
81
|
-
it "removes the specified number of delegates" do
|
82
|
-
jim = test_person.extend(Casting::Client, Casting::MissingMethodClient)
|
83
|
-
jim.cast_as(TestPerson::Greeter, TestPerson::Verbose)
|
84
|
-
|
85
|
-
assert_includes(jim.delegated_methods(true), :psst)
|
86
|
-
assert_includes(jim.delegated_methods(true), :verbose)
|
87
|
-
|
88
|
-
jim.uncast(2)
|
89
|
-
|
90
|
-
refute_includes(jim.delegated_methods(true), :psst)
|
91
|
-
refute_includes(jim.delegated_methods(true), :verbose)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
describe Casting::MissingMethodClient, '#delegated_methods' do
|
96
|
-
let(:client){
|
97
|
-
object = test_person.extend(Casting::Client, Casting::MissingMethodClient)
|
98
|
-
object.cast_as(TestPerson::Greeter)
|
99
|
-
object
|
100
|
-
}
|
101
|
-
|
102
|
-
it "returns all instance methods including private from the object's delegates" do
|
103
|
-
assert_includes(client.delegated_methods(true), :psst)
|
104
|
-
end
|
105
|
-
|
106
|
-
it "returns all public instance methods from the object and it's delegates" do
|
107
|
-
refute_includes(client.delegated_methods(false), :psst)
|
108
|
-
end
|
109
|
-
|
110
|
-
it "returns all protected instance methods from the object and it's delegates" do
|
111
|
-
assert_includes(client.delegated_methods(true), :hey)
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
describe Casting::MissingMethodClient, '#delegated_public_methods' do
|
116
|
-
let(:client){
|
117
|
-
object = test_person.extend(Casting::Client, Casting::MissingMethodClient)
|
118
|
-
object.cast_as(TestPerson::Greeter)
|
119
|
-
object
|
120
|
-
}
|
121
|
-
|
122
|
-
it "returns all public methods from the object's delegates" do
|
123
|
-
assert_includes(client.delegated_public_methods, :greet)
|
124
|
-
end
|
125
|
-
|
126
|
-
it "excludes all private methods from the object's delegates" do
|
127
|
-
refute_includes(client.delegated_public_methods, :psst)
|
128
|
-
end
|
129
|
-
|
130
|
-
it "excludes all protected methods from the object's delegates" do
|
131
|
-
refute_includes(client.delegated_public_methods, :hey)
|
132
|
-
end
|
133
|
-
|
134
|
-
it "includes methods from superclasses" do
|
135
|
-
client.cast_as(Nested)
|
136
|
-
assert_includes(client.delegated_public_methods(true), :nested_deep)
|
137
|
-
end
|
138
|
-
|
139
|
-
it "excludes methods from superclasses" do
|
140
|
-
client.cast_as(Nested)
|
141
|
-
refute_includes(client.delegated_public_methods(false), :nested_deep)
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
describe Casting::MissingMethodClient, '#delegated_protected_methods' do
|
146
|
-
let(:client){
|
147
|
-
object = test_person.extend(Casting::Client, Casting::MissingMethodClient)
|
148
|
-
object.cast_as(TestPerson::Greeter)
|
149
|
-
object
|
150
|
-
}
|
151
|
-
|
152
|
-
it "excludes all public methods from the object's delegates" do
|
153
|
-
refute_includes(client.delegated_protected_methods, :greet)
|
154
|
-
end
|
155
|
-
|
156
|
-
it "excludes all private methods from the object's delegates" do
|
157
|
-
refute_includes(client.delegated_protected_methods, :psst)
|
158
|
-
end
|
159
|
-
|
160
|
-
it "includes all protected methods from the object's delegates" do
|
161
|
-
assert_includes(client.delegated_protected_methods, :hey)
|
162
|
-
end
|
163
|
-
|
164
|
-
it "includes methods from superclasses" do
|
165
|
-
client.cast_as(Nested)
|
166
|
-
assert_includes(client.delegated_protected_methods(true), :protected_nested_deep)
|
167
|
-
end
|
168
|
-
|
169
|
-
it "excludes methods from superclasses" do
|
170
|
-
client.cast_as(Nested)
|
171
|
-
refute_includes(client.delegated_protected_methods(false), :protected_nested_deep)
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
describe Casting::MissingMethodClient, '#delegated_private_methods' do
|
176
|
-
let(:client){
|
177
|
-
object = test_person.extend(Casting::Client, Casting::MissingMethodClient)
|
178
|
-
object.cast_as(TestPerson::Greeter)
|
179
|
-
object
|
180
|
-
}
|
181
|
-
|
182
|
-
it "excludes all public methods from the object's delegates" do
|
183
|
-
refute_includes(client.delegated_private_methods, :greet)
|
184
|
-
end
|
185
|
-
|
186
|
-
it "includes all private methods from the object's delegates" do
|
187
|
-
assert_includes(client.delegated_private_methods, :psst)
|
188
|
-
end
|
189
|
-
|
190
|
-
it "excludes all protected methods from the object's delegates" do
|
191
|
-
refute_includes(client.delegated_private_methods, :hey)
|
192
|
-
end
|
193
|
-
|
194
|
-
it "includes methods from superclasses" do
|
195
|
-
client.cast_as(Nested)
|
196
|
-
assert_includes(client.delegated_private_methods(true), :private_nested_deep)
|
197
|
-
end
|
198
|
-
|
199
|
-
it "excludes methods from superclasses" do
|
200
|
-
client.cast_as(Nested)
|
201
|
-
refute_includes(client.delegated_private_methods(false), :private_nested_deep)
|
202
|
-
end
|
203
|
-
end
|
data/test/module_cleanup_test.rb
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
module Cleaner
|
4
|
-
def self.uncast_object(object)
|
5
|
-
object.send(:remove_instance_variable, :@cleaner_message)
|
6
|
-
end
|
7
|
-
|
8
|
-
def self.cast_object(object)
|
9
|
-
object.instance_variable_set(:@cleaner_message, "#{object.name} will be cleaned up")
|
10
|
-
end
|
11
|
-
|
12
|
-
def cleaner_message
|
13
|
-
@cleaner_message
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
class CleanupPerson
|
18
|
-
include Casting::Client
|
19
|
-
delegate_missing_methods
|
20
|
-
attr_accessor :name
|
21
|
-
end
|
22
|
-
|
23
|
-
describe 'modules with setup tasks' do
|
24
|
-
it 'allows modules to setup an object when cast_as' do
|
25
|
-
jim = CleanupPerson.new
|
26
|
-
jim.name = 'Jim'
|
27
|
-
jim.cast_as(Cleaner)
|
28
|
-
assert_equal "Jim will be cleaned up", jim.cleaner_message
|
29
|
-
assert_equal "Jim will be cleaned up", jim.instance_variable_get(:@cleaner_message)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
describe 'modules with cleanup tasks' do
|
34
|
-
it 'allows modules to cleanup their required attributes when uncast' do
|
35
|
-
jim = CleanupPerson.new
|
36
|
-
jim.name = 'Jim'
|
37
|
-
jim.cast_as(Cleaner)
|
38
|
-
assert_equal "Jim will be cleaned up", jim.cleaner_message
|
39
|
-
assert_equal "Jim will be cleaned up", jim.instance_variable_get(:@cleaner_message)
|
40
|
-
jim.uncast
|
41
|
-
refute jim.instance_variable_defined?(:@cleaner_message)
|
42
|
-
end
|
43
|
-
end
|
data/test/null_module_test.rb
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
describe Casting::Null do
|
4
|
-
it 'will answer to any method with nil' do
|
5
|
-
client = TestPerson.new
|
6
|
-
client.extend(Casting::Client)
|
7
|
-
attendant = Casting::Null
|
8
|
-
|
9
|
-
assert_nil client.delegate('greet', attendant)
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
describe Casting::Blank do
|
14
|
-
it 'will answer to any method with an empty string' do
|
15
|
-
client = TestPerson.new
|
16
|
-
client.extend(Casting::Client)
|
17
|
-
attendant = Casting::Blank
|
18
|
-
|
19
|
-
assert_empty client.delegate('greet', attendant)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
describe "making null objects" do
|
24
|
-
it "answers to missing methods" do
|
25
|
-
client = TestPerson.new
|
26
|
-
client.extend(Casting::Client)
|
27
|
-
client.delegate_missing_methods
|
28
|
-
attendant = Casting::Null
|
29
|
-
|
30
|
-
assert_respond_to client.cast_as(attendant), 'xyz'
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
describe "making blank objects" do
|
35
|
-
it "answers to missing methods" do
|
36
|
-
client = TestPerson.new
|
37
|
-
client.extend(Casting::Client)
|
38
|
-
client.delegate_missing_methods
|
39
|
-
attendant = Casting::Blank
|
40
|
-
|
41
|
-
assert_respond_to client.cast_as(attendant), 'xyz'
|
42
|
-
end
|
43
|
-
end
|
data/test/super_test.rb
DELETED
@@ -1,80 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
module AnyWay
|
4
|
-
def which_way
|
5
|
-
"any way"
|
6
|
-
end
|
7
|
-
def way_with_args(one, two, &block)
|
8
|
-
[one, two, block&.call].compact.inspect
|
9
|
-
end
|
10
|
-
def way_with_keyword_args(one:, two:, &block)
|
11
|
-
[one, two, block&.call].compact.inspect
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
module ThisWay
|
16
|
-
include Casting::SuperDelegate
|
17
|
-
def which_way
|
18
|
-
"this way or #{super_delegate}"
|
19
|
-
end
|
20
|
-
def way_with_args(one, two, &block)
|
21
|
-
[one, two, block&.call].compact.inspect
|
22
|
-
end
|
23
|
-
def way_with_keyword_args(one:, two:, &block)
|
24
|
-
[one, two, block&.call].compact.inspect
|
25
|
-
end
|
26
|
-
def no_super
|
27
|
-
super_delegate
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
module ThatWay
|
32
|
-
include Casting::SuperDelegate
|
33
|
-
def which_way
|
34
|
-
"#{ super_delegate(ThatWay) } and that way!"
|
35
|
-
end
|
36
|
-
def way_with_args(one, two, &block)
|
37
|
-
super_delegate(one, two, block&.call).compact
|
38
|
-
end
|
39
|
-
def way_with_keyword_args(one:, two:, &block)
|
40
|
-
[one, two, block&.call].compact.inspect
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
describe Casting, 'modules using delegate_super' do
|
45
|
-
it 'call the method from the next delegate with the same arguments' do
|
46
|
-
client = TestPerson.new.extend(Casting::Client)
|
47
|
-
client.delegate_missing_methods
|
48
|
-
client.cast_as(AnyWay, ThatWay, ThisWay)
|
49
|
-
|
50
|
-
assert_equal 'this way or any way and that way!', client.which_way
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'passes arguments' do
|
54
|
-
client = TestPerson.new.extend(Casting::Client)
|
55
|
-
client.delegate_missing_methods
|
56
|
-
client.cast_as(ThatWay, ThisWay)
|
57
|
-
|
58
|
-
assert_equal %{["first", "second", "block"]}, client.way_with_args('first', 'second'){ 'block' }
|
59
|
-
end
|
60
|
-
|
61
|
-
it 'passes keyword arguments' do
|
62
|
-
client = TestPerson.new.extend(Casting::Client)
|
63
|
-
client.delegate_missing_methods
|
64
|
-
client.cast_as(ThatWay, ThisWay)
|
65
|
-
|
66
|
-
assert_equal %{["first", "second", "block"]}, client.way_with_keyword_args(one: 'first', two: 'second'){ 'block' }
|
67
|
-
end
|
68
|
-
|
69
|
-
it 'raises an error when method is not defined' do
|
70
|
-
client = TestPerson.new.extend(Casting::Client)
|
71
|
-
client.delegate_missing_methods
|
72
|
-
client.cast_as(ThisWay)
|
73
|
-
|
74
|
-
err = expect{
|
75
|
-
client.no_super
|
76
|
-
}.must_raise(NoMethodError)
|
77
|
-
|
78
|
-
expect(err.message).must_match(/super_delegate: no delegate method \`no_super' for \#<TestPerson:\dx[a-z0-9]*> from ThisWay/)
|
79
|
-
end
|
80
|
-
end
|
data/test/test_helper.rb
DELETED
@@ -1,97 +0,0 @@
|
|
1
|
-
require "simplecov"
|
2
|
-
SimpleCov.start do
|
3
|
-
add_filter 'test'
|
4
|
-
end
|
5
|
-
require 'minitest/autorun'
|
6
|
-
require 'casting'
|
7
|
-
|
8
|
-
BlockTestPerson = Struct.new(:name)
|
9
|
-
BlockTestPerson.send(:include, Casting::Client)
|
10
|
-
BlockTestPerson.delegate_missing_methods
|
11
|
-
|
12
|
-
class TestPerson
|
13
|
-
def name
|
14
|
-
'name from TestPerson'
|
15
|
-
end
|
16
|
-
|
17
|
-
module Greeter
|
18
|
-
def greet
|
19
|
-
'hello'
|
20
|
-
end
|
21
|
-
|
22
|
-
protected
|
23
|
-
|
24
|
-
def hey; end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def psst; end
|
29
|
-
end
|
30
|
-
|
31
|
-
module Verbose
|
32
|
-
def verbose(arg1, arg2)
|
33
|
-
[arg1, arg2].join(',')
|
34
|
-
end
|
35
|
-
|
36
|
-
def verbose_keywords(key:, word:)
|
37
|
-
[key, word].join(',')
|
38
|
-
end
|
39
|
-
|
40
|
-
def verbose_multi_args(arg1, arg2, key:, word:, &block)
|
41
|
-
[arg1, arg2, key, word, block&.call].compact.join(',')
|
42
|
-
end
|
43
|
-
|
44
|
-
def verbose_flex(*args, **kwargs, &block)
|
45
|
-
[args, kwargs.map{|k,v| "#{k}:#{v}"}, block&.call].flatten.compact.join(',')
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
class TestGreeter
|
51
|
-
include TestPerson::Greeter
|
52
|
-
end
|
53
|
-
|
54
|
-
class SubTestPerson < TestPerson
|
55
|
-
def sub_method
|
56
|
-
'sub'
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
class Unrelated
|
61
|
-
module More
|
62
|
-
def unrelated
|
63
|
-
'unrelated'
|
64
|
-
end
|
65
|
-
end
|
66
|
-
include More
|
67
|
-
|
68
|
-
def class_defined
|
69
|
-
'oops!'
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
module Deep
|
74
|
-
def nested_deep; end
|
75
|
-
protected
|
76
|
-
def protected_nested_deep; end
|
77
|
-
private
|
78
|
-
def private_nested_deep; end
|
79
|
-
end
|
80
|
-
|
81
|
-
module Nested
|
82
|
-
include Deep
|
83
|
-
|
84
|
-
def nested; end
|
85
|
-
protected
|
86
|
-
def protected_nested; end
|
87
|
-
private
|
88
|
-
def private_nested; end
|
89
|
-
end
|
90
|
-
|
91
|
-
def test_person
|
92
|
-
TestPerson.new
|
93
|
-
end
|
94
|
-
|
95
|
-
def casting_person
|
96
|
-
test_person.extend(Casting::Client)
|
97
|
-
end
|