save_queue 0.2.3 → 0.3.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.
Files changed (38) hide show
  1. data/.gitignore +13 -4
  2. data/.travis.yml +4 -1
  3. data/CONTRIBUTING.md +120 -0
  4. data/HISTORY.md +11 -0
  5. data/LICENSE +13 -4
  6. data/README.md +282 -55
  7. data/Rakefile +10 -3
  8. data/lib/save_queue/exceptions.rb +13 -0
  9. data/lib/save_queue/object.rb +41 -18
  10. data/lib/save_queue/object_queue.rb +87 -0
  11. data/lib/save_queue/plugins/notification/object.rb +35 -0
  12. data/lib/save_queue/plugins/notification/queue.rb +25 -0
  13. data/lib/save_queue/plugins/notification.rb +15 -0
  14. data/lib/save_queue/plugins/validation/exceptions.rb +12 -0
  15. data/lib/save_queue/plugins/validation/queue.rb +16 -17
  16. data/lib/save_queue/plugins/validation.rb +4 -17
  17. data/lib/save_queue/ruby1.9/observer.rb +204 -0
  18. data/lib/save_queue/uniq_queue.rb +38 -0
  19. data/lib/save_queue/version.rb +1 -1
  20. data/lib/save_queue.rb +1 -0
  21. data/save_queue.gemspec +4 -3
  22. data/spec/notification/notification_spec.rb +45 -0
  23. data/spec/notification/object_spec.rb +54 -0
  24. data/spec/notification/queue_spec.rb +28 -0
  25. data/spec/object_queue_spec.rb +155 -0
  26. data/spec/object_spec.rb +208 -0
  27. data/spec/save_queue_spec.rb +75 -0
  28. data/spec/support/object_helpers.rb +10 -0
  29. data/spec/support/queue_helpers.rb +26 -0
  30. data/spec/uniq_queue_spec.rb +132 -0
  31. data/spec/validation/queue_spec.rb +139 -0
  32. data/spec/validation/validation_spec.rb +42 -0
  33. metadata +35 -20
  34. data/lib/save_queue/plugins/validation/object.rb +0 -25
  35. data/lib/save_queue/queue.rb +0 -45
  36. data/spec/save_queue_usage_spec.rb +0 -311
  37. data/spec/support/mock_helpers.rb +0 -17
  38. data/spec/validation_spec.rb +0 -126
@@ -0,0 +1,139 @@
1
+ require "spec_helper"
2
+ require "save_queue/plugins/validation/queue"
3
+
4
+ class ValidQueue < SaveQueue::ObjectQueue
5
+ include SaveQueue::Plugins::Validation::Queue
6
+ end
7
+
8
+
9
+ describe ValidQueue do
10
+ let(:queue) { ValidQueue.new }
11
+
12
+ context "contains valid objects" do
13
+ let(:valid_objects) do
14
+ 3.times.map do
15
+ new_velement(:valid => true)
16
+ end
17
+ end
18
+
19
+ before(:each) do
20
+ queue.add_all valid_objects
21
+ end
22
+
23
+ describe "#save" do
24
+ it "should save all of them" do
25
+ valid_objects.each{|o| o.should_receive(:save).once}
26
+ queue.save.should be_true
27
+ end
28
+
29
+ it "should not has any errors" do
30
+ queue.save.should be_true
31
+ queue.errors.should be_empty
32
+ end
33
+ end
34
+
35
+ describe "#save!" do
36
+ it "should save all of them" do
37
+ valid_objects.each{|o| o.should_receive(:save).once}
38
+ queue.save!
39
+ end
40
+
41
+ it "should not raise any exception" do
42
+ expect { queue.save! }.not_to raise_error
43
+ end
44
+
45
+ it "should not has any errors" do
46
+ queue.save!
47
+ queue.errors.should be_empty
48
+ end
49
+ end
50
+ end
51
+
52
+
53
+ describe "contains invalid objects" do
54
+ let(:invalid_objects) do
55
+ 3.times.map do
56
+ new_velement(:valid => false)
57
+ end
58
+ end
59
+
60
+ before(:each) do
61
+ queue.add_all invalid_objects
62
+ end
63
+
64
+ describe "#save" do
65
+ it "should not saved them" do
66
+ invalid_objects.each{|o| o.should_not_receive(:save)}
67
+ queue.save.should be_false
68
+ end
69
+
70
+ it "should set errors" do
71
+ queue.save.should be_false
72
+ queue.errors[:validation].should_not be_empty
73
+ end
74
+ end
75
+
76
+ describe "#save!" do
77
+ it "should not saved them" do
78
+ invalid_objects.each do |o|
79
+ o.as_null_object
80
+ o.should_not_receive(:save)
81
+ end
82
+
83
+ expect {queue.save!}.to raise_error
84
+ end
85
+
86
+ it "should raise SaveQueue::FailedValidationError exception" do
87
+ expect { queue.save! }.to raise_error(SaveQueue::FailedValidationError)
88
+ end
89
+
90
+ it "should set errors" do
91
+ expect{queue.save!}.to raise_error
92
+ queue.errors[:validation].should_not be_empty
93
+ end
94
+ end
95
+ end
96
+
97
+
98
+ #before(:each) do
99
+ # @invalid = new_object
100
+ # @invalid.stub(:valid?).and_return(false)
101
+ # @valid = new_object
102
+ # @valid.stub(:valid?).and_return(true)
103
+ #end
104
+
105
+ #describe SaveQueue::Plugins::Validation::Queue do
106
+ # before(:each) do
107
+ # @save_queue = SaveQueue::Plugins::Validation::Queue.new
108
+ # end
109
+ #
110
+ # describe "#valid?" do
111
+ # it "should set objects_with_errors" do
112
+ # @save_queue.add @invalid
113
+ # @save_queue.add @valid
114
+ #
115
+ # @save_queue.valid?.should be_false
116
+ #
117
+ # @save_queue.objects_with_errors.should include @invalid
118
+ # @save_queue.objects_with_errors.should_not include @valid
119
+ # end
120
+ # end
121
+ #
122
+ # describe "#validate!" do
123
+ # it "should raise FailedValidationError if failed to save objects" do
124
+ # @save_queue.add @invalid
125
+ # @save_queue.add @valid
126
+ #
127
+ # expect{ @save_queue.validate! }.to raise_error SaveQueue::Plugins::Validation::FailedValidationError
128
+ # end
129
+ #
130
+ # it "should return true if objects were valid" do
131
+ # @save_queue.add @valid
132
+ #
133
+ # expect{ @save_queue.validate! }.not_to raise_error SaveQueue::Plugins::Validation::FailedValidationError
134
+ #
135
+ # @save_queue.validate!.should be_true
136
+ # end
137
+ # end
138
+ #end
139
+ end
@@ -0,0 +1,42 @@
1
+ require "spec_helper"
2
+ require "save_queue/plugins/validation"
3
+
4
+ describe SaveQueue::Plugins::Validation do
5
+ describe "#integration" do
6
+ it "should mix Queue to object's save_queue" do
7
+ klass = new_class
8
+ klass.send :include, SaveQueue::Plugins::Validation
9
+
10
+ klass.queue_class.should include SaveQueue::Plugins::Validation::Queue
11
+ end
12
+
13
+ it "should not change original SaveQueue::*Queue class" do
14
+ klass = new_class
15
+ old_queue = klass.queue_class
16
+ klass.queue_class = Class.new(old_queue)
17
+
18
+ klass.send :include, SaveQueue::Plugins::Validation
19
+ old_queue.should_not include SaveQueue::Plugins::Validation::Queue
20
+ end
21
+ end
22
+
23
+ describe "workflow" do
24
+ let(:object) do
25
+ klass = new_class
26
+ klass.send :include, SaveQueue::Plugins::Validation
27
+ klass.new
28
+ end
29
+
30
+ describe "#save" do
31
+ it "should not return false if save_queue was saved" do
32
+ object.save_queue << new_velement(:valid => true)
33
+ object.save.should_not be_false
34
+ end
35
+
36
+ it "should return false if save_queue was not saved" do
37
+ object.save_queue << new_velement(:valid => false)
38
+ object.save.should be_false
39
+ end
40
+ end
41
+ end
42
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: save_queue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-19 00:00:00.000000000Z
12
+ date: 2012-01-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &18192820 !ruby/object:Gem::Requirement
16
+ requirement: &7350280 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '2.6'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *18192820
24
+ version_requirements: *7350280
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &18192160 !ruby/object:Gem::Requirement
27
+ requirement: &7366200 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *18192160
35
+ version_requirements: *7366200
36
36
  - !ruby/object:Gem::Dependency
37
- name: activesupport
38
- requirement: &18190480 !ruby/object:Gem::Requirement
37
+ name: hooks
38
+ requirement: &7365720 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,11 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *18190480
47
- description: Save Queue allows to push related objects to an object's queue for delayed
48
- save, that will triggered on object#save. In this case object wil store all related
49
- information on its save.
46
+ version_requirements: *7365720
47
+ description: ! 'Save Queue allows to push objects to other object''s queue for a delayed
48
+ save.
49
+
50
+ Queue save will be triggered by object#save.'
50
51
  email:
51
52
  - alexander.n.paramonov@gmail.com
52
53
  executables: []
@@ -56,23 +57,38 @@ files:
56
57
  - .gitignore
57
58
  - .rspec
58
59
  - .travis.yml
60
+ - CONTRIBUTING.md
59
61
  - Gemfile
60
62
  - HISTORY.md
61
63
  - LICENSE
62
64
  - README.md
63
65
  - Rakefile
64
66
  - lib/save_queue.rb
67
+ - lib/save_queue/exceptions.rb
65
68
  - lib/save_queue/object.rb
69
+ - lib/save_queue/object_queue.rb
70
+ - lib/save_queue/plugins/notification.rb
71
+ - lib/save_queue/plugins/notification/object.rb
72
+ - lib/save_queue/plugins/notification/queue.rb
66
73
  - lib/save_queue/plugins/validation.rb
67
- - lib/save_queue/plugins/validation/object.rb
74
+ - lib/save_queue/plugins/validation/exceptions.rb
68
75
  - lib/save_queue/plugins/validation/queue.rb
69
- - lib/save_queue/queue.rb
76
+ - lib/save_queue/ruby1.9/observer.rb
77
+ - lib/save_queue/uniq_queue.rb
70
78
  - lib/save_queue/version.rb
71
79
  - save_queue.gemspec
72
- - spec/save_queue_usage_spec.rb
80
+ - spec/notification/notification_spec.rb
81
+ - spec/notification/object_spec.rb
82
+ - spec/notification/queue_spec.rb
83
+ - spec/object_queue_spec.rb
84
+ - spec/object_spec.rb
85
+ - spec/save_queue_spec.rb
73
86
  - spec/spec_helper.rb
74
- - spec/support/mock_helpers.rb
75
- - spec/validation_spec.rb
87
+ - spec/support/object_helpers.rb
88
+ - spec/support/queue_helpers.rb
89
+ - spec/uniq_queue_spec.rb
90
+ - spec/validation/queue_spec.rb
91
+ - spec/validation/validation_spec.rb
76
92
  homepage: http://github.com/AlexParamonov/save_queue
77
93
  licenses: []
78
94
  post_install_message:
@@ -93,9 +109,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
93
109
  version: '0'
94
110
  requirements: []
95
111
  rubyforge_project: save_queue
96
- rubygems_version: 1.8.11
112
+ rubygems_version: 1.8.13
97
113
  signing_key:
98
114
  specification_version: 3
99
- summary: Push related objects to a queue for delayed save
115
+ summary: Push related objects to a queue for a delayed save
100
116
  test_files: []
101
- has_rdoc:
@@ -1,25 +0,0 @@
1
- module SaveQueue
2
- module Plugins
3
- module Validation
4
- # Should be included AFTER SaveQueue
5
- module Object
6
- module RunAlwaysFirst
7
- # @return [Boolean]
8
- def save(*args)
9
- # are objects in queue valid?
10
- return false unless valid?
11
- return false unless save_queue.valid?
12
-
13
- super
14
- end
15
- end
16
-
17
- def initialize(*args)
18
- super
19
- # this will make RunAlwaysFirst methods triggered first in inheritance tree
20
- extend RunAlwaysFirst
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,45 +0,0 @@
1
- module SaveQueue
2
- class Queue
3
- def initialize
4
- @queue = []
5
- end
6
-
7
- def add_all objects
8
- Array(objects).each do |object|
9
- add object
10
- end
11
- end
12
-
13
- def add object
14
- raise ArgumentError, "#{object.inspect} does not include SaveQueue::Object" unless object.class.include? SaveQueue::Object
15
- @queue << object unless @queue.include? object
16
- end
17
-
18
- def save
19
- saved = []
20
- @queue.each do |object|
21
- if object.has_unsaved_changes?
22
-
23
- result = object.save
24
- raise FailedSaveError, {:saved => saved, :failed => object, :pending => @queue - (saved + [object])} if false == result
25
-
26
- saved << object
27
- end
28
- end
29
- @queue = []
30
-
31
- true
32
- end
33
- end
34
-
35
- class FailedSaveError < RuntimeError
36
- attr_reader :context
37
- def initialize(context_hash)
38
- @context = context_hash
39
- end
40
-
41
- def to_s # Some default way to display errors
42
- "#{super}: " + @context.to_s
43
- end
44
- end
45
- end
@@ -1,311 +0,0 @@
1
- require "spec_helper"
2
-
3
- # TODO split by Object and Queue
4
- describe "SaveQueue usage" do
5
- before(:each) do
6
- @base = new_object
7
- @related_object = new_object
8
- end
9
-
10
- describe "#has_unsaved_changes?" do
11
- it "should return true for changed object" do
12
- @base.save
13
- @base.should_not have_unsaved_changes
14
- @base.mark_as_changed
15
- @base.should have_unsaved_changes
16
- end
17
-
18
- it "should return false for saved object" do
19
- @base.mark_as_changed
20
- @base.should have_unsaved_changes
21
- @base.save
22
- @base.should_not have_unsaved_changes
23
- end
24
-
25
- it "should return false for new object" do
26
- klass = Class.new
27
- klass.send :include, SaveQueue
28
-
29
- klass.new.should_not have_unsaved_changes
30
- end
31
- end
32
-
33
- describe "#add" do
34
- it "should ignore same objects in queue" do
35
- @base.save_queue.add @related_object
36
- @base.save_queue.add @related_object
37
- @base.save_queue.add @related_object
38
-
39
- @related_object.should_receive(:save).once.and_return(true)
40
- @base.save.should be_true
41
- @base.save.should be_true
42
- end
43
-
44
- it "should raise ArgumentError if object does not include SavedQueue" do
45
- object = new_mock_object :without_include
46
- object.stub_chain(:class, :include?).with(SaveQueue::Object).and_return(false)
47
-
48
- expect{ @base.save_queue.add object }.to raise_error ArgumentError, "#{object.inspect} does not include SaveQueue::Object"
49
- end
50
-
51
- it "should not raise ArgumentError if object includes SavedQueue" do
52
- object = new_mock_object :with_include
53
- object.stub_chain(:class, :include?).with(SaveQueue::Object).and_return(true)
54
-
55
- expect{ @base.save_queue.add object }.to_not raise_error ArgumentError, "#{object.inspect} does not include SaveQueue::Object"
56
- end
57
- end
58
-
59
- describe "#add_all" do
60
- it "should delegate to #add" do
61
- @base.save_queue.should_receive(:add).exactly(3).times
62
- @base.save_queue.add_all [1,2,3]
63
- end
64
- end
65
-
66
- describe "#save" do
67
- it "should raise SaveQueue::FailedSaveError if at least one object in queue is not saved" do
68
- @base.save_queue.add @related_object
69
- bad_object = new_mock_object :bad_object
70
- bad_object.stub(:save).and_return(false)
71
-
72
- @base.save_queue.add bad_object
73
-
74
-
75
- expect{ @base.save_queue.save }.to raise_error SaveQueue::FailedSaveError
76
- #, {:saved => [@related_object],
77
- # :failed => bad_object,
78
- # :pending => []}
79
- end
80
-
81
- it "should save assigned object" do
82
- @base.save_queue.add @related_object
83
-
84
- @related_object.should_receive(:save).once.and_return(true)
85
- @base.save.should be_true
86
- end
87
-
88
- it "only 1st save will save the queue" do
89
- @base.save_queue.add @related_object
90
-
91
- @related_object.should_receive(:save).once.and_return(true)
92
- @base.save.should be_true
93
- @base.save.should be_true
94
- end
95
-
96
- it "should not circle" do
97
- object = new_object
98
-
99
- @base.mark_as_changed
100
-
101
- object.save_queue.add @base
102
- @base.save_queue.add object
103
-
104
- $object_counter = mock :counter
105
- $object_counter.should_receive(:increment).once
106
-
107
- def object.save
108
- result = super
109
- $object_counter.increment
110
-
111
- result
112
- end
113
-
114
- $base_counter = mock :counter
115
- $base_counter.should_receive(:increment).once
116
-
117
- def @base.save
118
- result = super
119
- $base_counter.increment
120
-
121
- result
122
- end
123
-
124
-
125
-
126
- #object.should_receive(:save).once.and_return(true)
127
- #@base.should_receive(:save).once.and_return(true)
128
- @base.save.should be_true
129
- end
130
-
131
- it "should save only unsaved objects" do
132
- object = new_object
133
-
134
- @base.save_queue.add object
135
- object.save
136
-
137
- object.should_not_receive(:save)
138
- @base.save_queue.save.should be_true
139
- end
140
-
141
- it "should save and object if it had changed state" do
142
- object = new_object
143
-
144
- @base.save_queue.add object
145
- object.save
146
- object.mark_as_changed
147
-
148
- object.should_receive(:save).once.and_return(true)
149
- @base.save.should be_true
150
- end
151
-
152
- describe "multiple callers" do
153
- before(:each) do
154
- @base2 = new_object
155
- end
156
-
157
- it "should save assigned object only once" do
158
- object = new_object
159
-
160
- @base.save_queue.add object
161
- @base2.save_queue.add object
162
-
163
- $counter = mock :counter
164
- $counter.should_receive(:increment).once
165
-
166
- def object.save
167
- result = super
168
- $counter.increment
169
-
170
- result
171
- end
172
-
173
- #object.should_receive(:save).once.and_return(true)
174
- @base.save.should be_true
175
- @base2.save.should be_true
176
- end
177
-
178
- it "should correctly save all objects once" do
179
-
180
- $base_counters = []
181
- 3.times do |index|
182
- object = new_object
183
- $base_counters[index] = mock :counter
184
- $base_counters[index].should_receive(:increment).once
185
- eval %{
186
- def object.save
187
- result = super
188
- $base_counters[#{index}].increment
189
-
190
- result
191
- end
192
- }
193
-
194
- @base.save_queue.add object
195
- end
196
-
197
- $base2_counters = []
198
- 2.times do |index|
199
- object = new_object
200
- $base2_counters[index] = mock :counter
201
- $base2_counters[index].should_receive(:increment).once
202
- eval %{
203
- def object.save
204
- result = super
205
- $base2_counters[#{index}].increment
206
-
207
- result
208
- end
209
- }
210
-
211
- @base2.save_queue.add object
212
- end
213
-
214
- $shared_counters = []
215
- 2.times do |index|
216
- object = new_object
217
- $shared_counters[index] = mock :counter
218
- $shared_counters[index].should_receive(:increment).once
219
- eval %{
220
- def object.save
221
- result = super
222
- $shared_counters[#{index}].increment
223
-
224
- result
225
- end
226
- }
227
-
228
- @base.save_queue.add object
229
- @base2.save_queue.add object
230
- end
231
-
232
- @base.save.should be_true
233
- @base2.save.should be_true
234
- end
235
- end
236
- end
237
-
238
- describe "queue changes" do
239
- it "should be able to change queue class before initialization" do
240
- klass = Class.new
241
- klass.send :include, SaveQueue
242
- object = klass.new
243
- object.save_queue.should be_a SaveQueue::Queue
244
-
245
- other = Class.new(SaveQueue::Queue)
246
- klass.queue_class = other
247
- klass.new.save_queue.should be_kind_of other
248
-
249
- object.class.queue_class = other
250
- object.save_queue.should_not be_kind_of other
251
- object.save_queue.should be_a SaveQueue::Queue
252
- end
253
-
254
- describe "inheritance" do
255
- it "should inherit settings of parent class" do
256
- klass = Class.new
257
- klass.send :include, SaveQueue
258
-
259
- klass.queue_class.should == SaveQueue::Queue
260
-
261
- child = Class.new(klass)
262
- child.queue_class.should == SaveQueue::Queue
263
- end
264
-
265
- it "should not override settings of parent class" do
266
- klass = Class.new
267
- klass.send :include, SaveQueue
268
- klass.queue_class.should == SaveQueue::Queue
269
-
270
- child = Class.new(klass)
271
- child.queue_class = Integer
272
- child.queue_class.should == Integer
273
-
274
- klass.queue_class.should == SaveQueue::Queue
275
- end
276
-
277
-
278
- it "include SaveQueue should not override settings of parent class" do
279
- klass = Class.new
280
- klass.send :include, SaveQueue
281
- klass.queue_class = Integer
282
-
283
- klass.queue_class.should == Integer
284
-
285
- child = Class.new(klass)
286
- child.send :include, SaveQueue
287
- child.queue_class.should == Integer
288
- end
289
- end
290
- end
291
-
292
- private
293
- def new_mock_object name
294
- bad_object = mock name
295
- bad_object.stub_chain(:class, :include?).with(SaveQueue::Object).and_return(true)
296
- bad_object.stub(:save).and_return(true)
297
- bad_object.stub(:has_unsaved_changes?).and_return(true)
298
-
299
- bad_object
300
- end
301
-
302
- def new_object
303
- klass = Class.new
304
- klass.send :include, SaveQueue
305
-
306
- object = klass.new
307
- object.mark_as_changed
308
-
309
- object
310
- end
311
- end
@@ -1,17 +0,0 @@
1
- #def new_mock_object name
2
- # bad_object = mock name
3
- # bad_object.stub_chain(:class, :include?).with(SaveQueue::Object).and_return(true)
4
- # bad_object.stub(:valid?).and_return(true)
5
- # bad_object.stub(:save).and_return(true)
6
- # bad_object.stub(:has_unsaved_changes?).and_return(true)
7
- #
8
- # bad_object
9
- #end
10
- #
11
- #def new_object
12
- # object = Tests::Object.new
13
- # object.stub(:valid?).and_return(true)
14
- # object.mark_as_changed
15
- #
16
- # object
17
- #end