surrounded 1.1.0 → 1.1.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/Changelog.md +11 -20
- data/LICENSE.txt +1 -1
- data/README.md +3 -3
- data/Rakefile +12 -5
- data/lib/surrounded/access_control.rb +12 -11
- data/lib/surrounded/context/forwarding.rb +10 -10
- data/lib/surrounded/context/initializing.rb +8 -6
- data/lib/surrounded/context/name_collision_detector.rb +17 -17
- data/lib/surrounded/context/negotiator.rb +7 -8
- data/lib/surrounded/context/role_builders.rb +7 -7
- data/lib/surrounded/context/role_map.rb +6 -8
- data/lib/surrounded/context/trigger_controls.rb +11 -13
- data/lib/surrounded/context.rb +61 -56
- data/lib/surrounded/east_oriented.rb +4 -4
- data/lib/surrounded/exceptions.rb +1 -1
- data/lib/surrounded/shortcuts.rb +6 -8
- data/lib/surrounded/version.rb +1 -1
- data/lib/surrounded.rb +7 -7
- data/surrounded.gemspec +21 -15
- data/test/{casting_role_player_test.rb → casting_test_helper.rb} +4 -3
- data/test/collection_role_players_test.rb +16 -16
- data/test/context_access_test.rb +31 -30
- data/test/context_forwarding_test.rb +30 -30
- data/test/context_reuse_test.rb +14 -14
- data/test/context_shortcuts_test.rb +18 -16
- data/test/east_oriented_triggers_test.rb +14 -13
- data/test/example_delegate_class_test.rb +8 -8
- data/test/example_proxy_test.rb +25 -23
- data/test/example_threaded_test.rb +13 -13
- data/test/example_wrapper_test.rb +7 -7
- data/test/initialization_test.rb +24 -25
- data/test/name_collisions_test.rb +48 -42
- data/test/non_surrounded_role_player_test.rb +8 -8
- data/test/override_methods_test.rb +9 -9
- data/test/role_context_method_test.rb +129 -119
- data/test/surrounded_context_test.rb +71 -62
- data/test/surrounded_test.rb +13 -15
- data/test/test_helper.rb +5 -4
- data/test/threaded_context_test.rb +70 -0
- metadata +8 -38
- data/.codeclimate.yml +0 -4
- data/.github/workflows/codeql-analysis.yml +0 -70
- data/.github/workflows/test.yml +0 -18
- data/.gitignore +0 -19
- data/.pullreview.yml +0 -4
- data/.simplecov +0 -3
- data/Gemfile +0 -9
- data/examples/bottles.rb +0 -135
- data/examples/rails.rb +0 -57
data/lib/surrounded/context.rb
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
7
|
-
require
|
|
8
|
-
require
|
|
9
|
-
require
|
|
10
|
-
require
|
|
11
|
-
require
|
|
12
|
-
require 'surrounded/context/name_collision_detector'
|
|
1
|
+
require "surrounded/exceptions"
|
|
2
|
+
require "surrounded/context/role_map"
|
|
3
|
+
require "surrounded/context/seclusion"
|
|
4
|
+
require "surrounded/context/role_builders"
|
|
5
|
+
require "surrounded/context/initializing"
|
|
6
|
+
require "surrounded/context/forwarding"
|
|
7
|
+
require "surrounded/context/trigger_controls"
|
|
8
|
+
require "surrounded/access_control"
|
|
9
|
+
require "surrounded/shortcuts"
|
|
10
|
+
require "surrounded/east_oriented"
|
|
11
|
+
require "surrounded/context/name_collision_detector"
|
|
13
12
|
|
|
14
13
|
# Extend your classes with Surrounded::Context to handle their
|
|
15
14
|
# initialization and application of behaviors to the role players
|
|
@@ -27,16 +26,13 @@ module Surrounded
|
|
|
27
26
|
include InstanceMethods
|
|
28
27
|
|
|
29
28
|
trigger_mod = Module.new
|
|
30
|
-
const_set(
|
|
29
|
+
const_set(:TriggerMethods, trigger_mod)
|
|
31
30
|
include trigger_mod
|
|
32
31
|
|
|
33
32
|
extend TriggerControls
|
|
34
|
-
|
|
35
33
|
}
|
|
36
34
|
end
|
|
37
35
|
|
|
38
|
-
private
|
|
39
|
-
|
|
40
36
|
# Set the default type of implementation for role methods for all contexts.
|
|
41
37
|
def self.default_role_type
|
|
42
38
|
@default_role_type ||= :module
|
|
@@ -46,6 +42,8 @@ module Surrounded
|
|
|
46
42
|
attr_writer :default_role_type
|
|
47
43
|
end
|
|
48
44
|
|
|
45
|
+
private
|
|
46
|
+
|
|
49
47
|
def default_role_type
|
|
50
48
|
@default_role_type ||= Surrounded::Context.default_role_type
|
|
51
49
|
end
|
|
@@ -56,13 +54,19 @@ module Surrounded
|
|
|
56
54
|
end
|
|
57
55
|
|
|
58
56
|
# Provide the ability to create access control methods for your triggers.
|
|
59
|
-
def protect_triggers
|
|
57
|
+
def protect_triggers
|
|
58
|
+
extend(::Surrounded::AccessControl)
|
|
59
|
+
end
|
|
60
60
|
|
|
61
61
|
# Automatically create class methods for each trigger method.
|
|
62
|
-
def shortcut_triggers
|
|
62
|
+
def shortcut_triggers
|
|
63
|
+
extend(::Surrounded::Shortcuts)
|
|
64
|
+
end
|
|
63
65
|
|
|
64
66
|
# Automatically return the context object from trigger methods.
|
|
65
|
-
def east_oriented_triggers
|
|
67
|
+
def east_oriented_triggers
|
|
68
|
+
extend(::Surrounded::EastOriented)
|
|
69
|
+
end
|
|
66
70
|
|
|
67
71
|
# === Utility shortcuts
|
|
68
72
|
|
|
@@ -91,7 +95,7 @@ module Surrounded
|
|
|
91
95
|
# is allowed to inquire about the roles.
|
|
92
96
|
def role?(name, &block)
|
|
93
97
|
return false unless role_map.role?(name)
|
|
94
|
-
accessor = block.binding.eval(
|
|
98
|
+
accessor = block.binding.eval("self")
|
|
95
99
|
role_map.role_player?(accessor) && role_map.assigned_player(name)
|
|
96
100
|
end
|
|
97
101
|
|
|
@@ -119,7 +123,7 @@ module Surrounded
|
|
|
119
123
|
private
|
|
120
124
|
|
|
121
125
|
def clear_instance_variables
|
|
122
|
-
instance_variables.each{|ivar| remove_instance_variable(ivar) }
|
|
126
|
+
instance_variables.each { |ivar| remove_instance_variable(ivar) }
|
|
123
127
|
end
|
|
124
128
|
|
|
125
129
|
def role_map
|
|
@@ -129,8 +133,8 @@ module Surrounded
|
|
|
129
133
|
def map_roles(role_object_array)
|
|
130
134
|
detect_collisions role_object_array
|
|
131
135
|
role_object_array.to_a.each do |role, object|
|
|
132
|
-
if
|
|
133
|
-
|
|
136
|
+
if respond_to?("map_role_#{role}")
|
|
137
|
+
send("map_role_#{role}", object)
|
|
134
138
|
else
|
|
135
139
|
map_role(role, role_behavior_name(role), object)
|
|
136
140
|
map_role_collection(role, role_behavior_name(role), object)
|
|
@@ -155,13 +159,13 @@ module Surrounded
|
|
|
155
159
|
|
|
156
160
|
def apply_behavior(role, behavior, object)
|
|
157
161
|
if behavior && role_const_defined?(behavior)
|
|
158
|
-
applicator = if
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
162
|
+
applicator = if respond_to?("apply_behavior_#{role}")
|
|
163
|
+
method("apply_behavior_#{role}")
|
|
164
|
+
elsif role_const(behavior).is_a?(Class)
|
|
165
|
+
method(:apply_class_behavior)
|
|
166
|
+
else
|
|
167
|
+
method(:apply_module_behavior)
|
|
168
|
+
end
|
|
165
169
|
|
|
166
170
|
role_player = applicator.call(role_const(behavior), object)
|
|
167
171
|
map_role(role, behavior, role_player)
|
|
@@ -170,7 +174,7 @@ module Surrounded
|
|
|
170
174
|
end
|
|
171
175
|
|
|
172
176
|
def apply_module_behavior(mod, obj)
|
|
173
|
-
adder_name = module_extension_methods.find{|meth| obj.respond_to?(meth) }
|
|
177
|
+
adder_name = module_extension_methods.find { |meth| obj.respond_to?(meth) }
|
|
174
178
|
return obj unless adder_name
|
|
175
179
|
|
|
176
180
|
obj.method(adder_name).call(mod)
|
|
@@ -178,7 +182,7 @@ module Surrounded
|
|
|
178
182
|
end
|
|
179
183
|
|
|
180
184
|
def apply_class_behavior(klass, obj)
|
|
181
|
-
wrapper_name = wrap_methods.find{|meth| klass.respond_to?(meth) }
|
|
185
|
+
wrapper_name = wrap_methods.find { |meth| klass.respond_to?(meth) }
|
|
182
186
|
return obj if !wrapper_name
|
|
183
187
|
klass.method(wrapper_name).call(obj)
|
|
184
188
|
end
|
|
@@ -190,11 +194,11 @@ module Surrounded
|
|
|
190
194
|
end
|
|
191
195
|
end
|
|
192
196
|
|
|
193
|
-
role_player = if
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
197
|
+
role_player = if respond_to?("remove_behavior_#{role}")
|
|
198
|
+
send("remove_behavior_#{role}", role_const(behavior), object)
|
|
199
|
+
elsif remover_name
|
|
200
|
+
object.send(remover_name)
|
|
201
|
+
end
|
|
198
202
|
|
|
199
203
|
role_player || object
|
|
200
204
|
end
|
|
@@ -203,7 +207,7 @@ module Surrounded
|
|
|
203
207
|
role_map.each do |role, mod_name, object|
|
|
204
208
|
player = apply_behavior(role, mod_name, object)
|
|
205
209
|
if player.respond_to?(:store_context, true)
|
|
206
|
-
player.__send__(:store_context)
|
|
210
|
+
player.__send__(:store_context) {}
|
|
207
211
|
end
|
|
208
212
|
end
|
|
209
213
|
end
|
|
@@ -211,7 +215,7 @@ module Surrounded
|
|
|
211
215
|
def remove_behaviors
|
|
212
216
|
role_map.each do |role, mod_name, player|
|
|
213
217
|
if player.respond_to?(:remove_context, true)
|
|
214
|
-
player.__send__(:remove_context)
|
|
218
|
+
player.__send__(:remove_context) {}
|
|
215
219
|
end
|
|
216
220
|
remove_behavior(role, mod_name, player)
|
|
217
221
|
end
|
|
@@ -242,7 +246,7 @@ module Surrounded
|
|
|
242
246
|
end
|
|
243
247
|
|
|
244
248
|
def role_module_basename(mod)
|
|
245
|
-
mod.to_s.split(
|
|
249
|
+
mod.to_s.split("::").last
|
|
246
250
|
end
|
|
247
251
|
|
|
248
252
|
def role_const(name)
|
|
@@ -262,33 +266,34 @@ module Surrounded
|
|
|
262
266
|
name.singularize
|
|
263
267
|
else
|
|
264
268
|
# good enough for now but should be updated with better rules
|
|
265
|
-
name.to_s.
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
269
|
+
string = name.to_s.dup
|
|
270
|
+
if string.end_with?("ies")
|
|
271
|
+
string.sub(/ies\z/, "y")
|
|
272
|
+
elsif string.end_with?("s")
|
|
273
|
+
string.sub(/s\z/, "")
|
|
274
|
+
else
|
|
275
|
+
string
|
|
271
276
|
end
|
|
272
277
|
end
|
|
273
278
|
end
|
|
274
279
|
end
|
|
275
280
|
|
|
276
281
|
class RoleName
|
|
277
|
-
def initialize(string, suffix=nil)
|
|
278
|
-
@string = string
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
282
|
+
def initialize(string, suffix = nil)
|
|
283
|
+
@string = string
|
|
284
|
+
.to_s
|
|
285
|
+
.split("_")
|
|
286
|
+
.map { |part|
|
|
287
|
+
part.capitalize
|
|
288
|
+
}
|
|
289
|
+
.join
|
|
290
|
+
.sub(/_\d+/, "") + suffix.to_s
|
|
286
291
|
end
|
|
287
292
|
|
|
288
293
|
def to_str
|
|
289
294
|
@string
|
|
290
295
|
end
|
|
291
|
-
|
|
296
|
+
alias_method :to_s, :to_str
|
|
292
297
|
|
|
293
298
|
def to_sym
|
|
294
299
|
@string.to_sym
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module Surrounded
|
|
2
2
|
module Exceptions
|
|
3
3
|
def self.define(klass, exceptions:, namespace: Surrounded::Context)
|
|
4
|
-
Array(exceptions).each{ |exception|
|
|
4
|
+
Array(exceptions).each { |exception|
|
|
5
5
|
unless klass.const_defined?(exception)
|
|
6
6
|
klass.const_set(exception, Class.new(namespace.const_get(exception)))
|
|
7
7
|
end
|
data/lib/surrounded/shortcuts.rb
CHANGED
|
@@ -1,21 +1,19 @@
|
|
|
1
1
|
module Surrounded
|
|
2
2
|
module Shortcuts
|
|
3
3
|
private
|
|
4
|
-
|
|
4
|
+
|
|
5
5
|
def define_shortcut(name)
|
|
6
6
|
# if keyword initialize
|
|
7
|
-
if instance_method(:initialize).parameters.dig(0,0) == :keyreq
|
|
7
|
+
if instance_method(:initialize).parameters.dig(0, 0) == :keyreq
|
|
8
8
|
singleton_class.send(:define_method, name) do |**args|
|
|
9
|
-
instance =
|
|
10
|
-
|
|
11
|
-
end
|
|
9
|
+
instance = new(**args)
|
|
10
|
+
|
|
12
11
|
instance.public_send(name)
|
|
13
12
|
end
|
|
14
13
|
else # non-keyword initialize
|
|
15
14
|
singleton_class.send(:define_method, name) do |*args|
|
|
16
|
-
instance =
|
|
17
|
-
|
|
18
|
-
end
|
|
15
|
+
instance = new(*args)
|
|
16
|
+
|
|
19
17
|
instance.public_send(name)
|
|
20
18
|
end
|
|
21
19
|
end
|
data/lib/surrounded/version.rb
CHANGED
data/lib/surrounded.rb
CHANGED
|
@@ -3,23 +3,22 @@ require "surrounded/context"
|
|
|
3
3
|
require "singleton"
|
|
4
4
|
|
|
5
5
|
# This module should be added to objects which will enter
|
|
6
|
-
# into context objects.
|
|
6
|
+
# into context objects.
|
|
7
7
|
#
|
|
8
8
|
# Its main purpose is to keep a reference to the context
|
|
9
9
|
# and to implement method_missing to handle the relationship
|
|
10
10
|
# to other objects in the context.
|
|
11
11
|
module Surrounded
|
|
12
|
-
|
|
13
12
|
private
|
|
14
13
|
|
|
15
14
|
def store_context(&block)
|
|
16
|
-
accessor = block.binding.eval(
|
|
15
|
+
accessor = block.binding.eval("self")
|
|
17
16
|
surroundings.unshift(accessor)
|
|
18
17
|
self
|
|
19
18
|
end
|
|
20
19
|
|
|
21
20
|
def remove_context(&block)
|
|
22
|
-
accessor = block.binding.eval(
|
|
21
|
+
accessor = block.binding.eval("self")
|
|
23
22
|
surroundings.shift if surroundings.include?(accessor)
|
|
24
23
|
self
|
|
25
24
|
end
|
|
@@ -33,15 +32,16 @@ module Surrounded
|
|
|
33
32
|
end
|
|
34
33
|
|
|
35
34
|
def method_missing(meth, *args, &block)
|
|
36
|
-
context.role?(meth){} || super
|
|
35
|
+
context.role?(meth) {} || super
|
|
37
36
|
end
|
|
38
37
|
|
|
39
|
-
def respond_to_missing?(meth, include_private=false)
|
|
40
|
-
!!context.role?(meth){} || super
|
|
38
|
+
def respond_to_missing?(meth, include_private = false)
|
|
39
|
+
!!context.role?(meth) {} || super
|
|
41
40
|
end
|
|
42
41
|
|
|
43
42
|
class NullContext
|
|
44
43
|
include Singleton
|
|
44
|
+
|
|
45
45
|
def role?(*args)
|
|
46
46
|
nil
|
|
47
47
|
end
|
data/surrounded.gemspec
CHANGED
|
@@ -1,24 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
-
require
|
|
3
|
+
require "surrounded/version"
|
|
5
4
|
|
|
6
5
|
Gem::Specification.new do |spec|
|
|
7
|
-
spec.name
|
|
8
|
-
spec.version
|
|
9
|
-
spec.authors
|
|
10
|
-
spec.email
|
|
11
|
-
spec.description
|
|
12
|
-
spec.summary
|
|
13
|
-
spec.homepage
|
|
14
|
-
spec.license
|
|
6
|
+
spec.name = "surrounded"
|
|
7
|
+
spec.version = Surrounded.version
|
|
8
|
+
spec.authors = ["'Jim Gay'"]
|
|
9
|
+
spec.email = ["jim@saturnflyer.com"]
|
|
10
|
+
spec.description = "Gives an object implicit access to other objects in it's environment."
|
|
11
|
+
spec.summary = "Create encapsulated environments for your objects."
|
|
12
|
+
spec.homepage = "http://github.com/saturnflyer/surrounded"
|
|
13
|
+
spec.license = "MIT"
|
|
15
14
|
|
|
16
|
-
spec.files
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
spec.files = Dir[
|
|
16
|
+
"lib/**/*",
|
|
17
|
+
"Rakefile",
|
|
18
|
+
"README.md",
|
|
19
|
+
"Changelog.md",
|
|
20
|
+
"LICENSE.txt",
|
|
21
|
+
"test/**/*",
|
|
22
|
+
"surrounded.gemspec"
|
|
23
|
+
]
|
|
24
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
19
25
|
spec.require_paths = ["lib"]
|
|
20
26
|
|
|
21
|
-
spec.add_dependency "triad",
|
|
27
|
+
spec.add_dependency "triad", ">= 0.3.0"
|
|
22
28
|
|
|
23
29
|
spec.add_development_dependency "rake"
|
|
24
30
|
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "test_helper"
|
|
2
|
+
require "casting_test_helper"
|
|
2
3
|
|
|
3
4
|
class CollectionContext
|
|
4
5
|
extend Surrounded::Context
|
|
@@ -10,7 +11,7 @@ class CollectionContext
|
|
|
10
11
|
end
|
|
11
12
|
|
|
12
13
|
trigger :get_member_show do
|
|
13
|
-
members.map(&:show).join(
|
|
14
|
+
members.map(&:show).join(", ")
|
|
14
15
|
end
|
|
15
16
|
|
|
16
17
|
role :members do
|
|
@@ -25,27 +26,26 @@ class CollectionContext
|
|
|
25
26
|
end
|
|
26
27
|
end
|
|
27
28
|
|
|
28
|
-
role :others
|
|
29
|
-
role :other
|
|
30
|
-
|
|
29
|
+
role :others, &proc {}
|
|
30
|
+
role :other, &proc {}
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
describe Surrounded::Context,
|
|
34
|
-
let(:member_one){ User.new(
|
|
35
|
-
let(:member_two){ User.new(
|
|
36
|
-
let(:members){ [member_one, member_two] }
|
|
33
|
+
describe Surrounded::Context, "auto-assigning roles for collections" do
|
|
34
|
+
let(:member_one) { User.new("Jim") }
|
|
35
|
+
let(:member_two) { User.new("Amy") }
|
|
36
|
+
let(:members) { [member_one, member_two] }
|
|
37
37
|
|
|
38
|
-
let(:other_one){ User.new(
|
|
39
|
-
let(:other_two){ User.new(
|
|
40
|
-
let(:others){ [other_one, other_two] }
|
|
38
|
+
let(:other_one) { User.new("Guille") }
|
|
39
|
+
let(:other_two) { User.new("Jason") }
|
|
40
|
+
let(:others) { [other_one, other_two] }
|
|
41
41
|
|
|
42
|
-
let(:context){ CollectionContext.new(members: members, others: others) }
|
|
42
|
+
let(:context) { CollectionContext.new(members: members, others: others) }
|
|
43
43
|
|
|
44
|
-
it
|
|
44
|
+
it "assigns the collection role to collections" do
|
|
45
45
|
assert_equal members.size, context.get_members_count
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
it
|
|
48
|
+
it "assigns a defined role to each item in a role player collection" do
|
|
49
49
|
assert_equal "member show, member show", context.get_member_show
|
|
50
50
|
end
|
|
51
|
-
end
|
|
51
|
+
end
|
data/test/context_access_test.rb
CHANGED
|
@@ -1,62 +1,63 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
1
|
+
require "test_helper"
|
|
2
|
+
require "minitest/mock"
|
|
3
3
|
|
|
4
4
|
class FilteredContext
|
|
5
5
|
extend Surrounded::Context
|
|
6
|
+
|
|
6
7
|
protect_triggers
|
|
7
|
-
|
|
8
|
+
|
|
8
9
|
initialize :user, :other_user
|
|
9
|
-
|
|
10
|
+
|
|
10
11
|
trigger :if_ready do
|
|
11
|
-
|
|
12
|
+
"ready"
|
|
12
13
|
end
|
|
13
|
-
|
|
14
|
+
|
|
14
15
|
guard :if_ready do
|
|
15
|
-
user.name !=
|
|
16
|
+
user.name != "Amy"
|
|
16
17
|
end
|
|
17
|
-
|
|
18
|
+
|
|
18
19
|
trigger :check_disallow_behavior do
|
|
19
20
|
# used for disallow check
|
|
20
21
|
end
|
|
21
|
-
|
|
22
|
+
|
|
22
23
|
disallow :check_disallow_behavior do
|
|
23
24
|
user.special
|
|
24
25
|
end
|
|
25
|
-
|
|
26
|
+
|
|
26
27
|
trigger :unguarded do
|
|
27
28
|
# used for disallow check
|
|
28
29
|
end
|
|
29
30
|
|
|
30
31
|
role :user do
|
|
31
32
|
def special
|
|
32
|
-
|
|
33
|
+
"special user method"
|
|
33
34
|
end
|
|
34
35
|
end
|
|
35
36
|
end
|
|
36
37
|
|
|
37
|
-
describe Surrounded::Context,
|
|
38
|
-
let(:user){ User.new("Jim") }
|
|
39
|
-
let(:other_user){ User.new("Guille") }
|
|
40
|
-
let(:context){ FilteredContext.new(user: user, other_user: other_user) }
|
|
41
|
-
|
|
42
|
-
it
|
|
38
|
+
describe Surrounded::Context, "access control" do
|
|
39
|
+
let(:user) { User.new("Jim") }
|
|
40
|
+
let(:other_user) { User.new("Guille") }
|
|
41
|
+
let(:context) { FilteredContext.new(user: user, other_user: other_user) }
|
|
42
|
+
|
|
43
|
+
it "includes triggers when allowed" do
|
|
43
44
|
context.stub(:disallow_if_ready?, false) do
|
|
44
45
|
assert context.triggers.include?(:if_ready)
|
|
45
46
|
end
|
|
46
47
|
end
|
|
47
48
|
|
|
48
|
-
it
|
|
49
|
+
it "excludes triggers when not allowed" do
|
|
49
50
|
refute context.triggers.include?(:if_ready)
|
|
50
51
|
end
|
|
51
|
-
|
|
52
|
-
it
|
|
53
|
-
error = assert_raises(::FilteredContext::AccessError){
|
|
52
|
+
|
|
53
|
+
it "raises error specific to the context class when trigger method not allowed" do
|
|
54
|
+
error = assert_raises(::FilteredContext::AccessError) {
|
|
54
55
|
context.if_ready
|
|
55
56
|
}
|
|
56
57
|
assert_match(/access to FilteredContext#if_ready is not allowed/i, error.message)
|
|
57
58
|
end
|
|
58
|
-
|
|
59
|
-
it
|
|
59
|
+
|
|
60
|
+
it "supports rescuing from Surrounded defined error when trigger method not allowed" do
|
|
60
61
|
begin
|
|
61
62
|
context.if_ready
|
|
62
63
|
rescue ::Surrounded::Context::AccessError => error
|
|
@@ -64,20 +65,20 @@ describe Surrounded::Context, 'access control' do
|
|
|
64
65
|
end
|
|
65
66
|
assert_match(/access to FilteredContext#if_ready is not allowed/i, error.message)
|
|
66
67
|
end
|
|
67
|
-
|
|
68
|
-
it
|
|
69
|
-
assert_equal
|
|
68
|
+
|
|
69
|
+
it "applies roles in disallow blocks" do
|
|
70
|
+
assert_equal "special user method", context.disallow_check_disallow_behavior?
|
|
70
71
|
end
|
|
71
72
|
|
|
72
|
-
it
|
|
73
|
+
it "lets you ask if the object will allow a method" do
|
|
73
74
|
assert context.allow?(:unguarded)
|
|
74
75
|
refute context.allow?(:check_disallow_behavior)
|
|
75
76
|
end
|
|
76
77
|
|
|
77
|
-
it
|
|
78
|
-
error = assert_raises(NoMethodError){
|
|
78
|
+
it "complains if you ask about an undefined method" do
|
|
79
|
+
error = assert_raises(NoMethodError) {
|
|
79
80
|
context.allow?(:not_a_defined_method)
|
|
80
81
|
}
|
|
81
82
|
assert_match(/undefined method `not_a_defined_method' for #<#{context.class}/, error.message)
|
|
82
83
|
end
|
|
83
|
-
end
|
|
84
|
+
end
|