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
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "test_helper"
|
|
2
2
|
|
|
3
3
|
class Sending
|
|
4
4
|
extend Surrounded::Context
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
initialize :one, :two
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
forwarding [:hello, :goodbye] => :one
|
|
9
9
|
forward_trigger :two, :ping
|
|
10
10
|
forward_trigger :two, :argumentative
|
|
11
11
|
forwards :two, :blockhead
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
role :one do
|
|
14
14
|
def hello
|
|
15
|
-
|
|
15
|
+
"hello"
|
|
16
16
|
end
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
def goodbye
|
|
19
|
-
|
|
19
|
+
"goodbye"
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
role :two do
|
|
24
24
|
def ping
|
|
25
25
|
one.hello
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
def argumentative(yes, no)
|
|
29
|
-
[yes, no].join(
|
|
29
|
+
[yes, no].join(" and ")
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def blockhead
|
|
@@ -35,31 +35,31 @@ class Sending
|
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
-
describe Surrounded::Context,
|
|
39
|
-
let(:user){ User.new("Jim") }
|
|
40
|
-
let(:other_user){ User.new("Guille") }
|
|
41
|
-
let(:context){ Sending.new(one: user, two: other_user) }
|
|
42
|
-
|
|
43
|
-
it
|
|
44
|
-
assert_equal
|
|
45
|
-
assert_equal
|
|
38
|
+
describe Surrounded::Context, "forwarding triggers" do
|
|
39
|
+
let(:user) { User.new("Jim") }
|
|
40
|
+
let(:other_user) { User.new("Guille") }
|
|
41
|
+
let(:context) { Sending.new(one: user, two: other_user) }
|
|
42
|
+
|
|
43
|
+
it "forwards multiple configured instance methods as triggers" do
|
|
44
|
+
assert_equal "hello", context.hello
|
|
45
|
+
assert_equal "goodbye", context.goodbye
|
|
46
46
|
end
|
|
47
|
-
|
|
48
|
-
it
|
|
49
|
-
assert_equal
|
|
47
|
+
|
|
48
|
+
it "forwards individual configured instance methods as triggers" do
|
|
49
|
+
assert_equal "hello", context.ping
|
|
50
50
|
end
|
|
51
|
-
|
|
52
|
-
it
|
|
53
|
-
error = assert_raises(ArgumentError){
|
|
51
|
+
|
|
52
|
+
it "does not forward __id__" do
|
|
53
|
+
error = assert_raises(ArgumentError) {
|
|
54
54
|
Sending.class_eval do
|
|
55
55
|
forward_trigger :one, :__id__
|
|
56
56
|
end
|
|
57
57
|
}
|
|
58
58
|
assert_match(/you may not forward '__id__`/i, error.message)
|
|
59
59
|
end
|
|
60
|
-
|
|
61
|
-
it
|
|
62
|
-
error = assert_raises(ArgumentError){
|
|
60
|
+
|
|
61
|
+
it "does not forward __send__" do
|
|
62
|
+
error = assert_raises(ArgumentError) {
|
|
63
63
|
Sending.class_eval do
|
|
64
64
|
forward_trigger :one, :__send__
|
|
65
65
|
end
|
|
@@ -67,14 +67,14 @@ describe Surrounded::Context, 'forwarding triggers' do
|
|
|
67
67
|
assert_match(/you may not forward '__send__/i, error.message)
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
-
it
|
|
71
|
-
assert_equal
|
|
70
|
+
it "passes arguments" do
|
|
71
|
+
assert_equal "YES and NO", context.argumentative("YES", "NO")
|
|
72
72
|
end
|
|
73
73
|
|
|
74
|
-
it
|
|
74
|
+
it "passes blocks" do
|
|
75
75
|
result = context.blockhead do
|
|
76
76
|
"Put them in the iron maiden. Excellent!"
|
|
77
77
|
end
|
|
78
78
|
assert_equal "Put them in the iron maiden. Excellent!", result
|
|
79
79
|
end
|
|
80
|
-
end
|
|
80
|
+
end
|
data/test/context_reuse_test.rb
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "test_helper"
|
|
2
2
|
|
|
3
|
-
describe Surrounded::Context,
|
|
4
|
-
let(:user){ User.new("Jim") }
|
|
5
|
-
let(:other_user){ User.new("Guille") }
|
|
6
|
-
let(:context){ TestContext.new(user: user, other_user: other_user) }
|
|
3
|
+
describe Surrounded::Context, "reusing context object" do
|
|
4
|
+
let(:user) { User.new("Jim") }
|
|
5
|
+
let(:other_user) { User.new("Guille") }
|
|
6
|
+
let(:context) { TestContext.new(user: user, other_user: other_user) }
|
|
7
7
|
|
|
8
|
-
it
|
|
9
|
-
expect(context.access_other_object).must_equal
|
|
10
|
-
context.rebind(user: User.new(
|
|
11
|
-
expect(context.access_other_object).must_equal
|
|
8
|
+
it "allows rebinding new players" do
|
|
9
|
+
expect(context.access_other_object).must_equal "Guille"
|
|
10
|
+
context.rebind(user: User.new("Amy"), other_user: User.new("Elizabeth"))
|
|
11
|
+
expect(context.access_other_object).must_equal "Elizabeth"
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
it
|
|
15
|
-
originals = context.instance_variables.map{|var| context.instance_variable_get(var) }
|
|
16
|
-
context.rebind(user: User.new(
|
|
17
|
-
new_ivars = context.instance_variables.map{|var| context.instance_variable_get(var) }
|
|
14
|
+
it "clears internal storage when rebinding" do
|
|
15
|
+
originals = context.instance_variables.map { |var| context.instance_variable_get(var) }
|
|
16
|
+
context.rebind(user: User.new("Amy"), other_user: User.new("Elizabeth"))
|
|
17
|
+
new_ivars = context.instance_variables.map { |var| context.instance_variable_get(var) }
|
|
18
18
|
originals.zip(new_ivars).each do |original_ivar, new_ivar|
|
|
19
19
|
expect(original_ivar).wont_equal new_ivar
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
|
-
end
|
|
22
|
+
end
|
|
@@ -1,24 +1,26 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "test_helper"
|
|
2
2
|
|
|
3
3
|
class ShortcutContext
|
|
4
4
|
extend Surrounded::Context
|
|
5
|
+
|
|
5
6
|
shortcut_triggers
|
|
6
|
-
|
|
7
|
+
|
|
7
8
|
initialize :user, :other
|
|
8
|
-
|
|
9
|
+
|
|
9
10
|
trigger :shorty do
|
|
10
11
|
user.speak
|
|
11
12
|
end
|
|
12
|
-
|
|
13
|
+
|
|
13
14
|
role :user do
|
|
14
15
|
def speak
|
|
15
|
-
|
|
16
|
+
"it works, shorty!"
|
|
16
17
|
end
|
|
17
18
|
end
|
|
18
19
|
end
|
|
19
20
|
|
|
20
21
|
class ShortcutContextNoKeywords
|
|
21
22
|
extend Surrounded::Context
|
|
23
|
+
|
|
22
24
|
shortcut_triggers
|
|
23
25
|
|
|
24
26
|
initialize_without_keywords :user, :other
|
|
@@ -29,23 +31,23 @@ class ShortcutContextNoKeywords
|
|
|
29
31
|
|
|
30
32
|
role :user do
|
|
31
33
|
def speak
|
|
32
|
-
|
|
34
|
+
"it works, shorty!"
|
|
33
35
|
end
|
|
34
36
|
end
|
|
35
37
|
end
|
|
36
38
|
|
|
37
|
-
describe Surrounded::Context,
|
|
38
|
-
let(:user){ User.new("Jim") }
|
|
39
|
-
let(:other){ User.new("Guille") }
|
|
40
|
-
it
|
|
41
|
-
assert_equal
|
|
39
|
+
describe Surrounded::Context, "shortcuts" do
|
|
40
|
+
let(:user) { User.new("Jim") }
|
|
41
|
+
let(:other) { User.new("Guille") }
|
|
42
|
+
it "creates shortcut class methods for triggers" do
|
|
43
|
+
assert_equal "it works, shorty!", ShortcutContext.shorty(user: user, other: other)
|
|
42
44
|
end
|
|
43
45
|
end
|
|
44
46
|
|
|
45
|
-
describe Surrounded::Context,
|
|
46
|
-
let(:user){ User.new("Jim") }
|
|
47
|
-
let(:other){ User.new("Guille") }
|
|
48
|
-
it
|
|
49
|
-
assert_equal
|
|
47
|
+
describe Surrounded::Context, "shortcuts with initialize_without_keywords" do
|
|
48
|
+
let(:user) { User.new("Jim") }
|
|
49
|
+
let(:other) { User.new("Guille") }
|
|
50
|
+
it "creates shortcut class methods for triggers" do
|
|
51
|
+
assert_equal "it works, shorty!", ShortcutContextNoKeywords.shorty(user, other)
|
|
50
52
|
end
|
|
51
53
|
end
|
|
@@ -1,36 +1,37 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "test_helper"
|
|
2
2
|
|
|
3
3
|
class EastTestContext
|
|
4
4
|
extend Surrounded::Context
|
|
5
|
+
|
|
5
6
|
east_oriented_triggers
|
|
6
|
-
|
|
7
|
+
|
|
7
8
|
initialize :user, :other_user
|
|
8
|
-
|
|
9
|
+
|
|
9
10
|
trigger :ask? do
|
|
10
11
|
"asking a question..."
|
|
11
12
|
end
|
|
12
13
|
end
|
|
13
14
|
|
|
14
|
-
describe Surrounded::Context,
|
|
15
|
-
let(:user){ User.new("Jim") }
|
|
16
|
-
let(:other_user){ User.new("Guille") }
|
|
17
|
-
let(:context){ EastTestContext.new(user: user, other_user: other_user) }
|
|
15
|
+
describe Surrounded::Context, ".east_oriented_triggers" do
|
|
16
|
+
let(:user) { User.new("Jim") }
|
|
17
|
+
let(:other_user) { User.new("Guille") }
|
|
18
|
+
let(:context) { EastTestContext.new(user: user, other_user: other_user) }
|
|
18
19
|
|
|
19
|
-
it
|
|
20
|
+
it "returns the context object from trigger methods" do
|
|
20
21
|
assert_equal context, context.ask?
|
|
21
22
|
end
|
|
22
23
|
end
|
|
23
24
|
|
|
24
|
-
describe Surrounded::Context,
|
|
25
|
-
let(:user){ User.new("Jim") }
|
|
26
|
-
let(:other_user){ User.new("Guille") }
|
|
27
|
-
let(:context){
|
|
25
|
+
describe Surrounded::Context, ".east_oriented_triggers with protect_triggers" do
|
|
26
|
+
let(:user) { User.new("Jim") }
|
|
27
|
+
let(:other_user) { User.new("Guille") }
|
|
28
|
+
let(:context) {
|
|
28
29
|
ctxt = EastTestContext.new(user: user, other_user: other_user)
|
|
29
30
|
ctxt.singleton_class.send(:protect_triggers)
|
|
30
31
|
ctxt
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
it
|
|
34
|
+
it "returns the context object from trigger methods" do
|
|
34
35
|
assert_equal context, context.ask?
|
|
35
36
|
end
|
|
36
37
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "test_helper"
|
|
2
2
|
|
|
3
3
|
# If you want to use wrappers, here's how you could
|
|
4
4
|
class DelegateClassContext
|
|
@@ -6,9 +6,9 @@ class DelegateClassContext
|
|
|
6
6
|
|
|
7
7
|
initialize(:user, :task)
|
|
8
8
|
|
|
9
|
-
delegate_class :user,
|
|
9
|
+
delegate_class :user, "User" do
|
|
10
10
|
def some_admin_method
|
|
11
|
-
|
|
11
|
+
"hello from the admin DelegateClass wrapper!"
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
14
|
wrap :task do
|
|
@@ -20,10 +20,10 @@ class DelegateClassContext
|
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
describe DelegateClassContext do
|
|
23
|
-
let(:context){
|
|
24
|
-
DelegateClassContext.new(user: User.new(
|
|
23
|
+
let(:context) {
|
|
24
|
+
DelegateClassContext.new(user: User.new("jim"), task: Object.new)
|
|
25
25
|
}
|
|
26
|
-
it
|
|
27
|
-
assert_equal
|
|
26
|
+
it "wraps objects using DelegateClass" do
|
|
27
|
+
assert_equal "hello from the admin DelegateClass wrapper!", context.do_something
|
|
28
28
|
end
|
|
29
|
-
end
|
|
29
|
+
end
|
data/test/example_proxy_test.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "test_helper"
|
|
2
2
|
|
|
3
3
|
class ProxyContext
|
|
4
4
|
extend Surrounded::Context
|
|
@@ -58,57 +58,59 @@ ProxyUser = Class.new do
|
|
|
58
58
|
attr_reader :name
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
+
ProxyTask = Data.define(:name)
|
|
62
|
+
|
|
61
63
|
describe ProxyContext do
|
|
62
|
-
let(:user){
|
|
63
|
-
ProxyUser.new(
|
|
64
|
+
let(:user) {
|
|
65
|
+
ProxyUser.new("Jim")
|
|
64
66
|
}
|
|
65
|
-
let(:task){
|
|
66
|
-
|
|
67
|
+
let(:task) {
|
|
68
|
+
ProxyTask.new(name: "GTD")
|
|
67
69
|
}
|
|
68
|
-
let(:context){
|
|
70
|
+
let(:context) {
|
|
69
71
|
ProxyContext.new(admin: user, task: task)
|
|
70
72
|
}
|
|
71
|
-
it
|
|
72
|
-
assert_equal
|
|
73
|
+
it "proxys methods between objects and its interface" do
|
|
74
|
+
assert_equal "hello from Jim, the admin interface!", context.do_something
|
|
73
75
|
end
|
|
74
76
|
|
|
75
|
-
it
|
|
76
|
-
assert_equal
|
|
77
|
+
it "forwards methods that the object responds to" do
|
|
78
|
+
assert_equal "Jim", context.admin_name
|
|
77
79
|
end
|
|
78
80
|
|
|
79
|
-
it
|
|
80
|
-
err = _{ context.admin_missing_method }.must_raise(NoMethodError)
|
|
81
|
+
it "passes missing methods up the ancestry of the object" do
|
|
82
|
+
err = _ { context.admin_missing_method }.must_raise(NoMethodError)
|
|
81
83
|
|
|
82
|
-
assert_match(/ProxyUser
|
|
84
|
+
assert_match(/ProxyUser/, err.message)
|
|
83
85
|
end
|
|
84
86
|
|
|
85
|
-
it
|
|
86
|
-
err = _{ context.talking }.must_raise NameError
|
|
87
|
-
assert_match(
|
|
87
|
+
it "fails access to other objects in the context" do
|
|
88
|
+
err = _ { context.talking }.must_raise NameError
|
|
89
|
+
assert_match(/undefined local variable or method [`']task['`]/, err.message)
|
|
88
90
|
end
|
|
89
91
|
|
|
90
|
-
it
|
|
92
|
+
it "sets roles to respond to role methods" do
|
|
91
93
|
assert context.admin_responds?
|
|
92
94
|
end
|
|
93
95
|
|
|
94
96
|
# A Negotiator object merely applies methods to another object
|
|
95
97
|
# so that once the method is called, the object has no knowledge
|
|
96
98
|
# of the module from which the method was applied.
|
|
97
|
-
it
|
|
98
|
-
assert_raises(NameError){
|
|
99
|
+
it "does not find other interface methods" do
|
|
100
|
+
assert_raises(NameError) {
|
|
99
101
|
context.combined_interface_methods
|
|
100
102
|
}
|
|
101
103
|
end
|
|
102
104
|
|
|
103
|
-
it
|
|
105
|
+
it "is able to grab methods from the object" do
|
|
104
106
|
assert_equal :talking_to_others, context.get_admin_method.name
|
|
105
107
|
end
|
|
106
108
|
|
|
107
|
-
it
|
|
108
|
-
assert context.rebind(admin: User.new(
|
|
109
|
+
it "allows Surrounded objects to interact with others" do
|
|
110
|
+
assert context.rebind(admin: User.new("Surrounded"), task: task).talking
|
|
109
111
|
end
|
|
110
112
|
|
|
111
|
-
it
|
|
113
|
+
it "works with frozen and primitive objects" do
|
|
112
114
|
context.rebind(admin: "brrr".freeze, task: task)
|
|
113
115
|
assert context.get_admin_method
|
|
114
116
|
context.rebind(admin: nil, task: task)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "test_helper"
|
|
2
2
|
|
|
3
3
|
class ThreadedContext
|
|
4
4
|
extend Surrounded::Context
|
|
@@ -16,7 +16,7 @@ class ThreadedContext
|
|
|
16
16
|
result << members.concurrent_map do |member|
|
|
17
17
|
result << member.greet
|
|
18
18
|
end
|
|
19
|
-
result.flatten.join(
|
|
19
|
+
result.flatten.join(" ")
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def greet
|
|
@@ -44,21 +44,21 @@ class ThreadedContext
|
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
describe ThreadedContext do
|
|
47
|
-
let(:jim){ User.new(
|
|
48
|
-
let(:amy){ User.new(
|
|
49
|
-
let(:guille){ User.new(
|
|
50
|
-
let(:jason){ User.new(
|
|
51
|
-
let(:dave){ User.new(
|
|
47
|
+
let(:jim) { User.new("Jim") }
|
|
48
|
+
let(:amy) { User.new("Amy") }
|
|
49
|
+
let(:guille) { User.new("Guille") }
|
|
50
|
+
let(:jason) { User.new("Jason") }
|
|
51
|
+
let(:dave) { User.new("Dave") }
|
|
52
52
|
|
|
53
|
-
let(:greeter){ jim }
|
|
54
|
-
let(:members){ [amy, guille, jason, dave] }
|
|
53
|
+
let(:greeter) { jim }
|
|
54
|
+
let(:members) { [amy, guille, jason, dave] }
|
|
55
55
|
|
|
56
|
-
it
|
|
56
|
+
it "works in multi-threaded environments" do
|
|
57
57
|
meeting = ThreadedContext.new(leader: jim, members: members)
|
|
58
58
|
|
|
59
59
|
result = meeting.meet
|
|
60
60
|
|
|
61
|
-
assert_includes result,
|
|
62
|
-
assert_includes result,
|
|
61
|
+
assert_includes result, "Hello everyone. I am Jim"
|
|
62
|
+
assert_includes result, "Hello Jim, I am Amy"
|
|
63
63
|
end
|
|
64
|
-
end
|
|
64
|
+
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "test_helper"
|
|
2
2
|
|
|
3
3
|
# If you want to use wrappers, here's how you could
|
|
4
4
|
class WrapperContext
|
|
@@ -8,10 +8,10 @@ class WrapperContext
|
|
|
8
8
|
|
|
9
9
|
wrap :admin do
|
|
10
10
|
def some_admin_method
|
|
11
|
-
|
|
11
|
+
"hello from the admin wrapper!"
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
|
-
wrap :task
|
|
14
|
+
wrap :task, &proc {}
|
|
15
15
|
|
|
16
16
|
trigger :do_something do
|
|
17
17
|
admin.some_admin_method
|
|
@@ -19,10 +19,10 @@ class WrapperContext
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
describe WrapperContext do
|
|
22
|
-
let(:context){
|
|
22
|
+
let(:context) {
|
|
23
23
|
WrapperContext.new(admin: Object.new, task: Object.new)
|
|
24
24
|
}
|
|
25
|
-
it
|
|
26
|
-
assert_equal
|
|
25
|
+
it "wraps objects and allows them to respond to new methods" do
|
|
26
|
+
assert_equal "hello from the admin wrapper!", context.do_something
|
|
27
27
|
end
|
|
28
|
-
end
|
|
28
|
+
end
|
data/test/initialization_test.rb
CHANGED
|
@@ -1,32 +1,31 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "test_helper"
|
|
2
2
|
|
|
3
3
|
class KeywordContext
|
|
4
4
|
extend Surrounded::Context
|
|
5
5
|
|
|
6
6
|
keyword_initialize(:user, :other_user) do
|
|
7
|
-
@defined_by_initializer_block =
|
|
7
|
+
@defined_by_initializer_block = "yup"
|
|
8
8
|
end
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
describe Surrounded::Context,
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
assert_equal 'yup', context.instance_variable_get(:@defined_by_initializer_block)
|
|
11
|
+
describe Surrounded::Context, ".initialize" do
|
|
12
|
+
it "applies a provided block to the instance" do
|
|
13
|
+
context = KeywordContext.new(user: User.new("Jim"), other_user: User.new("Amy"))
|
|
14
|
+
assert_equal "yup", context.instance_variable_get(:@defined_by_initializer_block)
|
|
16
15
|
end
|
|
17
16
|
|
|
18
|
-
it
|
|
19
|
-
jim = User.new(
|
|
20
|
-
amy = User.new(
|
|
17
|
+
it "keeps track of the original initialize arguments" do
|
|
18
|
+
jim = User.new("Jim")
|
|
19
|
+
amy = User.new("Amy")
|
|
21
20
|
context = KeywordContext.new(user: jim, other_user: amy)
|
|
22
21
|
tracked = context.send(:initializer_arguments)
|
|
23
22
|
assert_equal jim, tracked[:user]
|
|
24
23
|
assert_equal amy, tracked[:other_user]
|
|
25
24
|
end
|
|
26
25
|
|
|
27
|
-
it
|
|
28
|
-
err = assert_raises(ArgumentError){
|
|
29
|
-
KeywordContext.new(other_user: User.new(
|
|
26
|
+
it "raises errors with missing keywords" do
|
|
27
|
+
err = assert_raises(ArgumentError) {
|
|
28
|
+
KeywordContext.new(other_user: User.new("Amy"))
|
|
30
29
|
}
|
|
31
30
|
assert_match(/missing keyword: :?user/, err.message)
|
|
32
31
|
end
|
|
@@ -36,7 +35,7 @@ class NonKeyworder
|
|
|
36
35
|
extend Surrounded::Context
|
|
37
36
|
|
|
38
37
|
initialize_without_keywords :this, :that do
|
|
39
|
-
|
|
38
|
+
instance_variable_set(:@defined_by_initializer_block, "yes")
|
|
40
39
|
end
|
|
41
40
|
|
|
42
41
|
trigger :access_other_object do
|
|
@@ -44,23 +43,23 @@ class NonKeyworder
|
|
|
44
43
|
end
|
|
45
44
|
end
|
|
46
45
|
|
|
47
|
-
describe Surrounded::Context,
|
|
48
|
-
it
|
|
46
|
+
describe Surrounded::Context, "non-keyword initializers" do
|
|
47
|
+
it "defines an initialize method accepting the same arguments" do
|
|
49
48
|
assert_equal 2, NonKeyworder.instance_method(:initialize).arity
|
|
50
49
|
end
|
|
51
50
|
|
|
52
|
-
it
|
|
53
|
-
assert NonKeyworder.new(User.new(
|
|
51
|
+
it "works without keyword arguments" do
|
|
52
|
+
assert NonKeyworder.new(User.new("Jim"), User.new("Guille"))
|
|
54
53
|
end
|
|
55
54
|
|
|
56
|
-
it
|
|
57
|
-
assert_equal
|
|
55
|
+
it "evaluates a given block" do
|
|
56
|
+
assert_equal "yes", NonKeyworder.new(User.new("Jim"), User.new("Guille")).instance_variable_get(:@defined_by_initializer_block)
|
|
58
57
|
end
|
|
59
58
|
|
|
60
|
-
it
|
|
61
|
-
context = NonKeyworder.new(User.new(
|
|
62
|
-
expect(context.access_other_object).must_equal
|
|
63
|
-
context.rebind(this: User.new(
|
|
64
|
-
expect(context.access_other_object).must_equal
|
|
59
|
+
it "allows rebinding with a hash" do
|
|
60
|
+
context = NonKeyworder.new(User.new("Jim"), User.new("Guille"))
|
|
61
|
+
expect(context.access_other_object).must_equal "Guille"
|
|
62
|
+
context.rebind(this: User.new("Amy"), that: User.new("Elizabeth"))
|
|
63
|
+
expect(context.access_other_object).must_equal "Elizabeth"
|
|
65
64
|
end
|
|
66
65
|
end
|