phenomenal 0.11.11.24.4 → 0.99.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.
Files changed (51) hide show
  1. data/LICENSE +1 -1
  2. data/README +3 -4
  3. data/Rakefile +3 -0
  4. data/lib/phenomenal.rb +15 -2
  5. data/lib/phenomenal/adaptation.rb +22 -12
  6. data/lib/phenomenal/context.rb +127 -134
  7. data/lib/phenomenal/dsl.rb +41 -14
  8. data/lib/phenomenal/feature.rb +8 -0
  9. data/lib/phenomenal/logger.rb +0 -1
  10. data/lib/phenomenal/manager.rb +117 -35
  11. data/lib/phenomenal/relationships/context_relationships.rb +22 -0
  12. data/lib/phenomenal/relationships/dsl.rb +18 -0
  13. data/lib/phenomenal/relationships/feature_relationships.rb +42 -0
  14. data/lib/phenomenal/relationships/implication.rb +35 -0
  15. data/lib/phenomenal/relationships/relationship.rb +42 -0
  16. data/lib/phenomenal/relationships/relationships_manager.rb +63 -0
  17. data/lib/phenomenal/relationships/relationships_store.rb +73 -0
  18. data/lib/phenomenal/relationships/requirement.rb +26 -0
  19. data/lib/phenomenal/relationships/suggestion.rb +41 -0
  20. data/lib/phenomenal/version.rb +3 -0
  21. data/spec/adaptation_spec.rb +64 -0
  22. data/spec/behavior/adaptation_spec.rb +5 -0
  23. data/spec/behavior/combined_contexts_spec.rb +5 -0
  24. data/spec/behavior/composition_spec.rb +5 -0
  25. data/spec/behavior/conflict_policy_spec.rb +5 -0
  26. data/spec/behavior/open_context.rb +5 -0
  27. data/spec/behavior/relationships_spec.rb +249 -0
  28. data/spec/context_spec.rb +268 -0
  29. data/spec/dsl_spec.rb +181 -0
  30. data/spec/feature_spec.rb +5 -0
  31. data/spec/manager_spec.rb +84 -0
  32. data/spec/proc_spec.rb +20 -0
  33. data/spec/relationships/context_relationships_spec.rb +13 -0
  34. data/spec/relationships/dsl_spec.rb +13 -0
  35. data/spec/relationships/feature_relationships_spec.rb +13 -0
  36. data/spec/relationships/relationship_spec.rb +31 -0
  37. data/spec/relationships/relationships_manager_spec.rb +15 -0
  38. data/spec/relationships/relationships_store_spec.rb +19 -0
  39. data/spec/spec_helper.rb +18 -0
  40. data/{test → spec}/test_classes.rb +3 -0
  41. metadata +69 -24
  42. data/demo.rb +0 -24
  43. data/demo_age.rb +0 -89
  44. data/demo_dsl.rb +0 -28
  45. data/phenomenal-0.11.11.24.3.gem +0 -0
  46. data/phenomenal.gemspec +0 -15
  47. data/test/test_cop_adaptation.rb +0 -168
  48. data/test/test_cop_composition.rb +0 -84
  49. data/test/test_cop_conflictpolicy.rb +0 -177
  50. data/test/test_cop_infrastructure.rb +0 -129
  51. data/test_declaration.rb +0 -18
data/demo_dsl.rb DELETED
@@ -1,28 +0,0 @@
1
- require_relative 'lib/phenomenal.rb'
2
- class Foo
3
- def initialize
4
- @inst_var = "bar"
5
- end
6
- def print
7
- "Base: " +@inst_var
8
- end
9
- end
10
-
11
- context :Test do
12
- implies :plop
13
-
14
- adaptations_for Foo
15
- adapt :print do
16
- pnml_proceed + "ADAPT"
17
- end
18
- end
19
-
20
- f = Foo.new
21
- puts f.print
22
-
23
- pnml_activate_context(:Test)
24
- puts f.print
25
-
26
- pnml_deactivate_context(:Test)
27
- puts f.print
28
-
Binary file
data/phenomenal.gemspec DELETED
@@ -1,15 +0,0 @@
1
- Gem::Specification.new do |s|
2
- s.name = "phenomenal"
3
- s.summary = "A context oriented programing framework for ruby"
4
- s.description = "A context oriented programing framework for ruby"
5
- s.version = "0.11.11.24.4"
6
- s.authors = "Loic Vigneron - Thibault Poncelet"
7
- s.email = "thibault.poncelet@student.uclouvain.be - loic.vigneron@student.uclouvain.be"
8
- s.date = "2011-11-24"
9
- s.platform = Gem::Platform::RUBY
10
- s.required_ruby_version = '>=1.9.2'
11
- s.files = Dir['**/**']
12
- s.has_rdoc = false
13
- s.test_files = Dir['test/*.rb']
14
- s.homepage = "http://www.phenomenal-gem.com"
15
- end
@@ -1,168 +0,0 @@
1
- require_relative "../lib/phenomenal.rb"
2
- require_relative "./test_classes.rb"
3
- require "test/unit"
4
-
5
- class TestCopAdaptation < Test::Unit::TestCase
6
- def setup
7
- phen_define_context(:quiet)
8
- phen_define_context(:offHook)
9
- phen_add_adaptation(:quiet,Phone,:advertise){|a_call| "vibrator" }
10
- phen_add_adaptation(:offHook,Phone,:advertise) do |a_call|
11
- "call waiting signal"
12
- end
13
- phen_define_context(:test)
14
- phen_add_adaptation(:test,TestClass,:to_s) do
15
- @value + " @access " + value + " attr_accessor_access"
16
- end
17
-
18
- phen_define_context(:test_2)
19
- phen_add_adaptation(:test_2,TestClass,:klass_var_access) do
20
- @@klass_var+1
21
- end
22
-
23
- phen_define_context(:test_3)
24
- phen_add_adaptation(:test_3,TestClass,:klass_inst_var_access) do
25
- @klass_inst_var+1
26
- end
27
- end
28
-
29
- def teardown
30
- while phen_context_active?(:quiet) do
31
- phen_deactivate_context(:quiet)
32
- end
33
- phen_forget_context(:quiet)
34
-
35
- while phen_context_active?(:offHook) do
36
- phen_deactivate_context(:offHook)
37
- end
38
- phen_forget_context(:offHook)
39
-
40
- while phen_context_active?(:test) do
41
- phen_deactivate_context(:test)
42
- end
43
- phen_forget_context(:test)
44
-
45
- while phen_context_active?(:test_2) do
46
- phen_deactivate_context(:test_2)
47
- end
48
- phen_forget_context(:test_2)
49
-
50
- while phen_context_active?(:test_3) do
51
- phen_deactivate_context(:test_3)
52
- end
53
- phen_forget_context(:test_3)
54
- end
55
-
56
- def test_overriding_adaptation
57
- phone = Phone.new
58
- call = Call.new("Bob")
59
- phone.receive(call)
60
- assert((phone.advertise(call))=="ringtone",
61
- "Default behaviour should be expressed")
62
- phen_activate_context(:quiet)
63
- assert((phone.advertise(call))=="vibrator",
64
- "Behavior adapted to quiet environments should be expressed")
65
- phen_deactivate_context(:quiet)
66
- assert((phone.advertise(call))=="ringtone",
67
- "Default behaviour should be expressed")
68
- end
69
-
70
- def test_conflicting_adaptation
71
- assert_raise(Phenomenal::Error,
72
- "A context cannot have two different adaptations for the same method.")do
73
- phen_add_adaptation(:quiet,Phone,:advertise) do |a_call|
74
- "call waiting signal"
75
- end
76
- end
77
- end
78
-
79
- def test_invalid_adaptation
80
- phen_define_context(:temp)
81
- assert_raise(Phenomenal::Error,
82
- "Adaptation of inexistent methods should be forbidden.") do
83
- phen_add_adaptation(:temp,Phone,:phonyAdvertise){|a_call| "vibrator"}
84
- phen_activate_context(:temp)
85
- end
86
- phen_forget_context(:temp)
87
- end
88
-
89
- def test_conflicting_activation
90
- assert(!phen_context_active?(:quiet))
91
- assert_nothing_raised(Phenomenal::Error,
92
- "Shoud be OK to activate the quiet context") do
93
- phen_activate_context(:quiet)
94
- end
95
- assert(phen_context_active?(:quiet))
96
- assert(!phen_context_active?(:offHook))
97
- assert_raise(Phenomenal::Error,
98
- "Should conflict with currently active quiet context") do
99
- phen_activate_context(:offHook)
100
- end
101
- assert(!phen_context_active?(:offHook),
102
- "Should not be mistakenly activated after error")
103
- end
104
-
105
- def test_runtime_adding_removing_adaptation
106
- phone = Phone.new
107
- call = Call.new("Bob")
108
- phone.receive(call)
109
- phen_activate_context(:quiet)
110
- assert(phen_context_active?(:quiet))
111
- assert_nothing_raised("Should be ok to remove an active adaptation") do
112
- phen_remove_adaptation(:quiet,Phone,:advertise)
113
- end
114
- assert((phone.advertise(call))=="ringtone",
115
- "Default behaviour should be expressed")
116
- assert_nothing_raised("Should be ok to add an active adaptation") do
117
- phen_add_adaptation(:quiet,Phone,:advertise){|a_call| "vibrator" }
118
- end
119
- assert((phone.advertise(call))=="vibrator",
120
- "Adapted behaviour should be expressed")
121
- assert_nothing_raised("Should be ok to deactivate the context") do
122
- phen_deactivate_context(:quiet)
123
- end
124
- assert((phone.advertise(call))=="ringtone",
125
- "Default behaviour should be expressed")
126
- end
127
-
128
- def test_instance_variable_access
129
- t = TestClass.new("VAR")
130
- assert("VAR"==t.to_s, %(Default to_s should acess var and return
131
- string value))
132
- phen_activate_context(:test)
133
- assert("VAR @access VAR attr_accessor_access"==t.to_s, %(Adapted to_s should
134
- acess both instance var and accessor meth and return string value))
135
- phen_deactivate_context(:test)
136
- assert("VAR"==t.to_s, %(Default to_s should acess var and return
137
- string value))
138
- end
139
-
140
- def test_class_variable_access
141
- assert(1==TestClass.klass_var_access, %(Default meth should acess var and
142
- return val))
143
- phen_activate_context(:test_2)
144
-
145
- # Doesn't work: Adaptations doesn't have access to class variables
146
- # Seems to be a Ruby bug
147
- #TODO
148
-
149
- #assert(2==TestClass.klass_var_access, %(Adapted meth should
150
- # acess klass variable and return its value +1))
151
- phen_deactivate_context(:test_2)
152
- assert(1==TestClass.klass_var_access, %(Default meth should acess var and
153
- return val))
154
- end
155
-
156
- def test_class_instance_variable_access
157
- assert(2==TestClass.klass_inst_var_access, %(Default meth should acess var
158
- and return val))
159
- phen_activate_context(:test_3)
160
-
161
- assert(3==TestClass.klass_inst_var_access, %(Adapted meth should
162
- acess klass variable and return its value +1))
163
- phen_deactivate_context(:test_3)
164
- assert(2==TestClass.klass_inst_var_access, %(Default meth should acess var
165
- and return string value))
166
- end
167
- end
168
-
@@ -1,84 +0,0 @@
1
- require_relative "../lib/phenomenal.rb"
2
- require_relative "./test_classes.rb"
3
- require "test/unit"
4
-
5
- class TestCopComposition < Test::Unit::TestCase
6
- def setup
7
- phen_define_context(:screening)
8
- phen_add_adaptation(:screening,Phone,:advertise) do |a_call|
9
- phen_proceed(a_call)+" with screening"
10
- end
11
- phen_define_context(:test)
12
- end
13
-
14
- def teardown
15
- while phen_context_active?(:test) do
16
- phen_deactivate_context(:test)
17
- end
18
- phen_forget_context(:test)
19
-
20
- while phen_context_active?(:screening) do
21
- phen_deactivate_context(:screening)
22
- end
23
- phen_forget_context(:screening)
24
- end
25
-
26
- def test_invalid_proceed
27
- assert_raise(Phenomenal::Error, %(
28
- Proceed cannot be used outside adaptation of
29
- other methods)) {phen_proceed}
30
- end
31
-
32
- def test_simple_composition_noargs
33
- prefix = "It's a nice "
34
- suffix = "simple composition"
35
- composed = prefix+suffix
36
- inst = TestClass.new(prefix)
37
- phen_add_adaptation(:test,String,:to_s) {phen_proceed+suffix}
38
- assert(inst.to_s==prefix,
39
- "The base to_s method of String must have its default behaviour")
40
- phen_activate_context(:test)
41
- assert(inst.to_s==composed,
42
- %(The adapted to_s method of String must had '#{suffix}'
43
- at the end of the string))
44
- end
45
-
46
- def test_simple_composition_args
47
- str="Nice String!"
48
- inst= TestClass.new(str)
49
- phen_add_adaptation(:test,String,:eql?) do | str |
50
- if phen_proceed(str)
51
- "OK"
52
- else
53
- "KO"
54
- end
55
- end
56
- assert(inst.eql?(str),
57
- "The base eql? method of String must have its default behaviour")
58
- phen_activate_context(:test)
59
- assert(inst.eql?(str)=="OK",
60
- %(The adapted eql? method of String must return 'OK' if the two string
61
- are equal))
62
- assert(inst.eql?(str+str)=="KO",
63
- %(The adapted eql? method of String must return 'KO' if the two string
64
- are not equal))
65
- end
66
-
67
- def test_nested_activation
68
- phone = Phone.new
69
- call = Call.new("Alice")
70
- phone.receive(call)
71
-
72
- assert((phone.advertise(call))=="ringtone",
73
- "Default behaviour should be expressed")
74
- phen_activate_context(:screening)
75
- assert((phone.advertise(call))=="ringtone with screening",
76
- %(Screening information should be overlaid over the default ringtone
77
- advertisement'.))
78
- phen_deactivate_context(:screening)
79
- assert((phone.advertise(call))=="ringtone",
80
- "Default behaviour should be expressed")
81
-
82
- end
83
- end
84
-
@@ -1,177 +0,0 @@
1
- require_relative "../lib/phenomenal.rb"
2
- require_relative "./test_classes.rb"
3
- require "test/unit"
4
-
5
- class TestCopConflictPolicy < Test::Unit::TestCase
6
- def setup
7
- phen_define_context(:screening)
8
- phen_add_adaptation(:screening,Phone,:advertise) do |a_call|
9
- phen_proceed(a_call)+" with screening"
10
- end
11
-
12
- phen_define_context(:quiet)
13
- phen_add_adaptation(:quiet,Phone,:advertise){|a_call| "vibrator" }
14
-
15
- end
16
-
17
- def teardown
18
- while phen_context_active?(:screening) do
19
- phen_deactivate_context(:screening)
20
- end
21
- phen_forget_context(:screening)
22
-
23
- while phen_context_active?(:quiet) do
24
- phen_deactivate_context(:quiet)
25
- end
26
- phen_forget_context(:quiet)
27
- phen_change_conflict_policy { |a,b| no_resolution_conflict_policy(a,b) }
28
- end
29
-
30
- def test_no_resolution_policy
31
- assert_nothing_raised(Phenomenal::Error,"The first context have to be
32
- activated without any problem"){phen_activate_context(:screening)}
33
- assert_raise(Phenomenal::Error,"In the default policy, a second context
34
- that adapt the same method and is not the default one cannot
35
- be activated"){phen_activate_context(:quiet)}
36
- end
37
-
38
- def test_protocol_age_policy
39
- assert(phen_context_informations(
40
- phen_default_context)[:activation_age].kind_of?(Fixnum),
41
- "Contexts should have the age property")
42
- end
43
-
44
- def test_activation_age_policy
45
- phen_change_conflict_policy { |a,b| age_conflict_policy(a,b) }
46
- puts "llll #{phen_default_context.class}"
47
- assert(phen_context_active?(phen_default_context),
48
- "Default context should normally be active")
49
- assert(!phen_context_active?(:screening), "Context1 should be inactive")
50
- assert(!phen_context_active?(:quiet),"Context2 should be inactive")
51
-
52
- phen_activate_context(:screening)
53
- assert(phen_context_informations(:screening)[:activation_age] <
54
- phen_context_informations(phen_default_context)[:activation_age],
55
- "screening context has been activated more recently than default")
56
-
57
- phen_activate_context(:quiet)
58
- assert(phen_context_informations(:quiet)[:activation_age] <
59
- phen_context_informations(:screening)[:activation_age],
60
- "quiet context has been activated more recently than screening")
61
- assert(phen_context_informations(:screening)[:activation_age] <
62
- phen_context_informations(phen_default_context)[:activation_age],
63
- "quiet context has still been activated more recently than default")
64
- phen_deactivate_context(:quiet)
65
- phen_deactivate_context(:screening)
66
- phen_activate_context(:screening)
67
- assert(phen_context_informations(:screening)[:activation_age] <
68
- phen_context_informations(:quiet)[:activation_age],
69
- "screening context has now been activated more recently than quiet")
70
- end
71
-
72
- def test_conflicting_activation_age_policy
73
- phen_change_conflict_policy { |a,b| age_conflict_policy(a,b) }
74
- assert_nothing_raised(Phenomenal::Error,"The first context have to be
75
- activated without any problem"){phen_activate_context(:screening)}
76
- assert_nothing_raised(Phenomenal::Error,"In the age policy, a second context
77
- that adapt the same method and is not the default one should
78
- be activated without error"){phen_activate_context(:quiet)}
79
- end
80
-
81
- def test_interleaved_activation_age_policy
82
- phen_change_conflict_policy { |a,b| age_conflict_policy(a,b) }
83
- phone = Phone.new
84
- call = Call.new("Alice")
85
- phone.receive(call)
86
-
87
- assert((phone.advertise(call))=="ringtone",
88
- "Default behaviour should be expressed --> ringtone")
89
-
90
- phen_activate_context(:quiet)
91
- assert((phone.advertise(call))=="vibrator",
92
- "Call advertisement should adapt to quiet context")
93
-
94
- phen_activate_context(:screening)
95
- assert((phone.advertise(call))=="vibrator with screening",
96
- "Screening information should be overlaid over quiet context behaviour
97
- (vibrator)")
98
-
99
- phen_deactivate_context(:quiet)
100
- assert((phone.advertise(call))=="ringtone with screening",
101
- "Screening information should be overlaid over default context behaviour
102
- (ringtone)")
103
-
104
- phen_deactivate_context(:screening)
105
- assert((phone.advertise(call))=="ringtone",
106
- "Call advertisement should be reverted to the default")
107
- end
108
-
109
- def test_nested_activation_age_policy
110
- phen_change_conflict_policy { |a,b| age_conflict_policy(a,b) }
111
- phone = Phone.new
112
- call = Call.new("Alice")
113
- phone.receive(call)
114
-
115
- assert((phone.advertise(call))=="ringtone",
116
- "Default behaviour should be expressed --> ringtone")
117
-
118
- phen_activate_context(:quiet)
119
- assert((phone.advertise(call))=="vibrator",
120
- "Call advertisement should adapt to quiet context")
121
-
122
- phen_activate_context(:screening)
123
- assert((phone.advertise(call))=="vibrator with screening",
124
- "Screening information should be overlaid over quiet context behaviour
125
- (vibrator)")
126
-
127
- phen_deactivate_context(:screening)
128
- assert((phone.advertise(call))=="vibrator",
129
- "Call advertisement should be reverted to that of quiet context")
130
-
131
- phen_deactivate_context(:quiet)
132
- assert((phone.advertise(call))=="ringtone",
133
- "Call advertisement should be reverted to the default")
134
- end
135
-
136
- def test_4_level_age_policy
137
- phen_change_conflict_policy { |a,b| age_conflict_policy(a,b) }
138
- phen_define_context(:level1)
139
- phen_add_adaptation(:level1,TestClass,:print) do |arg|
140
- phen_proceed(arg) + " 1 -> ARG1: #{arg.to_s}"
141
- end
142
-
143
- phen_define_context(:level2)
144
- phen_add_adaptation(:level2,TestClass,:print) do |arg|
145
- phen_proceed(arg) + " 2 -> ARG2: #{arg.to_s}"
146
- end
147
-
148
- phen_define_context(:level3)
149
- phen_add_adaptation(:level3,TestClass,:print) do |arg|
150
- phen_proceed(arg) + " 3 -> ARG3: #{arg.to_s}"
151
- end
152
-
153
- phen_define_context(:level4)
154
- phen_add_adaptation(:level4,TestClass,:print) do |arg|
155
- phen_proceed(arg) + " 4 -> ARG4: #{arg.to_s}"
156
- end
157
- t = TestClass.new("Foo")
158
- assert(t.print("bar")=="0 -> ARG: bar",
159
- "Default behaviour should be expressed")
160
- phen_activate_context(:level1)
161
- phen_activate_context(:level2)
162
- phen_activate_context(:level3)
163
- phen_activate_context(:level4)
164
- assert(t.print("bar")==
165
- "0 -> ARG: bar 1 -> ARG1: bar 2 -> ARG2: bar 3 -> ARG3: bar 4 -> ARG4: bar",
166
- "Composed behaviour should be expressed")
167
- phen_deactivate_context(:level1)
168
- phen_forget_context(:level1)
169
- phen_deactivate_context(:level2)
170
- phen_forget_context(:level2)
171
- phen_deactivate_context(:level3)
172
- phen_forget_context(:level3)
173
- phen_deactivate_context(:level4)
174
- phen_forget_context(:level4)
175
- end
176
- end
177
-