1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
require File.expand_path('../../../spec_helper', __FILE__)
# force reload for Prime::method_added and Prime::instance
Object.send(:remove_const, :Prime) if defined?(Prime)
load 'prime.rb'
describe :prime_each, :shared => true do
before :each do
ScratchPad.record []
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.new" do
before :each do
@object = Prime.new
end
it_behaves_like :prime_each, :each
it "does not rewind the enumerator with each call" do
@object.each { |prime| break if prime > 10 }
@object.each { |prime| break prime }.should == 13
end
end
|