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
@@ -1,3 +1,5 @@
|
|
1
|
+
# Define the methods that can be called by a feature to
|
2
|
+
# define relationships
|
1
3
|
module Phenomenal::FeatureRelationships
|
2
4
|
attr_accessor :relationships
|
3
5
|
|
@@ -20,7 +22,6 @@ module Phenomenal::FeatureRelationships
|
|
20
22
|
private
|
21
23
|
def add_relationship(source,targets,type)
|
22
24
|
targets[:on]=Array.new.push(targets[:on]) if !targets[:on].is_a?(Array)
|
23
|
-
|
24
25
|
if targets[:on].nil?
|
25
26
|
Phenomenal::Logger.instance.error(
|
26
27
|
"Invalid relationship, missing target context"
|
@@ -37,6 +38,5 @@ module Phenomenal::FeatureRelationships
|
|
37
38
|
end
|
38
39
|
end
|
39
40
|
end
|
40
|
-
|
41
41
|
end
|
42
42
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# Define the behavior of the Implication relationship
|
1
2
|
class Phenomenal::Implication < Phenomenal::Relationship
|
2
3
|
attr_accessor :activation_counter
|
3
4
|
def initialize(source,target,feature)
|
@@ -8,28 +9,33 @@ class Phenomenal::Implication < Phenomenal::Relationship
|
|
8
9
|
def activate_feature
|
9
10
|
if source.active?
|
10
11
|
target.activate
|
11
|
-
activation_counter+=1
|
12
|
+
self.activation_counter+=1
|
12
13
|
end
|
13
14
|
end
|
14
15
|
|
15
16
|
def deactivate_feature
|
16
17
|
if activation_counter>0
|
17
18
|
target.deactivate
|
18
|
-
|
19
|
+
self.activation_counter-=1
|
19
20
|
end
|
20
21
|
end
|
21
22
|
|
22
23
|
def activate_context(context)
|
23
24
|
if source==context
|
24
25
|
target.activate
|
26
|
+
self.activation_counter+=1
|
25
27
|
end
|
26
28
|
end
|
27
29
|
|
28
30
|
def deactivate_context(context)
|
29
|
-
if source==context
|
31
|
+
if source==context && activation_counter>0
|
30
32
|
target.deactivate
|
31
|
-
|
33
|
+
self.activation_counter-=1
|
34
|
+
elsif activation_counter>0
|
32
35
|
source.deactivate
|
36
|
+
self.activation_counter-=1
|
37
|
+
else
|
38
|
+
# Nothing to do
|
33
39
|
end
|
34
40
|
end
|
35
41
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# Define a first class relationship
|
1
2
|
class Phenomenal::Relationship
|
2
3
|
attr_accessor :source,:target,:manager,:feature
|
3
4
|
|
@@ -24,15 +25,27 @@ class Phenomenal::Relationship
|
|
24
25
|
self.target=t if !t.nil?
|
25
26
|
end
|
26
27
|
|
28
|
+
# Must be redifined for each type of relation
|
29
|
+
# if necessary
|
30
|
+
# Called when a context is activated
|
27
31
|
def activate_context(context)
|
28
32
|
end
|
29
33
|
|
34
|
+
# Must be redifined for each type of relation
|
35
|
+
# if necessary
|
36
|
+
# Called when a context is deactivated
|
30
37
|
def deactivate_context(context)
|
31
38
|
end
|
32
39
|
|
40
|
+
# Must be redifined for each type of relation
|
41
|
+
# if necessary
|
42
|
+
# Called when a feature is activated
|
33
43
|
def activate_feature
|
34
44
|
end
|
35
45
|
|
46
|
+
# Must be redifined for each type of relation
|
47
|
+
# if necessary
|
48
|
+
# Called when a feature is deactivated
|
36
49
|
def deactivate_feature
|
37
50
|
end
|
38
51
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# Define the class where all the actives relationships are
|
2
|
+
# efficiently stored
|
1
3
|
class Phenomenal::RelationshipsStore
|
2
4
|
attr_accessor :sources, :targets
|
3
5
|
|
@@ -34,16 +36,20 @@ class Phenomenal::RelationshipsStore
|
|
34
36
|
def update_references(context)
|
35
37
|
# Do nothing when anonymous, references are already valid
|
36
38
|
return if context.anonymous?
|
37
|
-
# Update sources
|
38
|
-
@sources[context.name].
|
39
|
-
relationship
|
39
|
+
# Update sources
|
40
|
+
if not @sources[context.name].nil?
|
41
|
+
@sources[context.name].each do |relationship|
|
42
|
+
relationship.source=context
|
43
|
+
end
|
44
|
+
@sources[context]=@source.delete(context.name)
|
40
45
|
end
|
41
|
-
@sources[context]=@source.delete(context.name)
|
42
46
|
# Update targets
|
43
|
-
@targets[context.name].
|
44
|
-
relationship
|
47
|
+
if not @targets[context.name].nil?
|
48
|
+
@targets[context.name].each do |relationship|
|
49
|
+
relationship.target=context
|
50
|
+
end
|
51
|
+
@targets[context]=@targets.delete(context.name)
|
45
52
|
end
|
46
|
-
@targets[context]=@targets.delete(context.name)
|
47
53
|
end
|
48
54
|
|
49
55
|
def get_for(context)
|
@@ -1,8 +1,13 @@
|
|
1
|
+
# Define the behavior of the Requirement relationship
|
1
2
|
class Phenomenal::Requirement < Phenomenal::Relationship
|
3
|
+
|
2
4
|
def activate_feature
|
3
5
|
check_requirement
|
4
6
|
end
|
5
7
|
|
8
|
+
def deactivate_feature
|
9
|
+
end
|
10
|
+
|
6
11
|
def activate_context(context)
|
7
12
|
if(source==context)
|
8
13
|
check_requirement
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# Define the behavior of the Suggestion relationship
|
1
2
|
class Phenomenal::Suggestion < Phenomenal::Relationship
|
2
3
|
attr_accessor :activation_counter
|
3
4
|
|
@@ -20,22 +21,29 @@ class Phenomenal::Suggestion < Phenomenal::Relationship
|
|
20
21
|
begin
|
21
22
|
if activation_counter>0
|
22
23
|
target.deactivate
|
23
|
-
self.
|
24
|
+
self.activation_counter-=1
|
24
25
|
end
|
25
26
|
rescue
|
26
27
|
end
|
27
28
|
end
|
28
29
|
|
29
|
-
|
30
30
|
def activate_context(context)
|
31
|
-
|
32
|
-
|
31
|
+
begin
|
32
|
+
if source==context
|
33
|
+
target.activate
|
34
|
+
self.activation_counter+=1
|
35
|
+
end
|
36
|
+
rescue
|
33
37
|
end
|
34
38
|
end
|
35
39
|
|
36
40
|
def deactivate_context(context)
|
37
|
-
|
38
|
-
|
41
|
+
begin
|
42
|
+
if source==context && activation_counter>0
|
43
|
+
target.deactivate
|
44
|
+
self.activation_counter-=1
|
45
|
+
end
|
46
|
+
rescue
|
39
47
|
end
|
40
48
|
end
|
41
49
|
end
|
data/lib/phenomenal/version.rb
CHANGED
@@ -0,0 +1,15 @@
|
|
1
|
+
module Phenomenal::DSL
|
2
|
+
def self.define_viewers(klass)
|
3
|
+
klass.class_eval do
|
4
|
+
# Graphical
|
5
|
+
def phen_graphical_view(file="view.png")
|
6
|
+
Phenomenal::Viewer::Graphical.new(file).generate
|
7
|
+
end
|
8
|
+
|
9
|
+
#Textual
|
10
|
+
def phen_textual_view
|
11
|
+
Phenomenal::Viewer::Textual.new.generate
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
# Define the way to generate a representation of the system
|
2
|
+
# using the graphical library graphviz
|
3
|
+
class Phenomenal::Viewer::Graphical
|
4
|
+
begin
|
5
|
+
require "graphviz"
|
6
|
+
@@graphviz=true
|
7
|
+
rescue LoadError
|
8
|
+
@@graphviz=false
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :manager, :rmanager
|
12
|
+
attr_accessor :main_graph, :feature_nodes, :r_feature_nodes, :context_nodes, :destination_file
|
13
|
+
|
14
|
+
def initialize(destination_file)
|
15
|
+
if !@@graphviz
|
16
|
+
Phenomenal::Logger.instance.error(
|
17
|
+
"The 'ruby-graphviz' gem isn't available. Please install it to generate graphic visualitations\n"+
|
18
|
+
" Otherwise use the text version"
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
@manager=Phenomenal::Manager.instance
|
23
|
+
@rmanager=Phenomenal::RelationshipsManager.instance
|
24
|
+
@destination_file=destination_file
|
25
|
+
@main_graph=nil
|
26
|
+
@feature_nodes={}
|
27
|
+
@r_feature_nodes={}
|
28
|
+
@context_nodes={}
|
29
|
+
end
|
30
|
+
|
31
|
+
def generate()
|
32
|
+
# Create main graph
|
33
|
+
self.main_graph = GraphViz::new("")
|
34
|
+
# Default options
|
35
|
+
self.main_graph[:compound] = "true"
|
36
|
+
self.main_graph.edge[:lhead] = ""
|
37
|
+
self.main_graph.edge[:ltail] = ""
|
38
|
+
self.main_graph.edge[:fontsize]=10.0
|
39
|
+
# Add nodes to the graph
|
40
|
+
self.manager.contexts.each do |key,context|
|
41
|
+
if not self.feature_nodes.include?(context) and not @context_nodes.include?(context)
|
42
|
+
add_node_for(context)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
# Create a relationship links
|
46
|
+
self.manager.contexts.each do |key,context|
|
47
|
+
add_edges_for(context)
|
48
|
+
end
|
49
|
+
self.main_graph.output( :png => self.destination_file )
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
def add_edges_for(context)
|
54
|
+
if context.is_a?(Phenomenal::Feature)
|
55
|
+
context.relationships.each do |relationship|
|
56
|
+
# Get source and destionation node
|
57
|
+
ltail=""
|
58
|
+
lhead=""
|
59
|
+
relationship.refresh
|
60
|
+
if self.feature_nodes.include?(relationship.source)
|
61
|
+
source_node=self.r_feature_nodes[relationship.source]
|
62
|
+
ltail="cluster_#{relationship.source.to_s}"
|
63
|
+
else
|
64
|
+
source_node=self.context_nodes[relationship.source]
|
65
|
+
end
|
66
|
+
if self.feature_nodes.include?(relationship.target)
|
67
|
+
target_node=self.r_feature_nodes[relationship.target]
|
68
|
+
lhead="cluster_#{relationship.target.to_s}"
|
69
|
+
else
|
70
|
+
target_node=self.context_nodes[relationship.target]
|
71
|
+
end
|
72
|
+
# Define graph container
|
73
|
+
s_parent_feature=relationship.source.parent_feature
|
74
|
+
t_parent_feature=relationship.target.parent_feature
|
75
|
+
if s_parent_feature==t_parent_feature && s_parent_feature!=self.manager.default_context
|
76
|
+
graph=self.feature_nodes[relationship.source.parent_feature]
|
77
|
+
else
|
78
|
+
graph=self.main_graph
|
79
|
+
end
|
80
|
+
# Add edge
|
81
|
+
edge=graph.add_edges(source_node,target_node,:ltail=>ltail,:lhead=>lhead)
|
82
|
+
# Define edge label
|
83
|
+
if context!=self.manager.default_context
|
84
|
+
edge[:label]=context.to_s
|
85
|
+
end
|
86
|
+
# Define edge color
|
87
|
+
if self.rmanager.relationships.include?(relationship)
|
88
|
+
edge[:color]="red"
|
89
|
+
end
|
90
|
+
# Define arrow type
|
91
|
+
if relationship.is_a?(Phenomenal::Implication)
|
92
|
+
edge[:arrowhead]="normal"
|
93
|
+
elsif relationship.is_a?(Phenomenal::Suggestion)
|
94
|
+
edge[:arrowhead]="empty"
|
95
|
+
elsif relationship.is_a?(Phenomenal::Requirement)
|
96
|
+
edge[:arrowhead]="inv"
|
97
|
+
else
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def add_node_for(context)
|
104
|
+
# The default context is the first to be added to the main graph
|
105
|
+
if self.feature_nodes[context.parent_feature].nil? and context==self.manager.default_context
|
106
|
+
current_graph=self.main_graph
|
107
|
+
# Always add the parent_feature before the contexts inside
|
108
|
+
elsif @feature_nodes[context.parent_feature].nil?
|
109
|
+
self.add_node_for(context.parent_feature)
|
110
|
+
else
|
111
|
+
current_graph=self.feature_nodes[context.parent_feature]
|
112
|
+
end
|
113
|
+
# Add node
|
114
|
+
if context.is_a?(Phenomenal::Feature)
|
115
|
+
node=current_graph.add_graph("cluster_#{context.to_s}")
|
116
|
+
node[:label]="#{context.to_s}"
|
117
|
+
# Add hidden node for feature relationship
|
118
|
+
fr=node.add_nodes("#{context.to_s}_relationship")
|
119
|
+
fr[:style]="invis"
|
120
|
+
fr[:height]=0.02
|
121
|
+
fr[:width]=0.02
|
122
|
+
fr[:fixedsize]=true
|
123
|
+
self.feature_nodes[context]=node
|
124
|
+
self.r_feature_nodes[context]=fr
|
125
|
+
else
|
126
|
+
node=current_graph.add_nodes(context.to_s)
|
127
|
+
self.context_nodes[context]=node
|
128
|
+
end
|
129
|
+
# Define node color
|
130
|
+
if context.active?
|
131
|
+
node[:color]="red"
|
132
|
+
else
|
133
|
+
node[:color]="black"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Define the way to generate a textual representation of the system
|
2
|
+
class Phenomenal::Viewer::Textual
|
3
|
+
attr_reader :manager, :rmanager
|
4
|
+
|
5
|
+
def initialize()
|
6
|
+
@manager=Phenomenal::Manager.instance
|
7
|
+
@rmanager=Phenomenal::RelationshipsManager.instance
|
8
|
+
end
|
9
|
+
|
10
|
+
def generate()
|
11
|
+
str=""
|
12
|
+
offset=" "
|
13
|
+
self.manager.contexts.each do |key,context|
|
14
|
+
if context.is_a?(Phenomenal::Feature)
|
15
|
+
type="Feature"
|
16
|
+
str=str+"#{type}: #{context.to_s} \n"
|
17
|
+
context.relationships.each do |relationship|
|
18
|
+
if relationship.is_a?(Phenomenal::Implication)
|
19
|
+
relation="=>"
|
20
|
+
elsif relationship.is_a?(Phenomenal::Suggestion)
|
21
|
+
relation="->"
|
22
|
+
elsif relationship.is_a?(Phenomenal::Requirement)
|
23
|
+
relation="=<"
|
24
|
+
else
|
25
|
+
relation="??"
|
26
|
+
end
|
27
|
+
str=str+"#{offset} #{relationship.source.to_s} #{relation} #{relationship.target.to_s} \n"
|
28
|
+
end
|
29
|
+
else
|
30
|
+
type="Context"
|
31
|
+
str=str+"#{type}: #{context.to_s} \n"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
str
|
35
|
+
end
|
36
|
+
end
|
data/spec/context_spec.rb
CHANGED
@@ -5,6 +5,7 @@ describe Phenomenal::Context do
|
|
5
5
|
before :each do
|
6
6
|
@context = Phenomenal::Context.new(:test)
|
7
7
|
@context2 = Phenomenal::Context.new(:test2)
|
8
|
+
@manager = Phenomenal::Manager.instance
|
8
9
|
end
|
9
10
|
|
10
11
|
after :each do
|
@@ -34,7 +35,9 @@ describe Phenomenal::Context do
|
|
34
35
|
end
|
35
36
|
|
36
37
|
it "should be anonymous if the name wasn't set" do
|
37
|
-
Phenomenal::Context.new
|
38
|
+
context = Phenomenal::Context.new
|
39
|
+
context.name.should be_nil
|
40
|
+
force_forget_context(context)
|
38
41
|
end
|
39
42
|
|
40
43
|
it "should be anonymous if it is the default context" do
|
@@ -42,24 +45,76 @@ describe Phenomenal::Context do
|
|
42
45
|
end
|
43
46
|
end
|
44
47
|
|
45
|
-
describe ".create" do
|
46
|
-
pending "TODO"
|
47
|
-
end
|
48
|
-
|
49
48
|
describe "#forget" do
|
50
|
-
|
49
|
+
it "should raise an error if the context is active" do
|
50
|
+
@context.activate
|
51
|
+
expect{@context.forget}.to raise_error Phenomenal::Error
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should unregister the context from the manager" do
|
55
|
+
@context.forget
|
56
|
+
@manager.contexts[@context].should be_nil
|
57
|
+
@context = Phenomenal::Context.new(:test)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should raise an error if used after being forgotted" do
|
61
|
+
@context.forget
|
62
|
+
expect{@context.activate}.to raise_error Phenomenal::Error
|
63
|
+
@context = Phenomenal::Context.new(:test)
|
64
|
+
end
|
51
65
|
end
|
52
66
|
|
53
67
|
describe "#add_adaptation" do
|
54
|
-
|
68
|
+
it "should save the default behavior in the default context" do
|
69
|
+
@context.add_adaptation(TestString, :size,true) do
|
70
|
+
42
|
71
|
+
end
|
72
|
+
a = phen_default_context.adaptations.find{|a| a.concern?(TestString,:size,true)}
|
73
|
+
a.bind(TestString.new("1234")).should==4
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should activate the adaptation if the context is active"do
|
77
|
+
string = TestString.new("1234")
|
78
|
+
string.size.should==4
|
79
|
+
@context.activate
|
80
|
+
string.size.should==4
|
81
|
+
@context.add_adaptation(TestString, :size,true) do
|
82
|
+
42
|
83
|
+
end
|
84
|
+
string.size.should==42
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should not activate the adaptation if the context is inactive"do
|
88
|
+
string = TestString.new("1234")
|
89
|
+
string.size.should==4
|
90
|
+
@context.add_adaptation(TestString, :size,true) do
|
91
|
+
42
|
92
|
+
end
|
93
|
+
string.size.should==4
|
94
|
+
end
|
55
95
|
end
|
56
96
|
|
57
97
|
describe "#remove_adaptation" do
|
58
|
-
|
98
|
+
it "should deactivate the adaptation if the context is active" do
|
99
|
+
string = TestString.new("1234")
|
100
|
+
string.size.should==4
|
101
|
+
@context.activate
|
102
|
+
@context.add_adaptation(TestString, :size,true) do
|
103
|
+
42
|
104
|
+
end
|
105
|
+
string.size.should==42
|
106
|
+
phen_remove_adaptation(:test, TestString, :size)
|
107
|
+
string.size.should==4
|
108
|
+
context(:test).active?.should be_true
|
109
|
+
end
|
59
110
|
end
|
60
111
|
|
61
112
|
describe "#context" do
|
62
|
-
|
113
|
+
it "should create a combined context of itself and the argument context" do
|
114
|
+
c = phen_context(:test).context(:new_context)
|
115
|
+
phen_context(:test,:new_context).should==c
|
116
|
+
force_forget_context(:new_context)
|
117
|
+
end
|
63
118
|
|
64
119
|
describe "#phen_context" do
|
65
120
|
it "should be an alias of #context" do
|
@@ -69,7 +124,11 @@ describe Phenomenal::Context do
|
|
69
124
|
end
|
70
125
|
|
71
126
|
describe "#feature" do
|
72
|
-
|
127
|
+
it "should create a combined context of itself and the feature" do
|
128
|
+
c = phen_context(:test).feature(:new_feature)
|
129
|
+
phen_context(:test).feature(:new_feature).should==c
|
130
|
+
force_forget_context(:new_feature)
|
131
|
+
end
|
73
132
|
|
74
133
|
describe "#phen_feature" do
|
75
134
|
it "should be an alias of #feature" do
|
@@ -79,19 +138,28 @@ describe Phenomenal::Context do
|
|
79
138
|
end
|
80
139
|
|
81
140
|
describe "#add_adaptations" do
|
82
|
-
|
141
|
+
it "should be able to adapt multiple instance method" do
|
142
|
+
@context.should respond_to :add_adaptations
|
143
|
+
end
|
83
144
|
end
|
84
145
|
|
85
146
|
describe "#adapatations_for" do
|
86
|
-
|
147
|
+
it "should set the current adapted class" do
|
148
|
+
@context.adaptations_for String
|
149
|
+
@context.instance_variable_get("@current_adapted_class").should == String
|
150
|
+
end
|
87
151
|
end
|
88
152
|
|
89
153
|
describe "#adapt" do
|
90
|
-
|
154
|
+
it "should be able to adapt an instance method" do
|
155
|
+
@context.should respond_to :adapt
|
156
|
+
end
|
91
157
|
end
|
92
158
|
|
93
|
-
describe "#
|
94
|
-
|
159
|
+
describe "#adapt_class" do
|
160
|
+
it "should be able to adapt a method" do
|
161
|
+
@context.should respond_to :adapt_class
|
162
|
+
end
|
95
163
|
end
|
96
164
|
|
97
165
|
|
@@ -189,14 +257,6 @@ describe Phenomenal::Context do
|
|
189
257
|
end
|
190
258
|
|
191
259
|
describe "#anonymous?" do
|
192
|
-
after do
|
193
|
-
force_forget_context(@context3)
|
194
|
-
end
|
195
|
-
it "should be true when the context has no name" do
|
196
|
-
@context3 = Phenomenal::Context.new
|
197
|
-
@context3.anonymous?.should be_true
|
198
|
-
end
|
199
|
-
|
200
260
|
it "should be false when the context has a name" do
|
201
261
|
@context.anonymous?.should be_false
|
202
262
|
end
|
@@ -204,6 +264,12 @@ describe Phenomenal::Context do
|
|
204
264
|
it "should be true for the default context" do
|
205
265
|
Phenomenal::Manager.instance.default_context.anonymous?.should be_true
|
206
266
|
end
|
267
|
+
|
268
|
+
it "should be true when the context has no name" do
|
269
|
+
@context3 = Phenomenal::Context.new
|
270
|
+
@context3.anonymous?.should be_true
|
271
|
+
force_forget_context(@context3)
|
272
|
+
end
|
207
273
|
end
|
208
274
|
|
209
275
|
describe "#information" do
|
@@ -235,13 +301,12 @@ describe Phenomenal::Context do
|
|
235
301
|
@context.activate
|
236
302
|
@context.information[:activation_count].should==1
|
237
303
|
end
|
238
|
-
|
239
|
-
force_forget_context(@feature)
|
240
|
-
end
|
304
|
+
|
241
305
|
it "should have a matching :type field" do
|
242
306
|
@context.information[:type].should=="Phenomenal::Context"
|
243
307
|
@feature = Phenomenal::Feature.new
|
244
308
|
@feature.information[:type].should=="Phenomenal::Feature"
|
309
|
+
force_forget_context(@feature)
|
245
310
|
end
|
246
311
|
|
247
312
|
|
@@ -260,8 +325,9 @@ describe Phenomenal::Context do
|
|
260
325
|
end
|
261
326
|
end
|
262
327
|
c.parent_feature.should be f
|
263
|
-
|
328
|
+
|
264
329
|
f.forget
|
330
|
+
context(:c).forget
|
265
331
|
end
|
266
332
|
end
|
267
333
|
end
|