entity_store 0.2.15 → 0.3.1

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: 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: []