Skip to content

Commit

Permalink
Merge 012cdee into a827119
Browse files Browse the repository at this point in the history
  • Loading branch information
ermaker committed Aug 10, 2016
2 parents a827119 + 012cdee commit dbcd630
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/cool.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@

# The list of classes in Cool module
module Cool
autoload :Retriable, 'cool/retriable'
end
22 changes: 22 additions & 0 deletions lib/cool/retriable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module Cool
# Retriable
module Retriable
def retry_(new_method, on: StandardError, times: 3, &condition) # rubocop:disable Metrics/MethodLength, Metrics/LineLength
condition ||= ->(*) { false }
orig_method = "__retry_orig_#{new_method}".to_sym
alias_method orig_method, new_method
define_method(new_method) do |*args, &block|
(times - 1).times do
retval =
begin
method(orig_method).call(*args, &block)
rescue on
next
end
return retval unless condition.call(retval)
end
return method(orig_method).call(*args, &block)
end
end
end
end
138 changes: 138 additions & 0 deletions spec/lib/cool/retriable_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
RSpec.describe Cool::Retriable do
describe '#retry_' do
it 'works' do
retriable = described_class
klass = Class.new do
extend retriable

ENUM = [:no, :no, :yes].to_enum
def do_it
ENUM.next
end
retry_(:do_it) { |retval| retval == :no }
end

expect(klass.new.do_it).to eq(:yes)
end

it 'works' do
retriable = described_class
klass = Class.new do
extend retriable

ENUM = [:no, :no, :no].to_enum
def do_it
ENUM.next
end
retry_(:do_it) { |retval| retval == :no }
end

expect(klass.new.do_it).to eq(:no)
end

it 'works' do
retriable = described_class
klass = Class.new do
extend retriable

ENUM = [nil, nil, :yes].to_enum
def do_it
ENUM.next
end
retry_(:do_it, &:nil?)
end

expect(klass.new.do_it).to eq(:yes)
end

it 'works' do
retriable = described_class
klass = Class.new do
extend retriable

ENUM = [[], {}, :yes].to_enum
def do_it
ENUM.next
end
retry_(:do_it, &:empty?)
end

expect(klass.new.do_it).to eq(:yes)
end

it 'works' do
retriable = described_class
klass = Class.new do
extend retriable

ENUM = [:no, :no, :yes].to_enum
def do_it
ENUM.next.tap { |value| raise if value == :no }
end
retry_(:do_it)
end

expect(klass.new.do_it).to eq(:yes)
end

it 'works' do
retriable = described_class
klass = Class.new do
extend retriable

ENUM = [:no, :no, :no].to_enum
def do_it
ENUM.next.tap { |value| raise if value == :no }
end
retry_(:do_it)
end

expect { klass.new.do_it }.to raise_error(StandardError)
end

it 'works' do
retriable = described_class
klass = Class.new do
extend retriable

ENUM = [:no].to_enum
def do_it
ENUM.next.tap { |value| raise if value == :no }
end
retry_(:do_it, times: 1)
end

expect { klass.new.do_it }.to raise_error(StandardError)
end

it 'works' do
retriable = described_class
klass = Class.new do
extend retriable

ENUM = [:error, nil, :yes].to_enum
def do_it
ENUM.next.tap { |value| raise if value == :error }
end
retry_(:do_it, &:nil?)
end

expect(klass.new.do_it).to eq(:yes)
end

it 'works' do
retriable = described_class
klass = Class.new do
extend retriable

ENUM = [:yes, :error].to_enum
def do_it
ENUM.next.tap { |value| raise if value == :error }
end
retry_(:do_it)
end

expect(klass.new.do_it).to eq(:yes)
end
end
end

0 comments on commit dbcd630

Please sign in to comment.