зеркало из https://github.com/github/ruby.git
Update to ruby/spec@740ccc8
This commit is contained in:
Родитель
c99e4c4278
Коммит
83decbb62b
|
@ -115,6 +115,10 @@ Lint/EmptyWhen:
|
|||
- language/case_spec.rb
|
||||
- optional/capi/spec_helper.rb
|
||||
|
||||
Lint/ErbNewArguments:
|
||||
Exclude:
|
||||
- 'library/erb/new_spec.rb'
|
||||
|
||||
Lint/FormatParameterMismatch:
|
||||
Exclude:
|
||||
- 'core/kernel/shared/sprintf.rb'
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# The Ruby Spec Suite
|
||||
|
||||
[![Actions Build Status](https://github.com/ruby/spec/workflows/CI/badge.svg)](https://github.com/ruby/spec/actions)
|
||||
[![Gitter](https://badges.gitter.im/ruby/spec.svg)](https://gitter.im/ruby/spec)
|
||||
|
||||
The Ruby Spec Suite, abbreviated `ruby/spec`, is a test suite for the behavior of the Ruby programming language.
|
||||
|
||||
|
|
|
@ -80,8 +80,16 @@ describe "Array#pack with format 'M'" do
|
|||
].should be_computed_by(:pack, "M")
|
||||
end
|
||||
|
||||
it "encodes a tab followed by a newline with an encoded newline" do
|
||||
it "encodes a tab at the end of a line with an encoded newline" do
|
||||
["\t"].pack("M").should == "\t=\n"
|
||||
["\t\n"].pack("M").should == "\t=\n\n"
|
||||
["abc\t\nxyz"].pack("M").should == "abc\t=\n\nxyz=\n"
|
||||
end
|
||||
|
||||
it "encodes a space at the end of a line with an encoded newline" do
|
||||
[" "].pack("M").should == " =\n"
|
||||
[" \n"].pack("M").should == " =\n\n"
|
||||
["abc \nxyz"].pack("M").should == "abc =\n\nxyz=\n"
|
||||
end
|
||||
|
||||
it "encodes 127..255 in hex format" do
|
||||
|
|
|
@ -56,6 +56,12 @@ describe "Enumerable#each_cons" do
|
|||
multi.each_cons(2).to_a.should == [[[1, 2], [3, 4, 5]], [[3, 4, 5], [6, 7, 8, 9]]]
|
||||
end
|
||||
|
||||
ruby_version_is "3.1" do
|
||||
it "returns self when a block is given" do
|
||||
@enum.each_cons(3){}.should == @enum
|
||||
end
|
||||
end
|
||||
|
||||
describe "when no block is given" do
|
||||
it "returns an enumerator" do
|
||||
e = @enum.each_cons(3)
|
||||
|
|
|
@ -57,6 +57,12 @@ describe "Enumerable#each_slice" do
|
|||
e.to_a.should == @sliced
|
||||
end
|
||||
|
||||
ruby_version_is "3.1" do
|
||||
it "returns self when a block is given" do
|
||||
@enum.each_slice(3){}.should == @enum
|
||||
end
|
||||
end
|
||||
|
||||
it "gathers whole arrays as elements when each yields multiple" do
|
||||
multi = EnumerableSpecs::YieldsMulti.new
|
||||
multi.each_slice(2).to_a.should == [[[1, 2], [3, 4, 5]], [[6, 7, 8, 9]]]
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
require_relative '../../../spec_helper'
|
||||
|
||||
ruby_version_is '3.1' do
|
||||
describe "Enumerator::Lazy#compact" do
|
||||
it 'returns array without nil elements' do
|
||||
arr = [1, nil, 3, false, 5].to_enum.lazy.compact
|
||||
arr.should be_an_instance_of(Enumerator::Lazy)
|
||||
arr.force.should == [1, 3, false, 5]
|
||||
end
|
||||
end
|
||||
end
|
|
@ -30,13 +30,3 @@ describe "Enumerator::Lazy#lazy" do
|
|||
lazy.lazy.should equal(lazy)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.1' do
|
||||
describe "Enumerator::Lazy#compact" do
|
||||
it 'returns array without nil elements' do
|
||||
arr = [1, nil, 3, false, 5].to_enum.lazy.compact
|
||||
arr.should be_an_instance_of(Enumerator::Lazy)
|
||||
arr.force.should == [1, 3, false, 5]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
require_relative '../../spec_helper'
|
||||
|
||||
describe "FalseClass#===" do
|
||||
it "returns true for false" do
|
||||
(false === false).should == true
|
||||
end
|
||||
|
||||
it "returns false for non-false object" do
|
||||
(false === 0).should == false
|
||||
(false === "").should == false
|
||||
(false === Object).should == false
|
||||
(false === nil).should == false
|
||||
end
|
||||
end
|
|
@ -66,8 +66,8 @@ ruby_version_is "3.2" do
|
|||
context "when fiber is non-blocking" do
|
||||
it "can become blocking" do
|
||||
fiber = Fiber.new(blocking: false) do
|
||||
Fiber.blocking do |fiber|
|
||||
fiber.blocking? ? :blocking : :non_blocking
|
||||
Fiber.blocking do |f|
|
||||
f.blocking? ? :blocking : :non_blocking
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -7,4 +7,8 @@ describe :float_to_i, shared: true do
|
|||
-9223372036854775808.1.send(@method).should eql(-9223372036854775808)
|
||||
9223372036854775808.1.send(@method).should eql(9223372036854775808)
|
||||
end
|
||||
|
||||
it "raises a FloatDomainError for NaN" do
|
||||
-> { nan_value.send(@method) }.should raise_error(FloatDomainError)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -41,4 +41,13 @@ describe "Hash#hash" do
|
|||
h.hash.should == {x: [h]}.hash
|
||||
# Like above, because h.eql?(x: [h])
|
||||
end
|
||||
|
||||
ruby_version_is "3.1" do
|
||||
it "allows ommiting values" do
|
||||
a = 1
|
||||
b = 2
|
||||
|
||||
eval('{a:, b:}.should == { a: 1, b: 2 }')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -402,13 +402,6 @@ describe "IO#read in binary mode" do
|
|||
xE2 = [226].pack('C*')
|
||||
result.should == ("abc" + xE2 + "def").force_encoding(Encoding::BINARY)
|
||||
end
|
||||
|
||||
it "does not transcode file contents when an internal encoding is specified" do
|
||||
result = File.open(@name, "r:binary:utf-8") { |f| f.read }.chomp
|
||||
result.encoding.should == Encoding::BINARY
|
||||
xE2 = [226].pack('C*')
|
||||
result.should == ("abc" + xE2 + "def").force_encoding(Encoding::BINARY)
|
||||
end
|
||||
end
|
||||
|
||||
describe "IO#read in text mode" do
|
||||
|
|
|
@ -93,10 +93,12 @@ describe "IO#readpartial" do
|
|||
@rd.readpartial(0).should == ""
|
||||
end
|
||||
|
||||
it "clears and returns the given buffer if the length argument is 0" do
|
||||
buffer = "existing content"
|
||||
@rd.readpartial(0, buffer).should == buffer
|
||||
buffer.should == ""
|
||||
ruby_bug "#18421", ""..."3.0.4" do
|
||||
it "clears and returns the given buffer if the length argument is 0" do
|
||||
buffer = "existing content"
|
||||
@rd.readpartial(0, buffer).should == buffer
|
||||
buffer.should == ""
|
||||
end
|
||||
end
|
||||
|
||||
it "preserves the encoding of the given buffer" do
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require_relative '../../spec_helper'
|
||||
|
||||
describe :io_set_encoding_write, shared: true do
|
||||
it "sets the encodings to nil" do
|
||||
it "sets the encodings to nil when they were set previously" do
|
||||
@io = new_io @name, "#{@object}:ibm437:ibm866"
|
||||
@io.set_encoding nil, nil
|
||||
|
||||
|
@ -9,6 +9,19 @@ describe :io_set_encoding_write, shared: true do
|
|||
@io.internal_encoding.should be_nil
|
||||
end
|
||||
|
||||
it "sets the encodings to nil when the IO is built with no explicit encoding" do
|
||||
@io = new_io @name, @object
|
||||
|
||||
# Checking our assumptions first
|
||||
@io.external_encoding.should be_nil
|
||||
@io.internal_encoding.should be_nil
|
||||
|
||||
@io.set_encoding nil, nil
|
||||
|
||||
@io.external_encoding.should be_nil
|
||||
@io.internal_encoding.should be_nil
|
||||
end
|
||||
|
||||
it "prevents the encodings from changing when Encoding defaults are changed" do
|
||||
@io = new_io @name, "#{@object}:utf-8:us-ascii"
|
||||
@io.set_encoding nil, nil
|
||||
|
@ -38,6 +51,7 @@ describe "IO#set_encoding when passed nil, nil" do
|
|||
@external = Encoding.default_external
|
||||
@internal = Encoding.default_internal
|
||||
|
||||
# The defaults
|
||||
Encoding.default_external = Encoding::UTF_8
|
||||
Encoding.default_internal = nil
|
||||
|
||||
|
@ -113,6 +127,22 @@ describe "IO#set_encoding when passed nil, nil" do
|
|||
describe "with 'a+' mode" do
|
||||
it_behaves_like :io_set_encoding_write, nil, "a+"
|
||||
end
|
||||
|
||||
describe "with standard IOs" do
|
||||
it "correctly resets them" do
|
||||
STDOUT.external_encoding.should == nil
|
||||
STDOUT.internal_encoding.should == nil
|
||||
|
||||
begin
|
||||
STDOUT.set_encoding(Encoding::US_ASCII, Encoding::ISO_8859_1)
|
||||
ensure
|
||||
STDOUT.set_encoding(nil, nil)
|
||||
end
|
||||
|
||||
STDOUT.external_encoding.should == nil
|
||||
STDOUT.internal_encoding.should == nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "IO#set_encoding" do
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
require_relative '../../spec_helper'
|
||||
require_relative '../../shared/kernel/complex'
|
||||
require_relative 'fixtures/Complex'
|
||||
|
||||
describe "Kernel.Complex()" do
|
||||
describe "when passed [Complex, Complex]" do
|
||||
|
@ -58,7 +60,92 @@ describe "Kernel.Complex()" do
|
|||
end
|
||||
end
|
||||
|
||||
describe "when passed a String" do
|
||||
describe "when passed [String]" do
|
||||
it_behaves_like :kernel_complex, :Complex_method, KernelSpecs
|
||||
|
||||
context "invalid argument" do
|
||||
it "raises Encoding::CompatibilityError if String is in not ASCII-compatible encoding" do
|
||||
-> {
|
||||
Complex("79+4i".encode("UTF-16"))
|
||||
}.should raise_error(Encoding::CompatibilityError, "ASCII incompatible encoding: UTF-16")
|
||||
end
|
||||
|
||||
it "raises ArgumentError for unrecognised Strings" do
|
||||
-> {
|
||||
Complex("ruby")
|
||||
}.should raise_error(ArgumentError, 'invalid value for convert(): "ruby"')
|
||||
end
|
||||
|
||||
it "raises ArgumentError for trailing garbage" do
|
||||
-> {
|
||||
Complex("79+4iruby")
|
||||
}.should raise_error(ArgumentError, 'invalid value for convert(): "79+4iruby"')
|
||||
end
|
||||
|
||||
it "does not understand Float::INFINITY" do
|
||||
-> {
|
||||
Complex("Infinity")
|
||||
}.should raise_error(ArgumentError, 'invalid value for convert(): "Infinity"')
|
||||
|
||||
-> {
|
||||
Complex("-Infinity")
|
||||
}.should raise_error(ArgumentError, 'invalid value for convert(): "-Infinity"')
|
||||
end
|
||||
|
||||
it "does not understand Float::NAN" do
|
||||
-> {
|
||||
Complex("NaN")
|
||||
}.should raise_error(ArgumentError, 'invalid value for convert(): "NaN"')
|
||||
end
|
||||
|
||||
it "does not understand a sequence of _" do
|
||||
-> {
|
||||
Complex("7__9+4__0i")
|
||||
}.should raise_error(ArgumentError, 'invalid value for convert(): "7__9+4__0i"')
|
||||
end
|
||||
|
||||
it "does not allow null-byte" do
|
||||
-> {
|
||||
Complex("1-2i\0")
|
||||
}.should raise_error(ArgumentError, "string contains null byte")
|
||||
end
|
||||
end
|
||||
|
||||
context "invalid argument and exception: false passed" do
|
||||
it "raises Encoding::CompatibilityError if String is in not ASCII-compatible encoding" do
|
||||
-> {
|
||||
Complex("79+4i".encode("UTF-16"), exception: false)
|
||||
}.should raise_error(Encoding::CompatibilityError, "ASCII incompatible encoding: UTF-16")
|
||||
end
|
||||
|
||||
it "returns nil for unrecognised Strings" do
|
||||
Complex("ruby", exception: false).should == nil
|
||||
end
|
||||
|
||||
it "returns nil when trailing garbage" do
|
||||
Complex("79+4iruby", exception: false).should == nil
|
||||
end
|
||||
|
||||
it "returns nil for Float::INFINITY" do
|
||||
Complex("Infinity", exception: false).should == nil
|
||||
Complex("-Infinity", exception: false).should == nil
|
||||
end
|
||||
|
||||
it "returns nil for Float::NAN" do
|
||||
Complex("NaN", exception: false).should == nil
|
||||
end
|
||||
|
||||
it "returns nil when there is a sequence of _" do
|
||||
Complex("7__9+4__0i", exception: false).should == nil
|
||||
end
|
||||
|
||||
it "returns nil when String contains null-byte" do
|
||||
Complex("1-2i\0", exception: false).should == nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "when passes [String, String]" do
|
||||
it "needs to be reviewed for spec completeness"
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
module KernelSpecs
|
||||
def self.Complex_method(string)
|
||||
Complex(string)
|
||||
end
|
||||
end
|
|
@ -154,6 +154,22 @@ describe :kernel_load, shared: true do
|
|||
end
|
||||
end
|
||||
|
||||
describe "when passed a module for 'wrap'" do
|
||||
ruby_version_is "3.1" do
|
||||
it "sets the enclosing scope to the supplied module" do
|
||||
path = File.expand_path "wrap_fixture.rb", CODE_LOADING_DIR
|
||||
mod = Module.new
|
||||
@object.load(path, mod)
|
||||
|
||||
Object.const_defined?(:LoadSpecWrap).should be_false
|
||||
mod.const_defined?(:LoadSpecWrap).should be_true
|
||||
|
||||
wrap_module = ScratchPad.recorded[1]
|
||||
wrap_module.should == mod
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "(shell expansion)" do
|
||||
before :each do
|
||||
@env_home = ENV["HOME"]
|
||||
|
|
|
@ -26,6 +26,21 @@ describe "MatchData#[]" do
|
|||
|
||||
it "supports ranges [start..end]" do
|
||||
/(.)(.)(\d+)(\d)/.match("THX1138.")[1..3].should == %w|H X 113|
|
||||
/(.)(.)(\d+)(\d)/.match("THX1138.")[3..10].should == %w|113 8|
|
||||
/(.)(.)(\d+)(\d)/.match("THX1138.")[-30..2].should == nil
|
||||
/(.)(.)(\d+)(\d)/.match("THX1138.")[3..1].should == []
|
||||
end
|
||||
|
||||
it "supports endless ranges [start..]" do
|
||||
/(.)(.)(\d+)(\d)/.match("THX1138.")[3..].should == %w|113 8|
|
||||
end
|
||||
|
||||
it "supports beginningless ranges [..end]" do
|
||||
/(.)(.)(\d+)(\d)/.match("THX1138.")[..1].should == %w|HX1138 H|
|
||||
end
|
||||
|
||||
it "supports beginningless endless ranges [nil..nil]" do
|
||||
/(.)(.)(\d+)(\d)/.match("THX1138.")[nil..nil].should == %w|HX1138 H X 113 8|
|
||||
end
|
||||
|
||||
ruby_version_is "3.0" do
|
||||
|
|
|
@ -84,6 +84,12 @@ module MethodSpecs
|
|||
def two_req_one_opt_with_splat_and_block(a, b, c=nil, *d, &blk); end
|
||||
def one_req_two_opt_with_splat_and_block(a, b=nil, c=nil, *d, &blk); end
|
||||
|
||||
def my_public_method; end
|
||||
def my_protected_method; end
|
||||
def my_private_method; end
|
||||
protected :my_protected_method
|
||||
private :my_private_method
|
||||
|
||||
define_method(:zero_defined_method, Proc.new {||})
|
||||
define_method(:zero_with_splat_defined_method, Proc.new {|*x|})
|
||||
define_method(:one_req_defined_method, Proc.new {|x|})
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
require_relative '../../spec_helper'
|
||||
require_relative 'fixtures/classes'
|
||||
|
||||
ruby_version_is "3.1"..."3.2" do
|
||||
describe "Method#private?" do
|
||||
it "returns false when the method is public" do
|
||||
obj = MethodSpecs::Methods.new
|
||||
obj.method(:my_public_method).private?.should == false
|
||||
end
|
||||
|
||||
it "returns false when the method is protected" do
|
||||
obj = MethodSpecs::Methods.new
|
||||
obj.method(:my_protected_method).private?.should == false
|
||||
end
|
||||
|
||||
it "returns true when the method is private" do
|
||||
obj = MethodSpecs::Methods.new
|
||||
obj.method(:my_private_method).private?.should == true
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,21 @@
|
|||
require_relative '../../spec_helper'
|
||||
require_relative 'fixtures/classes'
|
||||
|
||||
ruby_version_is "3.1"..."3.2" do
|
||||
describe "Method#protected?" do
|
||||
it "returns false when the method is public" do
|
||||
obj = MethodSpecs::Methods.new
|
||||
obj.method(:my_public_method).protected?.should == false
|
||||
end
|
||||
|
||||
it "returns true when the method is protected" do
|
||||
obj = MethodSpecs::Methods.new
|
||||
obj.method(:my_protected_method).protected?.should == true
|
||||
end
|
||||
|
||||
it "returns false when the method is private" do
|
||||
obj = MethodSpecs::Methods.new
|
||||
obj.method(:my_private_method).protected?.should == false
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,21 @@
|
|||
require_relative '../../spec_helper'
|
||||
require_relative 'fixtures/classes'
|
||||
|
||||
ruby_version_is "3.1"..."3.2" do
|
||||
describe "Method#public?" do
|
||||
it "returns true when the method is public" do
|
||||
obj = MethodSpecs::Methods.new
|
||||
obj.method(:my_public_method).public?.should == true
|
||||
end
|
||||
|
||||
it "returns false when the method is protected" do
|
||||
obj = MethodSpecs::Methods.new
|
||||
obj.method(:my_protected_method).public?.should == false
|
||||
end
|
||||
|
||||
it "returns false when the method is private" do
|
||||
obj = MethodSpecs::Methods.new
|
||||
obj.method(:my_private_method).public?.should == false
|
||||
end
|
||||
end
|
||||
end
|
|
@ -55,10 +55,12 @@ describe "Method#super_method" do
|
|||
end
|
||||
end
|
||||
|
||||
context "after aliasing an inherited method" do
|
||||
it "returns the expected super_method" do
|
||||
method = MethodSpecs::InheritedMethods::C.new.method(:meow)
|
||||
method.super_method.owner.should == MethodSpecs::InheritedMethods::A
|
||||
ruby_version_is "2.7.3" do
|
||||
context "after aliasing an inherited method" do
|
||||
it "returns the expected super_method" do
|
||||
method = MethodSpecs::InheritedMethods::C.new.method(:meow)
|
||||
method.super_method.owner.should == MethodSpecs::InheritedMethods::A
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
require_relative '../../spec_helper'
|
||||
|
||||
ruby_version_is "3.1" do
|
||||
describe "Process._fork" do
|
||||
it "for #respond_to? returns the same as Process.respond_to?(:fork)" do
|
||||
Process.respond_to?(:_fork).should == Process.respond_to?(:fork)
|
||||
end
|
||||
|
||||
guard_not -> { Process.respond_to?(:fork) } do
|
||||
it "raises a NotImplementedError when called" do
|
||||
-> { Process._fork }.should raise_error(NotImplementedError)
|
||||
end
|
||||
end
|
||||
|
||||
guard -> { Process.respond_to?(:fork) } do
|
||||
it "is called by Process#fork" do
|
||||
Process.should_receive(:_fork).once.and_return(42)
|
||||
|
||||
pid = Process.fork {}
|
||||
pid.should equal(42)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -567,6 +567,24 @@ describe "Process.spawn" do
|
|||
end
|
||||
end
|
||||
|
||||
platform_is_not :windows do
|
||||
it "redirects non-default file descriptor to itself" do
|
||||
File.open(@name, 'w') do |file|
|
||||
-> do
|
||||
Process.wait Process.spawn(
|
||||
ruby_cmd("f = IO.new(#{file.fileno}, 'w'); f.print(:bang); f.flush"), file.fileno => file.fileno)
|
||||
end.should output_to_fd("bang", file)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "redirects default file descriptor to itself" do
|
||||
-> do
|
||||
Process.wait Process.spawn(
|
||||
ruby_cmd("f = IO.new(#{STDOUT.fileno}, 'w'); f.print(:bang); f.flush"), STDOUT.fileno => STDOUT.fileno)
|
||||
end.should output_to_fd("bang", STDOUT)
|
||||
end
|
||||
|
||||
# :close_others
|
||||
|
||||
platform_is_not :windows do
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
require_relative '../../spec_helper'
|
||||
|
||||
ruby_version_is "3.2" do
|
||||
describe "Regexp.timeout" do
|
||||
after :each do
|
||||
Regexp.timeout = nil
|
||||
end
|
||||
|
||||
it "returns global timeout" do
|
||||
Regexp.timeout = 3
|
||||
Regexp.timeout.should == 3
|
||||
end
|
||||
|
||||
it "raises Regexp::TimeoutError after global timeout elapsed" do
|
||||
Regexp.timeout = 0.001
|
||||
Regexp.timeout.should == 0.001
|
||||
|
||||
-> {
|
||||
# A typical ReDoS case
|
||||
/^(a*)*$/ =~ "a" * 1000000 + "x"
|
||||
}.should raise_error(Regexp::TimeoutError, "regexp match timeout")
|
||||
end
|
||||
|
||||
it "raises Regexp::TimeoutError after timeout keyword value elapsed" do
|
||||
Regexp.timeout = 3 # This should be ignored
|
||||
Regexp.timeout.should == 3
|
||||
|
||||
re = Regexp.new("^a*b?a*$", timeout: 0.001)
|
||||
|
||||
-> {
|
||||
re =~ "a" * 1000000 + "x"
|
||||
}.should raise_error(Regexp::TimeoutError, "regexp match timeout")
|
||||
end
|
||||
end
|
||||
end
|
|
@ -357,11 +357,11 @@ describe "String#[]= with a Range index" do
|
|||
end
|
||||
|
||||
it "raises a RangeError if negative Range begin is out of range" do
|
||||
-> { "abc"[-4..-2] = "x" }.should raise_error(RangeError)
|
||||
-> { "abc"[-4..-2] = "x" }.should raise_error(RangeError, "-4..-2 out of range")
|
||||
end
|
||||
|
||||
it "raises a RangeError if positive Range begin is greater than String size" do
|
||||
-> { "abc"[4..2] = "x" }.should raise_error(RangeError)
|
||||
-> { "abc"[4..2] = "x" }.should raise_error(RangeError, "4..2 out of range")
|
||||
end
|
||||
|
||||
it "uses the Range end as an index rather than a count" do
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
module StringSpecs
|
||||
def self.to_c_method(string)
|
||||
string.to_c
|
||||
end
|
||||
end
|
|
@ -210,8 +210,6 @@ describe "String#gsub with pattern and replacement" do
|
|||
end
|
||||
end
|
||||
|
||||
# Note: $~ cannot be tested because mspec messes with it
|
||||
|
||||
it "sets $~ to MatchData of last match and nil when there's none" do
|
||||
'hello.'.gsub('hello', 'x')
|
||||
$~[0].should == 'hello'
|
||||
|
@ -225,6 +223,18 @@ describe "String#gsub with pattern and replacement" do
|
|||
'hello.'.gsub(/not/, 'x')
|
||||
$~.should == nil
|
||||
end
|
||||
|
||||
it "handles a pattern in a superset encoding" do
|
||||
result = 'abc'.force_encoding(Encoding::US_ASCII).gsub('é', 'è')
|
||||
result.should == 'abc'
|
||||
result.encoding.should == Encoding::US_ASCII
|
||||
end
|
||||
|
||||
it "handles a pattern in a subset encoding" do
|
||||
result = 'été'.gsub('t'.force_encoding(Encoding::US_ASCII), 'u')
|
||||
result.should == 'éué'
|
||||
result.encoding.should == Encoding::UTF_8
|
||||
end
|
||||
end
|
||||
|
||||
describe "String#gsub with pattern and Hash" do
|
||||
|
@ -521,6 +531,27 @@ describe "String#gsub! with pattern and replacement" do
|
|||
-> { s.gsub!(/e/, "e") }.should raise_error(FrozenError)
|
||||
-> { s.gsub!(/[aeiou]/, '*') }.should raise_error(FrozenError)
|
||||
end
|
||||
|
||||
it "handles a pattern in a superset encoding" do
|
||||
string = 'abc'.force_encoding(Encoding::US_ASCII)
|
||||
|
||||
result = string.gsub!('é', 'è')
|
||||
|
||||
result.should == nil
|
||||
string.should == 'abc'
|
||||
string.encoding.should == Encoding::US_ASCII
|
||||
end
|
||||
|
||||
it "handles a pattern in a subset encoding" do
|
||||
string = 'été'
|
||||
pattern = 't'.force_encoding(Encoding::US_ASCII)
|
||||
|
||||
result = string.gsub!(pattern, 'u')
|
||||
|
||||
result.should == string
|
||||
string.should == 'éué'
|
||||
string.encoding.should == Encoding::UTF_8
|
||||
end
|
||||
end
|
||||
|
||||
describe "String#gsub! with pattern and block" do
|
||||
|
|
|
@ -159,6 +159,14 @@ describe "String#index with String" do
|
|||
"あれ".index char
|
||||
end.should raise_error(Encoding::CompatibilityError)
|
||||
end
|
||||
|
||||
it "handles a substring in a superset encoding" do
|
||||
'abc'.force_encoding(Encoding::US_ASCII).index('é').should == nil
|
||||
end
|
||||
|
||||
it "handles a substring in a subset encoding" do
|
||||
'été'.index('t'.force_encoding(Encoding::US_ASCII)).should == 1
|
||||
end
|
||||
end
|
||||
|
||||
describe "String#index with Regexp" do
|
||||
|
|
|
@ -38,4 +38,26 @@ describe "String#partition with String" do
|
|||
it "takes precedence over a given block" do
|
||||
"hello world".partition("o") { true }.should == ["hell", "o", " world"]
|
||||
end
|
||||
|
||||
it "handles a pattern in a superset encoding" do
|
||||
string = "hello".force_encoding(Encoding::US_ASCII)
|
||||
|
||||
result = string.partition("é")
|
||||
|
||||
result.should == ["hello", "", ""]
|
||||
result[0].encoding.should == Encoding::US_ASCII
|
||||
result[1].encoding.should == Encoding::US_ASCII
|
||||
result[2].encoding.should == Encoding::US_ASCII
|
||||
end
|
||||
|
||||
it "handles a pattern in a subset encoding" do
|
||||
pattern = "o".force_encoding(Encoding::US_ASCII)
|
||||
|
||||
result = "héllo world".partition(pattern)
|
||||
|
||||
result.should == ["héll", "o", " world"]
|
||||
result[0].encoding.should == Encoding::UTF_8
|
||||
result[1].encoding.should == Encoding::US_ASCII
|
||||
result[2].encoding.should == Encoding::UTF_8
|
||||
end
|
||||
end
|
||||
|
|
|
@ -196,6 +196,14 @@ describe "String#rindex with String" do
|
|||
it "raises a TypeError when given offset is nil" do
|
||||
-> { "str".rindex("st", nil) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "handles a substring in a superset encoding" do
|
||||
'abc'.force_encoding(Encoding::US_ASCII).rindex('é').should == nil
|
||||
end
|
||||
|
||||
it "handles a substring in a subset encoding" do
|
||||
'été'.rindex('t'.force_encoding(Encoding::US_ASCII)).should == 1
|
||||
end
|
||||
end
|
||||
|
||||
describe "String#rindex with Regexp" do
|
||||
|
|
|
@ -46,4 +46,26 @@ describe "String#rpartition with String" do
|
|||
->{ "hello".rpartition(5) }.should raise_error(TypeError)
|
||||
->{ "hello".rpartition(nil) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "handles a pattern in a superset encoding" do
|
||||
string = "hello".force_encoding(Encoding::US_ASCII)
|
||||
|
||||
result = string.rpartition("é")
|
||||
|
||||
result.should == ["", "", "hello"]
|
||||
result[0].encoding.should == Encoding::US_ASCII
|
||||
result[1].encoding.should == Encoding::US_ASCII
|
||||
result[2].encoding.should == Encoding::US_ASCII
|
||||
end
|
||||
|
||||
it "handles a pattern in a subset encoding" do
|
||||
pattern = "o".force_encoding(Encoding::US_ASCII)
|
||||
|
||||
result = "héllo world".rpartition(pattern)
|
||||
|
||||
result.should == ["héllo w", "o", "rld"]
|
||||
result[0].encoding.should == Encoding::UTF_8
|
||||
result[1].encoding.should == Encoding::US_ASCII
|
||||
result[2].encoding.should == Encoding::UTF_8
|
||||
end
|
||||
end
|
||||
|
|
|
@ -214,6 +214,17 @@ describe "String#sub with pattern, replacement" do
|
|||
"ababa".sub(/(b)/, '\\\\\1').should == "a\\baba"
|
||||
end
|
||||
|
||||
it "handles a pattern in a superset encoding" do
|
||||
result = 'abc'.force_encoding(Encoding::US_ASCII).sub('é', 'è')
|
||||
result.should == 'abc'
|
||||
result.encoding.should == Encoding::US_ASCII
|
||||
end
|
||||
|
||||
it "handles a pattern in a subset encoding" do
|
||||
result = 'été'.sub('t'.force_encoding(Encoding::US_ASCII), 'u')
|
||||
result.should == 'éué'
|
||||
result.encoding.should == Encoding::UTF_8
|
||||
end
|
||||
end
|
||||
|
||||
describe "String#sub with pattern and block" do
|
||||
|
@ -299,6 +310,27 @@ describe "String#sub! with pattern, replacement" do
|
|||
-> { s.sub!(/e/, "e") }.should raise_error(FrozenError)
|
||||
-> { s.sub!(/[aeiou]/, '*') }.should raise_error(FrozenError)
|
||||
end
|
||||
|
||||
it "handles a pattern in a superset encoding" do
|
||||
string = 'abc'.force_encoding(Encoding::US_ASCII)
|
||||
|
||||
result = string.sub!('é', 'è')
|
||||
|
||||
result.should == nil
|
||||
string.should == 'abc'
|
||||
string.encoding.should == Encoding::US_ASCII
|
||||
end
|
||||
|
||||
it "handles a pattern in a subset encoding" do
|
||||
string = 'été'
|
||||
pattern = 't'.force_encoding(Encoding::US_ASCII)
|
||||
|
||||
result = string.sub!(pattern, 'u')
|
||||
|
||||
result.should == string
|
||||
string.should == 'éué'
|
||||
string.encoding.should == Encoding::UTF_8
|
||||
end
|
||||
end
|
||||
|
||||
describe "String#sub! with pattern and block" do
|
||||
|
|
|
@ -1,99 +1,42 @@
|
|||
require_relative '../../spec_helper'
|
||||
require_relative '../../shared/kernel/complex'
|
||||
require_relative 'fixtures/to_c'
|
||||
|
||||
describe "String#to_c" do
|
||||
it "returns a Complex object" do
|
||||
'9'.to_c.should be_an_instance_of(Complex)
|
||||
end
|
||||
|
||||
it "understands integers" do
|
||||
'20'.to_c.should == Complex(20)
|
||||
end
|
||||
|
||||
it "understands negative integers" do
|
||||
'-3'.to_c.should == Complex(-3)
|
||||
end
|
||||
|
||||
it "understands fractions (numerator/denominator) for the real part" do
|
||||
'2/3'.to_c.should == Complex(Rational(2, 3))
|
||||
end
|
||||
|
||||
it "understands fractions (numerator/denominator) for the imaginary part" do
|
||||
'4+2/3i'.to_c.should == Complex(4, Rational(2, 3))
|
||||
end
|
||||
|
||||
it "understands negative fractions (-numerator/denominator) for the real part" do
|
||||
'-2/3'.to_c.should == Complex(Rational(-2, 3))
|
||||
end
|
||||
|
||||
it "understands negative fractions (-numerator/denominator) for the imaginary part" do
|
||||
'7-2/3i'.to_c.should == Complex(7, Rational(-2, 3))
|
||||
end
|
||||
|
||||
it "understands floats (a.b) for the real part" do
|
||||
'2.3'.to_c.should == Complex(2.3)
|
||||
end
|
||||
|
||||
it "understands floats (a.b) for the imaginary part" do
|
||||
'4+2.3i'.to_c.should == Complex(4, 2.3)
|
||||
end
|
||||
|
||||
it "understands negative floats (-a.b) for the real part" do
|
||||
'-2.33'.to_c.should == Complex(-2.33)
|
||||
end
|
||||
|
||||
it "understands negative floats (-a.b) for the imaginary part" do
|
||||
'7-28.771i'.to_c.should == Complex(7, -28.771)
|
||||
end
|
||||
|
||||
it "understands an integer followed by 'i' to mean that integer is the imaginary part" do
|
||||
'35i'.to_c.should == Complex(0,35)
|
||||
end
|
||||
|
||||
it "understands a negative integer followed by 'i' to mean that negative integer is the imaginary part" do
|
||||
'-29i'.to_c.should == Complex(0,-29)
|
||||
end
|
||||
|
||||
it "understands an 'i' by itself as denoting a complex number with an imaginary part of 1" do
|
||||
'i'.to_c.should == Complex(0,1)
|
||||
end
|
||||
|
||||
it "understands a '-i' by itself as denoting a complex number with an imaginary part of -1" do
|
||||
'-i'.to_c.should == Complex(0,-1)
|
||||
end
|
||||
|
||||
it "understands 'a+bi' to mean a complex number with 'a' as the real part, 'b' as the imaginary" do
|
||||
'79+4i'.to_c.should == Complex(79,4)
|
||||
end
|
||||
|
||||
it "understands 'a-bi' to mean a complex number with 'a' as the real part, '-b' as the imaginary" do
|
||||
'79-4i'.to_c.should == Complex(79,-4)
|
||||
end
|
||||
|
||||
it "understands scientific notation for the real part" do
|
||||
'2e3+4i'.to_c.should == Complex(2e3,4)
|
||||
end
|
||||
|
||||
it "understands negative scientific notation for the real part" do
|
||||
'-2e3+4i'.to_c.should == Complex(-2e3,4)
|
||||
end
|
||||
|
||||
it "understands scientific notation for the imaginary part" do
|
||||
'4+2e3i'.to_c.should == Complex(4, 2e3)
|
||||
end
|
||||
|
||||
it "understands negative scientific notation for the imaginary part" do
|
||||
'4-2e3i'.to_c.should == Complex(4, -2e3)
|
||||
end
|
||||
|
||||
it "understands scientific notation for the real and imaginary part in the same String" do
|
||||
'2e3+2e4i'.to_c.should == Complex(2e3,2e4)
|
||||
end
|
||||
|
||||
it "understands negative scientific notation for the real and imaginary part in the same String" do
|
||||
'-2e3-2e4i'.to_c.should == Complex(-2e3,-2e4)
|
||||
end
|
||||
it_behaves_like :kernel_complex, :to_c_method, StringSpecs
|
||||
end
|
||||
|
||||
describe "String#to_c" do
|
||||
it "returns a complex number with 0 as the real part, 0 as the imaginary part for unrecognised Strings" do
|
||||
'ruby'.to_c.should == Complex(0,0)
|
||||
'ruby'.to_c.should == Complex(0, 0)
|
||||
end
|
||||
|
||||
it "ignores trailing garbage" do
|
||||
'79+4iruby'.to_c.should == Complex(79, 4)
|
||||
end
|
||||
|
||||
it "understands Float::INFINITY" do
|
||||
'Infinity'.to_c.should == Complex(0, 1)
|
||||
'-Infinity'.to_c.should == Complex(0, -1)
|
||||
end
|
||||
|
||||
it "understands Float::NAN" do
|
||||
'NaN'.to_c.should == Complex(0, 0)
|
||||
end
|
||||
|
||||
it "understands a sequence of _" do
|
||||
'7__9+4__0i'.to_c.should == Complex(79, 40)
|
||||
end
|
||||
|
||||
it "allows null-byte" do
|
||||
"1-2i\0".to_c.should == Complex(1, -2)
|
||||
"1\0-2i".to_c.should == Complex(1, 0)
|
||||
"\01-2i".to_c.should == Complex(0, 0)
|
||||
end
|
||||
|
||||
it "raises Encoding::CompatibilityError if String is in not ASCII-compatible encoding" do
|
||||
-> {
|
||||
'79+4i'.encode("UTF-16").to_c
|
||||
}.should raise_error(Encoding::CompatibilityError, "ASCII incompatible encoding: UTF-16")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -93,6 +93,11 @@ describe "String#unpack with format 'B'" do
|
|||
it "ignores spaces between directives" do
|
||||
"\x80\x00".unpack("B B").should == ["1", "0"]
|
||||
end
|
||||
|
||||
it "decodes into US-ASCII string values" do
|
||||
str = "s".force_encoding('UTF-8').unpack("B*")[0]
|
||||
str.encoding.name.should == 'US-ASCII'
|
||||
end
|
||||
end
|
||||
|
||||
describe "String#unpack with format 'b'" do
|
||||
|
@ -189,5 +194,4 @@ describe "String#unpack with format 'b'" do
|
|||
str = "s".force_encoding('UTF-8').unpack("b*")[0]
|
||||
str.encoding.name.should == 'US-ASCII'
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -97,6 +97,11 @@ describe "String#unpack with format 'M'" do
|
|||
["=FF=\n", ["\xff"]]
|
||||
].should be_computed_by(:unpack, "M")
|
||||
end
|
||||
|
||||
it "unpacks incomplete escape sequences as literal characters" do
|
||||
"foo=".unpack("M").should == ["foo="]
|
||||
"foo=4".unpack("M").should == ["foo=4"]
|
||||
end
|
||||
end
|
||||
|
||||
describe "String#unpack with format 'm'" do
|
||||
|
|
|
@ -40,4 +40,12 @@ describe "Struct#initialize" do
|
|||
it "can be overridden" do
|
||||
StructClasses::SubclassX.new(:y).new.key.should == :value
|
||||
end
|
||||
|
||||
ruby_version_is "3.1"..."3.2" do
|
||||
it "warns about passing only keyword arguments" do
|
||||
-> {
|
||||
StructClasses::Ruby.new(version: "3.1", platform: "OS")
|
||||
}.should complain(/warning: Passing only keyword arguments/)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
require_relative '../../spec_helper'
|
||||
|
||||
ruby_version_is "3.1" do
|
||||
# See https://bugs.ruby-lang.org/issues/18008
|
||||
describe "StructClass#keyword_init?" do
|
||||
it "returns true for a struct that accepts keyword arguments to initialize" do
|
||||
struct = Struct.new(:arg, keyword_init: true)
|
||||
struct.keyword_init?.should be_true
|
||||
end
|
||||
|
||||
it "returns false for a struct that does not accept keyword arguments to initialize" do
|
||||
struct = Struct.new(:arg, keyword_init: false)
|
||||
struct.keyword_init?.should be_false
|
||||
end
|
||||
|
||||
it "returns nil for a struct that did not explicitly specify keyword_init" do
|
||||
struct = Struct.new(:arg)
|
||||
struct.keyword_init?.should be_nil
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
require_relative '../../../spec_helper'
|
||||
|
||||
ruby_version_is "3.1" do
|
||||
describe "Thread::Backtrace.limit" do
|
||||
it "returns maximum backtrace length set by --backtrace-limit command-line option" do
|
||||
out = ruby_exe("print Thread::Backtrace.limit", options: "--backtrace-limit=2")
|
||||
out.should == "2"
|
||||
end
|
||||
|
||||
it "returns -1 when --backtrace-limit command-line option is not set" do
|
||||
out = ruby_exe("print Thread::Backtrace.limit")
|
||||
out.should == "-1"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
require_relative '../../spec_helper'
|
||||
|
||||
ruby_version_is "3.1" do
|
||||
describe "Thread#native_thread_id" do
|
||||
it "returns an integer when the thread is alive" do
|
||||
Thread.current.native_thread_id.should be_kind_of(Integer)
|
||||
end
|
||||
|
||||
it "returns nil when the thread is not running" do
|
||||
t = Thread.new {}
|
||||
t.join
|
||||
t.native_thread_id.should == nil
|
||||
end
|
||||
end
|
||||
end
|
|
@ -266,5 +266,10 @@ describe "Time.at" do
|
|||
time.zone.should == zone
|
||||
time.to_i.should == @epoch_time
|
||||
end
|
||||
|
||||
it "raises ArgumentError if format is invalid" do
|
||||
-> { Time.at(@epoch_time, in: "+09:99") }.should raise_error(ArgumentError)
|
||||
-> { Time.at(@epoch_time, in: "ABC") }.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -332,4 +332,55 @@ describe "Time.new with a timezone argument" do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.1' do # https://bugs.ruby-lang.org/issues/17485
|
||||
describe ":in keyword argument" do
|
||||
it "could be UTC offset as a String in '+HH:MM or '-HH:MM' format" do
|
||||
time = Time.new(2000, 1, 1, 12, 0, 0, in: "+05:00")
|
||||
|
||||
time.utc_offset.should == 5*60*60
|
||||
time.zone.should == nil
|
||||
|
||||
time = Time.new(2000, 1, 1, 12, 0, 0, in: "-09:00")
|
||||
|
||||
time.utc_offset.should == -9*60*60
|
||||
time.zone.should == nil
|
||||
end
|
||||
|
||||
it "could be UTC offset as a number of seconds" do
|
||||
time = Time.new(2000, 1, 1, 12, 0, 0, in: 5*60*60)
|
||||
|
||||
time.utc_offset.should == 5*60*60
|
||||
time.zone.should == nil
|
||||
|
||||
time = Time.new(2000, 1, 1, 12, 0, 0, in: -9*60*60)
|
||||
|
||||
time.utc_offset.should == -9*60*60
|
||||
time.zone.should == nil
|
||||
end
|
||||
|
||||
it "could be a timezone object" do
|
||||
zone = TimeSpecs::TimezoneWithName.new(name: "Asia/Colombo")
|
||||
time = Time.new(2000, 1, 1, 12, 0, 0, in: zone)
|
||||
|
||||
time.utc_offset.should == 5*3600+30*60
|
||||
time.zone.should == zone
|
||||
|
||||
zone = TimeSpecs::TimezoneWithName.new(name: "PST")
|
||||
time = Time.new(2000, 1, 1, 12, 0, 0, in: zone)
|
||||
|
||||
time.utc_offset.should == -9*60*60
|
||||
time.zone.should == zone
|
||||
end
|
||||
|
||||
it "raises ArgumentError if format is invalid" do
|
||||
-> { Time.new(2000, 1, 1, 12, 0, 0, in: "+09:99") }.should raise_error(ArgumentError)
|
||||
-> { Time.new(2000, 1, 1, 12, 0, 0, in: "ABC") }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "raises ArgumentError if two offset arguments are given" do
|
||||
-> { Time.new(2000, 1, 1, 12, 0, 0, "+05:00", in: "+05:00") }.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,4 +3,49 @@ require_relative 'shared/now'
|
|||
|
||||
describe "Time.now" do
|
||||
it_behaves_like :time_now, :now
|
||||
|
||||
describe ":in keyword argument" do
|
||||
it "could be UTC offset as a String in '+HH:MM or '-HH:MM' format" do
|
||||
time = Time.now(in: "+05:00")
|
||||
|
||||
time.utc_offset.should == 5*60*60
|
||||
time.zone.should == nil
|
||||
|
||||
time = Time.now(in: "-09:00")
|
||||
|
||||
time.utc_offset.should == -9*60*60
|
||||
time.zone.should == nil
|
||||
end
|
||||
|
||||
it "could be UTC offset as a number of seconds" do
|
||||
time = Time.now(in: 5*60*60)
|
||||
|
||||
time.utc_offset.should == 5*60*60
|
||||
time.zone.should == nil
|
||||
|
||||
time = Time.now(in: -9*60*60)
|
||||
|
||||
time.utc_offset.should == -9*60*60
|
||||
time.zone.should == nil
|
||||
end
|
||||
|
||||
it "could be a timezone object" do
|
||||
zone = TimeSpecs::TimezoneWithName.new(name: "Asia/Colombo")
|
||||
time = Time.now(in: zone)
|
||||
|
||||
time.utc_offset.should == 5*3600+30*60
|
||||
time.zone.should == zone
|
||||
|
||||
zone = TimeSpecs::TimezoneWithName.new(name: "PST")
|
||||
time = Time.now(in: zone)
|
||||
|
||||
time.utc_offset.should == -9*60*60
|
||||
time.zone.should == zone
|
||||
end
|
||||
|
||||
it "raises ArgumentError if format is invalid" do
|
||||
-> { Time.now(in: "+09:99") }.should raise_error(ArgumentError)
|
||||
-> { Time.now(in: "ABC") }.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,12 +7,10 @@ describe :time_local, shared: true do
|
|||
end
|
||||
|
||||
platform_is_not :windows do
|
||||
describe "timezone changes" do
|
||||
it "correctly adjusts the timezone change to 'CET' on 'Europe/Amsterdam'" do
|
||||
with_timezone("Europe/Amsterdam") do
|
||||
Time.send(@method, 1970, 5, 16).to_a.should ==
|
||||
[0, 0, 0, 16, 5, 1970, 6, 136, false, "CET"]
|
||||
end
|
||||
it "uses the 'CET' timezone with TZ=Europe/Amsterdam in 1970" do
|
||||
with_timezone("Europe/Amsterdam") do
|
||||
Time.send(@method, 1970, 5, 16).to_a.should ==
|
||||
[0, 0, 0, 16, 5, 1970, 6, 136, false, "CET"]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -41,5 +39,4 @@ describe :time_local_10_arg, shared: true do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -49,4 +49,13 @@ describe "Time#strftime" do
|
|||
time = @new_time_with_offset[2012, 1, 1, 0, 0, 0, Rational(36645, 10)]
|
||||
time.strftime("%::z").should == "+01:01:05"
|
||||
end
|
||||
|
||||
ruby_version_is "3.1" do
|
||||
it "supports RFC 3339 UTC for unknown offset local time, -0000, as %-z" do
|
||||
@time.strftime("%z").should == "+0000"
|
||||
@time.strftime("%-z").should == "-0000"
|
||||
@time.strftime("%-:z").should == "-00:00"
|
||||
@time.strftime("%-::z").should == "-00:00:00"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
require_relative '../../spec_helper'
|
||||
require_relative 'fixtures/classes'
|
||||
|
||||
ruby_version_is "3.1" do
|
||||
describe 'TracePoint.allow_reentry' do
|
||||
it 'allows the reentrance in a given block' do
|
||||
event_lines = []
|
||||
l1 = l2 = l3 = l4 = nil
|
||||
TracePoint.new(:line) do |tp|
|
||||
next unless TracePointSpec.target_thread?
|
||||
|
||||
event_lines << tp.lineno
|
||||
next if (__LINE__ + 2 .. __LINE__ + 4).cover?(tp.lineno)
|
||||
TracePoint.allow_reentry do
|
||||
a = 1; l3 = __LINE__
|
||||
b = 2; l4 = __LINE__
|
||||
end
|
||||
end.enable do
|
||||
c = 3; l1 = __LINE__
|
||||
d = 4; l2 = __LINE__
|
||||
end
|
||||
|
||||
event_lines.should == [l1, l3, l4, l2, l3, l4]
|
||||
end
|
||||
|
||||
it 'raises RuntimeError when not called inside a TracePoint' do
|
||||
-> {
|
||||
TracePoint.allow_reentry{}
|
||||
}.should raise_error(RuntimeError)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -53,6 +53,12 @@ module UnboundMethodSpecs
|
|||
|
||||
def discard_1(); :discard; end
|
||||
def discard_2(); :discard; end
|
||||
|
||||
def my_public_method; end
|
||||
def my_protected_method; end
|
||||
def my_private_method; end
|
||||
protected :my_protected_method
|
||||
private :my_private_method
|
||||
end
|
||||
|
||||
class Parent
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
require_relative '../../spec_helper'
|
||||
require_relative 'fixtures/classes'
|
||||
|
||||
ruby_version_is "3.1"..."3.2" do
|
||||
describe "UnboundMethod#private?" do
|
||||
it "returns false when the method is public" do
|
||||
obj = UnboundMethodSpecs::Methods.new
|
||||
obj.method(:my_public_method).unbind.private?.should == false
|
||||
end
|
||||
|
||||
it "returns false when the method is protected" do
|
||||
obj = UnboundMethodSpecs::Methods.new
|
||||
obj.method(:my_protected_method).unbind.private?.should == false
|
||||
end
|
||||
|
||||
it "returns true when the method is private" do
|
||||
obj = UnboundMethodSpecs::Methods.new
|
||||
obj.method(:my_private_method).unbind.private?.should == true
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,21 @@
|
|||
require_relative '../../spec_helper'
|
||||
require_relative 'fixtures/classes'
|
||||
|
||||
ruby_version_is "3.1"..."3.2" do
|
||||
describe "UnboundMethod#protected?" do
|
||||
it "returns false when the method is public" do
|
||||
obj = UnboundMethodSpecs::Methods.new
|
||||
obj.method(:my_public_method).unbind.protected?.should == false
|
||||
end
|
||||
|
||||
it "returns true when the method is protected" do
|
||||
obj = UnboundMethodSpecs::Methods.new
|
||||
obj.method(:my_protected_method).unbind.protected?.should == true
|
||||
end
|
||||
|
||||
it "returns false when the method is private" do
|
||||
obj = UnboundMethodSpecs::Methods.new
|
||||
obj.method(:my_private_method).unbind.protected?.should == false
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,21 @@
|
|||
require_relative '../../spec_helper'
|
||||
require_relative 'fixtures/classes'
|
||||
|
||||
ruby_version_is "3.1"..."3.2" do
|
||||
describe "UnboundMethod#public?" do
|
||||
it "returns true when the method is public" do
|
||||
obj = UnboundMethodSpecs::Methods.new
|
||||
obj.method(:my_public_method).unbind.public?.should == true
|
||||
end
|
||||
|
||||
it "returns false when the method is protected" do
|
||||
obj = UnboundMethodSpecs::Methods.new
|
||||
obj.method(:my_protected_method).unbind.public?.should == false
|
||||
end
|
||||
|
||||
it "returns false when the method is private" do
|
||||
obj = UnboundMethodSpecs::Methods.new
|
||||
obj.method(:my_private_method).unbind.public?.should == false
|
||||
end
|
||||
end
|
||||
end
|
|
@ -40,10 +40,12 @@ describe "UnboundMethod#super_method" do
|
|||
end
|
||||
end
|
||||
|
||||
context "after aliasing an inherited method" do
|
||||
it "returns the expected super_method" do
|
||||
method = MethodSpecs::InheritedMethods::C.instance_method(:meow)
|
||||
method.super_method.owner.should == MethodSpecs::InheritedMethods::A
|
||||
ruby_version_is "2.7.3" do
|
||||
context "after aliasing an inherited method" do
|
||||
it "returns the expected super_method" do
|
||||
method = MethodSpecs::InheritedMethods::C.instance_method(:meow)
|
||||
method.super_method.owner.should == MethodSpecs::InheritedMethods::A
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -263,12 +263,55 @@ describe "A block yielded a single" do
|
|||
m(obj) { |a, b, c| [a, b, c] }.should == [obj, nil, nil]
|
||||
end
|
||||
|
||||
it "receives the object if it does not respond to #to_ary" do
|
||||
obj = Object.new
|
||||
|
||||
m(obj) { |a, b, c| [a, b, c] }.should == [obj, nil, nil]
|
||||
end
|
||||
|
||||
it "calls #respond_to? to check if object has method #to_ary" do
|
||||
obj = mock("destructure block arguments")
|
||||
obj.should_receive(:respond_to?).with(:to_ary, true).and_return(true)
|
||||
obj.should_receive(:to_ary).and_return([1, 2])
|
||||
|
||||
m(obj) { |a, b, c| [a, b, c] }.should == [1, 2, nil]
|
||||
end
|
||||
|
||||
it "receives the object if it does not respond to #respond_to?" do
|
||||
obj = BasicObject.new
|
||||
|
||||
m(obj) { |a, b, c| [a, b, c] }.should == [obj, nil, nil]
|
||||
end
|
||||
|
||||
it "calls #to_ary on the object when it is defined dynamically" do
|
||||
obj = Object.new
|
||||
def obj.method_missing(name, *args, &block)
|
||||
if name == :to_ary
|
||||
[1, 2]
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
def obj.respond_to_missing?(name, include_private)
|
||||
name == :to_ary
|
||||
end
|
||||
|
||||
m(obj) { |a, b, c| [a, b, c] }.should == [1, 2, nil]
|
||||
end
|
||||
|
||||
it "raises a TypeError if #to_ary does not return an Array" do
|
||||
obj = mock("destructure block arguments")
|
||||
obj.should_receive(:to_ary).and_return(1)
|
||||
|
||||
-> { m(obj) { |a, b| } }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises error transparently if #to_ary raises error on its own" do
|
||||
obj = Object.new
|
||||
def obj.to_ary; raise "Exception raised in #to_ary" end
|
||||
|
||||
-> { m(obj) { |a, b| } }.should raise_error(RuntimeError, "Exception raised in #to_ary")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -321,6 +321,21 @@ ruby_version_is "3.0" do
|
|||
m({a: 1}).should == [[{a: 1}], {}]
|
||||
end
|
||||
|
||||
ruby_version_is "3.1" do
|
||||
describe "omitted values" do
|
||||
it "accepts short notation 'key' for 'key: value' syntax" do
|
||||
def m(a:, b:)
|
||||
[a, b]
|
||||
end
|
||||
|
||||
a = 1
|
||||
b = 2
|
||||
|
||||
eval('m(a:, b:).should == [1, 2]')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is "3.2" do
|
||||
it "does not work with call(*ruby2_keyword_args) with missing ruby2_keywords in between" do
|
||||
class << self
|
||||
|
|
|
@ -1679,6 +1679,15 @@ ruby_version_is "3.0" do
|
|||
|
||||
m.should == 42
|
||||
end
|
||||
|
||||
context "without parenthesis" do
|
||||
evaluate <<-ruby do
|
||||
def m = 42
|
||||
ruby
|
||||
|
||||
m.should == 42
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "with arguments" do
|
||||
|
@ -1716,6 +1725,16 @@ ruby_version_is "3.0" do
|
|||
m("meow", num: 2).should == "meow" * 4
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is ""..."3.0" do
|
||||
context "inside 'endless' method definitions" do
|
||||
it "does not allow method calls without parenthesis" do
|
||||
-> {
|
||||
eval("def greet(person) = 'Hi, '.concat person")
|
||||
}.should raise_error(SyntaxError)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "Keyword arguments are now separated from positional arguments" do
|
||||
|
@ -1824,4 +1843,14 @@ ruby_version_is "3.1" do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "Inside 'endless' method definitions" do
|
||||
it "allows method calls without parenthesis" do
|
||||
eval <<-ruby
|
||||
def greet(person) = "Hi, ".concat person
|
||||
ruby
|
||||
|
||||
greet("Homer").should == "Hi, Homer"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
require_relative '../../../spec_helper'
|
|
@ -1 +0,0 @@
|
|||
require_relative '../../../spec_helper'
|
|
@ -1 +0,0 @@
|
|||
require_relative '../../../spec_helper'
|
|
@ -1 +0,0 @@
|
|||
require_relative '../../../spec_helper'
|
|
@ -1 +0,0 @@
|
|||
require_relative '../../../spec_helper'
|
|
@ -1 +0,0 @@
|
|||
require_relative '../../../spec_helper'
|
|
@ -1 +0,0 @@
|
|||
require_relative '../../../spec_helper'
|
|
@ -1 +0,0 @@
|
|||
require_relative '../../../spec_helper'
|
|
@ -1 +0,0 @@
|
|||
require_relative '../../../spec_helper'
|
|
@ -1 +0,0 @@
|
|||
require_relative '../../../spec_helper'
|
|
@ -1,4 +0,0 @@
|
|||
require 'cmath'
|
||||
class IncludesMath
|
||||
include CMath
|
||||
end
|
|
@ -1 +0,0 @@
|
|||
require_relative '../../../spec_helper'
|
|
@ -1 +0,0 @@
|
|||
require_relative '../../../spec_helper'
|
|
@ -1,41 +0,0 @@
|
|||
require_relative '../fixtures/classes'
|
||||
|
||||
describe :complex_math_acos, shared: true do
|
||||
it "returns the arccosine of the passed argument" do
|
||||
@object.send(:acos, 1).should be_close(0.0, TOLERANCE)
|
||||
@object.send(:acos, 0).should be_close(1.5707963267949, TOLERANCE)
|
||||
@object.send(:acos, -1).should be_close(Math::PI,TOLERANCE)
|
||||
end
|
||||
|
||||
it "returns the arccosine for Complex numbers" do
|
||||
@object.send(:acos, Complex(3, 4)).should be_close(Complex(0.93681246115572, -2.30550903124348), TOLERANCE)
|
||||
end
|
||||
|
||||
it "returns the arccosine for numbers greater than 1.0 as a Complex number" do
|
||||
@object.send(:acos, 1.0001).should be_close(Complex(0.0, 0.0141420177752494), TOLERANCE)
|
||||
end
|
||||
|
||||
it "returns the arccosine for numbers less than -1.0 as a Complex number" do
|
||||
@object.send(:acos, -1.0001).should be_close(Complex(3.14159265358979, -0.0141420177752495), TOLERANCE)
|
||||
end
|
||||
end
|
||||
|
||||
describe :complex_math_acos_bang, shared: true do
|
||||
it "returns the arccosine of the argument" do
|
||||
@object.send(:acos!, 1).should be_close(0.0, TOLERANCE)
|
||||
@object.send(:acos!, 0).should be_close(1.5707963267949, TOLERANCE)
|
||||
@object.send(:acos!, -1).should be_close(Math::PI,TOLERANCE)
|
||||
end
|
||||
|
||||
it "raises a TypeError when passed a Complex number" do
|
||||
-> { @object.send(:acos!, Complex(4, 5)) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises an Errno::EDOM for numbers greater than 1.0" do
|
||||
-> { @object.send(:acos!, 1.0001) }.should raise_error(Errno::EDOM)
|
||||
end
|
||||
|
||||
it "raises an Errno::EDOM for numbers less than -1.0" do
|
||||
-> { @object.send(:acos!, -1.0001) }.should raise_error(Errno::EDOM)
|
||||
end
|
||||
end
|
|
@ -1,37 +0,0 @@
|
|||
require_relative '../fixtures/classes'
|
||||
|
||||
describe :complex_math_acosh, shared: true do
|
||||
it "returns the principle value of the inverse hyperbolic cosine of the argument" do
|
||||
@object.send(:acosh, 14.2).should be_close(3.345146999647, TOLERANCE)
|
||||
@object.send(:acosh, 1.0).should be_close(0.0, TOLERANCE)
|
||||
end
|
||||
|
||||
it "returns the principle value of the inverse hyperbolic cosine for numbers less than 1.0 as a Complex number" do
|
||||
@object.send(:acosh, 1.0 - TOLERANCE).should be_close(Complex(0.0, 0.00774598605746135), TOLERANCE)
|
||||
@object.send(:acosh, 0).should be_close(Complex(0.0, 1.5707963267949), TOLERANCE)
|
||||
@object.send(:acosh, -1.0).should be_close(Complex(0.0, 3.14159265358979), TOLERANCE)
|
||||
end
|
||||
|
||||
it "returns the principle value of the inverse hyperbolic cosine for Complex numbers" do
|
||||
@object.send(:acosh, Complex(3, 4))
|
||||
@object.send(:acosh, Complex(3, 4)).imaginary.should be_close(0.93681246115572, TOLERANCE)
|
||||
@object.send(:acosh, Complex(3, 4)).real.should be_close(2.305509031243477, TOLERANCE)
|
||||
end
|
||||
end
|
||||
|
||||
describe :complex_math_acosh_bang, shared: true do
|
||||
it "returns the principle value of the inverse hyperbolic cosine of the argument" do
|
||||
@object.send(:acosh!, 14.2).should be_close(3.345146999647, TOLERANCE)
|
||||
@object.send(:acosh!, 1.0).should be_close(0.0, TOLERANCE)
|
||||
end
|
||||
|
||||
it "raises Errno::EDOM for numbers less than 1.0" do
|
||||
-> { @object.send(:acosh!, 1.0 - TOLERANCE) }.should raise_error(Errno::EDOM)
|
||||
-> { @object.send(:acosh!, 0) }.should raise_error(Errno::EDOM)
|
||||
-> { @object.send(:acosh!, -1.0) }.should raise_error(Errno::EDOM)
|
||||
end
|
||||
|
||||
it "raises a TypeError when passed a Complex number" do
|
||||
-> { @object.send(:acosh!, Complex(4, 5)) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
|
@ -1,47 +0,0 @@
|
|||
require_relative '../fixtures/classes'
|
||||
|
||||
describe :complex_math_asin, shared: true do
|
||||
it "returns the arcsine of the argument" do
|
||||
@object.send(:asin, 1).should be_close(Math::PI/2, TOLERANCE)
|
||||
@object.send(:asin, 0).should be_close(0.0, TOLERANCE)
|
||||
@object.send(:asin, -1).should be_close(-Math::PI/2, TOLERANCE)
|
||||
@object.send(:asin, 0.25).should be_close(0.252680255142079, TOLERANCE)
|
||||
@object.send(:asin, 0.50).should be_close(0.523598775598299, TOLERANCE)
|
||||
@object.send(:asin, 0.75).should be_close(0.8480620789814816,TOLERANCE)
|
||||
end
|
||||
|
||||
it "returns the arcsine for Complex numbers" do
|
||||
@object.send(:asin, Complex(3, 4)).should be_close(Complex(0.633983865639174, 2.30550903124347), TOLERANCE)
|
||||
end
|
||||
|
||||
it "returns a Complex number when the argument is greater than 1.0" do
|
||||
@object.send(:asin, 1.0001).should be_close(Complex(1.5707963267949, -0.0141420177752494), TOLERANCE)
|
||||
end
|
||||
|
||||
it "returns a Complex number when the argument is less than -1.0" do
|
||||
@object.send(:asin, -1.0001).should be_close(Complex(-1.5707963267949, 0.0141420177752494), TOLERANCE)
|
||||
end
|
||||
end
|
||||
|
||||
describe :complex_math_asin_bang, shared: true do
|
||||
it "returns the arcsine of the argument" do
|
||||
@object.send(:asin!, 1).should be_close(Math::PI/2, TOLERANCE)
|
||||
@object.send(:asin!, 0).should be_close(0.0, TOLERANCE)
|
||||
@object.send(:asin!, -1).should be_close(-Math::PI/2, TOLERANCE)
|
||||
@object.send(:asin!, 0.25).should be_close(0.252680255142079, TOLERANCE)
|
||||
@object.send(:asin!, 0.50).should be_close(0.523598775598299, TOLERANCE)
|
||||
@object.send(:asin!, 0.75).should be_close(0.8480620789814816,TOLERANCE)
|
||||
end
|
||||
|
||||
it "raises an Errno::EDOM if the argument is greater than 1.0" do
|
||||
-> { @object.send(:asin!, 1.0001) }.should raise_error( Errno::EDOM)
|
||||
end
|
||||
|
||||
it "raises an Errno::EDOM if the argument is less than -1.0" do
|
||||
-> { @object.send(:asin!, -1.0001) }.should raise_error( Errno::EDOM)
|
||||
end
|
||||
|
||||
it "raises a TypeError when passed a Complex number" do
|
||||
-> { @object.send(:asin!, Complex(4, 5)) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
|
@ -1,32 +0,0 @@
|
|||
require_relative '../fixtures/classes'
|
||||
|
||||
describe :complex_math_asinh, shared: true do
|
||||
it "returns the inverse hyperbolic sin of the argument" do
|
||||
@object.send(:asinh, 1.5).should be_close(1.19476321728711, TOLERANCE)
|
||||
@object.send(:asinh, -2.97).should be_close(-1.8089166921397, TOLERANCE)
|
||||
@object.send(:asinh, 0.0).should == 0.0
|
||||
@object.send(:asinh, -0.0).should == -0.0
|
||||
@object.send(:asinh, 1.05367e-08).should be_close(1.05367e-08, TOLERANCE)
|
||||
@object.send(:asinh, -1.05367e-08).should be_close(-1.05367e-08, TOLERANCE)
|
||||
end
|
||||
|
||||
it "returns the inverse hyperbolic sin for Complex numbers" do
|
||||
@object.send(:asinh, Complex(3, 4)).should be_close(Complex(2.29991404087927, 0.917616853351479), TOLERANCE)
|
||||
@object.send(:asinh, Complex(3.5, -4)).should be_close(Complex(2.36263337274419, -0.843166327537659), TOLERANCE)
|
||||
end
|
||||
end
|
||||
|
||||
describe :complex_math_asinh_bang, shared: true do
|
||||
it "returns the inverse hyperbolic sin of the argument" do
|
||||
@object.send(:asinh!, 1.5).should be_close(1.19476321728711, TOLERANCE)
|
||||
@object.send(:asinh!, -2.97).should be_close(-1.8089166921397, TOLERANCE)
|
||||
@object.send(:asinh!, 0.0).should == 0.0
|
||||
@object.send(:asinh!, -0.0).should == -0.0
|
||||
@object.send(:asinh!, 1.05367e-08).should be_close(1.05367e-08, TOLERANCE)
|
||||
@object.send(:asinh!, -1.05367e-08).should be_close(-1.05367e-08, TOLERANCE)
|
||||
end
|
||||
|
||||
it "raises a TypeError when passed a Complex number" do
|
||||
-> { @object.send(:asinh!, Complex(4, 5)) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
|
@ -1,32 +0,0 @@
|
|||
require_relative '../fixtures/classes'
|
||||
|
||||
describe :complex_math_atan, shared: true do
|
||||
it "returns the arctangent of the argument" do
|
||||
@object.send(:atan, 1).should be_close(Math::PI/4, TOLERANCE)
|
||||
@object.send(:atan, 0).should be_close(0.0, TOLERANCE)
|
||||
@object.send(:atan, -1).should be_close(-Math::PI/4, TOLERANCE)
|
||||
@object.send(:atan, 0.25).should be_close(0.244978663126864, TOLERANCE)
|
||||
@object.send(:atan, 0.50).should be_close(0.463647609000806, TOLERANCE)
|
||||
@object.send(:atan, 0.75).should be_close(0.643501108793284, TOLERANCE)
|
||||
end
|
||||
|
||||
it "returns the arctangent for Complex numbers" do
|
||||
@object.send(:atan, Complex(3, 4)).should be_close(Complex(1.44830699523146, 0.158997191679999), TOLERANCE)
|
||||
@object.send(:atan, Complex(3.5, -4)).should be_close(Complex(1.44507428165589, -0.140323762363786), TOLERANCE)
|
||||
end
|
||||
end
|
||||
|
||||
describe :complex_math_atan_bang, shared: true do
|
||||
it "returns the arctangent of the argument" do
|
||||
@object.send(:atan!, 1).should be_close(Math::PI/4, TOLERANCE)
|
||||
@object.send(:atan!, 0).should be_close(0.0, TOLERANCE)
|
||||
@object.send(:atan!, -1).should be_close(-Math::PI/4, TOLERANCE)
|
||||
@object.send(:atan!, 0.25).should be_close(0.244978663126864, TOLERANCE)
|
||||
@object.send(:atan!, 0.50).should be_close(0.463647609000806, TOLERANCE)
|
||||
@object.send(:atan!, 0.75).should be_close(0.643501108793284, TOLERANCE)
|
||||
end
|
||||
|
||||
it "raises a TypeError when passed a Complex number" do
|
||||
-> { @object.send(:atan!, Complex(4, 5)) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
|
@ -1,34 +0,0 @@
|
|||
require_relative '../fixtures/classes'
|
||||
|
||||
describe :complex_math_atan2, shared: true do
|
||||
it "returns the arc tangent of the passed arguments" do
|
||||
@object.send(:atan2, 4.2, 0.3).should be_close(1.49948886200961, TOLERANCE)
|
||||
@object.send(:atan2, 0.0, 1.0).should be_close(0.0, TOLERANCE)
|
||||
@object.send(:atan2, -9.1, 3.2).should be_close(-1.23265379809025, TOLERANCE)
|
||||
@object.send(:atan2, 7.22, -3.3).should be_close(1.99950888779256, TOLERANCE)
|
||||
end
|
||||
|
||||
it "returns the arc tangent for two Complex numbers" do
|
||||
CMath.atan2(Complex(3, 4), Complex(3.5, -4)).should be_close(Complex(-0.641757436698881, 1.10829873031207), TOLERANCE)
|
||||
end
|
||||
|
||||
it "returns the arc tangent for Complex and real numbers" do
|
||||
CMath.atan2(Complex(3, 4), -7).should be_close(Complex(2.61576754731561, -0.494290673139855), TOLERANCE)
|
||||
CMath.atan2(5, Complex(3.5, -4)).should be_close(Complex(0.739102348493673, 0.487821626522923), TOLERANCE)
|
||||
end
|
||||
end
|
||||
|
||||
describe :complex_math_atan2_bang, shared: true do
|
||||
it "returns the arc tangent of the passed arguments" do
|
||||
@object.send(:atan2!, 4.2, 0.3).should be_close(1.49948886200961, TOLERANCE)
|
||||
@object.send(:atan2!, 0.0, 1.0).should be_close(0.0, TOLERANCE)
|
||||
@object.send(:atan2!, -9.1, 3.2).should be_close(-1.23265379809025, TOLERANCE)
|
||||
@object.send(:atan2!, 7.22, -3.3).should be_close(1.99950888779256, TOLERANCE)
|
||||
end
|
||||
|
||||
it "raises a TypeError when passed a Complex number" do
|
||||
-> { @object.send(:atan2!, Complex(4, 5), Complex(4, 5)) }.should raise_error(TypeError)
|
||||
-> { @object.send(:atan2!, 4, Complex(4, 5)) }.should raise_error(TypeError)
|
||||
-> { @object.send(:atan2!, Complex(4, 5), 5) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
|
@ -1,30 +0,0 @@
|
|||
require_relative '../fixtures/classes'
|
||||
|
||||
describe :complex_math_atanh_complex, shared: true do
|
||||
it "returns the inverse hyperbolic tangent as a Complex number for arguments greater than 1.0" do
|
||||
value = Complex(18.36840028483855, 1.5707963267948966)
|
||||
@object.send(@method, 1.0 + Float::EPSILON).should be_close(value, TOLERANCE)
|
||||
|
||||
value = Complex(0.100335347731076, 1.5707963267949)
|
||||
@object.send(@method, 10).should be_close(value, TOLERANCE)
|
||||
end
|
||||
|
||||
it "returns the inverse hyperbolic tangent as a Complex number for arguments greater than 1.0" do
|
||||
value = Complex(-18.36840028483855, 1.5707963267948966)
|
||||
@object.send(@method, -1.0 - Float::EPSILON).should be_close(value, TOLERANCE)
|
||||
|
||||
value = Complex(0.100335347731076, 1.5707963267949)
|
||||
@object.send(@method, 10).should be_close(value, TOLERANCE)
|
||||
end
|
||||
|
||||
it "returns the inverse hyperbolic tangent for Complex numbers" do
|
||||
value = Complex(0.117500907311434, 1.40992104959658)
|
||||
@object.send(@method, Complex(3, 4)).should be_close(value, TOLERANCE)
|
||||
end
|
||||
end
|
||||
|
||||
describe :complex_math_atanh_no_complex, shared: true do
|
||||
it "raises a TypeError when passed a Complex number" do
|
||||
-> { @object.send(:atanh!, Complex(4, 5)) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
|
@ -1,30 +0,0 @@
|
|||
require_relative '../fixtures/classes'
|
||||
|
||||
describe :complex_math_cos, shared: true do
|
||||
it "returns the cosine of the argument expressed in radians" do
|
||||
@object.send(:cos, CMath::PI).should be_close(-1.0, TOLERANCE)
|
||||
@object.send(:cos, 0).should be_close(1.0, TOLERANCE)
|
||||
@object.send(:cos, CMath::PI/2).should be_close(0.0, TOLERANCE)
|
||||
@object.send(:cos, 3*Math::PI/2).should be_close(0.0, TOLERANCE)
|
||||
@object.send(:cos, 2*Math::PI).should be_close(1.0, TOLERANCE)
|
||||
end
|
||||
|
||||
it "returns the cosine for Complex numbers" do
|
||||
@object.send(:cos, Complex(0, CMath::PI)).should be_close(Complex(11.5919532755215, 0.0), TOLERANCE)
|
||||
@object.send(:cos, Complex(3, 4)).should be_close(Complex(-27.0349456030742, -3.85115333481178), TOLERANCE)
|
||||
end
|
||||
end
|
||||
|
||||
describe :complex_math_cos_bang, shared: true do
|
||||
it "returns the cosine of the argument expressed in radians" do
|
||||
@object.send(:cos!, CMath::PI).should be_close(-1.0, TOLERANCE)
|
||||
@object.send(:cos!, 0).should be_close(1.0, TOLERANCE)
|
||||
@object.send(:cos!, CMath::PI/2).should be_close(0.0, TOLERANCE)
|
||||
@object.send(:cos!, 3*Math::PI/2).should be_close(0.0, TOLERANCE)
|
||||
@object.send(:cos!, 2*Math::PI).should be_close(1.0, TOLERANCE)
|
||||
end
|
||||
|
||||
it "raises a TypeError when passed a Complex number" do
|
||||
-> { @object.send(:cos!, Complex(3, 4)) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
|
@ -1,28 +0,0 @@
|
|||
require_relative '../fixtures/classes'
|
||||
|
||||
describe :complex_math_cosh, shared: true do
|
||||
it "returns the hyperbolic cosine of the passed argument" do
|
||||
@object.send(:cosh, 0.0).should == 1.0
|
||||
@object.send(:cosh, -0.0).should == 1.0
|
||||
@object.send(:cosh, 1.5).should be_close(2.35240961524325, TOLERANCE)
|
||||
@object.send(:cosh, -2.99).should be_close(9.96798496414416, TOLERANCE)
|
||||
end
|
||||
|
||||
it "returns the hyperbolic cosine for Complex numbers" do
|
||||
@object.send(:cosh, Complex(0, CMath::PI)).should be_close(Complex(-1.0, 0.0), TOLERANCE)
|
||||
@object.send(:cosh, Complex(3, 4)).should be_close(Complex(-6.58066304055116, -7.58155274274654), TOLERANCE)
|
||||
end
|
||||
end
|
||||
|
||||
describe :complex_math_cosh_bang, shared: true do
|
||||
it "returns the hyperbolic cosine of the passed argument" do
|
||||
@object.send(:cosh!, 0.0).should == 1.0
|
||||
@object.send(:cosh!, -0.0).should == 1.0
|
||||
@object.send(:cosh!, 1.5).should be_close(2.35240961524325, TOLERANCE)
|
||||
@object.send(:cosh!, -2.99).should be_close(9.96798496414416, TOLERANCE)
|
||||
end
|
||||
|
||||
it "raises a TypeError when passed a Complex number" do
|
||||
-> { @object.send(:cosh!, Complex(4, 5)) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
|
@ -1,28 +0,0 @@
|
|||
require_relative '../fixtures/classes'
|
||||
|
||||
describe :complex_math_exp, shared: true do
|
||||
it "returns the base-e exponential of the passed argument" do
|
||||
@object.send(:exp, 0.0).should == 1.0
|
||||
@object.send(:exp, -0.0).should == 1.0
|
||||
@object.send(:exp, -1.8).should be_close(0.165298888221587, TOLERANCE)
|
||||
@object.send(:exp, 1.25).should be_close(3.49034295746184, TOLERANCE)
|
||||
end
|
||||
|
||||
it "returns the base-e exponential for Complex numbers" do
|
||||
@object.send(:exp, Complex(0, 0)).should == Complex(1.0, 0.0)
|
||||
@object.send(:exp, Complex(1, 3)).should be_close(Complex(-2.69107861381979, 0.383603953541131), TOLERANCE)
|
||||
end
|
||||
end
|
||||
|
||||
describe :complex_math_exp_bang, shared: true do
|
||||
it "returns the base-e exponential of the passed argument" do
|
||||
@object.send(:exp!, 0.0).should == 1.0
|
||||
@object.send(:exp!, -0.0).should == 1.0
|
||||
@object.send(:exp!, -1.8).should be_close(0.165298888221587, TOLERANCE)
|
||||
@object.send(:exp!, 1.25).should be_close(3.49034295746184, TOLERANCE)
|
||||
end
|
||||
|
||||
it "raises a TypeError when passed a Complex number" do
|
||||
-> { @object.send(:exp!, Complex(1, 3)) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
|
@ -1,39 +0,0 @@
|
|||
require_relative '../fixtures/classes'
|
||||
|
||||
describe :complex_math_log, shared: true do
|
||||
it "returns the natural logarithm of the passed argument" do
|
||||
@object.send(:log, 0.0001).should be_close(-9.21034037197618, TOLERANCE)
|
||||
@object.send(:log, 0.000000000001e-15).should be_close(-62.1697975108392, TOLERANCE)
|
||||
@object.send(:log, 1).should be_close(0.0, TOLERANCE)
|
||||
@object.send(:log, 10).should be_close( 2.30258509299405, TOLERANCE)
|
||||
@object.send(:log, 10e15).should be_close(36.8413614879047, TOLERANCE)
|
||||
end
|
||||
|
||||
it "returns the natural logarithm for Complex numbers" do
|
||||
@object.send(:log, Complex(3, 4)).should be_close(Complex(1.6094379124341, 0.927295218001612), TOLERANCE)
|
||||
@object.send(:log, Complex(-3, 4)).should be_close(Complex(1.6094379124341, 2.21429743558818), TOLERANCE)
|
||||
end
|
||||
|
||||
it "returns the natural logarithm for negative numbers as a Complex number" do
|
||||
@object.send(:log, -10).should be_close(Complex(2.30258509299405, 3.14159265358979), TOLERANCE)
|
||||
@object.send(:log, -20).should be_close(Complex(2.99573227355399, 3.14159265358979), TOLERANCE)
|
||||
end
|
||||
end
|
||||
|
||||
describe :complex_math_log_bang, shared: true do
|
||||
it "returns the natural logarithm of the argument" do
|
||||
@object.send(:log!, 0.0001).should be_close(-9.21034037197618, TOLERANCE)
|
||||
@object.send(:log!, 0.000000000001e-15).should be_close(-62.1697975108392, TOLERANCE)
|
||||
@object.send(:log!, 1).should be_close(0.0, TOLERANCE)
|
||||
@object.send(:log!, 10).should be_close( 2.30258509299405, TOLERANCE)
|
||||
@object.send(:log!, 10e15).should be_close(36.8413614879047, TOLERANCE)
|
||||
end
|
||||
|
||||
it "raises an Errno::EDOM if the argument is less than 0" do
|
||||
-> { @object.send(:log!, -10) }.should raise_error(Errno::EDOM)
|
||||
end
|
||||
|
||||
it "raises a TypeError when passed a Complex number" do
|
||||
-> { @object.send(:log!, Complex(4, 5)) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
|
@ -1,41 +0,0 @@
|
|||
require_relative '../fixtures/classes'
|
||||
|
||||
describe :complex_math_log10, shared: true do
|
||||
it "returns the base-10 logarithm of the passed argument" do
|
||||
@object.send(:log10, 0.0001).should be_close(-4.0, TOLERANCE)
|
||||
@object.send(:log10, 0.000000000001e-15).should be_close(-27.0, TOLERANCE)
|
||||
@object.send(:log10, 1).should be_close(0.0, TOLERANCE)
|
||||
@object.send(:log10, 10).should be_close(1.0, TOLERANCE)
|
||||
@object.send(:log10, 10e15).should be_close(16.0, TOLERANCE)
|
||||
end
|
||||
|
||||
it "returns the base-10 logarithm for Complex numbers" do
|
||||
@object.send(:log10, Complex(3, 4)).should be_close(Complex(0.698970004336019, 0.402719196273373), TOLERANCE)
|
||||
@object.send(:log10, Complex(-3, 4)).should be_close(Complex(0.698970004336019, 0.961657157568468), TOLERANCE)
|
||||
end
|
||||
|
||||
# BUG: does not work correctly, because Math#log10
|
||||
# does not check for negative values
|
||||
#it "returns the base-10 logarithm for negative numbers as a Complex number" do
|
||||
# @object.send(:log10, -10).should be_close(Complex(2.30258509299405, 3.14159265358979), TOLERANCE)
|
||||
# @object.send(:log10, -20).should be_close(Complex(2.99573227355399, 3.14159265358979), TOLERANCE)
|
||||
#end
|
||||
end
|
||||
|
||||
describe :complex_math_log10_bang, shared: true do
|
||||
it "returns the base-10 logarithm of the argument" do
|
||||
@object.send(:log10!, 0.0001).should be_close(-4.0, TOLERANCE)
|
||||
@object.send(:log10!, 0.000000000001e-15).should be_close(-27.0, TOLERANCE)
|
||||
@object.send(:log10!, 1).should be_close(0.0, TOLERANCE)
|
||||
@object.send(:log10!, 10).should be_close(1.0, TOLERANCE)
|
||||
@object.send(:log10!, 10e15).should be_close(16.0, TOLERANCE)
|
||||
end
|
||||
|
||||
it "raises an Errno::EDOM when the passed argument is negative" do
|
||||
-> { @object.send(:log10!, -10) }.should raise_error(Errno::EDOM)
|
||||
end
|
||||
|
||||
it "raises a TypeError when passed a Complex number" do
|
||||
-> { @object.send(:log10!, Complex(4, 5)) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
|
@ -1,30 +0,0 @@
|
|||
require_relative '../fixtures/classes'
|
||||
|
||||
describe :complex_math_sin, shared: true do
|
||||
it "returns the sine of the passed argument expressed in radians" do
|
||||
@object.send(:sin, CMath::PI).should be_close(0.0, TOLERANCE)
|
||||
@object.send(:sin, 0).should be_close(0.0, TOLERANCE)
|
||||
@object.send(:sin, CMath::PI/2).should be_close(1.0, TOLERANCE)
|
||||
@object.send(:sin, 3*Math::PI/2).should be_close(-1.0, TOLERANCE)
|
||||
@object.send(:sin, 2*Math::PI).should be_close(0.0, TOLERANCE)
|
||||
end
|
||||
|
||||
it "returns the sine for Complex numbers" do
|
||||
@object.send(:sin, Complex(0, CMath::PI)).should be_close(Complex(0.0, 11.5487393572577), TOLERANCE)
|
||||
@object.send(:sin, Complex(3, 4)).should be_close(Complex(3.85373803791938, -27.0168132580039), TOLERANCE)
|
||||
end
|
||||
end
|
||||
|
||||
describe :complex_math_sin_bang, shared: true do
|
||||
it "returns the sine of the passed argument expressed in radians" do
|
||||
@object.send(:sin!, CMath::PI).should be_close(0.0, TOLERANCE)
|
||||
@object.send(:sin!, 0).should be_close(0.0, TOLERANCE)
|
||||
@object.send(:sin!, CMath::PI/2).should be_close(1.0, TOLERANCE)
|
||||
@object.send(:sin!, 3*Math::PI/2).should be_close(-1.0, TOLERANCE)
|
||||
@object.send(:sin!, 2*Math::PI).should be_close(0.0, TOLERANCE)
|
||||
end
|
||||
|
||||
it "raises a TypeError when passed a Complex number" do
|
||||
-> { @object.send(:sin!, Complex(4, 5)) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
|
@ -1,28 +0,0 @@
|
|||
require_relative '../fixtures/classes'
|
||||
|
||||
describe :complex_math_sinh, shared: true do
|
||||
it "returns the hyperbolic sin of the argument" do
|
||||
@object.send(:sinh, 0.0).should == 0.0
|
||||
@object.send(:sinh, -0.0).should == 0.0
|
||||
@object.send(:sinh, 1.5).should be_close(2.12927945509482, TOLERANCE)
|
||||
@object.send(:sinh, -2.8).should be_close(-8.19191835423591, TOLERANCE)
|
||||
end
|
||||
|
||||
it "returns the hyperbolic sin for Complex numbers" do
|
||||
@object.send(:sinh, Complex(0, CMath::PI)).should be_close(Complex(-0.0, 1.22464679914735e-16), TOLERANCE)
|
||||
@object.send(:sinh, Complex(3, 4)).should be_close(Complex(-6.548120040911, -7.61923172032141), TOLERANCE)
|
||||
end
|
||||
end
|
||||
|
||||
describe :complex_math_sinh_bang, shared: true do
|
||||
it "returns the hyperbolic sin of the argument" do
|
||||
@object.send(:sinh!, 0.0).should == 0.0
|
||||
@object.send(:sinh!, -0.0).should == 0.0
|
||||
@object.send(:sinh!, 1.5).should be_close(2.12927945509482, TOLERANCE)
|
||||
@object.send(:sinh!, -2.8).should be_close(-8.19191835423591, TOLERANCE)
|
||||
end
|
||||
|
||||
it "raises a TypeError when passed a Complex number" do
|
||||
-> { @object.send(:sinh!, Complex(4, 5)) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
|
@ -1,34 +0,0 @@
|
|||
require_relative '../fixtures/classes'
|
||||
|
||||
describe :complex_math_sqrt, shared: true do
|
||||
it "returns the square root for positive numbers" do
|
||||
@object.send(:sqrt, 4).should == 2
|
||||
@object.send(:sqrt, 19.36).should == 4.4
|
||||
end
|
||||
|
||||
it "returns the square root for negative numbers" do
|
||||
@object.send(:sqrt, -4).should == Complex(0, 2.0)
|
||||
@object.send(:sqrt, -19.36).should == Complex(0, 4.4)
|
||||
end
|
||||
|
||||
it "returns the square root for Complex numbers" do
|
||||
@object.send(:sqrt, Complex(4, 5)).should be_close(Complex(2.2806933416653, 1.09615788950152), TOLERANCE)
|
||||
@object.send(:sqrt, Complex(4, -5)).should be_close(Complex(2.2806933416653, -1.09615788950152), TOLERANCE)
|
||||
end
|
||||
end
|
||||
|
||||
describe :complex_math_sqrt_bang, shared: true do
|
||||
it "returns the square root for positive numbers" do
|
||||
@object.send(:sqrt!, 4).should == 2
|
||||
@object.send(:sqrt!, 19.36).should == 4.4
|
||||
end
|
||||
|
||||
it "raises Errno::EDOM when the passed argument is negative" do
|
||||
-> { @object.send(:sqrt!, -4) }.should raise_error(Errno::EDOM)
|
||||
-> { @object.send(:sqrt!, -19.36) }.should raise_error(Errno::EDOM)
|
||||
end
|
||||
|
||||
it "raises a TypeError when passed a Complex number" do
|
||||
-> { @object.send(:sqrt!, Complex(4, 5)) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
|
@ -1,28 +0,0 @@
|
|||
require_relative '../fixtures/classes'
|
||||
|
||||
describe :complex_math_tan, shared: true do
|
||||
it "returns the tangent of the argument" do
|
||||
@object.send(:tan, 0.0).should == 0.0
|
||||
@object.send(:tan, -0.0).should == -0.0
|
||||
@object.send(:tan, 4.22).should be_close(1.86406937682395, TOLERANCE)
|
||||
@object.send(:tan, -9.65).should be_close(-0.229109052606441, TOLERANCE)
|
||||
end
|
||||
|
||||
it "returns the tangent for Complex numbers" do
|
||||
@object.send(:tan, Complex(0, CMath::PI)).should be_close(Complex(0.0, 0.99627207622075), TOLERANCE)
|
||||
@object.send(:tan, Complex(3, 4)).should be_close(Complex(-0.000187346204629452, 0.999355987381473), TOLERANCE)
|
||||
end
|
||||
end
|
||||
|
||||
describe :complex_math_tan_bang, shared: true do
|
||||
it "returns the tangent of the argument" do
|
||||
@object.send(:tan!, 0.0).should == 0.0
|
||||
@object.send(:tan!, -0.0).should == -0.0
|
||||
@object.send(:tan!, 4.22).should be_close(1.86406937682395, TOLERANCE)
|
||||
@object.send(:tan!, -9.65).should be_close(-0.229109052606441, TOLERANCE)
|
||||
end
|
||||
|
||||
it "raises a TypeError when passed a Complex number" do
|
||||
-> { @object.send(:tan!, Complex(4, 5)) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
|
@ -1,32 +0,0 @@
|
|||
require_relative '../fixtures/classes'
|
||||
|
||||
describe :complex_math_tanh, shared: true do
|
||||
it "returns the hyperbolic tangent of the argument" do
|
||||
@object.send(:tanh, 0.0).should == 0.0
|
||||
@object.send(:tanh, -0.0).should == -0.0
|
||||
@object.send(:tanh, infinity_value).should == 1.0
|
||||
@object.send(:tanh, -infinity_value).should == -1.0
|
||||
@object.send(:tanh, 2.5).should be_close(0.98661429815143, TOLERANCE)
|
||||
@object.send(:tanh, -4.892).should be_close(-0.999887314427707, TOLERANCE)
|
||||
end
|
||||
|
||||
it "returns the hyperbolic tangent for Complex numbers" do
|
||||
@object.send(:tanh, Complex(0, CMath::PI)).should be_close(Complex(0.0, -1.22464679914735e-16), TOLERANCE)
|
||||
@object.send(:tanh, Complex(3, 4)).should be_close(Complex(1.00070953606723, 0.00490825806749599), TOLERANCE)
|
||||
end
|
||||
end
|
||||
|
||||
describe :complex_math_tanh_bang, shared: true do
|
||||
it "returns the hyperbolic tangent of the argument" do
|
||||
@object.send(:tanh!, 0.0).should == 0.0
|
||||
@object.send(:tanh!, -0.0).should == -0.0
|
||||
@object.send(:tanh!, infinity_value).should == 1.0
|
||||
@object.send(:tanh!, -infinity_value).should == -1.0
|
||||
@object.send(:tanh!, 2.5).should be_close(0.98661429815143, TOLERANCE)
|
||||
@object.send(:tanh!, -4.892).should be_close(-0.999887314427707, TOLERANCE)
|
||||
end
|
||||
|
||||
it "raises a TypeError when passed a Complex number" do
|
||||
-> { @object.send(:tanh!, Complex(4, 5)) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
|
@ -1 +0,0 @@
|
|||
require_relative '../../../spec_helper'
|
|
@ -1 +0,0 @@
|
|||
require_relative '../../../spec_helper'
|
|
@ -1 +0,0 @@
|
|||
require_relative '../../../spec_helper'
|
|
@ -1 +0,0 @@
|
|||
require_relative '../../../spec_helper'
|
|
@ -1 +0,0 @@
|
|||
require_relative '../../../spec_helper'
|
|
@ -138,4 +138,20 @@ END
|
|||
ERB.new(@eruby_str).result
|
||||
->{ ERB.new("<%= list %>").result }.should raise_error(NameError)
|
||||
end
|
||||
|
||||
describe "warning about arguments" do
|
||||
ruby_version_is "3.1" do
|
||||
it "warns when passed safe_level and later arguments" do
|
||||
-> {
|
||||
ERB.new(@eruby_str, nil, '%')
|
||||
}.should complain(/warning: Passing safe_level with the 2nd argument of ERB.new is deprecated. Do not use it, and specify other arguments as keyword arguments./)
|
||||
end
|
||||
|
||||
it "does not warn when passed arguments as keyword argument" do
|
||||
-> {
|
||||
ERB.new(@eruby_str, trim_mode: '%')
|
||||
}.should_not complain(/warning: Passing safe_level with the 2nd argument of ERB.new is deprecated. Do not use it, and specify other arguments as keyword arguments./)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
require_relative '../../../spec_helper'
|
|
@ -1,4 +0,0 @@
|
|||
Beethoven 1770
|
||||
Bach 1685
|
||||
Handel 1685
|
||||
|
|
@ -1 +0,0 @@
|
|||
hello world
|
|
@ -1 +0,0 @@
|
|||
require_relative '../../../spec_helper'
|
|
@ -1,28 +0,0 @@
|
|||
require 'scanf'
|
||||
|
||||
describe :scanf_io_block_scanf, shared: true do
|
||||
before :each do
|
||||
@data = File.open(fixture(__FILE__, 'date.txt'), 'rb')
|
||||
end
|
||||
|
||||
after :each do
|
||||
@data.close unless @data.closed?
|
||||
end
|
||||
|
||||
it "passes each match to the block as an array" do
|
||||
res = @data.send(@method, "%s%d") { |name, year| "#{name} was born in #{year}." }
|
||||
res.should == ["Beethoven was born in 1770.", "Bach was born in 1685.", "Handel was born in 1685."]
|
||||
end
|
||||
|
||||
it "keeps scanning the input and cycling back to the beginning of the input string" do
|
||||
a = []
|
||||
@data.send(@method, "%s"){|w| a << w}
|
||||
a.should == [["Beethoven"], ["1770"], ["Bach"], ["1685"], ["Handel"], ["1685"]]
|
||||
end
|
||||
|
||||
it "returns an empty array when a wrong specifier is passed" do
|
||||
a = []
|
||||
@data.send(@method, "%z"){|w| a << w}
|
||||
a.empty?.should be_true
|
||||
end
|
||||
end
|
|
@ -1 +0,0 @@
|
|||
require_relative '../../../spec_helper'
|
|
@ -1 +0,0 @@
|
|||
require_relative '../../../spec_helper'
|
|
@ -1,25 +0,0 @@
|
|||
require 'scanf'
|
||||
|
||||
describe :scanf_string_block_scanf, shared: true do
|
||||
it "passes each match to the block as an array" do
|
||||
a = []
|
||||
"hello world".send(@method, "%s%s"){|w| a << w}
|
||||
a.should == [["hello", "world"]]
|
||||
end
|
||||
|
||||
it "keeps scanning the input and cycling back to the beginning of the input string" do
|
||||
a = []
|
||||
"hello world".send(@method, "%s"){|w| a << w}
|
||||
a.should == [["hello"], ["world"]]
|
||||
|
||||
string = "123 abc 456 def 789 ghi"
|
||||
s = string.send(@method, "%d%s"){|num,str| [num * 2, str.upcase]}
|
||||
s.should == [[246, "ABC"], [912, "DEF"], [1578, "GHI"]]
|
||||
end
|
||||
|
||||
it "returns an empty array when a wrong specifier is passed" do
|
||||
a = []
|
||||
"hello world".send(@method, "%z"){|w| a << w}
|
||||
a.empty?.should be_true
|
||||
end
|
||||
end
|
|
@ -35,6 +35,21 @@ describe "StringIO#putc when passed [String]" do
|
|||
@io.putc("t")
|
||||
@io.pos.should == 3
|
||||
end
|
||||
|
||||
it "handles concurrent writes correctly" do
|
||||
@io = StringIO.new
|
||||
n = 8
|
||||
go = false
|
||||
threads = n.times.map { |i|
|
||||
Thread.new {
|
||||
Thread.pass until go
|
||||
@io.putc i.to_s
|
||||
}
|
||||
}
|
||||
go = true
|
||||
threads.each(&:join)
|
||||
@io.string.size.should == n
|
||||
end
|
||||
end
|
||||
|
||||
describe "StringIO#putc when passed [Object]" do
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче