event_sourced_record 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fb56334d7517be8d0816a7f12b91a6c2daf32d6f
4
- data.tar.gz: e7fc402917fad1bb62c5ab3aa25d3f750b824637
3
+ metadata.gz: b0ee2af5ab48feddf17d097471e7298e444b261f
4
+ data.tar.gz: 7b9d4960dfbaaae80abf9f93ed8e640cb1503d01
5
5
  SHA512:
6
- metadata.gz: 7a26c10327b28148eb26819aeda00f56481bd528bedcddd37465b839fcd06da7d08893b99d1aa8821211b84e5491b306f86c02c46cbfce57a6f00f43ef6883e7
7
- data.tar.gz: 2e0608be3b44eda77080c19edbc27d59f11272ffaccf09e433b17147b6bc883672e601d9fbef96746053112d2761ded6aeebd149ad984de58b0da1935e9b4bb8
6
+ metadata.gz: 3c596cb4d97f385ee2827a876f3d1ced7fc180ec80a03ea174aeafceb85269c42662190d486cdd426b6cf561372d3715b5743d1eea7bbea8500d61adb658acd2
7
+ data.tar.gz: b570432fd7e2db6d8fb072031d17475e7bc7579c5beaab175c5d4c752bbba7451700731ddde53f86a8761dc2d417b2a1d245e18236caf34c4de02fa26c5af9bf
data/CHANGELOG.md ADDED
@@ -0,0 +1,9 @@
1
+ [[[0.2.0]] - Feb 23 2015]
2
+
3
+ * BUGFIX - allow multiple calculators (#11).
4
+ * Included the configuration for the `data` column in the generated Event class
5
+ (#9).
6
+ * Made Event instances immutable (#8).
7
+ * Added `occurred_at` to generated events, which will be used by the calculator
8
+ for ordering events. If `occurred_at` is not defined, `created_at` will be
9
+ used instead (#6).
@@ -1,10 +1,10 @@
1
1
  class EventSourcedRecord::Calculator
2
2
  def self.events(*event_symbols)
3
- @@event_symbols = event_symbols
3
+ @event_symbols = event_symbols
4
4
  end
5
5
 
6
6
  def self.event_classes
7
- @@event_symbols.map { |sym|
7
+ @event_symbols.map { |sym|
8
8
  Module.const_get(sym.to_s.singularize.camelize)
9
9
  }
10
10
  end
@@ -88,13 +88,21 @@ class EventSourcedRecord::Calculator
88
88
  conditions = {projection_name + '_id' => projection.id} if projection
89
89
  end
90
90
  conditions ? event_class.where(conditions).to_a : []
91
- }.flatten.sort_by(&:created_at).reject { |evt|
91
+ }.flatten.sort_by{ |evt| occurrence_time(evt) }.reject { |evt|
92
92
  if last_event_time
93
- evt.created_at > last_event_time
93
+ occurrence_time(evt) > last_event_time
94
94
  end
95
95
  }
96
96
  end
97
97
 
98
+ def occurrence_time(event)
99
+ if event.respond_to?(:occurred_at) && event.occurred_at
100
+ event.occurred_at
101
+ else
102
+ event.created_at
103
+ end
104
+ end
105
+
98
106
  def uuid_field
99
107
  projection_name + '_uuid'
100
108
  end
@@ -9,6 +9,7 @@ module EventSourcedRecord::Event
9
9
  model.after_initialize :ensure_data
10
10
  model.after_initialize :ensure_projection_uuid
11
11
  model.after_initialize :lock_event_type
12
+ model.before_validation :ensure_occurred_at, on: :create
12
13
  model.validates :event_type, presence: true
13
14
  model.validate :validate_corrent_event_type
14
15
  model.validate :validate_by_event_type
@@ -56,6 +57,10 @@ module EventSourcedRecord::Event
56
57
  @event_type_locked = true
57
58
  end
58
59
 
60
+ def ensure_occurred_at
61
+ self.occurred_at = Time.now unless occurred_at
62
+ end
63
+
59
64
  def method_missing(meth, *args, &block)
60
65
  if event_type_config && event_type_config.attributes.include?(meth)
61
66
  ensure_data
@@ -1,3 +1,3 @@
1
1
  module EventSourcedRecord
2
- VERSION = "0.1.3"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -13,7 +13,7 @@ class EventSourcedRecord::EventSourcedRecordGenerator < Rails::Generators::Named
13
13
  def create_event
14
14
  arguments = [
15
15
  "#{file_name}_uuid:string:index", "event_type:string",
16
- "data:text", "created_at:datetime"
16
+ "data:text", "created_at:datetime", "occurred_at:datetime"
17
17
  ].join(' ')
18
18
  generate "event_sourced_record:event", "#{file_name}_event #{arguments}"
19
19
  end
@@ -119,4 +119,21 @@ class EventSourcedRecord::EventTest < MiniTest::Unit::TestCase
119
119
  event.touch
120
120
  end
121
121
  end
122
+
123
+ def test_occurred_at_is_set_if_not_specified
124
+ event = SubscriptionEvent.creation.create!(
125
+ bottles_per_shipment: 1, bottles_purchased: 6, user_id: 999
126
+ )
127
+
128
+ assert event.occurred_at
129
+ end
130
+
131
+ def test_occurred_at_can_be_specified
132
+ event = SubscriptionEvent.creation.new(
133
+ occurred_at: Time.new(2003, 1, 24, 11, 33), bottles_per_shipment: 1,
134
+ bottles_purchased: 6, user_id: 999
135
+ )
136
+
137
+ assert_equal(Time.new(2003, 1, 24, 11, 33), event.occurred_at)
138
+ end
122
139
  end
@@ -16,6 +16,7 @@ class EventSourcedRecord::EventGeneratorTest < Rails::Generators::TestCase
16
16
  event_type:string
17
17
  data:text
18
18
  created_at:datetime
19
+ occurred_at:datetime
19
20
  )
20
21
  end
21
22
 
@@ -23,11 +24,13 @@ class EventSourcedRecord::EventGeneratorTest < Rails::Generators::TestCase
23
24
  ar_major_version = ActiveRecord::VERSION::MAJOR
24
25
  if ar_major_version >= 4
25
26
  assert @generate_calls['migration'].include?(
26
- "create_subscription_events subscription_uuid:string:index event_type:string data:text created_at:datetime"
27
+ "create_subscription_events subscription_uuid:string:index event_type:string data:text created_at:datetime occurred_at:datetime"
27
28
  )
28
29
  else
29
30
  assert_migration("db/migrate/create_subscription_events.rb") do |contents|
30
31
  assert_match(/t.string :event_type/, contents)
32
+ assert_match(/t.datetime :created_at/, contents)
33
+ assert_match(/t.datetime :occurred_at/, contents)
31
34
  end
32
35
  end
33
36
  end
@@ -20,7 +20,7 @@ class EventSourcedRecord::EventSourcedRecordGeneratorTest < Rails::Generators::T
20
20
 
21
21
  test "calls the event generator" do
22
22
  assert @generate_calls['event_sourced_record:event'].include?(
23
- "shampoo_subscription_event shampoo_subscription_uuid:string:index event_type:string data:text created_at:datetime"
23
+ "shampoo_subscription_event shampoo_subscription_uuid:string:index event_type:string data:text created_at:datetime occurred_at:datetime"
24
24
  )
25
25
  end
26
26
 
data/test/test_helper.rb CHANGED
@@ -38,6 +38,7 @@ silence_stream(STDOUT) do
38
38
  t.string "event_type"
39
39
  t.text "data"
40
40
  t.datetime "created_at"
41
+ t.datetime "occurred_at"
41
42
  end
42
43
 
43
44
  create_table "subscriptions", force: true do |t|
@@ -46,6 +47,19 @@ silence_stream(STDOUT) do
46
47
  t.integer "bottles_left"
47
48
  t.string "uuid"
48
49
  end
50
+
51
+ create_table "bottle_events", force: true do |t|
52
+ t.string "bottle_uuid"
53
+ t.string "event_type"
54
+ t.text "data"
55
+ t.datetime "created_at"
56
+ end
57
+
58
+ create_table "bottles", force: true do |t|
59
+ t.integer "volume"
60
+ t.decimal "cost_price"
61
+ t.string "uuid"
62
+ end
49
63
  end
50
64
  end
51
65
 
@@ -90,3 +104,28 @@ class SubscriptionCalculator < EventSourcedRecord::Calculator
90
104
  @subscription.bottles_left -= shipment.num_bottles
91
105
  end
92
106
  end
107
+
108
+ class BottleEvent < ActiveRecord::Base
109
+ include EventSourcedRecord::Event
110
+
111
+ serialize :data
112
+
113
+ event_type :purchase do
114
+ attributes :volume, :cost_price
115
+ end
116
+ end
117
+
118
+ class Bottle < ActiveRecord::Base
119
+ has_many :bottle_events
120
+
121
+ validates :uuid, uniqueness: true
122
+ end
123
+
124
+ class BottleCalculator < EventSourcedRecord::Calculator
125
+ events :bottle_events, :shipments
126
+
127
+ def advance_purchase(event)
128
+ @bottle.volume = event.volume
129
+ @bottle.cost_price = event.cost_price
130
+ end
131
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: event_sourced_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Francis Hwang
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-14 00:00:00.000000000 Z
11
+ date: 2015-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -160,6 +160,7 @@ files:
160
160
  - ".gitignore"
161
161
  - ".travis.yml"
162
162
  - Appraisals
163
+ - CHANGELOG.md
163
164
  - Gemfile
164
165
  - Getting_Started.md
165
166
  - LICENSE.txt