mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
combinational tests for printf.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@15227 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
2fc0fe5332
commit
a470a2f1e1
1 changed files with 300 additions and 0 deletions
300
test/ruby/test_sprintf_comb.rb
Normal file
300
test/ruby/test_sprintf_comb.rb
Normal file
|
@ -0,0 +1,300 @@
|
|||
require 'test/unit'
|
||||
|
||||
class TestSprintfComb < Test::Unit::TestCase
|
||||
VS = [
|
||||
#-0x1000000000000000000000000000000000000000000000002,
|
||||
#-0x1000000000000000000000000000000000000000000000001,
|
||||
#-0x1000000000000000000000000000000000000000000000000,
|
||||
#-0xffffffffffffffffffffffffffffffffffffffffffffffff,
|
||||
#-0x1000000000000000000000002,
|
||||
#-0x1000000000000000000000001,
|
||||
#-0x1000000000000000000000000,
|
||||
#-0xffffffffffffffffffffffff,
|
||||
-0x10000000000000002,
|
||||
-0x10000000000000001,
|
||||
-0x10000000000000000,
|
||||
-0xffffffffffffffff,
|
||||
-0x4000000000000002,
|
||||
-0x4000000000000001,
|
||||
-0x4000000000000000,
|
||||
-0x3fffffffffffffff,
|
||||
-0x100000002,
|
||||
-0x100000001,
|
||||
-0x100000000,
|
||||
-0xffffffff,
|
||||
#-0xc717a08d, # 0xc717a08d * 0x524b2245 = 0x4000000000000001
|
||||
-0x80000002,
|
||||
-0x80000001,
|
||||
-0x80000000,
|
||||
-0x7fffffff,
|
||||
#-0x524b2245,
|
||||
-0x40000002,
|
||||
-0x40000001,
|
||||
-0x40000000,
|
||||
-0x3fffffff,
|
||||
#-0x10002,
|
||||
#-0x10001,
|
||||
#-0x10000,
|
||||
#-0xffff,
|
||||
#-0x8101, # 0x8101 * 0x7f01 = 0x40000001
|
||||
#-0x8002,
|
||||
#-0x8001,
|
||||
#-0x8000,
|
||||
#-0x7fff,
|
||||
#-0x7f01,
|
||||
#-65,
|
||||
#-64,
|
||||
#-63,
|
||||
#-62,
|
||||
#-33,
|
||||
#-32,
|
||||
#-31,
|
||||
#-30,
|
||||
-3,
|
||||
-2,
|
||||
-1,
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
#30,
|
||||
#31,
|
||||
#32,
|
||||
#33,
|
||||
#62,
|
||||
#63,
|
||||
#64,
|
||||
#65,
|
||||
#0x7f01,
|
||||
#0x7ffe,
|
||||
#0x7fff,
|
||||
#0x8000,
|
||||
#0x8001,
|
||||
#0x8101,
|
||||
#0xfffe,
|
||||
#0xffff,
|
||||
#0x10000,
|
||||
#0x10001,
|
||||
0x3ffffffe,
|
||||
0x3fffffff,
|
||||
0x40000000,
|
||||
0x40000001,
|
||||
#0x524b2245,
|
||||
0x7ffffffe,
|
||||
0x7fffffff,
|
||||
0x80000000,
|
||||
0x80000001,
|
||||
#0xc717a08d,
|
||||
0xfffffffe,
|
||||
0xffffffff,
|
||||
0x100000000,
|
||||
0x100000001,
|
||||
0x3ffffffffffffffe,
|
||||
0x3fffffffffffffff,
|
||||
0x4000000000000000,
|
||||
0x4000000000000001,
|
||||
0xfffffffffffffffe,
|
||||
0xffffffffffffffff,
|
||||
0x10000000000000000,
|
||||
0x10000000000000001,
|
||||
#0xffffffffffffffffffffffff,
|
||||
#0x1000000000000000000000000,
|
||||
#0x1000000000000000000000001,
|
||||
#0xffffffffffffffffffffffffffffffffffffffffffffffff,
|
||||
#0x1000000000000000000000000000000000000000000000000,
|
||||
#0x1000000000000000000000000000000000000000000000001
|
||||
]
|
||||
VS.reverse!
|
||||
|
||||
def combination(*args)
|
||||
if args.empty?
|
||||
yield []
|
||||
else
|
||||
arg = args.shift
|
||||
arg.each {|v|
|
||||
combination(*args) {|vs|
|
||||
yield [v, *vs]
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def emu(format, v)
|
||||
/\A%( )?(\#)?(\+)?(-)?(0)?(\d+)?(?:\.(\d+))?(.)\z/ =~ format
|
||||
sp = $1
|
||||
hs = $2
|
||||
pl = $3
|
||||
mi = $4
|
||||
zr = $5
|
||||
width = $6
|
||||
precision = $7
|
||||
type = $8
|
||||
width = width.to_i if width
|
||||
precision = precision.to_i if precision
|
||||
prefix = ''
|
||||
|
||||
zr = nil if precision
|
||||
|
||||
zr = nil if mi && zr
|
||||
|
||||
case type
|
||||
when 'b'
|
||||
radix = 2
|
||||
digitmap = {0 => '0', 1 => '1'}
|
||||
complement = !pl && !sp
|
||||
prefix = '0b' if hs
|
||||
when 'd'
|
||||
radix = 10
|
||||
digitmap = {}
|
||||
10.times {|i| digitmap[i] = i.to_s }
|
||||
complement = false
|
||||
when 'o'
|
||||
radix = 8
|
||||
digitmap = {}
|
||||
8.times {|i| digitmap[i] = i.to_s }
|
||||
complement = !pl && !sp
|
||||
when 'X'
|
||||
radix = 16
|
||||
digitmap = {}
|
||||
16.times {|i| digitmap[i] = i.to_s(16).upcase }
|
||||
complement = !pl && !sp
|
||||
prefix = '0X' if hs
|
||||
when 'x'
|
||||
radix = 16
|
||||
digitmap = {}
|
||||
16.times {|i| digitmap[i] = i.to_s(16) }
|
||||
complement = !pl && !sp
|
||||
prefix = '0x' if hs
|
||||
else
|
||||
raise "unexpected type: #{type.inspect}"
|
||||
end
|
||||
|
||||
digits = []
|
||||
abs = v.abs
|
||||
sign = ''
|
||||
while 0 < abs
|
||||
digits << (abs % radix)
|
||||
abs /= radix
|
||||
end
|
||||
|
||||
if v < 0
|
||||
if complement
|
||||
digits.map! {|d| radix-1 - d }
|
||||
carry = 1
|
||||
digits.each_index {|i|
|
||||
digits[i] += carry
|
||||
carry = 0
|
||||
if radix <= digits[i]
|
||||
digits[i] -= radix
|
||||
carry = 1
|
||||
end
|
||||
}
|
||||
if digits.last != radix-1
|
||||
digits << (radix-1)
|
||||
end
|
||||
sign = '..'
|
||||
else
|
||||
sign = '-'
|
||||
end
|
||||
else
|
||||
if pl
|
||||
sign = '+'
|
||||
elsif sp
|
||||
sign = ' '
|
||||
end
|
||||
end
|
||||
|
||||
dlen = digits.length
|
||||
dlen += 2 if sign == '..'
|
||||
|
||||
if v < 0 && complement
|
||||
d = radix - 1
|
||||
else
|
||||
d = 0
|
||||
end
|
||||
if precision
|
||||
if dlen < precision
|
||||
(precision - dlen).times {
|
||||
digits << d
|
||||
}
|
||||
end
|
||||
else
|
||||
if dlen == 0
|
||||
digits << d
|
||||
end
|
||||
end
|
||||
if type == 'o' && hs
|
||||
if digits.empty? || digits.last != d
|
||||
digits << d
|
||||
end
|
||||
end
|
||||
|
||||
digits.reverse!
|
||||
|
||||
str = digits.map {|d| digitmap[d] }.join
|
||||
|
||||
pad = ''
|
||||
nlen = prefix.length + sign.length + str.length
|
||||
if width && nlen < width
|
||||
len = width - nlen
|
||||
if zr
|
||||
if complement && v < 0
|
||||
pad = digitmap[radix-1] * len
|
||||
else
|
||||
pad = '0' * len
|
||||
end
|
||||
else
|
||||
pad = ' ' * len
|
||||
end
|
||||
end
|
||||
|
||||
if / / =~ pad
|
||||
if sign == '..'
|
||||
str = prefix + sign + str
|
||||
else
|
||||
str = sign + prefix + str
|
||||
end
|
||||
if mi
|
||||
str = str + pad
|
||||
else
|
||||
str = pad + str
|
||||
end
|
||||
else
|
||||
if sign == '..'
|
||||
str = prefix + sign + pad + str
|
||||
else
|
||||
str = sign + prefix + pad + str
|
||||
end
|
||||
end
|
||||
|
||||
str
|
||||
end
|
||||
|
||||
def test_format
|
||||
combination(
|
||||
%w[b d o X x],
|
||||
[nil, 0, 5, 20],
|
||||
[nil, 0, 8, 20],
|
||||
['', ' '],
|
||||
['', '#'],
|
||||
['', '+'],
|
||||
['', '-'],
|
||||
['', '0']) {|type, width, precision, sp, hs, pl, mi, zr|
|
||||
if precision
|
||||
precision = ".#{precision}"
|
||||
end
|
||||
format = "%#{sp}#{hs}#{pl}#{mi}#{zr}#{width}#{precision}#{type}"
|
||||
VS.each {|v|
|
||||
r = sprintf format, v
|
||||
e = emu format, v
|
||||
if true
|
||||
assert_equal(e, r, "sprintf(#{format.dump}, #{v})")
|
||||
else
|
||||
if e != r
|
||||
puts "#{e.dump}\t#{r.dump}\tsprintf(#{format.dump}, #{v})"
|
||||
end
|
||||
end
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue