1// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
2//
3// Use of this source code is governed by an MIT-style
4// license that can be found in the LICENSE file.
5
6// +build cgo
7
8package sqlite3
9
10import (
11	"errors"
12	"math"
13	"reflect"
14	"testing"
15)
16
17func TestCallbackArgCast(t *testing.T) {
18	intConv := callbackSyntheticForTests(reflect.ValueOf(int64(math.MaxInt64)), nil)
19	floatConv := callbackSyntheticForTests(reflect.ValueOf(float64(math.MaxFloat64)), nil)
20	errConv := callbackSyntheticForTests(reflect.Value{}, errors.New("test"))
21
22	tests := []struct {
23		f callbackArgConverter
24		o reflect.Value
25	}{
26		{intConv, reflect.ValueOf(int8(-1))},
27		{intConv, reflect.ValueOf(int16(-1))},
28		{intConv, reflect.ValueOf(int32(-1))},
29		{intConv, reflect.ValueOf(uint8(math.MaxUint8))},
30		{intConv, reflect.ValueOf(uint16(math.MaxUint16))},
31		{intConv, reflect.ValueOf(uint32(math.MaxUint32))},
32		// Special case, int64->uint64 is only 1<<63 - 1, not 1<<64 - 1
33		{intConv, reflect.ValueOf(uint64(math.MaxInt64))},
34		{floatConv, reflect.ValueOf(float32(math.Inf(1)))},
35	}
36
37	for _, test := range tests {
38		conv := callbackArgCast{test.f, test.o.Type()}
39		val, err := conv.Run(nil)
40		if err != nil {
41			t.Errorf("Couldn't convert to %s: %s", test.o.Type(), err)
42		} else if !reflect.DeepEqual(val.Interface(), test.o.Interface()) {
43			t.Errorf("Unexpected result from converting to %s: got %v, want %v", test.o.Type(), val.Interface(), test.o.Interface())
44		}
45	}
46
47	conv := callbackArgCast{errConv, reflect.TypeOf(int8(0))}
48	_, err := conv.Run(nil)
49	if err == nil {
50		t.Errorf("Expected error during callbackArgCast, but got none")
51	}
52}
53
54func TestCallbackConverters(t *testing.T) {
55	tests := []struct {
56		v   interface{}
57		err bool
58	}{
59		// Unfortunately, we can't tell which converter was returned,
60		// but we can at least check which types can be converted.
61		{[]byte{0}, false},
62		{"text", false},
63		{true, false},
64		{int8(0), false},
65		{int16(0), false},
66		{int32(0), false},
67		{int64(0), false},
68		{uint8(0), false},
69		{uint16(0), false},
70		{uint32(0), false},
71		{uint64(0), false},
72		{int(0), false},
73		{uint(0), false},
74		{float64(0), false},
75		{float32(0), false},
76
77		{func() {}, true},
78		{complex64(complex(0, 0)), true},
79		{complex128(complex(0, 0)), true},
80		{struct{}{}, true},
81		{map[string]string{}, true},
82		{[]string{}, true},
83		{(*int8)(nil), true},
84		{make(chan int), true},
85	}
86
87	for _, test := range tests {
88		_, err := callbackArg(reflect.TypeOf(test.v))
89		if test.err && err == nil {
90			t.Errorf("Expected an error when converting %s, got no error", reflect.TypeOf(test.v))
91		} else if !test.err && err != nil {
92			t.Errorf("Expected converter when converting %s, got error: %s", reflect.TypeOf(test.v), err)
93		}
94	}
95
96	for _, test := range tests {
97		_, err := callbackRet(reflect.TypeOf(test.v))
98		if test.err && err == nil {
99			t.Errorf("Expected an error when converting %s, got no error", reflect.TypeOf(test.v))
100		} else if !test.err && err != nil {
101			t.Errorf("Expected converter when converting %s, got error: %s", reflect.TypeOf(test.v), err)
102		}
103	}
104}
105