vendor: Update everything

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4620
This commit is contained in:
Jakob Borg
2017-12-29 11:38:00 +00:00
parent 1296a22069
commit c24bf7ea55
1070 changed files with 294926 additions and 488191 deletions

View File

@@ -64,9 +64,8 @@ If expected is omited, then the message looks like:
func Message(actual interface{}, message string, expected ...interface{}) string {
if len(expected) == 0 {
return fmt.Sprintf("Expected\n%s\n%s", Object(actual, 1), message)
} else {
return fmt.Sprintf("Expected\n%s\n%s\n%s", Object(actual, 1), message, Object(expected[0], 1))
}
return fmt.Sprintf("Expected\n%s\n%s\n%s", Object(actual, 1), message, Object(expected[0], 1))
}
/*
@@ -124,7 +123,7 @@ func findFirstMismatch(a, b string) int {
bSlice := strings.Split(b, "")
for index, str := range aSlice {
if index > len(b) - 1 {
if index > len(bSlice)-1 {
return index
}
if str != bSlice[index] {
@@ -265,9 +264,8 @@ func formatValue(value reflect.Value, indentation uint) string {
default:
if value.CanInterface() {
return fmt.Sprintf("%#v", value.Interface())
} else {
return fmt.Sprintf("%#v", value)
}
return fmt.Sprintf("%#v", value)
}
}
@@ -311,9 +309,8 @@ func formatSlice(v reflect.Value, indentation uint) string {
if longest > longFormThreshold {
indenter := strings.Repeat(Indent, int(indentation))
return fmt.Sprintf("[\n%s%s,\n%s]", indenter+Indent, strings.Join(result, ",\n"+indenter+Indent), indenter)
} else {
return fmt.Sprintf("[%s]", strings.Join(result, ", "))
}
return fmt.Sprintf("[%s]", strings.Join(result, ", "))
}
func formatMap(v reflect.Value, indentation uint) string {
@@ -332,9 +329,8 @@ func formatMap(v reflect.Value, indentation uint) string {
if longest > longFormThreshold {
indenter := strings.Repeat(Indent, int(indentation))
return fmt.Sprintf("{\n%s%s,\n%s}", indenter+Indent, strings.Join(result, ",\n"+indenter+Indent), indenter)
} else {
return fmt.Sprintf("{%s}", strings.Join(result, ", "))
}
return fmt.Sprintf("{%s}", strings.Join(result, ", "))
}
func formatStruct(v reflect.Value, indentation uint) string {
@@ -355,9 +351,8 @@ func formatStruct(v reflect.Value, indentation uint) string {
if longest > longFormThreshold {
indenter := strings.Repeat(Indent, int(indentation))
return fmt.Sprintf("{\n%s%s,\n%s}", indenter+Indent, strings.Join(result, ",\n"+indenter+Indent), indenter)
} else {
return fmt.Sprintf("{%s}", strings.Join(result, ", "))
}
return fmt.Sprintf("{%s}", strings.Join(result, ", "))
}
func isNilValue(a reflect.Value) bool {

View File

@@ -52,6 +52,23 @@ func BufferWithBytes(bytes []byte) *Buffer {
}
}
/*
BufferReader returns a new gbytes.Buffer that wraps a reader. The reader's contents are read into
the Buffer via io.Copy
*/
func BufferReader(reader io.Reader) *Buffer {
b := &Buffer{
lock: &sync.Mutex{},
}
go func() {
io.Copy(b, reader)
b.Close()
}()
return b
}
/*
Write implements the io.Writer interface
*/
@@ -223,7 +240,6 @@ func (b *Buffer) didSay(re *regexp.Regexp) (bool, []byte) {
if loc != nil {
b.readCursor += uint64(loc[1])
return true, copyOfUnreadBytes
} else {
return false, copyOfUnreadBytes
}
return false, copyOfUnreadBytes
}

85
vendor/github.com/onsi/gomega/gbytes/io_wrappers.go generated vendored Normal file
View File

@@ -0,0 +1,85 @@
package gbytes
import (
"errors"
"io"
"time"
)
// ErrTimeout is returned by TimeoutCloser, TimeoutReader, and TimeoutWriter when the underlying Closer/Reader/Writer does not return within the specified timeout
var ErrTimeout = errors.New("timeout occurred")
// TimeoutCloser returns an io.Closer that wraps the passed-in io.Closer. If the underlying Closer fails to close within the alloted timeout ErrTimeout is returned.
func TimeoutCloser(c io.Closer, timeout time.Duration) io.Closer {
return timeoutReaderWriterCloser{c: c, d: timeout}
}
// TimeoutReader returns an io.Reader that wraps the passed-in io.Reader. If the underlying Reader fails to read within the alloted timeout ErrTimeout is returned.
func TimeoutReader(r io.Reader, timeout time.Duration) io.Reader {
return timeoutReaderWriterCloser{r: r, d: timeout}
}
// TimeoutWriter returns an io.Writer that wraps the passed-in io.Writer. If the underlying Writer fails to write within the alloted timeout ErrTimeout is returned.
func TimeoutWriter(w io.Writer, timeout time.Duration) io.Writer {
return timeoutReaderWriterCloser{w: w, d: timeout}
}
type timeoutReaderWriterCloser struct {
c io.Closer
w io.Writer
r io.Reader
d time.Duration
}
func (t timeoutReaderWriterCloser) Close() error {
done := make(chan struct{})
var err error
go func() {
err = t.c.Close()
close(done)
}()
select {
case <-done:
return err
case <-time.After(t.d):
return ErrTimeout
}
}
func (t timeoutReaderWriterCloser) Read(p []byte) (int, error) {
done := make(chan struct{})
var n int
var err error
go func() {
n, err = t.r.Read(p)
close(done)
}()
select {
case <-done:
return n, err
case <-time.After(t.d):
return 0, ErrTimeout
}
}
func (t timeoutReaderWriterCloser) Write(p []byte) (int, error) {
done := make(chan struct{})
var n int
var err error
go func() {
n, err = t.w.Write(p)
close(done)
}()
select {
case <-done:
return n, err
case <-time.After(t.d):
return 0, ErrTimeout
}
}

View File

@@ -3,12 +3,14 @@ package gexec
import (
"errors"
"fmt"
"go/build"
"io/ioutil"
"os"
"os/exec"
"path"
"path/filepath"
"runtime"
"strings"
"sync"
)
@@ -21,17 +23,18 @@ var (
Build uses go build to compile the package at packagePath. The resulting binary is saved off in a temporary directory.
A path pointing to this binary is returned.
Build uses the $GOPATH set in your environment. It passes the variadic args on to `go build`.
Build uses the $GOPATH set in your environment. If $GOPATH is not set and you are using Go 1.8+,
it will use the default GOPATH instead. It passes the variadic args on to `go build`.
*/
func Build(packagePath string, args ...string) (compiledPath string, err error) {
return doBuild(os.Getenv("GOPATH"), packagePath, nil, args...)
return doBuild(build.Default.GOPATH, packagePath, nil, args...)
}
/*
BuildWithEnvironment is identical to Build but allows you to specify env vars to be set at build time.
*/
func BuildWithEnvironment(packagePath string, env []string, args ...string) (compiledPath string, err error) {
return doBuild(os.Getenv("GOPATH"), packagePath, env, args...)
return doBuild(build.Default.GOPATH, packagePath, env, args...)
}
/*
@@ -41,6 +44,16 @@ func BuildIn(gopath string, packagePath string, args ...string) (compiledPath st
return doBuild(gopath, packagePath, nil, args...)
}
func replaceGoPath(environ []string, newGoPath string) []string {
newEnviron := []string{}
for _, v := range environ {
if !strings.HasPrefix(v, "GOPATH=") {
newEnviron = append(newEnviron, v)
}
}
return append(newEnviron, "GOPATH="+newGoPath)
}
func doBuild(gopath, packagePath string, env []string, args ...string) (compiledPath string, err error) {
tmpDir, err := temporaryDirectory()
if err != nil {
@@ -60,7 +73,7 @@ func doBuild(gopath, packagePath string, env []string, args ...string) (compiled
cmdArgs = append(cmdArgs, "-o", executable, packagePath)
build := exec.Command("go", cmdArgs...)
build.Env = append([]string{"GOPATH=" + gopath}, os.Environ()...)
build.Env = replaceGoPath(os.Environ(), gopath)
build.Env = append(build.Env, env...)
output, err := build.CombinedOutput()

View File

@@ -62,9 +62,8 @@ func (m *exitMatcher) Match(actual interface{}) (success bool, err error) {
func (m *exitMatcher) FailureMessage(actual interface{}) (message string) {
if m.actualExitCode == -1 {
return "Expected process to exit. It did not."
} else {
return format.Message(m.actualExitCode, "to match exit code:", m.exitCode)
}
return format.Message(m.actualExitCode, "to match exit code:", m.exitCode)
}
func (m *exitMatcher) NegatedFailureMessage(actual interface{}) (message string) {
@@ -73,9 +72,8 @@ func (m *exitMatcher) NegatedFailureMessage(actual interface{}) (message string)
} else {
if m.exitCode == -1 {
return "Expected process not to exit. It did."
} else {
return format.Message(m.actualExitCode, "not to match exit code:", m.exitCode)
}
return format.Message(m.actualExitCode, "not to match exit code:", m.exitCode)
}
}

View File

@@ -7,7 +7,6 @@ import (
"io"
"os"
"os/exec"
"reflect"
"sync"
"syscall"
@@ -78,11 +77,11 @@ func Start(command *exec.Cmd, outWriter io.Writer, errWriter io.Writer) (*Sessio
commandOut, commandErr = session.Out, session.Err
if outWriter != nil && !reflect.ValueOf(outWriter).IsNil() {
if outWriter != nil {
commandOut = io.MultiWriter(commandOut, outWriter)
}
if errWriter != nil && !reflect.ValueOf(errWriter).IsNil() {
if errWriter != nil {
commandErr = io.MultiWriter(commandErr, errWriter)
}

View File

@@ -24,11 +24,12 @@ import (
"github.com/onsi/gomega/types"
)
const GOMEGA_VERSION = "1.0"
const GOMEGA_VERSION = "1.2.0"
const nilFailHandlerPanic = `You are trying to make an assertion, but Gomega's fail handler is nil.
If you're using Ginkgo then you probably forgot to put your assertion in an It().
Alternatively, you may have forgotten to register a fail handler with RegisterFailHandler() or RegisterTestingT().
Depending on your vendoring solution you may be inadvertently importing gomega and subpackages (e.g. ghhtp, gexec,...) from different locations.
`
var globalFailHandler types.GomegaFailHandler
@@ -45,7 +46,11 @@ func RegisterFailHandler(handler types.GomegaFailHandler) {
}
//RegisterTestingT connects Gomega to Golang's XUnit style
//Testing.T tests. You'll need to call this at the top of each XUnit style test:
//Testing.T tests. It is now deprecated and you should use NewGomegaWithT() instead.
//
//Legacy Documentation:
//
//You'll need to call this at the top of each XUnit style test:
//
// func TestFarmHasCow(t *testing.T) {
// RegisterTestingT(t)
@@ -58,6 +63,8 @@ func RegisterFailHandler(handler types.GomegaFailHandler) {
// pass `t` down to the matcher itself). This means that you cannot run the XUnit style tests
// in parallel as the global fail handler cannot point to more than one testing.T at a time.
//
// NewGomegaWithT() does not have this limitation
//
// (As an aside: Ginkgo gets around this limitation by running parallel tests in different *processes*).
func RegisterTestingT(t types.GomegaTestingT) {
RegisterFailHandler(testingtsupport.BuildTestingTGomegaFailHandler(t))
@@ -308,6 +315,60 @@ type GomegaAssertion interface {
//OmegaMatcher is deprecated in favor of the better-named and better-organized types.GomegaMatcher but sticks around to support existing code that uses it
type OmegaMatcher types.GomegaMatcher
//GomegaWithT wraps a *testing.T and provides `Expect`, `Eventually`, and `Consistently` methods. This allows you to leverage
//Gomega's rich ecosystem of matchers in standard `testing` test suites.
//
//Use `NewGomegaWithT` to instantiate a `GomegaWithT`
type GomegaWithT struct {
t types.GomegaTestingT
}
//NewGomegaWithT takes a *testing.T and returngs a `GomegaWithT` allowing you to use `Expect`, `Eventually`, and `Consistently` along with
//Gomega's rich ecosystem of matchers in standard `testing` test suits.
//
// func TestFarmHasCow(t *testing.T) {
// g := GomegaWithT(t)
//
// f := farm.New([]string{"Cow", "Horse"})
// g.Expect(f.HasCow()).To(BeTrue(), "Farm should have cow")
// }
func NewGomegaWithT(t types.GomegaTestingT) *GomegaWithT {
return &GomegaWithT{
t: t,
}
}
//See documentation for Expect
func (g *GomegaWithT) Expect(actual interface{}, extra ...interface{}) GomegaAssertion {
return assertion.New(actual, testingtsupport.BuildTestingTGomegaFailHandler(g.t), 0, extra...)
}
//See documentation for Eventually
func (g *GomegaWithT) Eventually(actual interface{}, intervals ...interface{}) GomegaAsyncAssertion {
timeoutInterval := defaultEventuallyTimeout
pollingInterval := defaultEventuallyPollingInterval
if len(intervals) > 0 {
timeoutInterval = toDuration(intervals[0])
}
if len(intervals) > 1 {
pollingInterval = toDuration(intervals[1])
}
return asyncassertion.New(asyncassertion.AsyncAssertionTypeEventually, actual, testingtsupport.BuildTestingTGomegaFailHandler(g.t), timeoutInterval, pollingInterval, 0)
}
//See documentation for Consistently
func (g *GomegaWithT) Consistently(actual interface{}, intervals ...interface{}) GomegaAsyncAssertion {
timeoutInterval := defaultConsistentlyDuration
pollingInterval := defaultConsistentlyPollingInterval
if len(intervals) > 0 {
timeoutInterval = toDuration(intervals[0])
}
if len(intervals) > 1 {
pollingInterval = toDuration(intervals[1])
}
return asyncassertion.New(asyncassertion.AsyncAssertionTypeConsistently, actual, testingtsupport.BuildTestingTGomegaFailHandler(g.t), timeoutInterval, pollingInterval, 0)
}
func toDuration(input interface{}) time.Duration {
duration, ok := input.(time.Duration)
if ok {

View File

@@ -14,7 +14,7 @@ import (
//MatchAllFields succeeds if every field of a struct matches the field matcher associated with
//it, and every element matcher is matched.
// Expect([]string{"a", "b"}).To(MatchAllFields(idFn, gstruct.Fields{
// Expect([]string{"a", "b"}).To(MatchAllFields(gstruct.Fields{
// "a": BeEqual("a"),
// "b": BeEqual("b"),
// })
@@ -26,7 +26,7 @@ func MatchAllFields(fields Fields) types.GomegaMatcher {
//MatchFields succeeds if each element of a struct matches the field matcher associated with
//it. It can ignore extra fields and/or missing fields.
// Expect([]string{"a", "c"}).To(MatchFields(idFn, IgnoreMissing|IgnoreExtra, gstruct.Fields{
// Expect([]string{"a", "c"}).To(MatchFields(IgnoreMissing|IgnoreExtra, gstruct.Fields{
// "a": BeEqual("a")
// "b": BeEqual("b"),
// })

View File

@@ -9,7 +9,7 @@ import (
)
type gomegaTestingT interface {
Errorf(format string, args ...interface{})
Fatalf(format string, args ...interface{})
}
func BuildTestingTGomegaFailHandler(t gomegaTestingT) types.GomegaFailHandler {
@@ -19,7 +19,7 @@ func BuildTestingTGomegaFailHandler(t gomegaTestingT) types.GomegaFailHandler {
skip = callerSkip[0]
}
stackTrace := pruneStack(string(debug.Stack()), skip)
t.Errorf("\n%s\n%s", stackTrace, message)
t.Fatalf("\n%s\n%s", stackTrace, message)
}
}

View File

@@ -214,6 +214,15 @@ func MatchJSON(json interface{}) types.GomegaMatcher {
}
}
//MatchXML succeeds if actual is a string or stringer of XML that matches
//the expected XML. The XMLs are decoded and the resulting objects are compared via
//reflect.DeepEqual so things like whitespaces shouldn't matter.
func MatchXML(xml interface{}) types.GomegaMatcher {
return &matchers.MatchXMLMatcher{
XMLToMatch: xml,
}
}
//MatchYAML succeeds if actual is a string or stringer of YAML that matches
//the expected YAML. The YAML's are decoded and the resulting objects are compared via
//reflect.DeepEqual so things like key-ordering and whitespace shouldn't matter.
@@ -260,7 +269,7 @@ func ContainElement(element interface{}) types.GomegaMatcher {
}
}
//ConsistOf succeeds if actual contains preciely the elements passed into the matcher. The ordering of the elements does not matter.
//ConsistOf succeeds if actual contains precisely the elements passed into the matcher. The ordering of the elements does not matter.
//By default ConsistOf() uses Equal() to match the elements, however custom matchers can be passed in instead. Here are some examples:
//
// Ω([]string{"Foo", "FooBar"}).Should(ConsistOf("FooBar", "Foo"))
@@ -357,13 +366,13 @@ func BeAnExistingFile() types.GomegaMatcher {
return &matchers.BeAnExistingFileMatcher{}
}
//BeARegularFile succeeds iff a file exists and is a regular file.
//BeARegularFile succeeds if a file exists and is a regular file.
//Actual must be a string representing the abs path to the file being checked.
func BeARegularFile() types.GomegaMatcher {
return &matchers.BeARegularFileMatcher{}
}
//BeADirectory succeeds iff a file exists and is a directory.
//BeADirectory succeeds if a file exists and is a directory.
//Actual must be a string representing the abs path to the file being checked.
func BeADirectory() types.GomegaMatcher {
return &matchers.BeADirectoryMatcher{}

View File

@@ -57,8 +57,7 @@ func (m *AndMatcher) MatchMayChangeInTheFuture(actual interface{}) bool {
}
}
return false // none of were going to change
} else {
// one of the matchers failed.. it must be able to change in order to affect the result
return oraclematcher.MatchMayChangeInTheFuture(m.firstFailedMatcher, actual)
}
// one of the matchers failed.. it must be able to change in order to affect the result
return oraclematcher.MatchMayChangeInTheFuture(m.firstFailedMatcher, actual)
}

View File

@@ -0,0 +1,14 @@
package matchers
import (
"encoding/xml"
"strings"
)
type attributesSlice []xml.Attr
func (attrs attributesSlice) Len() int { return len(attrs) }
func (attrs attributesSlice) Less(i, j int) bool {
return strings.Compare(attrs[i].Name.Local, attrs[j].Name.Local) == -1
}
func (attrs attributesSlice) Swap(i, j int) { attrs[i], attrs[j] = attrs[j], attrs[i] }

View File

@@ -2,8 +2,9 @@ package matchers
import (
"fmt"
"github.com/onsi/gomega/format"
"reflect"
"github.com/onsi/gomega/format"
)
type BeClosedMatcher struct {

View File

@@ -2,6 +2,7 @@ package matchers
import (
"fmt"
"github.com/onsi/gomega/format"
)

View File

@@ -2,8 +2,9 @@ package matchers
import (
"fmt"
"github.com/onsi/gomega/format"
"reflect"
"github.com/onsi/gomega/format"
)
type BeEquivalentToMatcher struct {

View File

@@ -2,6 +2,7 @@ package matchers
import (
"fmt"
"github.com/onsi/gomega/format"
)

View File

@@ -2,8 +2,9 @@ package matchers
import (
"fmt"
"github.com/onsi/gomega/format"
"time"
"github.com/onsi/gomega/format"
)
type BeTemporallyMatcher struct {

View File

@@ -2,6 +2,7 @@ package matchers
import (
"fmt"
"github.com/onsi/gomega/format"
)

View File

@@ -1,8 +1,9 @@
package matchers
import (
"github.com/onsi/gomega/format"
"reflect"
"github.com/onsi/gomega/format"
)
type BeZeroMatcher struct {

View File

@@ -2,8 +2,9 @@ package matchers
import (
"fmt"
"github.com/onsi/gomega/format"
"strings"
"github.com/onsi/gomega/format"
)
type ContainSubstringMatcher struct {

View File

@@ -1,6 +1,7 @@
package matchers
import (
"bytes"
"fmt"
"reflect"
@@ -15,6 +16,14 @@ func (matcher *EqualMatcher) Match(actual interface{}) (success bool, err error)
if actual == nil && matcher.Expected == nil {
return false, fmt.Errorf("Refusing to compare <nil> to <nil>.\nBe explicit and use BeNil() instead. This is to avoid mistakes where both sides of an assertion are erroneously uninitialized.")
}
// Shortcut for byte slices.
// Comparing long byte slices with reflect.DeepEqual is very slow,
// so use bytes.Equal if actual and expected are both byte slices.
if actualByteSlice, ok := actual.([]byte); ok {
if expectedByteSlice, ok := matcher.Expected.([]byte); ok {
return bytes.Equal(actualByteSlice, expectedByteSlice), nil
}
}
return reflect.DeepEqual(actual, matcher.Expected), nil
}

View File

@@ -2,8 +2,9 @@ package matchers
import (
"fmt"
"github.com/onsi/gomega/format"
"reflect"
"github.com/onsi/gomega/format"
)
type HaveKeyMatcher struct {

View File

@@ -2,8 +2,9 @@ package matchers
import (
"fmt"
"github.com/onsi/gomega/format"
"reflect"
"github.com/onsi/gomega/format"
)
type HaveKeyWithValueMatcher struct {

View File

@@ -2,6 +2,7 @@ package matchers
import (
"fmt"
"github.com/onsi/gomega/format"
)

View File

@@ -2,6 +2,7 @@ package matchers
import (
"fmt"
"github.com/onsi/gomega/format"
)

View File

@@ -2,6 +2,7 @@ package matchers
import (
"fmt"
"github.com/onsi/gomega/format"
)

View File

@@ -2,8 +2,9 @@ package matchers
import (
"fmt"
"github.com/onsi/gomega/format"
"reflect"
"github.com/onsi/gomega/format"
)
type MatchErrorMatcher struct {
@@ -21,14 +22,14 @@ func (matcher *MatchErrorMatcher) Match(actual interface{}) (success bool, err e
actualErr := actual.(error)
if isString(matcher.Expected) {
return reflect.DeepEqual(actualErr.Error(), matcher.Expected), nil
}
if isError(matcher.Expected) {
return reflect.DeepEqual(actualErr, matcher.Expected), nil
}
if isString(matcher.Expected) {
return actualErr.Error() == matcher.Expected, nil
}
var subMatcher omegaMatcher
var hasSubMatcher bool
if matcher.Expected != nil {

View File

@@ -5,12 +5,14 @@ import (
"encoding/json"
"fmt"
"reflect"
"strings"
"github.com/onsi/gomega/format"
)
type MatchJSONMatcher struct {
JSONToMatch interface{}
JSONToMatch interface{}
firstFailurePath []interface{}
}
func (matcher *MatchJSONMatcher) Match(actual interface{}) (success bool, err error) {
@@ -25,18 +27,45 @@ func (matcher *MatchJSONMatcher) Match(actual interface{}) (success bool, err er
// this is guarded by prettyPrint
json.Unmarshal([]byte(actualString), &aval)
json.Unmarshal([]byte(expectedString), &eval)
return reflect.DeepEqual(aval, eval), nil
var equal bool
equal, matcher.firstFailurePath = deepEqual(aval, eval)
return equal, nil
}
func (matcher *MatchJSONMatcher) FailureMessage(actual interface{}) (message string) {
actualString, expectedString, _ := matcher.prettyPrint(actual)
return format.Message(actualString, "to match JSON of", expectedString)
return formattedMessage(format.Message(actualString, "to match JSON of", expectedString), matcher.firstFailurePath)
}
func (matcher *MatchJSONMatcher) NegatedFailureMessage(actual interface{}) (message string) {
actualString, expectedString, _ := matcher.prettyPrint(actual)
return format.Message(actualString, "not to match JSON of", expectedString)
return formattedMessage(format.Message(actualString, "not to match JSON of", expectedString), matcher.firstFailurePath)
}
func formattedMessage(comparisonMessage string, failurePath []interface{}) string {
var diffMessage string
if len(failurePath) == 0 {
diffMessage = ""
} else {
diffMessage = fmt.Sprintf("\n\nfirst mismatched key: %s", formattedFailurePath(failurePath))
}
return fmt.Sprintf("%s%s", comparisonMessage, diffMessage)
}
func formattedFailurePath(failurePath []interface{}) string {
formattedPaths := []string{}
for i := len(failurePath) - 1; i >= 0; i-- {
switch p := failurePath[i].(type) {
case int:
formattedPaths = append(formattedPaths, fmt.Sprintf(`[%d]`, p))
default:
if i != len(failurePath)-1 {
formattedPaths = append(formattedPaths, ".")
}
formattedPaths = append(formattedPaths, fmt.Sprintf(`"%s"`, p))
}
}
return strings.Join(formattedPaths, "")
}
func (matcher *MatchJSONMatcher) prettyPrint(actual interface{}) (actualFormatted, expectedFormatted string, err error) {
@@ -62,3 +91,45 @@ func (matcher *MatchJSONMatcher) prettyPrint(actual interface{}) (actualFormatte
return abuf.String(), ebuf.String(), nil
}
func deepEqual(a interface{}, b interface{}) (bool, []interface{}) {
var errorPath []interface{}
if reflect.TypeOf(a) != reflect.TypeOf(b) {
return false, errorPath
}
switch a.(type) {
case []interface{}:
if len(a.([]interface{})) != len(b.([]interface{})) {
return false, errorPath
}
for i, v := range a.([]interface{}) {
elementEqual, keyPath := deepEqual(v, b.([]interface{})[i])
if !elementEqual {
return false, append(keyPath, i)
}
}
return true, errorPath
case map[string]interface{}:
if len(a.(map[string]interface{})) != len(b.(map[string]interface{})) {
return false, errorPath
}
for k, v1 := range a.(map[string]interface{}) {
v2, ok := b.(map[string]interface{})[k]
if !ok {
return false, errorPath
}
elementEqual, keyPath := deepEqual(v1, v2)
if !elementEqual {
return false, append(keyPath, k)
}
}
return true, errorPath
default:
return a == b, errorPath
}
}

View File

@@ -2,8 +2,9 @@ package matchers
import (
"fmt"
"github.com/onsi/gomega/format"
"regexp"
"github.com/onsi/gomega/format"
)
type MatchRegexpMatcher struct {

View File

@@ -0,0 +1,134 @@
package matchers
import (
"bytes"
"encoding/xml"
"errors"
"fmt"
"io"
"reflect"
"sort"
"strings"
"github.com/onsi/gomega/format"
"golang.org/x/net/html/charset"
)
type MatchXMLMatcher struct {
XMLToMatch interface{}
}
func (matcher *MatchXMLMatcher) Match(actual interface{}) (success bool, err error) {
actualString, expectedString, err := matcher.formattedPrint(actual)
if err != nil {
return false, err
}
aval, err := parseXmlContent(actualString)
if err != nil {
return false, fmt.Errorf("Actual '%s' should be valid XML, but it is not.\nUnderlying error:%s", actualString, err)
}
eval, err := parseXmlContent(expectedString)
if err != nil {
return false, fmt.Errorf("Expected '%s' should be valid XML, but it is not.\nUnderlying error:%s", expectedString, err)
}
return reflect.DeepEqual(aval, eval), nil
}
func (matcher *MatchXMLMatcher) FailureMessage(actual interface{}) (message string) {
actualString, expectedString, _ := matcher.formattedPrint(actual)
return fmt.Sprintf("Expected\n%s\nto match XML of\n%s", actualString, expectedString)
}
func (matcher *MatchXMLMatcher) NegatedFailureMessage(actual interface{}) (message string) {
actualString, expectedString, _ := matcher.formattedPrint(actual)
return fmt.Sprintf("Expected\n%s\nnot to match XML of\n%s", actualString, expectedString)
}
func (matcher *MatchXMLMatcher) formattedPrint(actual interface{}) (actualString, expectedString string, err error) {
var ok bool
actualString, ok = toString(actual)
if !ok {
return "", "", fmt.Errorf("MatchXMLMatcher matcher requires a string, stringer, or []byte. Got actual:\n%s", format.Object(actual, 1))
}
expectedString, ok = toString(matcher.XMLToMatch)
if !ok {
return "", "", fmt.Errorf("MatchXMLMatcher matcher requires a string, stringer, or []byte. Got expected:\n%s", format.Object(matcher.XMLToMatch, 1))
}
return actualString, expectedString, nil
}
func parseXmlContent(content string) (*xmlNode, error) {
allNodes := []*xmlNode{}
dec := newXmlDecoder(strings.NewReader(content))
for {
tok, err := dec.Token()
if err != nil {
if err == io.EOF {
break
}
return nil, fmt.Errorf("failed to decode next token: %v", err)
}
lastNodeIndex := len(allNodes) - 1
var lastNode *xmlNode
if len(allNodes) > 0 {
lastNode = allNodes[lastNodeIndex]
} else {
lastNode = &xmlNode{}
}
switch tok := tok.(type) {
case xml.StartElement:
attrs := attributesSlice(tok.Attr)
sort.Sort(attrs)
allNodes = append(allNodes, &xmlNode{XMLName: tok.Name, XMLAttr: tok.Attr})
case xml.EndElement:
if len(allNodes) > 1 {
allNodes[lastNodeIndex-1].Nodes = append(allNodes[lastNodeIndex-1].Nodes, lastNode)
allNodes = allNodes[:lastNodeIndex]
}
case xml.CharData:
lastNode.Content = append(lastNode.Content, tok.Copy()...)
case xml.Comment:
lastNode.Comments = append(lastNode.Comments, tok.Copy())
case xml.ProcInst:
lastNode.ProcInsts = append(lastNode.ProcInsts, tok.Copy())
}
}
if len(allNodes) == 0 {
return nil, errors.New("found no nodes")
}
firstNode := allNodes[0]
trimParentNodesContentSpaces(firstNode)
return firstNode, nil
}
func newXmlDecoder(reader io.Reader) *xml.Decoder {
dec := xml.NewDecoder(reader)
dec.CharsetReader = charset.NewReaderLabel
return dec
}
func trimParentNodesContentSpaces(node *xmlNode) {
if len(node.Nodes) > 0 {
node.Content = bytes.TrimSpace(node.Content)
for _, childNode := range node.Nodes {
trimParentNodesContentSpaces(childNode)
}
}
}
type xmlNode struct {
XMLName xml.Name
Comments []xml.Comment
ProcInsts []xml.ProcInst
XMLAttr []xml.Attr
Content []byte
Nodes []*xmlNode
}

View File

@@ -64,9 +64,8 @@ func (matcher *ReceiveMatcher) Match(actual interface{}) (success bool, err erro
if didReceive {
matcher.receivedValue = value
return subMatcher.Match(matcher.receivedValue.Interface())
} else {
return false, nil
}
return false, nil
}
if didReceive {
@@ -76,9 +75,8 @@ func (matcher *ReceiveMatcher) Match(actual interface{}) (success bool, err erro
}
return true, nil
} else {
return false, nil
}
return false, nil
}
func (matcher *ReceiveMatcher) FailureMessage(actual interface{}) (message string) {
@@ -94,9 +92,8 @@ func (matcher *ReceiveMatcher) FailureMessage(actual interface{}) (message strin
return subMatcher.FailureMessage(matcher.receivedValue.Interface())
}
return "When passed a matcher, ReceiveMatcher's channel *must* receive something."
} else {
return format.Message(actual, "to receive something."+closedAddendum)
}
return format.Message(actual, "to receive something."+closedAddendum)
}
func (matcher *ReceiveMatcher) NegatedFailureMessage(actual interface{}) (message string) {
@@ -112,9 +109,8 @@ func (matcher *ReceiveMatcher) NegatedFailureMessage(actual interface{}) (messag
return subMatcher.NegatedFailureMessage(matcher.receivedValue.Interface())
}
return "When passed a matcher, ReceiveMatcher's channel *must* receive something."
} else {
return format.Message(actual, "not to receive anything."+closedAddendum)
}
return format.Message(actual, "not to receive anything."+closedAddendum)
}
func (matcher *ReceiveMatcher) MatchMayChangeInTheFuture(actual interface{}) bool {

View File

@@ -15,12 +15,12 @@ type BipartiteGraph struct {
func NewBipartiteGraph(leftValues, rightValues []interface{}, neighbours func(interface{}, interface{}) (bool, error)) (*BipartiteGraph, error) {
left := NodeOrderedSet{}
for i, _ := range leftValues {
left = append(left, Node{i})
left = append(left, Node{Id: i})
}
right := NodeOrderedSet{}
for j, _ := range rightValues {
right = append(right, Node{j + len(left)})
right = append(right, Node{Id: j + len(left)})
}
edges := EdgeSet{}
@@ -32,7 +32,7 @@ func NewBipartiteGraph(leftValues, rightValues []interface{}, neighbours func(in
}
if neighbours {
edges = append(edges, Edge{left[i], right[j]})
edges = append(edges, Edge{Node1: left[i], Node2: right[j]})
}
}
}

View File

@@ -101,9 +101,8 @@ func (bg *BipartiteGraph) createSLAPGuideLayers(matching EdgeSet) (guideLayers [
if len(currentLayer) == 0 {
return []NodeOrderedSet{}
} else {
guideLayers = append(guideLayers, currentLayer)
}
guideLayers = append(guideLayers, currentLayer)
done := false
@@ -152,9 +151,8 @@ func (bg *BipartiteGraph) createSLAPGuideLayers(matching EdgeSet) (guideLayers [
if len(currentLayer) == 0 {
return []NodeOrderedSet{}
} else {
guideLayers = append(guideLayers, currentLayer)
}
guideLayers = append(guideLayers, currentLayer)
}
return

View File

@@ -53,9 +53,8 @@ func toInteger(a interface{}) int64 {
return int64(reflect.ValueOf(a).Uint())
} else if isFloat(a) {
return int64(reflect.ValueOf(a).Float())
} else {
panic(fmt.Sprintf("Expected a number! Got <%T> %#v", a, a))
}
panic(fmt.Sprintf("Expected a number! Got <%T> %#v", a, a))
}
func toUnsignedInteger(a interface{}) uint64 {
@@ -65,9 +64,8 @@ func toUnsignedInteger(a interface{}) uint64 {
return reflect.ValueOf(a).Uint()
} else if isFloat(a) {
return uint64(reflect.ValueOf(a).Float())
} else {
panic(fmt.Sprintf("Expected a number! Got <%T> %#v", a, a))
}
panic(fmt.Sprintf("Expected a number! Got <%T> %#v", a, a))
}
func toFloat(a interface{}) float64 {
@@ -77,9 +75,8 @@ func toFloat(a interface{}) float64 {
return float64(reflect.ValueOf(a).Uint())
} else if isFloat(a) {
return reflect.ValueOf(a).Float()
} else {
panic(fmt.Sprintf("Expected a number! Got <%T> %#v", a, a))
}
panic(fmt.Sprintf("Expected a number! Got <%T> %#v", a, a))
}
func isError(a interface{}) bool {

View File

@@ -4,7 +4,7 @@ type GomegaFailHandler func(message string, callerSkip ...int)
//A simple *testing.T interface wrapper
type GomegaTestingT interface {
Errorf(format string, args ...interface{})
Fatalf(format string, args ...interface{})
}
//All Gomega matchers must implement the GomegaMatcher interface