1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66888 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
eregon 2019-01-20 20:38:57 +00:00
parent 58573c33e4
commit 6204e0804b
147 changed files with 2728 additions and 21522 deletions

View file

@ -0,0 +1,11 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::ArithmeticSequence#begin" do
it "returns the begin of the sequence" do
1.step(10).begin.should == 1
(1..10).step.begin.should == 1
(1...10).step.begin.should == 1
end
end
end

View file

@ -0,0 +1,19 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::ArithmeticSequence#each" do
before :each do
ScratchPad.record []
@seq = 1.step(10, 4)
end
it "calls given block on each item of the sequence" do
@seq.each { |item| ScratchPad << item }
ScratchPad.recorded.should == [1, 5, 9]
end
it "returns self" do
@seq.each { |item| }.should equal(@seq)
end
end
end

View file

@ -0,0 +1,11 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::ArithmeticSequence#end" do
it "returns the end of the sequence" do
1.step(10).end.should == 10
(1..10).step.end.should == 10
(1...10).step(17).end.should == 10
end
end
end

View file

@ -0,0 +1,20 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::ArithmeticSequence#==" do
it "returns true if begin, end, step and exclude_end? are equal" do
1.step(10).should == 1.step(10)
1.step(10, 5).should == 1.step(10, 5)
(1..10).step.should == (1..10).step
(1...10).step(8).should == (1...10).step(8)
# both have exclude_end? == false
(1..10).step(100).should == 1.step(10, 100)
((1..10).step == (1..11).step).should == false
((1..10).step == (1...10).step).should == false
((1..10).step == (1..10).step(2)).should == false
end
end
end

View file

@ -0,0 +1,19 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::ArithmeticSequence#exclude_end?" do
context "when created using Numeric#step" do
it "always returns false" do
1.step(10).exclude_end?.should == false
10.step(1).exclude_end?.should == false
end
end
context "when created using Range#step" do
it "mirrors range.exclude_end?" do
(1...10).step.exclude_end?.should == true
(1..10).step.exclude_end?.should == false
end
end
end
end

View file

@ -0,0 +1,11 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::ArithmeticSequence#first" do
it "returns the first element of the sequence" do
1.step(10).first.should == 1
(1..10).step.first.should == 1
(1...10).step.first.should == 1
end
end
end

View file

@ -0,0 +1,22 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::ArithmeticSequence#hash" do
it "is based on begin, end, step and exclude_end?" do
1.step(10).hash.should be_an_instance_of(Integer)
1.step(10).hash.should == 1.step(10).hash
1.step(10, 5).hash.should == 1.step(10, 5).hash
(1..10).step.hash.should == (1..10).step.hash
(1...10).step(8).hash.should == (1...10).step(8).hash
# both have exclude_end? == false
(1..10).step(100).hash.should == 1.step(10, 100).hash
((1..10).step.hash == (1..11).step.hash).should == false
((1..10).step.hash == (1...10).step.hash).should == false
((1..10).step.hash == (1..10).step(2).hash).should == false
end
end
end

View file

@ -0,0 +1,22 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::ArithmeticSequence#inspect" do
context 'when Numeric#step is used' do
it "returns '(begin.step(end{, step}))'" do
1.step(10).inspect.should == "(1.step(10))"
1.step(10, 3).inspect.should == "(1.step(10, 3))"
end
end
context 'when Range#step is used' do
it "returns '((range).step{(step)})'" do
(1..10).step.inspect.should == "((1..10).step)"
(1..10).step(3).inspect.should == "((1..10).step(3))"
(1...10).step.inspect.should == "((1...10).step)"
(1...10).step(3).inspect.should == "((1...10).step(3))"
end
end
end
end

View file

@ -0,0 +1,11 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::ArithmeticSequence#last" do
it "returns the last element of the sequence" do
1.step(10).last.should == 10
(1..10).step.last.should == 10
(1...10).step(4).last.should == 9
end
end
end

View file

@ -0,0 +1,19 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::ArithmeticSequence.new" do
it "is not defined" do
lambda {
Enumerator::ArithmeticSequence.new
}.should raise_error(NoMethodError)
end
end
describe "Enumerator::ArithmeticSequence.allocate" do
it "is not defined" do
lambda {
Enumerator::ArithmeticSequence.allocate
}.should raise_error(TypeError, 'allocator undefined for Enumerator::ArithmeticSequence')
end
end
end

View file

@ -0,0 +1,19 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::ArithmeticSequence#size" do
context "for finite sequence" do
it "returns the number of elements in this arithmetic sequence" do
1.step(10).size.should == 10
(1...10).step.size.should == 9
end
end
context "for infinite sequence" do
it "returns Infinity" do
1.step(Float::INFINITY).size.should == Float::INFINITY
(1..Float::INFINITY).step.size.should == Float::INFINITY
end
end
end
end

View file

@ -0,0 +1,15 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::ArithmeticSequence#step" do
it "returns the original value given to step method" do
(1..10).step.step.should == 1
(1..10).step(3).step.should == 3
(1..10).step(0).step.should == 0
1.step(10).step.should == 1
1.step(10, 3).step.should == 3
1.step(10, 0).step.should == 0
end
end
end

View file

@ -0,0 +1,17 @@
require_relative '../../../spec_helper'
require_relative '../../enumerable/fixtures/classes'
ruby_version_is "2.6" do
describe "Enumerator::Chain#each" do
it "calls each on its consistuents as needed" do
a = EnumerableSpecs::EachCounter.new(:a, :b)
b = EnumerableSpecs::EachCounter.new(:c, :d)
ScratchPad.record []
Enumerator::Chain.new(a, b).each do |elem|
ScratchPad << elem << b.times_yielded
end
ScratchPad.recorded.should == [:a, 0, :b, 0, :c, 1, :d, 2]
end
end
end

View file

@ -0,0 +1,33 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::Chain#initialize" do
before :each do
@uninitialized = Enumerator::Chain.allocate
end
it "is a private method" do
Enumerator::Chain.should have_private_instance_method(:initialize, false)
end
it "returns self" do
@uninitialized.send(:initialize).should equal(@uninitialized)
end
it "accepts many arguments" do
@uninitialized.send(:initialize, 0..1, 2..3, 4..5).should equal(@uninitialized)
end
it "accepts arguments that are not Enumerable nor responding to :each" do
@uninitialized.send(:initialize, Object.new).should equal(@uninitialized)
end
describe "on frozen instance" do
it "raises a RuntimeError" do
lambda {
@uninitialized.freeze.send(:initialize)
}.should raise_error(RuntimeError)
end
end
end
end

View file

@ -0,0 +1,16 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::Chain#inspect" do
it "shows a representation of the Enumerator" do
Enumerator::Chain.new.inspect.should == "#<Enumerator::Chain: []>"
Enumerator::Chain.new(1..2, 3..4).inspect.should == "#<Enumerator::Chain: [1..2, 3..4]>"
end
it "calls inspect on its chain elements" do
obj = mock('inspect')
obj.should_receive(:inspect).and_return('some desc')
Enumerator::Chain.new(obj).inspect.should == "#<Enumerator::Chain: [some desc]>"
end
end
end

View file

@ -0,0 +1,53 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::Chain#rewind" do
before(:each) do
@obj = mock('obj')
@obj.should_receive(:each).any_number_of_times.and_yield(42)
@second = mock('obj')
@second.should_receive(:each).any_number_of_times.and_yield(:second)
@enum = Enumerator::Chain.new(@obj, @second)
end
it "returns self" do
@enum.rewind.should equal @enum
end
it "does nothing if receiver has not been iterated" do
@obj.should_not_receive(:rewind)
@obj.respond_to?(:rewind).should == true # sanity check
@enum.rewind
end
it "does nothing on objects that don't respond_to rewind" do
@obj.respond_to?(:rewind).should == false # sanity check
@enum.each {}
@enum.rewind
end
it "calls_rewind its objects" do
@obj.should_receive(:rewind)
@enum.each {}
@enum.rewind
end
it "calls_rewind in reverse order" do
@obj.should_not_receive(:rewind)
@second.should_receive(:rewind).and_raise(RuntimeError)
@enum.each {}
lambda { @enum.rewind }.should raise_error(RuntimeError)
end
it "calls rewind only for objects that have actually been iterated on" do
@obj = mock('obj')
@obj.should_receive(:each).any_number_of_times.and_raise(RuntimeError)
@enum = Enumerator::Chain.new(@obj, @second)
@obj.should_receive(:rewind)
@second.should_not_receive(:rewind)
lambda { @enum.each {} }.should raise_error(RuntimeError)
@enum.rewind
end
end
end

View file

@ -0,0 +1,24 @@
require_relative '../../../spec_helper'
require_relative '../../enumerable/fixtures/classes'
ruby_version_is "2.6" do
describe "Enumerator::Chain#size" do
it "returns the sum of the sizes of the elements" do
a = mock('size')
a.should_receive(:size).and_return(40)
Enumerator::Chain.new(a, [:a, :b]).size.should == 42
end
it "returns nil or Infinity for the first element of such a size" do
[nil, Float::INFINITY].each do |special|
a = mock('size')
a.should_receive(:size).and_return(40)
b = mock('special')
b.should_receive(:size).and_return(special)
c = mock('not called')
c.should_not_receive(:size)
Enumerator::Chain.new(a, b, c).size.should == special
end
end
end
end

View file

@ -1,5 +1,89 @@
require_relative '../../shared/enumerator/each'
require_relative '../../spec_helper'
describe "Enumerator#each" do
it_behaves_like :enum_each, :each
before :each do
object_each_with_arguments = Object.new
def object_each_with_arguments.each_with_arguments(arg, *args)
yield arg, *args
:method_returned
end
@enum_with_arguments = object_each_with_arguments.to_enum(:each_with_arguments, :arg0, :arg1, :arg2)
@enum_with_yielder = Enumerator.new {|y| y.yield :ok}
end
it "yields each element of self to the given block" do
acc = []
[1,2,3].to_enum.each {|e| acc << e }
acc.should == [1,2,3]
end
it "calls #each on the object given in the constructor by default" do
each = mock('each')
each.should_receive(:each)
each.to_enum.each {|e| e }
end
it "calls #each on the underlying object until it's exhausted" do
each = mock('each')
each.should_receive(:each).and_yield(1).and_yield(2).and_yield(3)
acc = []
each.to_enum.each {|e| acc << e }
acc.should == [1,2,3]
end
it "calls the method given in the constructor instead of #each" do
each = mock('peach')
each.should_receive(:peach)
each.to_enum(:peach).each {|e| e }
end
it "calls the method given in the constructor until it's exhausted" do
each = mock('each')
each.should_receive(:each).and_yield(1).and_yield(2).and_yield(3)
acc = []
each.to_enum.each {|e| acc << e }
acc.should == [1,2,3]
end
it "raises a NoMethodError if the object doesn't respond to #each" do
enum = Object.new.to_enum
lambda do
enum.each { |e| e }
end.should raise_error(NoMethodError)
end
it "returns self if not given arguments and not given a block" do
@enum_with_arguments.each.should equal(@enum_with_arguments)
@enum_with_yielder.each.should equal(@enum_with_yielder)
end
it "returns the same value from receiver.each if block is given" do
@enum_with_arguments.each {}.should equal(:method_returned)
end
it "passes given arguments at initialized to receiver.each" do
@enum_with_arguments.each.to_a.should == [[:arg0, :arg1, :arg2]]
end
it "requires multiple arguments" do
Enumerator.instance_method(:each).arity.should < 0
end
it "appends given arguments to receiver.each" do
@enum_with_arguments.each(:each0, :each1).to_a.should == [[:arg0, :arg1, :arg2, :each0, :each1]]
@enum_with_arguments.each(:each2, :each3).to_a.should == [[:arg0, :arg1, :arg2, :each2, :each3]]
end
it "returns the same value from receiver.each if block and arguments are given" do
@enum_with_arguments.each(:each1, :each2) {}.should equal(:method_returned)
end
it "returns new Enumerator if given arguments but not given a block" do
ret = @enum_with_arguments.each 1
ret.should be_an_instance_of(Enumerator)
ret.should_not equal(@enum_with_arguments)
end
end

View file

@ -1,15 +0,0 @@
require_relative '../../shared/enumerator/each'
describe "Enumerator#inject" do
it_behaves_like :enum_each, :each
it "works when chained against each_with_index" do
passed_values = []
[:a].each_with_index.inject(0) do |accumulator,value|
passed_values << value
accumulator + 1
end.should == 1
passed_values.should == [[:a,0]]
end
end

View file

@ -0,0 +1,8 @@
require_relative '../../../spec_helper'
require_relative 'shared/select'
ruby_version_is "2.6" do
describe "Enumerator::Lazy#filter" do
it_behaves_like :enumerator_lazy_select, :filter
end
end

View file

@ -1,6 +1,41 @@
require_relative '../../spec_helper'
require_relative '../../shared/enumerator/new'
describe "Enumerator.new" do
it_behaves_like :enum_new, :new
it "creates a new custom enumerator with the given object, iterator and arguments" do
enum = Enumerator.new(1, :upto, 3)
enum.should be_an_instance_of(Enumerator)
end
it "creates a new custom enumerator that responds to #each" do
enum = Enumerator.new(1, :upto, 3)
enum.respond_to?(:each).should == true
end
it "creates a new custom enumerator that runs correctly" do
Enumerator.new(1, :upto, 3).map{|x|x}.should == [1,2,3]
end
it "aliases the second argument to :each" do
Enumerator.new(1..2).to_a.should == Enumerator.new(1..2, :each).to_a
end
it "doesn't check for the presence of the iterator method" do
Enumerator.new(nil).should be_an_instance_of(Enumerator)
end
it "uses the latest define iterator method" do
class StrangeEach
def each
yield :foo
end
end
enum = Enumerator.new(StrangeEach.new)
enum.to_a.should == [:foo]
class StrangeEach
def each
yield :bar
end
end
enum.to_a.should == [:bar]
end
end

View file

@ -1,6 +1,27 @@
require_relative '../../spec_helper'
require_relative '../../shared/enumerator/next'
describe "Enumerator#next" do
it_behaves_like :enum_next,:next
before :each do
@enum = 1.upto(3)
end
it "returns the next element of the enumeration" do
@enum.next.should == 1
@enum.next.should == 2
@enum.next.should == 3
end
it "raises a StopIteration exception at the end of the stream" do
3.times { @enum.next }
lambda { @enum.next }.should raise_error(StopIteration)
end
it "cannot be called again until the enumerator is rewound" do
3.times { @enum.next }
lambda { @enum.next }.should raise_error(StopIteration)
lambda { @enum.next }.should raise_error(StopIteration)
lambda { @enum.next }.should raise_error(StopIteration)
@enum.rewind
@enum.next.should == 1
end
end

View file

@ -0,0 +1,35 @@
require_relative '../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator#+" do
before :each do
ScratchPad.record []
end
it "returns a chain of self and provided enumerators" do
one = Enumerator.new { |y| y << 1 }
two = Enumerator.new { |y| y << 2 }
three = Enumerator.new { |y| y << 3 }
chain = one + two + three
chain.should be_an_instance_of(Enumerator::Chain)
chain.each { |item| ScratchPad << item }
ScratchPad.recorded.should == [1, 2, 3]
end
it "calls #each on each argument" do
enum = Enumerator.new { |y| y << "one" }
obj1 = mock("obj1")
obj1.should_receive(:each).once.and_yield("two")
obj2 = mock("obj2")
obj2.should_receive(:each).once.and_yield("three")
chain = enum + obj1 + obj2
chain.each { |item| ScratchPad << item }
ScratchPad.recorded.should == ["one", "two", "three"]
end
end
end

View file

@ -1,9 +1,41 @@
require_relative '../../spec_helper'
require_relative '../../shared/enumerator/rewind'
require_relative 'fixtures/common'
describe "Enumerator#rewind" do
it_behaves_like :enum_rewind, :rewind
before :each do
@enum = 1.upto(3)
end
it "resets the enumerator to its initial state" do
@enum.next.should == 1
@enum.next.should == 2
@enum.rewind
@enum.next.should == 1
end
it "returns self" do
@enum.rewind.should == @enum
end
it "has no effect on a new enumerator" do
@enum.rewind
@enum.next.should == 1
end
it "has no effect if called multiple, consecutive times" do
@enum.next.should == 1
@enum.rewind
@enum.rewind
@enum.next.should == 1
end
it "works with peek to reset the position" do
@enum.next
@enum.next
@enum.rewind
@enum.next
@enum.peek.should == 2
end
it "calls the enclosed object's rewind method if one exists" do
obj = mock('rewinder')