2018-03-04 10:09:32 -05:00
|
|
|
require_relative '../../spec_helper'
|
2017-05-07 08:04:49 -04:00
|
|
|
require 'prime'
|
|
|
|
|
|
|
|
describe :prime_each, shared: true do
|
|
|
|
before :each do
|
|
|
|
ScratchPad.record []
|
|
|
|
end
|
|
|
|
|
|
|
|
it "enumerates primes" do
|
|
|
|
primes = Prime.instance
|
|
|
|
result = []
|
|
|
|
|
|
|
|
primes.each { |p|
|
|
|
|
result << p
|
|
|
|
break if p > 10
|
|
|
|
}
|
|
|
|
|
|
|
|
result.should == [2, 3, 5, 7, 11]
|
|
|
|
end
|
|
|
|
|
|
|
|
it "yields ascending primes to the block" do
|
|
|
|
previous = 1
|
|
|
|
@object.each do |prime|
|
|
|
|
break if prime > 1000
|
|
|
|
ScratchPad << prime
|
|
|
|
prime.should > previous
|
|
|
|
previous = prime
|
|
|
|
end
|
|
|
|
|
|
|
|
all_prime = true
|
|
|
|
ScratchPad.recorded.all? do |prime|
|
|
|
|
all_prime &&= (2..Math.sqrt(prime)).all? { |d| prime % d != 0 }
|
|
|
|
end
|
|
|
|
|
|
|
|
all_prime.should be_true
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns the last evaluated expression in the passed block" do
|
|
|
|
@object.each { break :value }.should equal(:value)
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "when not passed a block" do
|
|
|
|
before :each do
|
|
|
|
@prime_enum = @object.each
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns an object that is Enumerable" do
|
|
|
|
@prime_enum.each.should be_kind_of(Enumerable)
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns an object that responds to #with_index" do
|
|
|
|
@prime_enum.should respond_to(:with_index)
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns an object that responds to #with_object" do
|
|
|
|
@prime_enum.should respond_to(:with_object)
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns an object that responds to #next" do
|
|
|
|
@prime_enum.should respond_to(:next)
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns an object that responds to #rewind" do
|
|
|
|
@prime_enum.should respond_to(:rewind)
|
|
|
|
end
|
|
|
|
|
|
|
|
it "yields primes starting at 2 independent of prior enumerators" do
|
|
|
|
@prime_enum.next.should == 2
|
|
|
|
@prime_enum.next.should == 3
|
|
|
|
|
|
|
|
@object.each { |prime| break prime }.should == 2
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns an enumerator that yields previous primes when #rewind is called" do
|
|
|
|
@prime_enum.next.should == 2
|
|
|
|
@prime_enum.next.should == 3
|
|
|
|
@prime_enum.rewind
|
|
|
|
@prime_enum.next.should == 2
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns independent enumerators" do
|
|
|
|
enum = @object.each
|
|
|
|
enum.next.should == 2
|
|
|
|
enum.next.should == 3
|
|
|
|
|
|
|
|
@prime_enum.next.should == 2
|
|
|
|
|
|
|
|
enum.next.should == 5
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe :prime_each_with_arguments, shared: true do
|
|
|
|
before :each do
|
|
|
|
ScratchPad.record []
|
|
|
|
end
|
|
|
|
|
|
|
|
it "yields ascending primes less than or equal to the argument" do
|
|
|
|
bound = 1000
|
|
|
|
previous = 1
|
|
|
|
@object.each(bound) do |prime|
|
|
|
|
ScratchPad << prime
|
|
|
|
prime.should > previous
|
|
|
|
previous = prime
|
|
|
|
end
|
|
|
|
|
|
|
|
ScratchPad.recorded.all? do |prime|
|
|
|
|
(2..Math.sqrt(prime)).all? { |d| prime % d != 0 }
|
|
|
|
end.should be_true
|
|
|
|
|
|
|
|
ScratchPad.recorded.all? { |prime| prime <= bound }.should be_true
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns nil when no prime is generated" do
|
|
|
|
@object.each(1) { :value }.should be_nil
|
|
|
|
end
|
|
|
|
|
|
|
|
it "yields primes starting at 2 independent of prior enumeration" do
|
|
|
|
@object.each(10) { |prime| prime }.should == 7
|
|
|
|
@object.each(10) { |prime| break prime }.should == 2
|
|
|
|
end
|
|
|
|
|
|
|
|
it "accepts a pseudo-prime generator as the second argument" do
|
|
|
|
generator = mock('very bad pseudo-prime generator')
|
|
|
|
generator.should_receive(:upper_bound=).with(100)
|
|
|
|
generator.should_receive(:each).and_yield(2).and_yield(3).and_yield(4)
|
|
|
|
|
|
|
|
@object.each(100, generator) { |prime| ScratchPad << prime }
|
|
|
|
ScratchPad.recorded.should == [2, 3, 4]
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "when not passed a block" do
|
|
|
|
it "returns an object that returns primes less than or equal to the bound" do
|
|
|
|
bound = 100
|
|
|
|
@object.each(bound).all? { |prime| prime <= bound }.should be_true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "Prime.each" do
|
|
|
|
it_behaves_like :prime_each, :each, Prime
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "Prime.each" do
|
|
|
|
it_behaves_like :prime_each_with_arguments, :each, Prime
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "Prime#each with Prime.instance" do
|
|
|
|
it_behaves_like :prime_each, :each, Prime.instance
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "Prime#each with Prime.instance" do
|
|
|
|
it_behaves_like :prime_each_with_arguments, :each, Prime.instance
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "Prime#each with Prime.instance" do
|
|
|
|
before :each do
|
|
|
|
@object = Prime.instance
|
|
|
|
end
|
|
|
|
|
|
|
|
it_behaves_like :prime_each, :each
|
|
|
|
|
|
|
|
it "resets the enumerator with each call" do
|
|
|
|
@object.each { |prime| break if prime > 10 }
|
|
|
|
@object.each { |prime| break prime }.should == 2
|
|
|
|
end
|
|
|
|
end
|