// Copyright 2011 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package sql import ( "fmt" "reflect" "testing" ) type conversionTest struct { s, d interface{} // source and destination // following are used if they're non-zero wantint int64 wantuint uint64 wantstr string wanterr string } // Target variables for scanning into. var ( scanstr string scanint int scanint8 int8 scanint16 int16 scanint32 int32 scanuint8 uint8 scanuint16 uint16 ) var conversionTests = []conversionTest{ // Exact conversions (destination pointer type matches source type) {s: "foo", d: &scanstr, wantstr: "foo"}, {s: 123, d: &scanint, wantint: 123}, // To strings {s: []byte("byteslice"), d: &scanstr, wantstr: "byteslice"}, {s: 123, d: &scanstr, wantstr: "123"}, {s: int8(123), d: &scanstr, wantstr: "123"}, {s: int64(123), d: &scanstr, wantstr: "123"}, {s: uint8(123), d: &scanstr, wantstr: "123"}, {s: uint16(123), d: &scanstr, wantstr: "123"}, {s: uint32(123), d: &scanstr, wantstr: "123"}, {s: uint64(123), d: &scanstr, wantstr: "123"}, {s: 1.5, d: &scanstr, wantstr: "1.5"}, // Strings to integers {s: "255", d: &scanuint8, wantuint: 255}, {s: "256", d: &scanuint8, wanterr: `string "256" overflows uint8`}, {s: "256", d: &scanuint16, wantuint: 256}, {s: "-1", d: &scanint, wantint: -1}, {s: "foo", d: &scanint, wanterr: `converting string "foo" to a int: parsing "foo": invalid syntax`}, } func intValue(intptr interface{}) int64 { return reflect.Indirect(reflect.ValueOf(intptr)).Int() } func uintValue(intptr interface{}) uint64 { return reflect.Indirect(reflect.ValueOf(intptr)).Uint() } func TestConversions(t *testing.T) { for n, ct := range conversionTests { err := convertAssign(ct.d, ct.s) errstr := "" if err != nil { errstr = err.Error() } errf := func(format string, args ...interface{}) { base := fmt.Sprintf("convertAssign #%d: for %v (%T) -> %T, ", n, ct.s, ct.s, ct.d) t.Errorf(base+format, args...) } if errstr != ct.wanterr { errf("got error %q, want error %q", errstr, ct.wanterr) } if ct.wantstr != "" && ct.wantstr != scanstr { errf("want string %q, got %q", ct.wantstr, scanstr) } if ct.wantint != 0 && ct.wantint != intValue(ct.d) { errf("want int %d, got %d", ct.wantint, intValue(ct.d)) } if ct.wantuint != 0 && ct.wantuint != uintValue(ct.d) { errf("want uint %d, got %d", ct.wantuint, uintValue(ct.d)) } } } func TestNullableString(t *testing.T) { var ns NullableString convertAssign(&ns, []byte("foo")) if !ns.Valid { t.Errorf("expecting not null") } if ns.String != "foo" { t.Errorf("expecting foo; got %q", ns.String) } convertAssign(&ns, nil) if ns.Valid { t.Errorf("expecting null on nil") } if ns.String != "" { t.Errorf("expecting blank on nil; got %q", ns.String) } }