GoPLS Viewer

Home|gopls/internal/typeparams/normalize_test.go
1// Copyright 2021 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 typeparams_test
6
7import (
8    "go/ast"
9    "go/parser"
10    "go/token"
11    "go/types"
12    "regexp"
13    "strings"
14    "testing"
15
16    "golang.org/x/tools/internal/typeparams"
17    . "golang.org/x/tools/internal/typeparams"
18)
19
20func TestStructuralTerms(t *testing.T) {
21    if !Enabled {
22        t.Skip("typeparams are not enabled")
23    }
24
25    // In the following tests, src must define a type T with (at least) one type
26    // parameter. We will compute the structural terms of the first type
27    // parameter.
28    tests := []struct {
29        src       string
30        want      string
31        wantError string
32    }{
33        {"package emptyinterface0; type T[P interface{}] int""all"""},
34        {"package emptyinterface1; type T[P interface{ int | interface{} }] int""all"""},
35        {"package singleton; type T[P interface{ int }] int""int"""},
36        {"package under; type T[P interface{~int}] int""~int"""},
37        {"package superset; type T[P interface{ ~int | int }] int""~int"""},
38        {"package overlap; type T[P interface{ ~int; int }] int""int"""},
39        {"package emptyintersection; type T[P interface{ ~int; string }] int""""empty type set"},
40
41        {"package embedded0; type T[P interface{ I }] int; type I interface { int }""int"""},
42        {"package embedded1; type T[P interface{ I | string }] int; type I interface{ int | ~string }""int ?\\| ?~string"""},
43        {"package embedded2; type T[P interface{ I; string }] int; type I interface{ int | ~string }""string"""},
44
45        {"package named; type T[P C] int; type C interface{ ~int|int }""~int"""},
46        {`// package example is taken from the docstring for StructuralTerms
47package example
48
49type A interface{ ~string|~[]byte }
50
51type B interface{ int|string }
52
53type C interface { ~string|~int }
54
55type T[P interface{ A|B; C }] int
56`"~string ?\\| ?int"""},
57    }
58
59    for _test := range tests {
60        fset := token.NewFileSet()
61        ferr := parser.ParseFile(fset"p.go"test.src0)
62        if err != nil {
63            t.Fatal(err)
64        }
65        t.Run(f.Name.Name, func(t *testing.T) {
66            conf := types.Config{
67                Error: func(error) {}, // keep going on errors
68            }
69            pkgerr := conf.Check(""fset, []*ast.File{f}, nil)
70            if err != nil {
71                t.Logf("types.Config.Check: %v"err)
72                // keep going on type checker errors: we want to assert on behavior of
73                // invalid code as well.
74            }
75            obj := pkg.Scope().Lookup("T")
76            if obj == nil {
77                t.Fatal("type T not found")
78            }
79            T := typeparams.ForNamed(obj.Type().(*types.Named)).At(0)
80            termserr := StructuralTerms(T)
81            if test.wantError != "" {
82                if err == nil {
83                    t.Fatalf("StructuralTerms(%s): nil error, want %q"Ttest.wantError)
84                }
85                if !strings.Contains(err.Error(), test.wantError) {
86                    t.Errorf("StructuralTerms(%s): err = %q, want %q"Terrtest.wantError)
87                }
88                return
89            }
90            if err != nil {
91                t.Fatal(err)
92            }
93            var got string
94            if len(terms) == 0 {
95                got = "all"
96            } else {
97                qf := types.RelativeTo(pkg)
98                got = types.TypeString(NewUnion(terms), qf)
99            }
100            want := regexp.MustCompile(test.want)
101            if !want.MatchString(got) {
102                t.Errorf("StructuralTerms(%s) = %q, want %q"Tgottest.want)
103            }
104        })
105    }
106}
107
MembersX
TestStructuralTerms.tests
TestStructuralTerms.RangeStmt_1910.BlockStmt.err
TestStructuralTerms.RangeStmt_1910.BlockStmt.BlockStmt.pkg
TestStructuralTerms.RangeStmt_1910.BlockStmt.BlockStmt.err
TestStructuralTerms.RangeStmt_1910.BlockStmt.BlockStmt.terms
TestStructuralTerms.RangeStmt_1910.BlockStmt.BlockStmt.got
TestStructuralTerms
TestStructuralTerms.RangeStmt_1910.test
TestStructuralTerms.RangeStmt_1910.BlockStmt.fset
TestStructuralTerms.RangeStmt_1910.BlockStmt.BlockStmt.conf
TestStructuralTerms.RangeStmt_1910.BlockStmt.BlockStmt.T
TestStructuralTerms.RangeStmt_1910.BlockStmt.BlockStmt.want
regexp
TestStructuralTerms.t
TestStructuralTerms.RangeStmt_1910.BlockStmt.f
TestStructuralTerms.RangeStmt_1910.BlockStmt.BlockStmt.obj
TestStructuralTerms.RangeStmt_1910.BlockStmt.BlockStmt.BlockStmt.qf
Members
X