phenomenal 0.9.0 → 0.11.11.24.3

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 (50) hide show
  1. data/LICENSE +1 -1
  2. data/README +4 -3
  3. data/Rakefile +0 -3
  4. data/demo.rb +24 -0
  5. data/demo_age.rb +89 -0
  6. data/demo_dsl.rb +28 -0
  7. data/lib/phenomenal.rb +2 -15
  8. data/lib/phenomenal/adaptation.rb +12 -22
  9. data/lib/phenomenal/context.rb +134 -127
  10. data/lib/phenomenal/dsl.rb +14 -41
  11. data/lib/phenomenal/logger.rb +1 -0
  12. data/lib/phenomenal/manager.rb +35 -117
  13. data/phenomenal.gemspec +15 -0
  14. data/{spec → test}/test_classes.rb +0 -3
  15. data/test/test_cop_adaptation.rb +168 -0
  16. data/test/test_cop_composition.rb +84 -0
  17. data/test/test_cop_conflictpolicy.rb +177 -0
  18. data/test/test_cop_infrastructure.rb +129 -0
  19. data/test_declaration.rb +18 -0
  20. metadata +29 -70
  21. data/lib/phenomenal/feature.rb +0 -8
  22. data/lib/phenomenal/relationships/context_relationships.rb +0 -22
  23. data/lib/phenomenal/relationships/dsl.rb +0 -18
  24. data/lib/phenomenal/relationships/feature_relationships.rb +0 -42
  25. data/lib/phenomenal/relationships/implication.rb +0 -35
  26. data/lib/phenomenal/relationships/relationship.rb +0 -42
  27. data/lib/phenomenal/relationships/relationships_manager.rb +0 -63
  28. data/lib/phenomenal/relationships/relationships_store.rb +0 -73
  29. data/lib/phenomenal/relationships/requirement.rb +0 -26
  30. data/lib/phenomenal/relationships/suggestion.rb +0 -41
  31. data/lib/phenomenal/version.rb +0 -3
  32. data/spec/adaptation_spec.rb +0 -64
  33. data/spec/behavior/adaptation_spec.rb +0 -5
  34. data/spec/behavior/combined_contexts_spec.rb +0 -5
  35. data/spec/behavior/composition_spec.rb +0 -5
  36. data/spec/behavior/conflict_policy_spec.rb +0 -5
  37. data/spec/behavior/open_context.rb +0 -5
  38. data/spec/behavior/relationships_spec.rb +0 -249
  39. data/spec/context_spec.rb +0 -268
  40. data/spec/dsl_spec.rb +0 -181
  41. data/spec/feature_spec.rb +0 -5
  42. data/spec/manager_spec.rb +0 -84
  43. data/spec/proc_spec.rb +0 -20
  44. data/spec/relationships/context_relationships_spec.rb +0 -13
  45. data/spec/relationships/dsl_spec.rb +0 -13
  46. data/spec/relationships/feature_relationships_spec.rb +0 -13
  47. data/spec/relationships/relationship_spec.rb +0 -31
  48. data/spec/relationships/relationships_manager_spec.rb +0 -15
  49. data/spec/relationships/relationships_store_spec.rb +0 -19
  50. data/spec/spec_helper.rb +0 -18
@@ -1,8 +0,0 @@
1
- class Phenomenal::Feature < Phenomenal::Context
2
- include Phenomenal::FeatureRelationships
3
-
4
- def initialize(name=nil,manager=nil)
5
- super(name,manager)
6
- initialize_relationships
7
- end
8
- end
@@ -1,22 +0,0 @@
1
- module Phenomenal::ContextRelationships
2
- def requires(context,*contexts)
3
- contexts = contexts.push(context)
4
- contexts.each do |target|
5
- self.parent_feature.requirements_for(self,{:on=>target})
6
- end
7
- end
8
-
9
- def implies(context,*contexts)
10
- contexts = contexts.push(context)
11
- contexts.each do |target|
12
- self.parent_feature.implications_for(self,{:on=>target})
13
- end
14
- end
15
-
16
- def suggests(context,*contexts)
17
- contexts = contexts.push(context)
18
- contexts.each do |target|
19
- self.parent_feature.suggestions_for(self,{:on=>target})
20
- end
21
- end
22
- end
@@ -1,18 +0,0 @@
1
- module Phenomenal::DSL
2
- def self.define_relationships(klass)
3
- klass.class_eval do
4
- # Requirements
5
- def requirements_for(source,targets)
6
- Phenomenal::Manager.instance.default_context.requirements_for(source,targets)
7
- end
8
- # Implications
9
- def implications_for(source,targets)
10
- Phenomenal::Manager.instance.default_context.implications_for(source,targets)
11
- end
12
- # Suggestions
13
- def suggestions_for(source,targets)
14
- Phenomenal::Manager.instance.default_context.suggestions_for(source,targets)
15
- end
16
- end
17
- end
18
- end
@@ -1,42 +0,0 @@
1
- module Phenomenal::FeatureRelationships
2
- attr_accessor :relationships
3
-
4
- def initialize_relationships
5
- @relationships = Array.new
6
- end
7
-
8
- def requirements_for(source,targets)
9
- add_relationship(source,targets,Phenomenal::Requirement)
10
- end
11
-
12
- def implications_for(source,targets)
13
- add_relationship(source,targets,Phenomenal::Implication)
14
- end
15
-
16
- def suggestions_for(source,targets)
17
- add_relationship(source,targets,Phenomenal::Suggestion)
18
- end
19
-
20
- private
21
- def add_relationship(source,targets,type)
22
- targets[:on]=Array.new.push(targets[:on]) if !targets[:on].is_a?(Array)
23
-
24
- if targets[:on].nil?
25
- Phenomenal::Logger.instance.error(
26
- "Invalid relationship, missing target context"
27
- )
28
- end
29
- targets[:on].each do |target|
30
- r = type.new(source,target,self)
31
- if relationships.find{|o| o==r}.nil?
32
- relationships.push(r)
33
- if self.active?
34
- r.refresh
35
- manager.rmanager.relationships.add(r)
36
- r.activate_feature
37
- end
38
- end
39
- end
40
-
41
- end
42
- end
@@ -1,35 +0,0 @@
1
- class Phenomenal::Implication < Phenomenal::Relationship
2
- attr_accessor :activation_counter
3
- def initialize(source,target,feature)
4
- super(source,target,feature)
5
- @activation_counter=0
6
- end
7
-
8
- def activate_feature
9
- if source.active?
10
- target.activate
11
- activation_counter+=1
12
- end
13
- end
14
-
15
- def deactivate_feature
16
- if activation_counter>0
17
- target.deactivate
18
- activation_coutner-=1
19
- end
20
- end
21
-
22
- def activate_context(context)
23
- if source==context
24
- target.activate
25
- end
26
- end
27
-
28
- def deactivate_context(context)
29
- if source==context
30
- target.deactivate
31
- else
32
- source.deactivate
33
- end
34
- end
35
- end
@@ -1,42 +0,0 @@
1
- class Phenomenal::Relationship
2
- attr_accessor :source,:target,:manager,:feature
3
-
4
- def initialize(source,target,feature)
5
- @source=source
6
- @target=target
7
- @manager=Phenomenal::Manager.instance
8
- @feature=feature
9
- refresh
10
- end
11
-
12
- def ==(other)
13
- self.class==other.class &&
14
- self.source==other.source &&
15
- self.target==other.target &&
16
- self.feature==other.feature
17
- end
18
-
19
- def refresh
20
- s = manager.context_defined?(source)
21
- self.source=s if !s.nil?
22
-
23
- t = manager.context_defined?(target)
24
- self.target=t if !t.nil?
25
- end
26
-
27
- def activate_context(context)
28
- end
29
-
30
- def deactivate_context(context)
31
- end
32
-
33
- def activate_feature
34
- end
35
-
36
- def deactivate_feature
37
- end
38
-
39
- def to_s
40
- "#{self.class.name} between #{source.class.name}:#{source} and #{target.class.name}:#{target}"
41
- end
42
- end
@@ -1,63 +0,0 @@
1
- require 'singleton'
2
-
3
- class Phenomenal::RelationshipsManager
4
- include Singleton
5
-
6
- attr_accessor :relationships
7
-
8
- def activate_relationships(context)
9
- # Step 1: Import the new relationships for a feature
10
- if context.is_a?(Phenomenal::Feature)
11
- import_relationships(context)
12
- end
13
- # Step 2: Apply relationships
14
- relationships.get_for(context).each do |relationship|
15
- relationship.activate_context(context)
16
- end
17
- end
18
-
19
- def deactivate_relationships(context)
20
- # Step 1: Unapply relationships
21
- relationships.get_for(context).each do |relationship|
22
- relationship.deactivate_context(context)
23
- end
24
- # Step 2: Remove relationships
25
- if context.is_a?(Phenomenal::Feature)
26
- remove_relationships(context)
27
- end
28
- end
29
-
30
- # Called when a context is defined in the manager
31
- def update_relationships_references(context)
32
- relationships.update_references(context)
33
- end
34
-
35
- private
36
- def import_relationships(feature)
37
- begin
38
- feature.relationships.each do |relationship|
39
- relationship.refresh # Update references
40
- relationship.activate_feature # Activate relationship
41
- relationships.add(relationship)
42
- end
43
- rescue Phenomenal::Error => m
44
- feature.deactivate
45
- Phenomenal::Logger.instance.debug(
46
- "Unable to activate the feature #{feature} \n #{m}"
47
- )
48
- end
49
- end
50
-
51
- def remove_relationships(feature)
52
- feature.relationships.each do |relationship|
53
- if relationships.include?(relationship)
54
- relationship.deactivate_feature
55
- relationships.remove(relationship)
56
- end
57
- end
58
- end
59
-
60
- def initialize
61
- @relationships = Phenomenal::RelationshipsStore.new
62
- end
63
- end
@@ -1,73 +0,0 @@
1
- class Phenomenal::RelationshipsStore
2
- attr_accessor :sources, :targets
3
-
4
- def initialize
5
- @sources = {}
6
- @targets = {}
7
- end
8
-
9
- def add(relationship)
10
- if @sources[relationship.source].nil?
11
- @sources[relationship.source] = Array.new
12
- end
13
- @sources[relationship.source].push(relationship)
14
-
15
- if @targets[relationship.target].nil?
16
- @targets[relationship.target] = Array.new
17
- end
18
- @targets[relationship.target].push(relationship)
19
- end
20
-
21
- def remove(relationship)
22
- @sources[relationship.source].delete(relationship) if @sources[relationship.source] # In case of rollback
23
- @targets[relationship.target].delete(relationship) if @targets[relationship.target]
24
- end
25
-
26
- def include?(relationship)
27
- if @sources[relationship.source]
28
- @sources[relationship.source].include?(relationship)
29
- else
30
- false
31
- end
32
- end
33
-
34
- def update_references(context)
35
- # Do nothing when anonymous, references are already valid
36
- return if context.anonymous?
37
- # Update sources
38
- @sources[context.name].each do |relationship|
39
- relationship.source=context
40
- end
41
- @sources[context]=@source.delete(context.name)
42
- # Update targets
43
- @targets[context.name].each do |relationship|
44
- relationship.target=context
45
- end
46
- @targets[context]=@targets.delete(context.name)
47
- end
48
-
49
- def get_for(context)
50
- get_for_source(context).concat(get_for_target(context))
51
- end
52
-
53
- private
54
- # Return an array of relationships
55
- def get_for_source(source)
56
- rel = @sources[source]
57
- if rel.nil?
58
- Array.new
59
- else
60
- rel
61
- end
62
- end
63
-
64
- # Return an array of relationships
65
- def get_for_target(target)
66
- rel = @targets[target]
67
- if rel.nil?
68
- Array.new
69
- else
70
- rel
71
- end
72
- end
73
- end
@@ -1,26 +0,0 @@
1
- class Phenomenal::Requirement < Phenomenal::Relationship
2
- def activate_feature
3
- check_requirement
4
- end
5
-
6
- def activate_context(context)
7
- if(source==context)
8
- check_requirement
9
- end
10
- end
11
-
12
- def deactivate_context(context)
13
- if(target==context)
14
- source.deactivate
15
- end
16
- end
17
-
18
- private
19
- def check_requirement
20
- if source.active? && !target.active?
21
- Phenomenal::Logger.instance.error(
22
- "Requirement of #{target} for #{source} is not satisfied"
23
- )
24
- end
25
- end
26
- end
@@ -1,41 +0,0 @@
1
- class Phenomenal::Suggestion < Phenomenal::Relationship
2
- attr_accessor :activation_counter
3
-
4
- def initialize(source,target,feature)
5
- super(source,target,feature)
6
- @activation_counter=0
7
- end
8
-
9
- def activate_feature
10
- begin
11
- if source.active?
12
- target.activate
13
- self.activation_counter+=1
14
- end
15
- rescue
16
- end
17
- end
18
-
19
- def deactivate_feature
20
- begin
21
- if activation_counter>0
22
- target.deactivate
23
- self.activation_coutner-=1
24
- end
25
- rescue
26
- end
27
- end
28
-
29
-
30
- def activate_context(context)
31
- if source==context
32
- target.activate
33
- end
34
- end
35
-
36
- def deactivate_context(context)
37
- if source==context
38
- target.deactivate
39
- end
40
- end
41
- end
@@ -1,3 +0,0 @@
1
- module Phenomenal
2
- VERSION = "0.9.0"
3
- end
@@ -1,64 +0,0 @@
1
- require "spec_helper"
2
- describe Phenomenal::Adaptation do
3
- before :each do
4
- define_test_classes
5
- end
6
-
7
- describe "#deploy" do
8
- it "should be able to deploy itself in instances to override default implementation" do
9
- adaptation = Phenomenal::Adaptation.new(nil,TestString,:length,true,Proc.new{-1})
10
- t = TestString.new("1234")
11
- t.length.should == 4
12
- expect {adaptation.deploy}.to_not raise_error
13
- t.length.should == -1
14
- end
15
-
16
- it "should be able to deploy itself in classes to override default implementation" do
17
- TestString.name.should == "TestString"
18
- adaptation = Phenomenal::Adaptation.new(nil,TestString,:name,false,Proc.new{"TEST"})
19
- expect {adaptation.deploy}.to_not raise_error
20
- TestString.name.should == "TEST"
21
- end
22
- end
23
-
24
- describe "#bind" do
25
- it "should be possible to temporary bind adapation as instance methods" do
26
- adaptation = Phenomenal::Adaptation.new(nil,TestString,:length,true,Proc.new{-10})
27
- t = TestString.new("1234")
28
- t.length.should == -1
29
- adaptation.bind(t).should == -10
30
- t.length.should == -1
31
- end
32
-
33
- it "should be possible to temporary bind adapatation as class methods" do
34
- TestString.name.should == "TEST"
35
- adaptation = Phenomenal::Adaptation.new(nil,TestString,:name,false,Proc.new{"TEST2"})
36
- adaptation.bind(TestString).should == "TEST2"
37
- TestString.name.should == "TEST"
38
- end
39
- end
40
-
41
- describe "#instance_adaptation?" do
42
- it "should return true if the method is a instance method" do
43
- adaptation = Phenomenal::Adaptation.new(nil,TestString,:length,true,Proc.new{-10})
44
- adaptation.instance_adaptation?.should be_true
45
- end
46
-
47
- it "should return false if the method is a class method" do
48
- adaptation = Phenomenal::Adaptation.new(nil,TestString,:name,false,Proc.new{"TEST2"})
49
- adaptation.instance_adaptation?.should be_false
50
- end
51
- end
52
-
53
- describe "#concern" do
54
- it "should return true if the adaptation concern the class n_klass and method n_method and is instance method if instance=true" do
55
- adaptation = Phenomenal::Adaptation.new(nil,TestString,:length,true,Proc.new{-10})
56
- adaptation.concern?(TestString,:length,true).should be_true
57
- end
58
-
59
- it "should return false if the adaptation doesn't concern the class n_klass and method n_method and is instance method if instance=true" do
60
- adaptation = Phenomenal::Adaptation.new(nil,TestString,:size,true,Proc.new{-10})
61
- adaptation.concern?(TestString,:length,true).should be_false
62
- end
63
- end
64
- end