From f0bfe4c2a76168c6e85bed4ab06360f6654fcca0 Mon Sep 17 00:00:00 2001 From: Jeremy Bopp Date: Fri, 19 Jun 2020 16:42:58 -0500 Subject: [PATCH 1/2] Simplify pagination using Enumerator::Lazy --- lib/gitlab/paginated_response.rb | 43 +++++++------------------- spec/gitlab/paginated_response_spec.rb | 23 ++++++++++++-- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lib/gitlab/paginated_response.rb b/lib/gitlab/paginated_response.rb index ef06b80eb..e4e652828 100644 --- a/lib/gitlab/paginated_response.rb +++ b/lib/gitlab/paginated_response.rb @@ -42,37 +42,18 @@ def each_page end end - def auto_paginate - response = block_given? ? nil : [] - each_page do |page| - if block_given? - page.each do |item| - yield item - end - else - response += page - end - end - response - end - - def paginate_with_limit(limit) - response = block_given? ? nil : [] - count = 0 - each_page do |page| - if block_given? - page.each do |item| - yield item - count += 1 - break if count >= limit - end - else - response += page[0, limit - count] - count = response.length - end - break if count >= limit - end - response + def lazy_paginate(&b) + to_enum(:each_page).lazy.flat_map(&:to_ary) + end + + def auto_paginate(&b) + return lazy_paginate.to_a unless block_given? + lazy_paginate.each(&b) + end + + def paginate_with_limit(limit, &b) + return lazy_paginate.take(limit).to_a unless block_given? + lazy_paginate.take(limit).each(&b) end def last_page? diff --git a/spec/gitlab/paginated_response_spec.rb b/spec/gitlab/paginated_response_spec.rb index 09e99acae..97119da62 100644 --- a/spec/gitlab/paginated_response_spec.rb +++ b/spec/gitlab/paginated_response_spec.rb @@ -63,6 +63,25 @@ end end + describe '.lazy_paginate' do + it 'returns a lazy enumerator' do + expect(@paginated_response.lazy_paginate).to be_an(Enumerator::Lazy) + end + + it 'only requests needed pages' do + next_page = double('next_page') + allow(@paginated_response).to receive(:has_next_page?).and_return(true) + allow(@paginated_response).to receive(:next_page).and_return(next_page) + allow(next_page).to receive(:has_next_page?).and_return(true) + # NOTE: + # Do not define :next_page on the next_page double to prove that it is NOT + # called even though :has_next_page? has been defined to claim another + # page is available. + allow(next_page).to receive(:to_ary).and_return([5, 6, 7, 8]) + expect(@paginated_response.lazy_paginate.take(8)).to contain_exactly(1, 2, 3, 4, 5, 6, 7, 8) + end + end + describe '.auto_paginate' do it 'returns an array if block is not given' do next_page = double('next_page') @@ -104,7 +123,7 @@ allow(@paginated_response).to receive(:has_next_page?).and_return(true) allow(@paginated_response).to receive(:next_page).and_return(next_page) allow(next_page).to receive(:has_next_page?).and_return(false) - allow(next_page).to receive(:[]).with(0, 1).and_return([5]) + allow(next_page).to receive(:to_ary).and_return([5]) expect(@paginated_response.paginate_with_limit(5)).to contain_exactly(1, 2, 3, 4, 5) end end @@ -115,7 +134,7 @@ allow(@paginated_response).to receive(:has_next_page?).and_return(true) allow(@paginated_response).to receive(:next_page).and_return(next_page) allow(next_page).to receive(:has_next_page?).and_return(false) - allow(next_page).to receive(:each).and_yield(5).and_yield(6).and_yield(7).and_yield(8) + allow(next_page).to receive(:to_ary).and_return([5, 6, 7, 8]) end end From 59bf7eb106533e26f8a38e2f6e8060683e949838 Mon Sep 17 00:00:00 2001 From: Jeremy Bopp Date: Mon, 22 Jun 2020 18:22:30 -0500 Subject: [PATCH 2/2] Satisfy Rubocop requirement on method parameter name length --- lib/gitlab/paginated_response.rb | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/gitlab/paginated_response.rb b/lib/gitlab/paginated_response.rb index e4e652828..07b7e91f9 100644 --- a/lib/gitlab/paginated_response.rb +++ b/lib/gitlab/paginated_response.rb @@ -42,18 +42,20 @@ def each_page end end - def lazy_paginate(&b) + def lazy_paginate to_enum(:each_page).lazy.flat_map(&:to_ary) end - def auto_paginate(&b) + def auto_paginate(&block) return lazy_paginate.to_a unless block_given? - lazy_paginate.each(&b) + + lazy_paginate.each(&block) end - def paginate_with_limit(limit, &b) + def paginate_with_limit(limit, &block) return lazy_paginate.take(limit).to_a unless block_given? - lazy_paginate.take(limit).each(&b) + + lazy_paginate.take(limit).each(&block) end def last_page?