1
0
mirror of https://github.com/golang/go synced 2024-11-18 17:04:41 -07:00

go.tools/go/types: more test cases for types.Eval

R=adonovan
CC=golang-dev
https://golang.org/cl/11229043
This commit is contained in:
Robert Griesemer 2013-07-12 13:51:24 -07:00
parent 32ed9615b3
commit a3301d1bc6
2 changed files with 91 additions and 7 deletions

View File

@ -41,6 +41,8 @@ func New(str string) Type {
// Eval returns the type and, if constant, the value for the
// expression or type literal string str evaluated in scope.
// If the expression contains function literals, the function
// bodies are ignored (though they must be syntactically correct).
//
// If pkg == nil, the Universe scope is used and the provided
// scope is ignored. Otherwise, the scope must belong to the

View File

@ -6,16 +6,21 @@
package types
import "testing"
import (
"go/parser"
"go/token"
"strings"
"testing"
)
func testEval(t *testing.T, pkg *Package, scope *Scope, str string, typ Type, typStr, valStr string) {
gotTyp, gotVal, err := Eval(str, pkg, scope)
if err != nil {
t.Errorf("Eval(%s) failed: %s", str, err)
t.Errorf("Eval(%q) failed: %s", str, err)
return
}
if gotTyp == nil {
t.Errorf("Eval(%s) got nil type but no error", str)
t.Errorf("Eval(%q) got nil type but no error", str)
return
}
@ -23,14 +28,14 @@ func testEval(t *testing.T, pkg *Package, scope *Scope, str string, typ Type, ty
if typ != nil {
// we have a type, check identity
if !IsIdentical(gotTyp, typ) {
t.Errorf("Eval(%s) got type %s, want %s", str, gotTyp, typ)
t.Errorf("Eval(%q) got type %s, want %s", str, gotTyp, typ)
return
}
} else {
// we have a string, compare type string
gotStr := gotTyp.String()
if gotStr != typStr {
t.Errorf("Eval(%s) got type %s, want %s", str, gotStr, typStr)
t.Errorf("Eval(%q) got type %s, want %s", str, gotStr, typStr)
return
}
}
@ -41,7 +46,7 @@ func testEval(t *testing.T, pkg *Package, scope *Scope, str string, typ Type, ty
gotStr = gotVal.String()
}
if gotStr != valStr {
t.Errorf("Eval(%s) got value %s, want %s", str, gotStr, valStr)
t.Errorf("Eval(%q) got value %s, want %s", str, gotStr, valStr)
}
}
@ -57,4 +62,81 @@ func TestEvalComposite(t *testing.T) {
}
}
// TODO(gri) expand
func TestEvalArith(t *testing.T) {
var tests = []string{
`true`,
`false == false`,
`12345678 + 87654321 == 99999999`,
`10 * 20 == 200`,
`(1<<1000)*2 >> 100 == 2<<900`,
`"foo" + "bar" == "foobar"`,
`"abc" <= "bcd"`,
`len([10]struct{}{}) == 2*5`,
}
for _, test := range tests {
testEval(t, nil, nil, test, Typ[UntypedBool], "", "true")
}
}
func TestEvalContext(t *testing.T) {
src := `
package p
import "fmt"
import m "math"
const c = 3.0
type T []int
func f(a int, s string) float64 {
const d int = c + 1
var x int
x = a + len(s)
return float64(x)
}
`
fset := token.NewFileSet()
file, err := parser.ParseFile(fset, "p", src, 0)
if err != nil {
t.Fatal(err)
}
pkg, err := Check("p", fset, file)
if err != nil {
t.Fatal(err)
}
pkgScope := pkg.scope
if n := pkgScope.NumChildren(); n != 1 {
t.Fatalf("got %d file scopes, want 1", n)
}
fileScope := pkgScope.Child(0)
if n := fileScope.NumChildren(); n != 1 {
t.Fatalf("got %d functions scopes, want 1", n)
}
funcScope := fileScope.Child(0)
var tests = []string{
`true => true, untyped boolean`,
`fmt.Println => , func(a·3 ...interface{}) (n·1 int, err·2 error)`,
`c => 3, untyped float`,
`T => , p.T`,
`a => , int`,
`s => , string`,
`d => 4, int`,
`x => , int`,
`d/c => 1, int`,
`c/2 => 3/2, untyped float`,
`m.Pi < m.E => false, untyped boolean`,
}
for _, test := range tests {
str, typ := split(test, ", ")
str, val := split(str, "=>")
testEval(t, pkg, funcScope, str, nil, typ, val)
}
}
// split splits string s at the first occurrence of s.
func split(s, sep string) (string, string) {
i := strings.Index(s, sep)
return strings.TrimSpace(s[:i]), strings.TrimSpace(s[i+len(sep):])
}