rescue_each 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -10,7 +10,7 @@ Once of these tasks fails, perhaps there's a corrupt image. Normally this would
10
10
 
11
11
  #### Basics
12
12
 
13
- Simply replace your `each` and `each_with_index` calls with `rescue_each` and `rescue_each_with_index` respectively:
13
+ Simply replace your `each` calls with `rescue_each`:
14
14
 
15
15
  BatchTasks.all.each &:process!
16
16
 
@@ -29,6 +29,13 @@ transforms into:
29
29
 
30
30
  You'll probably find this handy if your batch task normally has its own status output.
31
31
 
32
+ #### Other Methods
33
+
34
+ `rescue_each` provides proxies for `each_with_index`, `find_each` and `find_in_batches`.
35
+ If you want to call another method on an `Enumerable`, you can use `rescue_send`:
36
+
37
+ odds = (1..5).rescue_send(:reject) { |i| i%2 == 0 }
38
+
32
39
  ### Note on Patches/Pull Requests
33
40
 
34
41
  * Fork the project.
data/Rakefile CHANGED
@@ -30,3 +30,8 @@ begin
30
30
  rescue LoadError
31
31
  puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
32
32
  end
33
+
34
+ desc "Open an IRB session with this library loaded"
35
+ task :console do
36
+ sh "irb -rrubygems -I lib -r rescue_each.rb"
37
+ end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.1
1
+ 1.1.0
data/lib/rescue_each.rb CHANGED
@@ -62,32 +62,72 @@ end
62
62
 
63
63
  module Enumerable
64
64
 
65
+ RESCUE_EACH_OPTIONS = [:stderr]
66
+
65
67
  def rescue_each(options = {})
66
68
 
67
- options.assert_valid_keys :stderr, :method
69
+ options.assert_valid_keys :method, :args, *RESCUE_EACH_OPTIONS
68
70
  options.reverse_merge! :method => :each
71
+ options.reverse_merge! :args => []
69
72
 
70
73
  errors = []
71
- send options[:method] do |*args|
74
+ retval = send options[:method], *options[:args] do |*args|
72
75
  begin
73
76
  yield *args.dup
74
77
  rescue Exception => e
78
+
75
79
  item = RescueEach::Error::Item.new e, args
76
80
  if options[:stderr] == :full
77
81
  $stderr.puts "rescue_each error: #{item}" if options[:stderr]
78
82
  elsif options[:stderr]
79
83
  $stderr.puts "rescue_each error: #{item.short_message}"
80
84
  end
85
+
86
+ if e.class.name == 'IRB::Abort'
87
+ if errors.empty?
88
+ raise
89
+ else
90
+ raise ::IRB::Abort, e.message + "\n" + RescueEach::Error.new(errors).to_s
91
+ end
92
+ end
93
+
81
94
  errors << item
95
+
82
96
  end
83
97
  end
84
98
  raise RescueEach::Error, errors unless errors.empty?
85
- self
99
+ return retval
100
+ end
101
+
102
+ def rescue_send(method, *args, &block)
103
+
104
+ args = args.dup
105
+ options = args.extract_options!
106
+ rescue_options = options.reject { |k,v| !RESCUE_EACH_OPTIONS.include? k }
107
+ options.except! *RESCUE_EACH_OPTIONS
108
+ args << options unless options.empty?
109
+
110
+ rescue_options[:method] = method
111
+ rescue_options[:args] = args
112
+
113
+ rescue_each rescue_options, &block
114
+
115
+ end
116
+
117
+ def rescue_map(*args, &block)
118
+ rescue_send :map, *args, &block
119
+ end
120
+
121
+ def rescue_each_with_index(*args, &block)
122
+ rescue_send :each_with_index, *args, &block
123
+ end
124
+
125
+ def rescue_find_each(*args, &block)
126
+ rescue_send :find_each, *args, &block
86
127
  end
87
128
 
88
- def rescue_each_with_index(options = {}, &block)
89
- options = options.reverse_merge :method => :each_with_index
90
- rescue_each(options, &block)
129
+ def rescue_find_in_batches(*args, &block)
130
+ rescue_send :find_in_batches, *args, &block
91
131
  end
92
132
 
93
133
  end
@@ -107,4 +107,72 @@ class RescueEachTest < ActiveSupport::TestCase
107
107
 
108
108
  end
109
109
 
110
+ test "Ctrl-C in IRB should break out of the loop" do
111
+
112
+ module ::IRB
113
+ class Abort < Exception; end
114
+ end
115
+
116
+ error_object = nil
117
+ output = []
118
+ begin
119
+ (1..5).rescue_each do |i|
120
+ raise 'foo bar' if i == 2
121
+ output << i
122
+ raise ::IRB::Abort, 'abort then interrupt!!' if i == 4
123
+ end
124
+ rescue ::IRB::Abort => e
125
+ error_object = e
126
+ end
127
+
128
+ assert_equal [1,3,4], output
129
+ assert_kind_of ::IRB::Abort, error_object
130
+ assert_match /abort then interrupt/, error_object.message
131
+ assert_match /foo bar/, error_object.message
132
+
133
+ end
134
+
135
+ test "no stderr option doesn't output to stderr" do
136
+ err = capture_stderr do
137
+ assert_raise RescueEach::Error do
138
+ [42].rescue_each do
139
+ raise 'foo bar'
140
+ end
141
+ end
142
+ end
143
+ assert_equal '', err
144
+ end
145
+
146
+ test "stderr option outputs to stderr" do
147
+ err = capture_stderr do
148
+ assert_raise RescueEach::Error do
149
+ [42].rescue_each :stderr => true do
150
+ raise 'foo bar'
151
+ end
152
+ end
153
+ end
154
+ assert_match /foo bar/, err
155
+ end
156
+
157
+ test "rescue_send passes through args" do
158
+ assert_true (1..5).rescue_send :include?, 3
159
+ assert_false (1..5).rescue_send :include?, 6
160
+ end
161
+
162
+ test "rescue_send handles rescue_each options" do
163
+ err = capture_stderr do
164
+ assert_raise RescueEach::Error do
165
+ [42].rescue_send :each, :stderr => true do
166
+ raise 'lorem ipsum'
167
+ end
168
+ end
169
+ end
170
+ assert_match /lorem ipsum/, err
171
+ end
172
+
173
+ test "rescue_send returns output of proxied method" do
174
+ output = (1..5).rescue_map { |x| x*x }
175
+ assert_equal [1,4,9,16,25], output
176
+ end
177
+
110
178
  end
data/test/test_helper.rb CHANGED
@@ -4,3 +4,13 @@ require 'test/unit'
4
4
  require 'active_support'
5
5
  require 'active_support/test_case'
6
6
  require 'rescue_each'
7
+
8
+ def capture_stderr
9
+ s = StringIO.new
10
+ oldstderr = $stderr
11
+ $stderr = s
12
+ yield
13
+ s.string
14
+ ensure
15
+ $stderr = oldstderr
16
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rescue_each
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Weathered