// TODO copyright/license package xfmt import ( "fmt" "reflect" "testing" ) // verify formatting result is the same in between std fmt and xfmt func TestXFmt(t *testing.T) { testv := []struct {format, xformatMeth string; value interface{}} { {"%c", "Cb", byte('A')}, {"%c", "C", rune(-1)}, {"%c", "C", 'B'}, // 1-byte encoded {"%c", "C", 'и'}, // 2-bytes encoded {"%c", "C", '\u20ac'}, // 3-bytes encoded {"%c", "C", '\U00010001'}, // 4-bytes encoded // TODO %q qb qr qs qcb qc {"%s", "S", "hello"}, {"%s", "Sb", []byte("world")}, {"%x", "Xb", []byte("hexstring")}, {"%x", "Xs", "stringhex"}, {"%d", "D", 12765}, {"%x", "X", 12789}, {"%016x", "X016", uint64(124)}, // TODO .V } buf := &Buffer{} xbuf := reflect.ValueOf(buf) for _, tt := range testv { // result via fmt resFmt := fmt.Sprintf(tt.format, tt.value) // result via xfmt (via reflect.Call) buf.Reset() xmeth := xbuf.MethodByName(tt.xformatMeth) if !xmeth.IsValid() { t.Errorf(".%v: no such method", tt.xformatMeth) continue } xargv := []reflect.Value{reflect.ValueOf(tt.value)} xretv := []reflect.Value{} callOk := false func () { defer func() { if r := recover(); r != nil { t.Errorf("%v: panic: %v", tt, r) } }() xretv = xmeth.Call(xargv) callOk = true }() if !callOk { continue } // check all formatters return pointer to the same buf // (this way it is handy to do .S("hello ") .X016(123) .V(zzz) ... if !(len(xretv) == 1 && xretv[0].Interface() == buf) { t.Errorf(".%v: returned %#v ; want %#v", tt.xformatMeth, xretv[0].Interface(), buf) continue } resXFmt := string(*buf) // results must be the same if resFmt != resXFmt { t.Errorf(".%v(%v) -> %q != printf(%q) -> %q", tt.xformatMeth, tt.value, resXFmt, tt.format, resFmt) } } }