$print __SRC {/** Buffer.appendf() tests...*/}

var testCount = 0
var verbose = ARGV.flags.verbose || ARGV.flags.v || false;
scope {

    const fmt = proc(fmt){
        //print(__SRC, '@argv =',  @argv)
        //return
        //assert 'string' === typename fmt
        const b = argv.callee.buffer
        [b.length 0]
        //[b.appendf @argv]
        [b.appendf.apply b argv]
        const rc = [b.toString]
        verbose && [print 'format args:\t' fmt '\n==> \t' rc]
        return rc
    }
    fmt.buffer = [api.Buffer 100]

    const av = array[ 42, "string formatter", "abcde",
        19.17, true, false, -13.19]
    verbose && [print __SRC 'value list for formatter =' av]
    const check = proc(cmp){
        //print(__SRC, '@argv =',  @argv)
        //assert [argv.length] > 1 /* catches when i try to pass a -N without parens around it */
        [argv.shift]
        //print(__SRC, '@argv =',  @argv)
        const s = [fmt.apply fmt argv]
        (s===cmp) || throw ("Mismatch: <<<"+cmp+">>> !== <<<" +s+">>>")
        testCount += 1
    }
    [check {%} '%%']
    [check {%x%y} '%%x%%y']

    [check {hi, world} "%1$s" {hi, world}]
    [check {hi, world (           hi, world)}
        "%1$s (%1$20s)" {hi, world}]
    [check {integer 42 042 02A 002a}
        "%1$y %1$d %1$03d %1$03X %1$04x" av.0]
    [check {(        42) (42        )}
        "(%1$10d) (%1$-10d)" av.0]
    [check {(       +42) (+42       )}
        "(%1$+10d) (%1$+-10d)" av.0]
    [check {00042} "%1$05d" av.0]
    [check {42.00000} "%1$0.5f" av.0]
    [check {string formatter}
        "%2$s" 0 av.1]
    [check {string}
        "%2$.6s" 0 av.1]
    [check {string formatter and string formatter}
        "%2$s and %2$s" 0 av.1]
    [check {(abcde     ) (     abcde)}
        "(%3$-10s) (%3$10s)" 0 0 av.2]
    [check {(     abcde) (abcde     )}
        "(%3$10s) (%3$-10s)" 0 0 av.2]
    [check {(       abc) (abc       )}
        "(%3$10.3s) (%3$-10.3s)" 0 0 av.2]
    [check {(abc       ) (       abc)}
        "(%3$-10.3s) (%3$10.3s)" 0 0 av.2]
    [check {(abcd) (abcd    )} 
        "(%3$.4s) (%3$-8.4s)" 0 0 av.2]
    [check {19.17 19.2 19.17 19.170}
        "%4$f %4$.1f %4$.2f %4$.3f" 0 0 0 av.3]
    [check {+19.17 (19.170    ) (    19.170) (+00019.170)}
        "%4$+0f (%4$-10.3f) (%4$10.3f) (%4$+010.3f)" 0 0 0 av.3]
    [check {1 true false null undefined}
        "%5$d %5$b %6$b %5$N %5$U" 0 0 0 0 av.4 av.5]
    [check {0.0} "%6$+f" 0 0 0 0 0 av.5]
    [check {-13.19} "%7$+f" 0 0 0 0 0 0 av.6]
    [fmt " %1$p = %1$d" av.0]
    assert catch{[fmt "%8$+f" 0]}
    true, true, true, true, true /* watch the above exception get auto-swept.
                But why are _two_ values being swept up? */
    [fmt " %1$p = %1$s" "temp string"]
    [check {68692C20776F726C64}
        "%1$B" "hi, world"]
    [check {68692C20}
        "%1$.4B" "hi, world"]
    [check '                     68692C20776F726C64'
        "%1$30B" "hi, world"]
    [check 'PathFinder' '%1$y' api.prototypes.PathFinder]

    //print('@av =',  @av)
    // WTF? @expando is failing to expand here?
    //fmt("%1$y %1$p %1$d %1$03d %1$03X %1$04x",@av)
    // But not here:
    //print('@av =',  @av)
    // But here:
    //fmt('@av =',  @av)
    // and yet func param processing does not differentiate between script and native functions!

    [check {-1.0} '%1$.1f' (-1.02)] // LOL: don't forget the parens around the float!
    [check {+1.0} '%1$+.1f' 1.02]

    [check {-1} {%1$d} (-1)]
    [check {-1} {%1$+d} (-1)]
    [check {+1} {%1$+d} 1]

    [check {h} {%1$c} {hi}]
    [check '     hhhhh' {%1$10.5c} {hi}]
    [check 'hhhhh     ' {%1$-10.5c} {hi}]
    [check '  ©' {%1$3c} '©']
    [check '©©©' {%1$0.3c} '©']
    [check '©©©  ' {%1$-5.3c} '©']
    [check '  ©©©' {%1$5.3c} '©']
    [check 'A' {%1$c} 65]
    [check 'AAAA' {%1$.4c} 65]
    [check {10} {%1$o} 8]
    [check {0010} {%1$04o} 8]
    [check '  10' {%1$4o} 8]
    assert '1 2 3' === ["%1$d %2$d %3$d".applyFormat 1 2 3]
    [check {(NULL)} {%1$q} null]
    [check {h''i} {%1$q} "h'i"]
    [check {NULL} {%1$Q} null]
    [check {'h''i'} {%1$Q} "h'i"]

    assert catch{[check {bad format string} {$1%s} "hi"]} inherits api.Exception

    [fmt '[%1$3c] [%1$0.3c] [%1$-5.3c]' '©']
    [fmt '%%J says: %1$J' av]
    [fmt '%%2J says: %1$2J' av]
    [fmt '%%-1J says: %1$-1J' av]

}

0 && scope {
    const formatString = proc(fmt){
        const b = argv.callee.buffer
        //[b.appendf @argv]
        [b.appendf.apply b argv]
        const rc = [b.toString]
        [b.length 0]
        return rc
    }
    formatString.buffer = [api.Buffer 100]
    api.Buffer.fmt = formatString
    //[print [api.Buffer.fmt '%1$s' 'api.Buffer.fmt call']]
}

scope {
    //print(object{a:"hi",b:true}.toJSONString(8))
    assert {{"a": "hi"}} === [object{a:"hi"}.toJSONString]
    assert {"hi\tthere"} === ["hi	there".toJSONString]
    assert {["hi", 1, null]} === [array["hi",1,null].toJSONString]
    assert {13} === [13.toJSONString]
    assert {12.3} === [12.3.toJSONString]

    0 && scope {
        var buf = [api.Buffer 100]
        var indent = 2
        buf.toJSONString(object{a:13,b:true}, indent)
        buf.append('\n')
        buf.toJSONString(array[1,2,3], indent)
        buf.append('\n')
        buf.toJSONString(1)
        buf.append('\n')
        buf.toJSONString(1.37)
        print(buf.toString())
    }
}

scope {
    var b= [api.Buffer 5000]
    [b.readFile __FILE]
    [b.writeToFile __FILE+'.2']
}

scope {
    var b = api.Buffer.readFile(__FILE)
    assert 'buffer' === typename b
    assert b inherits api.Buffer
    assert b !== api.Buffer
    assert "%1$p".applyFormat(b) !== "%1$p".applyFormat(,api.Buffer)

    var x = api.Buffer.readFile(__FILE)
    x.append("change")
    assert b !== x
    assert "%1$p".applyFormat(b) !== "%1$p".applyFormat(x)

    b.reset()
    var c = b.readFile(__FILE)
    c.append("change")
    assert c === b
    assert "%1$p".applyFormat(b) === "%1$p".applyFormat(c)

    // print(typename b("???")) // WHAT exactly is this calling?
    assert b inherits api.prototypes.Function
    //return b
}

[print "Done running" testCount "Buffer.format() assertions."]
