mirror of
https://github.com/octoleo/syncthing.git
synced 2024-11-09 14:50:56 +00:00
Add deps
This commit is contained in:
parent
dd9a4e044a
commit
a8ffde6f21
@ -12,11 +12,11 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/d4l3k/messagediff"
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
)
|
||||
|
||||
@ -65,8 +65,8 @@ func TestDefaultValues(t *testing.T) {
|
||||
|
||||
cfg := New(device1)
|
||||
|
||||
if !reflect.DeepEqual(cfg.Options, expected) {
|
||||
t.Errorf("Default config differs;\n E: %#v\n A: %#v", expected, cfg.Options)
|
||||
if diff, equal := messagediff.PrettyDiff(cfg.Options, expected); !equal {
|
||||
t.Errorf("Default config differs. Diff:\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,14 +133,14 @@ func TestDeviceConfig(t *testing.T) {
|
||||
if cfg.Version != CurrentVersion {
|
||||
t.Errorf("%d: Incorrect version %d != %d", i, cfg.Version, CurrentVersion)
|
||||
}
|
||||
if !reflect.DeepEqual(cfg.Folders, expectedFolders) {
|
||||
t.Errorf("%d: Incorrect Folders\n A: %#v\n E: %#v", i, cfg.Folders, expectedFolders)
|
||||
if diff, equal := messagediff.PrettyDiff(cfg.Folders, expectedFolders); !equal {
|
||||
t.Errorf("%d: Incorrect Folders. Diff:\n%s", i, diff)
|
||||
}
|
||||
if !reflect.DeepEqual(cfg.Devices, expectedDevices) {
|
||||
t.Errorf("%d: Incorrect Devices\n A: %#v\n E: %#v", i, cfg.Devices, expectedDevices)
|
||||
if diff, equal := messagediff.PrettyDiff(cfg.Devices, expectedDevices); !equal {
|
||||
t.Errorf("%d: Incorrect Devices. Diff:\n%s", i, diff)
|
||||
}
|
||||
if !reflect.DeepEqual(cfg.Folders[0].DeviceIDs(), expectedDeviceIDs) {
|
||||
t.Errorf("%d: Incorrect DeviceIDs\n A: %#v\n E: %#v", i, cfg.Folders[0].DeviceIDs(), expectedDeviceIDs)
|
||||
if diff, equal := messagediff.PrettyDiff(cfg.Folders[0].DeviceIDs(), expectedDeviceIDs); !equal {
|
||||
t.Errorf("%d: Incorrect DeviceIDs. Diff:\n%s", i, diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -153,8 +153,8 @@ func TestNoListenAddress(t *testing.T) {
|
||||
|
||||
expected := []string{""}
|
||||
actual := cfg.Options().ListenAddress
|
||||
if !reflect.DeepEqual(actual, expected) {
|
||||
t.Errorf("Unexpected ListenAddress %#v", actual)
|
||||
if diff, equal := messagediff.PrettyDiff(actual, expected); !equal {
|
||||
t.Errorf("Unexpected ListenAddress. Diff:\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,8 +197,8 @@ func TestOverriddenValues(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(cfg.Options(), expected) {
|
||||
t.Errorf("Overridden config differs;\n E: %#v\n A: %#v", expected, cfg.Options())
|
||||
if diff, equal := messagediff.PrettyDiff(cfg.Options(), expected); !equal {
|
||||
t.Errorf("Overridden config differs. Diff:\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
@ -231,8 +231,8 @@ func TestDeviceAddressesDynamic(t *testing.T) {
|
||||
}
|
||||
|
||||
actual := cfg.Devices()
|
||||
if !reflect.DeepEqual(actual, expected) {
|
||||
t.Errorf("Devices differ;\n E: %#v\n A: %#v", expected, actual)
|
||||
if diff, equal := messagediff.PrettyDiff(actual, expected); !equal {
|
||||
t.Errorf("Devices differ. Diff:\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
@ -268,8 +268,8 @@ func TestDeviceCompression(t *testing.T) {
|
||||
}
|
||||
|
||||
actual := cfg.Devices()
|
||||
if !reflect.DeepEqual(actual, expected) {
|
||||
t.Errorf("Devices differ;\n E: %#v\n A: %#v", expected, actual)
|
||||
if diff, equal := messagediff.PrettyDiff(actual, expected); !equal {
|
||||
t.Errorf("Devices differ. Diff:\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
@ -302,8 +302,8 @@ func TestDeviceAddressesStatic(t *testing.T) {
|
||||
}
|
||||
|
||||
actual := cfg.Devices()
|
||||
if !reflect.DeepEqual(actual, expected) {
|
||||
t.Errorf("Devices differ;\n E: %#v\n A: %#v", expected, actual)
|
||||
if diff, equal := messagediff.PrettyDiff(actual, expected); !equal {
|
||||
t.Errorf("Devices differ. Diff:\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
@ -325,8 +325,8 @@ func TestVersioningConfig(t *testing.T) {
|
||||
"foo": "bar",
|
||||
"baz": "quux",
|
||||
}
|
||||
if !reflect.DeepEqual(vc.Params, expected) {
|
||||
t.Errorf("vc.Params differ;\n E: %#v\n A: %#v", expected, vc.Params)
|
||||
if diff, equal := messagediff.PrettyDiff(vc.Params, expected); !equal {
|
||||
t.Errorf("vc.Params differ. Diff:\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
@ -447,8 +447,8 @@ func TestNewSaveLoad(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(cfg.Raw(), cfg2.Raw()) {
|
||||
t.Errorf("Configs are not equal;\n E: %#v\n A: %#v", cfg.Raw(), cfg2.Raw())
|
||||
if diff, equal := messagediff.PrettyDiff(cfg.Raw(), cfg2.Raw()); !equal {
|
||||
t.Errorf("Configs are not equal. Diff:\n%s", diff)
|
||||
}
|
||||
|
||||
os.Remove(path)
|
||||
|
@ -10,10 +10,10 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/d4l3k/messagediff"
|
||||
"github.com/syncthing/syncthing/lib/db"
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
)
|
||||
@ -532,8 +532,9 @@ func TestListDropFolder(t *testing.T) {
|
||||
// Check that we have both folders and their data is in the global list
|
||||
|
||||
expectedFolderList := []string{"test0", "test1"}
|
||||
if actualFolderList := ldb.ListFolders(); !reflect.DeepEqual(actualFolderList, expectedFolderList) {
|
||||
t.Fatalf("FolderList mismatch\nE: %v\nA: %v", expectedFolderList, actualFolderList)
|
||||
actualFolderList := ldb.ListFolders()
|
||||
if diff, equal := messagediff.PrettyDiff(actualFolderList, expectedFolderList); !equal {
|
||||
t.Fatalf("FolderList mismatch. Diff:\n%s", diff)
|
||||
}
|
||||
if l := len(globalList(s0)); l != 3 {
|
||||
t.Errorf("Incorrect global length %d != 3 for s0", l)
|
||||
@ -547,8 +548,9 @@ func TestListDropFolder(t *testing.T) {
|
||||
db.DropFolder(ldb, "test1")
|
||||
|
||||
expectedFolderList = []string{"test0"}
|
||||
if actualFolderList := ldb.ListFolders(); !reflect.DeepEqual(actualFolderList, expectedFolderList) {
|
||||
t.Fatalf("FolderList mismatch\nE: %v\nA: %v", expectedFolderList, actualFolderList)
|
||||
actualFolderList = ldb.ListFolders()
|
||||
if diff, equal := messagediff.PrettyDiff(actualFolderList, expectedFolderList); !equal {
|
||||
t.Fatalf("FolderList mismatch. Diff:\n%s", diff)
|
||||
}
|
||||
if l := len(globalList(s0)); l != 3 {
|
||||
t.Errorf("Incorrect global length %d != 3 for s0", l)
|
||||
|
@ -8,8 +8,9 @@ package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/d4l3k/messagediff"
|
||||
)
|
||||
|
||||
func TestJobQueue(t *testing.T) {
|
||||
@ -126,36 +127,36 @@ func TestBringToFront(t *testing.T) {
|
||||
q.Push("f4", 0, 0)
|
||||
|
||||
_, queued := q.Jobs()
|
||||
if !reflect.DeepEqual(queued, []string{"f1", "f2", "f3", "f4"}) {
|
||||
t.Errorf("Incorrect order %v at start", queued)
|
||||
if diff, equal := messagediff.PrettyDiff(queued, []string{"f1", "f2", "f3", "f4"}); !equal {
|
||||
t.Errorf("Order does not match. Diff:\n%s", diff)
|
||||
}
|
||||
|
||||
q.BringToFront("f1") // corner case: does nothing
|
||||
|
||||
_, queued = q.Jobs()
|
||||
if !reflect.DeepEqual(queued, []string{"f1", "f2", "f3", "f4"}) {
|
||||
t.Errorf("Incorrect order %v", queued)
|
||||
if diff, equal := messagediff.PrettyDiff(queued, []string{"f1", "f2", "f3", "f4"}); !equal {
|
||||
t.Errorf("Order does not match. Diff:\n%s", diff)
|
||||
}
|
||||
|
||||
q.BringToFront("f3")
|
||||
|
||||
_, queued = q.Jobs()
|
||||
if !reflect.DeepEqual(queued, []string{"f3", "f1", "f2", "f4"}) {
|
||||
t.Errorf("Incorrect order %v", queued)
|
||||
if diff, equal := messagediff.PrettyDiff(queued, []string{"f3", "f1", "f2", "f4"}); !equal {
|
||||
t.Errorf("Order does not match. Diff:\n%s", diff)
|
||||
}
|
||||
|
||||
q.BringToFront("f2")
|
||||
|
||||
_, queued = q.Jobs()
|
||||
if !reflect.DeepEqual(queued, []string{"f2", "f3", "f1", "f4"}) {
|
||||
t.Errorf("Incorrect order %v", queued)
|
||||
if diff, equal := messagediff.PrettyDiff(queued, []string{"f2", "f3", "f1", "f4"}); !equal {
|
||||
t.Errorf("Order does not match. Diff:\n%s", diff)
|
||||
}
|
||||
|
||||
q.BringToFront("f4") // corner case: last element
|
||||
|
||||
_, queued = q.Jobs()
|
||||
if !reflect.DeepEqual(queued, []string{"f4", "f2", "f3", "f1"}) {
|
||||
t.Errorf("Incorrect order %v", queued)
|
||||
if diff, equal := messagediff.PrettyDiff(queued, []string{"f4", "f2", "f3", "f1"}); !equal {
|
||||
t.Errorf("Order does not match. Diff:\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,7 +176,7 @@ func TestShuffle(t *testing.T) {
|
||||
}
|
||||
|
||||
t.Logf("%v", queued)
|
||||
if !reflect.DeepEqual(queued, []string{"f1", "f2", "f3", "f4"}) {
|
||||
if _, equal := messagediff.PrettyDiff(queued, []string{"f1", "f2", "f3", "f4"}); !equal {
|
||||
// The queue was shuffled
|
||||
return
|
||||
}
|
||||
@ -199,8 +200,8 @@ func TestSortBySize(t *testing.T) {
|
||||
}
|
||||
expected := []string{"f4", "f1", "f3", "f2"}
|
||||
|
||||
if !reflect.DeepEqual(actual, expected) {
|
||||
t.Errorf("SortSmallestFirst(): %#v != %#v", actual, expected)
|
||||
if diff, equal := messagediff.PrettyDiff(actual, expected); !equal {
|
||||
t.Errorf("SortSmallestFirst() diff:\n%s", diff)
|
||||
}
|
||||
|
||||
q.SortLargestFirst()
|
||||
@ -211,8 +212,8 @@ func TestSortBySize(t *testing.T) {
|
||||
}
|
||||
expected = []string{"f2", "f3", "f1", "f4"}
|
||||
|
||||
if !reflect.DeepEqual(actual, expected) {
|
||||
t.Errorf("SortLargestFirst(): %#v != %#v", actual, expected)
|
||||
if diff, equal := messagediff.PrettyDiff(actual, expected); !equal {
|
||||
t.Errorf("SortLargestFirst() diff:\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
@ -231,8 +232,8 @@ func TestSortByAge(t *testing.T) {
|
||||
}
|
||||
expected := []string{"f4", "f1", "f3", "f2"}
|
||||
|
||||
if !reflect.DeepEqual(actual, expected) {
|
||||
t.Errorf("SortOldestFirst(): %#v != %#v", actual, expected)
|
||||
if diff, equal := messagediff.PrettyDiff(actual, expected); !equal {
|
||||
t.Errorf("SortOldestFirst() diff:\n%s", diff)
|
||||
}
|
||||
|
||||
q.SortNewestFirst()
|
||||
@ -243,8 +244,8 @@ func TestSortByAge(t *testing.T) {
|
||||
}
|
||||
expected = []string{"f2", "f3", "f1", "f4"}
|
||||
|
||||
if !reflect.DeepEqual(actual, expected) {
|
||||
t.Errorf("SortNewestFirst(): %#v != %#v", actual, expected)
|
||||
if diff, equal := messagediff.PrettyDiff(actual, expected); !equal {
|
||||
t.Errorf("SortNewestFirst() diff:\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,6 +80,7 @@ func TestInWritableDirWindowsRemove(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.Chmod("testdata/windows/ro/readonlynew", 0700)
|
||||
defer os.RemoveAll("testdata")
|
||||
|
||||
create := func(name string) error {
|
||||
@ -123,6 +124,7 @@ func TestInWritableDirWindowsRename(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.Chmod("testdata/windows/ro/readonlynew", 0700)
|
||||
defer os.RemoveAll("testdata")
|
||||
|
||||
create := func(name string) error {
|
||||
|
@ -13,13 +13,13 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime"
|
||||
rdebug "runtime/debug"
|
||||
"sort"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/d4l3k/messagediff"
|
||||
"github.com/syncthing/syncthing/lib/ignore"
|
||||
"github.com/syncthing/syncthing/lib/osutil"
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
@ -120,8 +120,8 @@ func TestWalk(t *testing.T) {
|
||||
sort.Sort(fileList(tmp))
|
||||
files := fileList(tmp).testfiles()
|
||||
|
||||
if !reflect.DeepEqual(files, testdata) {
|
||||
t.Errorf("Walk returned unexpected data\nExpected: %v\nActual: %v", testdata, files)
|
||||
if diff, equal := messagediff.PrettyDiff(files, testdata); !equal {
|
||||
t.Errorf("Walk returned unexpected data. Diff:\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
|
22
vendor/github.com/d4l3k/messagediff/LICENSE
generated
vendored
Normal file
22
vendor/github.com/d4l3k/messagediff/LICENSE
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Tristan Rice
|
||||
|
||||
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.
|
||||
|
65
vendor/github.com/d4l3k/messagediff/README.md
generated
vendored
Normal file
65
vendor/github.com/d4l3k/messagediff/README.md
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
# messagediff [![Build Status](https://travis-ci.org/d4l3k/messagediff.svg?branch=master)](https://travis-ci.org/d4l3k/messagediff) [![Coverage Status](https://coveralls.io/repos/github/d4l3k/messagediff/badge.svg?branch=master)](https://coveralls.io/github/d4l3k/messagediff?branch=master) [![GoDoc](https://godoc.org/github.com/d4l3k/messagediff?status.svg)](https://godoc.org/github.com/d4l3k/messagediff)
|
||||
|
||||
A library for doing diffs of arbitrary Golang structs.
|
||||
|
||||
If the unsafe package is available messagediff will diff unexported fields in
|
||||
addition to exported fields. This is primarily used for testing purposes as it
|
||||
allows for providing informative error messages.
|
||||
|
||||
|
||||
## Example Usage
|
||||
In a normal file:
|
||||
```go
|
||||
package main
|
||||
|
||||
import "github.com/d4l3k/messagediff"
|
||||
|
||||
type someStruct struct {
|
||||
A, b int
|
||||
C []int
|
||||
}
|
||||
|
||||
func main() {
|
||||
a := someStruct{1, 2, []int{1}}
|
||||
b := someStruct{1, 3, []int{1, 2}}
|
||||
diff, equal := messagediff.PrettyDiff(a, b)
|
||||
/*
|
||||
diff =
|
||||
`added: .C[1] = 2
|
||||
modified: .b = 3`
|
||||
|
||||
equal = false
|
||||
*/
|
||||
}
|
||||
|
||||
```
|
||||
In a test:
|
||||
```go
|
||||
import "github.com/d4l3k/messagediff"
|
||||
|
||||
...
|
||||
|
||||
type someStruct struct {
|
||||
A, b int
|
||||
C []int
|
||||
}
|
||||
|
||||
func TestSomething(t *testing.T) {
|
||||
want := someStruct{1, 2, []int{1}}
|
||||
got := someStruct{1, 3, []int{1, 2}}
|
||||
if diff, equal := messagediff.PrettyDiff(want, got); !equal {
|
||||
t.Errorf("Something() = %#v\n%s", got, diff)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
See the `DeepDiff` function for using the diff results programmatically.
|
||||
|
||||
## License
|
||||
Copyright (c) 2015 [Tristan Rice](https://fn.lc) <rice@fn.lc>
|
||||
|
||||
messagediff is licensed under the MIT license. See the LICENSE file for more information.
|
||||
|
||||
bypass.go and bypasssafe.go are borrowed from
|
||||
[go-spew](https://github.com/davecgh/go-spew) and have a seperate copyright
|
||||
notice.
|
151
vendor/github.com/d4l3k/messagediff/bypass.go
generated
vendored
Normal file
151
vendor/github.com/d4l3k/messagediff/bypass.go
generated
vendored
Normal file
@ -0,0 +1,151 @@
|
||||
// Copyright (c) 2015 Dave Collins <dave@davec.name>
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
// NOTE: Due to the following build constraints, this file will only be compiled
|
||||
// when the code is not running on Google App Engine and "-tags disableunsafe"
|
||||
// is not added to the go build command line.
|
||||
// +build !appengine,!disableunsafe
|
||||
|
||||
package messagediff
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// UnsafeDisabled is a build-time constant which specifies whether or
|
||||
// not access to the unsafe package is available.
|
||||
UnsafeDisabled = false
|
||||
|
||||
// ptrSize is the size of a pointer on the current arch.
|
||||
ptrSize = unsafe.Sizeof((*byte)(nil))
|
||||
)
|
||||
|
||||
var (
|
||||
// offsetPtr, offsetScalar, and offsetFlag are the offsets for the
|
||||
// internal reflect.Value fields. These values are valid before golang
|
||||
// commit ecccf07e7f9d which changed the format. The are also valid
|
||||
// after commit 82f48826c6c7 which changed the format again to mirror
|
||||
// the original format. Code in the init function updates these offsets
|
||||
// as necessary.
|
||||
offsetPtr = uintptr(ptrSize)
|
||||
offsetScalar = uintptr(0)
|
||||
offsetFlag = uintptr(ptrSize * 2)
|
||||
|
||||
// flagKindWidth and flagKindShift indicate various bits that the
|
||||
// reflect package uses internally to track kind information.
|
||||
//
|
||||
// flagRO indicates whether or not the value field of a reflect.Value is
|
||||
// read-only.
|
||||
//
|
||||
// flagIndir indicates whether the value field of a reflect.Value is
|
||||
// the actual data or a pointer to the data.
|
||||
//
|
||||
// These values are valid before golang commit 90a7c3c86944 which
|
||||
// changed their positions. Code in the init function updates these
|
||||
// flags as necessary.
|
||||
flagKindWidth = uintptr(5)
|
||||
flagKindShift = uintptr(flagKindWidth - 1)
|
||||
flagRO = uintptr(1 << 0)
|
||||
flagIndir = uintptr(1 << 1)
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Older versions of reflect.Value stored small integers directly in the
|
||||
// ptr field (which is named val in the older versions). Versions
|
||||
// between commits ecccf07e7f9d and 82f48826c6c7 added a new field named
|
||||
// scalar for this purpose which unfortunately came before the flag
|
||||
// field, so the offset of the flag field is different for those
|
||||
// versions.
|
||||
//
|
||||
// This code constructs a new reflect.Value from a known small integer
|
||||
// and checks if the size of the reflect.Value struct indicates it has
|
||||
// the scalar field. When it does, the offsets are updated accordingly.
|
||||
vv := reflect.ValueOf(0xf00)
|
||||
if unsafe.Sizeof(vv) == (ptrSize * 4) {
|
||||
offsetScalar = ptrSize * 2
|
||||
offsetFlag = ptrSize * 3
|
||||
}
|
||||
|
||||
// Commit 90a7c3c86944 changed the flag positions such that the low
|
||||
// order bits are the kind. This code extracts the kind from the flags
|
||||
// field and ensures it's the correct type. When it's not, the flag
|
||||
// order has been changed to the newer format, so the flags are updated
|
||||
// accordingly.
|
||||
upf := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) + offsetFlag)
|
||||
upfv := *(*uintptr)(upf)
|
||||
flagKindMask := uintptr((1<<flagKindWidth - 1) << flagKindShift)
|
||||
if (upfv&flagKindMask)>>flagKindShift != uintptr(reflect.Int) {
|
||||
flagKindShift = 0
|
||||
flagRO = 1 << 5
|
||||
flagIndir = 1 << 6
|
||||
|
||||
// Commit adf9b30e5594 modified the flags to separate the
|
||||
// flagRO flag into two bits which specifies whether or not the
|
||||
// field is embedded. This causes flagIndir to move over a bit
|
||||
// and means that flagRO is the combination of either of the
|
||||
// original flagRO bit and the new bit.
|
||||
//
|
||||
// This code detects the change by extracting what used to be
|
||||
// the indirect bit to ensure it's set. When it's not, the flag
|
||||
// order has been changed to the newer format, so the flags are
|
||||
// updated accordingly.
|
||||
if upfv&flagIndir == 0 {
|
||||
flagRO = 3 << 5
|
||||
flagIndir = 1 << 7
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unsafeReflectValue converts the passed reflect.Value into a one that bypasses
|
||||
// the typical safety restrictions preventing access to unaddressable and
|
||||
// unexported data. It works by digging the raw pointer to the underlying
|
||||
// value out of the protected value and generating a new unprotected (unsafe)
|
||||
// reflect.Value to it.
|
||||
//
|
||||
// This allows us to check for implementations of the Stringer and error
|
||||
// interfaces to be used for pretty printing ordinarily unaddressable and
|
||||
// inaccessible values such as unexported struct fields.
|
||||
func unsafeReflectValue(v reflect.Value) (rv reflect.Value) {
|
||||
indirects := 1
|
||||
vt := v.Type()
|
||||
upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr)
|
||||
rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag))
|
||||
if rvf&flagIndir != 0 {
|
||||
vt = reflect.PtrTo(v.Type())
|
||||
indirects++
|
||||
} else if offsetScalar != 0 {
|
||||
// The value is in the scalar field when it's not one of the
|
||||
// reference types.
|
||||
switch vt.Kind() {
|
||||
case reflect.Uintptr:
|
||||
case reflect.Chan:
|
||||
case reflect.Func:
|
||||
case reflect.Map:
|
||||
case reflect.Ptr:
|
||||
case reflect.UnsafePointer:
|
||||
default:
|
||||
upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) +
|
||||
offsetScalar)
|
||||
}
|
||||
}
|
||||
|
||||
pv := reflect.NewAt(vt, upv)
|
||||
rv = pv
|
||||
for i := 0; i < indirects; i++ {
|
||||
rv = rv.Elem()
|
||||
}
|
||||
return rv
|
||||
}
|
37
vendor/github.com/d4l3k/messagediff/bypasssafe.go
generated
vendored
Normal file
37
vendor/github.com/d4l3k/messagediff/bypasssafe.go
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
// Copyright (c) 2015 Dave Collins <dave@davec.name>
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
// NOTE: Due to the following build constraints, this file will only be compiled
|
||||
// when either the code is running on Google App Engine or "-tags disableunsafe"
|
||||
// is added to the go build command line.
|
||||
// +build appengine disableunsafe
|
||||
|
||||
package messagediff
|
||||
|
||||
import "reflect"
|
||||
|
||||
const (
|
||||
// UnsafeDisabled is a build-time constant which specifies whether or
|
||||
// not access to the unsafe package is available.
|
||||
UnsafeDisabled = true
|
||||
)
|
||||
|
||||
// unsafeReflectValue typically converts the passed reflect.Value into a one
|
||||
// that bypasses the typical safety restrictions preventing access to
|
||||
// unaddressable and unexported data. However, doing this relies on access to
|
||||
// the unsafe package. This is a stub version which simply returns the passed
|
||||
// reflect.Value when the unsafe package is not available.
|
||||
func unsafeReflectValue(v reflect.Value) reflect.Value {
|
||||
return v
|
||||
}
|
188
vendor/github.com/d4l3k/messagediff/messagediff.go
generated
vendored
Normal file
188
vendor/github.com/d4l3k/messagediff/messagediff.go
generated
vendored
Normal file
@ -0,0 +1,188 @@
|
||||
package messagediff
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// PrettyDiff does a deep comparison and returns the nicely formated results.
|
||||
func PrettyDiff(a, b interface{}) (string, bool) {
|
||||
d, equal := DeepDiff(a, b)
|
||||
var dstr []string
|
||||
for path, added := range d.Added {
|
||||
dstr = append(dstr, fmt.Sprintf("added: %s = %#v\n", path.String(), added))
|
||||
}
|
||||
for path, removed := range d.Removed {
|
||||
dstr = append(dstr, fmt.Sprintf("removed: %s = %#v\n", path.String(), removed))
|
||||
}
|
||||
for path, modified := range d.Modified {
|
||||
dstr = append(dstr, fmt.Sprintf("modified: %s = %#v\n", path.String(), modified))
|
||||
}
|
||||
sort.Strings(dstr)
|
||||
return strings.Join(dstr, ""), equal
|
||||
}
|
||||
|
||||
// DeepDiff does a deep comparison and returns the results.
|
||||
func DeepDiff(a, b interface{}) (*Diff, bool) {
|
||||
d := newdiff()
|
||||
return d, diff(a, b, nil, d)
|
||||
}
|
||||
|
||||
func newdiff() *Diff {
|
||||
return &Diff{
|
||||
Added: make(map[*Path]interface{}),
|
||||
Removed: make(map[*Path]interface{}),
|
||||
Modified: make(map[*Path]interface{}),
|
||||
}
|
||||
}
|
||||
|
||||
func diff(a, b interface{}, path Path, d *Diff) bool {
|
||||
aVal := reflect.ValueOf(a)
|
||||
bVal := reflect.ValueOf(b)
|
||||
if !aVal.IsValid() && !bVal.IsValid() {
|
||||
// Both are nil.
|
||||
return true
|
||||
}
|
||||
if !aVal.IsValid() || !bVal.IsValid() {
|
||||
// One is nil and the other isn't.
|
||||
d.Modified[&path] = b
|
||||
return false
|
||||
}
|
||||
if aVal.Type() != bVal.Type() {
|
||||
d.Modified[&path] = b
|
||||
return false
|
||||
}
|
||||
kind := aVal.Type().Kind()
|
||||
equal := true
|
||||
switch kind {
|
||||
case reflect.Array, reflect.Slice:
|
||||
aLen := aVal.Len()
|
||||
bLen := bVal.Len()
|
||||
for i := 0; i < min(aLen, bLen); i++ {
|
||||
localPath := append(path, SliceIndex(i))
|
||||
if eq := diff(aVal.Index(i).Interface(), bVal.Index(i).Interface(), localPath, d); !eq {
|
||||
equal = false
|
||||
}
|
||||
}
|
||||
if aLen > bLen {
|
||||
for i := bLen; i < aLen; i++ {
|
||||
localPath := append(path, SliceIndex(i))
|
||||
d.Removed[&localPath] = aVal.Index(i).Interface()
|
||||
equal = false
|
||||
}
|
||||
} else if aLen < bLen {
|
||||
for i := aLen; i < bLen; i++ {
|
||||
localPath := append(path, SliceIndex(i))
|
||||
d.Added[&localPath] = bVal.Index(i).Interface()
|
||||
equal = false
|
||||
}
|
||||
}
|
||||
case reflect.Map:
|
||||
for _, key := range aVal.MapKeys() {
|
||||
aI := aVal.MapIndex(key)
|
||||
bI := bVal.MapIndex(key)
|
||||
localPath := append(path, MapKey{key.Interface()})
|
||||
if !bI.IsValid() {
|
||||
d.Removed[&localPath] = aI.Interface()
|
||||
equal = false
|
||||
} else if eq := diff(aI.Interface(), bI.Interface(), localPath, d); !eq {
|
||||
equal = false
|
||||
}
|
||||
}
|
||||
for _, key := range bVal.MapKeys() {
|
||||
aI := aVal.MapIndex(key)
|
||||
if !aI.IsValid() {
|
||||
bI := bVal.MapIndex(key)
|
||||
localPath := append(path, MapKey{key.Interface()})
|
||||
d.Added[&localPath] = bI.Interface()
|
||||
equal = false
|
||||
}
|
||||
}
|
||||
case reflect.Struct:
|
||||
typ := aVal.Type()
|
||||
for i := 0; i < typ.NumField(); i++ {
|
||||
index := []int{i}
|
||||
field := typ.FieldByIndex(index)
|
||||
localPath := append(path, StructField(field.Name))
|
||||
aI := unsafeReflectValue(aVal.FieldByIndex(index)).Interface()
|
||||
bI := unsafeReflectValue(bVal.FieldByIndex(index)).Interface()
|
||||
if eq := diff(aI, bI, localPath, d); !eq {
|
||||
equal = false
|
||||
}
|
||||
}
|
||||
case reflect.Ptr:
|
||||
aVal = aVal.Elem()
|
||||
bVal = bVal.Elem()
|
||||
if !aVal.IsValid() && !bVal.IsValid() {
|
||||
// Both are nil.
|
||||
equal = true
|
||||
} else if !aVal.IsValid() || !bVal.IsValid() {
|
||||
// One is nil and the other isn't.
|
||||
d.Modified[&path] = b
|
||||
equal = false
|
||||
} else {
|
||||
equal = diff(aVal.Interface(), bVal.Interface(), path, d)
|
||||
}
|
||||
default:
|
||||
if reflect.DeepEqual(a, b) {
|
||||
equal = true
|
||||
} else {
|
||||
d.Modified[&path] = b
|
||||
equal = false
|
||||
}
|
||||
}
|
||||
return equal
|
||||
}
|
||||
|
||||
func min(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// Diff represents a change in a struct.
|
||||
type Diff struct {
|
||||
Added, Removed, Modified map[*Path]interface{}
|
||||
}
|
||||
|
||||
// Path represents a path to a changed datum.
|
||||
type Path []PathNode
|
||||
|
||||
func (p Path) String() string {
|
||||
var out string
|
||||
for _, n := range p {
|
||||
out += n.String()
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// PathNode represents one step in the path.
|
||||
type PathNode interface {
|
||||
String() string
|
||||
}
|
||||
|
||||
// StructField is a path element representing a field of a struct.
|
||||
type StructField string
|
||||
|
||||
func (n StructField) String() string {
|
||||
return fmt.Sprintf(".%s", string(n))
|
||||
}
|
||||
|
||||
// MapKey is a path element representing a key of a map.
|
||||
type MapKey struct {
|
||||
Key interface{}
|
||||
}
|
||||
|
||||
func (n MapKey) String() string {
|
||||
return fmt.Sprintf("[%#v]", n.Key)
|
||||
}
|
||||
|
||||
// SliceIndex is a path element representing a index of a slice.
|
||||
type SliceIndex int
|
||||
|
||||
func (n SliceIndex) String() string {
|
||||
return fmt.Sprintf("[%d]", n)
|
||||
}
|
116
vendor/github.com/d4l3k/messagediff/messagediff_test.go
generated
vendored
Normal file
116
vendor/github.com/d4l3k/messagediff/messagediff_test.go
generated
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
package messagediff
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
type testStruct struct {
|
||||
A, b int
|
||||
C []int
|
||||
}
|
||||
|
||||
func TestPrettyDiff(t *testing.T) {
|
||||
testData := []struct {
|
||||
a, b interface{}
|
||||
diff string
|
||||
equal bool
|
||||
}{
|
||||
{
|
||||
true,
|
||||
false,
|
||||
"modified: = false\n",
|
||||
false,
|
||||
},
|
||||
{
|
||||
true,
|
||||
0,
|
||||
"modified: = 0\n",
|
||||
false,
|
||||
},
|
||||
{
|
||||
[]int{0, 1, 2},
|
||||
[]int{0, 1, 2, 3},
|
||||
"added: [3] = 3\n",
|
||||
false,
|
||||
},
|
||||
{
|
||||
[]int{0, 1, 2, 3},
|
||||
[]int{0, 1, 2},
|
||||
"removed: [3] = 3\n",
|
||||
false,
|
||||
},
|
||||
{
|
||||
[]int{0},
|
||||
[]int{1},
|
||||
"modified: [0] = 1\n",
|
||||
false,
|
||||
},
|
||||
{
|
||||
&[]int{0},
|
||||
&[]int{1},
|
||||
"modified: [0] = 1\n",
|
||||
false,
|
||||
},
|
||||
{
|
||||
map[string]int{"a": 1, "b": 2},
|
||||
map[string]int{"b": 4, "c": 3},
|
||||
"added: [\"c\"] = 3\nmodified: [\"b\"] = 4\nremoved: [\"a\"] = 1\n",
|
||||
false,
|
||||
},
|
||||
{
|
||||
testStruct{1, 2, []int{1}},
|
||||
testStruct{1, 3, []int{1, 2}},
|
||||
"added: .C[1] = 2\nmodified: .b = 3\n",
|
||||
false,
|
||||
},
|
||||
{
|
||||
nil,
|
||||
nil,
|
||||
"",
|
||||
true,
|
||||
},
|
||||
{
|
||||
&time.Time{},
|
||||
nil,
|
||||
"modified: = <nil>\n",
|
||||
false,
|
||||
},
|
||||
{
|
||||
time.Time{},
|
||||
time.Time{},
|
||||
"",
|
||||
true,
|
||||
},
|
||||
{
|
||||
time.Date(1970, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||
time.Time{},
|
||||
"modified: .loc = (*time.Location)(nil)\nmodified: .sec = 0\n",
|
||||
false,
|
||||
},
|
||||
}
|
||||
for i, td := range testData {
|
||||
diff, equal := PrettyDiff(td.a, td.b)
|
||||
if diff != td.diff {
|
||||
t.Errorf("%d. PrettyDiff(%#v, %#v) diff = %#v; not %#v", i, td.a, td.b, diff, td.diff)
|
||||
}
|
||||
if equal != td.equal {
|
||||
t.Errorf("%d. PrettyDiff(%#v, %#v) equal = %#v; not %#v", i, td.a, td.b, equal, td.equal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPathString(t *testing.T) {
|
||||
testData := []struct {
|
||||
in Path
|
||||
want string
|
||||
}{{
|
||||
Path{StructField("test"), SliceIndex(1), MapKey{"blue"}, MapKey{12.3}},
|
||||
".test[1][\"blue\"][12.3]",
|
||||
}}
|
||||
for i, td := range testData {
|
||||
if out := td.in.String(); out != td.want {
|
||||
t.Errorf("%d. %#v.String() = %#v; not %#v", i, td.in, out, td.want)
|
||||
}
|
||||
}
|
||||
}
|
6
vendor/manifest
vendored
6
vendor/manifest
vendored
@ -25,6 +25,12 @@
|
||||
"revision": "b6e0c321c9b5b28ba5ee21e828323e4b982c6976",
|
||||
"branch": "master"
|
||||
},
|
||||
{
|
||||
"importpath": "github.com/d4l3k/messagediff",
|
||||
"repository": "https://github.com/d4l3k/messagediff",
|
||||
"revision": "bf29d7cd9038386a5b4a22e2d73c8fb20ae14602",
|
||||
"branch": "master"
|
||||
},
|
||||
{
|
||||
"importpath": "github.com/golang/snappy",
|
||||
"repository": "https://github.com/golang/snappy",
|
||||
|
Loading…
Reference in New Issue
Block a user