phenomenal 0.99.0 → 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.
- data/Rakefile +1 -7
- data/lib/phenomenal.rb +10 -1
- data/lib/phenomenal/adaptation.rb +6 -8
- data/lib/phenomenal/conflict_policies.rb +2 -1
- data/lib/phenomenal/context.rb +36 -31
- data/lib/phenomenal/dsl.rb +14 -9
- data/lib/phenomenal/feature.rb +1 -0
- data/lib/phenomenal/manager.rb +10 -12
- data/lib/phenomenal/proc.rb +2 -2
- data/lib/phenomenal/relationships/context_relationships.rb +2 -0
- data/lib/phenomenal/relationships/dsl.rb +1 -0
- data/lib/phenomenal/relationships/feature_relationships.rb +2 -2
- data/lib/phenomenal/relationships/implication.rb +10 -4
- data/lib/phenomenal/relationships/relationship.rb +13 -0
- data/lib/phenomenal/relationships/relationships_manager.rb +1 -1
- data/lib/phenomenal/relationships/relationships_store.rb +13 -7
- data/lib/phenomenal/relationships/requirement.rb +5 -0
- data/lib/phenomenal/relationships/suggestion.rb +14 -6
- data/lib/phenomenal/version.rb +1 -1
- data/lib/phenomenal/viewer/dsl.rb +15 -0
- data/lib/phenomenal/viewer/graphical.rb +136 -0
- data/lib/phenomenal/viewer/textual.rb +36 -0
- data/spec/context_spec.rb +93 -27
- data/spec/dsl_spec.rb +0 -39
- data/spec/integration/adaptation_spec.rb +127 -0
- data/spec/integration/combined_contexts_spec.rb +48 -0
- data/spec/integration/composition_spec.rb +62 -0
- data/spec/integration/conflict_policy_spec.rb +143 -0
- data/spec/integration/open_context.rb +48 -0
- data/spec/{behavior → integration}/relationships_spec.rb +0 -6
- data/spec/manager_spec.rb +30 -19
- data/spec/relationships/context_relationships_spec.rb +23 -3
- data/spec/relationships/dsl_spec.rb +9 -3
- data/spec/relationships/feature_relationships_spec.rb +22 -3
- data/spec/relationships/relationship_spec.rb +13 -1
- data/spec/relationships/relationships_manager_spec.rb +0 -11
- data/spec/relationships/relationships_store_spec.rb +31 -7
- data/spec/spec_helper.rb +1 -0
- data/spec/test_classes.rb +3 -0
- metadata +16 -13
- data/spec/behavior/adaptation_spec.rb +0 -5
- data/spec/behavior/combined_contexts_spec.rb +0 -5
- data/spec/behavior/composition_spec.rb +0 -5
- data/spec/behavior/conflict_policy_spec.rb +0 -5
- data/spec/behavior/open_context.rb +0 -5
data/spec/dsl_spec.rb
CHANGED
@@ -1,18 +1,11 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Phenomenal::DSL do
|
4
|
-
|
5
|
-
describe "#phen_define_context" do
|
6
|
-
pending "TODO"
|
7
|
-
end
|
8
|
-
|
9
4
|
describe "#phen_context" do
|
10
5
|
it "should exist in Kernel" do
|
11
6
|
Kernel.should respond_to :phen_context
|
12
7
|
end
|
13
8
|
|
14
|
-
pending "TODO"
|
15
|
-
|
16
9
|
describe "#context" do
|
17
10
|
it "should exist in Kernel" do
|
18
11
|
Kernel.should respond_to :context
|
@@ -29,8 +22,6 @@ describe Phenomenal::DSL do
|
|
29
22
|
Kernel.should respond_to :phen_feature
|
30
23
|
end
|
31
24
|
|
32
|
-
pending "TODO"
|
33
|
-
|
34
25
|
describe "#feature" do
|
35
26
|
it "should exist in Kernel" do
|
36
27
|
Kernel.should respond_to :feature
|
@@ -46,39 +37,29 @@ describe Phenomenal::DSL do
|
|
46
37
|
it "should exist in Kernel" do
|
47
38
|
Kernel.should respond_to :phen_forget_context
|
48
39
|
end
|
49
|
-
|
50
|
-
pending "TODO"
|
51
40
|
end
|
52
41
|
describe "#phen_add_adaptation" do
|
53
42
|
it "should exist in Kernel" do
|
54
43
|
Kernel.should respond_to :phen_add_adaptation
|
55
44
|
end
|
56
|
-
|
57
|
-
pending "TODO"
|
58
45
|
end
|
59
46
|
|
60
47
|
describe "#phen_add_class_adaptation" do
|
61
48
|
it "should exist in Kernel" do
|
62
49
|
Kernel.should respond_to :phen_add_class_adaptation
|
63
50
|
end
|
64
|
-
|
65
|
-
pending "TODO"
|
66
51
|
end
|
67
52
|
|
68
53
|
describe "#phen_remove_adaptation" do
|
69
54
|
it "should exist in Kernel" do
|
70
55
|
Kernel.should respond_to :phen_remove_adaptation
|
71
56
|
end
|
72
|
-
|
73
|
-
pending "TODO"
|
74
57
|
end
|
75
58
|
|
76
59
|
describe "#phen_remove_class_adaptation" do
|
77
60
|
it "should exist in Kernel" do
|
78
61
|
Kernel.should respond_to :phen_remove_class_adaptation
|
79
62
|
end
|
80
|
-
|
81
|
-
pending "TODO"
|
82
63
|
end
|
83
64
|
|
84
65
|
describe "#phen_activate_context" do
|
@@ -86,8 +67,6 @@ describe Phenomenal::DSL do
|
|
86
67
|
Kernel.should respond_to :phen_activate_context
|
87
68
|
end
|
88
69
|
|
89
|
-
pending "TODO"
|
90
|
-
|
91
70
|
describe "#activate_context" do
|
92
71
|
it "should exist in Kernel" do
|
93
72
|
Kernel.should respond_to :activate_context
|
@@ -104,8 +83,6 @@ describe Phenomenal::DSL do
|
|
104
83
|
Kernel.should respond_to :phen_deactivate_context
|
105
84
|
end
|
106
85
|
|
107
|
-
pending "TODO"
|
108
|
-
|
109
86
|
describe "#deactivate_context" do
|
110
87
|
it "should exist in Kernel" do
|
111
88
|
Kernel.should respond_to :deactivate_context
|
@@ -121,32 +98,24 @@ describe Phenomenal::DSL do
|
|
121
98
|
it "should exist in Kernel" do
|
122
99
|
Kernel.should respond_to :phen_context_active?
|
123
100
|
end
|
124
|
-
|
125
|
-
pending "TODO"
|
126
101
|
end
|
127
102
|
|
128
103
|
describe "#phen_context_information" do
|
129
104
|
it "should exist in Kernel" do
|
130
105
|
Kernel.should respond_to :phen_context_information
|
131
106
|
end
|
132
|
-
|
133
|
-
pending "TODO"
|
134
107
|
end
|
135
108
|
|
136
109
|
describe "#phen_default_context" do
|
137
110
|
it "should exist in Kernel" do
|
138
111
|
Kernel.should respond_to :phen_default_context
|
139
112
|
end
|
140
|
-
|
141
|
-
pending "TODO"
|
142
113
|
end
|
143
114
|
|
144
115
|
describe "#phen_defined_contexts" do
|
145
116
|
it "should exist in Kernel" do
|
146
117
|
Kernel.should respond_to :phen_defined_contexts
|
147
118
|
end
|
148
|
-
|
149
|
-
pending "TODO"
|
150
119
|
end
|
151
120
|
|
152
121
|
describe "#phen_proceed" do
|
@@ -154,8 +123,6 @@ describe Phenomenal::DSL do
|
|
154
123
|
Kernel.should respond_to :phen_proceed
|
155
124
|
end
|
156
125
|
|
157
|
-
pending "TODO"
|
158
|
-
|
159
126
|
describe "#proceed" do
|
160
127
|
it "should exist in Kernel" do
|
161
128
|
Kernel.should respond_to :proceed
|
@@ -171,11 +138,5 @@ describe Phenomenal::DSL do
|
|
171
138
|
it "should exist in Kernel" do
|
172
139
|
Kernel.should respond_to :phen_change_conflict_policy
|
173
140
|
end
|
174
|
-
|
175
|
-
pending "TODO"
|
176
|
-
end
|
177
|
-
|
178
|
-
describe ".phen_alias" do
|
179
|
-
pending "TODO"
|
180
141
|
end
|
181
142
|
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Simple adaptations" do
|
4
|
+
before :each do
|
5
|
+
|
6
|
+
phen_change_conflict_policy { |a,b| no_resolution_conflict_policy(a,b) }
|
7
|
+
|
8
|
+
context(:quiet) do
|
9
|
+
adaptations_for Phone
|
10
|
+
adapt :advertise do |a_call|
|
11
|
+
"vibrator"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context(:offHook) do
|
16
|
+
adaptations_for Phone
|
17
|
+
adapt :advertise do |a_call|
|
18
|
+
"call waiting signal"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
context(:test) do
|
24
|
+
adaptations_for TestClass
|
25
|
+
adapt :to_s do
|
26
|
+
@value + " @access " + value + " attr_accessor_access"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context(:test_2) do
|
31
|
+
adaptations_for TestClass
|
32
|
+
adapt_class :klass_var_access do
|
33
|
+
@@klass_var+1
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context(:test_3) do
|
38
|
+
adaptations_for TestClass
|
39
|
+
adapt_class :klass_inst_var_access do
|
40
|
+
@klass_inst_var+1
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
after :each do
|
47
|
+
force_forget_context(context(:quiet))
|
48
|
+
force_forget_context(context(:offHook))
|
49
|
+
force_forget_context(context(:test))
|
50
|
+
force_forget_context(context(:test_2))
|
51
|
+
force_forget_context(context(:test_3))
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should override default behavior" do
|
55
|
+
phone = Phone.new
|
56
|
+
call = Call.new("Bob")
|
57
|
+
phone.receive(call)
|
58
|
+
phone.advertise(call).should=="ringtone"
|
59
|
+
activate_context(:quiet)
|
60
|
+
phone.advertise(call).should=="vibrator"
|
61
|
+
deactivate_context(:quiet)
|
62
|
+
phone.advertise(call).should=="ringtone"
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should refuse confliction adaptations in the same context" do
|
66
|
+
expect{context(:quiet).add_adaptation(Phone,:advertise,true) do |a_call|
|
67
|
+
"A call test"
|
68
|
+
end}.to raise_error Phenomenal::Error
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should refuse adaptations for inexistent methods" do
|
72
|
+
expect{phen_add_adaptation(:test,Phone,:phonyAdvertise){|a_call| "vibrator"}}.
|
73
|
+
to raise_error Phenomenal::Error
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should be possible to add/remove adaptations at runtime" do
|
77
|
+
phone = Phone.new
|
78
|
+
call = Call.new("Bob")
|
79
|
+
phone.receive(call)
|
80
|
+
|
81
|
+
activate_context(:quiet)
|
82
|
+
phen_context_active?(:quiet).should be_true
|
83
|
+
expect{phen_remove_adaptation(:quiet,Phone,:advertise)}.to_not raise_error
|
84
|
+
|
85
|
+
phone.advertise(call).should=="ringtone"
|
86
|
+
|
87
|
+
expect{phen_add_adaptation(:quiet,Phone,:advertise){|a_call| "vibrator" }}.to_not raise_error
|
88
|
+
|
89
|
+
phone.advertise(call).should=="vibrator"
|
90
|
+
expect{deactivate_context(:quiet)}.to_not raise_error
|
91
|
+
|
92
|
+
phone.advertise(call).should=="ringtone"
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should be possible to access instance variables in adaptations" do
|
96
|
+
t = TestClass.new("VAR")
|
97
|
+
t.to_s.should=="VAR"
|
98
|
+
|
99
|
+
activate_context(:test)
|
100
|
+
|
101
|
+
t.to_s.should == "VAR @access VAR attr_accessor_access"
|
102
|
+
|
103
|
+
deactivate_context(:test)
|
104
|
+
t.to_s.should=="VAR"
|
105
|
+
end
|
106
|
+
|
107
|
+
it "sould be possible to access class variables" do
|
108
|
+
TestClass.klass_var_access.should==1
|
109
|
+
activate_context(:test_2)
|
110
|
+
|
111
|
+
pending "Adaptations doesn't have access to class variables, seems to be a Ruby bug"
|
112
|
+
TestClass.klass_var_access.should==2
|
113
|
+
|
114
|
+
deactivate_context(:test_2)
|
115
|
+
TestClass.klass_var_access.should==1
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should be possible to access class instance variables adaptations" do
|
119
|
+
TestClass.klass_inst_var_access.should==2
|
120
|
+
|
121
|
+
activate_context(:test_3)
|
122
|
+
TestClass.klass_inst_var_access.should==3
|
123
|
+
|
124
|
+
deactivate_context(:test_3)
|
125
|
+
TestClass.klass_inst_var_access.should==2
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Combined contexts" do
|
4
|
+
it "should be possible to define combined contexts" do
|
5
|
+
expect{ context :a,:b}.to_not raise_error
|
6
|
+
force_forget_context(:a)
|
7
|
+
force_forget_context(:b)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should reopen the same combined context " do
|
11
|
+
context(:a,:b).should==context(:a,:b)
|
12
|
+
force_forget_context(:a)
|
13
|
+
force_forget_context(:b)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should use the adaptation of the combined context before the adaptations of the separated contexts" do
|
17
|
+
context :a do
|
18
|
+
adaptations_for TestString2
|
19
|
+
adapt :length do
|
20
|
+
84
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context :a,:b do
|
25
|
+
adaptations_for TestString2
|
26
|
+
adapt :length do
|
27
|
+
42
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
inst = TestString2.new("1234")
|
33
|
+
inst.length.should==4
|
34
|
+
activate_context :a
|
35
|
+
inst.length.should==84
|
36
|
+
activate_context :b
|
37
|
+
inst.length.should==42
|
38
|
+
activate_context :a
|
39
|
+
inst.length.should==42
|
40
|
+
deactivate_context :a
|
41
|
+
deactivate_context :a
|
42
|
+
inst.length.should==4
|
43
|
+
|
44
|
+
force_forget_context(:a)
|
45
|
+
force_forget_context(:b)
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Composition of adaptations" do
|
4
|
+
before :each do
|
5
|
+
|
6
|
+
context(:screening) do
|
7
|
+
adaptations_for Phone
|
8
|
+
adapt :advertise do |a_call|
|
9
|
+
proceed(a_call)+" with screening"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context(:test)
|
14
|
+
end
|
15
|
+
|
16
|
+
after :each do
|
17
|
+
force_forget_context(:screening)
|
18
|
+
force_forget_context(:test)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should adapt methods without args" do
|
22
|
+
prefix = "It's a nice "
|
23
|
+
suffix = "simple composition"
|
24
|
+
composed = prefix+suffix
|
25
|
+
inst = TestClass.new(prefix)
|
26
|
+
phen_add_adaptation(:test,String,:to_s) {phen_proceed+suffix}
|
27
|
+
|
28
|
+
inst.to_s.should == prefix
|
29
|
+
activate_context(:test)
|
30
|
+
inst.to_s.should==composed
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should adapt methods with args" do
|
34
|
+
str="Nice String!"
|
35
|
+
inst= TestClass.new(str)
|
36
|
+
phen_add_adaptation(:test,String,:eql?) do | str |
|
37
|
+
if phen_proceed(str)
|
38
|
+
"OK"
|
39
|
+
else
|
40
|
+
"KO"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
inst.eql?(str).should be_true
|
45
|
+
activate_context(:test)
|
46
|
+
|
47
|
+
inst.eql?(str).should=="OK"
|
48
|
+
inst.eql?(str+str).should=="KO"
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should allow nested compositions" do
|
52
|
+
phone = Phone.new
|
53
|
+
call = Call.new("Alice")
|
54
|
+
phone.receive(call)
|
55
|
+
|
56
|
+
phone.advertise(call).should=="ringtone"
|
57
|
+
activate_context(:screening)
|
58
|
+
phone.advertise(call).should=="ringtone with screening"
|
59
|
+
deactivate_context(:screening)
|
60
|
+
phone.advertise(call).should=="ringtone"
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Conflict policies" do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
phen_change_conflict_policy { |a,b| no_resolution_conflict_policy(a,b) }
|
7
|
+
context(:screening) do
|
8
|
+
adaptations_for Phone
|
9
|
+
adapt :advertise do |a_call|
|
10
|
+
phen_proceed(a_call)+" with screening"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context(:quiet) do
|
15
|
+
adaptations_for Phone
|
16
|
+
adapt :advertise do |a_call|
|
17
|
+
"vibrator"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
after :each do
|
23
|
+
force_forget_context(:screening)
|
24
|
+
force_forget_context(:quiet)
|
25
|
+
phen_change_conflict_policy { |a,b| age_conflict_policy(a,b) }
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should not allow two contexts with an adaptation for the same method to be active at the same time" do
|
29
|
+
|
30
|
+
expect{activate_context(:screening)}.to_not raise_error
|
31
|
+
expect{activate_context(:quiet)}.to raise_error Phenomenal::Error
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should set the age of the context such that the most recent one has the smaller age" do
|
35
|
+
phen_change_conflict_policy { |a,b| age_conflict_policy(a,b) }
|
36
|
+
|
37
|
+
phen_context_active?(phen_default_context).should be_true
|
38
|
+
phen_context_active?(:screening).should be_false
|
39
|
+
phen_context_active?(:quiet).should be_false
|
40
|
+
|
41
|
+
phen_activate_context(:screening)
|
42
|
+
|
43
|
+
(phen_context_information(:screening)[:age] <
|
44
|
+
phen_context_information(phen_default_context)[:age]).should be_true,
|
45
|
+
"screening context has been activated more recently than default"
|
46
|
+
|
47
|
+
phen_activate_context(:quiet)
|
48
|
+
(phen_context_information(:quiet)[:age] <
|
49
|
+
phen_context_information(:screening)[:age]).should be_true
|
50
|
+
"quiet context has been activated more recently than screening"
|
51
|
+
(phen_context_information(:screening)[:age] <
|
52
|
+
phen_context_information(phen_default_context)[:age]).should be_true,
|
53
|
+
"quiet context has still been activated more recently than default"
|
54
|
+
phen_deactivate_context(:quiet)
|
55
|
+
phen_deactivate_context(:screening)
|
56
|
+
phen_activate_context(:screening)
|
57
|
+
(phen_context_information(:screening)[:age] <
|
58
|
+
phen_context_information(:quiet)[:age]).should be_true,
|
59
|
+
"screening context has now been activated more recently than quiet"
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should choose the context the most recently activated" do
|
63
|
+
phen_change_conflict_policy { |a,b| age_conflict_policy(a,b) }
|
64
|
+
expect{activate_context(:screening)}.to_not raise_error
|
65
|
+
expect{activate_context(:quiet)}.to_not raise_error
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should work with interleaved activation of contexts" do
|
69
|
+
phen_change_conflict_policy { |a,b| age_conflict_policy(a,b) }
|
70
|
+
phone = Phone.new
|
71
|
+
call = Call.new("Alice")
|
72
|
+
phone.receive(call)
|
73
|
+
|
74
|
+
phone.advertise(call).should=="ringtone"
|
75
|
+
|
76
|
+
activate_context(:quiet)
|
77
|
+
phone.advertise(call).should=="vibrator"
|
78
|
+
|
79
|
+
activate_context(:screening)
|
80
|
+
phone.advertise(call).should=="vibrator with screening"
|
81
|
+
|
82
|
+
deactivate_context(:quiet)
|
83
|
+
phone.advertise(call).should=="ringtone with screening"
|
84
|
+
|
85
|
+
deactivate_context(:screening)
|
86
|
+
phone.advertise(call).should=="ringtone"
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should nest calls with the age policy" do
|
90
|
+
phen_change_conflict_policy { |a,b| age_conflict_policy(a,b) }
|
91
|
+
phone = Phone.new
|
92
|
+
call = Call.new("Alice")
|
93
|
+
phone.receive(call)
|
94
|
+
|
95
|
+
phone.advertise(call).should=="ringtone"
|
96
|
+
|
97
|
+
activate_context(:quiet)
|
98
|
+
phone.advertise(call).should=="vibrator"
|
99
|
+
|
100
|
+
activate_context(:screening)
|
101
|
+
phone.advertise(call).should=="vibrator with screening"
|
102
|
+
|
103
|
+
deactivate_context(:screening)
|
104
|
+
phone.advertise(call).should=="vibrator"
|
105
|
+
|
106
|
+
deactivate_context(:quiet)
|
107
|
+
phone.advertise(call).should=="ringtone"
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should PPPPPPPPPPPPPPPPPPPP" do
|
111
|
+
phen_change_conflict_policy { |a,b| age_conflict_policy(a,b) }
|
112
|
+
context(:level1)
|
113
|
+
phen_add_adaptation(:level1,TestClass,:print) do |arg|
|
114
|
+
phen_proceed(arg) + " 1 -> ARG1: #{arg.to_s}"
|
115
|
+
end
|
116
|
+
|
117
|
+
context(:level2)
|
118
|
+
phen_add_adaptation(:level2,TestClass,:print) do |arg|
|
119
|
+
phen_proceed(arg) + " 2 -> ARG2: #{arg.to_s}"
|
120
|
+
end
|
121
|
+
|
122
|
+
context(:level3)
|
123
|
+
phen_add_adaptation(:level3,TestClass,:print) do |arg|
|
124
|
+
phen_proceed(arg) + " 3 -> ARG3: #{arg.to_s}"
|
125
|
+
end
|
126
|
+
|
127
|
+
context(:level4)
|
128
|
+
phen_add_adaptation(:level4,TestClass,:print) do |arg|
|
129
|
+
phen_proceed(arg) + " 4 -> ARG4: #{arg.to_s}"
|
130
|
+
end
|
131
|
+
t = TestClass.new("Foo")
|
132
|
+
t.print("bar").should=="0 -> ARG: bar"
|
133
|
+
activate_context(:level1)
|
134
|
+
activate_context(:level2)
|
135
|
+
activate_context(:level3)
|
136
|
+
activate_context(:level4)
|
137
|
+
t.print("bar").should=="0 -> ARG: bar 1 -> ARG1: bar 2 -> ARG2: bar 3 -> ARG3: bar 4 -> ARG4: bar"
|
138
|
+
force_forget_context(:level1)
|
139
|
+
force_forget_context(:level2)
|
140
|
+
force_forget_context(:level3)
|
141
|
+
force_forget_context(:level4)
|
142
|
+
end
|
143
|
+
end
|