graph_mediator 0.2.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.
@@ -0,0 +1,59 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ describe "mediated_transactions in different threads" do
4
+
5
+ before(:all) do
6
+ ActiveRecord::Base.establish_connection({'adapter' => 'sqlite3', 'database' => 'thread-test'})
7
+ end
8
+
9
+ after(:all) do
10
+ ActiveRecord::Base.establish_connection({'adapter' => 'sqlite3', 'database' => ':memory:'})
11
+ end
12
+
13
+ before(:each) do
14
+ load_traceable_callback_tester
15
+ @t = Traceable.new(:name => :gizmo)
16
+ @t.save_without_mediation!
17
+ end
18
+
19
+ after(:each) do
20
+ Object.__send__(:remove_const, :Traceable)
21
+ end
22
+
23
+ # This will produce two warnings regarding overlapping transactions
24
+ it "should be different instances" do
25
+ objectid1, objectid2 = nil, nil
26
+ mediator1, mediator2 = nil, nil
27
+
28
+ # puts 'start thread 1'
29
+ thread1 = Thread.new do
30
+ t1 = Traceable.find(@t.id)
31
+ # puts 'preparing to mediate transaction on thread 1'
32
+ mediator1 = t1.__send__(:_get_mediator)
33
+ # puts 'mediating transaction on thread 1'
34
+ Kernel.sleep(2)
35
+ # puts 'thread 1 finished'
36
+ end
37
+
38
+ # puts 'sleeping kernel 1'
39
+ Kernel.sleep(1)
40
+
41
+ # puts 'start thread 2'
42
+ thread2 = Thread.new do
43
+ t2 = Traceable.find(@t.id)
44
+ # puts 'preparing to mediate transaction on thread 2'
45
+ mediator2 = t2.__send__(:_get_mediator)
46
+ # puts 'mediating transaction on thread 2'
47
+ Kernel.sleep(1)
48
+ # puts 'thread 2 finished'
49
+ end
50
+
51
+ # puts 'finishing thread 1'
52
+ thread1.join
53
+ # puts 'finishing thread 2'
54
+ thread2.join
55
+ # pp mediator1, mediator2
56
+ mediator1.should_not equal(mediator2)
57
+ end
58
+
59
+ end
@@ -0,0 +1,19 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ describe "GraphMediator validation scenarios" do
4
+
5
+ before(:each) do
6
+ load_traceable_callback_tester
7
+ end
8
+
9
+ after(:each) do
10
+ Object.__send__(:remove_const, :Traceable)
11
+ end
12
+
13
+ it "should not call after_mediation if validation fails" do
14
+ t = Traceable.new
15
+ t.save.should == false
16
+ @traceables_callbacks.should == [:before]
17
+ end
18
+
19
+ end
@@ -0,0 +1,170 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ module AliasMethodChainSpec # namespacing
4
+
5
+ describe "alias method chain" do
6
+
7
+ module ModifiedAliasMethodChain
8
+ # From Tammo Freese's patch:
9
+ # https://rails.lighthouseapp.com/projects/8994/tickets/285-alias_method_chain-limits-extensibility
10
+ def alias_method_chain(target, feature)
11
+ punctuation = nil
12
+ with_method, without_method = "#{target}_with_#{feature}#{punctuation}", "#{target}_without_#{feature}#{punctuation}"
13
+
14
+ method_defined_here = (instance_methods(false) + private_instance_methods(false)).include?(RUBY_VERSION < '1.9' ? target.to_s : target)
15
+ unless method_defined_here
16
+ module_eval <<-EOS
17
+ def #{target}(*args, &block)
18
+ super
19
+ end
20
+ EOS
21
+ end
22
+
23
+ alias_method without_method, target
24
+ # alias_method target, with_method
25
+
26
+ target_method_exists = (instance_methods + private_instance_methods).include?(RUBY_VERSION < '1.9' ? with_method : with_method.to_sym)
27
+ raise NameError unless target_method_exists
28
+
29
+ module_eval <<-EOS
30
+ def #{target}(*args, &block)
31
+ self.__send__(:'#{with_method}', *args, &block)
32
+ end
33
+ EOS
34
+ end
35
+ end
36
+
37
+ module BasicAliasMethodChain
38
+ def alias_method_chain(target, feature)
39
+ punctuation = nil
40
+ with_method, without_method = "#{target}_with_#{feature}#{punctuation}", "#{target}_without_#{feature}#{punctuation}"
41
+ alias_method without_method, target
42
+ alias_method target, with_method
43
+ end
44
+ end
45
+
46
+ module Bar
47
+ def bar
48
+ 'bar'
49
+ end
50
+ end
51
+
52
+ module Baz
53
+ def baz
54
+ 'baz'
55
+ end
56
+ end
57
+
58
+ module BazWithLess
59
+ def self.included(base)
60
+ base.alias_method_chain :baz, :less
61
+ end
62
+
63
+ def baz_with_less
64
+ baz_without_less + ' less'
65
+ end
66
+ end
67
+
68
+ class Foo
69
+ extend ModifiedAliasMethodChain
70
+ include Bar
71
+
72
+ def foo_with_more
73
+ foo_without_more + ' more'
74
+ end
75
+
76
+ def foo
77
+ 'foo'
78
+ end
79
+ alias_method_chain :foo, :more
80
+
81
+ def bar_with_less
82
+ bar_without_less + ' less'
83
+ end
84
+ alias_method_chain :bar, :less
85
+
86
+ include Baz
87
+ include BazWithLess
88
+ end
89
+
90
+ class FooBasic
91
+ extend BasicAliasMethodChain
92
+ include Bar
93
+
94
+ def foo_with_more
95
+ foo_without_more + ' more'
96
+ end
97
+
98
+ def foo
99
+ 'foo'
100
+ end
101
+ alias_method_chain :foo, :more
102
+
103
+ def bar_with_less
104
+ bar_without_less + ' less'
105
+ end
106
+ alias_method_chain :bar, :less
107
+
108
+ include Baz
109
+ include BazWithLess
110
+ end
111
+
112
+ it "test modified alias method chain" do
113
+ f = Foo.new
114
+ f.foo.should == 'foo more'
115
+ f.foo_without_more.should == 'foo'
116
+ f.foo_with_more.should == 'foo more'
117
+ f.bar.should == 'bar less'
118
+ f.bar_without_less.should == 'bar'
119
+ f.bar_with_less.should == 'bar less'
120
+ f.baz.should == 'baz less'
121
+ f.baz_without_less.should == 'baz'
122
+ f.baz_with_less.should == 'baz less'
123
+ Bar.class_eval do
124
+ def bar
125
+ 'new bar'
126
+ end
127
+ end
128
+ f.bar.should == 'new bar less'
129
+ f.bar_without_less.should == 'new bar'
130
+ f.bar_with_less.should == 'new bar less'
131
+ Foo.class_eval do
132
+ def baz_with_less
133
+ 'lesser'
134
+ end
135
+ end
136
+ f.baz_without_less.should == 'baz'
137
+ f.baz_with_less.should == 'lesser'
138
+ f.baz.should == 'lesser'
139
+ end
140
+
141
+ it "test basic alias method chain" do
142
+ f = FooBasic.new
143
+ f.foo.should == 'foo more'
144
+ f.foo_without_more.should == 'foo'
145
+ f.foo_with_more.should == 'foo more'
146
+ f.bar.should == 'bar less'
147
+ f.bar_without_less.should == 'bar'
148
+ f.bar_with_less.should == 'bar less'
149
+ Bar.class_eval do
150
+ def bar
151
+ 'new bar'
152
+ end
153
+ end
154
+ # no change
155
+ f.bar.should == 'bar less'
156
+ f.bar_without_less.should == 'bar'
157
+ f.bar_with_less.should == 'bar less'
158
+ Foo.class_eval do
159
+ def baz_with_less
160
+ raise
161
+ end
162
+ end
163
+ # no error
164
+ f.baz_without_less.should == 'baz'
165
+ f.baz_with_less.should == 'baz less'
166
+ f.baz.should == 'baz less'
167
+ end
168
+ end
169
+
170
+ end
@@ -0,0 +1,122 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ require 'investigation/self_decorating'
4
+
5
+ module DecoratingSubclassSpec # namespacing
6
+
7
+ describe "Decorating by extending object eigenclass" do
8
+
9
+ module Other
10
+
11
+ def dingo
12
+ super
13
+ end
14
+ # super fails in dingo_without_other (see above)
15
+ alias_method :dingo_without_other, :dingo
16
+
17
+ def dingo
18
+ super + " other"
19
+ end
20
+
21
+ def bat
22
+ 'bat'
23
+ end
24
+ end
25
+
26
+ class SuperClass
27
+ def dingo
28
+ 'dingo'
29
+ end
30
+ end
31
+
32
+ def reload_bar
33
+ Object.send(:remove_const, :Bar) if Object.const_defined?(:Bar)
34
+ instance_eval <<EOS
35
+ module ::Bar
36
+ def bar
37
+ 'modular bar'
38
+ end
39
+ end
40
+ EOS
41
+ end
42
+
43
+ class SubClass < SuperClass; end
44
+
45
+ before(:each) do
46
+ reload_bar
47
+ end
48
+
49
+ after(:all) do
50
+ Object.__send__(:remove_const, :Bar)
51
+ end
52
+
53
+ it "should extend Foo::Secret" do
54
+ f = SelfDecorating.new
55
+ f.foo.should == 'foo'
56
+ end
57
+
58
+ context "with a new SelfDecorating" do
59
+
60
+ before(:each) do
61
+ load('investigation/self_decorating.rb')
62
+ end
63
+
64
+ after(:each) do
65
+ Object.send(:remove_const, :SelfDecorating)
66
+ end
67
+
68
+ it "should be able to decorate methods in base after they are defined" do
69
+ SelfDecorating.send(:define_method, :bar) { 'bar' }
70
+ SelfDecorating.decorate :bar
71
+ f = SelfDecorating.new
72
+ f.bar.should == 'bar with secret'
73
+ f.bar_without_secret.should == 'bar'
74
+ end
75
+
76
+ it "should be able to decorate methods in Secret before they are defined" do
77
+ SelfDecorating.decorate :bar
78
+ SelfDecorating.send(:define_method, :bar) { 'bar' }
79
+ f = SelfDecorating.new
80
+ f.bar.should == 'bar with secret'
81
+ f.bar_without_secret.should == 'bar'
82
+ end
83
+
84
+ it "should not interfere with overrides in superclasses" do
85
+ SelfDecorating.class_eval { include Bar }
86
+ SelfDecorating.decorate :bar
87
+ f = SelfDecorating.new
88
+ f.bar.should == 'modular bar with secret'
89
+ f.bar_without_secret.should == 'modular bar'
90
+ Bar.class_eval { def bar; 'new bar'; end }
91
+ f.bar_without_secret.should == 'new bar'
92
+ f.bar.should == 'new bar with secret'
93
+ end
94
+
95
+ it "should not interfere with overrides in the base class" do
96
+ SelfDecorating.class_eval do
97
+ include Bar
98
+ def bar
99
+ "locally " + super
100
+ end
101
+ end
102
+ SelfDecorating.decorate :bar
103
+ f = SelfDecorating.new
104
+ f.bar.should == 'locally modular bar with secret'
105
+ f.bar_without_secret.should == 'locally modular bar'
106
+ end
107
+
108
+ end
109
+
110
+ it "should test overriding superclass methods in a module" do
111
+ s = SubClass.new
112
+ s.dingo.should == 'dingo'
113
+ SubClass.send(:include, Other)
114
+ s.dingo.should == 'dingo other'
115
+ # 1.8 bug - aliased method that calls super in a module
116
+ # http://redmine.ruby-lang.org/issues/show/734
117
+ lambda { s.dingo_without_other }.should raise_error(NoMethodError)
118
+ s.bat.should == 'bat'
119
+ end
120
+ end
121
+
122
+ end
@@ -0,0 +1,131 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ module InsertingSuperClassSpec # namespacing
4
+
5
+ describe "insert superclass" do
6
+
7
+ module Decorator
8
+ def decorate(*methods)
9
+ methods.each do |m|
10
+ alias_method "#{m}_without_decoration", m
11
+ define_method(m) do |*args,&block|
12
+ super + " decorated"
13
+ end
14
+ end
15
+ end
16
+ end
17
+
18
+ def reload_foo
19
+ [:Bar, :Foo, :SubFoo].each { |c| Object.send(:remove_const, c) if Object.const_defined?(c) }
20
+ instance_eval <<EOS
21
+ module ::Bar
22
+ def second; 'bar second'; end
23
+ end
24
+
25
+ module Baz
26
+ def super_method
27
+ 'super'
28
+ end
29
+ end
30
+
31
+ class ::Foo
32
+ extend Decorator
33
+ include Bar
34
+ include Baz
35
+ module DecorateMe
36
+ def first; 'first'; end
37
+ def second; super + ' overridden'; end
38
+ def third; 'third'; end
39
+ end
40
+ include DecorateMe
41
+
42
+ def local
43
+ 'local'
44
+ end
45
+
46
+ decorate :first, :second, :third, :super_method, :local
47
+
48
+ def third
49
+ 'broken'
50
+ end
51
+ end
52
+
53
+ class ::SubFoo < Foo
54
+ def first
55
+ 'sub ' + super
56
+ end
57
+ def first_without_decoration
58
+ 'sub ' + super
59
+ end
60
+ def second
61
+ 'sub ' + super
62
+ end
63
+ def second_without_decoration
64
+ 'sub ' + super
65
+ end
66
+ end
67
+ EOS
68
+ end
69
+
70
+ before(:each) do
71
+ reload_foo
72
+ end
73
+
74
+ after(:all) do
75
+ Object.__send__(:remove_const, :Bar)
76
+ Object.__send__(:remove_const, :Foo)
77
+ end
78
+
79
+ it "should decorate the declared methods" do
80
+ f = Foo.new
81
+ f.first.should == "first decorated"
82
+ f.first_without_decoration.should == "first"
83
+ end
84
+
85
+ it "should decorate superclass methods not declared in DecorateMe" do
86
+ # the same case as the DecorateMe module
87
+ f = Foo.new
88
+ f.super_method.should == "super decorated"
89
+ f.super_method_without_decoration.should == "super"
90
+ end
91
+
92
+ it "should not interfere with overrides of superclass methods in DecorateMe" do
93
+ f = Foo.new
94
+ f.second.should == "bar second overridden decorated"
95
+ f.second_without_decoration.should == "bar second overridden"
96
+ end
97
+
98
+ it "has the issue that it raises errors attempting to decorate methods defined only in the base class" do
99
+ f = Foo.new
100
+ lambda { f.local }.should raise_error(NoMethodError) # not .should == 'local decorated'
101
+ f.local_without_decoration.should.should == 'local'
102
+ end
103
+
104
+ it "has the issue that overrides in base class override decoration" do
105
+ f = Foo.new
106
+ f.third.should == 'broken' # not 'broken decorated'
107
+ f.third_without_decoration.should == 'third'
108
+ end
109
+
110
+ it "should not interfere with external overrides of superclasses methods" do
111
+ Bar.class_eval { def second; 'external'; end }
112
+ f = Foo.new
113
+ f.second.should == 'external overridden decorated'
114
+ f.second_without_decoration.should == 'external overridden'
115
+ end
116
+
117
+ it "should allow subclasses to override decoration" do
118
+ f = SubFoo.new
119
+ f.first.should == 'sub first decorated'
120
+ f.second.should == 'sub bar second overridden decorated'
121
+ end
122
+
123
+ it "should allow subclasses to override methods without decoration" do
124
+ f = SubFoo.new
125
+ f.first_without_decoration.should == 'sub first'
126
+ f.second_without_decoration.should == 'sub bar second overridden'
127
+ end
128
+
129
+ end
130
+
131
+ end