1// Copyright 2011 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package reflectlite_test
6
7import (
8	"bytes"
9	"go/ast"
10	"go/token"
11	. "internal/reflectlite"
12	"io"
13	"testing"
14)
15
16func TestImplicitSetConversion(t *testing.T) {
17	// Assume TestImplicitMapConversion covered the basics.
18	// Just make sure conversions are being applied at all.
19	var r io.Reader
20	b := new(bytes.Buffer)
21	rv := ValueOf(&r).Elem()
22	rv.Set(ValueOf(b))
23	if r != b {
24		t.Errorf("after Set: r=%T(%v)", r, r)
25	}
26}
27
28var implementsTests = []struct {
29	x any
30	t any
31	b bool
32}{
33	{new(*bytes.Buffer), new(io.Reader), true},
34	{new(bytes.Buffer), new(io.Reader), false},
35	{new(*bytes.Buffer), new(io.ReaderAt), false},
36	{new(*ast.Ident), new(ast.Expr), true},
37	{new(*notAnExpr), new(ast.Expr), false},
38	{new(*ast.Ident), new(notASTExpr), false},
39	{new(notASTExpr), new(ast.Expr), false},
40	{new(ast.Expr), new(notASTExpr), false},
41	{new(*notAnExpr), new(notASTExpr), true},
42	{new(mapError), new(error), true},
43	{new(*mapError), new(error), true},
44}
45
46type notAnExpr struct{}
47
48func (notAnExpr) Pos() token.Pos { return token.NoPos }
49func (notAnExpr) End() token.Pos { return token.NoPos }
50func (notAnExpr) exprNode()      {}
51
52type notASTExpr interface {
53	Pos() token.Pos
54	End() token.Pos
55	exprNode()
56}
57
58type mapError map[string]string
59
60func (mapError) Error() string { return "mapError" }
61
62var _ error = mapError{}
63var _ error = new(mapError)
64
65func TestImplements(t *testing.T) {
66	for _, tt := range implementsTests {
67		xv := TypeOf(tt.x).Elem()
68		xt := TypeOf(tt.t).Elem()
69		if b := xv.Implements(xt); b != tt.b {
70			t.Errorf("(%s).Implements(%s) = %v, want %v", TypeString(xv), TypeString(xt), b, tt.b)
71		}
72	}
73}
74
75var assignableTests = []struct {
76	x any
77	t any
78	b bool
79}{
80	{new(chan int), new(<-chan int), true},
81	{new(<-chan int), new(chan int), false},
82	{new(*int), new(IntPtr), true},
83	{new(IntPtr), new(*int), true},
84	{new(IntPtr), new(IntPtr1), false},
85	{new(Ch), new(<-chan any), true},
86	// test runs implementsTests too
87}
88
89type IntPtr *int
90type IntPtr1 *int
91type Ch <-chan any
92
93func TestAssignableTo(t *testing.T) {
94	for i, tt := range append(assignableTests, implementsTests...) {
95		xv := TypeOf(tt.x).Elem()
96		xt := TypeOf(tt.t).Elem()
97		if b := xv.AssignableTo(xt); b != tt.b {
98			t.Errorf("%d:AssignableTo: got %v, want %v", i, b, tt.b)
99		}
100	}
101}
102