Skip to content

Instantly share code, notes, and snippets.

@ravinggenius
Last active December 11, 2015 23:58
Show Gist options
  • Save ravinggenius/4680464 to your computer and use it in GitHub Desktop.
Save ravinggenius/4680464 to your computer and use it in GitHub Desktop.
class ListScanner
attr_reader :list
def initialize(list)
@list = list.freeze
reset!
end
def get
reply = list[@index]
@index = @index + 1
reply
end
def get_until(&exit_block)
reply = []
foretell.each do |item|
if exit_block.call(item)
return reply
else
reply << get
end
end
reply
end
def end_of_list?
list.count == @index
end
def glimpse
list[@index]
end
def recount
list[0, @index]
end
def foretell
list[@index..-1]
end
def reset!
@index = 0
end
end
require 'spec_helper'
describe ListScanner do
let(:scanner) { Rip::ListScanner.new((1..10).to_a) }
describe '#get' do
it 'returns the next item' do
expect(scanner.get).to eq(1)
expect(scanner.get).to eq(2)
expect(scanner.get).to eq(3)
expect(scanner.get).to eq(4)
end
end
describe '#get_until' do
let(:get_up_to_six) do
lambda do |item|
item == 6
end
end
it 'returns items until a conditional block returns true' do
expect(scanner.get_until(&get_up_to_six)).to eq([1, 2, 3, 4, 5])
end
context 'after getting a token' do
before(:each) do
scanner.get
end
it 'does not consume the ending item', :focus do
expect(scanner.get_until(&get_up_to_six)).to eq([2, 3, 4, 5])
end
end
end
describe '#recount' do
before(:each) do
3.times do
scanner.get
end
end
it 'returns all items which have been gotten' do
expect(scanner.recount).to eq([1, 2, 3])
end
end
describe '#foretell' do
before(:each) do
4.times do
scanner.get
end
end
it 'returns the next item' do
expect(scanner.foretell).to eq([5, 6, 7, 8, 9, 10])
end
end
describe '#end_of_list?' do
before(:each) do
9.times do
scanner.get
end
end
it 'returns the next item, but does not advance the index' do
expect(scanner.end_of_list?).to be_false
scanner.get
expect(scanner.end_of_list?).to be_true
end
end
describe '#glimpse' do
it 'returns the next item, but does not advance the index' do
expect(scanner.glimpse).to eq(1)
expect(scanner.glimpse).to eq(1)
expect(scanner.glimpse).to eq(1)
end
end
describe '#reset!' do
before(:each) do
4.times do
scanner.get
end
end
it 'returns the next item' do
expect(scanner.get).to eq(5)
scanner.reset!
expect(scanner.get).to eq(1)
end
end
end
@siannopollo
Copy link

You're calling list.each, which starts at the beginning of the list. You really want a representation of the list from the @index onward. If you change list.each to list[@index..-1] that should make the test pass.

@siannopollo
Copy link

Or better yet, use your foretell method.

@ravinggenius
Copy link
Author

Should not be coding so tired. That is one reason I created the #foretell method in the first place!

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment