Commit 57927121 authored by Kirill Smelkov's avatar Kirill Smelkov

Make Bytes and unicode to be distinguishable from string in test errors

For example currently if result of decoding is expected to be unicode,
but is actually string the following confusing error is generated with
exactly the same have and want:

    --- FAIL: TestDecode/unicode(non-utf8)/"X\x01\x00\x00\x00\x93." (0.00s)
        ogorek_test.go:504: decode:
            have: "\x93"
            want: "\x93"

This happens because by default Printf("%#v") does not emit object type
even if it was derived type from builtin string - either our Bytes or
unicode, and emits the same string representation irregardless of which
type it is.

I think out-of-the box behaviour of %#v is unreasonable, but it is there
for a long time and so instead of trying to argue with Go upstream,
which after many years of arguing I think is not practical, teach our
Bytes and unicode types how to represent themselves under %#v with
indicating their type in the output.

After the fix the error from above becomes

    --- FAIL: TestDecode/unicode(non-utf8)/"X\x01\x00\x00\x00\x93." (0.00s)
        ogorek_test.go:504: decode:
            have: "\x93"
            want: ogórek.unicode("\x93")

which is more clear because want is different from have.

Adjusted behaviour is not test-only, because user applications might
want to do the same %#v at application level and there it would be also
confusing not to see a type.
parent 9913a56c
......@@ -132,6 +132,16 @@ type Tuple []interface{}
// Bytes represents Python's bytes.
type Bytes string
// make Bytes and unicode to be represented by %#v distinctly from string
// (without GoString %#v emits just "..." for all string, Bytes and unicode)
func (v Bytes) GoString() string {
return fmt.Sprintf("%T(%#v)", v, string(v))
}
func (v unicode) GoString() string {
return fmt.Sprintf("%T(%#v)", v, string(v))
}
// Decoder is a decoder for pickle streams.
type Decoder struct {
r *bufio.Reader
......
......@@ -957,6 +957,24 @@ func TestUnquoteCharEOF(t *testing.T) {
}
}
func TestStringsFmt(t *testing.T) {
tvhash := []struct{
in interface{}
vhashok string
}{
{"мир", `"мир"`},
{Bytes("мир"), `ogórek.Bytes("мир")`},
{unicode("мир"), `ogórek.unicode("мир")`},
}
for _, tt := range tvhash {
vhash := fmt.Sprintf("%#v", tt.in)
if vhash != tt.vhashok {
t.Errorf("%T %q: %%#v:\nhave: %s\nwant: %s", tt.in, tt.in, vhash, tt.vhashok)
}
}
}
// like io.LimitedReader but for writes
// XXX it would be good to have it in stdlib
type LimitedWriter struct {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment