sandthorn 1.0.0 → 1.1.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.
- checksums.yaml +5 -5
- data/Gemfile +1 -1
- data/README.md +5 -5
- data/lib/sandthorn.rb +0 -1
- data/lib/sandthorn/aggregate_root_base.rb +15 -27
- data/lib/sandthorn/aggregate_root_marshal.rb +4 -5
- data/lib/sandthorn/version.rb +1 -1
- data/sandthorn.gemspec +1 -1
- data/spec/aggregate_delta_spec.rb +6 -13
- data/spec/aggregate_events_spec.rb +3 -3
- data/spec/aggregate_root_spec.rb +37 -41
- data/spec/complex_aggregate_spec.rb +1 -1
- data/spec/constructor_events_spec.rb +5 -5
- data/spec/default_attributes_spec.rb +3 -3
- data/spec/initialize_signature_change_spec.rb +2 -2
- data/spec/stateless_events_spec.rb +11 -7
- data/spec/tracing_spec.rb +6 -6
- metadata +4 -13
- data/lib/sandthorn/event.rb +0 -61
- data/spec/aggregate_snapshot_spec.rb +0 -263
- data/spec/different_driver_spec.rb +0 -101
- data/spec/event_inspector_spec.rb +0 -152
- data/spec/event_spec.rb +0 -99
@@ -1,101 +0,0 @@
|
|
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
|
@@ -1,152 +0,0 @@
|
|
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 have the new event" do
|
56
|
-
# subject.has_event?(:new).should be_true
|
57
|
-
# end
|
58
|
-
|
59
|
-
# it "should report true on has_unsaved_event? :this_is_an_event" do
|
60
|
-
# subject.has_unsaved_event?(:this_is_an_event).should be_true
|
61
|
-
# end
|
62
|
-
# it "should report false on has_unsaved_event? :no_event_here" do
|
63
|
-
# subject.has_unsaved_event?(:no_event_here).should be_false
|
64
|
-
# end
|
65
|
-
# end
|
66
|
-
# context "with tracing information" do
|
67
|
-
# let(:subject) do
|
68
|
-
# aggregate.aggregate_trace user_id: 123, ip: "1234" do |traced|
|
69
|
-
# traced.this_is_an_event "my name"
|
70
|
-
# end
|
71
|
-
# aggregate
|
72
|
-
# end
|
73
|
-
|
74
|
-
# it "should report true on has_unsaved_event? :this_is_an_event" do
|
75
|
-
# subject.has_unsaved_event?(:this_is_an_event, trace: {user_id: 123, ip: "1234"}).should be_true
|
76
|
-
# end
|
77
|
-
# it "should report false on has_unsaved_event? :no_event_here" do
|
78
|
-
# subject.has_unsaved_event?(:this_is_an_event, trace: {user_id: 321}).should be_false
|
79
|
-
# subject.has_unsaved_event?(:this_is_an_event, trace: {another_user_id: 123}).should be_false
|
80
|
-
# end
|
81
|
-
# end
|
82
|
-
# end
|
83
|
-
# context "when inspecting saved events" do
|
84
|
-
# context "with no tracing information" do
|
85
|
-
# let(:subject) { aggregate.this_is_an_event;aggregate.save;aggregate }
|
86
|
-
|
87
|
-
# it "should report true on has_unsaved_event? :this_is_an_event" do
|
88
|
-
# subject.has_saved_event?(:this_is_an_event).should be_true
|
89
|
-
# end
|
90
|
-
# it "should report false on has_unsaved_event? :no_event_here" do
|
91
|
-
# subject.has_saved_event?(:no_event_here).should be_false
|
92
|
-
# end
|
93
|
-
# end
|
94
|
-
# context "with tracing information" do
|
95
|
-
# let(:subject) do
|
96
|
-
# aggregate.aggregate_trace user_id: 123, ip: "1234" do |traced|
|
97
|
-
# traced.this_is_an_event "my name"
|
98
|
-
# end
|
99
|
-
# aggregate.save
|
100
|
-
# aggregate
|
101
|
-
# end
|
102
|
-
|
103
|
-
# it "should report true on has_unsaved_event? :this_is_an_event" do
|
104
|
-
# subject.has_saved_event?(:this_is_an_event, trace: {user_id: 123, ip: "1234"}).should be_true
|
105
|
-
# end
|
106
|
-
# it "should report false on has_unsaved_event? :no_event_here" do
|
107
|
-
# subject.has_saved_event?(:this_is_an_event, trace: {user_id: 321}).should be_false
|
108
|
-
# subject.has_saved_event?(:this_is_an_event, trace: {another_user_id: 123}).should be_false
|
109
|
-
# end
|
110
|
-
# it "should be able to check complex trace" do
|
111
|
-
# subject.aggregate_trace client_ip: "10", user_id: "123" do |trace|
|
112
|
-
# trace.new_damaged_item_was_added "foobar"
|
113
|
-
# trace.save
|
114
|
-
# end
|
115
|
-
# subject.has_saved_event?(:new_damaged_item_was_added, trace: {user_id: "123", client_ip: "10"})
|
116
|
-
# end
|
117
|
-
# end
|
118
|
-
# end
|
119
|
-
# context "when inspecting any events" do
|
120
|
-
# context "with no tracing information" do
|
121
|
-
# let(:subject) { aggregate.this_is_an_event;aggregate.save;aggregate.another_event;aggregate }
|
122
|
-
|
123
|
-
# it "should report true on has_unsaved_event? :this_is_an_event" do
|
124
|
-
# subject.has_event?(:this_is_an_event).should be_true
|
125
|
-
# subject.has_event?(:another_event).should be_true
|
126
|
-
# end
|
127
|
-
# it "should report false on has_unsaved_event? :no_event_here" do
|
128
|
-
# subject.has_event?(:no_event_here).should be_false
|
129
|
-
# end
|
130
|
-
# end
|
131
|
-
# context "with tracing information" do
|
132
|
-
# let(:subject) do
|
133
|
-
# aggregate.aggregate_trace user_id: 123, ip: "1234" do |traced|
|
134
|
-
# traced.this_is_an_event "my name"
|
135
|
-
# traced.save
|
136
|
-
# traced.another_event
|
137
|
-
# end
|
138
|
-
# aggregate
|
139
|
-
# end
|
140
|
-
|
141
|
-
# it "should report true on has_unsaved_event? :this_is_an_event" do
|
142
|
-
# subject.has_event?(:this_is_an_event, trace: {user_id: 123, ip: "1234"}).should be_true
|
143
|
-
# subject.has_event?(:another_event, trace: {user_id: 123, ip: "1234"}).should be_true
|
144
|
-
# end
|
145
|
-
# it "should report false on has_unsaved_event? :no_event_here" do
|
146
|
-
# subject.has_event?(:this_is_an_event, trace: {user_id: 321}).should be_false
|
147
|
-
# subject.has_event?(:another_event, trace: {ip: "123"}).should be_false
|
148
|
-
# end
|
149
|
-
# end
|
150
|
-
# end
|
151
|
-
# end
|
152
|
-
# end
|
data/spec/event_spec.rb
DELETED
@@ -1,99 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Sandthorn
|
4
|
-
describe Event do
|
5
|
-
let(:event_data) do
|
6
|
-
JSON.parse(
|
7
|
-
'{"aggregate_type":"SandthornProduct",
|
8
|
-
"aggregate_version":1,
|
9
|
-
"aggregate_id":"62d88e96-c551-4157-a837-1674e3f2698d",
|
10
|
-
"sequence_number":114,
|
11
|
-
"event_name":"new",
|
12
|
-
"timestamp":"2014-08-16 20:02:05 UTC",
|
13
|
-
"event_data":{"method_name":"new",
|
14
|
-
"method_args":[{"name":"Hahah",
|
15
|
-
"price":"50",
|
16
|
-
"stock_status":"outofstock"}],
|
17
|
-
"attribute_deltas":[{"attribute_name":"name",
|
18
|
-
"old_value":null,
|
19
|
-
"new_value":"Hahah"},
|
20
|
-
{"attribute_name":"price",
|
21
|
-
"old_value":null,
|
22
|
-
"new_value":50},
|
23
|
-
{"attribute_name":"stock_status",
|
24
|
-
"old_value":null,
|
25
|
-
"new_value":"outofstock"},
|
26
|
-
{"attribute_name":"active",
|
27
|
-
"old_value":null,
|
28
|
-
"new_value":true},
|
29
|
-
{"attribute_name":"on_sale",
|
30
|
-
"old_value":null,
|
31
|
-
"new_value":false},
|
32
|
-
{"attribute_name":"aggregate_id",
|
33
|
-
"old_value":null,
|
34
|
-
"new_value":"62d88e96-c551-4157-a837-1674e3f2698d"}]}}', symbolize_names: true)
|
35
|
-
end
|
36
|
-
|
37
|
-
let(:subject) { Event.new(event_data) }
|
38
|
-
describe "primitive attributes" do
|
39
|
-
attrs = %i(
|
40
|
-
aggregate_id
|
41
|
-
aggregate_type
|
42
|
-
aggregate_version
|
43
|
-
timestamp
|
44
|
-
event_name
|
45
|
-
event_data
|
46
|
-
method_args
|
47
|
-
trace
|
48
|
-
)
|
49
|
-
|
50
|
-
attrs.each do |attr|
|
51
|
-
it "has an accessor for #{attr}" do
|
52
|
-
expect(subject.send(attr)).to eq(subject[attr])
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
describe "#new_values" do
|
58
|
-
context "when given the value of an attribute that has changed" do
|
59
|
-
it "returns the new value" do
|
60
|
-
expect(subject.new_values[:name]).to eq("Hahah")
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
context "when given a non-existing attribute name" do
|
65
|
-
it "returns nil" do
|
66
|
-
expect(subject.new_values[:foo]).to be_nil
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
describe "#attributes_deltas" do
|
72
|
-
it "returns something enumerable" do
|
73
|
-
expect(subject.attribute_deltas).to respond_to(:each)
|
74
|
-
end
|
75
|
-
|
76
|
-
describe "a delta" do
|
77
|
-
let(:wrapped_delta) { subject.attribute_deltas.first }
|
78
|
-
let(:raw_delta) { subject[:event_data][:attribute_deltas].first }
|
79
|
-
describe "#attribute_name" do
|
80
|
-
it "has the same value as the raw hash" do
|
81
|
-
expect(wrapped_delta.attribute_name).to eq(raw_delta[:attribute_name])
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
describe "#new_value" do
|
86
|
-
it "has the same value as the raw hash" do
|
87
|
-
expect(wrapped_delta.new_value).to eq(raw_delta[:new_value])
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
describe "#old_value" do
|
92
|
-
it "has the same value as the raw hash" do
|
93
|
-
expect(wrapped_delta.old_value).to eq(raw_delta[:old_value])
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|