mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Update to ruby/spec@bacedc5
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60973 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
821d9a2d30
commit
4d7b0b9112
104 changed files with 2105 additions and 510 deletions
|
@ -13,6 +13,10 @@ Layout/TrailingWhitespace:
|
|||
Lint:
|
||||
Enabled: true
|
||||
|
||||
# {...} has higher precedence than do ... end, on purpose
|
||||
Lint/AmbiguousBlockAssociation:
|
||||
Enabled: false
|
||||
|
||||
Lint/AssignmentInCondition:
|
||||
Enabled: false
|
||||
|
||||
|
|
|
@ -6,14 +6,6 @@
|
|||
# Note that changes in the inspected code, or installation of new
|
||||
# versions of RuboCop, may require this file to be generated again.
|
||||
|
||||
# Offense count: 6
|
||||
Lint/AmbiguousBlockAssociation:
|
||||
Exclude:
|
||||
- 'core/kernel/trace_var_spec.rb'
|
||||
- 'language/fixtures/argv_encoding.rb'
|
||||
- 'language/fixtures/break.rb'
|
||||
- 'shared/process/abort.rb'
|
||||
|
||||
# Offense count: 3
|
||||
Lint/CircularArgumentReference:
|
||||
Exclude:
|
||||
|
@ -57,6 +49,8 @@ Lint/FormatParameterMismatch:
|
|||
Exclude:
|
||||
- 'core/kernel/sprintf_spec.rb'
|
||||
- 'core/string/modulo_spec.rb'
|
||||
- 'core/kernel/shared/sprintf.rb'
|
||||
- 'core/kernel/shared/sprintf_encoding.rb'
|
||||
|
||||
# Offense count: 25
|
||||
Lint/HandleExceptions:
|
||||
|
|
|
@ -27,6 +27,11 @@ describe "Processing RUBYOPT" do
|
|||
ruby_exe("")[/\A.*/].should == RUBY_DESCRIPTION
|
||||
end
|
||||
|
||||
it "ignores whitespace around the option" do
|
||||
ENV["RUBYOPT"] = ' -v '
|
||||
ruby_exe("")[/\A.*/].should == RUBY_DESCRIPTION
|
||||
end
|
||||
|
||||
it "sets $VERBOSE to true for '-w'" do
|
||||
ENV["RUBYOPT"] = '-w'
|
||||
ruby_exe("p $VERBOSE", escape: true).chomp.should == "true"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/push', __FILE__)
|
||||
|
||||
describe "Array#<<" do
|
||||
it "pushes the object onto the end of the array" do
|
||||
|
@ -33,3 +34,9 @@ describe "Array#<<" do
|
|||
lambda { ArraySpecs.frozen_array << 5 }.should raise_error(RuntimeError)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is "2.5" do
|
||||
describe "Array#append" do
|
||||
it_behaves_like(:array_push, :append)
|
||||
end
|
||||
end
|
||||
|
|
9
spec/ruby/core/array/prepend_spec.rb
Normal file
9
spec/ruby/core/array/prepend_spec.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/unshift', __FILE__)
|
||||
|
||||
ruby_version_is "2.5" do
|
||||
describe "Array#prepend" do
|
||||
it_behaves_like(:array_unshift, :prepend)
|
||||
end
|
||||
end
|
|
@ -1,36 +1,7 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/push', __FILE__)
|
||||
|
||||
describe "Array#push" do
|
||||
it "appends the arguments to the array" do
|
||||
a = [ "a", "b", "c" ]
|
||||
a.push("d", "e", "f").should equal(a)
|
||||
a.push().should == ["a", "b", "c", "d", "e", "f"]
|
||||
a.push(5)
|
||||
a.should == ["a", "b", "c", "d", "e", "f", 5]
|
||||
|
||||
a = [0, 1]
|
||||
a.push(2)
|
||||
a.should == [0, 1, 2]
|
||||
end
|
||||
|
||||
it "isn't confused by previous shift" do
|
||||
a = [ "a", "b", "c" ]
|
||||
a.shift
|
||||
a.push("foo")
|
||||
a.should == ["b", "c", "foo"]
|
||||
end
|
||||
|
||||
it "properly handles recursive arrays" do
|
||||
empty = ArraySpecs.empty_recursive_array
|
||||
empty.push(:last).should == [empty, :last]
|
||||
|
||||
array = ArraySpecs.recursive_array
|
||||
array.push(:last).should == [1, 'two', 3.0, array, array, array, array, array, :last]
|
||||
end
|
||||
|
||||
it "raises a RuntimeError on a frozen array" do
|
||||
lambda { ArraySpecs.frozen_array.push(1) }.should raise_error(RuntimeError)
|
||||
lambda { ArraySpecs.frozen_array.push }.should raise_error(RuntimeError)
|
||||
end
|
||||
it_behaves_like(:array_push, :push)
|
||||
end
|
||||
|
|
33
spec/ruby/core/array/shared/push.rb
Normal file
33
spec/ruby/core/array/shared/push.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
describe :array_push, shared: true do
|
||||
it "appends the arguments to the array" do
|
||||
a = [ "a", "b", "c" ]
|
||||
a.send(@method, "d", "e", "f").should equal(a)
|
||||
a.send(@method).should == ["a", "b", "c", "d", "e", "f"]
|
||||
a.send(@method, 5)
|
||||
a.should == ["a", "b", "c", "d", "e", "f", 5]
|
||||
|
||||
a = [0, 1]
|
||||
a.send(@method, 2)
|
||||
a.should == [0, 1, 2]
|
||||
end
|
||||
|
||||
it "isn't confused by previous shift" do
|
||||
a = [ "a", "b", "c" ]
|
||||
a.shift
|
||||
a.send(@method, "foo")
|
||||
a.should == ["b", "c", "foo"]
|
||||
end
|
||||
|
||||
it "properly handles recursive arrays" do
|
||||
empty = ArraySpecs.empty_recursive_array
|
||||
empty.send(@method, :last).should == [empty, :last]
|
||||
|
||||
array = ArraySpecs.recursive_array
|
||||
array.send(@method, :last).should == [1, 'two', 3.0, array, array, array, array, array, :last]
|
||||
end
|
||||
|
||||
it "raises a RuntimeError on a frozen array" do
|
||||
lambda { ArraySpecs.frozen_array.send(@method, 1) }.should raise_error(RuntimeError)
|
||||
lambda { ArraySpecs.frozen_array.send(@method) }.should raise_error(RuntimeError)
|
||||
end
|
||||
end
|
46
spec/ruby/core/array/shared/unshift.rb
Normal file
46
spec/ruby/core/array/shared/unshift.rb
Normal file
|
@ -0,0 +1,46 @@
|
|||
describe :array_unshift, shared: true do
|
||||
it "prepends object to the original array" do
|
||||
a = [1, 2, 3]
|
||||
a.send(@method, "a").should equal(a)
|
||||
a.should == ['a', 1, 2, 3]
|
||||
a.send(@method).should equal(a)
|
||||
a.should == ['a', 1, 2, 3]
|
||||
a.send(@method, 5, 4, 3)
|
||||
a.should == [5, 4, 3, 'a', 1, 2, 3]
|
||||
|
||||
# shift all but one element
|
||||
a = [1, 2]
|
||||
a.shift
|
||||
a.send(@method, 3, 4)
|
||||
a.should == [3, 4, 2]
|
||||
|
||||
# now shift all elements
|
||||
a.shift
|
||||
a.shift
|
||||
a.shift
|
||||
a.send(@method, 3, 4)
|
||||
a.should == [3, 4]
|
||||
end
|
||||
|
||||
it "quietly ignores unshifting nothing" do
|
||||
[].send(@method).should == []
|
||||
end
|
||||
|
||||
it "properly handles recursive arrays" do
|
||||
empty = ArraySpecs.empty_recursive_array
|
||||
empty.send(@method, :new).should == [:new, empty]
|
||||
|
||||
array = ArraySpecs.recursive_array
|
||||
array.send(@method, :new)
|
||||
array[0..5].should == [:new, 1, 'two', 3.0, array, array]
|
||||
end
|
||||
|
||||
it "raises a RuntimeError on a frozen array when the array is modified" do
|
||||
lambda { ArraySpecs.frozen_array.send(@method, 1) }.should raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
# see [ruby-core:23666]
|
||||
it "raises a RuntimeError on a frozen array when the array would not be modified" do
|
||||
lambda { ArraySpecs.frozen_array.send(@method) }.should raise_error(RuntimeError)
|
||||
end
|
||||
end
|
|
@ -66,7 +66,9 @@ describe "Array#sort" do
|
|||
it "does not deal with exceptions raised by unimplemented or incorrect #<=>" do
|
||||
o = Object.new
|
||||
|
||||
lambda { [o, 1].sort }.should raise_error
|
||||
lambda {
|
||||
[o, 1].sort
|
||||
}.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "may take a block which is used to determine the order of objects a and b described as -1, 0 or +1" do
|
||||
|
|
|
@ -1,50 +1,7 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/unshift', __FILE__)
|
||||
|
||||
describe "Array#unshift" do
|
||||
it "prepends object to the original array" do
|
||||
a = [1, 2, 3]
|
||||
a.unshift("a").should equal(a)
|
||||
a.should == ['a', 1, 2, 3]
|
||||
a.unshift().should equal(a)
|
||||
a.should == ['a', 1, 2, 3]
|
||||
a.unshift(5, 4, 3)
|
||||
a.should == [5, 4, 3, 'a', 1, 2, 3]
|
||||
|
||||
# shift all but one element
|
||||
a = [1, 2]
|
||||
a.shift
|
||||
a.unshift(3, 4)
|
||||
a.should == [3, 4, 2]
|
||||
|
||||
# now shift all elements
|
||||
a.shift
|
||||
a.shift
|
||||
a.shift
|
||||
a.unshift(3, 4)
|
||||
a.should == [3, 4]
|
||||
end
|
||||
|
||||
it "quietly ignores unshifting nothing" do
|
||||
[].unshift().should == []
|
||||
[].unshift(*[]).should == []
|
||||
end
|
||||
|
||||
it "properly handles recursive arrays" do
|
||||
empty = ArraySpecs.empty_recursive_array
|
||||
empty.unshift(:new).should == [:new, empty]
|
||||
|
||||
array = ArraySpecs.recursive_array
|
||||
array.unshift(:new)
|
||||
array[0..5].should == [:new, 1, 'two', 3.0, array, array]
|
||||
end
|
||||
|
||||
it "raises a RuntimeError on a frozen array when the array is modified" do
|
||||
lambda { ArraySpecs.frozen_array.unshift(1) }.should raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
# see [ruby-core:23666]
|
||||
it "raises a RuntimeError on a frozen array when the array would not be modified" do
|
||||
lambda { ArraySpecs.frozen_array.unshift }.should raise_error(RuntimeError)
|
||||
end
|
||||
it_behaves_like(:array_unshift, :unshift)
|
||||
end
|
||||
|
|
|
@ -11,9 +11,9 @@ describe "Bignum#**" do
|
|||
end
|
||||
|
||||
it "raises a TypeError when given a non-Integer" do
|
||||
lambda { @bignum ** mock('10') }.should raise_error
|
||||
lambda { @bignum ** "10" }.should raise_error
|
||||
lambda { @bignum ** :symbol }.should raise_error
|
||||
lambda { @bignum ** mock('10') }.should raise_error(TypeError)
|
||||
lambda { @bignum ** "10" }.should raise_error(TypeError)
|
||||
lambda { @bignum ** :symbol }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "switch to a Float when the values is too big" do
|
||||
|
|
|
@ -31,7 +31,7 @@ platform_is_not :windows do
|
|||
it "calls #to_path on non-String argument" do
|
||||
p = mock('path')
|
||||
p.should_receive(:to_path).and_return('.')
|
||||
lambda { Dir.chroot(p) }.should raise_error
|
||||
lambda { Dir.chroot(p) }.should raise_error(Errno::EPERM)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -30,9 +30,9 @@ describe :dir_open, shared: true do
|
|||
lambda do
|
||||
Dir.send(@method, DirSpecs.mock_dir) do |dir|
|
||||
closed_dir = dir
|
||||
raise
|
||||
raise "dir specs"
|
||||
end
|
||||
end.should raise_error
|
||||
end.should raise_error(RuntimeError, "dir specs")
|
||||
|
||||
lambda { closed_dir.read }.should raise_error(IOError)
|
||||
end
|
||||
|
|
18
spec/ruby/core/file/printf_spec.rb
Normal file
18
spec/ruby/core/file/printf_spec.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../kernel/shared/sprintf', __FILE__)
|
||||
|
||||
describe "File#printf" do
|
||||
it_behaves_like :kernel_sprintf, -> (format, *args) {
|
||||
begin
|
||||
@filename = tmp("printf.txt")
|
||||
|
||||
File.open(@filename, "w", encoding: "utf-8") do |f|
|
||||
f.printf(format, *args)
|
||||
end
|
||||
|
||||
File.read(@filename, encoding: "utf-8")
|
||||
ensure
|
||||
rm_r @filename
|
||||
end
|
||||
}
|
||||
end
|
|
@ -11,10 +11,10 @@ describe "File::Stat#blocks" do
|
|||
end
|
||||
|
||||
platform_is_not :windows do
|
||||
it "returns the blocks of a File::Stat object" do
|
||||
it "returns a non-negative integer" do
|
||||
st = File.stat(@file)
|
||||
st.blocks.is_a?(Integer).should == true
|
||||
st.blocks.should > 0
|
||||
st.blocks.should >= 0
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -13,7 +13,9 @@ describe "File::Stat#initialize" do
|
|||
end
|
||||
|
||||
it "raises an exception if the file doesn't exist" do
|
||||
lambda { File::Stat.new(tmp("i_am_a_dummy_file_that_doesnt_exist")) }.should raise_error
|
||||
lambda {
|
||||
File::Stat.new(tmp("i_am_a_dummy_file_that_doesnt_exist"))
|
||||
}.should raise_error(Errno::ENOENT)
|
||||
end
|
||||
|
||||
it "creates a File::Stat object for the given file" do
|
||||
|
|
|
@ -33,4 +33,15 @@ describe "File.utime" do
|
|||
it "accepts an object that has a #to_path method" do
|
||||
File.utime(@atime, @mtime, mock_to_path(@file1), mock_to_path(@file2))
|
||||
end
|
||||
|
||||
platform_is :linux do
|
||||
platform_is wordsize: 64 do
|
||||
it "allows Time instances in the far future to set mtime and atime" do
|
||||
time = Time.at(1<<44)
|
||||
File.utime(time, time, @file1)
|
||||
File.atime(@file1).year.should == 559444
|
||||
File.mtime(@file1).year.should == 559444
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -43,6 +43,16 @@ describe "IO#read_nonblock" do
|
|||
end
|
||||
end
|
||||
|
||||
platform_is_not :windows do
|
||||
it 'sets the IO in nonblock mode' do
|
||||
require 'io/nonblock'
|
||||
@read.nonblock?.should == false
|
||||
@write.write "abc"
|
||||
@read.read_nonblock(1).should == "a"
|
||||
@read.nonblock?.should == true
|
||||
end
|
||||
end
|
||||
|
||||
it "returns at most the number of bytes requested" do
|
||||
@write << "hello"
|
||||
@read.read_nonblock(4).should == "hell"
|
||||
|
|
|
@ -115,6 +115,47 @@ describe :io_each, shared: true do
|
|||
end
|
||||
end
|
||||
|
||||
describe "with both separator and limit" do
|
||||
describe "when no block is given" do
|
||||
it "returns an Enumerator" do
|
||||
enum = @io.send(@method, nil, 1024)
|
||||
enum.should be_an_instance_of(Enumerator)
|
||||
|
||||
enum.each { |l| ScratchPad << l }
|
||||
ScratchPad.recorded.should == [IOSpecs.lines.join]
|
||||
end
|
||||
|
||||
describe "returned Enumerator" do
|
||||
describe "size" do
|
||||
it "should return nil" do
|
||||
@io.send(@method, nil, 1024).size.should == nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "when a block is given" do
|
||||
it "accepts an empty block" do
|
||||
@io.send(@method, nil, 1024) {}.should equal(@io)
|
||||
end
|
||||
|
||||
describe "when passed nil as a separator" do
|
||||
it "yields self's content starting from the current position when the passed separator is nil" do
|
||||
@io.pos = 100
|
||||
@io.send(@method, nil, 1024) { |s| ScratchPad << s }
|
||||
ScratchPad.recorded.should == ["qui a linha cinco.\nHere is line six.\n"]
|
||||
end
|
||||
end
|
||||
|
||||
describe "when passed an empty String as a separator" do
|
||||
it "yields each paragraph" do
|
||||
@io.send(@method, "", 1024) { |s| ScratchPad << s }
|
||||
ScratchPad.recorded.should == IOSpecs.paragraphs
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is "2.4" do
|
||||
describe "when passed chomp" do
|
||||
it "yields each line without trailing newline characters to the passed block" do
|
||||
|
|
|
@ -80,3 +80,19 @@ describe "IO#sysread on a file" do
|
|||
lambda { IOSpecs.closed_io.sysread(5) }.should raise_error(IOError)
|
||||
end
|
||||
end
|
||||
|
||||
describe "IO#sysread" do
|
||||
before do
|
||||
@read, @write = IO.pipe
|
||||
end
|
||||
|
||||
after do
|
||||
@read.close
|
||||
@write.close
|
||||
end
|
||||
|
||||
it "returns a smaller string if less than size bytes are available" do
|
||||
@write.syswrite "ab"
|
||||
@read.sysread(3).should == "ab"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -32,7 +32,9 @@ platform_is_not :windows do
|
|||
end
|
||||
|
||||
it "checks if the file is writable if writing zero bytes" do
|
||||
lambda { @readonly_file.write_nonblock("") }.should raise_error
|
||||
lambda {
|
||||
@readonly_file.write_nonblock("")
|
||||
}.should raise_error(IOError)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -73,4 +75,12 @@ describe 'IO#write_nonblock' do
|
|||
end
|
||||
end
|
||||
|
||||
platform_is_not :windows do
|
||||
it 'sets the IO in nonblock mode' do
|
||||
require 'io/nonblock'
|
||||
@write.nonblock?.should == false
|
||||
@write.write_nonblock('a')
|
||||
@write.nonblock?.should == true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -33,13 +33,14 @@ describe "Kernel#open" do
|
|||
@io = open("|date")
|
||||
begin
|
||||
@io.should be_kind_of(IO)
|
||||
@io.read
|
||||
ensure
|
||||
@io.close
|
||||
end
|
||||
end
|
||||
|
||||
it "opens an io when called with a block" do
|
||||
@output = open("|date") { |f| f.gets }
|
||||
@output = open("|date") { |f| f.read }
|
||||
@output.should_not == ''
|
||||
end
|
||||
|
||||
|
@ -61,7 +62,7 @@ describe "Kernel#open" do
|
|||
end
|
||||
|
||||
it "opens an io when called with a block" do
|
||||
@output = open("|date /t") { |f| f.gets }
|
||||
@output = open("|date /t") { |f| f.read }
|
||||
@output.should_not == ''
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/sprintf', __FILE__)
|
||||
require "stringio"
|
||||
|
||||
describe "Kernel#printf" do
|
||||
it "is a private method" do
|
||||
|
@ -31,4 +33,29 @@ describe "Kernel.printf" do
|
|||
object.should_receive(:write).with("string")
|
||||
Kernel.printf(object, "%s", "string")
|
||||
end
|
||||
|
||||
describe "formatting" do
|
||||
context "io is specified" do
|
||||
it_behaves_like :kernel_sprintf, -> (format, *args) {
|
||||
io = StringIO.new
|
||||
printf(io, format, *args)
|
||||
io.string
|
||||
}
|
||||
end
|
||||
|
||||
context "io is not specified" do
|
||||
it_behaves_like :kernel_sprintf, -> (format, *args) {
|
||||
stdout = $stdout
|
||||
|
||||
begin
|
||||
$stdout = io = StringIO.new
|
||||
printf(format, *args)
|
||||
io.string
|
||||
ensure
|
||||
$stdout = stdout
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
871
spec/ruby/core/kernel/shared/sprintf.rb
Normal file
871
spec/ruby/core/kernel/shared/sprintf.rb
Normal file
|
@ -0,0 +1,871 @@
|
|||
describe :kernel_sprintf, shared: true do
|
||||
def format(*args)
|
||||
@method.call(*args)
|
||||
end
|
||||
|
||||
describe "integer formats" do
|
||||
it "converts argument into Integer with to_int" do
|
||||
obj = Object.new
|
||||
def obj.to_i; 10; end
|
||||
def obj.to_int; 10; end
|
||||
|
||||
obj.should_receive(:to_int).and_return(10)
|
||||
format("%b", obj).should == "1010"
|
||||
end
|
||||
|
||||
it "converts argument into Integer with to_i if to_int isn't available" do
|
||||
obj = Object.new
|
||||
def obj.to_i; 10; end
|
||||
|
||||
obj.should_receive(:to_i).and_return(10)
|
||||
format("%b", obj).should == "1010"
|
||||
end
|
||||
|
||||
it "converts String argument with Kernel#Integer" do
|
||||
format("%d", "0b1010").should == "10"
|
||||
format("%d", "112").should == "112"
|
||||
format("%d", "0127").should == "87"
|
||||
format("%d", "0xc4").should == "196"
|
||||
end
|
||||
|
||||
it "raises TypeError exception if cannot convert to Integer" do
|
||||
-> () {
|
||||
format("%b", Object.new)
|
||||
}.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
["b", "B"].each do |f|
|
||||
describe f do
|
||||
it "converts argument as a binary number" do
|
||||
format("%#{f}", 10).should == "1010"
|
||||
end
|
||||
|
||||
it "displays negative number as a two's complement prefixed with '..1'" do
|
||||
format("%#{f}", -10).should == "..1" + "0110"
|
||||
end
|
||||
|
||||
it "collapse negative number representation if it equals 1" do
|
||||
format("%#{f}", -1).should_not == "..11"
|
||||
format("%#{f}", -1).should == "..1"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
["d", "i", "u"].each do |f|
|
||||
describe f do
|
||||
it "converts argument as a decimal number" do
|
||||
format("%#{f}", 112).should == "112"
|
||||
format("%#{f}", -112).should == "-112"
|
||||
end
|
||||
|
||||
it "works well with large numbers" do
|
||||
format("%#{f}", 1234567890987654321).should == "1234567890987654321"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "o" do
|
||||
it "converts argument as an octal number" do
|
||||
format("%o", 87).should == "127"
|
||||
end
|
||||
|
||||
it "displays negative number as a two's complement prefixed with '..7'" do
|
||||
format("%o", -87).should == "..7" + "651"
|
||||
end
|
||||
|
||||
it "collapse negative number representation if it equals 7" do
|
||||
format("%o", -1).should_not == "..77"
|
||||
format("%o", -1).should == "..7"
|
||||
end
|
||||
end
|
||||
|
||||
describe "x" do
|
||||
it "converts argument as a hexadecimal number" do
|
||||
format("%x", 196).should == "c4"
|
||||
end
|
||||
|
||||
it "displays negative number as a two's complement prefixed with '..f'" do
|
||||
format("%x", -196).should == "..f" + "3c"
|
||||
end
|
||||
|
||||
it "collapse negative number representation if it equals f" do
|
||||
format("%x", -1).should_not == "..ff"
|
||||
format("%x", -1).should == "..f"
|
||||
end
|
||||
end
|
||||
|
||||
describe "X" do
|
||||
it "converts argument as a hexadecimal number with uppercase letters" do
|
||||
format("%X", 196).should == "C4"
|
||||
end
|
||||
|
||||
it "displays negative number as a two's complement prefixed with '..f'" do
|
||||
format("%X", -196).should == "..F" + "3C"
|
||||
end
|
||||
|
||||
it "collapse negative number representation if it equals F" do
|
||||
format("%X", -1).should_not == "..FF"
|
||||
format("%X", -1).should == "..F"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "float formats" do
|
||||
it "converts argument into Float" do
|
||||
obj = mock("float")
|
||||
obj.should_receive(:to_f).and_return(9.6)
|
||||
format("%f", obj).should == "9.600000"
|
||||
end
|
||||
|
||||
it "raises TypeError exception if cannot convert to Float" do
|
||||
-> () {
|
||||
format("%f", Object.new)
|
||||
}.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
{"e" => "e", "E" => "E"}.each_pair do |f, exp|
|
||||
describe f do
|
||||
it "converts argument into exponential notation [-]d.dddddde[+-]dd" do
|
||||
format("%#{f}", 109.52).should == "1.095200#{exp}+02"
|
||||
format("%#{f}", -109.52).should == "-1.095200#{exp}+02"
|
||||
format("%#{f}", 0.10952).should == "1.095200#{exp}-01"
|
||||
format("%#{f}", -0.10952).should == "-1.095200#{exp}-01"
|
||||
end
|
||||
|
||||
it "cuts excessive digits and keeps only 6 ones" do
|
||||
format("%#{f}", 1.123456789).should == "1.123457#{exp}+00"
|
||||
end
|
||||
|
||||
it "rounds the last significant digit to the closest one" do
|
||||
format("%#{f}", 1.555555555).should == "1.555556#{exp}+00"
|
||||
format("%#{f}", -1.555555555).should == "-1.555556#{exp}+00"
|
||||
format("%#{f}", 1.444444444).should == "1.444444#{exp}+00"
|
||||
end
|
||||
|
||||
it "displays Float::INFINITY as Inf" do
|
||||
format("%#{f}", Float::INFINITY).should == "Inf"
|
||||
format("%#{f}", -Float::INFINITY).should == "-Inf"
|
||||
end
|
||||
|
||||
it "displays Float::NAN as NaN" do
|
||||
format("%#{f}", Float::NAN).should == "NaN"
|
||||
format("%#{f}", -Float::NAN).should == "NaN"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "f" do
|
||||
it "converts floating point argument as [-]ddd.dddddd" do
|
||||
format("%f", 10.952).should == "10.952000"
|
||||
format("%f", -10.952).should == "-10.952000"
|
||||
end
|
||||
|
||||
it "cuts excessive digits and keeps only 6 ones" do
|
||||
format("%f", 1.123456789).should == "1.123457"
|
||||
end
|
||||
|
||||
it "rounds the last significant digit to the closest one" do
|
||||
format("%f", 1.555555555).should == "1.555556"
|
||||
format("%f", -1.555555555).should == "-1.555556"
|
||||
format("%f", 1.444444444).should == "1.444444"
|
||||
end
|
||||
|
||||
it "displays Float::INFINITY as Inf" do
|
||||
format("%f", Float::INFINITY).should == "Inf"
|
||||
format("%f", -Float::INFINITY).should == "-Inf"
|
||||
end
|
||||
|
||||
it "displays Float::NAN as NaN" do
|
||||
format("%f", Float::NAN).should == "NaN"
|
||||
format("%f", -Float::NAN).should == "NaN"
|
||||
end
|
||||
end
|
||||
|
||||
{"g" => "e", "G" => "E"}.each_pair do |f, exp|
|
||||
describe f do
|
||||
context "the exponent is less than -4" do
|
||||
it "converts a floating point number using exponential form" do
|
||||
format("%#{f}", 0.0000123456).should == "1.23456#{exp}-05"
|
||||
format("%#{f}", -0.0000123456).should == "-1.23456#{exp}-05"
|
||||
|
||||
format("%#{f}", 0.000000000123456).should == "1.23456#{exp}-10"
|
||||
format("%#{f}", -0.000000000123456).should == "-1.23456#{exp}-10"
|
||||
end
|
||||
end
|
||||
|
||||
context "the exponent is greater than or equal to the precision (6 by default)" do
|
||||
it "converts a floating point number using exponential form" do
|
||||
format("%#{f}", 1234567).should == "1.23457#{exp}+06"
|
||||
format("%#{f}", 1234567890123).should == "1.23457#{exp}+12"
|
||||
format("%#{f}", -1234567).should == "-1.23457#{exp}+06"
|
||||
end
|
||||
end
|
||||
|
||||
context "otherwise" do
|
||||
it "converts a floating point number in dd.dddd form" do
|
||||
format("%#{f}", 0.0001).should == "0.0001"
|
||||
format("%#{f}", -0.0001).should == "-0.0001"
|
||||
format("%#{f}", 123456).should == "123456"
|
||||
format("%#{f}", -123456).should == "-123456"
|
||||
end
|
||||
|
||||
it "cuts excessive digits in fractional part and keeps only 4 ones" do
|
||||
format("%#{f}", 12.12341111).should == "12.1234"
|
||||
format("%#{f}", -12.12341111).should == "-12.1234"
|
||||
end
|
||||
|
||||
it "rounds the last significant digit to the closest one in fractional part" do
|
||||
format("%#{f}", 1.555555555).should == "1.55556"
|
||||
format("%#{f}", -1.555555555).should == "-1.55556"
|
||||
format("%#{f}", 1.444444444).should == "1.44444"
|
||||
end
|
||||
|
||||
it "cuts fraction part to have only 6 digits at all" do
|
||||
format("%#{f}", 1.1234567).should == "1.12346"
|
||||
format("%#{f}", 12.1234567).should == "12.1235"
|
||||
format("%#{f}", 123.1234567).should == "123.123"
|
||||
format("%#{f}", 1234.1234567).should == "1234.12"
|
||||
format("%#{f}", 12345.1234567).should == "12345.1"
|
||||
format("%#{f}", 123456.1234567).should == "123456"
|
||||
end
|
||||
end
|
||||
|
||||
it "displays Float::INFINITY as Inf" do
|
||||
format("%#{f}", Float::INFINITY).should == "Inf"
|
||||
format("%#{f}", -Float::INFINITY).should == "-Inf"
|
||||
end
|
||||
|
||||
it "displays Float::NAN as NaN" do
|
||||
format("%#{f}", Float::NAN).should == "NaN"
|
||||
format("%#{f}", -Float::NAN).should == "NaN"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "a" do
|
||||
it "converts floating point argument as [-]0xh.hhhhp[+-]dd" do
|
||||
format("%a", 196).should == "0x1.88p+7"
|
||||
format("%a", -196).should == "-0x1.88p+7"
|
||||
format("%a", 196.1).should == "0x1.8833333333333p+7"
|
||||
format("%a", 0.01).should == "0x1.47ae147ae147bp-7"
|
||||
format("%a", -0.01).should == "-0x1.47ae147ae147bp-7"
|
||||
end
|
||||
|
||||
it "displays Float::INFINITY as Inf" do
|
||||
format("%a", Float::INFINITY).should == "Inf"
|
||||
format("%a", -Float::INFINITY).should == "-Inf"
|
||||
end
|
||||
|
||||
it "displays Float::NAN as NaN" do
|
||||
format("%a", Float::NAN).should == "NaN"
|
||||
format("%a", -Float::NAN).should == "NaN"
|
||||
end
|
||||
end
|
||||
|
||||
describe "A" do
|
||||
it "converts floating point argument as [-]0xh.hhhhp[+-]dd and use uppercase X and P" do
|
||||
format("%A", 196).should == "0X1.88P+7"
|
||||
format("%A", -196).should == "-0X1.88P+7"
|
||||
format("%A", 196.1).should == "0X1.8833333333333P+7"
|
||||
format("%A", 0.01).should == "0X1.47AE147AE147BP-7"
|
||||
format("%A", -0.01).should == "-0X1.47AE147AE147BP-7"
|
||||
end
|
||||
|
||||
it "displays Float::INFINITY as Inf" do
|
||||
format("%A", Float::INFINITY).should == "Inf"
|
||||
format("%A", -Float::INFINITY).should == "-Inf"
|
||||
end
|
||||
|
||||
it "displays Float::NAN as NaN" do
|
||||
format("%A", Float::NAN).should == "NaN"
|
||||
format("%A", -Float::NAN).should == "NaN"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "other formats" do
|
||||
describe "c" do
|
||||
it "displays character if argument is a numeric code of character" do
|
||||
format("%c", 97).should == "a"
|
||||
end
|
||||
|
||||
it "displays character if argument is a single character string" do
|
||||
format("%c", "a").should == "a"
|
||||
end
|
||||
|
||||
it "raises ArgumentError if argument is a string of several characters" do
|
||||
-> () {
|
||||
format("%c", "abc")
|
||||
}.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "raises ArgumentError if argument is an empty string" do
|
||||
-> () {
|
||||
format("%c", "")
|
||||
}.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "supports Unicode characters" do
|
||||
format("%c", 1286).should == "Ԇ"
|
||||
format("%c", "ش").should == "ش"
|
||||
end
|
||||
end
|
||||
|
||||
describe "p" do
|
||||
it "displays argument.inspect value" do
|
||||
obj = mock("object")
|
||||
obj.should_receive(:inspect).and_return("<inspect-result>")
|
||||
format("%p", obj).should == "<inspect-result>"
|
||||
end
|
||||
end
|
||||
|
||||
describe "s" do
|
||||
it "substitute argument passes as a string" do
|
||||
format("%s", "abc").should == "abc"
|
||||
end
|
||||
|
||||
it "converts argument to string with to_s" do
|
||||
obj = mock("string")
|
||||
obj.should_receive(:to_s).and_return("abc")
|
||||
format("%s", obj).should == "abc"
|
||||
end
|
||||
|
||||
it "does not try to convert with to_str" do
|
||||
obj = BasicObject.new
|
||||
def obj.to_str
|
||||
"abc"
|
||||
end
|
||||
|
||||
-> () {
|
||||
format("%s", obj)
|
||||
}.should raise_error(NoMethodError)
|
||||
end
|
||||
end
|
||||
|
||||
describe "%" do
|
||||
ruby_version_is ""..."2.5" do
|
||||
it "alone displays the percent sign" do
|
||||
format("%").should == "%"
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is "2.5" do
|
||||
it "alone raises an ArgumentError" do
|
||||
-> {
|
||||
format("%")
|
||||
}.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
|
||||
it "is escaped by %" do
|
||||
format("%%").should == "%"
|
||||
format("%%d", 10).should == "%d"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "flags" do
|
||||
describe "space" do
|
||||
context "applies to numeric formats bBdiouxXeEfgGaA" do
|
||||
it "leaves a space at the start of non-negative numbers" do
|
||||
format("% b", 10).should == " 1010"
|
||||
format("% B", 10).should == " 1010"
|
||||
format("% d", 112).should == " 112"
|
||||
format("% i", 112).should == " 112"
|
||||
format("% o", 87).should == " 127"
|
||||
format("% u", 112).should == " 112"
|
||||
format("% x", 196).should == " c4"
|
||||
format("% X", 196).should == " C4"
|
||||
|
||||
format("% e", 109.52).should == " 1.095200e+02"
|
||||
format("% E", 109.52).should == " 1.095200E+02"
|
||||
format("% f", 10.952).should == " 10.952000"
|
||||
format("% g", 12.1234).should == " 12.1234"
|
||||
format("% G", 12.1234).should == " 12.1234"
|
||||
format("% a", 196).should == " 0x1.88p+7"
|
||||
format("% A", 196).should == " 0X1.88P+7"
|
||||
end
|
||||
|
||||
it "does not leave a space at the start of negative numbers" do
|
||||
format("% b", -10).should == "-1010"
|
||||
format("% B", -10).should == "-1010"
|
||||
format("% d", -112).should == "-112"
|
||||
format("% i", -112).should == "-112"
|
||||
format("% o", -87).should == "-127"
|
||||
format("% u", -112).should == "-112"
|
||||
format("% x", -196).should == "-c4"
|
||||
format("% X", -196).should == "-C4"
|
||||
|
||||
format("% e", -109.52).should == "-1.095200e+02"
|
||||
format("% E", -109.52).should == "-1.095200E+02"
|
||||
format("% f", -10.952).should == "-10.952000"
|
||||
format("% g", -12.1234).should == "-12.1234"
|
||||
format("% G", -12.1234).should == "-12.1234"
|
||||
format("% a", -196).should == "-0x1.88p+7"
|
||||
format("% A", -196).should == "-0X1.88P+7"
|
||||
end
|
||||
|
||||
it "prevents converting negative argument to two's complement form" do
|
||||
format("% b", -10).should == "-1010"
|
||||
format("% B", -10).should == "-1010"
|
||||
format("% o", -87).should == "-127"
|
||||
format("% x", -196).should == "-c4"
|
||||
format("% X", -196).should == "-C4"
|
||||
end
|
||||
|
||||
it "treats several white spaces as one" do
|
||||
format("% b", 10).should == " 1010"
|
||||
format("% B", 10).should == " 1010"
|
||||
format("% d", 112).should == " 112"
|
||||
format("% i", 112).should == " 112"
|
||||
format("% o", 87).should == " 127"
|
||||
format("% u", 112).should == " 112"
|
||||
format("% x", 196).should == " c4"
|
||||
format("% X", 196).should == " C4"
|
||||
|
||||
format("% e", 109.52).should == " 1.095200e+02"
|
||||
format("% E", 109.52).should == " 1.095200E+02"
|
||||
format("% f", 10.952).should == " 10.952000"
|
||||
format("% g", 12.1234).should == " 12.1234"
|
||||
format("% G", 12.1234).should == " 12.1234"
|
||||
format("% a", 196).should == " 0x1.88p+7"
|
||||
format("% A", 196).should == " 0X1.88P+7"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "(digit)$" do
|
||||
it "specifies the absolute argument number for this field" do
|
||||
format("%2$b", 0, 10).should == "1010"
|
||||
format("%2$B", 0, 10).should == "1010"
|
||||
format("%2$d", 0, 112).should == "112"
|
||||
format("%2$i", 0, 112).should == "112"
|
||||
format("%2$o", 0, 87).should == "127"
|
||||
format("%2$u", 0, 112).should == "112"
|
||||
format("%2$x", 0, 196).should == "c4"
|
||||
format("%2$X", 0, 196).should == "C4"
|
||||
|
||||
format("%2$e", 0, 109.52).should == "1.095200e+02"
|
||||
format("%2$E", 0, 109.52).should == "1.095200E+02"
|
||||
format("%2$f", 0, 10.952).should == "10.952000"
|
||||
format("%2$g", 0, 12.1234).should == "12.1234"
|
||||
format("%2$G", 0, 12.1234).should == "12.1234"
|
||||
format("%2$a", 0, 196).should == "0x1.88p+7"
|
||||
format("%2$A", 0, 196).should == "0X1.88P+7"
|
||||
|
||||
format("%2$c", 1, 97).should == "a"
|
||||
format("%2$p", "a", []).should == "[]"
|
||||
format("%2$s", "-", "abc").should == "abc"
|
||||
end
|
||||
|
||||
it "raises exception if argument number is bigger than actual arguments list" do
|
||||
-> () {
|
||||
format("%4$d", 1, 2, 3)
|
||||
}.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "ignores '-' sign" do
|
||||
format("%2$d", 1, 2, 3).should == "2"
|
||||
format("%-2$d", 1, 2, 3).should == "2"
|
||||
end
|
||||
|
||||
it "raises ArgumentError exception when absolute and relative argument numbers are mixed" do
|
||||
-> () {
|
||||
format("%1$d %d", 1, 2)
|
||||
}.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#" do
|
||||
context "applies to format o" do
|
||||
it "increases the precision until the first digit will be `0' if it is not formatted as complements" do
|
||||
format("%#o", 87).should == "0127"
|
||||
end
|
||||
|
||||
it "does nothing for negative argument" do
|
||||
format("%#o", -87).should == "..7651"
|
||||
end
|
||||
end
|
||||
|
||||
context "applies to formats bBxX" do
|
||||
it "prefixes the result with 0x, 0X, 0b and 0B respectively for non-zero argument" do
|
||||
format("%#b", 10).should == "0b1010"
|
||||
format("%#b", -10).should == "0b..10110"
|
||||
format("%#B", 10).should == "0B1010"
|
||||
format("%#B", -10).should == "0B..10110"
|
||||
|
||||
format("%#x", 196).should == "0xc4"
|
||||
format("%#x", -196).should == "0x..f3c"
|
||||
format("%#X", 196).should == "0XC4"
|
||||
format("%#X", -196).should == "0X..F3C"
|
||||
end
|
||||
|
||||
it "does nothing for zero argument" do
|
||||
format("%#b", 0).should == "0"
|
||||
format("%#B", 0).should == "0"
|
||||
|
||||
format("%#o", 0).should == "0"
|
||||
|
||||
format("%#x", 0).should == "0"
|
||||
format("%#X", 0).should == "0"
|
||||
end
|
||||
end
|
||||
|
||||
context "applies to formats aAeEfgG" do
|
||||
it "forces a decimal point to be added, even if no digits follow" do
|
||||
format("%#.0a", 16.25).should == "0x1.p+4"
|
||||
format("%#.0A", 16.25).should == "0X1.P+4"
|
||||
|
||||
format("%#.0e", 100).should == "1.e+02"
|
||||
format("%#.0E", 100).should == "1.E+02"
|
||||
|
||||
format("%#.0f", 123.4).should == "123."
|
||||
|
||||
format("%#g", 123456).should == "123456."
|
||||
format("%#G", 123456).should == "123456."
|
||||
end
|
||||
|
||||
it "changes format from dd.dddd to exponential form for gG" do
|
||||
format("%#.0g", 123.4).should_not == "123."
|
||||
format("%#.0g", 123.4).should == "1.e+02"
|
||||
end
|
||||
end
|
||||
|
||||
context "applies to gG" do
|
||||
it "does not remove trailing zeros" do
|
||||
format("%#g", 123.4).should == "123.400"
|
||||
format("%#g", 123.4).should == "123.400"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "+" do
|
||||
context "applies to numeric formats bBdiouxXaAeEfgG" do
|
||||
it "adds a leading plus sign to non-negative numbers" do
|
||||
format("%+b", 10).should == "+1010"
|
||||
format("%+B", 10).should == "+1010"
|
||||
format("%+d", 112).should == "+112"
|
||||
format("%+i", 112).should == "+112"
|
||||
format("%+o", 87).should == "+127"
|
||||
format("%+u", 112).should == "+112"
|
||||
format("%+x", 196).should == "+c4"
|
||||
format("%+X", 196).should == "+C4"
|
||||
|
||||
format("%+e", 109.52).should == "+1.095200e+02"
|
||||
format("%+E", 109.52).should == "+1.095200E+02"
|
||||
format("%+f", 10.952).should == "+10.952000"
|
||||
format("%+g", 12.1234).should == "+12.1234"
|
||||
format("%+G", 12.1234).should == "+12.1234"
|
||||
format("%+a", 196).should == "+0x1.88p+7"
|
||||
format("%+A", 196).should == "+0X1.88P+7"
|
||||
end
|
||||
|
||||
it "does not use two's complement form for negative numbers for formats bBoxX" do
|
||||
format("%+b", -10).should == "-1010"
|
||||
format("%+B", -10).should == "-1010"
|
||||
format("%+o", -87).should == "-127"
|
||||
format("%+x", -196).should == "-c4"
|
||||
format("%+X", -196).should == "-C4"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "-" do
|
||||
it "left-justifies the result of conversion if width is specified" do
|
||||
format("%-10b", 10).should == "1010 "
|
||||
format("%-10B", 10).should == "1010 "
|
||||
format("%-10d", 112).should == "112 "
|
||||
format("%-10i", 112).should == "112 "
|
||||
format("%-10o", 87).should == "127 "
|
||||
format("%-10u", 112).should == "112 "
|
||||
format("%-10x", 196).should == "c4 "
|
||||
format("%-10X", 196).should == "C4 "
|
||||
|
||||
format("%-20e", 109.52).should == "1.095200e+02 "
|
||||
format("%-20E", 109.52).should == "1.095200E+02 "
|
||||
format("%-20f", 10.952).should == "10.952000 "
|
||||
format("%-20g", 12.1234).should == "12.1234 "
|
||||
format("%-20G", 12.1234).should == "12.1234 "
|
||||
format("%-20a", 196).should == "0x1.88p+7 "
|
||||
format("%-20A", 196).should == "0X1.88P+7 "
|
||||
|
||||
format("%-10c", 97).should == "a "
|
||||
format("%-10p", []).should == "[] "
|
||||
format("%-10s", "abc").should == "abc "
|
||||
end
|
||||
end
|
||||
|
||||
describe "0 (zero)" do
|
||||
context "applies to numeric formats bBdiouxXaAeEfgG and width is specified" do
|
||||
it "pads with zeros, not spaces" do
|
||||
format("%010b", 10).should == "0000001010"
|
||||
format("%010B", 10).should == "0000001010"
|
||||
format("%010d", 112).should == "0000000112"
|
||||
format("%010i", 112).should == "0000000112"
|
||||
format("%010o", 87).should == "0000000127"
|
||||
format("%010u", 112).should == "0000000112"
|
||||
format("%010x", 196).should == "00000000c4"
|
||||
format("%010X", 196).should == "00000000C4"
|
||||
|
||||
format("%020e", 109.52).should == "000000001.095200e+02"
|
||||
format("%020E", 109.52).should == "000000001.095200E+02"
|
||||
format("%020f", 10.952).should == "0000000000010.952000"
|
||||
format("%020g", 12.1234).should == "000000000000012.1234"
|
||||
format("%020G", 12.1234).should == "000000000000012.1234"
|
||||
format("%020a", 196).should == "0x000000000001.88p+7"
|
||||
format("%020A", 196).should == "0X000000000001.88P+7"
|
||||
end
|
||||
|
||||
it "uses radix-1 when displays negative argument as a two's complement" do
|
||||
format("%010b", -10).should == "..11110110"
|
||||
format("%010B", -10).should == "..11110110"
|
||||
format("%010o", -87).should == "..77777651"
|
||||
format("%010x", -196).should == "..ffffff3c"
|
||||
format("%010X", -196).should == "..FFFFFF3C"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "*" do
|
||||
it "uses the previous argument as the field width" do
|
||||
format("%*b", 10, 10).should == " 1010"
|
||||
format("%*B", 10, 10).should == " 1010"
|
||||
format("%*d", 10, 112).should == " 112"
|
||||
format("%*i", 10, 112).should == " 112"
|
||||
format("%*o", 10, 87).should == " 127"
|
||||
format("%*u", 10, 112).should == " 112"
|
||||
format("%*x", 10, 196).should == " c4"
|
||||
format("%*X", 10, 196).should == " C4"
|
||||
|
||||
format("%*e", 20, 109.52).should == " 1.095200e+02"
|
||||
format("%*E", 20, 109.52).should == " 1.095200E+02"
|
||||
format("%*f", 20, 10.952).should == " 10.952000"
|
||||
format("%*g", 20, 12.1234).should == " 12.1234"
|
||||
format("%*G", 20, 12.1234).should == " 12.1234"
|
||||
format("%*a", 20, 196).should == " 0x1.88p+7"
|
||||
format("%*A", 20, 196).should == " 0X1.88P+7"
|
||||
|
||||
format("%*c", 10, 97).should == " a"
|
||||
format("%*p", 10, []).should == " []"
|
||||
format("%*s", 10, "abc").should == " abc"
|
||||
end
|
||||
|
||||
it "left-justifies the result if width is negative" do
|
||||
format("%*b", -10, 10).should == "1010 "
|
||||
format("%*B", -10, 10).should == "1010 "
|
||||
format("%*d", -10, 112).should == "112 "
|
||||
format("%*i", -10, 112).should == "112 "
|
||||
format("%*o", -10, 87).should == "127 "
|
||||
format("%*u", -10, 112).should == "112 "
|
||||
format("%*x", -10, 196).should == "c4 "
|
||||
format("%*X", -10, 196).should == "C4 "
|
||||
|
||||
format("%*e", -20, 109.52).should == "1.095200e+02 "
|
||||
format("%*E", -20, 109.52).should == "1.095200E+02 "
|
||||
format("%*f", -20, 10.952).should == "10.952000 "
|
||||
format("%*g", -20, 12.1234).should == "12.1234 "
|
||||
format("%*G", -20, 12.1234).should == "12.1234 "
|
||||
format("%*a", -20, 196).should == "0x1.88p+7 "
|
||||
format("%*A", -20, 196).should == "0X1.88P+7 "
|
||||
|
||||
format("%*c", -10, 97).should == "a "
|
||||
format("%*p", -10, []).should == "[] "
|
||||
format("%*s", -10, "abc").should == "abc "
|
||||
end
|
||||
|
||||
it "uses the specified argument as the width if * is followed by a number and $" do
|
||||
format("%1$*2$b", 10, 10).should == " 1010"
|
||||
format("%1$*2$B", 10, 10).should == " 1010"
|
||||
format("%1$*2$d", 112, 10).should == " 112"
|
||||
format("%1$*2$i", 112, 10).should == " 112"
|
||||
format("%1$*2$o", 87, 10).should == " 127"
|
||||
format("%1$*2$u", 112, 10).should == " 112"
|
||||
format("%1$*2$x", 196, 10).should == " c4"
|
||||
format("%1$*2$X", 196, 10).should == " C4"
|
||||
|
||||
format("%1$*2$e", 109.52, 20).should == " 1.095200e+02"
|
||||
format("%1$*2$E", 109.52, 20).should == " 1.095200E+02"
|
||||
format("%1$*2$f", 10.952, 20).should == " 10.952000"
|
||||
format("%1$*2$g", 12.1234, 20).should == " 12.1234"
|
||||
format("%1$*2$G", 12.1234, 20).should == " 12.1234"
|
||||
format("%1$*2$a", 196, 20).should == " 0x1.88p+7"
|
||||
format("%1$*2$A", 196, 20).should == " 0X1.88P+7"
|
||||
|
||||
format("%1$*2$c", 97, 10).should == " a"
|
||||
format("%1$*2$p", [], 10).should == " []"
|
||||
format("%1$*2$s", "abc", 10).should == " abc"
|
||||
end
|
||||
|
||||
it "left-justifies the result if specified with $ argument is negative" do
|
||||
format("%1$*2$b", 10, -10).should == "1010 "
|
||||
format("%1$*2$B", 10, -10).should == "1010 "
|
||||
format("%1$*2$d", 112, -10).should == "112 "
|
||||
format("%1$*2$i", 112, -10).should == "112 "
|
||||
format("%1$*2$o", 87, -10).should == "127 "
|
||||
format("%1$*2$u", 112, -10).should == "112 "
|
||||
format("%1$*2$x", 196, -10).should == "c4 "
|
||||
format("%1$*2$X", 196, -10).should == "C4 "
|
||||
|
||||
format("%1$*2$e", 109.52, -20).should == "1.095200e+02 "
|
||||
format("%1$*2$E", 109.52, -20).should == "1.095200E+02 "
|
||||
format("%1$*2$f", 10.952, -20).should == "10.952000 "
|
||||
format("%1$*2$g", 12.1234, -20).should == "12.1234 "
|
||||
format("%1$*2$G", 12.1234, -20).should == "12.1234 "
|
||||
format("%1$*2$a", 196, -20).should == "0x1.88p+7 "
|
||||
format("%1$*2$A", 196, -20).should == "0X1.88P+7 "
|
||||
|
||||
format("%1$*2$c", 97, -10).should == "a "
|
||||
format("%1$*2$p", [], -10).should == "[] "
|
||||
format("%1$*2$s", "abc", -10).should == "abc "
|
||||
end
|
||||
|
||||
it "raises ArgumentError when is mixed with width" do
|
||||
-> () {
|
||||
format("%*10d", 10, 112)
|
||||
}.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "width" do
|
||||
it "specifies the minimum number of characters that will be written to the result" do
|
||||
format("%10b", 10).should == " 1010"
|
||||
format("%10B", 10).should == " 1010"
|
||||
format("%10d", 112).should == " 112"
|
||||
format("%10i", 112).should == " 112"
|
||||
format("%10o", 87).should == " 127"
|
||||
format("%10u", 112).should == " 112"
|
||||
format("%10x", 196).should == " c4"
|
||||
format("%10X", 196).should == " C4"
|
||||
|
||||
format("%20e", 109.52).should == " 1.095200e+02"
|
||||
format("%20E", 109.52).should == " 1.095200E+02"
|
||||
format("%20f", 10.952).should == " 10.952000"
|
||||
format("%20g", 12.1234).should == " 12.1234"
|
||||
format("%20G", 12.1234).should == " 12.1234"
|
||||
format("%20a", 196).should == " 0x1.88p+7"
|
||||
format("%20A", 196).should == " 0X1.88P+7"
|
||||
|
||||
format("%10c", 97).should == " a"
|
||||
format("%10p", []).should == " []"
|
||||
format("%10s", "abc").should == " abc"
|
||||
end
|
||||
|
||||
it "is ignored if argument's actual length is greater" do
|
||||
format("%5d", 1234567890).should == "1234567890"
|
||||
end
|
||||
end
|
||||
|
||||
describe "precision" do
|
||||
context "integer types" do
|
||||
it "controls the number of decimal places displayed" do
|
||||
format("%.6b", 10).should == "001010"
|
||||
format("%.6B", 10).should == "001010"
|
||||
format("%.5d", 112).should == "00112"
|
||||
format("%.5i", 112).should == "00112"
|
||||
format("%.5o", 87).should == "00127"
|
||||
format("%.5u", 112).should == "00112"
|
||||
|
||||
format("%.5x", 196).should == "000c4"
|
||||
format("%.5X", 196).should == "000C4"
|
||||
end
|
||||
end
|
||||
|
||||
context "float types" do
|
||||
it "controls the number of decimal places displayed in fraction part" do
|
||||
format("%.10e", 109.52).should == "1.0952000000e+02"
|
||||
format("%.10E", 109.52).should == "1.0952000000E+02"
|
||||
format("%.10f", 10.952).should == "10.9520000000"
|
||||
format("%.10a", 196).should == "0x1.8800000000p+7"
|
||||
format("%.10A", 196).should == "0X1.8800000000P+7"
|
||||
end
|
||||
|
||||
it "does not affect G format" do
|
||||
format("%.10g", 12.1234).should == "12.1234"
|
||||
format("%.10g", 123456789).should == "123456789"
|
||||
end
|
||||
end
|
||||
|
||||
context "string formats" do
|
||||
it "determines the maximum number of characters to be copied from the string" do
|
||||
format("%.1p", [1]).should == "["
|
||||
format("%.2p", [1]).should == "[1"
|
||||
format("%.10p", [1]).should == "[1]"
|
||||
format("%.0p", [1]).should == ""
|
||||
|
||||
format("%.1s", "abc").should == "a"
|
||||
format("%.2s", "abc").should == "ab"
|
||||
format("%.10s", "abc").should == "abc"
|
||||
format("%.0s", "abc").should == ""
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "reference by name" do
|
||||
describe "%<name>s style" do
|
||||
it "uses value passed in a hash argument" do
|
||||
format("%<foo>d", foo: 123).should == "123"
|
||||
end
|
||||
|
||||
it "supports flags, width, precision and type" do
|
||||
format("%+20.10<foo>f", foo: 10.952).should == " +10.9520000000"
|
||||
end
|
||||
|
||||
it "allows to place name in any position" do
|
||||
format("%+15.5<foo>f", foo: 10.952).should == " +10.95200"
|
||||
format("%+15<foo>.5f", foo: 10.952).should == " +10.95200"
|
||||
format("%+<foo>15.5f", foo: 10.952).should == " +10.95200"
|
||||
format("%<foo>+15.5f", foo: 10.952).should == " +10.95200"
|
||||
end
|
||||
|
||||
it "cannot be mixed with unnamed style" do
|
||||
-> () {
|
||||
format("%d %<foo>d", 1, foo: "123")
|
||||
}.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "raises KeyError when there is no matching key" do
|
||||
-> () {
|
||||
format("%<foo>s", {})
|
||||
}.should raise_error(KeyError)
|
||||
end
|
||||
end
|
||||
|
||||
describe "%{name} style" do
|
||||
it "uses value passed in a hash argument" do
|
||||
format("%{foo}", foo: 123).should == "123"
|
||||
end
|
||||
|
||||
it "does not support type style" do
|
||||
format("%{foo}d", foo: 123).should == "123d"
|
||||
end
|
||||
|
||||
it "supports flags, width and precision" do
|
||||
format("%-20.5{foo}", foo: "123456789").should == "12345 "
|
||||
end
|
||||
|
||||
it "cannot be mixed with unnamed style" do
|
||||
-> () {
|
||||
format("%d %{foo}", 1, foo: "123")
|
||||
}.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "raises KeyError when there is no matching key" do
|
||||
-> () {
|
||||
format("%{foo}", {})
|
||||
}.should raise_error(KeyError)
|
||||
end
|
||||
|
||||
it "converts value to String with to_s" do
|
||||
obj = Object.new
|
||||
def obj.to_s; end
|
||||
def obj.to_str; end
|
||||
|
||||
obj.should_receive(:to_s).and_return("42")
|
||||
obj.should_not_receive(:to_str)
|
||||
|
||||
format("%{foo}", foo: obj).should == "42"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
28
spec/ruby/core/kernel/shared/sprintf_encoding.rb
Normal file
28
spec/ruby/core/kernel/shared/sprintf_encoding.rb
Normal file
|
@ -0,0 +1,28 @@
|
|||
describe :kernel_sprintf_encoding, shared: true do
|
||||
def format(*args)
|
||||
@method.call(*args)
|
||||
end
|
||||
|
||||
it "returns a String in the same encoding as the format String if compatible" do
|
||||
string = "%s".force_encoding(Encoding::KOI8_U)
|
||||
result = format(string, "dogs")
|
||||
result.encoding.should equal(Encoding::KOI8_U)
|
||||
end
|
||||
|
||||
it "returns a String in the argument's encoding if format encoding is more restrictive" do
|
||||
string = "foo %s".force_encoding(Encoding::US_ASCII)
|
||||
argument = "b\303\274r".force_encoding(Encoding::UTF_8)
|
||||
|
||||
result = format(string, argument)
|
||||
result.encoding.should equal(Encoding::UTF_8)
|
||||
end
|
||||
|
||||
it "raises Encoding::CompatibilityError if both encodings are ASCII compatible and there ano not ASCII characters" do
|
||||
string = "Ä %s".encode('windows-1252')
|
||||
argument = "Ђ".encode('windows-1251')
|
||||
|
||||
-> () {
|
||||
format(string, argument)
|
||||
}.should raise_error(Encoding::CompatibilityError)
|
||||
end
|
||||
end
|
|
@ -1,310 +1,24 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../shared/sprintf', __FILE__)
|
||||
require File.expand_path('../shared/sprintf_encoding', __FILE__)
|
||||
|
||||
describe "Kernel#sprintf" do
|
||||
it "is a private method" do
|
||||
Kernel.should have_private_instance_method(:sprintf)
|
||||
end
|
||||
it_behaves_like :kernel_sprintf, -> (format, *args) {
|
||||
sprintf(format, *args)
|
||||
}
|
||||
|
||||
it "treats nil arguments as zero-width strings in %s slots" do
|
||||
sprintf("%s%d%s%s", nil, 4, 'a', 'b').should == '4ab'
|
||||
end
|
||||
|
||||
it "passes some tests for positive %x" do
|
||||
sprintf("%x", 123).should == "7b"
|
||||
sprintf("%0x", 123).should == "7b"
|
||||
sprintf("% x", 123).should == " 7b"
|
||||
sprintf("%+x", 123).should == "+7b"
|
||||
sprintf("%+0x", 123).should == "+7b"
|
||||
sprintf("%+ x", 123).should == "+7b"
|
||||
sprintf("% 0x", 123).should == " 7b"
|
||||
|
||||
sprintf("%#x", 123).should == "0x7b"
|
||||
sprintf("%#0x", 123).should == "0x7b"
|
||||
sprintf("%# x", 123).should == " 0x7b"
|
||||
sprintf("%#+x", 123).should == "+0x7b"
|
||||
sprintf("%#+0x", 123).should == "+0x7b"
|
||||
sprintf("%#+ x", 123).should == "+0x7b"
|
||||
sprintf("%# 0x", 123).should == " 0x7b"
|
||||
|
||||
sprintf("%8x", 123).should == " 7b"
|
||||
sprintf("%08x", 123).should == "0000007b"
|
||||
sprintf("% 8x", 123).should == " 7b"
|
||||
sprintf("%+8x", 123).should == " +7b"
|
||||
sprintf("%+08x", 123).should == "+000007b"
|
||||
sprintf("%+ 8x", 123).should == " +7b"
|
||||
sprintf("% 08x", 123).should == " 000007b"
|
||||
|
||||
sprintf("%#8x", 123).should == " 0x7b"
|
||||
sprintf("%#08x", 123).should == "0x00007b"
|
||||
sprintf("%# 8x", 123).should == " 0x7b"
|
||||
sprintf("%#+8x", 123).should == " +0x7b"
|
||||
sprintf("%#+08x", 123).should == "+0x0007b"
|
||||
sprintf("%#+ 8x", 123).should == " +0x7b"
|
||||
sprintf("%# 08x", 123).should == " 0x0007b"
|
||||
|
||||
sprintf("%8.10x", 123).should == "000000007b"
|
||||
sprintf("%08.10x", 123).should == "000000007b"
|
||||
sprintf("% 8.10x", 123).should == " 000000007b"
|
||||
sprintf("%+8.10x", 123).should == "+000000007b"
|
||||
sprintf("%+08.10x", 123).should == "+000000007b"
|
||||
sprintf("%+ 8.10x", 123).should == "+000000007b"
|
||||
sprintf("% 08.10x", 123).should == " 000000007b"
|
||||
|
||||
sprintf("%10.8x", 123).should == " 0000007b"
|
||||
sprintf("%010.8x", 123).should == " 0000007b"
|
||||
sprintf("% 10.8x", 123).should == " 0000007b"
|
||||
sprintf("%+10.8x", 123).should == " +0000007b"
|
||||
sprintf("%+010.8x", 123).should == " +0000007b"
|
||||
sprintf("%+ 10.8x", 123).should == " +0000007b"
|
||||
sprintf("% 010.8x", 123).should == " 0000007b"
|
||||
end
|
||||
|
||||
describe "with format string that contains %{} sections" do
|
||||
it "substitutes values for named references" do
|
||||
sprintf("%{foo}f", {foo: 1}).should == "1f"
|
||||
end
|
||||
|
||||
it "raises KeyError when no matching key is in second argument" do
|
||||
lambda { sprintf("%{foo}f", {}) }.should raise_error(KeyError)
|
||||
end
|
||||
end
|
||||
|
||||
describe "with format string that contains %<> sections" do
|
||||
it "formats values for named references" do
|
||||
sprintf("%<foo>f", {foo: 1}).should == "1.000000"
|
||||
end
|
||||
|
||||
it "raises KeyError when no matching key is in second argument" do
|
||||
lambda { sprintf("%<foo>f", {}) }.should raise_error(KeyError)
|
||||
end
|
||||
|
||||
it "raises ArgumentError if missing second named argument" do
|
||||
lambda { sprintf("%<key><foo>d", {key: 1}) }.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
|
||||
describe "with negative values" do
|
||||
describe "with format %x" do
|
||||
it "precedes the number with '..'" do
|
||||
sprintf("%0x", -123).should == "..f85"
|
||||
sprintf("%#0x", -123).should == "0x..f85"
|
||||
sprintf("%08x", -123).should == "..ffff85"
|
||||
sprintf("%#08x", -123).should == "0x..ff85"
|
||||
sprintf("%8.10x", -123).should == "..ffffff85"
|
||||
sprintf("%08.10x", -123).should == "..ffffff85"
|
||||
sprintf("%10.8x", -123).should == " ..ffff85"
|
||||
sprintf("%010.8x", -123).should == " ..ffff85"
|
||||
end
|
||||
end
|
||||
|
||||
describe "with format %b or %B" do
|
||||
it "precedes the number with '..'" do
|
||||
sprintf("%.7b", -5).should == "..11011"
|
||||
sprintf("%.7B", -5).should == "..11011"
|
||||
sprintf("%0b", -5).should == "..1011"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "passes some tests for negative %x" do
|
||||
sprintf("%x", -123).should == "..f85"
|
||||
sprintf("% x", -123).should == "-7b"
|
||||
sprintf("%+x", -123).should == "-7b"
|
||||
sprintf("%+0x", -123).should == "-7b"
|
||||
sprintf("%+ x", -123).should == "-7b"
|
||||
sprintf("% 0x", -123).should == "-7b"
|
||||
|
||||
sprintf("%#x", -123).should == "0x..f85"
|
||||
sprintf("%# x", -123).should == "-0x7b"
|
||||
sprintf("%#+x", -123).should == "-0x7b"
|
||||
sprintf("%#+0x", -123).should == "-0x7b"
|
||||
sprintf("%#+ x", -123).should == "-0x7b"
|
||||
sprintf("%# 0x", -123).should == "-0x7b"
|
||||
|
||||
sprintf("%8x", -123).should == " ..f85"
|
||||
sprintf("% 8x", -123).should == " -7b"
|
||||
sprintf("%+8x", -123).should == " -7b"
|
||||
sprintf("%+08x", -123).should == "-000007b"
|
||||
sprintf("%+ 8x", -123).should == " -7b"
|
||||
sprintf("% 08x", -123).should == "-000007b"
|
||||
|
||||
sprintf("%#8x", -123).should == " 0x..f85"
|
||||
sprintf("%# 8x", -123).should == " -0x7b"
|
||||
sprintf("%#+8x", -123).should == " -0x7b"
|
||||
sprintf("%#+08x", -123).should == "-0x0007b"
|
||||
sprintf("%#+ 8x", -123).should == " -0x7b"
|
||||
sprintf("%# 08x", -123).should == "-0x0007b"
|
||||
|
||||
sprintf("% 8.10x", -123).should == "-000000007b"
|
||||
sprintf("%+8.10x", -123).should == "-000000007b"
|
||||
sprintf("%+08.10x", -123).should == "-000000007b"
|
||||
sprintf("%+ 8.10x", -123).should == "-000000007b"
|
||||
sprintf("% 08.10x", -123).should == "-000000007b"
|
||||
|
||||
sprintf("% 10.8x", -123).should == " -0000007b"
|
||||
sprintf("%+10.8x", -123).should == " -0000007b"
|
||||
sprintf("%+010.8x", -123).should == " -0000007b"
|
||||
sprintf("%+ 10.8x", -123).should == " -0000007b"
|
||||
sprintf("% 010.8x", -123).should == " -0000007b"
|
||||
end
|
||||
|
||||
it "passes some tests for negative %u" do
|
||||
sprintf("%u", -123).should == "-123"
|
||||
sprintf("%0u", -123).should == "-123"
|
||||
sprintf("%#u", -123).should == "-123"
|
||||
sprintf("%#0u", -123).should == "-123"
|
||||
sprintf("%8u", -123).should == " -123"
|
||||
sprintf("%08u", -123).should == "-0000123"
|
||||
sprintf("%#8u", -123).should == " -123"
|
||||
sprintf("%#08u", -123).should == "-0000123"
|
||||
|
||||
sprintf("%30u", -123).should == " -123"
|
||||
sprintf("%030u", -123).should == "-00000000000000000000000000123"
|
||||
|
||||
sprintf("%#30u", -123).should == " -123"
|
||||
sprintf("%#030u", -123).should == "-00000000000000000000000000123"
|
||||
|
||||
sprintf("%24.30u", -123).should == "-000000000000000000000000000123"
|
||||
sprintf("%024.30u", -123).should == "-000000000000000000000000000123"
|
||||
|
||||
sprintf("%#24.30u", -123).should == "-000000000000000000000000000123"
|
||||
sprintf("%#024.30u", -123).should == "-000000000000000000000000000123"
|
||||
|
||||
|
||||
sprintf("%30.24u", -123).should == " -000000000000000000000123"
|
||||
sprintf("%030.24u", -123).should == " -000000000000000000000123"
|
||||
|
||||
sprintf("%#30.24u", -123).should == " -000000000000000000000123"
|
||||
sprintf("%#030.24u", -123).should == " -000000000000000000000123"
|
||||
end
|
||||
|
||||
it "passes some tests for positive %u" do
|
||||
sprintf("%30u", 123).should == " 123"
|
||||
sprintf("%030u", 123).should == "000000000000000000000000000123"
|
||||
|
||||
sprintf("%#30u", 123).should == " 123"
|
||||
sprintf("%#030u", 123).should == "000000000000000000000000000123"
|
||||
|
||||
sprintf("%24.30u", 123).should == "000000000000000000000000000123"
|
||||
sprintf("%024.30u", 123).should == "000000000000000000000000000123"
|
||||
|
||||
sprintf("%#24.30u", 123).should == "000000000000000000000000000123"
|
||||
sprintf("%#024.30u", 123).should == "000000000000000000000000000123"
|
||||
|
||||
sprintf("%30.24u", 123).should == " 000000000000000000000123"
|
||||
sprintf("%030.24u", 123).should == " 000000000000000000000123"
|
||||
|
||||
sprintf("%#30.24u", 123).should == " 000000000000000000000123"
|
||||
sprintf("%#030.24u", 123).should == " 000000000000000000000123"
|
||||
end
|
||||
|
||||
it "passes some tests for positive %d" do
|
||||
sprintf("%30d", 123).should == " 123"
|
||||
sprintf("%030d", 123).should == "000000000000000000000000000123"
|
||||
|
||||
sprintf("%#30d", 123).should == " 123"
|
||||
sprintf("%#030d", 123).should == "000000000000000000000000000123"
|
||||
|
||||
sprintf("%24.30d", 123).should == "000000000000000000000000000123"
|
||||
sprintf("%024.30d", 123).should == "000000000000000000000000000123"
|
||||
|
||||
sprintf("%#24.30d", 123).should == "000000000000000000000000000123"
|
||||
sprintf("%#024.30d", 123).should == "000000000000000000000000000123"
|
||||
|
||||
sprintf("%30.24d", 123).should == " 000000000000000000000123"
|
||||
sprintf("%030.24d", 123).should == " 000000000000000000000123"
|
||||
|
||||
sprintf("%#30.24d", 123).should == " 000000000000000000000123"
|
||||
sprintf("%#030.24d", 123).should == " 000000000000000000000123"
|
||||
end
|
||||
|
||||
it "passes some tests for positive %f" do
|
||||
sprintf("%30f", 123.1).should == " 123.100000"
|
||||
sprintf("%030f", 123.1).should == "00000000000000000000123.100000"
|
||||
|
||||
sprintf("%#30f", 123.1).should == " 123.100000"
|
||||
sprintf("%#030f", 123.1).should == "00000000000000000000123.100000"
|
||||
|
||||
sprintf("%10.4f", 123.1).should == " 123.1000"
|
||||
sprintf("%010.4f", 123.1).should == "00123.1000"
|
||||
|
||||
sprintf("%10.0f", 123.1).should == " 123"
|
||||
sprintf("%010.0f", 123.1).should == "0000000123"
|
||||
end
|
||||
|
||||
it "passes some tests for negative %f" do
|
||||
sprintf("%30f", -123.5).should == " -123.500000"
|
||||
sprintf("%030f", -123.5).should == "-0000000000000000000123.500000"
|
||||
|
||||
sprintf("%#30f", -123.5).should == " -123.500000"
|
||||
sprintf("%#030f", -123.5).should == "-0000000000000000000123.500000"
|
||||
|
||||
sprintf("%10.4f", -123.5).should == " -123.5000"
|
||||
sprintf("%010.4f", -123.5).should == "-0123.5000"
|
||||
|
||||
sprintf("%10.0f", -123.5).should == " -124"
|
||||
sprintf("%010.0f", -123.5).should == "-000000124"
|
||||
end
|
||||
|
||||
it "passes some tests for infinite and nan" do
|
||||
sprintf("%f", Float::INFINITY).should == "Inf"
|
||||
sprintf("%f", -Float::INFINITY).should == "-Inf"
|
||||
sprintf("%f", Float::NAN).should == "NaN"
|
||||
|
||||
sprintf("%10f", Float::INFINITY).should == " Inf"
|
||||
sprintf("%10f", -Float::INFINITY).should == " -Inf"
|
||||
sprintf("%10f", Float::NAN).should == " NaN"
|
||||
end
|
||||
|
||||
it "passes kstephens's tests" do
|
||||
sprintf("%*1$.*2$3$d", 10, 5, 1).should == " 00001"
|
||||
sprintf("%b", 0).should == "0"
|
||||
sprintf("%B", 0).should == "0"
|
||||
sprintf("%b", -5).should == "..1011"
|
||||
sprintf("%B", -5).should == "..1011"
|
||||
sprintf("%+b", -5).should == "-101"
|
||||
sprintf("%+b", 10).should == "+1010"
|
||||
sprintf("%+b", 0).should == "+0"
|
||||
sprintf("%+o", -5).should == "-5"
|
||||
sprintf("%+o", 10).should == "+12"
|
||||
sprintf("%+o", 0).should == "+0"
|
||||
sprintf("%+d", -5).should == "-5"
|
||||
sprintf("%+d", 10).should == "+10"
|
||||
sprintf("%+d", 0).should == "+0"
|
||||
sprintf("%+x", -15).should == "-f"
|
||||
sprintf("%+x", 100).should == "+64"
|
||||
sprintf("%+x", 0).should == "+0"
|
||||
sprintf("%+X", -15).should == "-F"
|
||||
sprintf("%+X", 100).should == "+64"
|
||||
sprintf("%+X", 0).should == "+0"
|
||||
sprintf("=%02X", 1).should == "=01"
|
||||
sprintf("%+03d", 0).should == "+00"
|
||||
sprintf("%+03d", 5).should == "+05"
|
||||
sprintf("%+03d", -5).should == "-05"
|
||||
sprintf("%+03d", 12).should == "+12"
|
||||
sprintf("%+03d", -12).should == "-12"
|
||||
sprintf("%+03d", 123).should == "+123"
|
||||
sprintf("%+03d", -123).should == "-123"
|
||||
end
|
||||
|
||||
with_feature :encoding do
|
||||
it "returns a String in the same encoding as the format String if compatible" do
|
||||
format = "%.2f %4s".force_encoding(Encoding::KOI8_U)
|
||||
result = sprintf(format, 1.2, "dogs")
|
||||
result.encoding.should equal(Encoding::KOI8_U)
|
||||
end
|
||||
|
||||
it "returns a String in the argument encoding if format encoding is more restrictive" do
|
||||
format = "foo %s".force_encoding(Encoding::US_ASCII)
|
||||
arg = "b\303\274r".force_encoding(Encoding::UTF_8)
|
||||
|
||||
result = sprintf(format, arg)
|
||||
result.encoding.should equal(Encoding::UTF_8)
|
||||
end
|
||||
end
|
||||
it_behaves_like :kernel_sprintf_encoding, -> (format, *args) {
|
||||
sprintf(format, *args)
|
||||
}
|
||||
end
|
||||
|
||||
describe "Kernel.sprintf" do
|
||||
it "needs to be reviewed for spec completeness"
|
||||
it_behaves_like :kernel_sprintf, -> (format, *args) {
|
||||
Kernel.sprintf(format, *args)
|
||||
}
|
||||
|
||||
it_behaves_like :kernel_sprintf_encoding, -> (format, *args) {
|
||||
Kernel.sprintf(format, *args)
|
||||
}
|
||||
end
|
||||
|
|
|
@ -2,7 +2,6 @@ require File.expand_path('../../../spec_helper', __FILE__)
|
|||
|
||||
ruby_version_is "2.0.0" do
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../fixtures/string_refinement', __FILE__)
|
||||
|
||||
describe "main.using" do
|
||||
it "requires one Module argument" do
|
||||
|
@ -16,6 +15,7 @@ ruby_version_is "2.0.0" do
|
|||
end
|
||||
|
||||
it "uses refinements from the given module only in the target file" do
|
||||
require File.expand_path('../fixtures/string_refinement', __FILE__)
|
||||
load File.expand_path('../fixtures/string_refinement_user.rb', __FILE__)
|
||||
MainSpecs::DATA[:in_module].should == 'foo'
|
||||
MainSpecs::DATA[:toplevel].should == 'foo'
|
||||
|
@ -25,6 +25,7 @@ ruby_version_is "2.0.0" do
|
|||
end
|
||||
|
||||
it "uses refinements from the given module for method calls in the target file" do
|
||||
require File.expand_path('../fixtures/string_refinement', __FILE__)
|
||||
load File.expand_path('../fixtures/string_refinement_user.rb', __FILE__)
|
||||
lambda do
|
||||
'hello'.foo
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
module ModuleSpecs
|
||||
module EmptyRefinement
|
||||
end
|
||||
|
||||
module RefinementForStringToS
|
||||
refine String do
|
||||
def to_s; "hello from refinement"; end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,6 +1,3 @@
|
|||
|
||||
return ## this code causes double free and now we are debugging.
|
||||
|
||||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/refine', __FILE__)
|
||||
|
||||
|
@ -87,18 +84,20 @@ describe "Module#refine" do
|
|||
end
|
||||
end
|
||||
|
||||
ruby_version_is "2.4" do
|
||||
it "accepts a module as argument" do
|
||||
inner_self = nil
|
||||
Module.new do
|
||||
refine(Enumerable) do
|
||||
def blah
|
||||
quarantine! do # https://bugs.ruby-lang.org/issues/14070
|
||||
ruby_version_is "2.4" do
|
||||
it "accepts a module as argument" do
|
||||
inner_self = nil
|
||||
Module.new do
|
||||
refine(Enumerable) do
|
||||
def blah
|
||||
end
|
||||
inner_self = self
|
||||
end
|
||||
inner_self = self
|
||||
end
|
||||
end
|
||||
|
||||
inner_self.public_instance_methods.should include(:blah)
|
||||
inner_self.public_instance_methods.should include(:blah)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -616,4 +615,3 @@ describe "Module#refine" do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/using', __FILE__)
|
||||
|
||||
describe "Module#using" do
|
||||
it "imports class refinements from module into the current class/module" do
|
||||
|
@ -90,7 +89,7 @@ describe "Module#using" do
|
|||
it "raises error in method scope" do
|
||||
mod = Module.new do
|
||||
def self.foo
|
||||
using ModuleSpecs::EmptyRefinement
|
||||
using Module.new {}
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -156,7 +155,11 @@ describe "Module#using" do
|
|||
|
||||
Module.new do
|
||||
Class.new do
|
||||
using ModuleSpecs::RefinementForStringToS
|
||||
using Module.new {
|
||||
refine String do
|
||||
def to_s; "hello from refinement"; end
|
||||
end
|
||||
}
|
||||
ScratchPad << "1".to_s
|
||||
end
|
||||
|
||||
|
@ -175,7 +178,11 @@ describe "Module#using" do
|
|||
Module.new do
|
||||
Class.new do
|
||||
ScratchPad << "1".to_s
|
||||
using ModuleSpecs::RefinementForStringToS
|
||||
using Module.new {
|
||||
refine String do
|
||||
def to_s; "hello from refinement"; end
|
||||
end
|
||||
}
|
||||
ScratchPad << "1".to_s
|
||||
end
|
||||
end
|
||||
|
@ -241,7 +248,11 @@ describe "Module#using" do
|
|||
|
||||
Module.new do
|
||||
if false
|
||||
using ModuleSpecs::RefinementForStringToS
|
||||
using Module.new {
|
||||
refine String do
|
||||
def to_s; "hello from refinement"; end
|
||||
end
|
||||
}
|
||||
end
|
||||
result = "1".to_s
|
||||
end
|
||||
|
|
|
@ -25,9 +25,11 @@ describe "Mutex#sleep" do
|
|||
m = Mutex.new
|
||||
m.lock
|
||||
duration = 0.1
|
||||
start = Time.now
|
||||
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
||||
m.sleep duration
|
||||
(Time.now - start).should be_close(duration, 0.2)
|
||||
now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
||||
(now - start).should > 0
|
||||
(now - start).should < 2.0
|
||||
end
|
||||
|
||||
it "unlocks the mutex while sleeping" do
|
||||
|
@ -71,4 +73,23 @@ describe "Mutex#sleep" do
|
|||
m.lock
|
||||
m.sleep(0.01).should be_kind_of(Integer)
|
||||
end
|
||||
|
||||
it "wakes up when requesting sleep times near or equal to zero" do
|
||||
times = []
|
||||
val = 1
|
||||
|
||||
# power of two divisor so we eventually get near zero
|
||||
loop do
|
||||
val = val / 16.0
|
||||
times << val
|
||||
break if val == 0.0
|
||||
end
|
||||
|
||||
m = Mutex.new
|
||||
m.lock
|
||||
times.each do |time|
|
||||
# just testing that sleep completes
|
||||
m.sleep(time).should_not == nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,17 +10,24 @@ describe "Process.groups" do
|
|||
actual = (Process.groups - [gid]).sort
|
||||
actual.should == expected
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# NOTE: This is kind of sketchy.
|
||||
it "sets the list of gids of groups in the supplemental group access list" do
|
||||
groups = Process.groups
|
||||
if Process.uid == 0
|
||||
describe "Process.groups=" do
|
||||
platform_is_not :windows do
|
||||
as_superuser do
|
||||
it "sets the list of gids of groups in the supplemental group access list" do
|
||||
groups = Process.groups
|
||||
Process.groups = []
|
||||
Process.groups.should == []
|
||||
Process.groups = groups
|
||||
Process.groups.sort.should == groups.sort
|
||||
else
|
||||
platform_is :aix do
|
||||
end
|
||||
end
|
||||
|
||||
as_user do
|
||||
platform_is :aix do
|
||||
it "sets the list of gids of groups in the supplemental group access list" do
|
||||
# setgroups() is not part of the POSIX standard,
|
||||
# so its behavior varies from OS to OS. AIX allows a non-root
|
||||
# process to set the supplementary group IDs, as long as
|
||||
|
@ -30,6 +37,7 @@ describe "Process.groups" do
|
|||
# it should no longer be able to set any supplementary
|
||||
# group IDs, even if it originally belonged to them.
|
||||
# It should only be able to set its primary group ID.
|
||||
groups = Process.groups
|
||||
Process.groups = groups
|
||||
Process.groups.sort.should == groups.sort
|
||||
Process.groups = []
|
||||
|
@ -41,14 +49,16 @@ describe "Process.groups" do
|
|||
lambda { Process.groups = supplementary }.should raise_error(Errno::EPERM)
|
||||
end
|
||||
end
|
||||
platform_is_not :aix do
|
||||
lambda { Process.groups = [] }.should raise_error(Errno::EPERM)
|
||||
end
|
||||
|
||||
platform_is_not :aix do
|
||||
it "raises Errno::EPERM" do
|
||||
groups = Process.groups
|
||||
lambda {
|
||||
Process.groups = groups
|
||||
}.should raise_error(Errno::EPERM)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "Process.groups=" do
|
||||
it "needs to be reviewed for spec completeness"
|
||||
end
|
||||
|
|
|
@ -137,6 +137,7 @@ describe "String#index with String" do
|
|||
|
||||
"hello".index("he", 1).should == nil
|
||||
"hello".index("he", 2).should == nil
|
||||
"I’ve got a multibyte character.\n".index("\n\n").should == nil
|
||||
end
|
||||
|
||||
with_feature :encoding do
|
||||
|
|
14
spec/ruby/core/string/percent_spec.rb
Normal file
14
spec/ruby/core/string/percent_spec.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../kernel/shared/sprintf', __FILE__)
|
||||
require File.expand_path('../../kernel/shared/sprintf_encoding', __FILE__)
|
||||
|
||||
describe "String#%" do
|
||||
it_behaves_like :kernel_sprintf, -> (format, *args) {
|
||||
format % args
|
||||
}
|
||||
|
||||
it_behaves_like :kernel_sprintf_encoding, -> (format, *args) {
|
||||
format % args
|
||||
}
|
||||
end
|
||||
|
|
@ -17,8 +17,13 @@ describe "Thread#thread_variables" do
|
|||
end
|
||||
|
||||
it "sets a value private to self" do
|
||||
@t.thread_variable_set :thread_variables_spec_a, 82
|
||||
@t.thread_variable_set :thread_variables_spec_b, 82
|
||||
@t.thread_variable_set :a, 82
|
||||
@t.thread_variable_set :b, 82
|
||||
Thread.current.thread_variables.should_not include(:a, :b)
|
||||
end
|
||||
|
||||
it "only contains user thread variables and is empty initially" do
|
||||
Thread.current.thread_variables.should == []
|
||||
@t.thread_variables.should == []
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,6 @@ require File.expand_path('../../../spec_helper', __FILE__)
|
|||
describe "Time#round" do
|
||||
before do
|
||||
@time = Time.utc(2010, 3, 30, 5, 43, "25.123456789".to_r)
|
||||
@subclass = Class.new(Time).now
|
||||
end
|
||||
|
||||
it "defaults to rounding to 0 places" do
|
||||
|
@ -19,7 +18,10 @@ describe "Time#round" do
|
|||
end
|
||||
|
||||
it "returns an instance of Time, even if #round is called on a subclass" do
|
||||
@subclass.round.should be_an_instance_of(Time)
|
||||
subclass = Class.new(Time)
|
||||
instance = subclass.at(0)
|
||||
instance.class.should equal subclass
|
||||
instance.round.should be_an_instance_of(Time)
|
||||
end
|
||||
|
||||
it "copies own timezone to the returning value" do
|
||||
|
|
|
@ -19,4 +19,11 @@ describe :time_gm, shared: true do
|
|||
it "interprets post-Gregorian reform dates using Gregorian calendar" do
|
||||
Time.send(@method, 1582, 10, 15, 12).to_i.should == -12219249600 # 2299161j
|
||||
end
|
||||
|
||||
it "handles fractional usec close to rounding limit" do
|
||||
time = Time.send(@method, 2000, 1, 1, 12, 30, 0, 9999r/10000)
|
||||
|
||||
time.usec.should == 0
|
||||
time.nsec.should == 999
|
||||
end
|
||||
end
|
||||
|
|
19
spec/ruby/core/tracepoint/binding_spec.rb
Normal file
19
spec/ruby/core/tracepoint/binding_spec.rb
Normal file
|
@ -0,0 +1,19 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
describe 'TracePoint#binding' do
|
||||
def test
|
||||
secret = 42
|
||||
end
|
||||
|
||||
it 'return the generated binding object from event' do
|
||||
bindings = []
|
||||
TracePoint.new(:return) { |tp|
|
||||
bindings << tp.binding
|
||||
}.enable {
|
||||
test
|
||||
}
|
||||
bindings.size.should == 1
|
||||
bindings[0].should be_kind_of(Binding)
|
||||
bindings[0].local_variables.should == [:secret]
|
||||
end
|
||||
end
|
26
spec/ruby/core/tracepoint/defined_class_spec.rb
Normal file
26
spec/ruby/core/tracepoint/defined_class_spec.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe 'TracePoint#defined_class' do
|
||||
it 'returns class or module of the method being called' do
|
||||
last_class_name = nil
|
||||
TracePoint.new(:call) do |tp|
|
||||
last_class_name = tp.defined_class
|
||||
end.enable do
|
||||
TracePointSpec::B.new.foo
|
||||
last_class_name.should equal(TracePointSpec::B)
|
||||
|
||||
TracePointSpec::B.new.bar
|
||||
last_class_name.should equal(TracePointSpec::A)
|
||||
|
||||
c = TracePointSpec::C.new
|
||||
last_class_name.should equal(TracePointSpec::C)
|
||||
|
||||
c.foo
|
||||
last_class_name.should equal(TracePointSpec::B)
|
||||
|
||||
c.bar
|
||||
last_class_name.should equal(TracePointSpec::A)
|
||||
end
|
||||
end
|
||||
end
|
64
spec/ruby/core/tracepoint/disable_spec.rb
Normal file
64
spec/ruby/core/tracepoint/disable_spec.rb
Normal file
|
@ -0,0 +1,64 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
describe 'TracePoint#disable' do
|
||||
def test; end
|
||||
it 'returns true if trace was enabled' do
|
||||
event_name, method_name = nil
|
||||
trace = TracePoint.new(:call) do |tp|
|
||||
event_name = tp.event
|
||||
method_name = tp.method_id
|
||||
end
|
||||
|
||||
trace.enable
|
||||
trace.disable.should be_true
|
||||
event_name, method_name = nil
|
||||
test
|
||||
method_name.equal?(:test).should be_false
|
||||
event_name.should equal(nil)
|
||||
end
|
||||
|
||||
it 'returns false if trace was disabled' do
|
||||
event_name, method_name = nil
|
||||
trace = TracePoint.new(:call) do |tp|
|
||||
event_name = tp.event
|
||||
method_name = tp.method_id
|
||||
end
|
||||
|
||||
trace.disable.should be_false
|
||||
event_name, method_name = nil
|
||||
test
|
||||
method_name.equal?(:test).should be_false
|
||||
event_name.should equal(nil)
|
||||
end
|
||||
|
||||
it 'is disabled within a block & is enabled outside the block' do
|
||||
enabled = nil
|
||||
trace = TracePoint.new(:line) {}
|
||||
trace.enable
|
||||
trace.disable { enabled = trace.enabled? }
|
||||
enabled.should be_false
|
||||
trace.enabled?.should be_true
|
||||
trace.disable
|
||||
end
|
||||
|
||||
it 'is disabled within a block & also returns false when its called with a block' do
|
||||
trace = TracePoint.new(:line) {}
|
||||
trace.enable
|
||||
trace.disable { trace.enabled? }.should == false
|
||||
trace.enabled?.should equal(true)
|
||||
trace.disable
|
||||
end
|
||||
|
||||
ruby_bug "#14057", "2.0"..."2.5" do
|
||||
it 'can accept param within a block but it should not yield arguments' do
|
||||
event_name = nil
|
||||
trace = TracePoint.new(:line) {}
|
||||
trace.enable
|
||||
trace.disable do |*args|
|
||||
args.should == []
|
||||
end
|
||||
trace.enabled?.should be_true
|
||||
trace.disable
|
||||
end
|
||||
end
|
||||
end
|
92
spec/ruby/core/tracepoint/enable_spec.rb
Normal file
92
spec/ruby/core/tracepoint/enable_spec.rb
Normal file
|
@ -0,0 +1,92 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
describe 'TracePoint#enable' do
|
||||
def test; end
|
||||
|
||||
describe 'without a block' do
|
||||
it 'returns true if trace was enabled' do
|
||||
event_name, method_name = nil, nil
|
||||
method_name = []
|
||||
trace = TracePoint.new(:call) do |tp|
|
||||
event_name = tp.event
|
||||
method_name << tp.method_id
|
||||
end
|
||||
|
||||
test
|
||||
event_name.should == nil
|
||||
|
||||
trace.enable
|
||||
test
|
||||
event_name.should equal(:call)
|
||||
trace.disable
|
||||
end
|
||||
|
||||
it 'returns false if trace was disabled' do
|
||||
event_name, method_name = nil, nil
|
||||
trace = TracePoint.new(:call) do |tp|
|
||||
event_name = tp.event
|
||||
method_name = tp.method_id
|
||||
end
|
||||
|
||||
trace.enable.should be_false
|
||||
event_name.should equal(:call)
|
||||
test
|
||||
method_name.equal?(:test).should be_true
|
||||
|
||||
trace.disable
|
||||
event_name, method_name = nil
|
||||
test
|
||||
method_name.equal?(:test).should be_false
|
||||
event_name.should equal(nil)
|
||||
|
||||
trace.enable.should be_false
|
||||
event_name.should equal(:call)
|
||||
test
|
||||
method_name.equal?(:test).should be_true
|
||||
trace.disable
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with a block' do
|
||||
it 'enables the trace object within a block' do
|
||||
event_name = nil
|
||||
TracePoint.new(:line) do |tp|
|
||||
event_name = tp.event
|
||||
end.enable { event_name.should equal(:line) }
|
||||
end
|
||||
|
||||
ruby_bug "#14057", "2.0"..."2.5" do
|
||||
it 'can accept arguments within a block but it should not yield arguments' do
|
||||
event_name = nil
|
||||
trace = TracePoint.new(:line) { |tp| event_name = tp.event }
|
||||
trace.enable do |*args|
|
||||
event_name.should equal(:line)
|
||||
args.should == []
|
||||
end
|
||||
trace.enabled?.should be_false
|
||||
end
|
||||
end
|
||||
|
||||
it 'enables trace object on calling with a block if it was already enabled' do
|
||||
enabled = nil
|
||||
trace = TracePoint.new(:line) {}
|
||||
trace.enable
|
||||
trace.enable { enabled = trace.enabled? }
|
||||
enabled.should == true
|
||||
trace.disable
|
||||
end
|
||||
|
||||
it 'returns value returned by the block' do
|
||||
trace = TracePoint.new(:line) {}
|
||||
trace.enable { true; 'test' }.should == 'test'
|
||||
end
|
||||
|
||||
it 'disables the trace object outside the block' do
|
||||
event_name = nil
|
||||
trace = TracePoint.new(:line) { |tp|event_name = tp.event }
|
||||
trace.enable { '2 + 2' }
|
||||
event_name.should equal(:line)
|
||||
trace.enabled?.should be_false
|
||||
end
|
||||
end
|
||||
end
|
14
spec/ruby/core/tracepoint/enabled_spec.rb
Normal file
14
spec/ruby/core/tracepoint/enabled_spec.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
describe 'TracePoint#enabled?' do
|
||||
it 'returns true when current status of the trace is enable' do
|
||||
trace = TracePoint.new(:call) {}
|
||||
trace.enable do
|
||||
trace.enabled?.should be_true
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns false when current status of the trace is disabled' do
|
||||
TracePoint.new(:call) {}.enabled?.should be_false
|
||||
end
|
||||
end
|
21
spec/ruby/core/tracepoint/event_spec.rb
Normal file
21
spec/ruby/core/tracepoint/event_spec.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe 'TracePoint#event' do
|
||||
it 'returns the type of event' do
|
||||
event_name = nil
|
||||
TracePoint.new(:end, :call) do |tp|
|
||||
event_name = tp.event
|
||||
end.enable do
|
||||
TracePointSpec.test
|
||||
event_name.should equal(:call)
|
||||
|
||||
TracePointSpec::B.new.foo
|
||||
event_name.should equal(:call)
|
||||
|
||||
class TracePointSpec::B; end
|
||||
event_name.should equal(:end)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -4,5 +4,31 @@ module TracePointSpec
|
|||
end
|
||||
alias_method :m_alias, :m
|
||||
end
|
||||
end
|
||||
|
||||
module A
|
||||
def bar; end
|
||||
end
|
||||
|
||||
class B
|
||||
include A
|
||||
|
||||
def foo; end;
|
||||
end
|
||||
|
||||
class C < B
|
||||
def initialize
|
||||
end
|
||||
|
||||
def foo
|
||||
super
|
||||
end
|
||||
|
||||
def bar
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def self.test
|
||||
'test'
|
||||
end
|
||||
end
|
||||
|
|
8
spec/ruby/core/tracepoint/inspect_spec.rb
Normal file
8
spec/ruby/core/tracepoint/inspect_spec.rb
Normal file
|
@ -0,0 +1,8 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
describe 'TracePoint#inspect' do
|
||||
it 'returns a string containing a human-readable TracePoint status' do
|
||||
TracePoint.new(:call) {}.inspect.should ==
|
||||
'#<TracePoint:disabled>'
|
||||
end
|
||||
end
|
10
spec/ruby/core/tracepoint/lineno_spec.rb
Normal file
10
spec/ruby/core/tracepoint/lineno_spec.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
describe 'TracePoint#lineno' do
|
||||
it 'returns the line number of the event' do
|
||||
lineno = nil
|
||||
TracePoint.new(:line) { |tp| lineno = tp.lineno }.enable do
|
||||
lineno.should == 7
|
||||
end
|
||||
end
|
||||
end
|
13
spec/ruby/core/tracepoint/method_id_spec.rb
Normal file
13
spec/ruby/core/tracepoint/method_id_spec.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
describe 'TracePoint#method_id' do
|
||||
def test; end
|
||||
|
||||
it 'returns the name at the definition of the method being called' do
|
||||
method_name = nil
|
||||
TracePoint.new(:call) { |tp| method_name = tp.method_id}.enable do
|
||||
test
|
||||
method_name.should equal(:test)
|
||||
end
|
||||
end
|
||||
end
|
68
spec/ruby/core/tracepoint/new_spec.rb
Normal file
68
spec/ruby/core/tracepoint/new_spec.rb
Normal file
|
@ -0,0 +1,68 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe 'TracePoint.new' do
|
||||
it 'returns a new TracePoint object, not enabled by default' do
|
||||
TracePoint.new(:call) {}.enabled?.should be_false
|
||||
end
|
||||
|
||||
it 'includes :line event when event is not specified' do
|
||||
event_name = nil
|
||||
TracePoint.new() { |tp| event_name = tp.event }.enable do
|
||||
event_name.should equal(:line)
|
||||
|
||||
event_name = nil
|
||||
TracePointSpec.test
|
||||
event_name.should equal(:line)
|
||||
|
||||
event_name = nil
|
||||
TracePointSpec::B.new.foo
|
||||
event_name.should equal(:line)
|
||||
end
|
||||
end
|
||||
|
||||
it 'converts given event name as string into symbol using to_sym' do
|
||||
event_name = nil
|
||||
(o = mock('return')).should_receive(:to_sym).and_return(:return)
|
||||
|
||||
TracePoint.new(o) { |tp| event_name = tp.event}.enable do
|
||||
event_name.should equal(nil)
|
||||
TracePointSpec.test
|
||||
event_name.should equal(:return)
|
||||
end
|
||||
end
|
||||
|
||||
it 'includes multiple events when multiple event names are passed as params' do
|
||||
event_name = nil
|
||||
TracePoint.new(:end, :call) do |tp|
|
||||
event_name = tp.event
|
||||
end.enable do
|
||||
TracePointSpec.test
|
||||
event_name.should equal(:call)
|
||||
|
||||
TracePointSpec::B.new.foo
|
||||
event_name.should equal(:call)
|
||||
|
||||
class TracePointSpec::B; end
|
||||
event_name.should equal(:end)
|
||||
end
|
||||
end
|
||||
|
||||
it 'raises a TypeError when the given object is not a string/symbol' do
|
||||
o = mock('123')
|
||||
-> { TracePoint.new(o) {}}.should raise_error(TypeError)
|
||||
|
||||
o.should_receive(:to_sym).and_return(123)
|
||||
-> { TracePoint.new(o) {}}.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
ruby_bug "#140740", "2.0"..."2.5" do
|
||||
it 'expects to be called with a block' do
|
||||
-> { TracePoint.new(:line) }.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
|
||||
it "raises a Argument error when the give argument doesn't match an event name" do
|
||||
-> { TracePoint.new(:test) }.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
18
spec/ruby/core/tracepoint/path_spec.rb
Normal file
18
spec/ruby/core/tracepoint/path_spec.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
describe 'TracePoint#path' do
|
||||
it 'returns the path of the file being run' do
|
||||
path = nil
|
||||
TracePoint.new(:line) { |tp| path = tp.path }.enable do
|
||||
path.should == "#{__FILE__}"
|
||||
end
|
||||
end
|
||||
|
||||
it 'equals (eval) inside an eval for :end event' do
|
||||
path = nil
|
||||
TracePoint.new(:end) { |tp| path = tp.path }.enable do
|
||||
eval("class A; end")
|
||||
path.should == '(eval)'
|
||||
end
|
||||
end
|
||||
end
|
16
spec/ruby/core/tracepoint/raised_exception_spec.rb
Normal file
16
spec/ruby/core/tracepoint/raised_exception_spec.rb
Normal file
|
@ -0,0 +1,16 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
describe 'TracePoint#raised_exception' do
|
||||
it 'returns value from exception raised on the :raise event' do
|
||||
raised_exception, error_result = nil
|
||||
trace = TracePoint.new(:raise) { |tp| raised_exception = tp.raised_exception }
|
||||
trace.enable do
|
||||
begin
|
||||
raise StandardError
|
||||
rescue => e
|
||||
error_result = e
|
||||
end
|
||||
raised_exception.should equal(error_result)
|
||||
end
|
||||
end
|
||||
end
|
13
spec/ruby/core/tracepoint/return_value_spec.rb
Normal file
13
spec/ruby/core/tracepoint/return_value_spec.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
describe 'TracePoint#return_value' do
|
||||
def test; 'test' end
|
||||
|
||||
it 'returns value from :return event' do
|
||||
trace_value = nil
|
||||
TracePoint.new(:return) { |tp| trace_value = tp.return_value}.enable do
|
||||
test
|
||||
trace_value.should == 'test'
|
||||
end
|
||||
end
|
||||
end
|
10
spec/ruby/core/tracepoint/self_spec.rb
Normal file
10
spec/ruby/core/tracepoint/self_spec.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
describe 'TracePoint#self' do
|
||||
it 'return the trace object from event' do
|
||||
trace = nil
|
||||
TracePoint.new(:line) { |tp| trace = tp.self }.enable do
|
||||
trace.equal?(self).should be_true
|
||||
end
|
||||
end
|
||||
end
|
9
spec/ruby/core/tracepoint/trace_spec.rb
Normal file
9
spec/ruby/core/tracepoint/trace_spec.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
describe 'TracePoint.trace' do
|
||||
it 'activates the trace automatically' do
|
||||
trace = TracePoint.trace(:call) {}
|
||||
trace.enabled?.should be_true
|
||||
trace.disable
|
||||
end
|
||||
end
|
|
@ -29,4 +29,8 @@ describe "The BEGIN keyword" do
|
|||
|
||||
ScratchPad.recorded.should == ['foo', 'bar']
|
||||
end
|
||||
|
||||
it "returns the top-level script's filename for __FILE__" do
|
||||
ruby_exe(fixture(__FILE__, "begin_file.rb")).chomp.should =~ /begin_file\.rb$/
|
||||
end
|
||||
end
|
||||
|
|
|
@ -24,6 +24,24 @@ describe "The break statement in a block" do
|
|||
value.should == :value
|
||||
end
|
||||
end
|
||||
|
||||
describe "captured and delegated to another method repeatedly" do
|
||||
it "breaks out of the block" do
|
||||
@program.looped_break_in_captured_block
|
||||
ScratchPad.recorded.should == [:begin,
|
||||
:preloop,
|
||||
:predele,
|
||||
:preyield,
|
||||
:prebreak,
|
||||
:postbreak,
|
||||
:postyield,
|
||||
:postdele,
|
||||
:predele,
|
||||
:preyield,
|
||||
:prebreak,
|
||||
:end]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "The break statement in a captured block" do
|
||||
|
|
|
@ -375,6 +375,28 @@ describe "Constant resolution within methods" do
|
|||
end
|
||||
|
||||
end
|
||||
|
||||
describe "with &&=" do
|
||||
it "re-assigns a scoped constant if already true" do
|
||||
module ConstantSpecs
|
||||
OpAssignTrue = true
|
||||
end
|
||||
suppress_warning do
|
||||
ConstantSpecs::OpAssignTrue &&= 1
|
||||
end
|
||||
ConstantSpecs::OpAssignTrue.should == 1
|
||||
ConstantSpecs.send :remove_const, :OpAssignTrue
|
||||
end
|
||||
|
||||
it "leaves scoped constant if not true" do
|
||||
module ConstantSpecs
|
||||
OpAssignFalse = false
|
||||
end
|
||||
ConstantSpecs::OpAssignFalse &&= 1
|
||||
ConstantSpecs::OpAssignFalse.should == false
|
||||
ConstantSpecs.send :remove_const, :OpAssignFalse
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "Constant resolution within a singleton class (class << obj)" do
|
||||
|
|
|
@ -750,7 +750,7 @@ describe "The defined? keyword for a scoped constant" do
|
|||
end
|
||||
|
||||
it "returns nil when an undefined constant is scoped to a defined constant" do
|
||||
defined?(DefinedSpecs::Child::B).should be_nil
|
||||
defined?(DefinedSpecs::Child::Undefined).should be_nil
|
||||
end
|
||||
|
||||
it "returns nil when a constant is scoped to an undefined constant" do
|
||||
|
@ -785,7 +785,7 @@ describe "The defined? keyword for a top-level scoped constant" do
|
|||
end
|
||||
|
||||
it "returns nil when an undefined constant is scoped to a defined constant" do
|
||||
defined?(::DefinedSpecs::Child::B).should be_nil
|
||||
defined?(::DefinedSpecs::Child::Undefined).should be_nil
|
||||
end
|
||||
|
||||
it "returns nil when the undefined constant is scoped to an undefined constant" do
|
||||
|
|
3
spec/ruby/language/fixtures/begin_file.rb
Normal file
3
spec/ruby/language/fixtures/begin_file.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
BEGIN {
|
||||
puts __FILE__
|
||||
}
|
|
@ -106,6 +106,34 @@ module BreakSpecs
|
|||
note :d
|
||||
end
|
||||
|
||||
def looped_break_in_captured_block
|
||||
note :begin
|
||||
looped_delegate_block do |i|
|
||||
note :prebreak
|
||||
break if i == 1
|
||||
note :postbreak
|
||||
end
|
||||
note :end
|
||||
end
|
||||
|
||||
def looped_delegate_block(&block)
|
||||
note :preloop
|
||||
2.times do |i|
|
||||
note :predele
|
||||
yield_value(i, &block)
|
||||
note :postdele
|
||||
end
|
||||
note :postloop
|
||||
end
|
||||
private :looped_delegate_block
|
||||
|
||||
def yield_value(value)
|
||||
note :preyield
|
||||
yield value
|
||||
note :postyield
|
||||
end
|
||||
private :yield_value
|
||||
|
||||
def method(v)
|
||||
yield v
|
||||
end
|
||||
|
|
|
@ -291,10 +291,20 @@ describe "The rescue keyword" do
|
|||
end.should == :expected
|
||||
end
|
||||
|
||||
ruby_version_is ""..."2.4" do
|
||||
it "fails when using 'rescue' in method arguments" do
|
||||
lambda { eval '1.+ (1 rescue 1)' }.should raise_error(SyntaxError)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is "2.4" do
|
||||
it "allows 'rescue' in method arguments" do
|
||||
two = eval '1.+ (raise("Error") rescue 1)'
|
||||
two.should == 2
|
||||
end
|
||||
|
||||
it "requires the 'rescue' in method arguments to be wrapped in parens" do
|
||||
lambda { eval '1.+(1 rescue 1)' }.should raise_error(SyntaxError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -409,6 +409,39 @@ describe "The return keyword" do
|
|||
end
|
||||
end
|
||||
|
||||
describe "within a class" do
|
||||
ruby_version_is ""..."2.5" do
|
||||
it "is allowed" do
|
||||
File.write(@filename, <<-END_OF_CODE)
|
||||
class A
|
||||
ScratchPad << "before return"
|
||||
return
|
||||
|
||||
ScratchPad << "after return"
|
||||
end
|
||||
END_OF_CODE
|
||||
|
||||
load @filename
|
||||
ScratchPad.recorded.should == ["before return"]
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is "2.5" do
|
||||
it "raises a SyntaxError" do
|
||||
File.write(@filename, <<-END_OF_CODE)
|
||||
class A
|
||||
ScratchPad << "before return"
|
||||
return
|
||||
|
||||
ScratchPad << "after return"
|
||||
end
|
||||
END_OF_CODE
|
||||
|
||||
-> { load @filename }.should raise_error(SyntaxError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "file loading" do
|
||||
it "stops file loading and execution" do
|
||||
File.write(@filename, <<-END_OF_CODE)
|
||||
|
|
|
@ -11,20 +11,35 @@ describe "BigDecimal.limit" do
|
|||
BigDecimal.limit(old)
|
||||
end
|
||||
|
||||
it "use the global limit if no precision is specified" do
|
||||
it "uses the global limit if no precision is specified" do
|
||||
BigDecimalSpecs.with_limit(0) do
|
||||
(BigDecimal('0.888') + BigDecimal('0')).should == BigDecimal('0.888')
|
||||
(BigDecimal('0.888') - BigDecimal('0')).should == BigDecimal('0.888')
|
||||
(BigDecimal('0.888') * BigDecimal('3')).should == BigDecimal('2.664')
|
||||
(BigDecimal('0.888') / BigDecimal('3')).should == BigDecimal('0.296')
|
||||
end
|
||||
|
||||
BigDecimalSpecs.with_limit(1) do
|
||||
(BigDecimal('0.888') + BigDecimal('0')).should == BigDecimal('0.9')
|
||||
(BigDecimal('0.888') - BigDecimal('0')).should == BigDecimal('0.9')
|
||||
(BigDecimal('0.888') * BigDecimal('3')).should == BigDecimal('3')
|
||||
(BigDecimal('0.888') / BigDecimal('3')).should == BigDecimal('0.3')
|
||||
end
|
||||
|
||||
BigDecimalSpecs.with_limit(2) do
|
||||
(BigDecimal('0.888') + BigDecimal('0')).should == BigDecimal('0.89')
|
||||
(BigDecimal('0.888') - BigDecimal('0')).should == BigDecimal('0.89')
|
||||
(BigDecimal('0.888') * BigDecimal('3')).should == BigDecimal('2.7')
|
||||
(BigDecimal('0.888') / BigDecimal('3')).should == BigDecimal('0.30')
|
||||
end
|
||||
end
|
||||
|
||||
it "picks the specified precision over global limit" do
|
||||
BigDecimalSpecs.with_limit(3) do
|
||||
BigDecimal('0.888').add(BigDecimal('0'), 2).should == BigDecimal('0.89')
|
||||
BigDecimal('0.888').sub(BigDecimal('0'), 2).should == BigDecimal('0.89')
|
||||
BigDecimal('0.888').mult(BigDecimal('3'), 2).should == BigDecimal('2.7')
|
||||
BigDecimal('0.888').div(BigDecimal('3'), 2).should == BigDecimal('0.30')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -34,9 +34,13 @@ describe "Date constants" do
|
|||
|
||||
it "freezes MONTHNAMES, DAYNAMES, ABBR_MONTHNAMES, ABBR_DAYSNAMES" do
|
||||
[Date::MONTHNAMES, Date::DAYNAMES, Date::ABBR_MONTHNAMES, Date::ABBR_DAYNAMES].each do |ary|
|
||||
lambda { ary << "Unknown" }.should raise_error
|
||||
lambda {
|
||||
ary << "Unknown"
|
||||
}.should raise_error(RuntimeError, /frozen/)
|
||||
ary.compact.each do |name|
|
||||
lambda { name << "modified" }.should raise_error
|
||||
lambda {
|
||||
name << "modified"
|
||||
}.should raise_error(RuntimeError, /frozen/)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,15 +13,6 @@ describe "Date#<<" do
|
|||
d.should == Date.civil(2008, 2, 29)
|
||||
end
|
||||
|
||||
ruby_version_is ""..."2.3" do
|
||||
it "raises an error on non numeric parameters" do
|
||||
lambda { Date.civil(2007,2,27) << :hello }.should raise_error
|
||||
lambda { Date.civil(2007,2,27) << "hello" }.should raise_error
|
||||
lambda { Date.civil(2007,2,27) << Date.new }.should raise_error
|
||||
lambda { Date.civil(2007,2,27) << Object.new }.should raise_error
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is "2.3" do
|
||||
it "raises an error on non numeric parameters" do
|
||||
lambda { Date.civil(2007,2,27) << :hello }.should raise_error(TypeError)
|
||||
|
|
|
@ -7,7 +7,7 @@ describe "DateTime.now" do
|
|||
end
|
||||
|
||||
it "sets the current date" do
|
||||
(DateTime.now - Date.today).to_f.should be_close(0.0, 1.0)
|
||||
(DateTime.now - Date.today).to_f.should be_close(0.0, 2.0)
|
||||
end
|
||||
|
||||
it "sets the current time" do
|
||||
|
|
|
@ -6,6 +6,18 @@ describe "DateTime#to_time" do
|
|||
DateTime.now.to_time.should be_kind_of(Time)
|
||||
end
|
||||
|
||||
it "returns a Time representing the same instant" do
|
||||
datetime = DateTime.civil(3, 12, 31, 23, 58, 59)
|
||||
time = datetime.to_time.utc
|
||||
|
||||
time.year.should == 3
|
||||
time.month.should == 12
|
||||
time.day.should == 31
|
||||
time.hour.should == 23
|
||||
time.min.should == 58
|
||||
time.sec.should == 59
|
||||
end
|
||||
|
||||
ruby_version_is "2.4" do
|
||||
it "preserves the same time regardless of local time or zone" do
|
||||
date = DateTime.new(2012, 12, 24, 12, 23, 00, '+03:00')
|
||||
|
|
|
@ -65,7 +65,7 @@ END
|
|||
end
|
||||
|
||||
|
||||
it "not support '<%-= expr %> even when trim_mode is '-'" do
|
||||
it "does not support '<%-= expr %> even when trim_mode is '-'" do
|
||||
|
||||
input = <<'END'
|
||||
<p>
|
||||
|
@ -74,7 +74,9 @@ END
|
|||
</p>
|
||||
END
|
||||
|
||||
lambda { ERB.new(input, nil, '-').result }.should raise_error
|
||||
lambda {
|
||||
ERB.new(input, nil, '-').result
|
||||
}.should raise_error(SyntaxError)
|
||||
end
|
||||
|
||||
it "regards lines starting with '%' as '<% ... %>' when trim_mode is '%'" do
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require 'etc'
|
||||
|
||||
ruby_version_is "2.2" do
|
||||
describe "Etc.nprocessors" do
|
||||
it "returns the number of online processors" do
|
||||
Etc.nprocessors.should be_kind_of(Integer)
|
||||
Etc.nprocessors.should >= 1
|
||||
end
|
||||
describe "Etc.nprocessors" do
|
||||
it "returns the number of online processors" do
|
||||
Etc.nprocessors.should be_kind_of(Integer)
|
||||
Etc.nprocessors.should >= 1
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,9 +8,13 @@ describe "OpenSSL::Config#freeze" do
|
|||
|
||||
it "freezes" do
|
||||
c = OpenSSL::Config.new
|
||||
lambda{c['foo'] = [ ['key', 'value'] ]}.should_not raise_error
|
||||
lambda {
|
||||
c['foo'] = [ ['key', 'value'] ]
|
||||
}.should_not raise_error
|
||||
c.freeze
|
||||
c.frozen?.should be_true
|
||||
lambda{c['foo'] = [ ['key', 'value'] ]}.should raise_error
|
||||
lambda {
|
||||
c['foo'] = [ ['key', 'value'] ]
|
||||
}.should raise_error(TypeError)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,7 +16,9 @@ describe "Socket::IPSocket#peeraddr" do
|
|||
end
|
||||
|
||||
it "raises error if socket is not connected" do
|
||||
lambda { @server.peeraddr }.should raise_error
|
||||
lambda {
|
||||
@server.peeraddr
|
||||
}.should raise_error(Errno::ENOTCONN)
|
||||
end
|
||||
|
||||
it "returns an array of information on the peer" do
|
||||
|
|
|
@ -21,7 +21,9 @@ describe "UNIXSocket#peeraddr" do
|
|||
end
|
||||
|
||||
it "raises an error in server sockets" do
|
||||
lambda { @server.peeraddr }.should raise_error
|
||||
lambda {
|
||||
@server.peeraddr
|
||||
}.should raise_error(Errno::ENOTCONN)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
require File.expand_path('../../../core/kernel/shared/sprintf', __FILE__)
|
||||
|
||||
describe "StringIO#printf" do
|
||||
before :each do
|
||||
|
@ -28,6 +29,14 @@ describe "StringIO#printf" do
|
|||
@io.printf("%d %04x", 123, 123)
|
||||
@io.pos.should eql(16)
|
||||
end
|
||||
|
||||
describe "formatting" do
|
||||
it_behaves_like :kernel_sprintf, -> (format, *args) {
|
||||
io = StringIO.new
|
||||
io.printf(format, *args)
|
||||
io.string
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
describe "StringIO#printf when in append mode" do
|
||||
|
@ -59,3 +68,4 @@ describe "StringIO#printf when self is not writable" do
|
|||
lambda { io.printf("test") }.should raise_error(IOError)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
platform_is_not :windows do
|
||||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../shared/log', __FILE__)
|
||||
require 'syslog'
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
platform_is_not :windows do
|
||||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require 'syslog'
|
||||
|
||||
describe "Syslog.close" do
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
platform_is_not :windows do
|
||||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require 'syslog'
|
||||
|
||||
describe "Syslog::Constants" do
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
platform_is_not :windows do
|
||||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../shared/log', __FILE__)
|
||||
require 'syslog'
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
platform_is_not :windows do
|
||||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../shared/log', __FILE__)
|
||||
require 'syslog'
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
platform_is_not :windows do
|
||||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../shared/log', __FILE__)
|
||||
require 'syslog'
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
platform_is_not :windows do
|
||||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../shared/log', __FILE__)
|
||||
require 'syslog'
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
platform_is_not :windows do
|
||||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require 'syslog'
|
||||
|
||||
describe "Syslog.facility" do
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
platform_is_not :windows do
|
||||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require 'syslog'
|
||||
|
||||
describe "Syslog.ident" do
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
platform_is_not :windows do
|
||||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../shared/log', __FILE__)
|
||||
require 'syslog'
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
platform_is_not :windows do
|
||||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require 'syslog'
|
||||
|
||||
describe "Syslog.inspect" do
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
platform_is_not :windows do
|
||||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require 'syslog'
|
||||
|
||||
describe "Syslog.instance" do
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
platform_is_not :windows do
|
||||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require 'syslog'
|
||||
|
||||
describe "Syslog.log" do
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
platform_is_not :windows do
|
||||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require 'syslog'
|
||||
|
||||
describe "Syslog.mask" do
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
platform_is_not :windows do
|
||||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../shared/log', __FILE__)
|
||||
require 'syslog'
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
platform_is_not :windows do
|
||||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../shared/reopen', __FILE__)
|
||||
require 'syslog'
|
||||
|
||||
|
@ -73,8 +74,13 @@ platform_is_not :windows do
|
|||
|
||||
it "raises an error if the log is opened" do
|
||||
Syslog.open
|
||||
lambda { Syslog.open}.should raise_error
|
||||
lambda { Syslog.close; Syslog.open }.should_not raise_error
|
||||
lambda {
|
||||
Syslog.open
|
||||
}.should raise_error(RuntimeError, /syslog already open/)
|
||||
lambda {
|
||||
Syslog.close
|
||||
Syslog.open
|
||||
}.should_not raise_error
|
||||
Syslog.close
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
platform_is_not :windows do
|
||||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require 'syslog'
|
||||
|
||||
describe "Syslog.opened?" do
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
platform_is_not :windows do
|
||||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require 'syslog'
|
||||
|
||||
describe "Syslog.options" do
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
platform_is_not :windows do
|
||||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../shared/reopen', __FILE__)
|
||||
require 'syslog'
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
platform_is_not :windows do
|
||||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../shared/log', __FILE__)
|
||||
require 'syslog'
|
||||
|
||||
|
|
27
spec/ruby/library/time/to_datetime_spec.rb
Normal file
27
spec/ruby/library/time/to_datetime_spec.rb
Normal file
|
@ -0,0 +1,27 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require 'time'
|
||||
|
||||
describe "Time#to_datetime" do
|
||||
it "returns a DateTime representing the same instant" do
|
||||
time = Time.utc(3, 12, 31, 23, 58, 59)
|
||||
datetime = time.to_datetime
|
||||
datetime.year.should == 3
|
||||
datetime.month.should == 12
|
||||
datetime.day.should == 31
|
||||
datetime.hour.should == 23
|
||||
datetime.min.should == 58
|
||||
datetime.sec.should == 59
|
||||
end
|
||||
|
||||
it "roundtrips" do
|
||||
time = Time.utc(3, 12, 31, 23, 58, 59)
|
||||
datetime = time.to_datetime
|
||||
datetime.to_time.utc.should == time
|
||||
end
|
||||
|
||||
it "yields a DateTime with the default Calendar reform day" do
|
||||
Time.utc(1582, 10, 4, 1, 2, 3).to_datetime.start.should == Date::ITALY
|
||||
Time.utc(1582, 10, 14, 1, 2, 3).to_datetime.start.should == Date::ITALY
|
||||
Time.utc(1582, 10, 15, 1, 2, 3).to_datetime.start.should == Date::ITALY
|
||||
end
|
||||
end
|
|
@ -21,7 +21,9 @@ describe "URI.join" do
|
|||
end
|
||||
|
||||
it "raises an error if given no argument" do
|
||||
lambda{ URI.join }.should raise_error
|
||||
lambda {
|
||||
URI.join
|
||||
}.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "doesn't create redundant '/'s" do
|
||||
|
|
|
@ -18,7 +18,9 @@ describe :uri_join, shared: true do
|
|||
end
|
||||
|
||||
it "raises an error if given no argument" do
|
||||
lambda{ @object.join }.should raise_error
|
||||
lambda {
|
||||
@object.join
|
||||
}.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "doesn't create redundant '/'s" do
|
||||
|
|
|
@ -34,6 +34,27 @@ describe "YAML.load" do
|
|||
end
|
||||
end
|
||||
|
||||
it "loads strings with chars from non-base Unicode plane" do
|
||||
# We add these strings as bytes and force the encoding for safety
|
||||
# as bugs in parsing unicode characters can obscure bugs in this
|
||||
# area.
|
||||
|
||||
yaml_and_strings = {
|
||||
# "--- 🌵" => "🌵"
|
||||
[45, 45, 45, 32, 240, 159, 140, 181] =>
|
||||
[240, 159, 140, 181],
|
||||
# "--- 🌵 and some text" => "🌵 and some text"
|
||||
[45, 45, 45, 32, 240, 159, 140, 181, 32, 97, 110, 100, 32, 115, 111, 109, 101, 32, 116, 101, 120, 116] =>
|
||||
[240, 159, 140, 181, 32, 97, 110, 100, 32, 115, 111, 109, 101, 32, 116, 101, 120, 116],
|
||||
# "--- Some text 🌵 and some text" => "Some text 🌵 and some text"
|
||||
[45, 45, 45, 32, 83, 111, 109, 101, 32, 116, 101, 120, 116, 32, 240, 159, 140, 181, 32, 97, 110, 100, 32, 115, 111, 109, 101, 32, 116, 101, 120, 116] =>
|
||||
[83, 111, 109, 101, 32, 116, 101, 120, 116, 32, 240, 159, 140, 181, 32, 97, 110, 100, 32, 115, 111, 109, 101, 32, 116, 101, 120, 116]
|
||||
}
|
||||
yaml_and_strings.each do |yaml, str|
|
||||
YAML.load(yaml.pack("C*").force_encoding("UTF-8")).should == str.pack("C*").force_encoding("UTF-8")
|
||||
end
|
||||
end
|
||||
|
||||
it "fails on invalid keys" do
|
||||
if YAML.to_s == "Psych"
|
||||
error = Psych::SyntaxError
|
||||
|
|
|
@ -96,6 +96,12 @@ static VALUE numeric_spec_rb_num_coerce_relop(VALUE self, VALUE x, VALUE y, VALU
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_RB_ABSINT_SINGLEBIT_P
|
||||
static VALUE numeric_spec_rb_absint_singlebit_p(VALUE self, VALUE num) {
|
||||
return INT2FIX(rb_absint_singlebit_p(num));
|
||||
}
|
||||
#endif
|
||||
|
||||
void Init_numeric_spec(void) {
|
||||
VALUE cls;
|
||||
cls = rb_define_class("CApiNumericSpecs", rb_cObject);
|
||||
|
@ -159,6 +165,10 @@ void Init_numeric_spec(void) {
|
|||
#ifdef HAVE_RB_NUM_COERCE_RELOP
|
||||
rb_define_method(cls, "rb_num_coerce_relop", numeric_spec_rb_num_coerce_relop, 3);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_RB_ABSINT_SINGLEBIT_P
|
||||
rb_define_method(cls, "rb_absint_singlebit_p", numeric_spec_rb_absint_singlebit_p, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -5,6 +5,32 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FL_ABLE
|
||||
static VALUE object_spec_FL_ABLE(VALUE self, VALUE obj) {
|
||||
if (FL_ABLE(obj)) {
|
||||
return Qtrue;
|
||||
} else {
|
||||
return Qfalse;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FL_TEST
|
||||
static int object_spec_FL_TEST_flag(VALUE flag_string) {
|
||||
char *flag_cstr = StringValueCStr(flag_string);
|
||||
if (strcmp(flag_cstr, "FL_TAINT") == 0) {
|
||||
return FL_TAINT;
|
||||
} else if (strcmp(flag_cstr, "FL_FREEZE") == 0) {
|
||||
return FL_FREEZE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VALUE object_spec_FL_TEST(VALUE self, VALUE obj, VALUE flag) {
|
||||
return INT2FIX(FL_TEST(obj, object_spec_FL_TEST_flag(flag)));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OBJ_TAINT
|
||||
static VALUE object_spec_OBJ_TAINT(VALUE self, VALUE obj) {
|
||||
OBJ_TAINT(obj);
|
||||
|
@ -204,7 +230,11 @@ static VALUE object_spec_rb_method_boundp(VALUE self, VALUE obj, VALUE method, V
|
|||
|
||||
#ifdef HAVE_RB_SPECIAL_CONST_P
|
||||
static VALUE object_spec_rb_special_const_p(VALUE self, VALUE value) {
|
||||
return rb_special_const_p(value);
|
||||
if (rb_special_const_p(value)) {
|
||||
return Qtrue;
|
||||
} else {
|
||||
return Qfalse;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -404,6 +434,14 @@ void Init_object_spec(void) {
|
|||
VALUE cls;
|
||||
cls = rb_define_class("CApiObjectSpecs", rb_cObject);
|
||||
|
||||
#ifdef HAVE_FL_ABLE
|
||||
rb_define_method(cls, "FL_ABLE", object_spec_FL_ABLE, 1);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FL_TEST
|
||||
rb_define_method(cls, "FL_TEST", object_spec_FL_TEST, 2);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OBJ_TAINT
|
||||
rb_define_method(cls, "OBJ_TAINT", object_spec_OBJ_TAINT, 1);
|
||||
#endif
|
||||
|
|
|
@ -422,6 +422,7 @@
|
|||
#define HAVE_RB_NUM_COERCE_BIN 1
|
||||
#define HAVE_RB_NUM_COERCE_CMP 1
|
||||
#define HAVE_RB_NUM_COERCE_RELOP 1
|
||||
#define HAVE_RB_ABSINT_SINGLEBIT_P 1
|
||||
#define HAVE_RB_NUM_ZERODIV 1
|
||||
|
||||
/* Fixnum */
|
||||
|
@ -431,6 +432,8 @@
|
|||
#endif
|
||||
|
||||
/* Object */
|
||||
#define HAVE_FL_ABLE 1
|
||||
#define HAVE_FL_TEST 1
|
||||
#define HAVE_OBJ_TAINT 1
|
||||
#define HAVE_OBJ_TAINTED 1
|
||||
#define HAVE_OBJ_INFECT 1
|
||||
|
|
|
@ -429,4 +429,19 @@ describe "CApiNumericSpecs" do
|
|||
lambda { @s.rb_num_coerce_relop(2, obj, :<) }.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
|
||||
describe "rb_absint_singlebit_p" do
|
||||
it "returns 1 if absolute value fits into a bit" do
|
||||
@s.rb_absint_singlebit_p(1).should == 1
|
||||
@s.rb_absint_singlebit_p(2).should == 1
|
||||
@s.rb_absint_singlebit_p(3).should == 0
|
||||
@s.rb_absint_singlebit_p(-1).should == 1
|
||||
@s.rb_absint_singlebit_p(-2).should == 1
|
||||
@s.rb_absint_singlebit_p(-3).should == 0
|
||||
@s.rb_absint_singlebit_p(bignum_value).should == 1
|
||||
@s.rb_absint_singlebit_p(bignum_value(1)).should == 0
|
||||
@s.rb_absint_singlebit_p(-bignum_value).should == 1
|
||||
@s.rb_absint_singlebit_p(-bignum_value(1)).should == 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue