semver = require 'semver' should = require 'should' printf = require '../lib/printf' describe 'sprintf', -> it 'Specifier: b', -> printf('%b', 123).should.eql '1111011' it 'Flag: (space)', -> printf('% d', 42).should.eql ' 42' printf('% d', -42).should.eql '-42' printf('% 5d', 42).should.eql ' 42' printf('% 5d', -42).should.eql ' -42' printf('% 15d', 42).should.eql ' 42' printf('% 15d', -42).should.eql ' -42' it 'Flag: +', -> printf('%+d', 42).should.eql '+42' printf('%+d', -42).should.eql '-42' printf('%+5d', 42).should.eql ' +42' printf('%+5d', -42).should.eql ' -42' printf('%+15d', 42).should.eql ' +42' printf('%+15d', -42).should.eql ' -42' it 'Flag: 0', -> printf('%0d', 42).should.eql '42' printf('%0d', -42).should.eql '-42' printf('%05d', 42).should.eql '00042' printf('%05d', -42).should.eql '-00042' printf('%015d', 42).should.eql '000000000000042' printf('%015d', -42).should.eql '-000000000000042' it 'Flag: -', -> printf('%-d', 42).should.eql '42' printf('%-d', -42).should.eql '-42' printf('%-5d', 42).should.eql '42 ' printf('%-5d', -42).should.eql '-42 ' printf('%-15d', 42).should.eql '42 ' printf('%-15d', -42).should.eql '-42 ' printf('%-0d', 42).should.eql '42' printf('%-0d', -42).should.eql '-42' printf('%-05d', 42).should.eql '42 ' printf('%-05d', -42).should.eql '-42 ' printf('%-015d', 42).should.eql '42 ' printf('%-015d', -42).should.eql '-42 ' printf('%0-d', 42).should.eql '42' printf('%0-d', -42).should.eql '-42' printf('%0-5d', 42).should.eql '42 ' printf('%0-5d', -42).should.eql '-42 ' printf('%0-15d', 42).should.eql '42 ' printf('%0-15d', -42).should.eql '-42 ' it 'Precision', -> printf('%d', 42.8952).should.eql '42' printf('%.2d', 42.8952).should.eql '42' # Note: the %d format is an int printf('%.2i', 42.8952).should.eql '42' printf('%.2f', 42.8952).should.eql '42.90' printf('%.2F', 42.8952).should.eql '42.90' printf('%.10f', 42.8952).should.eql '42.8952000000' printf('%1.2f', 42.8952).should.eql '42.90' printf('%6.2f', 42.8952).should.eql ' 42.90' printf('%06.2f', 42.8952).should.eql '042.90' printf('%+6.2f', 42.8952).should.eql '+42.90' printf('%5.10f', 42.8952).should.eql '42.8952000000' printf('%1.4g', 1.06800e-10).should.eql '1.068e-10' it 'Bases', -> printf('%c', 0x7f).should.eql '' error = false try printf '%c', -100 catch e e.message.should.eql 'invalid character code passed to %c in printf' error = true error.should.be.true error = false try printf '%c', 0x200000 catch e e.message.should.eql 'invalid character code passed to %c in printf' error = true error.should.be.true it 'Mapping', -> # %1$s format printf('%1$').should.eql '%1$' printf('%0$s').should.eql '%0$s' printf('%1$s %2$s', 'Hot', 'Pocket').should.eql 'Hot Pocket' printf('%1$.1f %2$s %3$ss', 12, 'Hot', 'Pocket').should.eql '12.0 Hot Pockets' printf('%1$*.f', '42', 3).should.eql ' 42' error = false try printf '%2$*s', 'Hot Pocket' catch e e.message.should.eql "got 1 printf arguments, insufficient for '%2$*s'" error = true error.should.be.true # %(map)s format printf('%(foo', {}).should.eql '%(foo' printf('%(temperature)s %(crevace)s', temperature: 'Hot' crevace: 'Pocket' ).should.eql 'Hot Pocket' printf('%(quantity).1f %(temperature)s %(crevace)ss', quantity: 12 temperature: 'Hot' crevace: 'Pocket' ).should.eql '12.0 Hot Pockets' printf('nested values %(nested.foo)s %(nested.bar.baz)d', nested: foo: 'work' bar: baz: 2 ).should.eql 'nested values work 2' error = false try printf '%(foo)s', 42 catch e e.message.should.eql 'format requires a mapping' error = true error.should.be.true error = false try printf '%(foo)s %(bar)s', 'foo', 42 catch e e.message.should.eql 'format requires a mapping' error = true error.should.be.true error = false try printf '%(foo)*s', foo: 'Hot Pocket' catch e e.message.should.eql '* width not supported in mapped formats' error = true error.should.be.true it 'Positionals', -> printf('%*s', 'foo', 4).should.eql ' foo' printf('%*.*f', 3.14159265, 10, 2).should.eql ' 3.14' printf('%0*.*f', 3.14159265, 10, 2).should.eql '0000003.14' printf('%-*.*f', 3.14159265, 10, 2).should.eql '3.14 ' error = false try printf '%*s', 'foo', 'bar' catch e e.message.should.eql 'the argument for * width at position 2 is not a number in %*s' error = true error.should.be.true error = false try printf '%10.*f', 'foo', 42 catch e e.message.should.eql "format argument 'foo' not a float; parseFloat returned NaN" error = true error.should.be.true it 'vs. Formatter', -> i = 0 while i < 1000 printf '%d %s Pockets', i, 'Hot' i++ it 'Formatter', -> str = new printf.Formatter('%d %s Pockets') i = 0 while i < 1000 str.format i, 'Hot' i++ it 'Miscellaneous', -> printf('+%s+', 'hello').should.eql '+hello+' printf('+%d+', 10).should.eql '+10+' printf('%c', 'a').should.eql 'a' printf('%c', 34).should.eql '\"' printf('%c', 36).should.eql '$' printf('%d', 10).should.eql '10' error = false try printf '%s%s', 42 catch e e.message.should.eql "got 1 printf arguments, insufficient for '%s%s'" error = true error.should.be.true error = false try printf '%c' catch e e.message.should.eql "got 0 printf arguments, insufficient for '%c'" error = true error.should.be.true printf('%10', 42).should.eql '%10' it 'Escape', -> printf('%d %', 10).should.eql '10 %' it 'Object inspection', -> test = foo: is: bar: true baz: false isnot: array: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] maybe: undefined printf('%.0O', test).replace(/\s+/g, ' ').should.eql '{ foo: [Object] }' printf('%#O', test.foo.isnot.array).should.eql '[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 ]' # Object inspect serialize object in different order when showHidden is true printf('%+O', test.foo.is).should.eql '{ bar: \u001b[33mtrue\u001b[39m, baz: \u001b[33mfalse\u001b[39m }' return if semver.lt process.version, 'v0.9.0' printf('%O', test).replace(/\s+/g, ' ').should.eql '{ foo: { is: { bar: true, baz: false }, isnot: { array: [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, [length]: 10 ] }, maybe: undefined } }' if semver.lt process.version, 'v8.0.0' then printf('%.2O', test).replace(/\s+/g, ' ').should.eql '{ foo: { is: { bar: true, baz: false }, isnot: { array: [Object] }, maybe: undefined } }' else printf('%.2O', test).replace(/\s+/g, ' ').should.eql '{ foo: { is: { bar: true, baz: false }, isnot: { array: [Array] }, maybe: undefined } }'