sandthorn 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+ require 'sandthorn/aggregate_root_dirty_hashy'
3
+ require 'benchmark'
4
+
5
+ module Sandthorn
6
+ module AggregateRoot
7
+ class TestClass
8
+ include Sandthorn::AggregateRoot::DirtyHashy
9
+ attr_reader :name
10
+
11
+
12
+ def initialize args = {}
13
+ end
14
+
15
+ def change_name value
16
+ unless name == value
17
+ @name = value
18
+ commit
19
+ end
20
+ end
21
+
22
+ end
23
+
24
+ describe "benchmark" do
25
+
26
+ let(:test_object) {
27
+ o = TestClass.new().save
28
+ o
29
+ }
30
+ n = 500
31
+ it "should new, change_name, save and find 500 aggregates" do
32
+
33
+ Benchmark.bm do |x|
34
+ x.report("new change save find") { for i in 1..n; s = TestClass.new().change_name("benchmark").save(); TestClass.find(s.id); end }
35
+ end
36
+
37
+ end
38
+ it "should find 500 aggregates" do
39
+ Benchmark.bm do |x|
40
+ x.report("find") { for i in 1..n; TestClass.find(test_object.id); end }
41
+ end
42
+ end
43
+ it "should commit 500 actions" do
44
+ Benchmark.bm do |x|
45
+ x.report("commit") { for i in 1..n; test_object.change_name "#{i}"; end }
46
+ end
47
+ end
48
+ it "should commit and save 500 actions" do
49
+ Benchmark.bm do |x|
50
+ x.report("commit save") { for i in 1..n; test_object.change_name("#{i}").save; end }
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+ require 'sandthorn/aggregate_root_dirty_hashy'
3
+ require 'date'
4
+
5
+ class Hello
6
+ attr_reader :foo_bar
7
+ attr_accessor :change_me
8
+
9
+ def initialize foo_bar
10
+ @foo_bar = foo_bar
11
+ end
12
+
13
+ def set_foo_bar value
14
+ @foo_bar = value
15
+ end
16
+ end
17
+
18
+ class IAmComplex
19
+ include Sandthorn::AggregateRoot::DirtyHashy
20
+ attr_reader :a_date
21
+ attr_reader :hello
22
+
23
+ def set_hello! hello
24
+ set_hello_event hello
25
+ end
26
+
27
+ def set_foo_bar_on_hello value
28
+ @hello.set_foo_bar value
29
+ commit value
30
+ end
31
+
32
+
33
+ def initialize date
34
+ @a_date = date
35
+ end
36
+
37
+ private
38
+ def set_hello_event hello
39
+ @hello = hello
40
+ commit hello
41
+ end
42
+
43
+ end
44
+
45
+
46
+ describe 'when using complex types in events' do
47
+ before(:each) do
48
+ aggr = IAmComplex.new Date.new 2012,01,20
49
+ aggr.set_hello! Hello.new "foo"
50
+ @events = aggr.aggregate_events
51
+ end
52
+ it 'should be able to build from events' do
53
+ aggr = IAmComplex.aggregate_build @events
54
+ aggr.a_date.should be_a(Date)
55
+ aggr.hello.should be_a(Hello)
56
+ end
57
+
58
+ it 'should detect hello changing' do
59
+ aggr = IAmComplex.aggregate_build @events
60
+ hello = aggr.hello
61
+ hello.change_me = ["Fantastisk"]
62
+ aggr.set_hello! hello
63
+ hello.change_me << "Otroligt"
64
+ aggr.set_hello! hello
65
+ builded = IAmComplex.aggregate_build aggr.aggregate_events
66
+ builded.hello.change_me.should include "Fantastisk"
67
+ builded.hello.change_me.should include "Otroligt"
68
+ end
69
+
70
+ it 'should detect foo_bar chaning in hello' do
71
+ aggr = IAmComplex.aggregate_build @events
72
+ aggr.set_foo_bar_on_hello "morgan"
73
+
74
+ builded = IAmComplex.aggregate_build aggr.aggregate_events
75
+ builded.hello.foo_bar.should eql "morgan"
76
+ end
77
+ end
Binary file
@@ -0,0 +1,101 @@
1
+ # require 'spec_helper'
2
+ # require 'sandthorn_driver_sequel'
3
+
4
+ # module UnknownModule
5
+ # class Foo
6
+ # include Sandthorn::AggregateRoot
7
+ # end
8
+ # end
9
+ # module Sandthorn
10
+ # class TestContextSwitching
11
+ # attr_reader :foo
12
+ # include Sandthorn::AggregateRoot
13
+ # def change_foo value
14
+ # unless foo == value
15
+ # @foo = foo
16
+ # foo_was_changed
17
+ # end
18
+ # end
19
+ # private
20
+ # def foo_was_changed
21
+ # record_event
22
+ # end
23
+ # end
24
+ # class AnotherContext < TestContextSwitching
25
+ # end
26
+ # describe "when using different contexts configuration" do
27
+ # before(:each) do
28
+ # Sandthorn.configuration = configuration
29
+ # migrate
30
+
31
+ # end
32
+ # let(:configuration) do
33
+ # c = []
34
+ # setup.each do |s|
35
+ # c << { aggregate_pattern: s[:aggregate_pattern], driver: SandthornDriverSequel::SequelDriver.new(url: s[:url], context: s[:context]) }
36
+ # end
37
+ # c
38
+ # end
39
+ # let(:migrate) do
40
+ # setup.each do |s|
41
+ # migrator = SandthornDriverSequel::Migration.new url: s[:url], context: s[:context]
42
+ # migrator.migrate!
43
+ # migrator.send(:clear_for_test)
44
+ # end
45
+ # end
46
+ # let(:setup) do
47
+ # [
48
+ # { url: spec_db, context: :context_test, aggregate_pattern: Sandthorn::TestContextSwitching },
49
+ # { url: spec_db, context: :nil, aggregate_pattern: Sandthorn }
50
+ # ]
51
+ # end
52
+ # let(:create_in_context_test) { t = TestContextSwitching.new; t.change_foo :hello_context_1; t.aggregate_save; t;}
53
+ # let(:create_in_default_context) { t = AnotherContext.new; t.change_foo :hello_default_context; t.aggregate_save; t;}
54
+ # def exists_in_context? aggregate, context = nil
55
+ # driver = SandthornDriverSequel::SequelDriver.new url: spec_db
56
+ # table = "aggregates"
57
+ # table = "#{context}_#{table}" if context
58
+ # driver.execute do |db|
59
+ # return db[table.to_sym].where(aggregate_id: aggregate.aggregate_id).any?
60
+ # end
61
+ # end
62
+ # context "when trying to access an aggregate in a non configured context" do
63
+ # it "should raise configuration error" do
64
+ # expect { UnknownModule::Foo.find "boo" }.to raise_exception Sandthorn::Errors::ConfigurationError
65
+ # end
66
+ # end
67
+ # context "when saving the aggregates" do
68
+ # context "it should find the aggregates in separate contexts" do
69
+ # it "should find TestContextSwitching aggregate in test-context only" do
70
+ # expect(exists_in_context?(create_in_context_test, :context_test)).to be_true
71
+ # expect(exists_in_context?(create_in_context_test)).to be_false
72
+ # end
73
+ # it "should find AnotherContext aggregate in default-context only" do
74
+ # expect(exists_in_context?(create_in_default_context)).to be_true
75
+ # expect(exists_in_context?(create_in_default_context, :context_test)).to be_false
76
+ # end
77
+ # end
78
+ # end
79
+ # context "getting events should respect context" do
80
+ # before(:each) {create_in_context_test;create_in_default_context; }
81
+ # context "when getting for specific context" do
82
+ # let(:events) { Sandthorn.get_events classes: [Sandthorn::TestContextSwitching], after_sequence_number: 0 }
83
+ # it "should have events" do
84
+ # expect(events.length).to eq 2
85
+ # end
86
+ # end
87
+ # context "when getting for all contexts" do
88
+ # let(:events) { Sandthorn.get_events after_sequence_number: 0 }
89
+ # it "should not be possible if multiple contexts" do
90
+ # expect{events}.to raise_exception(Sandthorn::Errors::Error)
91
+ # end
92
+ # end
93
+ # context "when getting for both classes" do
94
+ # let(:events) { Sandthorn.get_events classes: [Sandthorn::TestContextSwitching, Sandthorn::AnotherContext], after_sequence_number: 0 }
95
+ # it "should not be possible if multiple contexts" do
96
+ # expect{events}.to raise_exception(Sandthorn::Errors::Error)
97
+ # end
98
+ # end
99
+ # end
100
+ # end
101
+ # end
@@ -0,0 +1,148 @@
1
+ require 'spec_helper'
2
+ require 'sandthorn/event_inspector'
3
+ require 'sandthorn/aggregate_root_dirty_hashy'
4
+
5
+ class InspectorAggregate
6
+ include Sandthorn::AggregateRoot::DirtyHashy
7
+
8
+ attr_reader :foo_bar
9
+
10
+ def initialize args = {}
11
+ @foo_bar = args.fetch(:foo_bar, nil)
12
+ end
13
+
14
+ def this_is_an_event args = nil
15
+ record_event args
16
+ end
17
+ def another_event
18
+ record_event
19
+ end
20
+ def new_damaged_item_was_added hello
21
+ record_event hello
22
+ end
23
+ end
24
+
25
+ module Sandthorn
26
+ describe EventInspector do
27
+ let(:aggregate) {InspectorAggregate.new.extend EventInspector}
28
+
29
+ context "when using extract_trace_info from an event" do
30
+ let(:trace_info) {{user_id: "foo", ip: "bar"}}
31
+ let(:subject) do
32
+ aggregate.aggregate_trace trace_info do |traced|
33
+ traced.this_is_an_event
34
+ end
35
+ aggregate
36
+ end
37
+ context "and unsaved aggregate" do
38
+ it "should extract exact traceinfo from event" do
39
+ all_trace = subject.events_with_trace_info
40
+ all_trace.last[:trace].should eql trace_info
41
+ end
42
+ end
43
+ context "and saved aggregate" do
44
+ it "should extract exact traceinfo from event" do
45
+ subject.save
46
+ all_trace = subject.events_with_trace_info
47
+ all_trace.last[:trace].should eql trace_info
48
+ end
49
+ end
50
+ end
51
+ context "when inspecting non saved events" do
52
+ context "with no tracing information" do
53
+ let(:subject) { aggregate.this_is_an_event;aggregate }
54
+
55
+ it "should report true on has_unsaved_event? :this_is_an_event" do
56
+ subject.has_unsaved_event?(:this_is_an_event).should be_true
57
+ end
58
+ it "should report false on has_unsaved_event? :no_event_here" do
59
+ subject.has_unsaved_event?(:no_event_here).should be_false
60
+ end
61
+ end
62
+ context "with tracing information" do
63
+ let(:subject) do
64
+ aggregate.aggregate_trace user_id: 123, ip: "1234" do |traced|
65
+ traced.this_is_an_event "my name"
66
+ end
67
+ aggregate
68
+ end
69
+
70
+ it "should report true on has_unsaved_event? :this_is_an_event" do
71
+ subject.has_unsaved_event?(:this_is_an_event, trace: {user_id: 123, ip: "1234"}).should be_true
72
+ end
73
+ it "should report false on has_unsaved_event? :no_event_here" do
74
+ subject.has_unsaved_event?(:this_is_an_event, trace: {user_id: 321}).should be_false
75
+ subject.has_unsaved_event?(:this_is_an_event, trace: {another_user_id: 123}).should be_false
76
+ end
77
+ end
78
+ end
79
+ context "when inspecting saved events" do
80
+ context "with no tracing information" do
81
+ let(:subject) { aggregate.this_is_an_event;aggregate.save;aggregate }
82
+
83
+ it "should report true on has_unsaved_event? :this_is_an_event" do
84
+ subject.has_saved_event?(:this_is_an_event).should be_true
85
+ end
86
+ it "should report false on has_unsaved_event? :no_event_here" do
87
+ subject.has_saved_event?(:no_event_here).should be_false
88
+ end
89
+ end
90
+ context "with tracing information" do
91
+ let(:subject) do
92
+ aggregate.aggregate_trace user_id: 123, ip: "1234" do |traced|
93
+ traced.this_is_an_event "my name"
94
+ end
95
+ aggregate.save
96
+ aggregate
97
+ end
98
+
99
+ it "should report true on has_unsaved_event? :this_is_an_event" do
100
+ subject.has_saved_event?(:this_is_an_event, trace: {user_id: 123, ip: "1234"}).should be_true
101
+ end
102
+ it "should report false on has_unsaved_event? :no_event_here" do
103
+ subject.has_saved_event?(:this_is_an_event, trace: {user_id: 321}).should be_false
104
+ subject.has_saved_event?(:this_is_an_event, trace: {another_user_id: 123}).should be_false
105
+ end
106
+ it "should be able to check complex trace" do
107
+ subject.aggregate_trace client_ip: "10", user_id: "123" do |trace|
108
+ trace.new_damaged_item_was_added "foobar"
109
+ trace.save
110
+ end
111
+ subject.has_saved_event?(:new_damaged_item_was_added, trace: {user_id: "123", client_ip: "10"})
112
+ end
113
+ end
114
+ end
115
+ context "when inspecting any events" do
116
+ context "with no tracing information" do
117
+ let(:subject) { aggregate.this_is_an_event;aggregate.save;aggregate.another_event;aggregate }
118
+
119
+ it "should report true on has_unsaved_event? :this_is_an_event" do
120
+ subject.has_event?(:this_is_an_event).should be_true
121
+ subject.has_event?(:another_event).should be_true
122
+ end
123
+ it "should report false on has_unsaved_event? :no_event_here" do
124
+ subject.has_event?(:no_event_here).should be_false
125
+ end
126
+ end
127
+ context "with tracing information" do
128
+ let(:subject) do
129
+ aggregate.aggregate_trace user_id: 123, ip: "1234" do |traced|
130
+ traced.this_is_an_event "my name"
131
+ traced.save
132
+ traced.another_event
133
+ end
134
+ aggregate
135
+ end
136
+
137
+ it "should report true on has_unsaved_event? :this_is_an_event" do
138
+ subject.has_event?(:this_is_an_event, trace: {user_id: 123, ip: "1234"}).should be_true
139
+ subject.has_event?(:another_event, trace: {user_id: 123, ip: "1234"}).should be_true
140
+ end
141
+ it "should report false on has_unsaved_event? :no_event_here" do
142
+ subject.has_event?(:this_is_an_event, trace: {user_id: 321}).should be_false
143
+ subject.has_event?(:another_event, trace: {ip: "123"}).should be_false
144
+ end
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,42 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ require "ap"
8
+ require "bundler"
9
+ require "sandthorn_driver_sequel"
10
+
11
+ Bundler.require
12
+
13
+ module Helpers
14
+ def class_including(mod)
15
+ Class.new.tap {|c| c.send :include, mod }
16
+ end
17
+ end
18
+
19
+ RSpec.configure do |config|
20
+ config.treat_symbols_as_metadata_keys_with_true_values = true
21
+ config.run_all_when_everything_filtered = true
22
+ config.filter_run :focus
23
+
24
+ # Run specs in random order to surface order dependencies. If you find an
25
+ # order dependency and want to debug it, you can fix the order by providing
26
+ # the seed, which is printed after each run.
27
+ # --seed 1234
28
+ config.order = 'random'
29
+ config.before(:each) { sqlite_store_setup }
30
+ end
31
+
32
+ def spec_db
33
+ "sqlite://spec/db/sequel_driver.sqlite3"
34
+ end
35
+ def sqlite_store_setup
36
+ url = spec_db
37
+ catch_all_config = [ { driver: SandthornDriverSequel.driver_from_url(url: url) } ]
38
+ Sandthorn.configuration = catch_all_config
39
+ migrator = SandthornDriverSequel::Migration.new url: url
40
+ SandthornDriverSequel.migrate_db url: url
41
+ migrator.send(:clear_for_test)
42
+ end
@@ -0,0 +1,121 @@
1
+ # require 'spec_helper'
2
+ # require 'sandthorn/event_inspector'
3
+ # require 'sandthorn/aggregate_root_dirty_hashy'
4
+
5
+ # class UsualSuspect
6
+ # include Sandthorn::AggregateRoot::DirtyHashy
7
+
8
+ # def initialize full_name
9
+ # @full_name = full_name
10
+ # @charges = []
11
+ # end
12
+
13
+ # def charge_suspect_of_crime! crime_name
14
+ # suspect_was_charged crime_name
15
+ # end
16
+
17
+ # private
18
+ # def suspect_was_charged crime_name
19
+ # @charges << crime_name
20
+ # record_event crime_name
21
+ # end
22
+ # end
23
+
24
+ # class Simple
25
+ # end
26
+ # module Go
27
+ # def go
28
+ # @foo = "bar"
29
+ # record_event
30
+ # end
31
+ # end
32
+
33
+ # describe "using a traced change" do
34
+ # context "when extending an instance with aggregate_root" do
35
+ # it "should record tracing if specified" do
36
+ # simple = Simple.new
37
+ # simple.extend Sandthorn::EventInspector
38
+ # simple.extend Sandthorn::AggregateRoot::DirtyHashy
39
+ # simple.extend Sandthorn::AggregateRootSnapshot
40
+
41
+ # simple.extend Go
42
+ # simple.aggregate_trace "123" do |traced|
43
+ # traced.go
44
+ # end
45
+ # simple.events_with_trace_info.last[:trace].should eql("123")
46
+ # end
47
+ # end
48
+ # context "when not tracing" do
49
+ # it "should not have any trace event info at all on new" do
50
+ # suspect = UsualSuspect.new "Ronny"
51
+ # event = suspect.aggregate_events.first
52
+ # event[:trace].should be_nil
53
+ # end
54
+ # it "should not have any trace event info at all on regular event" do
55
+ # suspect = UsualSuspect.new "Ronny"
56
+ # event = suspect.aggregate_events.first
57
+ # event[:trace].should be_nil
58
+ # end
59
+ # end
60
+ # context "when changing aggregate in a traced context" do
61
+ # let(:suspect) {UsualSuspect.new("Conny").extend Sandthorn::EventInspector}
62
+ # it "should record modififier in the event" do
63
+ # suspect.aggregate_trace "Lars Krantz" do |s|
64
+ # s.charge_suspect_of_crime! "Theft"
65
+ # end
66
+ # event = suspect.events_with_trace_info.last
67
+ # event[:trace].should eql "Lars Krantz"
68
+ # end
69
+
70
+ # it "should record optional other tracing information" do
71
+ # trace_info = {ip: "127.0.0.1", client: "Mozilla"}
72
+ # suspect.aggregate_trace trace_info do |s|
73
+ # s.charge_suspect_of_crime! "Murder"
74
+ # end
75
+ # event = suspect.events_with_trace_info.last
76
+ # event[:trace].should eql trace_info
77
+ # end
78
+ # end
79
+ # context "when initializing a new aggregate in a traced context" do
80
+ # it "should record modifier in the new event" do
81
+ # UsualSuspect.aggregate_trace "Lars Krantz" do
82
+ # suspect = UsualSuspect.new("Sonny").extend Sandthorn::EventInspector
83
+ # event = suspect.events_with_trace_info.first
84
+ # event[:trace].should eql "Lars Krantz"
85
+ # end
86
+ # end
87
+ # it "should record tracing for all events in the trace block" do
88
+ # trace_info = {gender: :unknown, occupation: :master}
89
+ # UsualSuspect.aggregate_trace trace_info do
90
+ # suspect = UsualSuspect.new("Sonny").extend Sandthorn::EventInspector
91
+ # suspect.charge_suspect_of_crime! "Hit and run"
92
+ # event = suspect.events_with_trace_info.last
93
+ # event[:trace].should eql trace_info
94
+ # end
95
+ # end
96
+ # it "should record tracing for all events in the trace block" do
97
+ # trace_info = {user_aggregate_id: "foo-bar-x", gender: :unknown, occupation: :master}
98
+ # UsualSuspect.aggregate_trace trace_info do
99
+ # suspect = UsualSuspect.new("Conny").extend Sandthorn::EventInspector
100
+ # suspect.charge_suspect_of_crime! "Desception"
101
+ # event = suspect.events_with_trace_info.last
102
+ # event[:trace].should eql trace_info
103
+ # end
104
+ # end
105
+ # it "should only record info within block" do
106
+ # fork do
107
+ # UsualSuspect.aggregate_trace "Lars Krantz" do
108
+ # suspect = UsualSuspect.new("Sonny").extend Sandthorn::EventInspector
109
+ # event = suspect.events_with_trace_info.first
110
+ # event[:trace].should eql "Lars Krantz"
111
+ # sleep 1
112
+ # end
113
+ # end
114
+ # sleep 0.5
115
+ # s2 = UsualSuspect.new("Ronny").extend Sandthorn::EventInspector
116
+ # event = s2.events_with_trace_info.first
117
+ # event[:trace].should be_nil
118
+ # end
119
+ # end
120
+
121
+ # end