sandthorn 0.0.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,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