rietveld 1.0.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 +7 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +13 -0
- data/Rakefile +1 -0
- data/lib/rietveld/context.rb +32 -0
- data/lib/rietveld/role.rb +365 -0
- data/lib/rietveld/version.rb +3 -0
- data/lib/rietveld.rb +6 -0
- data/rietveld.gemspec +26 -0
- data/spec/example_context_specs/money_transfer_spec.rb +66 -0
- data/spec/role_spec.rb +120 -0
- data/spec/spec_helper.rb +8 -0
- metadata +103 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0f831ee5bab34effe5e45935530fa692b5148d03
|
4
|
+
data.tar.gz: 7249be7df3e42e3a8cc62872ea36c3ec8dfad061
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5bb4ddb9985c21de6e899c26f6f2e4f6f2dbeb383bf73a65bd9490612a04292c5eaed5fe36c555ca267d7621877dee9a2443f53055eebc13fdf49895666f86f7
|
7
|
+
data.tar.gz: fa16fccfea98bc912b3601b6862ab6edec15369d15b72bb04fdc3060c5944bbb31b1d36311df7ad86b9307f30dac6ac726eacd53a6bf145ab97aaab62ecbef53
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Marten Schilstra
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Rietveld
|
2
|
+
class Context
|
3
|
+
class << self
|
4
|
+
def roles
|
5
|
+
@roles ||= {}
|
6
|
+
end
|
7
|
+
|
8
|
+
def role(role_name, &block)
|
9
|
+
roles[role_name] = Class.new(Rietveld::Role, &block)
|
10
|
+
|
11
|
+
define_method(role_name) do
|
12
|
+
instance_variable_get("@#{role_name}")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def roles
|
18
|
+
self.class.roles
|
19
|
+
end
|
20
|
+
|
21
|
+
def role?(name)
|
22
|
+
roles.key?(name)
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(**args)
|
26
|
+
roles.each do |role_name, role_klass|
|
27
|
+
role_object = role_klass.new(args[role_name], self)
|
28
|
+
instance_variable_set("@#{role_name}", role_object)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,365 @@
|
|
1
|
+
module Rietveld # :nodoc:
|
2
|
+
|
3
|
+
##
|
4
|
+
# The Role class implements a DCI Role with the Delegator pattern.
|
5
|
+
#
|
6
|
+
# It tries to be as transparent as possible to the object it delegates to. For
|
7
|
+
# instance most BasicObject and Kernel methods are directly forwarded. Though
|
8
|
+
# methods concerning methods and / or instance variables return values from
|
9
|
+
# the delegator and the object it delegates to.
|
10
|
+
|
11
|
+
class Role < BasicObject
|
12
|
+
# Inherit from Basic Object and include Kernel, this is to avoid Rails
|
13
|
+
# injecting unwanted methods into our precious Role class
|
14
|
+
include ::Kernel
|
15
|
+
|
16
|
+
# The object acting out this role
|
17
|
+
attr_accessor :__role_player__
|
18
|
+
|
19
|
+
# Returns the context this role is playing in
|
20
|
+
attr_accessor :__context__
|
21
|
+
|
22
|
+
def initialize(role_player, context = nil)
|
23
|
+
self.__role_player__ = role_player
|
24
|
+
self.__context__ = context
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns the __role_player__ without its role object wrapping it.
|
28
|
+
def unwrap
|
29
|
+
__role_player__
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns the class of the role itself
|
33
|
+
alias_method :role_class, :class
|
34
|
+
|
35
|
+
# Gets a method defined on the role itself
|
36
|
+
alias_method :role_method, :method
|
37
|
+
|
38
|
+
# Get an array of methods defined on the role itself
|
39
|
+
alias_method :role_methods, :methods
|
40
|
+
|
41
|
+
# Get an array of protected methods defined on the role itself
|
42
|
+
alias_method :role_protected_methods, :protected_methods
|
43
|
+
|
44
|
+
# Get an array of public methods defined on the role itself
|
45
|
+
alias_method :role_public_methods, :public_methods
|
46
|
+
|
47
|
+
# Get an array of private methods defined on the role itself
|
48
|
+
alias_method :role_private_methods, :private_methods
|
49
|
+
|
50
|
+
# Is the other role equal? to this one
|
51
|
+
alias_method :role_equal?, :equal?
|
52
|
+
|
53
|
+
# Is the other role eql? to this one
|
54
|
+
alias_method :role_eql?, :eql?
|
55
|
+
|
56
|
+
# Get the hash for the role
|
57
|
+
alias_method :role_hash, :hash
|
58
|
+
|
59
|
+
# Gets the instance variables defined on the role itself
|
60
|
+
alias_method :role_instance_variables, :instance_variables
|
61
|
+
|
62
|
+
# Get an instance variable defined on the role
|
63
|
+
alias_method :role_instance_variable_get, :instance_variable_get
|
64
|
+
|
65
|
+
# Set an instance variable defined on the role
|
66
|
+
alias_method :role_instance_variable_set, :instance_variable_set
|
67
|
+
|
68
|
+
# Remove an instance variable defined on the role
|
69
|
+
alias_method :remove_role_instance_variable, :remove_instance_variable
|
70
|
+
|
71
|
+
# Is given instance variable defined on the role
|
72
|
+
alias_method :role_instance_variable_defined?, :instance_variable_defined?
|
73
|
+
|
74
|
+
# Get the singleton class of the role
|
75
|
+
alias_method :role_singleton_class, :singleton_class
|
76
|
+
|
77
|
+
# Gets the singleton methods defined on the role itself
|
78
|
+
alias_method :role_singleton_methods, :singleton_methods
|
79
|
+
|
80
|
+
# Gets a singleton method defined on the role itself
|
81
|
+
alias_method :role_singleton_method, :singleton_method
|
82
|
+
|
83
|
+
##--
|
84
|
+
## From BasicObject
|
85
|
+
##++
|
86
|
+
|
87
|
+
# See BasicObject#==, forwarded to __role_player__
|
88
|
+
def ==(other)
|
89
|
+
__role_player__ == other
|
90
|
+
end
|
91
|
+
|
92
|
+
# See BasicObject#equal?, forwarded to __role_player__
|
93
|
+
def equal?(other)
|
94
|
+
__role_player__.equal?(other)
|
95
|
+
end
|
96
|
+
|
97
|
+
# See BasicObject#class, forwarded to __role_player__
|
98
|
+
def class
|
99
|
+
__role_player__.class
|
100
|
+
end
|
101
|
+
|
102
|
+
# See BasicObject#!, forwarded to __role_player__
|
103
|
+
def !
|
104
|
+
!__role_player__
|
105
|
+
end
|
106
|
+
|
107
|
+
# See BasicObject#!=, forwarded to __role_player__
|
108
|
+
def !=(other)
|
109
|
+
__role_player__ != other
|
110
|
+
end
|
111
|
+
|
112
|
+
private
|
113
|
+
|
114
|
+
# See BasicObject#singleton_method_added, forwarded to __role_player__
|
115
|
+
def singleton_method_added(sym)
|
116
|
+
__role_player__.singleton_method_added(sym)
|
117
|
+
end
|
118
|
+
|
119
|
+
# See BasicObject#singleton_method_removed, forwarded to __role_player__
|
120
|
+
def singleton_method_removed(sym)
|
121
|
+
__role_player__.singleton_method_removed(sym)
|
122
|
+
end
|
123
|
+
|
124
|
+
# See BasicObject#singleton_method_undefined, forwarded to __role_player__
|
125
|
+
def singleton_method_undefined(sym)
|
126
|
+
__role_player__.singleton_method_undefined(sym)
|
127
|
+
end
|
128
|
+
|
129
|
+
# If the role itself does not have a given method defined, it will try to
|
130
|
+
# delegate it to the role_player
|
131
|
+
def method_missing(name, *args, &block)
|
132
|
+
if __role_player__.respond_to?(name)
|
133
|
+
__role_player__.__send__(name, *args, &block)
|
134
|
+
elsif __context__.role?(name)
|
135
|
+
__context__.send(name)
|
136
|
+
else
|
137
|
+
super
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
public
|
142
|
+
|
143
|
+
# True if either role object or role_player responds to given method
|
144
|
+
def respond_to?(name, include_all = false)
|
145
|
+
__role_player__.respond_to?(name, include_all) || super
|
146
|
+
end
|
147
|
+
|
148
|
+
# True if either role object or role_player responds to given missing method
|
149
|
+
def respond_to_missing?(name, include_private = false)
|
150
|
+
__role_player__.respond_to_missing?(name, include_private) || super
|
151
|
+
end
|
152
|
+
|
153
|
+
##--
|
154
|
+
## From Kernel
|
155
|
+
##++
|
156
|
+
|
157
|
+
# See Kernel#nil?, forwarded to __role_player__
|
158
|
+
def nil?
|
159
|
+
__role_player__.nil?
|
160
|
+
end
|
161
|
+
|
162
|
+
# See Kernel#===, forwarded to __role_player__
|
163
|
+
def ===(other)
|
164
|
+
__role_player__ === other
|
165
|
+
end
|
166
|
+
|
167
|
+
# See Kernel#=~, forwarded to __role_player__
|
168
|
+
def =~(other)
|
169
|
+
__role_player__ =~ other
|
170
|
+
end
|
171
|
+
|
172
|
+
# See Kernel#!~, forwarded to __role_player__
|
173
|
+
def !~(other)
|
174
|
+
__role_player__ !~ other
|
175
|
+
end
|
176
|
+
|
177
|
+
# See Kernel#eql?, forwarded to __role_player__
|
178
|
+
def eql?(other)
|
179
|
+
__role_player__.eql?(other)
|
180
|
+
end
|
181
|
+
|
182
|
+
# See Kernel#hash, forwarded to __role_player__
|
183
|
+
def hash
|
184
|
+
__role_player__.hash
|
185
|
+
end
|
186
|
+
|
187
|
+
# See Kernel#<=>, forwarded to __role_player__
|
188
|
+
def <=>(other)
|
189
|
+
__role_player__ <=> other
|
190
|
+
end
|
191
|
+
|
192
|
+
# Returns the class of the __role_player__
|
193
|
+
def class
|
194
|
+
__role_player__.class
|
195
|
+
end
|
196
|
+
|
197
|
+
# Returns the singleton_class of the __role_player__
|
198
|
+
def singleton_class
|
199
|
+
__role_player__.singleton_class
|
200
|
+
end
|
201
|
+
|
202
|
+
# Returns a clone of role object with a clone of the __role_player__
|
203
|
+
def clone
|
204
|
+
role_clone = super
|
205
|
+
role_clone.__role_player__ = __role_player__.clone
|
206
|
+
role_clone
|
207
|
+
end
|
208
|
+
|
209
|
+
# Returns a dup of __role_player__
|
210
|
+
def dup
|
211
|
+
__role_player__.dup
|
212
|
+
end
|
213
|
+
|
214
|
+
# See Kernel#taint, forwarded to __role_player__
|
215
|
+
def taint
|
216
|
+
super
|
217
|
+
__role_player__.taint
|
218
|
+
end
|
219
|
+
|
220
|
+
# See Kernel#tainted?, forwarded to __role_player__
|
221
|
+
def tainted?
|
222
|
+
super || __role_player__.tainted?
|
223
|
+
end
|
224
|
+
|
225
|
+
# See Kernel#untaint, forwarded to __role_player__
|
226
|
+
def untaint
|
227
|
+
super
|
228
|
+
__role_player__.untaint
|
229
|
+
end
|
230
|
+
|
231
|
+
# See Kernel#freeze, forwarded to __role_player__
|
232
|
+
def freeze
|
233
|
+
super
|
234
|
+
__role_player__.freeze
|
235
|
+
end
|
236
|
+
|
237
|
+
# See Kernel#unfreeze, forwarded to __role_player__
|
238
|
+
def unfreeze
|
239
|
+
super || __role_player__.frozen?
|
240
|
+
end
|
241
|
+
|
242
|
+
# See Kernel#to_s, forwarded to __role_player__
|
243
|
+
def to_s
|
244
|
+
__role_player__.to_s
|
245
|
+
end
|
246
|
+
|
247
|
+
# See Kernel#inspect, forwarded to __role_player__
|
248
|
+
#
|
249
|
+
# Returns a string in the form of:
|
250
|
+
# #<ExampleRole:0x37d837e #<ExampleObject>>
|
251
|
+
def inspect
|
252
|
+
"#<#{role_class.name}:0x#{__id__.to_s(16)} #{__role_player__.inspect}>"
|
253
|
+
end
|
254
|
+
|
255
|
+
# See Kernel#methods, returns the union of the methods from the role object
|
256
|
+
# and __role_player__
|
257
|
+
def methods
|
258
|
+
super | __role_player__.methods
|
259
|
+
end
|
260
|
+
|
261
|
+
# See Kernel#singleton_methods, returns the union of the singleton methods
|
262
|
+
# from the role object and __role_player__
|
263
|
+
def singleton_methods
|
264
|
+
__role_player__.singleton_methods
|
265
|
+
end
|
266
|
+
|
267
|
+
# See Kernel#protected_methods, returns the union of the protected_methods
|
268
|
+
# from the role object and __role_player__
|
269
|
+
def protected_methods
|
270
|
+
super | __role_player__.protected_methods
|
271
|
+
end
|
272
|
+
|
273
|
+
# See Kernel#private_methods, returns the union of the private_methods
|
274
|
+
# from the role object and __role_player__
|
275
|
+
def private_methods
|
276
|
+
super | __role_player__.private_methods
|
277
|
+
end
|
278
|
+
|
279
|
+
# See Kernel#private_methods, returns the union of the private_methods
|
280
|
+
# from the role object and __role_player__
|
281
|
+
def public_methods
|
282
|
+
super | __role_player__.public_methods
|
283
|
+
end
|
284
|
+
|
285
|
+
# See Kernel#instance_variables, returns the union of the instance_variables
|
286
|
+
# from the role object and __role_player__
|
287
|
+
def instance_variables
|
288
|
+
super | __role_player__.instance_variables
|
289
|
+
end
|
290
|
+
|
291
|
+
# See Kernel#instance_variable_get, prefers to return an instance variable
|
292
|
+
# defined on __role_player__, otherwise will lookup instance variables on
|
293
|
+
# role
|
294
|
+
def instance_variable_get(name)
|
295
|
+
__role_player__.instance_variable_get(name) || super
|
296
|
+
end
|
297
|
+
|
298
|
+
# See Kernel#instance_variable_set, prefers to set an instance variable
|
299
|
+
# on __role_player__, if an instance variable with the same name on the role
|
300
|
+
# object is already set, it wil set one on the role.
|
301
|
+
def instance_variable_set(name, value)
|
302
|
+
if role_instance_variable_defined?(name)
|
303
|
+
super
|
304
|
+
else
|
305
|
+
__role_player__.instance_variable_set(name, value)
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
# See Kernel#instance_variable_defined?, returns true if an instance
|
310
|
+
# variable is defined on either __role_player__ or the role object
|
311
|
+
def instance_variable_defined?(name)
|
312
|
+
super || __role_player__.instance_variable_defined?(name)
|
313
|
+
end
|
314
|
+
|
315
|
+
# See Kernel#remove_instance_variable, if the instance variable is defined
|
316
|
+
# on the role object, it wil remove that one, else it will remove one
|
317
|
+
# defined on __role_player__
|
318
|
+
def remove_instance_variable(name)
|
319
|
+
if role_instance_variable_defined?(name)
|
320
|
+
super
|
321
|
+
else
|
322
|
+
__role_player__.remove_instance_variable(name)
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
# See Kernel#instance_of?, forwarded to __role_player__
|
327
|
+
def instance_of?(type)
|
328
|
+
__role_player__.instance_of?(type)
|
329
|
+
end
|
330
|
+
|
331
|
+
# See Kernel#kind_of?, forwarded to __role_player__
|
332
|
+
def kind_of?(type)
|
333
|
+
__role_player__.kind_of?(type)
|
334
|
+
end
|
335
|
+
|
336
|
+
# See Kernel#is_a?, forwarded to __role_player__
|
337
|
+
def is_a?(type)
|
338
|
+
__role_player__.is_a?(type)
|
339
|
+
end
|
340
|
+
|
341
|
+
# See Kernel#method, if given method is defined on role object, it will
|
342
|
+
# return that one, otherwise the one from __role_player__
|
343
|
+
def method(name)
|
344
|
+
super
|
345
|
+
rescue
|
346
|
+
__role_player__.method(name)
|
347
|
+
end
|
348
|
+
|
349
|
+
# See Kernel#public_method, if given public_method is defined on role
|
350
|
+
# object, it will return that one, otherwise the one from __role_player__
|
351
|
+
def public_method(name)
|
352
|
+
super
|
353
|
+
rescue
|
354
|
+
__role_player__.public_method(name)
|
355
|
+
end
|
356
|
+
|
357
|
+
# See Kernel#singleton_method, if given singleton_method is defined on role
|
358
|
+
# object, it will return that one, otherwise the one from __role_player__
|
359
|
+
def singleton_method(name)
|
360
|
+
super
|
361
|
+
rescue
|
362
|
+
__role_player__.singleton_method(name)
|
363
|
+
end
|
364
|
+
end
|
365
|
+
end
|
data/lib/rietveld.rb
ADDED
data/rietveld.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rietveld/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rietveld"
|
8
|
+
spec.version = Rietveld::VERSION
|
9
|
+
spec.authors = ["Marten Schilstra"]
|
10
|
+
spec.email = ["mail@martenschilstra.nl"]
|
11
|
+
spec.summary = %q{
|
12
|
+
A practical implementation of DCI for Ruby
|
13
|
+
}
|
14
|
+
spec.description = ""
|
15
|
+
spec.homepage = ""
|
16
|
+
spec.license = "MIT"
|
17
|
+
|
18
|
+
spec.files = `git ls-files -z`.split("\x0")
|
19
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
|
+
spec.require_paths = ["lib"]
|
22
|
+
|
23
|
+
spec.add_development_dependency 'bundler', '~> 1.5'
|
24
|
+
spec.add_development_dependency 'rake'
|
25
|
+
spec.add_development_dependency 'rspec', '~> 3.0.0beta'
|
26
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class BankAccount
|
4
|
+
attr_accessor :balance
|
5
|
+
|
6
|
+
def initialize(initial_balance = 0)
|
7
|
+
self.balance = initial_balance
|
8
|
+
end
|
9
|
+
|
10
|
+
def increase_balance(amount)
|
11
|
+
self.balance += amount
|
12
|
+
end
|
13
|
+
|
14
|
+
def decrease_balance(amount)
|
15
|
+
increase_balance(-amount)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class MoneyTransferContext < Rietveld::Context
|
20
|
+
role :source_account do
|
21
|
+
def withdraw(amount)
|
22
|
+
if balance >= amount
|
23
|
+
decrease_balance(amount)
|
24
|
+
amount
|
25
|
+
else
|
26
|
+
raise 'Insufficient funds'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def transfer(amount)
|
31
|
+
destination_account.deposit(withdraw(amount))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
role :destination_account do
|
36
|
+
def deposit(amount)
|
37
|
+
increase_balance(amount)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def transfer(amount)
|
42
|
+
source_account.transfer(amount)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
describe MoneyTransferContext do
|
48
|
+
let(:source_account) { BankAccount.new(200) }
|
49
|
+
let(:destination_account) { BankAccount.new(100) }
|
50
|
+
|
51
|
+
let(:context) { MoneyTransferContext.new(
|
52
|
+
source_account: source_account,
|
53
|
+
destination_account: destination_account) }
|
54
|
+
|
55
|
+
context 'when transfering' do
|
56
|
+
before { context.transfer(50) }
|
57
|
+
|
58
|
+
it 'deposits given amount into destination account' do
|
59
|
+
expect(destination_account.balance).to be(150)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'withdraws given amount from source account' do
|
63
|
+
expect(source_account.balance).to be(150)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/spec/role_spec.rb
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class ExampleClass
|
4
|
+
def object_method
|
5
|
+
"object_method"
|
6
|
+
end
|
7
|
+
|
8
|
+
def set_object_instance_variable(val)
|
9
|
+
@object_instance_var = val
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_object_instance_variable
|
13
|
+
@object_instance_var
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class ExampleRole < Rietveld::Role
|
18
|
+
def role_method
|
19
|
+
object_method
|
20
|
+
end
|
21
|
+
|
22
|
+
def set_role_instance_variable(val)
|
23
|
+
@role_instance_var = val
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_role_instance_variable
|
27
|
+
@role_instance_var
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe Rietveld::Role do
|
32
|
+
let(:object) { ExampleClass.new }
|
33
|
+
let(:role) { ExampleRole.new(object) }
|
34
|
+
|
35
|
+
context 'straight delegates' do
|
36
|
+
example '#==' do
|
37
|
+
expect(role == object).to be(object == object)
|
38
|
+
end
|
39
|
+
|
40
|
+
example '#equal?' do
|
41
|
+
expect(role.equal?(object)).to be(object.equal?(object))
|
42
|
+
end
|
43
|
+
|
44
|
+
example '#eql?' do
|
45
|
+
expect(role.eql?(object)).to be(object.eql?(object))
|
46
|
+
end
|
47
|
+
|
48
|
+
example '#class' do
|
49
|
+
expect(role.class).to be(object.class)
|
50
|
+
expect(role.class).to be(ExampleClass)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'hybrid delegates' do
|
55
|
+
describe '#methods' do
|
56
|
+
it 'should include methods of the role_player' do
|
57
|
+
expect(role.methods).to include(*object.methods)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should include methods of the role' do
|
61
|
+
expect(role.methods).to include(*role.role_methods)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should be a union of role_player and role methods' do
|
65
|
+
methods = role.role_methods | object.methods
|
66
|
+
expect(role.methods).to contain_exactly(*methods)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'delegation' do
|
72
|
+
it 'delegates to object methods' do
|
73
|
+
expect(role.object_method).to eq(object.object_method)
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'responds to object methods' do
|
77
|
+
expect(role).to respond_to(:object_method)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'ivars' do
|
82
|
+
context 'belonging to object' do
|
83
|
+
before { object.set_object_instance_variable('test') }
|
84
|
+
|
85
|
+
it 'has #instance_variable_defined?' do
|
86
|
+
expect(role).to be_instance_variable_defined('@object_instance_var')
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'can access with #instance_variable_get' do
|
90
|
+
expect(role.instance_variable_get('@object_instance_var')).to eq('test')
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'can change with #instance_variable_set' do
|
94
|
+
role.instance_variable_set('@object_instance_var', 'changed')
|
95
|
+
expect(object.get_object_instance_variable).to eq('changed')
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'belonging to role' do
|
100
|
+
before { role.set_role_instance_variable('test') }
|
101
|
+
|
102
|
+
it 'has #instance_variable_defined?' do
|
103
|
+
expect(role).to be_instance_variable_defined('@role_instance_var')
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'object has not #instance_variable_defined?' do
|
107
|
+
expect(object).to_not be_instance_variable_defined('@role_instance_var')
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'can access with #instance_variable_get' do
|
111
|
+
expect(role.instance_variable_get('@role_instance_var')).to eq('test')
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'can change with #instance_variable_set' do
|
115
|
+
role.instance_variable_set('@role_instance_var', 'changed')
|
116
|
+
expect(role.get_role_instance_variable).to eq('changed')
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rietveld
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Marten Schilstra
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-04-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.5'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 3.0.0beta
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.0.0beta
|
55
|
+
description: ''
|
56
|
+
email:
|
57
|
+
- mail@martenschilstra.nl
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- ".rspec"
|
64
|
+
- Gemfile
|
65
|
+
- LICENSE.txt
|
66
|
+
- README.md
|
67
|
+
- Rakefile
|
68
|
+
- lib/rietveld.rb
|
69
|
+
- lib/rietveld/context.rb
|
70
|
+
- lib/rietveld/role.rb
|
71
|
+
- lib/rietveld/version.rb
|
72
|
+
- rietveld.gemspec
|
73
|
+
- spec/example_context_specs/money_transfer_spec.rb
|
74
|
+
- spec/role_spec.rb
|
75
|
+
- spec/spec_helper.rb
|
76
|
+
homepage: ''
|
77
|
+
licenses:
|
78
|
+
- MIT
|
79
|
+
metadata: {}
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
require_paths:
|
83
|
+
- lib
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
requirements: []
|
95
|
+
rubyforge_project:
|
96
|
+
rubygems_version: 2.2.1
|
97
|
+
signing_key:
|
98
|
+
specification_version: 4
|
99
|
+
summary: A practical implementation of DCI for Ruby
|
100
|
+
test_files:
|
101
|
+
- spec/example_context_specs/money_transfer_spec.rb
|
102
|
+
- spec/role_spec.rb
|
103
|
+
- spec/spec_helper.rb
|