| // Copyright 2015 The Vanadium 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 build_test |
| |
| import ( |
| "fmt" |
| "io/ioutil" |
| "os" |
| "path" |
| "path/filepath" |
| "reflect" |
| "strings" |
| "testing" |
| |
| "v.io/v23/vdl" |
| "v.io/v23/vdlroot/vdltool" |
| "v.io/x/ref/lib/vdl/build" |
| "v.io/x/ref/lib/vdl/compile" |
| "v.io/x/ref/lib/vdl/internal/vdltestutil" |
| "v.io/x/ref/lib/vdl/testdata/base" |
| "v.io/x/ref/lib/vdl/vdlutil" |
| ) |
| |
| func init() { |
| // Uncomment this to enable verbose logs for debugging. |
| //vdlutil.SetVerbose() |
| } |
| |
| // The cwd is set to the directory containing this file. Currently we have the |
| // following directory structure: |
| // .../release/go/src/v.io/x/ref/lib/vdl/build/build_test.go |
| // We want to end up with the following: |
| // VDLROOT = .../release/go/src/v.io/v23/vdlroot |
| // VDLPATH = .../release/go |
| // |
| // TODO(toddw): Put a full VDLPATH tree under ../testdata and only use that. |
| const ( |
| defaultVDLRoot = "../../../../../v23/vdlroot" |
| defaultVDLPath = "../../../../../.." |
| ) |
| |
| func setEnvironment(t *testing.T, vdlroot, vdlpath string) { |
| if err := os.Setenv("VDLROOT", vdlroot); err != nil { |
| t.Fatalf("Setenv(VDLROOT, %q) failed: %v", vdlroot, err) |
| } |
| if err := os.Setenv("VDLPATH", vdlpath); err != nil { |
| t.Fatalf("Setenv(VDLPATH, %q) failed: %v", vdlpath, err) |
| } |
| } |
| |
| // Tests the VDLROOT part of SrcDirs(). |
| func TestSrcDirsVDLRoot(t *testing.T) { |
| cwd, err := os.Getwd() |
| if err != nil { |
| t.Fatalf("Getwd() failed: %v", err) |
| } |
| tests := []struct { |
| VDLRoot string |
| Want string |
| ErrRE string |
| }{ |
| {"", "", ""}, |
| {"/noexist", "", "doesn't exist"}, |
| {"/a", "/a", ""}, |
| {"/a/b/c", "/a/b/c", ""}, |
| } |
| tmpDir, err := ioutil.TempDir("", "") |
| if err != nil { |
| t.Fatalf("TempDir() failed: %v", err) |
| } |
| defer os.RemoveAll(tmpDir) |
| for _, test := range tests { |
| // The directory must exist in order to succeed. Ignore mkdir errors, to |
| // allow the same dir to be re-used. |
| vdlRoot := test.VDLRoot |
| if vdlRoot != "" && vdlRoot != "/noexist" { |
| vdlRoot = filepath.Join(tmpDir, vdlRoot) |
| os.MkdirAll(vdlRoot, os.ModePerm) |
| } |
| setEnvironment(t, vdlRoot, defaultVDLPath) |
| name := fmt.Sprintf("%+v", test) |
| errs := vdlutil.NewErrors(-1) |
| got := build.SrcDirs(errs) |
| vdltestutil.ExpectResult(t, errs, name, test.ErrRE) |
| // Every result will have our valid VDLPATH srcdir. |
| var want []string |
| if test.Want != "" { |
| want = append(want, filepath.Join(tmpDir, test.Want)) |
| } |
| want = append(want, filepath.Join(cwd, defaultVDLPath)) |
| if !reflect.DeepEqual(got, want) { |
| t.Errorf("SrcDirs(%s) got %v, want %v", name, got, want) |
| } |
| } |
| } |
| |
| // Tests the VDLPATH part of SrcDirs(). |
| func TestSrcDirsVDLPath(t *testing.T) { |
| cwd, err := os.Getwd() |
| if err != nil { |
| t.Fatalf("Getwd() failed: %v", err) |
| } |
| abs := func(relative string) string { |
| return filepath.Join(cwd, relative) |
| } |
| tests := []struct { |
| VDLPath string |
| Want []string |
| }{ |
| {"", nil}, |
| // Test absolute paths. |
| {"/a", []string{"/a"}}, |
| {"/a/b", []string{"/a/b"}}, |
| {"/a:/b", []string{"/a", "/b"}}, |
| {"/a/1:/b/2", []string{"/a/1", "/b/2"}}, |
| {"/a/1:/b/2:/c/3", []string{"/a/1", "/b/2", "/c/3"}}, |
| {":::/a/1::::/b/2::::/c/3:::", []string{"/a/1", "/b/2", "/c/3"}}, |
| // Test relative paths. |
| {"a", []string{abs("a")}}, |
| {"a/b", []string{abs("a/b")}}, |
| {"a:b", []string{abs("a"), abs("b")}}, |
| {"a/1:b/2", []string{abs("a/1"), abs("b/2")}}, |
| {"a/1:b/2:c/3", []string{abs("a/1"), abs("b/2"), abs("c/3")}}, |
| {":::a/1::::b/2::::c/3:::", []string{abs("a/1"), abs("b/2"), abs("c/3")}}, |
| // Test mixed absolute / relative paths. |
| {"a:/b", []string{abs("a"), "/b"}}, |
| {"/a/1:b/2", []string{"/a/1", abs("b/2")}}, |
| {"/a/1:b/2:/c/3", []string{"/a/1", abs("b/2"), "/c/3"}}, |
| {":::/a/1::::b/2::::/c/3:::", []string{"/a/1", abs("b/2"), "/c/3"}}, |
| } |
| for _, test := range tests { |
| setEnvironment(t, defaultVDLRoot, test.VDLPath) |
| name := fmt.Sprintf("SrcDirs(%q)", test.VDLPath) |
| errs := vdlutil.NewErrors(-1) |
| got := build.SrcDirs(errs) |
| var errRE string |
| if test.Want == nil { |
| errRE = "No src dirs; set VDLPATH to a valid value" |
| } |
| vdltestutil.ExpectResult(t, errs, name, errRE) |
| // Every result will have our valid VDLROOT srcdir. |
| want := append([]string{abs(defaultVDLRoot)}, test.Want...) |
| if !reflect.DeepEqual(got, want) { |
| t.Errorf("%s got %v, want %v", name, got, want) |
| } |
| } |
| } |
| |
| // Tests Is{Dir,Import}Path. |
| func TestIsDirImportPath(t *testing.T) { |
| tests := []struct { |
| Path string |
| IsDir bool |
| }{ |
| // Import paths. |
| {"", false}, |
| {"...", false}, |
| {".../", false}, |
| {"all", false}, |
| {"foo", false}, |
| {"foo/", false}, |
| {"foo...", false}, |
| {"foo/...", false}, |
| {"a/b/c", false}, |
| {"a/b/c/", false}, |
| {"a/b/c...", false}, |
| {"a/b/c/...", false}, |
| {"...a/b/c...", false}, |
| {"...a/b/c/...", false}, |
| {".../a/b/c/...", false}, |
| {".../a/b/c...", false}, |
| // Dir paths. |
| {".", true}, |
| {"..", true}, |
| {"./", true}, |
| {"../", true}, |
| {"./...", true}, |
| {"../...", true}, |
| {".././.././...", true}, |
| {"/", true}, |
| {"/.", true}, |
| {"/..", true}, |
| {"/...", true}, |
| {"/./...", true}, |
| {"/foo", true}, |
| {"/foo/", true}, |
| {"/foo...", true}, |
| {"/foo/...", true}, |
| {"/a/b/c", true}, |
| {"/a/b/c/", true}, |
| {"/a/b/c...", true}, |
| {"/a/b/c/...", true}, |
| {"/a/b/c/../../...", true}, |
| } |
| for _, test := range tests { |
| if got, want := build.IsDirPath(test.Path), test.IsDir; got != want { |
| t.Errorf("IsDirPath(%q) want %v", test.Path, want) |
| } |
| if got, want := build.IsImportPath(test.Path), !test.IsDir; got != want { |
| t.Errorf("IsImportPath(%q) want %v", test.Path, want) |
| } |
| } |
| } |
| |
| var allModes = []build.UnknownPathMode{ |
| build.UnknownPathIsIgnored, |
| build.UnknownPathIsError, |
| } |
| |
| // Tests TransitivePackages success cases. |
| func TestTransitivePackages(t *testing.T) { |
| // Test with VDLROOT set. |
| setEnvironment(t, defaultVDLRoot, defaultVDLPath) |
| testTransitivePackages(t) |
| // Test with VDLROOT unset. |
| setEnvironment(t, "", defaultVDLPath) |
| testTransitivePackages(t) |
| } |
| |
| func testTransitivePackages(t *testing.T) { |
| tests := []struct { |
| InPaths []string // Input paths to TransitivePackages call |
| OutPaths []string // Wanted paths from build.Package.Path. |
| GenPaths []string // Wanted paths from build.Package.GenPath, same as OutPaths if nil. |
| }{ |
| {nil, nil, nil}, |
| {[]string{}, nil, nil}, |
| // Single-package, both import and dir path. |
| { |
| []string{"v.io/x/ref/lib/vdl/testdata/base"}, |
| []string{"v.io/x/ref/lib/vdl/testdata/base"}, |
| nil, |
| }, |
| { |
| []string{"../testdata/base"}, |
| []string{"v.io/x/ref/lib/vdl/testdata/base"}, |
| nil, |
| }, |
| // Single-package with wildcard, both import and dir path. |
| { |
| []string{"v.io/x/ref/lib/vdl/testdata/base..."}, |
| []string{"v.io/x/ref/lib/vdl/testdata/base"}, |
| nil, |
| }, |
| { |
| []string{"v.io/x/ref/lib/vdl/testdata/base/..."}, |
| []string{"v.io/x/ref/lib/vdl/testdata/base"}, |
| nil, |
| }, |
| { |
| []string{"../testdata/base..."}, |
| []string{"v.io/x/ref/lib/vdl/testdata/base"}, |
| nil, |
| }, |
| { |
| []string{"../testdata/base/..."}, |
| []string{"v.io/x/ref/lib/vdl/testdata/base"}, |
| nil, |
| }, |
| // Redundant specification as both import and dir path. |
| { |
| []string{"v.io/x/ref/lib/vdl/testdata/base", "../testdata/base"}, |
| []string{"v.io/x/ref/lib/vdl/testdata/base"}, |
| nil, |
| }, |
| { |
| []string{"v.io/x/ref/lib/vdl/testdata/arith", "../testdata/arith"}, |
| []string{ |
| "v.io/x/ref/lib/vdl/testdata/arith/exp", |
| "v.io/x/ref/lib/vdl/testdata/base", |
| "v.io/x/ref/lib/vdl/testdata/arith", |
| }, |
| nil, |
| }, |
| // Wildcards as both import and dir path. |
| { |
| []string{"v.io/x/ref/lib/vdl/testdata..."}, |
| []string{ |
| "v.io/x/ref/lib/vdl/testdata/arith/exp", |
| "v.io/x/ref/lib/vdl/testdata/base", |
| "v.io/x/ref/lib/vdl/testdata/arith", |
| "v.io/x/ref/lib/vdl/testdata/nativetest", |
| "v.io/x/ref/lib/vdl/testdata/nativedep", |
| "v.io/x/ref/lib/vdl/testdata/nativedep2", |
| "v.io/x/ref/lib/vdl/testdata/testconfig", |
| }, |
| nil, |
| }, |
| { |
| []string{"v.io/x/ref/lib/vdl/testdata/..."}, |
| []string{ |
| "v.io/x/ref/lib/vdl/testdata/arith/exp", |
| "v.io/x/ref/lib/vdl/testdata/base", |
| "v.io/x/ref/lib/vdl/testdata/arith", |
| "v.io/x/ref/lib/vdl/testdata/nativetest", |
| "v.io/x/ref/lib/vdl/testdata/nativedep", |
| "v.io/x/ref/lib/vdl/testdata/nativedep2", |
| "v.io/x/ref/lib/vdl/testdata/testconfig", |
| }, |
| nil, |
| }, |
| { |
| []string{"../testdata..."}, |
| []string{ |
| "v.io/x/ref/lib/vdl/testdata/arith/exp", |
| "v.io/x/ref/lib/vdl/testdata/base", |
| "v.io/x/ref/lib/vdl/testdata/arith", |
| "v.io/x/ref/lib/vdl/testdata/nativetest", |
| "v.io/x/ref/lib/vdl/testdata/nativedep", |
| "v.io/x/ref/lib/vdl/testdata/nativedep2", |
| "v.io/x/ref/lib/vdl/testdata/testconfig", |
| }, |
| nil, |
| }, |
| { |
| []string{"../testdata/..."}, |
| []string{ |
| "v.io/x/ref/lib/vdl/testdata/arith/exp", |
| "v.io/x/ref/lib/vdl/testdata/base", |
| "v.io/x/ref/lib/vdl/testdata/arith", |
| "v.io/x/ref/lib/vdl/testdata/nativetest", |
| "v.io/x/ref/lib/vdl/testdata/nativedep", |
| "v.io/x/ref/lib/vdl/testdata/nativedep2", |
| "v.io/x/ref/lib/vdl/testdata/testconfig", |
| }, |
| nil, |
| }, |
| // Multi-Wildcards as both import and dir path. |
| { |
| []string{"v...vdl/testdata/..."}, |
| []string{ |
| "v.io/x/ref/lib/vdl/testdata/arith/exp", |
| "v.io/x/ref/lib/vdl/testdata/base", |
| "v.io/x/ref/lib/vdl/testdata/arith", |
| "v.io/x/ref/lib/vdl/testdata/nativetest", |
| "v.io/x/ref/lib/vdl/testdata/nativedep", |
| "v.io/x/ref/lib/vdl/testdata/nativedep2", |
| "v.io/x/ref/lib/vdl/testdata/testconfig", |
| }, |
| nil, |
| }, |
| { |
| []string{"../../...vdl/testdata/..."}, |
| []string{ |
| "v.io/x/ref/lib/vdl/testdata/arith/exp", |
| "v.io/x/ref/lib/vdl/testdata/base", |
| "v.io/x/ref/lib/vdl/testdata/arith", |
| "v.io/x/ref/lib/vdl/testdata/nativetest", |
| "v.io/x/ref/lib/vdl/testdata/nativedep", |
| "v.io/x/ref/lib/vdl/testdata/nativedep2", |
| "v.io/x/ref/lib/vdl/testdata/testconfig", |
| }, |
| nil, |
| }, |
| // Multi-Wildcards as both import and dir path. |
| { |
| []string{"v...vdl/testdata/...exp"}, |
| []string{"v.io/x/ref/lib/vdl/testdata/arith/exp"}, |
| nil, |
| }, |
| { |
| []string{"../../...vdl/testdata/...exp"}, |
| []string{"v.io/x/ref/lib/vdl/testdata/arith/exp"}, |
| nil, |
| }, |
| // Standard vdl package, as both import and dir path. |
| { |
| []string{"vdltool"}, |
| []string{"vdltool"}, |
| []string{"v.io/v23/vdlroot/vdltool"}, |
| }, |
| { |
| []string{"../../../../../v23/vdlroot/vdltool"}, |
| []string{"vdltool"}, |
| []string{"v.io/v23/vdlroot/vdltool"}, |
| }, |
| } |
| for _, test := range tests { |
| // All modes should result in the same successful output. |
| for _, mode := range allModes { |
| name := fmt.Sprintf("%v %v", mode, test.InPaths) |
| errs := vdlutil.NewErrors(-1) |
| pkgs := build.TransitivePackages(test.InPaths, mode, build.Opts{}, errs) |
| vdltestutil.ExpectResult(t, errs, name, "") |
| var paths []string |
| for _, pkg := range pkgs { |
| paths = append(paths, pkg.Path) |
| } |
| if got, want := paths, test.OutPaths; !reflect.DeepEqual(got, want) { |
| t.Errorf("%v got paths %v, want %v", name, got, want) |
| } |
| wantGen := test.GenPaths |
| if wantGen == nil { |
| wantGen = test.OutPaths |
| } |
| paths = nil |
| for _, pkg := range pkgs { |
| paths = append(paths, pkg.GenPath) |
| } |
| if got, want := paths, wantGen; !reflect.DeepEqual(got, want) { |
| t.Errorf("%v got gen paths %v, want %v", name, got, want) |
| } |
| } |
| } |
| } |
| |
| // Tests TransitivePackages error cases. |
| func TestTransitivePackagesUnknownPathError(t *testing.T) { |
| // Test with VDLROOT set. |
| setEnvironment(t, defaultVDLRoot, defaultVDLPath) |
| testTransitivePackagesUnknownPathError(t) |
| // Test with VDLROOT unset. |
| setEnvironment(t, "", defaultVDLPath) |
| testTransitivePackagesUnknownPathError(t) |
| } |
| |
| func testTransitivePackagesUnknownPathError(t *testing.T) { |
| tests := []struct { |
| InPaths []string |
| ErrRE string |
| }{ |
| // Non-existent as both import and dir path. |
| { |
| []string{"noexist"}, |
| `can't resolve "noexist" to any packages`, |
| }, |
| { |
| []string{"./noexist"}, |
| `can't resolve "./noexist" to any packages`, |
| }, |
| // Invalid package path, as both import and dir path. |
| { |
| []string{".foo"}, |
| `import path ".foo" is invalid`, |
| }, |
| { |
| []string{"foo/.bar"}, |
| `import path "foo/.bar" is invalid`, |
| }, |
| { |
| []string{"_foo"}, |
| `import path "_foo" is invalid`, |
| }, |
| { |
| []string{"foo/_bar"}, |
| `import path "foo/_bar" is invalid`, |
| }, |
| { |
| []string{"../../../../../../.foo"}, |
| `package path ".foo" is invalid`, |
| }, |
| { |
| []string{"../../../../../../foo/.bar"}, |
| `package path "foo/.bar" is invalid`, |
| }, |
| { |
| []string{"../../../../../../_foo"}, |
| `package path "_foo" is invalid`, |
| }, |
| { |
| []string{"../../../../../../foo/_bar"}, |
| `package path "foo/_bar" is invalid`, |
| }, |
| // Special-case error for packages under vdlroot, which can't be imported |
| // using the vdlroot prefix. |
| { |
| []string{"v.io/v23/vdlroot/vdltool"}, |
| `packages under vdlroot must be specified without the vdlroot prefix`, |
| }, |
| { |
| []string{"v.io/v23/vdlroot/..."}, |
| `can't resolve "v.io/v23/vdlroot/..." to any packages`, |
| }, |
| } |
| for _, test := range tests { |
| for _, mode := range allModes { |
| name := fmt.Sprintf("%v %v", mode, test.InPaths) |
| errs := vdlutil.NewErrors(-1) |
| pkgs := build.TransitivePackages(test.InPaths, mode, build.Opts{}, errs) |
| errRE := test.ErrRE |
| if mode == build.UnknownPathIsIgnored { |
| // Ignore mode returns success, while error mode returns error. |
| errRE = "" |
| } |
| vdltestutil.ExpectResult(t, errs, name, errRE) |
| if pkgs != nil { |
| t.Errorf("%v got unexpected packages %v", name, pkgs) |
| } |
| } |
| } |
| } |
| |
| // Tests vdl.config file support. |
| func TestPackageConfig(t *testing.T) { |
| setEnvironment(t, defaultVDLRoot, defaultVDLPath) |
| tests := []struct { |
| Path string |
| Config vdltool.Config |
| }{ |
| {"v.io/x/ref/lib/vdl/testdata/base", vdltool.Config{}}, |
| { |
| "v.io/x/ref/lib/vdl/testdata/testconfig", |
| vdltool.Config{ |
| GenLanguages: map[vdltool.GenLanguage]struct{}{vdltool.GenLanguageGo: struct{}{}}, |
| }, |
| }, |
| } |
| for _, test := range tests { |
| name := path.Base(test.Path) |
| env := compile.NewEnv(-1) |
| deps := build.TransitivePackages([]string{test.Path}, build.UnknownPathIsError, build.Opts{}, env.Errors) |
| vdltestutil.ExpectResult(t, env.Errors, name, "") |
| if len(deps) != 1 { |
| t.Fatalf("TransitivePackages(%q) got %v, want 1 dep", name, deps) |
| } |
| if got, want := deps[0].Name, name; got != want { |
| t.Errorf("TransitivePackages(%q) got Name %q, want %q", name, got, want) |
| } |
| if got, want := deps[0].Path, test.Path; got != want { |
| t.Errorf("TransitivePackages(%q) got Path %q, want %q", name, got, want) |
| } |
| if got, want := deps[0].Config, test.Config; !reflect.DeepEqual(got, want) { |
| t.Errorf("TransitivePackages(%q) got Config %+v, want %+v", name, got, want) |
| } |
| } |
| } |
| |
| // Tests BuildConfig, BuildConfigValue and TransitivePackagesForConfig. |
| func TestBuildConfig(t *testing.T) { |
| setEnvironment(t, defaultVDLRoot, defaultVDLPath) |
| tests := []struct { |
| Src string |
| Value interface{} |
| }{ |
| { |
| `config = x;import "v.io/x/ref/lib/vdl/testdata/base";const x = base.NamedBool(true)`, |
| base.NamedBool(true), |
| }, |
| { |
| `config = x;import "v.io/x/ref/lib/vdl/testdata/base";const x = base.NamedString("abc")`, |
| base.NamedString("abc"), |
| }, |
| { |
| `config = x;import "v.io/x/ref/lib/vdl/testdata/base";const x = base.Args{1, 2}`, |
| base.Args{1, 2}, |
| }, |
| } |
| for _, test := range tests { |
| // Build import package dependencies. |
| env := compile.NewEnv(-1) |
| deps := build.TransitivePackagesForConfig("file", strings.NewReader(test.Src), build.Opts{}, env.Errors) |
| for _, dep := range deps { |
| build.BuildPackage(dep, env) |
| } |
| vdltestutil.ExpectResult(t, env.Errors, test.Src, "") |
| // Test BuildConfig |
| wantV := vdl.ZeroValue(vdl.TypeOf(test.Value)) |
| if err := vdl.Convert(wantV, test.Value); err != nil { |
| t.Errorf("Convert(%v) got error %v, want nil", test.Value, err) |
| } |
| gotV := build.BuildConfig("file", strings.NewReader(test.Src), nil, nil, env) |
| if !vdl.EqualValue(gotV, wantV) { |
| t.Errorf("BuildConfig(%v) got %v, want %v", test.Src, gotV, wantV) |
| } |
| vdltestutil.ExpectResult(t, env.Errors, test.Src, "") |
| // TestBuildConfigValue |
| gotRV := reflect.New(reflect.TypeOf(test.Value)) |
| build.BuildConfigValue("file", strings.NewReader(test.Src), nil, env, gotRV.Interface()) |
| if got, want := gotRV.Elem().Interface(), test.Value; !reflect.DeepEqual(got, want) { |
| t.Errorf("BuildConfigValue(%v) got %v, want %v", test.Src, got, want) |
| } |
| vdltestutil.ExpectResult(t, env.Errors, test.Src, "") |
| } |
| } |
| |
| type ts []*vdl.Type |
| type vs []*vdl.Value |
| |
| func TestBuildExprs(t *testing.T) { |
| ttArray := vdl.ArrayType(2, vdl.Int32Type) |
| ttStruct := vdl.StructType( |
| vdl.Field{ |
| Name: "A", |
| Type: vdl.Int32Type, |
| }, vdl.Field{ |
| Name: "B", |
| Type: vdl.StringType, |
| }, |
| ) |
| vvArray := vdl.ZeroValue(ttArray) |
| vvArray.Index(0).AssignInt(1) |
| vvArray.Index(1).AssignInt(-2) |
| vvStruct := vdl.ZeroValue(ttStruct) |
| vvStruct.StructField(0).AssignInt(1) |
| vvStruct.StructField(1).AssignString("abc") |
| tests := []struct { |
| Data string |
| Types ts |
| Want vs |
| Err string |
| }{ |
| {``, nil, nil, "syntax error"}, |
| {`true`, nil, vs{vdl.BoolValue(nil, true)}, ""}, |
| {`false`, nil, vs{vdl.BoolValue(nil, false)}, ""}, |
| {`"abc"`, nil, vs{vdl.StringValue(nil, "abc")}, ""}, |
| {`1`, nil, vs{nil}, "1 must be assigned a type"}, |
| {`1`, ts{vdl.Int64Type}, vs{vdl.IntValue(vdl.Int64Type, 1)}, ""}, |
| {`1.0`, ts{vdl.Int64Type}, vs{vdl.IntValue(vdl.Int64Type, 1)}, ""}, |
| {`1.5`, ts{vdl.Int64Type}, vs{nil}, "loses precision"}, |
| {`1.0`, ts{vdl.Float64Type}, vs{vdl.FloatValue(vdl.Float64Type, 1.0)}, ""}, |
| {`1.5`, ts{vdl.Float64Type}, vs{vdl.FloatValue(vdl.Float64Type, 1.5)}, ""}, |
| {`1+2`, ts{vdl.Int64Type}, vs{vdl.IntValue(vdl.Int64Type, 3)}, ""}, |
| {`1+2,"abc"`, ts{vdl.Int64Type, nil}, vs{vdl.IntValue(vdl.Int64Type, 3), vdl.StringValue(nil, "abc")}, ""}, |
| {`1,2,3`, ts{vdl.Int64Type}, vs{vdl.IntValue(vdl.Int64Type, 1), vdl.IntValue(vdl.Int64Type, 2), vdl.IntValue(vdl.Int64Type, 3)}, ""}, |
| {`{1,-2}`, ts{ttArray}, vs{vvArray}, ""}, |
| {`{0+1,1-3}`, ts{ttArray}, vs{vvArray}, ""}, |
| {`{1,"abc"}`, ts{ttStruct}, vs{vvStruct}, ""}, |
| {`{A:1,B:"abc"}`, ts{ttStruct}, vs{vvStruct}, ""}, |
| {`{B:"abc",A:1}`, ts{ttStruct}, vs{vvStruct}, ""}, |
| {`{B:"a"+"bc",A:1*1}`, ts{ttStruct}, vs{vvStruct}, ""}, |
| } |
| for _, test := range tests { |
| env := compile.NewEnv(-1) |
| values := build.BuildExprs(test.Data, test.Types, env) |
| vdltestutil.ExpectResult(t, env.Errors, test.Data, test.Err) |
| if got, want := len(values), len(test.Want); got != want { |
| t.Errorf("%s got len %d, want %d", test.Data, got, want) |
| } |
| for ix, want := range test.Want { |
| var got *vdl.Value |
| if ix < len(values) { |
| got = values[ix] |
| } |
| if !vdl.EqualValue(got, want) { |
| t.Errorf("%s got value #%d %v, want %v", test.Data, ix, got, want) |
| } |
| } |
| } |
| } |