casting 0.2.0 → 0.3.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 +7 -0
- data/lib/casting.rb +128 -0
- data/lib/casting/version.rb +3 -0
- data/test/casting_test.rb +27 -52
- data/test/test_helper.rb +46 -6
- metadata +19 -16
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4cd9c772929ade9385c386920a6983f76b7d4499
|
4
|
+
data.tar.gz: 30a9a0733b90d6b228bee245177c70ef59c75ea5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9f8fe2c025d614134d088537c2afe2f9513c7d474ab1d9e02d19e57cd2c0a03497ed35dab6bdacf268892dea6c167090abe2f48b39032c2cbf8daeaf27cbef98
|
7
|
+
data.tar.gz: 6df689773211f4dab302fee36785709c883addb19672c0c662f9df0d4c9a3b8f8e2064f7d2625d222e8c1221d8f5b3b64b5f113722a033fc677288314415fdbe
|
data/lib/casting.rb
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'redcard'
|
2
|
+
|
3
|
+
module Casting
|
4
|
+
|
5
|
+
class MissingAttendant < StandardError
|
6
|
+
def message
|
7
|
+
"You must set your attendant object using `to'."
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class InvalidAttendant < StandardError
|
12
|
+
end
|
13
|
+
|
14
|
+
module Client
|
15
|
+
def delegation(delegated_method_name)
|
16
|
+
Casting::Delegation.new(delegated_method_name, self)
|
17
|
+
end
|
18
|
+
|
19
|
+
def delegate(delegated_method_name, attendant, *args)
|
20
|
+
delegation(delegated_method_name).to(attendant).with(*args).call
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class PreparedDelegation
|
25
|
+
|
26
|
+
attr_reader :client
|
27
|
+
attr_reader :delegated_method_name, :attendant, :arguments
|
28
|
+
private :delegated_method_name, :attendant, :arguments
|
29
|
+
|
30
|
+
def initialize(settings)
|
31
|
+
@delegated_method_name = settings[:delegated_method_name]
|
32
|
+
@client = settings[:client]
|
33
|
+
@attendant = settings[:attendant]
|
34
|
+
@arguments = settings[:arguments]
|
35
|
+
end
|
36
|
+
|
37
|
+
def to(object_or_module)
|
38
|
+
@attendant = method_carrier(object_or_module)
|
39
|
+
begin
|
40
|
+
check_valid_type
|
41
|
+
rescue TypeError => e
|
42
|
+
raise unless RedCard.check '2.0'
|
43
|
+
@attendant = method_module || raise
|
44
|
+
end
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
def with(*args)
|
49
|
+
@arguments = args
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
53
|
+
def call
|
54
|
+
raise MissingAttendant.new unless attendant
|
55
|
+
|
56
|
+
if arguments
|
57
|
+
delegated_method.bind(client).call(*arguments)
|
58
|
+
else
|
59
|
+
delegated_method.bind(client).call
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def check_valid_type
|
66
|
+
begin
|
67
|
+
!client.nil? && delegated_method.bind(client)
|
68
|
+
rescue TypeError => e
|
69
|
+
raise TypeError.new("`to' argument must be a module or an instance of #{client.class}")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def method_carrier(object_or_module)
|
74
|
+
if Module === object_or_module
|
75
|
+
if RedCard.check '2.0'
|
76
|
+
object_or_module
|
77
|
+
else
|
78
|
+
client.clone.extend(object_or_module)
|
79
|
+
end
|
80
|
+
else
|
81
|
+
object_or_module
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def method_module
|
86
|
+
delegated_method.owner unless delegated_method.owner.is_a?(Class)
|
87
|
+
end
|
88
|
+
|
89
|
+
def delegated_method
|
90
|
+
if Module === attendant
|
91
|
+
attendant.instance_method(delegated_method_name)
|
92
|
+
else
|
93
|
+
attendant.method(delegated_method_name).unbind
|
94
|
+
end
|
95
|
+
rescue NameError => e
|
96
|
+
raise InvalidAttendant.new(e.message)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
class Delegation
|
101
|
+
|
102
|
+
attr_reader :prepared_delegation
|
103
|
+
private :prepared_delegation
|
104
|
+
|
105
|
+
def initialize(delegated_method_name, client)
|
106
|
+
@prepared_delegation = PreparedDelegation.new(:delegated_method_name => delegated_method_name, :client => client)
|
107
|
+
end
|
108
|
+
|
109
|
+
def client
|
110
|
+
prepared_delegation.client
|
111
|
+
end
|
112
|
+
|
113
|
+
def to(object_or_module)
|
114
|
+
prepared_delegation.to(object_or_module)
|
115
|
+
self
|
116
|
+
end
|
117
|
+
|
118
|
+
def with(*args)
|
119
|
+
prepared_delegation.with(*args)
|
120
|
+
self
|
121
|
+
end
|
122
|
+
|
123
|
+
def call
|
124
|
+
prepared_delegation.call
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
end
|
data/test/casting_test.rb
CHANGED
@@ -1,34 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
class TestPerson
|
5
|
-
def name
|
6
|
-
'name from TestPerson'
|
7
|
-
end
|
8
|
-
|
9
|
-
module Greeter
|
10
|
-
def greet
|
11
|
-
'hello'
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
module Verbose
|
16
|
-
def verbose(arg1, arg2)
|
17
|
-
%w{arg1 arg2}.join(',')
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
class SubTestPerson < TestPerson
|
23
|
-
def sub_method
|
24
|
-
'sub'
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
class Unrelated
|
29
|
-
end
|
1
|
+
require 'test_helper'
|
2
|
+
require 'casting'
|
30
3
|
|
31
4
|
describe Casting::Delegation do
|
5
|
+
|
32
6
|
it 'initializes with method name and object' do
|
33
7
|
assert Casting::Delegation.new('some_method', Object.new)
|
34
8
|
end
|
@@ -42,39 +16,43 @@ describe Casting::Delegation do
|
|
42
16
|
|
43
17
|
it 'raises an error when setting an invalid attendant type' do
|
44
18
|
delegation = Casting::Delegation.new('some_method', TestPerson.new)
|
45
|
-
assert_raises(
|
19
|
+
assert_raises(Casting::InvalidAttendant){
|
46
20
|
delegation.to(Unrelated.new)
|
47
21
|
}
|
48
22
|
end
|
49
23
|
|
50
24
|
it 'sets an attendant to an object of an ancestor class of the object class' do
|
51
|
-
attendant =
|
25
|
+
attendant = test_person
|
52
26
|
client = SubTestPerson.new
|
53
27
|
|
54
28
|
delegation = Casting::Delegation.new('name', client)
|
55
29
|
assert delegation.to(attendant)
|
56
30
|
end
|
57
31
|
|
58
|
-
it '
|
59
|
-
client =
|
60
|
-
|
61
|
-
attendant.extend(TestPerson::Greeter)
|
62
|
-
delegation = Casting::Delegation.new('greet', client).to(attendant)
|
32
|
+
it 'delegates when given a module' do
|
33
|
+
client = test_person
|
34
|
+
delegation = Casting::Delegation.new('greet', client).to(TestPerson::Greeter)
|
63
35
|
assert_equal 'hello', delegation.call
|
64
36
|
end
|
65
37
|
|
66
|
-
it '
|
67
|
-
client =
|
38
|
+
it 'does not delegate when given a class' do
|
39
|
+
client = test_person
|
40
|
+
assert_raises(TypeError){
|
41
|
+
Casting::Delegation.new('class_defined', client).to(Unrelated)
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'assigns arguments to the delegated method using with' do
|
46
|
+
client = test_person
|
68
47
|
attendant = TestPerson.new
|
69
48
|
attendant.extend(TestPerson::Verbose)
|
70
|
-
delegation = Casting::Delegation.new('verbose', client).to(attendant).with('arg1','arg2')
|
71
|
-
assert_equal 'arg1,arg2', delegation.call
|
72
|
-
end
|
73
49
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
50
|
+
delegation = Casting::Delegation.new('verbose', client).to(attendant)
|
51
|
+
|
52
|
+
attendant_output = attendant.verbose('hello', 'goodbye')
|
53
|
+
delegation_output = delegation.with('hello', 'goodbye').call
|
54
|
+
|
55
|
+
assert_equal attendant_output, delegation_output
|
78
56
|
end
|
79
57
|
end
|
80
58
|
|
@@ -84,10 +62,9 @@ describe Casting::Client do
|
|
84
62
|
client.extend(Casting::Client)
|
85
63
|
attendant = TestPerson.new
|
86
64
|
attendant.extend(TestPerson::Greeter)
|
87
|
-
|
88
65
|
assert_equal attendant.greet, client.delegate('greet', attendant)
|
89
66
|
end
|
90
|
-
|
67
|
+
|
91
68
|
it 'passes additional parameters to the attendant' do
|
92
69
|
client = TestPerson.new
|
93
70
|
client.extend(Casting::Client)
|
@@ -99,15 +76,13 @@ describe Casting::Client do
|
|
99
76
|
|
100
77
|
assert_equal attendant_output, client_output
|
101
78
|
end
|
102
|
-
|
79
|
+
|
103
80
|
it 'passes the object as the client for delegation' do
|
104
81
|
client = Object.new
|
105
82
|
client.extend(Casting::Client)
|
106
83
|
|
107
84
|
delegation = client.delegation('id')
|
108
|
-
|
85
|
+
|
109
86
|
assert_equal client, delegation.client
|
110
87
|
end
|
111
|
-
end
|
112
|
-
|
113
|
-
CoverMe.complete!
|
88
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -1,9 +1,49 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
|
4
|
-
c.project.root = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
5
|
-
c.file_pattern = [/#{CoverMe.config.project.root}\/lib\/.+\.rb/]
|
1
|
+
require 'simplecov'
|
2
|
+
SimpleCov.start do
|
3
|
+
add_filter 'test'
|
6
4
|
end
|
7
5
|
|
8
6
|
require 'minitest/spec'
|
9
|
-
require 'minitest/autorun'
|
7
|
+
require 'minitest/autorun'
|
8
|
+
|
9
|
+
|
10
|
+
class TestPerson
|
11
|
+
def name
|
12
|
+
'name from TestPerson'
|
13
|
+
end
|
14
|
+
|
15
|
+
module Greeter
|
16
|
+
def greet
|
17
|
+
'hello'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module Verbose
|
22
|
+
def verbose(arg1, arg2)
|
23
|
+
%w{arg1 arg2}.join(',')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class SubTestPerson < TestPerson
|
29
|
+
def sub_method
|
30
|
+
'sub'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Unrelated
|
35
|
+
module More
|
36
|
+
def unrelated
|
37
|
+
'unrelated'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
include More
|
41
|
+
|
42
|
+
def class_defined
|
43
|
+
'oops!'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_person
|
48
|
+
TestPerson.new
|
49
|
+
end
|
metadata
CHANGED
@@ -1,27 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: casting
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.3.1
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Jim Gay
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2013-05-20 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
16
|
-
requirement:
|
17
|
-
none: false
|
14
|
+
name: redcard
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - ~>
|
20
18
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
22
|
-
type: :
|
19
|
+
version: 1.1.0
|
20
|
+
type: :runtime
|
23
21
|
prerelease: false
|
24
|
-
version_requirements:
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.1.0
|
25
27
|
description: Proper method delegation.
|
26
28
|
email:
|
27
29
|
- jim@saturnflyer.com
|
@@ -29,31 +31,32 @@ executables: []
|
|
29
31
|
extensions: []
|
30
32
|
extra_rdoc_files: []
|
31
33
|
files:
|
34
|
+
- lib/casting.rb
|
35
|
+
- lib/casting/version.rb
|
32
36
|
- test/test_helper.rb
|
33
37
|
- test/casting_test.rb
|
34
38
|
homepage: ''
|
35
39
|
licenses: []
|
40
|
+
metadata: {}
|
36
41
|
post_install_message:
|
37
42
|
rdoc_options: []
|
38
43
|
require_paths:
|
39
44
|
- lib
|
40
45
|
required_ruby_version: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
46
|
requirements:
|
43
|
-
- -
|
47
|
+
- - '>='
|
44
48
|
- !ruby/object:Gem::Version
|
45
49
|
version: '0'
|
46
50
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
|
-
none: false
|
48
51
|
requirements:
|
49
|
-
- -
|
52
|
+
- - '>='
|
50
53
|
- !ruby/object:Gem::Version
|
51
54
|
version: '0'
|
52
55
|
requirements: []
|
53
56
|
rubyforge_project:
|
54
|
-
rubygems_version:
|
57
|
+
rubygems_version: 2.0.0
|
55
58
|
signing_key:
|
56
|
-
specification_version:
|
59
|
+
specification_version: 4
|
57
60
|
summary: Proper method delegation.
|
58
61
|
test_files:
|
59
62
|
- test/test_helper.rb
|