save_queue 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -11,11 +11,11 @@ Usage
11
11
 
12
12
  How to start:
13
13
 
14
- 1. include SavedQueue:
14
+ 1. include SaveQueue:
15
15
 
16
- require 'saved_queue'
16
+ require 'save_queue'
17
17
  class Artice
18
- include SavedQueue
18
+ include SaveQueue
19
19
  end
20
20
 
21
21
  2. call \#mark_as_saved method when object gets dirty:
@@ -36,20 +36,22 @@ How to start:
36
36
  end
37
37
  end
38
38
 
39
- 4. Save Queue forced you to use valid? method, this should be changes in future and extracted to a module:
39
+ 4. If you want to use validation, include SaveQueue::Plugins::Validation and implement #valid? method. You may got failed objects by save_queue.objects_with_errors
40
40
 
41
41
  class Artice
42
+ include SaveQueue::Plugins::Validation
43
+
42
44
  # @return [boolean]
43
45
  def valid?
44
46
  true
45
47
  end
46
48
  end
47
49
 
48
- 5. add SavedQueue to some other classes:
50
+ 5. add SaveQueue to some other classes:
49
51
 
50
- require 'saved_queue'
52
+ require 'save_queue'
51
53
  class Tag
52
- include SavedQueue
54
+ include SaveQueue
53
55
  end
54
56
 
55
57
  class Artice
@@ -78,6 +80,8 @@ How to start:
78
80
 
79
81
  7. Handle errors
80
82
 
83
+ 7.1. You did not include SaveQueue::Plugins::Validation:
84
+
81
85
  begin
82
86
  article.save
83
87
  rescue SaveQueue::FailedSaveError => save_error
@@ -89,6 +93,13 @@ How to start:
89
93
  save_error.context
90
94
  end
91
95
 
96
+ 7.2. You've included SaveQueue::Plugins::Validation:
97
+
98
+ # Note nothing was actually saved. You dont need to do a cleanup
99
+ unless article.save then
100
+ failed_objects = article.saved_query.objects_with_errors
101
+ end
102
+
92
103
 
93
104
 
94
105
  If you have custom logic for marking objects dirty then you may want to override
@@ -103,9 +114,6 @@ method \#mark_as_saved becomes useless in this case and you should mark objects
103
114
 
104
115
  Note: Today Save Queue use only #save method to perform save actions on an objects, but later this should be changed to custom option.
105
116
 
106
- Note: Save Queue forced you to use valid? method, this should be changes in future and extracted to a module
107
-
108
-
109
117
  Requirements
110
118
  ------------
111
119
  none, rspec2 for testing
@@ -2,13 +2,20 @@ require "save_queue/queue"
2
2
 
3
3
  module SaveQueue
4
4
  module Object
5
+ #class_inheritable_accessor :queue_class
6
+ def self.included base
7
+ base.class_eval do
8
+ class<<self
9
+ attr_accessor :queue_class
10
+ end
11
+
12
+ self.queue_class = Queue
13
+ end
14
+ end
5
15
 
6
16
  module RunAlwaysFirst
7
17
  # @return [Boolean]
8
18
  def save(*args)
9
- # are objects in queue valid?
10
- return false unless valid?
11
- return false unless save_queue.valid?
12
19
  #return false if defined?(super) and false == super
13
20
 
14
21
  super_saved = true
@@ -23,7 +30,7 @@ module SaveQueue
23
30
 
24
31
  def initialize(*args)
25
32
  super if defined?(super)
26
- queue = Queue.new
33
+ queue = self.class.queue_class.new
27
34
  instance_variable_set "@_save_queue", queue
28
35
 
29
36
  # this will make RunAlwaysFirst methods triggered first in inheritance tree
@@ -1,13 +1,23 @@
1
1
  module SaveQueue
2
2
  module Plugins
3
3
  module Validation
4
+ # Should be included AFTER SaveQueue
4
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?
5
12
 
6
- # @return [Boolean]
7
- def save(*args)
8
- # are objects in queue valid?
9
- return false unless valid?
10
- return false unless save_queue.valid?
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
11
21
  end
12
22
  end
13
23
  end
@@ -0,0 +1,34 @@
1
+ require "save_queue/queue"
2
+ module SaveQueue
3
+ module Plugins
4
+ module Validation
5
+ class Queue < ::SaveQueue::Queue
6
+ attr_reader :objects_with_errors
7
+
8
+ def initialize(*args)
9
+ @objects_with_errors = []
10
+ super
11
+ end
12
+
13
+ def valid?
14
+ @objects_with_errors = []
15
+ @queue.each do |object|
16
+ @objects_with_errors << object unless object.valid?
17
+ end
18
+
19
+ @objects_with_errors.empty?
20
+ end
21
+
22
+ def validate!
23
+ raise FailedValidationError, @objects_with_errors unless valid?
24
+
25
+ true
26
+ end
27
+
28
+ def errors
29
+ @objects_with_errors.map(&:errors).reduce(:+)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,28 @@
1
+ require "save_queue/queue"
2
+
3
+ require "save_queue/plugins/validation/object"
4
+ require "save_queue/plugins/validation/queue"
5
+
6
+
7
+ module SaveQueue
8
+ module Plugins
9
+ module Validation
10
+ def self.included base
11
+ # must be included after SaveQueue::Object
12
+ base.send :include, Validation::Object
13
+ base.queue_class = Validation::Queue
14
+ end
15
+
16
+ class FailedValidationError < RuntimeError
17
+ attr_reader :failed_objects
18
+ def initialize(failed_objects)
19
+ @failed_objects = Array(failed_objects)
20
+ end
21
+
22
+ def to_s # Some default way to display errors
23
+ "#{super}: " + @failed_objects.map{|object| "\"#{object.to_s}\": " + object.errors.full_messages.join(', ')}.join("\n")
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -30,12 +30,6 @@ module SaveQueue
30
30
 
31
31
  true
32
32
  end
33
-
34
- def valid?
35
- @queue.all? do |object|
36
- object.valid?
37
- end
38
- end
39
33
  end
40
34
 
41
35
  class FailedSaveError < RuntimeError
@@ -1,3 +1,3 @@
1
1
  module SaveQueue
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/save_queue.rb CHANGED
@@ -5,6 +5,4 @@ module SaveQueue
5
5
  def self.included base
6
6
  base.send :include, SaveQueue::Object
7
7
  end
8
-
9
-
10
8
  end
@@ -1,9 +1,4 @@
1
- require "save_queue"
2
- module Tests
3
- class Object
4
- include SaveQueue
5
- end
6
- end
1
+ require "spec_helper"
7
2
 
8
3
  # TODO split by Object and Queue
9
4
  describe "SaveQueue usage" do
@@ -28,7 +23,10 @@ describe "SaveQueue usage" do
28
23
  end
29
24
 
30
25
  it "should return false for new object" do
31
- Tests::Object.new.should_not have_unsaved_changes
26
+ klass = Class.new
27
+ klass.send :include, SaveQueue
28
+
29
+ klass.new.should_not have_unsaved_changes
32
30
  end
33
31
  end
34
32
 
@@ -58,7 +56,7 @@ describe "SaveQueue usage" do
58
56
  end
59
57
  end
60
58
 
61
- describe "add_all" do
59
+ describe "#add_all" do
62
60
  it "should delegate to #add" do
63
61
  @base.save_queue.should_receive(:add).exactly(3).times
64
62
  @base.save_queue.add_all [1,2,3]
@@ -151,38 +149,6 @@ describe "SaveQueue usage" do
151
149
  @base.save.should be_true
152
150
  end
153
151
 
154
- context "invalid caller" do
155
- it "should not save queue" do
156
- @base.save_queue.add @related_object
157
-
158
- @base.stub(:valid?).and_return(false)
159
-
160
- @related_object.should_not_receive(:save)
161
- @base.save.should be_false
162
-
163
- #@base.stub(:valid?).and_return(true)
164
- #@related_object.should_receive(:save).once.and_return(true)
165
- #@base.save.should be_true
166
- end
167
- end
168
-
169
- describe "invalid object in queue" do
170
- it "should not save queue and caller" do
171
- invalid = new_mock_object :invalid
172
- invalid.stub(:valid?).and_return(false)
173
-
174
- valid = new_mock_object :valid
175
- valid.stub(:valid?).and_return(true)
176
-
177
- @base.save_queue.add invalid
178
- @base.save_queue.add valid
179
-
180
- invalid.should_not_receive(:save)
181
- valid.should_not_receive(:save)
182
- @base.save.should be_false
183
- end
184
- end
185
-
186
152
  describe "multiple callers" do
187
153
  before(:each) do
188
154
  @base2 = new_object
@@ -269,11 +235,27 @@ describe "SaveQueue usage" do
269
235
  end
270
236
  end
271
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
+ end
254
+
272
255
  private
273
256
  def new_mock_object name
274
257
  bad_object = mock name
275
258
  bad_object.stub_chain(:class, :include?).with(SaveQueue::Object).and_return(true)
276
- bad_object.stub(:valid?).and_return(true)
277
259
  bad_object.stub(:save).and_return(true)
278
260
  bad_object.stub(:has_unsaved_changes?).and_return(true)
279
261
 
@@ -281,12 +263,12 @@ describe "SaveQueue usage" do
281
263
  end
282
264
 
283
265
  def new_object
284
- object = Tests::Object.new
285
- object.stub(:valid?).and_return(true)
266
+ klass = Class.new
267
+ klass.send :include, SaveQueue
268
+
269
+ object = klass.new
286
270
  object.mark_as_changed
287
271
 
288
272
  object
289
273
  end
290
-
291
-
292
274
  end
@@ -0,0 +1,2 @@
1
+ require "save_queue"
2
+ Dir[File.dirname(File.expand_path(__FILE__)) + "/support/**/*.rb"].each {|f| require f}
@@ -0,0 +1,17 @@
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
@@ -0,0 +1,126 @@
1
+ require "spec_helper"
2
+ require "save_queue/plugins/validation"
3
+
4
+ describe SaveQueue::Plugins::Validation do
5
+ before(:each) do
6
+ @invalid = new_object
7
+ @invalid.stub(:valid?).and_return(false)
8
+ @valid = new_object
9
+ @valid.stub(:valid?).and_return(true)
10
+ end
11
+
12
+ describe SaveQueue::Plugins::Validation::Object do
13
+ before(:each) do
14
+ @base = new_object
15
+ end
16
+
17
+ context "valid object and caller" do
18
+ before(:each) do
19
+ @base.save_queue.add @valid
20
+ @base.stub(:valid?).and_return(true)
21
+ end
22
+
23
+ it "should save caller" do
24
+ @base.save.should be_true
25
+ end
26
+
27
+ it "should save queue" do
28
+ @valid.should_receive(:save)
29
+
30
+ @base.save
31
+ end
32
+ end
33
+
34
+ context "invalid caller" do
35
+ it "should not save queue" do
36
+ @base.save_queue.add @valid
37
+
38
+ @base.stub(:valid?).and_return(false)
39
+
40
+ @valid.should_not_receive(:save)
41
+ @base.save.should be_false
42
+ end
43
+ end
44
+
45
+ context "invalid object in queue" do
46
+ before(:each) do
47
+ @base.save_queue.add @valid
48
+ @base.save_queue.add @invalid
49
+ end
50
+
51
+ it "should not save caller" do
52
+ @base.save.should be_false
53
+ end
54
+
55
+ it "should not save queue" do
56
+ @invalid.should_not_receive(:save)
57
+ @valid.should_not_receive(:save)
58
+
59
+ @base.save
60
+ end
61
+ end
62
+ end
63
+
64
+ describe SaveQueue::Plugins::Validation::Queue do
65
+ before(:each) do
66
+ @save_queue = SaveQueue::Plugins::Validation::Queue.new
67
+ end
68
+
69
+ describe "#valid?" do
70
+ it "should set objects_with_errors" do
71
+ @save_queue.add @invalid
72
+ @save_queue.add @valid
73
+
74
+ @save_queue.valid?.should be_false
75
+
76
+ @save_queue.objects_with_errors.should include @invalid
77
+ @save_queue.objects_with_errors.should_not include @valid
78
+ end
79
+ end
80
+
81
+ describe "#validate!" do
82
+ it "should raise FailedValidationError if failed to save objects" do
83
+ @save_queue.add @invalid
84
+ @save_queue.add @valid
85
+
86
+ expect{ @save_queue.validate! }.to raise_error SaveQueue::Plugins::Validation::FailedValidationError
87
+ end
88
+
89
+ it "should return true if objects were valid" do
90
+ @save_queue.add @valid
91
+
92
+ expect{ @save_queue.validate! }.to_not raise_error SaveQueue::Plugins::Validation::FailedValidationError
93
+
94
+ @save_queue.validate!.should be_true
95
+ end
96
+ end
97
+ end
98
+
99
+ describe "#integration" do
100
+ before(:each) do
101
+ @klass = Class.new
102
+ @klass.send :include, SaveQueue
103
+ @klass.send :include, SaveQueue::Plugins::Validation
104
+ end
105
+ it "should set query_class to SaveQueue::Plugins::Validation::Queue" do
106
+ @klass.queue_class.should == SaveQueue::Plugins::Validation::Queue
107
+ end
108
+
109
+ it "should mix SaveQueue::Plugins::Validation::Object" do
110
+ @klass.should include SaveQueue::Plugins::Validation::Object
111
+ end
112
+ end
113
+
114
+ private
115
+ def new_object
116
+ klass = Class.new
117
+ klass.send :include, SaveQueue
118
+ klass.send :include, SaveQueue::Plugins::Validation
119
+
120
+ object = klass.new
121
+ object.stub(:valid?).and_return(true)
122
+ object.mark_as_changed
123
+
124
+ object
125
+ end
126
+ 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.1.0
4
+ version: 0.2.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-15 00:00:00.000000000Z
12
+ date: 2011-11-16 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &23937520 !ruby/object:Gem::Requirement
16
+ requirement: &5065560 !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: *23937520
24
+ version_requirements: *5065560
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &23936900 !ruby/object:Gem::Requirement
27
+ requirement: &5059980 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *23936900
35
+ version_requirements: *5059980
36
36
  description: Save Queue allows to push related objects to an object's queue for delayed
37
37
  save, that will triggered on object#save. In this case object wil store all related
38
38
  information on its save.
@@ -52,12 +52,16 @@ files:
52
52
  - Rakefile
53
53
  - lib/save_queue.rb
54
54
  - lib/save_queue/object.rb
55
+ - lib/save_queue/plugins/validation.rb
55
56
  - lib/save_queue/plugins/validation/object.rb
56
57
  - lib/save_queue/plugins/validation/queue.rb
57
58
  - lib/save_queue/queue.rb
58
59
  - lib/save_queue/version.rb
59
60
  - save_queue.gemspec
60
61
  - spec/save_queue_usage_spec.rb
62
+ - spec/spec_helper.rb
63
+ - spec/support/mock_helpers.rb
64
+ - spec/validation_spec.rb
61
65
  homepage: http://github.com/AlexParamonov/save_queue
62
66
  licenses: []
63
67
  post_install_message:
@@ -78,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
78
82
  version: '0'
79
83
  requirements: []
80
84
  rubyforge_project: save_queue
81
- rubygems_version: 1.8.10
85
+ rubygems_version: 1.8.11
82
86
  signing_key:
83
87
  specification_version: 3
84
88
  summary: Push related objects to a queue for delayed save