summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/mitchellh
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/mitchellh')
-rw-r--r--vendor/github.com/mitchellh/go-homedir/LICENSE21
-rw-r--r--vendor/github.com/mitchellh/go-homedir/README.md14
-rw-r--r--vendor/github.com/mitchellh/go-homedir/homedir.go137
-rw-r--r--vendor/github.com/mitchellh/go-homedir/homedir_test.go112
-rw-r--r--vendor/github.com/mitchellh/mapstructure/.travis.yml11
-rw-r--r--vendor/github.com/mitchellh/mapstructure/README.md2
-rw-r--r--vendor/github.com/mitchellh/mapstructure/mapstructure.go89
-rw-r--r--vendor/github.com/mitchellh/mapstructure/mapstructure_bugs_test.go18
-rw-r--r--vendor/github.com/mitchellh/mapstructure/mapstructure_test.go175
9 files changed, 568 insertions, 11 deletions
diff --git a/vendor/github.com/mitchellh/go-homedir/LICENSE b/vendor/github.com/mitchellh/go-homedir/LICENSE
new file mode 100644
index 000000000..f9c841a51
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-homedir/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2013 Mitchell Hashimoto
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/github.com/mitchellh/go-homedir/README.md b/vendor/github.com/mitchellh/go-homedir/README.md
new file mode 100644
index 000000000..d70706d5b
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-homedir/README.md
@@ -0,0 +1,14 @@
+# go-homedir
+
+This is a Go library for detecting the user's home directory without
+the use of cgo, so the library can be used in cross-compilation environments.
+
+Usage is incredibly simple, just call `homedir.Dir()` to get the home directory
+for a user, and `homedir.Expand()` to expand the `~` in a path to the home
+directory.
+
+**Why not just use `os/user`?** The built-in `os/user` package requires
+cgo on Darwin systems. This means that any Go code that uses that package
+cannot cross compile. But 99% of the time the use for `os/user` is just to
+retrieve the home directory, which we can do for the current user without
+cgo. This library does that, enabling cross-compilation.
diff --git a/vendor/github.com/mitchellh/go-homedir/homedir.go b/vendor/github.com/mitchellh/go-homedir/homedir.go
new file mode 100644
index 000000000..47e1f9ef8
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-homedir/homedir.go
@@ -0,0 +1,137 @@
+package homedir
+
+import (
+ "bytes"
+ "errors"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "runtime"
+ "strconv"
+ "strings"
+ "sync"
+)
+
+// DisableCache will disable caching of the home directory. Caching is enabled
+// by default.
+var DisableCache bool
+
+var homedirCache string
+var cacheLock sync.RWMutex
+
+// Dir returns the home directory for the executing user.
+//
+// This uses an OS-specific method for discovering the home directory.
+// An error is returned if a home directory cannot be detected.
+func Dir() (string, error) {
+ if !DisableCache {
+ cacheLock.RLock()
+ cached := homedirCache
+ cacheLock.RUnlock()
+ if cached != "" {
+ return cached, nil
+ }
+ }
+
+ cacheLock.Lock()
+ defer cacheLock.Unlock()
+
+ var result string
+ var err error
+ if runtime.GOOS == "windows" {
+ result, err = dirWindows()
+ } else {
+ // Unix-like system, so just assume Unix
+ result, err = dirUnix()
+ }
+
+ if err != nil {
+ return "", err
+ }
+ homedirCache = result
+ return result, nil
+}
+
+// Expand expands the path to include the home directory if the path
+// is prefixed with `~`. If it isn't prefixed with `~`, the path is
+// returned as-is.
+func Expand(path string) (string, error) {
+ if len(path) == 0 {
+ return path, nil
+ }
+
+ if path[0] != '~' {
+ return path, nil
+ }
+
+ if len(path) > 1 && path[1] != '/' && path[1] != '\\' {
+ return "", errors.New("cannot expand user-specific home dir")
+ }
+
+ dir, err := Dir()
+ if err != nil {
+ return "", err
+ }
+
+ return filepath.Join(dir, path[1:]), nil
+}
+
+func dirUnix() (string, error) {
+ // First prefer the HOME environmental variable
+ if home := os.Getenv("HOME"); home != "" {
+ return home, nil
+ }
+
+ // If that fails, try getent
+ var stdout bytes.Buffer
+ cmd := exec.Command("getent", "passwd", strconv.Itoa(os.Getuid()))
+ cmd.Stdout = &stdout
+ if err := cmd.Run(); err != nil {
+ // If the error is ErrNotFound, we ignore it. Otherwise, return it.
+ if err != exec.ErrNotFound {
+ return "", err
+ }
+ } else {
+ if passwd := strings.TrimSpace(stdout.String()); passwd != "" {
+ // username:password:uid:gid:gecos:home:shell
+ passwdParts := strings.SplitN(passwd, ":", 7)
+ if len(passwdParts) > 5 {
+ return passwdParts[5], nil
+ }
+ }
+ }
+
+ // If all else fails, try the shell
+ stdout.Reset()
+ cmd = exec.Command("sh", "-c", "cd && pwd")
+ cmd.Stdout = &stdout
+ if err := cmd.Run(); err != nil {
+ return "", err
+ }
+
+ result := strings.TrimSpace(stdout.String())
+ if result == "" {
+ return "", errors.New("blank output when reading home directory")
+ }
+
+ return result, nil
+}
+
+func dirWindows() (string, error) {
+ // First prefer the HOME environmental variable
+ if home := os.Getenv("HOME"); home != "" {
+ return home, nil
+ }
+
+ drive := os.Getenv("HOMEDRIVE")
+ path := os.Getenv("HOMEPATH")
+ home := drive + path
+ if drive == "" || path == "" {
+ home = os.Getenv("USERPROFILE")
+ }
+ if home == "" {
+ return "", errors.New("HOMEDRIVE, HOMEPATH, and USERPROFILE are blank")
+ }
+
+ return home, nil
+}
diff --git a/vendor/github.com/mitchellh/go-homedir/homedir_test.go b/vendor/github.com/mitchellh/go-homedir/homedir_test.go
new file mode 100644
index 000000000..e4054e72a
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-homedir/homedir_test.go
@@ -0,0 +1,112 @@
+package homedir
+
+import (
+ "os"
+ "os/user"
+ "path/filepath"
+ "testing"
+)
+
+func patchEnv(key, value string) func() {
+ bck := os.Getenv(key)
+ deferFunc := func() {
+ os.Setenv(key, bck)
+ }
+
+ os.Setenv(key, value)
+ return deferFunc
+}
+
+func BenchmarkDir(b *testing.B) {
+ // We do this for any "warmups"
+ for i := 0; i < 10; i++ {
+ Dir()
+ }
+
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ Dir()
+ }
+}
+
+func TestDir(t *testing.T) {
+ u, err := user.Current()
+ if err != nil {
+ t.Fatalf("err: %s", err)
+ }
+
+ dir, err := Dir()
+ if err != nil {
+ t.Fatalf("err: %s", err)
+ }
+
+ if u.HomeDir != dir {
+ t.Fatalf("%#v != %#v", u.HomeDir, dir)
+ }
+}
+
+func TestExpand(t *testing.T) {
+ u, err := user.Current()
+ if err != nil {
+ t.Fatalf("err: %s", err)
+ }
+
+ cases := []struct {
+ Input string
+ Output string
+ Err bool
+ }{
+ {
+ "/foo",
+ "/foo",
+ false,
+ },
+
+ {
+ "~/foo",
+ filepath.Join(u.HomeDir, "foo"),
+ false,
+ },
+
+ {
+ "",
+ "",
+ false,
+ },
+
+ {
+ "~",
+ u.HomeDir,
+ false,
+ },
+
+ {
+ "~foo/foo",
+ "",
+ true,
+ },
+ }
+
+ for _, tc := range cases {
+ actual, err := Expand(tc.Input)
+ if (err != nil) != tc.Err {
+ t.Fatalf("Input: %#v\n\nErr: %s", tc.Input, err)
+ }
+
+ if actual != tc.Output {
+ t.Fatalf("Input: %#v\n\nOutput: %#v", tc.Input, actual)
+ }
+ }
+
+ DisableCache = true
+ defer func() { DisableCache = false }()
+ defer patchEnv("HOME", "/custom/path/")()
+ expected := filepath.Join("/", "custom", "path", "foo/bar")
+ actual, err := Expand("~/foo/bar")
+
+ if err != nil {
+ t.Errorf("No error is expected, got: %v", err)
+ } else if actual != expected {
+ t.Errorf("Expected: %v; actual: %v", expected, actual)
+ }
+}
diff --git a/vendor/github.com/mitchellh/mapstructure/.travis.yml b/vendor/github.com/mitchellh/mapstructure/.travis.yml
index 5c14c1339..d9deadb86 100644
--- a/vendor/github.com/mitchellh/mapstructure/.travis.yml
+++ b/vendor/github.com/mitchellh/mapstructure/.travis.yml
@@ -1,7 +1,8 @@
-language: go
+language: go
+
+go:
+ - 1.9.x
+ - tip
-go:
- - 1.8.1
-
script:
- - go test
+ - go test
diff --git a/vendor/github.com/mitchellh/mapstructure/README.md b/vendor/github.com/mitchellh/mapstructure/README.md
index 659d6885f..7ecc785e4 100644
--- a/vendor/github.com/mitchellh/mapstructure/README.md
+++ b/vendor/github.com/mitchellh/mapstructure/README.md
@@ -1,4 +1,4 @@
-# mapstructure
+# mapstructure [![Godoc](https://godoc.org/github.com/mitchell/mapstructure?status.svg)](https://godoc.org/github.com/mitchell/mapstructure)
mapstructure is a Go library for decoding generic map values to structures
and vice versa, while providing helpful error handling.
diff --git a/vendor/github.com/mitchellh/mapstructure/mapstructure.go b/vendor/github.com/mitchellh/mapstructure/mapstructure.go
index 30a9957c6..39ec1e943 100644
--- a/vendor/github.com/mitchellh/mapstructure/mapstructure.go
+++ b/vendor/github.com/mitchellh/mapstructure/mapstructure.go
@@ -237,6 +237,8 @@ func (d *Decoder) decode(name string, data interface{}, val reflect.Value) error
err = d.decodePtr(name, data, val)
case reflect.Slice:
err = d.decodeSlice(name, data, val)
+ case reflect.Array:
+ err = d.decodeArray(name, data, val)
case reflect.Func:
err = d.decodeFunc(name, data, val)
default:
@@ -292,12 +294,22 @@ func (d *Decoder) decodeString(name string, data interface{}, val reflect.Value)
val.SetString(strconv.FormatUint(dataVal.Uint(), 10))
case dataKind == reflect.Float32 && d.config.WeaklyTypedInput:
val.SetString(strconv.FormatFloat(dataVal.Float(), 'f', -1, 64))
- case dataKind == reflect.Slice && d.config.WeaklyTypedInput:
+ case dataKind == reflect.Slice && d.config.WeaklyTypedInput,
+ dataKind == reflect.Array && d.config.WeaklyTypedInput:
dataType := dataVal.Type()
elemKind := dataType.Elem().Kind()
- switch {
- case elemKind == reflect.Uint8:
- val.SetString(string(dataVal.Interface().([]uint8)))
+ switch elemKind {
+ case reflect.Uint8:
+ var uints []uint8
+ if dataKind == reflect.Array {
+ uints = make([]uint8, dataVal.Len(), dataVal.Len())
+ for i := range uints {
+ uints[i] = dataVal.Index(i).Interface().(uint8)
+ }
+ } else {
+ uints = dataVal.Interface().([]uint8)
+ }
+ val.SetString(string(uints))
default:
converted = false
}
@@ -647,6 +659,73 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
return nil
}
+func (d *Decoder) decodeArray(name string, data interface{}, val reflect.Value) error {
+ dataVal := reflect.Indirect(reflect.ValueOf(data))
+ dataValKind := dataVal.Kind()
+ valType := val.Type()
+ valElemType := valType.Elem()
+ arrayType := reflect.ArrayOf(valType.Len(), valElemType)
+
+ valArray := val
+
+ if valArray.Interface() == reflect.Zero(valArray.Type()).Interface() || d.config.ZeroFields {
+ // Check input type
+ if dataValKind != reflect.Array && dataValKind != reflect.Slice {
+ if d.config.WeaklyTypedInput {
+ switch {
+ // Empty maps turn into empty arrays
+ case dataValKind == reflect.Map:
+ if dataVal.Len() == 0 {
+ val.Set(reflect.Zero(arrayType))
+ return nil
+ }
+
+ // All other types we try to convert to the array type
+ // and "lift" it into it. i.e. a string becomes a string array.
+ default:
+ // Just re-try this function with data as a slice.
+ return d.decodeArray(name, []interface{}{data}, val)
+ }
+ }
+
+ return fmt.Errorf(
+ "'%s': source data must be an array or slice, got %s", name, dataValKind)
+
+ }
+ if dataVal.Len() > arrayType.Len() {
+ return fmt.Errorf(
+ "'%s': expected source data to have length less or equal to %d, got %d", name, arrayType.Len(), dataVal.Len())
+
+ }
+
+ // Make a new array to hold our result, same size as the original data.
+ valArray = reflect.New(arrayType).Elem()
+ }
+
+ // Accumulate any errors
+ errors := make([]string, 0)
+
+ for i := 0; i < dataVal.Len(); i++ {
+ currentData := dataVal.Index(i).Interface()
+ currentField := valArray.Index(i)
+
+ fieldName := fmt.Sprintf("%s[%d]", name, i)
+ if err := d.decode(fieldName, currentData, currentField); err != nil {
+ errors = appendErrors(errors, err)
+ }
+ }
+
+ // Finally, set the value to the array we built up
+ val.Set(valArray)
+
+ // If there were errors, we return those
+ if len(errors) > 0 {
+ return &Error{errors}
+ }
+
+ return nil
+}
+
func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) error {
dataVal := reflect.Indirect(reflect.ValueOf(data))
@@ -716,7 +795,7 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value)
errors = appendErrors(errors,
fmt.Errorf("%s: unsupported type for squash: %s", fieldType.Name, fieldKind))
} else {
- structs = append(structs, val.FieldByName(fieldType.Name))
+ structs = append(structs, structVal.FieldByName(fieldType.Name))
}
continue
}
diff --git a/vendor/github.com/mitchellh/mapstructure/mapstructure_bugs_test.go b/vendor/github.com/mitchellh/mapstructure/mapstructure_bugs_test.go
index 08e495664..ecfb76987 100644
--- a/vendor/github.com/mitchellh/mapstructure/mapstructure_bugs_test.go
+++ b/vendor/github.com/mitchellh/mapstructure/mapstructure_bugs_test.go
@@ -258,3 +258,21 @@ func TestDecodeSliceToEmptySliceWOZeroing(t *testing.T) {
}
}
}
+
+// #70
+func TestNextSquashMapstructure(t *testing.T) {
+ data := &struct {
+ Level1 struct {
+ Level2 struct {
+ Foo string
+ } `mapstructure:",squash"`
+ } `mapstructure:",squash"`
+ }{}
+ err := Decode(map[interface{}]interface{}{"foo": "baz"}, &data)
+ if err != nil {
+ t.Fatalf("should not error: %s", err)
+ }
+ if data.Level1.Level2.Foo != "baz" {
+ t.Fatal("value should be baz")
+ }
+}
diff --git a/vendor/github.com/mitchellh/mapstructure/mapstructure_test.go b/vendor/github.com/mitchellh/mapstructure/mapstructure_test.go
index 547af7331..89861edda 100644
--- a/vendor/github.com/mitchellh/mapstructure/mapstructure_test.go
+++ b/vendor/github.com/mitchellh/mapstructure/mapstructure_test.go
@@ -49,6 +49,13 @@ type EmbeddedSlice struct {
Vunique string
}
+type ArrayAlias [2]string
+
+type EmbeddedArray struct {
+ ArrayAlias `mapstructure:"array_alias"`
+ Vunique string
+}
+
type SquashOnNonStructType struct {
InvalidSquashType int `mapstructure:",squash"`
}
@@ -85,6 +92,15 @@ type SliceOfStruct struct {
Value []Basic
}
+type Array struct {
+ Vfoo string
+ Vbar [2]string
+}
+
+type ArrayOfStruct struct {
+ Value [2]Basic
+}
+
type Func struct {
Foo func() string
}
@@ -112,14 +128,19 @@ type TypeConversionResult struct {
FloatToBool bool
FloatToString string
SliceUint8ToString string
+ ArrayUint8ToString string
StringToInt int
StringToUint uint
StringToBool bool
StringToFloat float32
StringToStrSlice []string
StringToIntSlice []int
+ StringToStrArray [1]string
+ StringToIntArray [1]int
SliceToMap map[string]interface{}
MapToSlice []interface{}
+ ArrayToMap map[string]interface{}
+ MapToArray [1]interface{}
}
func TestBasicTypes(t *testing.T) {
@@ -322,6 +343,29 @@ func TestDecode_EmbeddedSlice(t *testing.T) {
}
}
+func TestDecode_EmbeddedArray(t *testing.T) {
+ t.Parallel()
+
+ input := map[string]interface{}{
+ "array_alias": [2]string{"foo", "bar"},
+ "vunique": "bar",
+ }
+
+ var result EmbeddedArray
+ err := Decode(input, &result)
+ if err != nil {
+ t.Fatalf("got an err: %s", err.Error())
+ }
+
+ if !reflect.DeepEqual(result.ArrayAlias, ArrayAlias([2]string{"foo", "bar"})) {
+ t.Errorf("array value: %#v", result.ArrayAlias)
+ }
+
+ if result.Vunique != "bar" {
+ t.Errorf("vunique value should be 'bar': %#v", result.Vunique)
+ }
+}
+
func TestDecode_EmbeddedSquash(t *testing.T) {
t.Parallel()
@@ -582,14 +626,19 @@ func TestDecode_TypeConversion(t *testing.T) {
"FloatToBool": 42.42,
"FloatToString": 42.42,
"SliceUint8ToString": []uint8("foo"),
+ "ArrayUint8ToString": [3]uint8{'f', 'o', 'o'},
"StringToInt": "42",
"StringToUint": "42",
"StringToBool": "1",
"StringToFloat": "42.42",
"StringToStrSlice": "A",
"StringToIntSlice": "42",
+ "StringToStrArray": "A",
+ "StringToIntArray": "42",
"SliceToMap": []interface{}{},
"MapToSlice": map[string]interface{}{},
+ "ArrayToMap": []interface{}{},
+ "MapToArray": map[string]interface{}{},
}
expectedResultStrict := TypeConversionResult{
@@ -622,14 +671,19 @@ func TestDecode_TypeConversion(t *testing.T) {
FloatToBool: true,
FloatToString: "42.42",
SliceUint8ToString: "foo",
+ ArrayUint8ToString: "foo",
StringToInt: 42,
StringToUint: 42,
StringToBool: true,
StringToFloat: 42.42,
StringToStrSlice: []string{"A"},
StringToIntSlice: []int{42},
+ StringToStrArray: [1]string{"A"},
+ StringToIntArray: [1]int{42},
SliceToMap: map[string]interface{}{},
MapToSlice: []interface{}{},
+ ArrayToMap: map[string]interface{}{},
+ MapToArray: [1]interface{}{},
}
// Test strict type conversion
@@ -965,6 +1019,99 @@ func TestSliceToMap(t *testing.T) {
}
}
+func TestArray(t *testing.T) {
+ t.Parallel()
+
+ inputStringArray := map[string]interface{}{
+ "vfoo": "foo",
+ "vbar": [2]string{"foo", "bar"},
+ }
+
+ inputStringArrayPointer := map[string]interface{}{
+ "vfoo": "foo",
+ "vbar": &[2]string{"foo", "bar"},
+ }
+
+ outputStringArray := &Array{
+ "foo",
+ [2]string{"foo", "bar"},
+ }
+
+ testArrayInput(t, inputStringArray, outputStringArray)
+ testArrayInput(t, inputStringArrayPointer, outputStringArray)
+}
+
+func TestInvalidArray(t *testing.T) {
+ t.Parallel()
+
+ input := map[string]interface{}{
+ "vfoo": "foo",
+ "vbar": 42,
+ }
+
+ result := Array{}
+ err := Decode(input, &result)
+ if err == nil {
+ t.Errorf("expected failure")
+ }
+}
+
+func TestArrayOfStruct(t *testing.T) {
+ t.Parallel()
+
+ input := map[string]interface{}{
+ "value": []map[string]interface{}{
+ {"vstring": "one"},
+ {"vstring": "two"},
+ },
+ }
+
+ var result ArrayOfStruct
+ err := Decode(input, &result)
+ if err != nil {
+ t.Fatalf("got unexpected error: %s", err)
+ }
+
+ if len(result.Value) != 2 {
+ t.Fatalf("expected two values, got %d", len(result.Value))
+ }
+
+ if result.Value[0].Vstring != "one" {
+ t.Errorf("first value should be 'one', got: %s", result.Value[0].Vstring)
+ }
+
+ if result.Value[1].Vstring != "two" {
+ t.Errorf("second value should be 'two', got: %s", result.Value[1].Vstring)
+ }
+}
+
+func TestArrayToMap(t *testing.T) {
+ t.Parallel()
+
+ input := []map[string]interface{}{
+ {
+ "foo": "bar",
+ },
+ {
+ "bar": "baz",
+ },
+ }
+
+ var result map[string]interface{}
+ err := WeakDecode(input, &result)
+ if err != nil {
+ t.Fatalf("got an error: %s", err)
+ }
+
+ expected := map[string]interface{}{
+ "foo": "bar",
+ "bar": "baz",
+ }
+ if !reflect.DeepEqual(result, expected) {
+ t.Errorf("bad: %#v", result)
+ }
+}
+
func TestInvalidType(t *testing.T) {
t.Parallel()
@@ -1191,3 +1338,31 @@ func testSliceInput(t *testing.T, input map[string]interface{}, expected *Slice)
}
}
}
+
+func testArrayInput(t *testing.T, input map[string]interface{}, expected *Array) {
+ var result Array
+ err := Decode(input, &result)
+ if err != nil {
+ t.Fatalf("got error: %s", err)
+ }
+
+ if result.Vfoo != expected.Vfoo {
+ t.Errorf("Vfoo expected '%s', got '%s'", expected.Vfoo, result.Vfoo)
+ }
+
+ if result.Vbar == [2]string{} {
+ t.Fatalf("Vbar a slice, got '%#v'", result.Vbar)
+ }
+
+ if len(result.Vbar) != len(expected.Vbar) {
+ t.Errorf("Vbar length should be %d, got %d", len(expected.Vbar), len(result.Vbar))
+ }
+
+ for i, v := range result.Vbar {
+ if v != expected.Vbar[i] {
+ t.Errorf(
+ "Vbar[%d] should be '%#v', got '%#v'",
+ i, expected.Vbar[i], v)
+ }
+ }
+}