entity_store 0.2.15 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f6957074ac4594c6b4a1068ad4131fab670763a0
4
- data.tar.gz: 7a975bf8fc65eacf1a15914d973371a1267f0295
3
+ metadata.gz: 80ef2d2f7cb967ed15151bd5d3fa17c5526c4022
4
+ data.tar.gz: ee08573ec53e96fa70df0cb30c48db9df19d56de
5
5
  SHA512:
6
- metadata.gz: 9865c283a793d09f4d22b57fe4c0bb40c2d8b58b3049708692050539856663e252e19d63e0fed878967ce2d56977328606e72dcadc3fb8b0e60e655068427b1d
7
- data.tar.gz: d3ce7d96186648e7f44152be97694393d4b783f3a1c0ebcca08feac5c4aee73dfb50dc6f6ce4cca6e90d84bb753b25dee54c0c061a1619ca52c9766a1a3968a9
6
+ metadata.gz: 653358d1589d59332805e9501e41c637bc2bbb4a4292b19ca0586871cb7352cbb709f2a23e97813cfdcb2be823414b61a9f50acd01e5983c002d08dfcd4d05e3
7
+ data.tar.gz: e2fde849bd73b14d086f78fb2268304c55771f85f74d21db3c0b74b4f800c8856e369767e82cdc353c8efa9cbf9d06ac7027f4ad69c8daa7cc289c903eb7d7b3
@@ -6,7 +6,6 @@ module EntityStore
6
6
  klass.class_eval do
7
7
  include HashSerialization
8
8
  include Attributes
9
- extend ClassMethods
10
9
 
11
10
  version_incremented_event_class = "#{self.name}VersionIncremented".split('::').inject(Object) {|obj, name|
12
11
  obj.const_defined?(name) ? obj.const_get(name) : obj.const_set(name, Class.new)
@@ -24,28 +23,6 @@ module EntityStore
24
23
  end
25
24
  end
26
25
 
27
- module ClassMethods
28
-
29
- def related_entities(*names)
30
- names.each do |name|
31
- # attr accessor for the id
32
- define_method("#{name}_id") { instance_variable_get("@#{name}_id")}
33
- define_method("#{name}_id=") do |value| instance_variable_set("@#{name}_id", value) end
34
-
35
- # lazy loader for related entity
36
- define_method(name) {
37
- if instance_variable_get("@#{name}_id") && @_related_entity_loader
38
- instance_variable_get("@_#{name}") || instance_variable_set("@_#{name}", @_related_entity_loader.get(instance_variable_get("@#{name}_id")))
39
- end
40
- }
41
- end
42
-
43
- define_method(:loaded_related_entities) {
44
- names.collect{ |name| instance_variable_get("@_#{name}") }.select{|entity| !entity.nil? }
45
- }
46
- end
47
- end
48
-
49
26
  def type
50
27
  self.class.name
51
28
  end
@@ -63,12 +40,6 @@ module EntityStore
63
40
  event_class.new(:entity_id => id, :version => version)
64
41
  end
65
42
 
66
- # Holds a reference to the store used to load this entity so the same store
67
- # can be used for related entities
68
- def related_entity_loader=(value)
69
- @_related_entity_loader = value
70
- end
71
-
72
43
  def pending_events
73
44
  @pending_events ||= []
74
45
  end
@@ -51,7 +51,7 @@ module EntityStore
51
51
  entities.update({'_id' => BSON::ObjectId.from_string(entity.id)}, { '$set' => { 'version' => entity.version } })
52
52
  end
53
53
 
54
- # Public - create a snapshot of the entity and store in the entities collection
54
+ # Public: create a snapshot of the entity and store in the entities collection
55
55
  #
56
56
  def snapshot_entity(entity)
57
57
  query = {'_id' => BSON::ObjectId.from_string(entity.id)}
@@ -74,7 +74,7 @@ module EntityStore
74
74
  entities.update({'_id' => BSON::ObjectId.from_string(id)}, { '$unset' => { 'snapshot' => 1}})
75
75
  end
76
76
 
77
- # Public - remove all snapshots
77
+ # Public: remove all snapshots
78
78
  #
79
79
  # type - String optional class name for the entity
80
80
  #
@@ -88,19 +88,26 @@ module EntityStore
88
88
  events.insert({'_type' => event.class.name, '_entity_id' => BSON::ObjectId.from_string(event.entity_id) }.merge(event.attributes) ).to_s
89
89
  end
90
90
 
91
- def get_entity!(id)
92
- get_entity(id, true)
93
- end
94
-
95
- # Public - loads the entity from the store, including any available snapshots
91
+ # Public: loads the entity from the store, including any available snapshots
96
92
  # then loads the events to complete the state
97
93
  #
98
- # id - String representation of BSON::ObjectId
99
- # raise_exception - Boolean indicating whether to raise an exception if not found (default=false)
94
+ # ids - Array of Strings representation of BSON::ObjectId
95
+ # options - Hash of options (default: {})
96
+ # :raise_exception - Boolean (default: true)
100
97
  #
101
- # Returns an object of the entity type
102
- def get_entity(id, raise_exception=false)
103
- if attrs = entities.find_one('_id' => BSON::ObjectId.from_string(id))
98
+ # Returns an array of entities
99
+ def get_entities(ids, options={})
100
+
101
+ object_ids = ids.map do |id|
102
+ begin
103
+ BSON::ObjectId.from_string(id)
104
+ rescue BSON::InvalidObjectId
105
+ raise NotFound.new(id) if options.fetch(:raise_exception, true)
106
+ nil
107
+ end
108
+ end
109
+
110
+ entities.find('_id' => { '$in' => object_ids }).map do |attrs|
104
111
  begin
105
112
  entity_type = EntityStore::Config.load_type(attrs['_type'])
106
113
 
@@ -111,41 +118,55 @@ module EntityStore
111
118
  attrs.delete('snapshot') unless active_key == attrs['snapshot_key']
112
119
  end
113
120
 
114
- entity = entity_type.new(attrs['snapshot'] || {'id' => id })
121
+ entity = entity_type.new(attrs['snapshot'] || {'id' => attrs['_id'].to_s })
115
122
  rescue => e
116
123
  log_error "Error loading type #{attrs['_type']}", e
117
124
  raise
118
125
  end
119
126
 
120
127
  entity
121
- else
122
- raise NotFound.new(id) if raise_exception
123
- nil
124
128
  end
125
- rescue BSON::InvalidObjectId
126
- raise NotFound.new(id) if raise_exception
127
- nil
129
+
128
130
  end
129
131
 
130
- def get_events(id, since_version=nil)
131
- query = { '_entity_id' => BSON::ObjectId.from_string(id) }
132
+ # Public: get events for an array of criteria objects
133
+ # because each entity could have a different reference
134
+ # version this allows optional criteria to be specifed
135
+ #
136
+ #
137
+ # criteria - Hash :id mandatory, :since_version optional
138
+ #
139
+ # Examples
140
+ #
141
+ # get_events_for_criteria([ { id: "23232323"}, { id: "2398429834", since_version: 4 } ] )
142
+ #
143
+ # Returns Hash with id as key and Array of Event instances as value
144
+ def get_events(criteria)
145
+ return {} if criteria.empty?
146
+
147
+ query_items = criteria.map do |item|
148
+ raise ArgumentError.new(":id missing from criteria") unless item[:id]
149
+ item_query = { '_entity_id' => BSON::ObjectId.from_string(item[:id]) }
150
+ item_query['entity_version'] = { '$gt' => item[:since_version] } if item[:since_version]
151
+ item_query
152
+ end
132
153
 
133
- query['entity_version'] = { '$gt' => since_version } if since_version
154
+ query = { '$or' => query_items }
134
155
 
135
156
  options = {
136
157
  :sort => [['entity_version', Mongo::ASCENDING], ['_id', Mongo::ASCENDING]]
137
158
  }
138
159
 
139
- loaded_events = events.find(query, options).collect do |attrs|
160
+ result = Hash[ criteria.map { |item| [ item[:id], [] ] } ]
161
+
162
+ events.find(query, options).each do |attrs|
140
163
  begin
141
- EntityStore::Config.load_type(attrs['_type']).new(attrs)
164
+ result[attrs['_entity_id'].to_s] << EntityStore::Config.load_type(attrs['_type']).new(attrs)
142
165
  rescue => e
143
166
  log_error "Error loading type #{attrs['_type']}", e
144
- nil
145
167
  end
146
168
  end
147
-
148
- loaded_events.compact
169
+ result
149
170
  end
150
171
  end
151
172
  end
@@ -20,12 +20,6 @@ module EntityStore
20
20
  end
21
21
 
22
22
  def save(entity)
23
- do_save entity
24
- entity.loaded_related_entities.each do |e| do_save e end if entity.respond_to?(:loaded_related_entities)
25
- entity
26
- end
27
-
28
- def do_save(entity)
29
23
  # need to look at concurrency if we start storing version on client
30
24
  unless entity.pending_events.empty?
31
25
  entity.version += 1
@@ -42,7 +36,7 @@ module EntityStore
42
36
  end
43
37
  entity
44
38
  rescue => e
45
- log_error "Store#do_save error: #{e.inspect} - #{entity.inspect}", e
39
+ log_error "Store#save error: #{e.inspect} - #{entity.inspect}", e
46
40
  raise e
47
41
  end
48
42
 
@@ -74,29 +68,67 @@ module EntityStore
74
68
  end
75
69
 
76
70
  def get(id, raise_exception=false)
77
- log_debug { "Store#get #{id}"}
78
- if entity = storage_client.get_entity(id, raise_exception)
71
+ options = {
72
+ raise_exception: raise_exception
73
+ }
79
74
 
80
- storage_client.get_events(id, entity.version).each do |event|
75
+ get_with_ids([id], options).first
76
+ end
77
+
78
+ # Public: get a series of entities
79
+ #
80
+ # ids - Array of id strings
81
+ # options - Hash of options (default: {})
82
+ # :raise_exception - Boolean (default true)
83
+ #
84
+ # Returns an Array of entities
85
+ def get_with_ids(ids, options={})
86
+
87
+ entities = Hash[ storage_client.get_entities(ids, options).map { |e| [ e.id, e] } ]
88
+
89
+ if options.fetch(:raise_exception, true)
90
+ ids.each do |id|
91
+ raise NotFound.new(id) unless entities[id]
92
+ end
93
+ end
94
+
95
+ criteria = entities.map do |id, entity|
96
+ { id: id, since_version: entity.version }
97
+ end
98
+
99
+ events = storage_client.get_events(criteria)
100
+
101
+ entities.each do |id, entity|
102
+
103
+ next unless entity_events = events[id]
104
+
105
+ entity_events.each do |event|
81
106
  begin
82
107
  event.apply(entity)
83
108
  log_debug { "Applied #{event.inspect} to #{id}" }
84
109
  rescue => e
85
110
  log_error "Failed to apply #{event.class.name} #{event.attributes} to #{id} with #{e.inspect}", e
111
+ raise if options.fetch(:raise_exception, true)
86
112
  end
87
113
  entity.version = event.entity_version
88
114
  end
89
115
 
90
- # assign this entity loader to allow lazy loading of related entities
91
- entity.related_entity_loader = self
92
116
  end
93
- entity
117
+
118
+ # ensure entities are returned in same order as requested
119
+ ids.map { |id| entities[id] }
120
+
94
121
  end
95
122
 
96
- # Public : USE AT YOUR PERIL this clears the ENTIRE data store
123
+ # Public: USE AT YOUR PERIL this clears the ENTIRE data store
124
+ #
125
+ # confirm - Symbol that must equal :i_am_sure
97
126
  #
98
127
  # Returns nothing
99
- def clear_all
128
+ def clear_all(confirm)
129
+ unless confirm == :i_am_sure
130
+ raise "#clear_all call with :i_am_sure in order to do this"
131
+ end
100
132
  storage_client.clear
101
133
  @_storage_client = nil
102
134
  end
@@ -105,7 +137,7 @@ module EntityStore
105
137
  @_event_bus ||= EventBus.new
106
138
  end
107
139
 
108
- # Public : returns an array representing a full audit trail for the entity.
140
+ # Public: returns an array representing a full audit trail for the entity.
109
141
  # After each event is applied the state of the entity is rendered.
110
142
  # Optionally accepts a block which should return true or false to indicate
111
143
  # whether to render the line. The block yields entity, event, lines collection
@@ -1,3 +1,3 @@
1
1
  module EntityStore
2
- VERSION = "0.2.15".freeze
2
+ VERSION = "0.3.1".freeze
3
3
  end
@@ -9,76 +9,16 @@ end
9
9
  class DummyEntity
10
10
  include Entity
11
11
 
12
- related_entities :club, :user
13
-
14
12
  attr_accessor :name, :description, :members
15
13
  entity_value_array_attribute :things, ThingEntityValue
16
14
  entity_value_dictionary_attribute :other_things, ThingEntityValue
17
15
  end
18
16
 
19
17
  describe Entity do
20
- describe ".related_entities" do
21
- before(:each) do
22
- @entity_loader = double(Store)
23
- @club = double('Entity', :id => random_string)
24
- @user = double('Entity', :id => random_string)
25
- @entity = DummyEntity.new(:related_entity_loader => @entity_loader, :club_id => @club.id, :user_id => @user.id)
26
- @entity_loader.stub(:get) { |id|
27
- case id
28
- when @club.id
29
- @club
30
- when @user.id
31
- @user
32
- end
33
- }
34
- end
35
-
36
- it "should have the club_id set" do
37
- @entity.club_id.should eq(@club.id)
38
- end
39
- it "should load club" do
40
- @entity.club.should eq(@club)
41
- end
42
- it "should call entity_loader with club id" do
43
- @entity_loader.should_receive(:get).with(@club.id)
44
- @entity.club
45
- end
46
- it "should have the user_id set" do
47
- @entity.user_id.should eq(@user.id)
48
- end
49
- it "should load user" do
50
- @entity.user.should eq(@user)
51
- end
52
- it "should call entity_loader with user id" do
53
- @entity_loader.should_receive(:get).with(@user.id)
54
- @entity.user
55
- end
56
-
57
- context "when only user loaded" do
58
- before(:each) do
59
- @entity.user
60
- end
61
-
62
- it "should only have user in the loaded related entities collection" do
63
- @entity.loaded_related_entities.should eq([@user])
64
- end
65
- end
66
-
67
- context "when both user and club loaded" do
68
- before(:each) do
69
- @entity.club
70
- @entity.user
71
- end
72
-
73
- it "should only have user in the loaded related entities collection" do
74
- @entity.loaded_related_entities.should eq([@club, @user])
75
- end
76
- end
77
- end
78
18
 
79
19
  describe "#attributes" do
80
20
  before(:each) do
81
- @entity = DummyEntity.new(:id => @id = random_object_id, :club_id => @club_id = random_string,
21
+ @entity = DummyEntity.new(:id => @id = random_object_id, :club_id => @club_id = random_string,
82
22
  :user_id => @user_id = random_string, :name => @name = random_string, :version => @version = random_integer,
83
23
  :members => [], things: [ ThingEntityValue.new(name: random_string), ThingEntityValue.new(name: random_string) ],
84
24
  other_things_dictionary: { random_string => ThingEntityValue.new(name: random_string) } )
@@ -88,8 +28,7 @@ describe Entity do
88
28
 
89
29
  it "returns a hash of the attributes" do
90
30
  subject.should eq({
91
- :id => @id, :version => @version, :name => @name, :club_id => @club_id,
92
- :user_id => @user_id, :description => nil, :members => [],
31
+ :id => @id, :version => @version, :name => @name, :description => nil, :members => [],
93
32
  :things => @entity.things.map { |t| { name: t.name } },
94
33
  :other_things_dictionary => { @entity.other_things_dictionary.keys.first => { name: @entity.other_things_dictionary.values.first.name }}
95
34
  })
@@ -183,7 +122,7 @@ describe Entity do
183
122
  end
184
123
  it "should set items" do
185
124
  entity.things.each_with_index do |item, i| item.should be(items[i]) end
186
- end
125
+ end
187
126
  end
188
127
  context "when something else in array" do
189
128
  let(:items) { [ random_string, random_string ] }
@@ -248,7 +187,7 @@ describe Entity do
248
187
 
249
188
  it "should set items" do
250
189
  ids.each do |id| entity.other_things_dictionary[id].name.should eq(items[id].name) end
251
- end
190
+ end
252
191
  end
253
192
  context "when something else in array" do
254
193
  let(:items) { { ids[0] => random_string, ids[1] => random_string } }
@@ -268,7 +207,7 @@ describe Entity do
268
207
  end
269
208
 
270
209
  describe "hash initialisation, ie from snapshot" do
271
- let(:attributes) { { other_things_dictionary: { ids[0] => { name: random_string }, ids[1] => { name: random_string } } } }
210
+ let(:attributes) { { other_things_dictionary: { ids[0] => { name: random_string }, ids[1] => { name: random_string } } } }
272
211
 
273
212
  subject { DummyEntity.new(attributes) }
274
213
 
@@ -56,7 +56,7 @@ describe MongoEntityStore do
56
56
  store.add_event(third_event)
57
57
  end
58
58
 
59
- subject { store.get_events(event_entity_id, since_version) }
59
+ subject { store.get_events( [{ id: event_entity_id, since_version: since_version }])[event_entity_id] }
60
60
 
61
61
  context "all events" do
62
62
  let(:event_entity_id) { entity_id }
@@ -86,7 +86,7 @@ describe MongoEntityStore do
86
86
  end
87
87
  end
88
88
 
89
- describe "#get_entity" do
89
+ describe "#get_entities" do
90
90
  let(:entity_class) { DummyEntity }
91
91
 
92
92
  let(:saved_entity) do
@@ -95,23 +95,26 @@ describe MongoEntityStore do
95
95
  entity
96
96
  end
97
97
 
98
- subject { store.get_entity(saved_entity.id) }
98
+ let(:id) { saved_entity.id }
99
+ let(:options) { { } }
100
+
101
+ subject { store.get_entities( [ id ], options) }
99
102
 
100
103
  it "should retrieve an entity from the store with the same ID" do
101
- subject.id.should == saved_entity.id
104
+ subject.first.id.should == saved_entity.id
102
105
  end
103
106
 
104
107
  it "should retrieve an entity from the store with the same class" do
105
- subject.class.should == saved_entity.class
108
+ subject.first.class.should == saved_entity.class
106
109
  end
107
110
 
108
111
  it "should have the same version" do
109
- subject.version.should == saved_entity.version
112
+ subject.first.version.should == saved_entity.version
110
113
  end
111
114
 
112
115
  context "when a snapshot does not exist" do
113
116
  it "should not have set the name" do
114
- subject.name.should be_nil
117
+ subject.first.name.should be_nil
115
118
  end
116
119
  end
117
120
 
@@ -123,7 +126,7 @@ describe MongoEntityStore do
123
126
 
124
127
  context "when a snapshot key not in use" do
125
128
  it "should have set the name" do
126
- subject.name.should == saved_entity.name
129
+ subject.first.name.should == saved_entity.name
127
130
  end
128
131
  end
129
132
 
@@ -132,7 +135,7 @@ describe MongoEntityStore do
132
135
 
133
136
  context "when the key matches the class's key" do
134
137
  it "should have set the name" do
135
- subject.name.should == saved_entity.name
138
+ subject.first.name.should == saved_entity.name
136
139
  end
137
140
  end
138
141
 
@@ -142,29 +145,26 @@ describe MongoEntityStore do
142
145
  end
143
146
 
144
147
  it "should ignore the invalidated snapshot" do
145
- subject.name.should be_nil
148
+ subject.first.name.should be_nil
146
149
  end
147
150
  end
148
151
  end
149
152
  end
150
- end
151
-
152
- describe "#get_entity!" do
153
- context "when invalid id format passed" do
154
- subject { store.get_entity!(random_string) }
155
153
 
156
- it "should raise not found" do
157
- expect { subject }.to raise_error(NotFound)
154
+ describe "context when enable exceptions" do
155
+ let(:options) do
156
+ { raise_exception: true }
158
157
  end
159
- end
160
158
 
161
- context "when valid id format passed but no object exists" do
162
- subject { store.get_entity!(random_object_id) }
159
+ context "when invalid id format passed" do
160
+ let(:id) { random_string }
163
161
 
164
- it "should raise not found" do
165
- expect { subject }.to raise_error(NotFound)
162
+ it "should raise not found" do
163
+ expect { subject }.to raise_error(NotFound)
164
+ end
166
165
  end
167
166
  end
167
+
168
168
  end
169
169
 
170
170
  describe "#snapshot_entity" do
@@ -77,30 +77,7 @@ describe Store do
77
77
  end
78
78
 
79
79
  describe "#save" do
80
- context "when entity has related entities loaded" do
81
- before(:each) do
82
- @entity = DummyEntityForStore.new(:id => random_string)
83
- @entity.version = random_integer * EntityStore::Config.snapshot_threshold + 1
84
- @store = Store.new
85
- @related_entity = double('Entity')
86
- @entity.stub(:loaded_related_entities) { [ @related_entity ] }
87
- @store.stub(:do_save)
88
- end
89
-
90
- subject { @store.save(@entity) }
91
-
92
- it "should save the entity" do
93
- @store.should_receive(:do_save).with(@entity)
94
- subject
95
- end
96
- it "should save them as well" do
97
- @store.should_receive(:do_save).with(@related_entity)
98
- subject
99
- end
100
- end
101
- end
102
80
 
103
- describe "#do_save" do
104
81
  before(:each) do
105
82
  @new_id = random_string
106
83
  @entity = DummyEntityForStore.new(:id => random_string)
@@ -112,7 +89,7 @@ describe Store do
112
89
  @entity.stub(:pending_events) { [ double('Event') ] }
113
90
  end
114
91
 
115
- subject { @store.do_save(@entity) }
92
+ subject { @store.save(@entity) }
116
93
 
117
94
  it "increments the entity version number" do
118
95
  expect { subject }.to change { @entity.version }.by 1
@@ -176,45 +153,84 @@ describe Store do
176
153
 
177
154
  end
178
155
 
179
- describe "#get" do
180
- before(:each) do
181
- @id = random_integer
182
- @entity = DummyEntityForStore.new(id: random_string, version: random_integer)
183
- DummyEntityForStore.stub(:new).and_return(@entity)
184
- @events = [
185
- double("Event", apply: true, entity_version: @entity.version + 1),
186
- double("Event", apply: true, entity_version: @entity.version + 2)
187
- ]
188
-
189
- @storage_client = double("StorageClient", :get_entity => @entity, :get_events => @events)
190
- @store = Store.new
191
- @store.stub(:storage_client) { @storage_client }
156
+ describe "getters" do
157
+ let(:ids) { [ random_string, random_string, random_string ] }
158
+ let(:entities) { ids.map { |id| DummyEntityForStore.new(id: id, version: random_integer) } }
159
+ let(:events) do
160
+ Hash[ ids.map do |id|
161
+ [
162
+ id,
163
+ [
164
+ double("Event", apply: true, entity_version: entities.find { |e| e.id == id } .version + 1),
165
+ double("Event", apply: true, entity_version: entities.find { |e| e.id == id } .version + 2)
166
+ ]
167
+ ]
168
+ end ]
192
169
  end
193
170
 
194
- subject { @store.get(@id) }
171
+ let(:storage_client) { double("StorageClient") }
172
+ let(:store) { Store.new }
195
173
 
196
- it "should retrieve object from the storage client" do
197
- @storage_client.should_receive(:get_entity).with(@id, false)
198
- subject
199
- end
200
- it "should assign itself as the related_entity_loader" do
201
- @entity.should_receive(:related_entity_loader=).with(@store)
202
- subject
203
- end
204
- it "should return a ride" do
205
- subject.should eq(@entity)
206
- end
207
- it "should retrieve it's events" do
208
- @storage_client.should_receive(:get_events).with(@id, @entity.version)
209
- subject
174
+ before(:each) do
175
+ storage_client.stub(:get_entities) do |ids|
176
+ entities.select { |e| ids.include?(e.id) }
177
+ end
178
+
179
+ storage_client.stub(:get_events) do |criteria|
180
+ Hash[ criteria.map { |c| [ c[:id], events[c[:id]] ] }]
181
+ end
182
+ store.stub(:storage_client) { storage_client }
210
183
  end
211
- it "should apply each event to the entity" do
212
- @events.each do |event| event.should_receive(:apply).with(@entity) end
213
- subject
184
+ describe "#get" do
185
+ let(:entity) { entities[1] }
186
+ let(:id) { entity.id }
187
+
188
+ subject { store.get(id) }
189
+
190
+ it "should retrieve object from the storage client" do
191
+ storage_client.should_receive(:get_entities).with([id], { raise_exception: false })
192
+ subject
193
+ end
194
+ it "should return the entity" do
195
+ subject.id.should eq(entity.id)
196
+ end
197
+ it "should apply each event to the entity" do
198
+ events[id].each do |event|
199
+ event.should_receive(:apply).with(entity)
200
+ end
201
+ subject
202
+ end
203
+ it "should set the entity version to that of the last event" do
204
+ subject
205
+ entity.version.should eq(events[id].last.entity_version)
206
+ end
214
207
  end
215
- it "should set the entity version to that of the last event" do
216
- subject
217
- @entity.version.should eq(@events.last.entity_version)
208
+
209
+ describe "#get_with_ids" do
210
+
211
+ subject { store.get_with_ids(ids) }
212
+
213
+ it "should retrieve object from the storage client" do
214
+ storage_client.should_receive(:get_entities).with(ids, {})
215
+ subject
216
+ end
217
+ it "should return the entities" do
218
+ subject.map { |e| e.id }.should eq(ids)
219
+ end
220
+ it "should apply each event to the entities" do
221
+ entities.each do |entity|
222
+ events[entity.id].each do |event|
223
+ event.should_receive(:apply).with(entity)
224
+ end
225
+ end
226
+ subject
227
+ end
228
+ it "should set the entity version to that of the last event" do
229
+ subject
230
+ entities.each do |entity|
231
+ entity.version.should eq(events[entity.id].last.entity_version)
232
+ end
233
+ end
218
234
  end
219
235
  end
220
236
  end
metadata CHANGED
@@ -1,55 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: entity_store
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.15
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Bird
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-24 00:00:00.000000000 Z
11
+ date: 2014-05-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mongo
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.8'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.8'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bson_ext
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '1.8'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.8'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: hatchet
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0.2'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ~>
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0.2'
55
55
  description: Event sourced entity store with a replaceable body
@@ -96,12 +96,12 @@ require_paths:
96
96
  - lib
97
97
  required_ruby_version: !ruby/object:Gem::Requirement
98
98
  requirements:
99
- - - '>='
99
+ - - ">="
100
100
  - !ruby/object:Gem::Version
101
101
  version: '0'
102
102
  required_rubygems_version: !ruby/object:Gem::Requirement
103
103
  requirements:
104
- - - '>='
104
+ - - ">="
105
105
  - !ruby/object:Gem::Version
106
106
  version: '0'
107
107
  requirements: []