Skip to content

Commit

Permalink
Merge pull request #44 from SonicGarden/any-enum-with-progress
Browse files Browse the repository at this point in the history
[review] each_with_progress メソッドを追加
  • Loading branch information
aki77 authored Apr 19, 2024
2 parents bdf20b1 + 8743ee9 commit 6d0655f
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 19 deletions.
26 changes: 15 additions & 11 deletions lib/dekiru/data_migration_operator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,26 @@ def duration
((self.ended_at || Time.current) - self.started_at)
end

def find_each_with_progress(target_scope, options = {})
total = options.delete(:total)
opt = {
format: '%a |%b>>%i| %p%% %t',
}.merge(options).merge(
total: total || target_scope.count,
output: stream
)
@pb = ::ProgressBar.create(opt)
target_scope.find_each do |target|
yield target
def each_with_progress(enum, options = {})
options = options.dup
options[:total] ||= ((enum.size == Float::INFINITY ? nil : enum.size) rescue nil)
options[:format] ||= options[:total] ? '%a |%b>>%i| %p%% %t' : '%a |%b>>%i| ??%% %t'
options[:output] = stream

@pb = ::ProgressBar.create(options)
enum.each do |item|
yield item
@pb.increment
end
@pb.finish
end

def find_each_with_progress(target_scope, options = {}, &block)
# `LocalJumpError: no block given (yield)` が出る場合、 find_each メソッドが enumerator を返していない可能性があります
# 直接 each_with_progress を使うか、 find_each が enumerator を返すように修正してください
each_with_progress(target_scope.find_each, options, &block)
end

private

def current_transaction_open?
Expand Down
68 changes: 60 additions & 8 deletions spec/dekiru/data_migration_operator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -106,17 +106,38 @@ def flush
end
end

describe '#find_each_with_progress' do
describe '#each_with_progress' do
it '進捗が表示される' do
record = (0...10)

allow(STDIN).to receive(:gets) do
"yes\n"
end

sum = 0
operator.execute do
each_with_progress(record, title: 'count up number') do |num|
sum += num
end
end

expect(sum).to eq(45)
expect(operator.result).to eq(true)
expect(operator.error).to eq(nil)
expect(operator.stream.out).to include('Are you sure to commit?')
expect(operator.stream.out).to include('count up number:')
expect(operator.stream.out).to include('Finished successfully:')
expect(operator.stream.out).to include('Total time:')
end

it 'total をオプションで渡すことができる' do
class Dekiru::DummyRecord
def self.count
10
raise "won't call"
end

def self.find_each
(0...count).to_a.each do |num|
yield(num)
end
def self.each
yield 99
end
end

Expand All @@ -126,7 +147,34 @@ def self.find_each

sum = 0
operator.execute do
find_each_with_progress(Dekiru::DummyRecord, title: 'count up number') do |num|
each_with_progress(Dekiru::DummyRecord, title: 'pass total as option', total: 1) do |num|
sum += num
end
end

expect(sum).to eq(99)
expect(operator.result).to eq(true)
expect(operator.error).to eq(nil)
expect(operator.stream.out).to include('Are you sure to commit?')
expect(operator.stream.out).to include('pass total as option:')
expect(operator.stream.out).to include('Finished successfully:')
expect(operator.stream.out).to include('Total time:')
end
end

describe '#find_each_with_progress' do
it '進捗が表示される' do
record = (0...10).to_a.tap do |r|
r.singleton_class.alias_method(:find_each, :each)
end

allow(STDIN).to receive(:gets) do
"yes\n"
end

sum = 0
operator.execute do
find_each_with_progress(record, title: 'count up number') do |num|
sum += num
end
end
Expand All @@ -147,7 +195,11 @@ def self.count
end

def self.find_each
yield 99
if block_given?
yield 99
else
Enumerator.new { |y| y << 99 }
end
end
end

Expand Down

0 comments on commit 6d0655f

Please sign in to comment.