1require 'test/unit' 2 3class TestSprintf < Test::Unit::TestCase 4 def test_positional 5 assert_equal(" 00001", sprintf("%*1$.*2$3$d", 10, 5, 1)) 6 end 7 8 def test_binary 9 assert_equal("0", sprintf("%b", 0)) 10 assert_equal("1", sprintf("%b", 1)) 11 assert_equal("10", sprintf("%b", 2)) 12 assert_equal("..1", sprintf("%b", -1)) 13 14 assert_equal(" 0", sprintf("%4b", 0)) 15 assert_equal(" 1", sprintf("%4b", 1)) 16 assert_equal(" 10", sprintf("%4b", 2)) 17 assert_equal(" ..1", sprintf("%4b", -1)) 18 19 assert_equal("0000", sprintf("%04b", 0)) 20 assert_equal("0001", sprintf("%04b", 1)) 21 assert_equal("0010", sprintf("%04b", 2)) 22 assert_equal("..11", sprintf("%04b", -1)) 23 24 assert_equal("0000", sprintf("%.4b", 0)) 25 assert_equal("0001", sprintf("%.4b", 1)) 26 assert_equal("0010", sprintf("%.4b", 2)) 27 assert_equal("..11", sprintf("%.4b", -1)) 28 29 assert_equal(" 0000", sprintf("%6.4b", 0)) 30 assert_equal(" 0001", sprintf("%6.4b", 1)) 31 assert_equal(" 0010", sprintf("%6.4b", 2)) 32 assert_equal(" ..11", sprintf("%6.4b", -1)) 33 34 assert_equal(" 0", sprintf("%#4b", 0)) 35 assert_equal(" 0b1", sprintf("%#4b", 1)) 36 assert_equal("0b10", sprintf("%#4b", 2)) 37 assert_equal("0b..1", sprintf("%#4b", -1)) 38 39 assert_equal("0000", sprintf("%#04b", 0)) 40 assert_equal("0b01", sprintf("%#04b", 1)) 41 assert_equal("0b10", sprintf("%#04b", 2)) 42 assert_equal("0b..1", sprintf("%#04b", -1)) 43 44 assert_equal("0000", sprintf("%#.4b", 0)) 45 assert_equal("0b0001", sprintf("%#.4b", 1)) 46 assert_equal("0b0010", sprintf("%#.4b", 2)) 47 assert_equal("0b..11", sprintf("%#.4b", -1)) 48 49 assert_equal(" 0000", sprintf("%#6.4b", 0)) 50 assert_equal("0b0001", sprintf("%#6.4b", 1)) 51 assert_equal("0b0010", sprintf("%#6.4b", 2)) 52 assert_equal("0b..11", sprintf("%#6.4b", -1)) 53 54 assert_equal("+0", sprintf("%+b", 0)) 55 assert_equal("+1", sprintf("%+b", 1)) 56 assert_equal("+10", sprintf("%+b", 2)) 57 assert_equal("-1", sprintf("%+b", -1)) 58 59 assert_equal(" +0", sprintf("%+4b", 0)) 60 assert_equal(" +1", sprintf("%+4b", 1)) 61 assert_equal(" +10", sprintf("%+4b", 2)) 62 assert_equal(" -1", sprintf("%+4b", -1)) 63 64 assert_equal("+000", sprintf("%+04b", 0)) 65 assert_equal("+001", sprintf("%+04b", 1)) 66 assert_equal("+010", sprintf("%+04b", 2)) 67 assert_equal("-001", sprintf("%+04b", -1)) 68 69 assert_equal("+0000", sprintf("%+.4b", 0)) 70 assert_equal("+0001", sprintf("%+.4b", 1)) 71 assert_equal("+0010", sprintf("%+.4b", 2)) 72 assert_equal("-0001", sprintf("%+.4b", -1)) 73 74 assert_equal(" +0000", sprintf("%+6.4b", 0)) 75 assert_equal(" +0001", sprintf("%+6.4b", 1)) 76 assert_equal(" +0010", sprintf("%+6.4b", 2)) 77 assert_equal(" -0001", sprintf("%+6.4b", -1)) 78 end 79 80 def test_nan 81 nan = 0.0 / 0.0 82 assert_equal("NaN", sprintf("%f", nan)) 83 assert_equal("NaN", sprintf("%-f", nan)) 84 assert_equal("+NaN", sprintf("%+f", nan)) 85 86 assert_equal(" NaN", sprintf("%8f", nan)) 87 assert_equal("NaN ", sprintf("%-8f", nan)) 88 assert_equal(" +NaN", sprintf("%+8f", nan)) 89 90 assert_equal(" NaN", sprintf("%08f", nan)) 91 assert_equal("NaN ", sprintf("%-08f", nan)) 92 assert_equal(" +NaN", sprintf("%+08f", nan)) 93 94 assert_equal(" NaN", sprintf("% 8f", nan)) 95 assert_equal(" NaN ", sprintf("%- 8f", nan)) 96 assert_equal(" +NaN", sprintf("%+ 8f", nan)) 97 98 assert_equal(" NaN", sprintf("% 08f", nan)) 99 assert_equal(" NaN ", sprintf("%- 08f", nan)) 100 assert_equal(" +NaN", sprintf("%+ 08f", nan)) 101 end 102 103 def test_inf 104 inf = 1.0 / 0.0 105 assert_equal("Inf", sprintf("%f", inf)) 106 assert_equal("Inf", sprintf("%-f", inf)) 107 assert_equal("+Inf", sprintf("%+f", inf)) 108 109 assert_equal(" Inf", sprintf("%8f", inf)) 110 assert_equal("Inf ", sprintf("%-8f", inf)) 111 assert_equal(" +Inf", sprintf("%+8f", inf)) 112 113 assert_equal(" Inf", sprintf("%08f", inf)) 114 assert_equal("Inf ", sprintf("%-08f", inf)) 115 assert_equal(" +Inf", sprintf("%+08f", inf)) 116 117 assert_equal(" Inf", sprintf("% 8f", inf)) 118 assert_equal(" Inf ", sprintf("%- 8f", inf)) 119 assert_equal(" +Inf", sprintf("%+ 8f", inf)) 120 121 assert_equal(" Inf", sprintf("% 08f", inf)) 122 assert_equal(" Inf ", sprintf("%- 08f", inf)) 123 assert_equal(" +Inf", sprintf("%+ 08f", inf)) 124 125 assert_equal("-Inf", sprintf("%f", -inf)) 126 assert_equal("-Inf", sprintf("%-f", -inf)) 127 assert_equal("-Inf", sprintf("%+f", -inf)) 128 129 assert_equal(" -Inf", sprintf("%8f", -inf)) 130 assert_equal("-Inf ", sprintf("%-8f", -inf)) 131 assert_equal(" -Inf", sprintf("%+8f", -inf)) 132 133 assert_equal(" -Inf", sprintf("%08f", -inf)) 134 assert_equal("-Inf ", sprintf("%-08f", -inf)) 135 assert_equal(" -Inf", sprintf("%+08f", -inf)) 136 137 assert_equal(" -Inf", sprintf("% 8f", -inf)) 138 assert_equal("-Inf ", sprintf("%- 8f", -inf)) 139 assert_equal(" -Inf", sprintf("%+ 8f", -inf)) 140 141 assert_equal(" -Inf", sprintf("% 08f", -inf)) 142 assert_equal("-Inf ", sprintf("%- 08f", -inf)) 143 assert_equal(" -Inf", sprintf("%+ 08f", -inf)) 144 assert_equal('..f00000000', 145 sprintf("%x", -2**32), '[ruby-dev:32351]') 146 assert_equal("..101111111111111111111111111111111", 147 sprintf("%b", -2147483649), '[ruby-dev:32365]') 148 assert_equal(" Inf", sprintf("% e", inf), '[ruby-dev:34002]') 149 end 150 151 def test_invalid 152 # Star precision before star width: 153 assert_raise(ArgumentError, "[ruby-core:11569]") {sprintf("%.**d", 5, 10, 1)} 154 155 # Precision before flags and width: 156 assert_raise(ArgumentError, "[ruby-core:11569]") {sprintf("%.5+05d", 5)} 157 assert_raise(ArgumentError, "[ruby-core:11569]") {sprintf("%.5 5d", 5)} 158 159 # Overriding a star width with a numeric one: 160 assert_raise(ArgumentError, "[ruby-core:11569]") {sprintf("%*1s", 5, 1)} 161 162 # Width before flags: 163 assert_raise(ArgumentError, "[ruby-core:11569]") {sprintf("%5+0d", 1)} 164 assert_raise(ArgumentError, "[ruby-core:11569]") {sprintf("%5 0d", 1)} 165 166 # Specifying width multiple times: 167 assert_raise(ArgumentError, "[ruby-core:11569]") {sprintf("%50+30+20+10+5d", 5)} 168 assert_raise(ArgumentError, "[ruby-core:11569]") {sprintf("%50 30 20 10 5d", 5)} 169 170 # Specifying the precision multiple times with negative star arguments: 171 assert_raise(ArgumentError, "[ruby-core:11570]") {sprintf("%.*.*.*.*f", -1, -1, -1, 5, 1)} 172 173 # Null bytes after percent signs are removed: 174 assert_equal("%\0x hello", sprintf("%\0x hello"), "[ruby-core:11571]") 175 176 assert_raise(ArgumentError, "[ruby-core:11573]") {sprintf("%.25555555555555555555555555555555555555s", "hello")} 177 178 assert_raise(ArgumentError) { sprintf("%\1", 1) } 179 assert_raise(ArgumentError) { sprintf("%!", 1) } 180 assert_raise(ArgumentError) { sprintf("%1$1$d", 1) } 181 assert_raise(ArgumentError) { sprintf("%0%") } 182 verbose, $VERBOSE = $VERBOSE, nil 183 assert_nothing_raised { sprintf("", 1) } 184 ensure 185 $VERBOSE = verbose 186 end 187 188 def test_float 189 assert_equal("36893488147419111424", 190 sprintf("%20.0f", 36893488147419107329.0)) 191 assert_equal(" Inf", sprintf("% 0e", 1.0/0.0), "moved from btest/knownbug") 192 assert_equal(" -0.", sprintf("%#10.0f", -0.5), "[ruby-dev:42552]") 193 assert_equal("0x1p+2", sprintf('%.0a', Float('0x1.fp+1')), "[ruby-dev:42551]") 194 assert_equal("-0x1.0p+2", sprintf('%.1a', Float('-0x1.ffp+1')), "[ruby-dev:42551]") 195 end 196 197 def test_float_hex 198 assert_equal("-0x0p+0", sprintf("%a", -0.0)) 199 assert_equal("0x0p+0", sprintf("%a", 0.0)) 200 assert_equal("0x1p-1", sprintf("%a", 0.5)) 201 assert_equal("0x1p+0", sprintf("%a", 1.0)) 202 assert_equal("0x1p+1", sprintf("%a", 2.0)) 203 assert_equal("0x1p+10", sprintf("%a", 1024)) 204 assert_equal("0x1.23456p+789", sprintf("%a", 3.704450999893983e+237)) 205 assert_equal("0x1p-1074", sprintf("%a", 4.9e-324)) 206 assert_equal("Inf", sprintf("%e", Float::INFINITY)) 207 assert_equal("Inf", sprintf("%E", Float::INFINITY)) 208 assert_equal("NaN", sprintf("%e", Float::NAN)) 209 assert_equal("NaN", sprintf("%E", Float::NAN)) 210 211 assert_equal(" -0x1p+0", sprintf("%10a", -1)) 212 assert_equal(" -0x1.8p+0", sprintf("%10a", -1.5)) 213 assert_equal(" -0x1.4p+0", sprintf("%10a", -1.25)) 214 assert_equal(" -0x1.2p+0", sprintf("%10a", -1.125)) 215 assert_equal(" -0x1.1p+0", sprintf("%10a", -1.0625)) 216 assert_equal("-0x1.08p+0", sprintf("%10a", -1.03125)) 217 218 bug3962 = '[ruby-core:32841]' 219 assert_equal("-0x0001p+0", sprintf("%010a", -1), bug3962) 220 assert_equal("-0x01.8p+0", sprintf("%010a", -1.5), bug3962) 221 assert_equal("-0x01.4p+0", sprintf("%010a", -1.25), bug3962) 222 assert_equal("-0x01.2p+0", sprintf("%010a", -1.125), bug3962) 223 assert_equal("-0x01.1p+0", sprintf("%010a", -1.0625), bug3962) 224 assert_equal("-0x1.08p+0", sprintf("%010a", -1.03125), bug3962) 225 226 bug3964 = '[ruby-core:32848]' 227 assert_equal("0x000000000000000p+0", sprintf("%020a", 0), bug3964) 228 assert_equal("0x000000000000001p+0", sprintf("%020a", 1), bug3964) 229 assert_equal("-0x00000000000001p+0", sprintf("%020a", -1), bug3964) 230 assert_equal("0x00000000000000.p+0", sprintf("%#020a", 0), bug3964) 231 232 bug3965 = '[ruby-dev:42431]' 233 assert_equal("0x1.p+0", sprintf("%#.0a", 1), bug3965) 234 assert_equal("0x00000000000000.p+0", sprintf("%#020a", 0), bug3965) 235 assert_equal("0x0000.0000000000p+0", sprintf("%#020.10a", 0), bug3965) 236 237 bug3979 = '[ruby-dev:42453]' 238 assert_equal(" 0x0.000p+0", sprintf("%20.3a", 0), bug3979) 239 assert_equal(" 0x1.000p+0", sprintf("%20.3a", 1), bug3979) 240 end 241 242 BSIZ = 120 243 244 def test_skip 245 assert_equal(" " * BSIZ + "1", sprintf(" " * BSIZ + "%d", 1)) 246 end 247 248 def test_char 249 assert_equal("a", sprintf("%c", 97)) 250 assert_equal("a", sprintf("%c", ?a)) 251 assert_raise(ArgumentError) { sprintf("%c", sprintf("%c%c", ?a, ?a)) } 252 assert_equal(" " * (BSIZ - 1) + "a", sprintf(" " * (BSIZ - 1) + "%c", ?a)) 253 assert_equal(" " * (BSIZ - 1) + "a", sprintf(" " * (BSIZ - 1) + "%-1c", ?a)) 254 assert_equal(" " * BSIZ + "a", sprintf("%#{ BSIZ + 1 }c", ?a)) 255 assert_equal("a" + " " * BSIZ, sprintf("%-#{ BSIZ + 1 }c", ?a)) 256 end 257 258 def test_string 259 assert_equal("foo", sprintf("%s", "foo")) 260 assert_equal("fo", sprintf("%.2s", "foo")) 261 assert_equal(" " * BSIZ, sprintf("%s", " " * BSIZ)) 262 assert_equal(" " * (BSIZ - 1) + "foo", sprintf("%#{ BSIZ - 1 + 3 }s", "foo")) 263 assert_equal(" " * BSIZ + "foo", sprintf("%#{ BSIZ + 3 }s", "foo")) 264 assert_equal("foo" + " " * BSIZ, sprintf("%-#{ BSIZ + 3 }s", "foo")) 265 end 266 267 def test_integer 268 assert_equal("01", sprintf("%#o", 1)) 269 assert_equal("0x1", sprintf("%#x", 1)) 270 assert_equal("0X1", sprintf("%#X", 1)) 271 assert_equal("0b1", sprintf("%#b", 1)) 272 assert_equal("0B1", sprintf("%#B", 1)) 273 assert_equal("1", sprintf("%d", 1.0)) 274 assert_equal("4294967296", sprintf("%d", (2**32).to_f)) 275 assert_equal("-2147483648", sprintf("%d", -(2**31).to_f)) 276 assert_equal("18446744073709551616", sprintf("%d", (2**64).to_f)) 277 assert_equal("-9223372036854775808", sprintf("%d", -(2**63).to_f)) 278 assert_equal("1", sprintf("%d", "1")) 279 o = Object.new; def o.to_int; 1; end 280 assert_equal("1", sprintf("%d", o)) 281 assert_equal("+1", sprintf("%+d", 1)) 282 assert_equal(" 1", sprintf("% d", 1)) 283 assert_equal("..f", sprintf("%x", -1)) 284 assert_equal("..7", sprintf("%o", -1)) 285 one = (2**32).coerce(1).first 286 mone = (2**32).coerce(-1).first 287 assert_equal("+1", sprintf("%+d", one)) 288 assert_equal(" 1", sprintf("% d", one)) 289 assert_equal("..f", sprintf("%x", mone)) 290 assert_equal("..7", sprintf("%o", mone)) 291 assert_equal(" " * BSIZ + "1", sprintf("%#{ BSIZ + 1 }d", one)) 292 assert_equal(" " * (BSIZ - 1) + "1", sprintf(" " * (BSIZ - 1) + "%d", 1)) 293 end 294 295 def test_float2 296 inf = 1.0 / 0.0 297 assert_equal(" " * BSIZ + "Inf", sprintf("%#{ BSIZ + 3 }.1f", inf)) 298 assert_equal("+Inf", sprintf("%+-f", inf)) 299 assert_equal(" " * BSIZ + "1.0", sprintf("%#{ BSIZ + 3 }.1f", 1.0)) 300 end 301 302 class T012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 303 end 304 305 def test_star 306 assert_equal("-1 ", sprintf("%*d", -3, -1)) 307 end 308 309 def test_escape 310 assert_equal("%" * BSIZ, sprintf("%%" * BSIZ)) 311 end 312 313 def test_rb_sprintf 314 assert_match(/^#<TestSprintf::T012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789:0x[0-9a-f]+>$/, 315 T012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789.new.inspect) 316 end 317 318 def test_negative_hex 319 s1 = sprintf("%0x", -0x40000000) 320 s2 = sprintf("%0x", -0x40000001) 321 b1 = (/\.\./ =~ s1) != nil 322 b2 = (/\.\./ =~ s2) != nil 323 assert(b1 == b2, "[ruby-dev:33224]") 324 end 325 326 def test_named_untyped 327 assert_equal("value", sprintf("%<key>s", :key => "value")) 328 e = assert_raise(ArgumentError) {sprintf("%1$<key2>s", :key => "value")} 329 assert_equal("named<key2> after numbered", e.message) 330 e = assert_raise(ArgumentError) {sprintf("%s%s%<key2>s", "foo", "bar", :key => "value")} 331 assert_equal("named<key2> after unnumbered(2)", e.message) 332 e = assert_raise(ArgumentError) {sprintf("%<key><key2>s", :key => "value")} 333 assert_equal("named<key2> after <key>", e.message) 334 e = assert_raise(KeyError) {sprintf("%<key>s", {})} 335 assert_equal("key<key> not found", e.message) 336 end 337 338 def test_named_untyped_enc 339 key = "\u{3012}" 340 [Encoding::UTF_8, Encoding::EUC_JP].each do |enc| 341 k = key.encode(enc) 342 e = assert_raise(ArgumentError) {sprintf("%1$<#{k}>s", key: "value")} 343 assert_equal(enc, e.message.encoding) 344 assert_equal("named<#{k}> after numbered", e.message) 345 e = assert_raise(ArgumentError) {sprintf("%s%s%<#{k}>s", "foo", "bar", key: "value")} 346 assert_equal(enc, e.message.encoding) 347 assert_equal("named<#{k}> after unnumbered(2)", e.message) 348 e = assert_raise(ArgumentError) {sprintf("%<key><#{k}>s", key: "value")} 349 assert_equal(enc, e.message.encoding) 350 assert_equal("named<#{k}> after <key>", e.message) 351 e = assert_raise(ArgumentError) {sprintf("%<#{k}><key>s", k.to_sym => "value")} 352 assert_equal(enc, e.message.encoding) 353 assert_equal("named<key> after <#{k}>", e.message) 354 e = assert_raise(KeyError) {sprintf("%<#{k}>s", {})} 355 assert_equal(enc, e.message.encoding) 356 assert_equal("key<#{k}> not found", e.message) 357 end 358 end 359 360 def test_named_typed 361 assert_equal("value", sprintf("%{key}", :key => "value")) 362 e = assert_raise(ArgumentError) {sprintf("%1${key2}", :key => "value")} 363 assert_equal("named{key2} after numbered", e.message) 364 e = assert_raise(ArgumentError) {sprintf("%s%s%{key2}", "foo", "bar", :key => "value")} 365 assert_equal("named{key2} after unnumbered(2)", e.message) 366 e = assert_raise(ArgumentError) {sprintf("%<key>{key2}", :key => "value")} 367 assert_equal("named{key2} after <key>", e.message) 368 assert_equal("value{key2}", sprintf("%{key}{key2}", :key => "value")) 369 e = assert_raise(KeyError) {sprintf("%{key}", {})} 370 assert_equal("key{key} not found", e.message) 371 end 372 373 def test_named_typed_enc 374 key = "\u{3012}" 375 [Encoding::UTF_8, Encoding::EUC_JP].each do |enc| 376 k = key.encode(enc) 377 e = assert_raise(ArgumentError) {sprintf("%1${#{k}}s", key: "value")} 378 assert_equal(enc, e.message.encoding) 379 assert_equal("named{#{k}} after numbered", e.message) 380 e = assert_raise(ArgumentError) {sprintf("%s%s%{#{k}}s", "foo", "bar", key: "value")} 381 assert_equal(enc, e.message.encoding) 382 assert_equal("named{#{k}} after unnumbered(2)", e.message) 383 e = assert_raise(ArgumentError) {sprintf("%<key>{#{k}}s", key: "value")} 384 assert_equal(enc, e.message.encoding) 385 assert_equal("named{#{k}} after <key>", e.message) 386 e = assert_raise(ArgumentError) {sprintf("%<#{k}>{key}s", k.to_sym => "value")} 387 assert_equal(enc, e.message.encoding) 388 assert_equal("named{key} after <#{k}>", e.message) 389 e = assert_raise(KeyError) {sprintf("%{#{k}}", {})} 390 assert_equal(enc, e.message.encoding) 391 assert_equal("key{#{k}} not found", e.message) 392 end 393 end 394end 395