casting 0.5.2 → 0.6.1
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/lib/casting/client.rb +22 -4
- data/lib/casting/missing_method_client.rb +6 -6
- data/lib/casting/missing_method_client_class.rb +53 -0
- data/lib/casting/prepared_delegation.rb +2 -2
- data/lib/casting/version.rb +1 -1
- data/test/casting_19_test.rb +0 -1
- data/test/casting_20_test.rb +0 -1
- data/test/casting_test.rb +0 -5
- data/test/class_refinement_test.rb +119 -0
- data/test/test_helper.rb +4 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7a049ec2ac612c4ec99f2a08de7050e45242a69a
|
4
|
+
data.tar.gz: fd53cbfb8d14d07a077f001f6d85037e3a3a4a33
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b1ef3ecf6e9fe204ad27b6a5274c021df0f8d4ce7bae9543abe4a57fc7cf7dba54061f3c1bf7b296c9faf008fb75d9b188497619ad0bf3fefe0e05391e2b75e1
|
7
|
+
data.tar.gz: 0a8b280a22b0c34d6cae5b1774ae8c879ab35a9a1080317abf6e3abb657bd2aabf26bbd5ff80864fa8b03517631a29805906f8ccbedc6e6771e39c23946b074b
|
data/lib/casting/client.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
require 'casting/delegation'
|
2
2
|
require 'casting/missing_method_client'
|
3
|
+
require 'casting/missing_method_client_class'
|
3
4
|
|
4
5
|
module Casting
|
5
6
|
module Client
|
6
7
|
|
7
8
|
def self.included(base)
|
8
|
-
def base.delegate_missing_methods
|
9
|
-
|
9
|
+
def base.delegate_missing_methods(*which)
|
10
|
+
Casting::Client.set_delegation_strategy(self, *which.reverse)
|
10
11
|
end
|
11
12
|
|
12
13
|
unless base.instance_methods.include?('delegate')
|
@@ -28,14 +29,31 @@ module Casting
|
|
28
29
|
delegation(delegated_method_name).to(attendant).with(*args).call
|
29
30
|
end
|
30
31
|
|
31
|
-
def delegate_missing_methods
|
32
|
-
self.
|
32
|
+
def delegate_missing_methods(*which)
|
33
|
+
Casting::Client.set_delegation_strategy(self.singleton_class, *which.reverse)
|
33
34
|
end
|
34
35
|
|
35
36
|
private
|
36
37
|
|
38
|
+
def self.set_delegation_strategy(base, *which)
|
39
|
+
which = [:instance] if which.empty?
|
40
|
+
which.map!{|selection|
|
41
|
+
selection == :instance && selection = self.method(:set_method_missing_client)
|
42
|
+
selection == :class && selection = self.method(:set_method_missing_client_class)
|
43
|
+
selection
|
44
|
+
}.map{|meth| meth.call(base) }
|
45
|
+
end
|
46
|
+
|
37
47
|
def self.add_delegate_method_to(base)
|
38
48
|
base.class_eval{ alias_method :delegate, :cast }
|
39
49
|
end
|
50
|
+
|
51
|
+
def self.set_method_missing_client(base)
|
52
|
+
base.send(:include, ::Casting::MissingMethodClient)
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.set_method_missing_client_class(base)
|
56
|
+
base.send(:extend, ::Casting::MissingMethodClientClass)
|
57
|
+
end
|
40
58
|
end
|
41
59
|
end
|
@@ -11,6 +11,12 @@ module Casting
|
|
11
11
|
self
|
12
12
|
end
|
13
13
|
|
14
|
+
private
|
15
|
+
|
16
|
+
def __delegates__
|
17
|
+
@__delegates__ ||= []
|
18
|
+
end
|
19
|
+
|
14
20
|
def method_missing(meth, *args, &block)
|
15
21
|
if !!method_delegate(meth)
|
16
22
|
delegate(meth, method_delegate(meth), *args, &block)
|
@@ -23,12 +29,6 @@ module Casting
|
|
23
29
|
!!method_delegate(meth) || super
|
24
30
|
end
|
25
31
|
|
26
|
-
private
|
27
|
-
|
28
|
-
def __delegates__
|
29
|
-
@__delegates__ ||= []
|
30
|
-
end
|
31
|
-
|
32
32
|
def method_delegate(meth)
|
33
33
|
__delegates__.find{|attendant|
|
34
34
|
if Module === attendant
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Casting
|
2
|
+
module MissingMethodClientClass
|
3
|
+
|
4
|
+
def self.extended(base)
|
5
|
+
base.send(:include, InstanceMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
module InstanceMethods
|
9
|
+
private
|
10
|
+
|
11
|
+
def __class_delegates__
|
12
|
+
self.class.__delegates__
|
13
|
+
end
|
14
|
+
|
15
|
+
def method_missing(meth, *args, &block)
|
16
|
+
if !!method_class_delegate(meth)
|
17
|
+
delegate(meth, method_class_delegate(meth), *args, &block)
|
18
|
+
else
|
19
|
+
super
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def respond_to_missing?(meth, *)
|
24
|
+
!!method_class_delegate(meth) || super
|
25
|
+
end
|
26
|
+
|
27
|
+
def method_class_delegate(meth)
|
28
|
+
__class_delegates__.find{|attendant|
|
29
|
+
if Module === attendant
|
30
|
+
attendant.instance_methods
|
31
|
+
else
|
32
|
+
attendant.methods
|
33
|
+
end.include?(meth)
|
34
|
+
}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def cast_as(attendant)
|
39
|
+
__delegates__.unshift(attendant)
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
def uncast
|
44
|
+
__delegates__.shift
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
def __delegates__
|
49
|
+
Thread.current[:class_delegates] ||= {}
|
50
|
+
Thread.current[:class_delegates][self.name] ||= []
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -27,7 +27,7 @@ module Casting
|
|
27
27
|
@attendant = method_carrier(object_or_module)
|
28
28
|
begin
|
29
29
|
check_valid_type
|
30
|
-
rescue TypeError
|
30
|
+
rescue TypeError
|
31
31
|
raise unless RedCard.check '2.0'
|
32
32
|
@attendant = method_module || raise
|
33
33
|
end
|
@@ -55,7 +55,7 @@ module Casting
|
|
55
55
|
def check_valid_type
|
56
56
|
begin
|
57
57
|
!client.nil? && delegated_method.bind(client)
|
58
|
-
rescue TypeError
|
58
|
+
rescue TypeError
|
59
59
|
raise TypeError.new("`to' argument must be a module or an instance of #{client.class}")
|
60
60
|
end
|
61
61
|
end
|
data/lib/casting/version.rb
CHANGED
data/test/casting_19_test.rb
CHANGED
data/test/casting_20_test.rb
CHANGED
data/test/casting_test.rb
CHANGED
@@ -1,9 +1,4 @@
|
|
1
1
|
require 'test_helper'
|
2
|
-
require 'casting'
|
3
|
-
|
4
|
-
BlockTestPerson = Struct.new(:name)
|
5
|
-
BlockTestPerson.send(:include, Casting::Client)
|
6
|
-
BlockTestPerson.delegate_missing_methods
|
7
2
|
|
8
3
|
describe Casting, '.delegating' do
|
9
4
|
it 'delegates missing methods for the objects inside the block' do
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
ClassDelegatingPerson = Struct.new(:name)
|
4
|
+
ClassDelegatingPerson.send(:include, Casting::Client)
|
5
|
+
ClassDelegatingPerson.delegate_missing_methods :class
|
6
|
+
|
7
|
+
InstanceDelegatingPerson = Struct.new(:name)
|
8
|
+
InstanceDelegatingPerson.send(:include, Casting::Client)
|
9
|
+
InstanceDelegatingPerson.delegate_missing_methods :instance
|
10
|
+
|
11
|
+
ClassThenInstanceDelegatingPerson = Struct.new(:name)
|
12
|
+
ClassThenInstanceDelegatingPerson.send(:include, Casting::Client)
|
13
|
+
ClassThenInstanceDelegatingPerson.delegate_missing_methods :class, :instance
|
14
|
+
|
15
|
+
InstanceThenClassDelegatingPerson = Struct.new(:name)
|
16
|
+
InstanceThenClassDelegatingPerson.send(:include, Casting::Client)
|
17
|
+
InstanceThenClassDelegatingPerson.delegate_missing_methods :instance, :class
|
18
|
+
|
19
|
+
module ClassGreeter
|
20
|
+
def greet
|
21
|
+
'hello from the class delegate'
|
22
|
+
end
|
23
|
+
|
24
|
+
def class_greeting
|
25
|
+
'Hi!'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
module InstanceGreeter
|
30
|
+
def greet
|
31
|
+
'hello from the instance delegate'
|
32
|
+
end
|
33
|
+
|
34
|
+
def instance_greeting
|
35
|
+
'hi!'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe Casting, '.delegating' do
|
40
|
+
it 'delegates methods for all instances to a class delegate inside a block' do
|
41
|
+
jim = ClassDelegatingPerson.new('Jim')
|
42
|
+
amy = ClassDelegatingPerson.new('Amy')
|
43
|
+
|
44
|
+
assert_raises(NoMethodError){
|
45
|
+
jim.greet
|
46
|
+
}
|
47
|
+
Casting.delegating(ClassDelegatingPerson => TestPerson::Greeter) do
|
48
|
+
assert_equal 'hello', jim.greet
|
49
|
+
assert_equal 'hello', amy.greet
|
50
|
+
end
|
51
|
+
assert_raises(NoMethodError){
|
52
|
+
jim.greet
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'delegates methods for given instances to an instance delegate inside a block' do
|
57
|
+
jim = InstanceDelegatingPerson.new('Jim')
|
58
|
+
amy = InstanceDelegatingPerson.new('Amy')
|
59
|
+
|
60
|
+
assert_raises(NoMethodError){
|
61
|
+
jim.greet
|
62
|
+
}
|
63
|
+
Casting.delegating(jim => TestPerson::Greeter) do
|
64
|
+
assert_equal 'hello', jim.greet
|
65
|
+
assert_raises(NoMethodError){ amy.greet }
|
66
|
+
end
|
67
|
+
assert_raises(NoMethodError){
|
68
|
+
jim.greet
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'delegates first to class delegates, then to instance delegates inside a block' do
|
73
|
+
jim = ClassThenInstanceDelegatingPerson.new('Jim')
|
74
|
+
amy = ClassThenInstanceDelegatingPerson.new('Amy')
|
75
|
+
|
76
|
+
assert_raises(NoMethodError){
|
77
|
+
jim.greet
|
78
|
+
}
|
79
|
+
Casting.delegating(ClassThenInstanceDelegatingPerson => ClassGreeter, jim => InstanceGreeter) do
|
80
|
+
assert_equal 'hello from the class delegate', jim.greet
|
81
|
+
assert_equal 'hi!', jim.instance_greeting
|
82
|
+
assert_equal 'hello from the class delegate', amy.greet
|
83
|
+
assert(NoMethodError){ amy.instance_greeting }
|
84
|
+
end
|
85
|
+
assert_raises(NoMethodError){
|
86
|
+
jim.greet
|
87
|
+
}
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'delegates first to instance delegates, then to class delegates inside a block' do
|
91
|
+
jim = InstanceThenClassDelegatingPerson.new('Jim')
|
92
|
+
amy = InstanceThenClassDelegatingPerson.new('Amy')
|
93
|
+
|
94
|
+
assert_raises(NoMethodError){
|
95
|
+
jim.greet
|
96
|
+
}
|
97
|
+
Casting.delegating(InstanceThenClassDelegatingPerson => ClassGreeter, jim => InstanceGreeter) do
|
98
|
+
assert_equal 'hello from the instance delegate', jim.greet
|
99
|
+
assert_equal 'hi!', jim.instance_greeting
|
100
|
+
assert_equal 'hello from the class delegate', amy.greet
|
101
|
+
assert(NoMethodError){ amy.instance_greeting }
|
102
|
+
end
|
103
|
+
assert_raises(NoMethodError){
|
104
|
+
jim.greet
|
105
|
+
}
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'sets instances to respond_to? class delegate methods' do
|
109
|
+
jim = ClassDelegatingPerson.new('Jim')
|
110
|
+
|
111
|
+
refute jim.respond_to?(:greet)
|
112
|
+
|
113
|
+
Casting.delegating(ClassDelegatingPerson => ClassGreeter) do
|
114
|
+
assert jim.respond_to?(:greet)
|
115
|
+
end
|
116
|
+
|
117
|
+
refute jim.respond_to?(:greet)
|
118
|
+
end
|
119
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -6,9 +6,12 @@ end
|
|
6
6
|
require 'coveralls'
|
7
7
|
Coveralls.wear!
|
8
8
|
|
9
|
-
require 'minitest/spec'
|
10
9
|
require 'minitest/autorun'
|
10
|
+
require 'casting'
|
11
11
|
|
12
|
+
BlockTestPerson = Struct.new(:name)
|
13
|
+
BlockTestPerson.send(:include, Casting::Client)
|
14
|
+
BlockTestPerson.delegate_missing_methods
|
12
15
|
|
13
16
|
class TestPerson
|
14
17
|
def name
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: casting
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jim Gay
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-05
|
11
|
+
date: 2013-06-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redcard
|
@@ -38,12 +38,14 @@ files:
|
|
38
38
|
- lib/casting/version.rb
|
39
39
|
- lib/casting/delegation.rb
|
40
40
|
- lib/casting/missing_method_client.rb
|
41
|
+
- lib/casting/missing_method_client_class.rb
|
41
42
|
- lib/casting/prepared_delegation.rb
|
42
43
|
- lib/casting/client.rb
|
43
44
|
- test/test_helper.rb
|
44
45
|
- test/casting_19_test.rb
|
45
46
|
- test/casting_20_test.rb
|
46
47
|
- test/casting_test.rb
|
48
|
+
- test/class_refinement_test.rb
|
47
49
|
- test/client_test.rb
|
48
50
|
- test/delegation_test.rb
|
49
51
|
- test/missing_method_client_test.rb
|
@@ -67,7 +69,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
67
69
|
version: '0'
|
68
70
|
requirements: []
|
69
71
|
rubyforge_project:
|
70
|
-
rubygems_version: 2.0.
|
72
|
+
rubygems_version: 2.0.3
|
71
73
|
signing_key:
|
72
74
|
specification_version: 4
|
73
75
|
summary: Proper method delegation.
|
@@ -76,6 +78,7 @@ test_files:
|
|
76
78
|
- test/casting_19_test.rb
|
77
79
|
- test/casting_20_test.rb
|
78
80
|
- test/casting_test.rb
|
81
|
+
- test/class_refinement_test.rb
|
79
82
|
- test/client_test.rb
|
80
83
|
- test/delegation_test.rb
|
81
84
|
- test/missing_method_client_test.rb
|