Merge pull request #17056 from vdemeester/16756-integration-cli-checkers-api-build
Vendoring new go-check checkers and use checker for docker_api_build_test.go
This commit is contained in:
commit
cffd50752c
17 changed files with 1029 additions and 240 deletions
|
@ -9,7 +9,7 @@ source 'hack/.vendor-helpers.sh'
|
|||
clone git github.com/Azure/go-ansiterm 70b2c90b260171e829f1ebd7c17f600c11858dbe
|
||||
clone git github.com/Sirupsen/logrus v0.8.2 # logrus is a common dependency among multiple deps
|
||||
clone git github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a
|
||||
clone git github.com/go-check/check 64131543e7896d5bcc6bd5a76287eb75ea96c673
|
||||
clone git github.com/go-check/check 11d3bc7aa68e238947792f30573146a3231fc0f1
|
||||
clone git github.com/gorilla/context 14f550f51a
|
||||
clone git github.com/gorilla/mux e444e69cbd
|
||||
clone git github.com/kr/pty 5cf931ef8f
|
||||
|
@ -17,6 +17,7 @@ clone git github.com/mattn/go-sqlite3 v1.1.0
|
|||
clone git github.com/microsoft/hcsshim 325e531f8c49dd78580d5fd197ddb972fa4610e7
|
||||
clone git github.com/mistifyio/go-zfs v2.1.1
|
||||
clone git github.com/tchap/go-patricia v2.1.0
|
||||
clone git github.com/vdemeester/shakers 3c10293ce22b900c27acad7b28656196fcc2f73b
|
||||
clone git golang.org/x/net 3cffabab72adf04f8e3b01c5baf775361837b5fe https://github.com/golang/net.git
|
||||
|
||||
#get libnetwork packages
|
||||
|
|
|
@ -4,8 +4,8 @@ import (
|
|||
"archive/tar"
|
||||
"bytes"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
|
@ -17,31 +17,29 @@ func (s *DockerSuite) TestBuildApiDockerfilePath(c *check.C) {
|
|||
defer tw.Close()
|
||||
|
||||
dockerfile := []byte("FROM busybox")
|
||||
if err := tw.WriteHeader(&tar.Header{
|
||||
err := tw.WriteHeader(&tar.Header{
|
||||
Name: "Dockerfile",
|
||||
Size: int64(len(dockerfile)),
|
||||
}); err != nil {
|
||||
c.Fatalf("failed to write tar file header: %v", err)
|
||||
}
|
||||
if _, err := tw.Write(dockerfile); err != nil {
|
||||
c.Fatalf("failed to write tar file content: %v", err)
|
||||
}
|
||||
if err := tw.Close(); err != nil {
|
||||
c.Fatalf("failed to close tar archive: %v", err)
|
||||
}
|
||||
})
|
||||
//failed to write tar file header
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
_, err = tw.Write(dockerfile)
|
||||
// failed to write tar file content
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// failed to close tar archive
|
||||
c.Assert(tw.Close(), checker.IsNil)
|
||||
|
||||
res, body, err := sockRequestRaw("POST", "/build?dockerfile=../Dockerfile", buffer, "application/x-tar")
|
||||
c.Assert(err, check.IsNil)
|
||||
c.Assert(res.StatusCode, check.Equals, http.StatusInternalServerError)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
|
||||
|
||||
out, err := readBody(body)
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
if !strings.Contains(string(out), "Forbidden path outside the build context") {
|
||||
c.Fatalf("Didn't complain about leaving build context: %s", out)
|
||||
}
|
||||
// Didn't complain about leaving build context
|
||||
c.Assert(string(out), checker.Contains, "Forbidden path outside the build context")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestBuildApiDockerFileRemote(c *check.C) {
|
||||
|
@ -53,27 +51,21 @@ COPY * /tmp/
|
|||
RUN find / -name ba*
|
||||
RUN find /tmp/`,
|
||||
})
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer server.Close()
|
||||
|
||||
res, body, err := sockRequestRaw("POST", "/build?dockerfile=baz&remote="+server.URL()+"/testD", nil, "application/json")
|
||||
c.Assert(err, check.IsNil)
|
||||
c.Assert(res.StatusCode, check.Equals, http.StatusOK)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
|
||||
|
||||
buf, err := readBody(body)
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// Make sure Dockerfile exists.
|
||||
// Make sure 'baz' doesn't exist ANYWHERE despite being mentioned in the URL
|
||||
out := string(buf)
|
||||
if !strings.Contains(out, "/tmp/Dockerfile") ||
|
||||
strings.Contains(out, "baz") {
|
||||
c.Fatalf("Incorrect output: %s", out)
|
||||
}
|
||||
c.Assert(out, checker.Contains, "/tmp/Dockerfile")
|
||||
c.Assert(out, checker.Not(checker.Contains), "baz")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestBuildApiRemoteTarballContext(c *check.C) {
|
||||
|
@ -83,29 +75,30 @@ func (s *DockerSuite) TestBuildApiRemoteTarballContext(c *check.C) {
|
|||
defer tw.Close()
|
||||
|
||||
dockerfile := []byte("FROM busybox")
|
||||
if err := tw.WriteHeader(&tar.Header{
|
||||
err := tw.WriteHeader(&tar.Header{
|
||||
Name: "Dockerfile",
|
||||
Size: int64(len(dockerfile)),
|
||||
}); err != nil {
|
||||
c.Fatalf("failed to write tar file header: %v", err)
|
||||
}
|
||||
if _, err := tw.Write(dockerfile); err != nil {
|
||||
c.Fatalf("failed to write tar file content: %v", err)
|
||||
}
|
||||
if err := tw.Close(); err != nil {
|
||||
c.Fatalf("failed to close tar archive: %v", err)
|
||||
}
|
||||
})
|
||||
// failed to write tar file header
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
_, err = tw.Write(dockerfile)
|
||||
// failed to write tar file content
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// failed to close tar archive
|
||||
c.Assert(tw.Close(), checker.IsNil)
|
||||
|
||||
server, err := fakeBinaryStorage(map[string]*bytes.Buffer{
|
||||
"testT.tar": buffer,
|
||||
})
|
||||
c.Assert(err, check.IsNil)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
defer server.Close()
|
||||
|
||||
res, b, err := sockRequestRaw("POST", "/build?remote="+server.URL()+"/testT.tar", nil, "application/tar")
|
||||
c.Assert(err, check.IsNil)
|
||||
c.Assert(res.StatusCode, check.Equals, http.StatusOK)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
|
||||
b.Close()
|
||||
}
|
||||
|
||||
|
@ -117,51 +110,52 @@ func (s *DockerSuite) TestBuildApiRemoteTarballContextWithCustomDockerfile(c *ch
|
|||
|
||||
dockerfile := []byte(`FROM busybox
|
||||
RUN echo 'wrong'`)
|
||||
if err := tw.WriteHeader(&tar.Header{
|
||||
err := tw.WriteHeader(&tar.Header{
|
||||
Name: "Dockerfile",
|
||||
Size: int64(len(dockerfile)),
|
||||
}); err != nil {
|
||||
c.Fatalf("failed to write tar file header: %v", err)
|
||||
}
|
||||
if _, err := tw.Write(dockerfile); err != nil {
|
||||
c.Fatalf("failed to write tar file content: %v", err)
|
||||
}
|
||||
})
|
||||
// failed to write tar file header
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
_, err = tw.Write(dockerfile)
|
||||
// failed to write tar file content
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
custom := []byte(`FROM busybox
|
||||
RUN echo 'right'
|
||||
`)
|
||||
if err := tw.WriteHeader(&tar.Header{
|
||||
err = tw.WriteHeader(&tar.Header{
|
||||
Name: "custom",
|
||||
Size: int64(len(custom)),
|
||||
}); err != nil {
|
||||
c.Fatalf("failed to write tar file header: %v", err)
|
||||
}
|
||||
if _, err := tw.Write(custom); err != nil {
|
||||
c.Fatalf("failed to write tar file content: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
if err := tw.Close(); err != nil {
|
||||
c.Fatalf("failed to close tar archive: %v", err)
|
||||
}
|
||||
// failed to write tar file header
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
_, err = tw.Write(custom)
|
||||
// failed to write tar file content
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// failed to close tar archive
|
||||
c.Assert(tw.Close(), checker.IsNil)
|
||||
|
||||
server, err := fakeBinaryStorage(map[string]*bytes.Buffer{
|
||||
"testT.tar": buffer,
|
||||
})
|
||||
c.Assert(err, check.IsNil)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
defer server.Close()
|
||||
url := "/build?dockerfile=custom&remote=" + server.URL() + "/testT.tar"
|
||||
res, body, err := sockRequestRaw("POST", url, nil, "application/tar")
|
||||
c.Assert(err, check.IsNil)
|
||||
c.Assert(res.StatusCode, check.Equals, http.StatusOK)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
|
||||
|
||||
defer body.Close()
|
||||
content, err := readBody(body)
|
||||
c.Assert(err, check.IsNil)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
if strings.Contains(string(content), "wrong") {
|
||||
c.Fatalf("Build used the wrong dockerfile.")
|
||||
}
|
||||
// Build used the wrong dockerfile.
|
||||
c.Assert(string(content), checker.Not(checker.Contains), "wrong")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestBuildApiLowerDockerfile(c *check.C) {
|
||||
|
@ -170,24 +164,18 @@ func (s *DockerSuite) TestBuildApiLowerDockerfile(c *check.C) {
|
|||
"dockerfile": `FROM busybox
|
||||
RUN echo from dockerfile`,
|
||||
}, false)
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer git.Close()
|
||||
|
||||
res, body, err := sockRequestRaw("POST", "/build?remote="+git.RepoURL, nil, "application/json")
|
||||
c.Assert(err, check.IsNil)
|
||||
c.Assert(res.StatusCode, check.Equals, http.StatusOK)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
|
||||
|
||||
buf, err := readBody(body)
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
out := string(buf)
|
||||
if !strings.Contains(out, "from dockerfile") {
|
||||
c.Fatalf("Incorrect output: %s", out)
|
||||
}
|
||||
c.Assert(out, checker.Contains, "from dockerfile")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestBuildApiBuildGitWithF(c *check.C) {
|
||||
|
@ -198,25 +186,19 @@ RUN echo from baz`,
|
|||
"Dockerfile": `FROM busybox
|
||||
RUN echo from Dockerfile`,
|
||||
}, false)
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer git.Close()
|
||||
|
||||
// Make sure it tries to 'dockerfile' query param value
|
||||
res, body, err := sockRequestRaw("POST", "/build?dockerfile=baz&remote="+git.RepoURL, nil, "application/json")
|
||||
c.Assert(err, check.IsNil)
|
||||
c.Assert(res.StatusCode, check.Equals, http.StatusOK)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
|
||||
|
||||
buf, err := readBody(body)
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
out := string(buf)
|
||||
if !strings.Contains(out, "from baz") {
|
||||
c.Fatalf("Incorrect output: %s", out)
|
||||
}
|
||||
c.Assert(out, checker.Contains, "from baz")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestBuildApiDoubleDockerfile(c *check.C) {
|
||||
|
@ -227,25 +209,19 @@ RUN echo from Dockerfile`,
|
|||
"dockerfile": `FROM busybox
|
||||
RUN echo from dockerfile`,
|
||||
}, false)
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer git.Close()
|
||||
|
||||
// Make sure it tries to 'dockerfile' query param value
|
||||
res, body, err := sockRequestRaw("POST", "/build?remote="+git.RepoURL, nil, "application/json")
|
||||
c.Assert(err, check.IsNil)
|
||||
c.Assert(res.StatusCode, check.Equals, http.StatusOK)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
|
||||
|
||||
buf, err := readBody(body)
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
out := string(buf)
|
||||
if !strings.Contains(out, "from Dockerfile") {
|
||||
c.Fatalf("Incorrect output: %s", out)
|
||||
}
|
||||
c.Assert(out, checker.Contains, "from Dockerfile")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestBuildApiDockerfileSymlink(c *check.C) {
|
||||
|
@ -255,31 +231,27 @@ func (s *DockerSuite) TestBuildApiDockerfileSymlink(c *check.C) {
|
|||
tw := tar.NewWriter(buffer)
|
||||
defer tw.Close()
|
||||
|
||||
if err := tw.WriteHeader(&tar.Header{
|
||||
err := tw.WriteHeader(&tar.Header{
|
||||
Name: "Dockerfile",
|
||||
Typeflag: tar.TypeSymlink,
|
||||
Linkname: "/etc/passwd",
|
||||
}); err != nil {
|
||||
c.Fatalf("failed to write tar file header: %v", err)
|
||||
}
|
||||
if err := tw.Close(); err != nil {
|
||||
c.Fatalf("failed to close tar archive: %v", err)
|
||||
}
|
||||
})
|
||||
// failed to write tar file header
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// failed to close tar archive
|
||||
c.Assert(tw.Close(), checker.IsNil)
|
||||
|
||||
res, body, err := sockRequestRaw("POST", "/build", buffer, "application/x-tar")
|
||||
c.Assert(err, check.IsNil)
|
||||
c.Assert(res.StatusCode, check.Equals, http.StatusInternalServerError)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
|
||||
|
||||
out, err := readBody(body)
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// The reason the error is "Cannot locate specified Dockerfile" is because
|
||||
// in the builder, the symlink is resolved within the context, therefore
|
||||
// Dockerfile -> /etc/passwd becomes etc/passwd from the context which is
|
||||
// a nonexistent file.
|
||||
if !strings.Contains(string(out), "Cannot locate specified Dockerfile: Dockerfile") {
|
||||
c.Fatalf("Didn't complain about leaving build context: %s", out)
|
||||
}
|
||||
c.Assert(string(out), checker.Contains, "Cannot locate specified Dockerfile: Dockerfile", check.Commentf("Didn't complain about leaving build context"))
|
||||
}
|
||||
|
|
|
@ -2,17 +2,14 @@
|
|||
package checker
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/go-check/check"
|
||||
"github.com/vdemeester/shakers"
|
||||
)
|
||||
|
||||
// As a commodity, we bring all check.Checker variables into the current namespace to avoid having
|
||||
// to think about check.X versus checker.X.
|
||||
var (
|
||||
DeepEquals = check.DeepEquals
|
||||
Equals = check.Equals
|
||||
ErrorMatches = check.ErrorMatches
|
||||
FitsTypeOf = check.FitsTypeOf
|
||||
HasLen = check.HasLen
|
||||
|
@ -23,37 +20,27 @@ var (
|
|||
NotNil = check.NotNil
|
||||
PanicMatches = check.PanicMatches
|
||||
Panics = check.Panics
|
||||
|
||||
Contains = shakers.Contains
|
||||
ContainsAny = shakers.ContainsAny
|
||||
Count = shakers.Count
|
||||
Equals = shakers.Equals
|
||||
EqualFold = shakers.EqualFold
|
||||
False = shakers.False
|
||||
GreaterOrEqualThan = shakers.GreaterOrEqualThan
|
||||
GreaterThan = shakers.GreaterThan
|
||||
HasPrefix = shakers.HasPrefix
|
||||
HasSuffix = shakers.HasSuffix
|
||||
Index = shakers.Index
|
||||
IndexAny = shakers.IndexAny
|
||||
IsAfter = shakers.IsAfter
|
||||
IsBefore = shakers.IsBefore
|
||||
IsBetween = shakers.IsBetween
|
||||
IsLower = shakers.IsLower
|
||||
IsUpper = shakers.IsUpper
|
||||
LessOrEqualThan = shakers.LessOrEqualThan
|
||||
LessThan = shakers.LessThan
|
||||
TimeEquals = shakers.TimeEquals
|
||||
True = shakers.True
|
||||
TimeIgnore = shakers.TimeIgnore
|
||||
)
|
||||
|
||||
// Contains checker verifies that string value contains a substring.
|
||||
var Contains check.Checker = &containsChecker{
|
||||
&check.CheckerInfo{
|
||||
Name: "Contains",
|
||||
Params: []string{"value", "substring"},
|
||||
},
|
||||
}
|
||||
|
||||
type containsChecker struct {
|
||||
*check.CheckerInfo
|
||||
}
|
||||
|
||||
func (checker *containsChecker) Check(params []interface{}, names []string) (bool, string) {
|
||||
return contains(params[0], params[1])
|
||||
}
|
||||
|
||||
func contains(value, substring interface{}) (bool, string) {
|
||||
substringStr, ok := substring.(string)
|
||||
if !ok {
|
||||
return false, "Substring must be a string"
|
||||
}
|
||||
valueStr, valueIsStr := value.(string)
|
||||
if !valueIsStr {
|
||||
if valueWithStr, valueHasStr := value.(fmt.Stringer); valueHasStr {
|
||||
valueStr, valueIsStr = valueWithStr.String(), true
|
||||
}
|
||||
}
|
||||
if valueIsStr {
|
||||
return strings.Contains(valueStr, substringStr), ""
|
||||
}
|
||||
return false, "Obtained value is not a string and has no .String()"
|
||||
}
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
package checker
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
check.TestingT(t)
|
||||
}
|
||||
|
||||
func init() {
|
||||
check.Suite(&CheckersS{})
|
||||
}
|
||||
|
||||
type CheckersS struct{}
|
||||
|
||||
var _ = check.Suite(&CheckersS{})
|
||||
|
||||
func testInfo(c *check.C, checker check.Checker, name string, paramNames []string) {
|
||||
info := checker.Info()
|
||||
if info.Name != name {
|
||||
c.Fatalf("Got name %s, expected %s", info.Name, name)
|
||||
}
|
||||
if !reflect.DeepEqual(info.Params, paramNames) {
|
||||
c.Fatalf("Got param names %#v, expected %#v", info.Params, paramNames)
|
||||
}
|
||||
}
|
||||
|
||||
func testCheck(c *check.C, checker check.Checker, expectedResult bool, expectedError string, params ...interface{}) ([]interface{}, []string) {
|
||||
info := checker.Info()
|
||||
if len(params) != len(info.Params) {
|
||||
c.Fatalf("unexpected param count in test; expected %d got %d", len(info.Params), len(params))
|
||||
}
|
||||
names := append([]string{}, info.Params...)
|
||||
result, error := checker.Check(params, names)
|
||||
if result != expectedResult || error != expectedError {
|
||||
c.Fatalf("%s.Check(%#v) returned (%#v, %#v) rather than (%#v, %#v)",
|
||||
info.Name, params, result, error, expectedResult, expectedError)
|
||||
}
|
||||
return params, names
|
||||
}
|
||||
|
||||
func (s *CheckersS) TestContains(c *check.C) {
|
||||
testInfo(c, Contains, "Contains", []string{"value", "substring"})
|
||||
|
||||
testCheck(c, Contains, true, "", "abcd", "bc")
|
||||
testCheck(c, Contains, false, "", "abcd", "efg")
|
||||
testCheck(c, Contains, false, "", "", "bc")
|
||||
testCheck(c, Contains, true, "", "abcd", "")
|
||||
testCheck(c, Contains, true, "", "", "")
|
||||
|
||||
testCheck(c, Contains, false, "Obtained value is not a string and has no .String()", 12, "1")
|
||||
testCheck(c, Contains, false, "Substring must be a string", "", 1)
|
||||
}
|
|
@ -1,6 +1,30 @@
|
|||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
// Copyright (c) 2012 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package check
|
||||
|
||||
|
|
53
vendor/src/github.com/go-check/check/check.go
vendored
53
vendor/src/github.com/go-check/check/check.go
vendored
|
@ -21,6 +21,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -43,7 +44,7 @@ const (
|
|||
missedSt
|
||||
)
|
||||
|
||||
type funcStatus int
|
||||
type funcStatus uint32
|
||||
|
||||
// A method value can't reach its own Method structure.
|
||||
type methodType struct {
|
||||
|
@ -81,7 +82,7 @@ type C struct {
|
|||
method *methodType
|
||||
kind funcKind
|
||||
testName string
|
||||
status funcStatus
|
||||
_status funcStatus
|
||||
logb *logger
|
||||
logw io.Writer
|
||||
done chan *C
|
||||
|
@ -93,6 +94,14 @@ type C struct {
|
|||
timer
|
||||
}
|
||||
|
||||
func (c *C) status() funcStatus {
|
||||
return funcStatus(atomic.LoadUint32((*uint32)(&c._status)))
|
||||
}
|
||||
|
||||
func (c *C) setStatus(s funcStatus) {
|
||||
atomic.StoreUint32((*uint32)(&c._status), uint32(s))
|
||||
}
|
||||
|
||||
func (c *C) stopNow() {
|
||||
runtime.Goexit()
|
||||
}
|
||||
|
@ -326,7 +335,7 @@ func (c *C) logPanic(skip int, value interface{}) {
|
|||
if name == "Value.call" && strings.HasSuffix(path, valueGo) {
|
||||
continue
|
||||
}
|
||||
if name == "call16" && strings.Contains(path, asmGo) {
|
||||
if (name == "call16" || name == "call32") && strings.Contains(path, asmGo) {
|
||||
continue
|
||||
}
|
||||
c.logf("%s:%d\n in %s", nicePath(file), line, name)
|
||||
|
@ -455,7 +464,7 @@ func (tracker *resultTracker) _loopRoutine() {
|
|||
tracker._waiting += 1
|
||||
case c = <-tracker._doneChan:
|
||||
tracker._waiting -= 1
|
||||
switch c.status {
|
||||
switch c.status() {
|
||||
case succeededSt:
|
||||
if c.kind == testKd {
|
||||
if c.mustFail {
|
||||
|
@ -601,15 +610,15 @@ func (runner *suiteRunner) run() *Result {
|
|||
runner.tracker.start()
|
||||
if runner.checkFixtureArgs() {
|
||||
c := runner.runFixture(runner.setUpSuite, "", nil)
|
||||
if c == nil || c.status == succeededSt {
|
||||
if c == nil || c.status() == succeededSt {
|
||||
for i := 0; i != len(runner.tests); i++ {
|
||||
c := runner.runTest(runner.tests[i])
|
||||
if c.status == fixturePanickedSt {
|
||||
if c.status() == fixturePanickedSt {
|
||||
runner.skipTests(missedSt, runner.tests[i+1:])
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if c != nil && c.status == skippedSt {
|
||||
} else if c != nil && c.status() == skippedSt {
|
||||
runner.skipTests(skippedSt, runner.tests)
|
||||
} else {
|
||||
runner.skipTests(missedSt, runner.tests)
|
||||
|
@ -674,22 +683,22 @@ func (runner *suiteRunner) callDone(c *C) {
|
|||
switch v := value.(type) {
|
||||
case *fixturePanic:
|
||||
if v.status == skippedSt {
|
||||
c.status = skippedSt
|
||||
c.setStatus(skippedSt)
|
||||
} else {
|
||||
c.logSoftPanic("Fixture has panicked (see related PANIC)")
|
||||
c.status = fixturePanickedSt
|
||||
c.setStatus(fixturePanickedSt)
|
||||
}
|
||||
default:
|
||||
c.logPanic(1, value)
|
||||
c.status = panickedSt
|
||||
c.setStatus(panickedSt)
|
||||
}
|
||||
}
|
||||
if c.mustFail {
|
||||
switch c.status {
|
||||
switch c.status() {
|
||||
case failedSt:
|
||||
c.status = succeededSt
|
||||
c.setStatus(succeededSt)
|
||||
case succeededSt:
|
||||
c.status = failedSt
|
||||
c.setStatus(failedSt)
|
||||
c.logString("Error: Test succeeded, but was expected to fail")
|
||||
c.logString("Reason: " + c.reason)
|
||||
}
|
||||
|
@ -724,11 +733,11 @@ func (runner *suiteRunner) runFixtureWithPanic(method *methodType, testName stri
|
|||
return nil
|
||||
}
|
||||
c := runner.runFixture(method, testName, logb)
|
||||
if c != nil && c.status != succeededSt {
|
||||
if c != nil && c.status() != succeededSt {
|
||||
if skipped != nil {
|
||||
*skipped = c.status == skippedSt
|
||||
*skipped = c.status() == skippedSt
|
||||
}
|
||||
panic(&fixturePanic{c.status, method})
|
||||
panic(&fixturePanic{c.status(), method})
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
@ -753,7 +762,7 @@ func (runner *suiteRunner) forkTest(method *methodType) *C {
|
|||
if mt.NumIn() != 1 || mt.In(0) != reflect.TypeOf(c) {
|
||||
// Rather than a plain panic, provide a more helpful message when
|
||||
// the argument type is incorrect.
|
||||
c.status = panickedSt
|
||||
c.setStatus(panickedSt)
|
||||
c.logArgPanic(c.method, "*check.C")
|
||||
return
|
||||
}
|
||||
|
@ -773,7 +782,7 @@ func (runner *suiteRunner) forkTest(method *methodType) *C {
|
|||
c.StartTimer()
|
||||
c.method.Call([]reflect.Value{reflect.ValueOf(c)})
|
||||
c.StopTimer()
|
||||
if c.status != succeededSt || c.duration >= c.benchTime || benchN >= 1e9 {
|
||||
if c.status() != succeededSt || c.duration >= c.benchTime || benchN >= 1e9 {
|
||||
return
|
||||
}
|
||||
perOpN := int(1e9)
|
||||
|
@ -808,7 +817,7 @@ func (runner *suiteRunner) runTest(method *methodType) *C {
|
|||
func (runner *suiteRunner) skipTests(status funcStatus, methods []*methodType) {
|
||||
for _, method := range methods {
|
||||
runner.runFunc(method, testKd, "", nil, func(c *C) {
|
||||
c.status = status
|
||||
c.setStatus(status)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -825,7 +834,7 @@ func (runner *suiteRunner) checkFixtureArgs() bool {
|
|||
succeeded = false
|
||||
runner.runFunc(method, fixtureKd, "", nil, func(c *C) {
|
||||
c.logArgPanic(method, "*check.C")
|
||||
c.status = panickedSt
|
||||
c.setStatus(panickedSt)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -839,7 +848,7 @@ func (runner *suiteRunner) reportCallStarted(c *C) {
|
|||
|
||||
func (runner *suiteRunner) reportCallDone(c *C) {
|
||||
runner.tracker.callDone(c)
|
||||
switch c.status {
|
||||
switch c.status() {
|
||||
case succeededSt:
|
||||
if c.mustFail {
|
||||
runner.output.WriteCallSuccess("FAIL EXPECTED", c)
|
||||
|
@ -917,7 +926,7 @@ func (ow *outputWriter) WriteCallSuccess(label string, c *C) {
|
|||
if c.reason != "" {
|
||||
suffix = " (" + c.reason + ")"
|
||||
}
|
||||
if c.status == succeededSt {
|
||||
if c.status() == succeededSt {
|
||||
suffix += "\t" + c.timerString()
|
||||
}
|
||||
suffix += "\n"
|
||||
|
|
|
@ -16,7 +16,7 @@ func (c *C) TestName() string {
|
|||
|
||||
// Failed returns whether the currently running test has already failed.
|
||||
func (c *C) Failed() bool {
|
||||
return c.status == failedSt
|
||||
return c.status() == failedSt
|
||||
}
|
||||
|
||||
// Fail marks the currently running test as failed.
|
||||
|
@ -25,7 +25,7 @@ func (c *C) Failed() bool {
|
|||
// what went wrong. The higher level helper functions will fail the test
|
||||
// and do the logging properly.
|
||||
func (c *C) Fail() {
|
||||
c.status = failedSt
|
||||
c.setStatus(failedSt)
|
||||
}
|
||||
|
||||
// FailNow marks the currently running test as failed and stops running it.
|
||||
|
@ -40,7 +40,7 @@ func (c *C) FailNow() {
|
|||
// Succeed marks the currently running test as succeeded, undoing any
|
||||
// previous failures.
|
||||
func (c *C) Succeed() {
|
||||
c.status = succeededSt
|
||||
c.setStatus(succeededSt)
|
||||
}
|
||||
|
||||
// SucceedNow marks the currently running test as succeeded, undoing any
|
||||
|
@ -72,7 +72,7 @@ func (c *C) Skip(reason string) {
|
|||
panic("Missing reason why the test is being skipped")
|
||||
}
|
||||
c.reason = reason
|
||||
c.status = skippedSt
|
||||
c.setStatus(skippedSt)
|
||||
c.stopNow()
|
||||
}
|
||||
|
||||
|
|
4
vendor/src/github.com/vdemeester/shakers/.gitignore
vendored
Normal file
4
vendor/src/github.com/vdemeester/shakers/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
Godeps/_workspace/bin
|
||||
Godeps/_workspace/pkg
|
||||
|
||||
*.test
|
12
vendor/src/github.com/vdemeester/shakers/Dockerfile
vendored
Normal file
12
vendor/src/github.com/vdemeester/shakers/Dockerfile
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
FROM golang:1.5
|
||||
|
||||
RUN go get golang.org/x/tools/cmd/cover
|
||||
RUN go get github.com/golang/lint/golint
|
||||
RUN go get golang.org/x/tools/cmd/vet
|
||||
|
||||
WORKDIR /go/src/github.com/vdemeester/shakers
|
||||
|
||||
# enable GO15VENDOREXPERIMENT
|
||||
ENV GO15VENDOREXPERIMENT 1
|
||||
|
||||
COPY . /go/src/github.com/vdemeester/shakers
|
40
vendor/src/github.com/vdemeester/shakers/Makefile
vendored
Normal file
40
vendor/src/github.com/vdemeester/shakers/Makefile
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
.PHONY: all
|
||||
|
||||
SHAKERS_MOUNT := $(if $(BIND_DIR),-v "$(CURDIR)/$(BIND_DIR):/go/src/github.com/vdemeester/shakers/$(BIND_DIR)")
|
||||
|
||||
GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD 2>/dev/null)
|
||||
SHAKERS_DEV_IMAGE := shakers-dev$(if $(GIT_BRANCH),:$(GIT_BRANCH))
|
||||
|
||||
DOCKER_RUN_SHAKERS := docker run $(if $(CIRCLECI),,--rm) -it $(SHAKERS_ENVS) $(SHAKERS_MOUNT) "$(SHAKERS_DEV_IMAGE)"
|
||||
|
||||
print-%: ; @echo $*=$($*)
|
||||
|
||||
default: binary
|
||||
|
||||
binary: build
|
||||
$(DOCKER_RUN_SHAKERS) ./script/make.sh binary
|
||||
|
||||
test-unit: build
|
||||
$(DOCKER_RUN_SHAKERS) ./script/make.sh test-unit
|
||||
|
||||
validate: build
|
||||
$(DOCKER_RUN_SHAKERS) ./script/make.sh validate-gofmt validate-golint validate-govet
|
||||
|
||||
validate-govet: build
|
||||
$(DOCKER_RUN_SHAKERS) ./script/make.sh validate-govet
|
||||
|
||||
validate-golint: build
|
||||
$(DOCKER_RUN_SHAKERS) ./script/make.sh validate-golint
|
||||
|
||||
validate-gofmt: build
|
||||
$(DOCKER_RUN_SHAKERS) ./script/make.sh validate-gofmt
|
||||
|
||||
build:
|
||||
docker build -t "$(SHAKERS_DEV_IMAGE)" .
|
||||
|
||||
shell: build
|
||||
$(DOCKER_RUN_SHAKERS) /bin/bash
|
||||
|
||||
run-dev:
|
||||
go build
|
||||
./traefik
|
24
vendor/src/github.com/vdemeester/shakers/README.md
vendored
Normal file
24
vendor/src/github.com/vdemeester/shakers/README.md
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
# Shakers
|
||||
🐹 + 🐙 = 😽 [![Circle CI](https://circleci.com/gh/vdemeester/shakers.svg?style=svg)](https://circleci.com/gh/vdemeester/shakers)
|
||||
|
||||
A collection of `go-check` Checkers to ease the use of it.
|
||||
|
||||
## Building and testing it
|
||||
|
||||
You need either [docker](https://github.com/docker/docker), or `go`
|
||||
and `godep` in order to build and test shakers.
|
||||
|
||||
### Using Docker and Makefile
|
||||
|
||||
You need to run the ``test-unit`` target.
|
||||
```bash
|
||||
$ make test-unit
|
||||
docker build -t "shakers-dev:master" .
|
||||
# […]
|
||||
docker run --rm -it "shakers-dev:master" ./script/make.sh test-unit
|
||||
---> Making bundle: test-unit (in .)
|
||||
+ go test -cover -coverprofile=cover.out .
|
||||
ok github.com/vdemeester/shakers 0.015s coverage: 96.0% of statements
|
||||
|
||||
Test success
|
||||
```
|
46
vendor/src/github.com/vdemeester/shakers/bool.go
vendored
Normal file
46
vendor/src/github.com/vdemeester/shakers/bool.go
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
package shakers
|
||||
|
||||
import (
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// True checker verifies the obtained value is true
|
||||
//
|
||||
// c.Assert(myBool, True)
|
||||
//
|
||||
var True check.Checker = &boolChecker{
|
||||
&check.CheckerInfo{
|
||||
Name: "True",
|
||||
Params: []string{"obtained"},
|
||||
},
|
||||
true,
|
||||
}
|
||||
|
||||
// False checker verifies the obtained value is false
|
||||
//
|
||||
// c.Assert(myBool, False)
|
||||
//
|
||||
var False check.Checker = &boolChecker{
|
||||
&check.CheckerInfo{
|
||||
Name: "False",
|
||||
Params: []string{"obtained"},
|
||||
},
|
||||
false,
|
||||
}
|
||||
|
||||
type boolChecker struct {
|
||||
*check.CheckerInfo
|
||||
expected bool
|
||||
}
|
||||
|
||||
func (checker *boolChecker) Check(params []interface{}, names []string) (bool, string) {
|
||||
return is(checker.expected, params[0])
|
||||
}
|
||||
|
||||
func is(expected bool, obtained interface{}) (bool, string) {
|
||||
obtainedBool, ok := obtained.(bool)
|
||||
if !ok {
|
||||
return false, "obtained value must be a bool."
|
||||
}
|
||||
return obtainedBool == expected, ""
|
||||
}
|
11
vendor/src/github.com/vdemeester/shakers/circle.yml
vendored
Normal file
11
vendor/src/github.com/vdemeester/shakers/circle.yml
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
machine:
|
||||
services:
|
||||
- docker
|
||||
|
||||
dependencies:
|
||||
override:
|
||||
- make validate
|
||||
|
||||
test:
|
||||
override:
|
||||
- make test-unit
|
310
vendor/src/github.com/vdemeester/shakers/common.go
vendored
Normal file
310
vendor/src/github.com/vdemeester/shakers/common.go
vendored
Normal file
|
@ -0,0 +1,310 @@
|
|||
package shakers
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// As a commodity, we bring all check.Checker variables into the current namespace to avoid having
|
||||
// to think about check.X versus checker.X.
|
||||
var (
|
||||
DeepEquals = check.DeepEquals
|
||||
ErrorMatches = check.ErrorMatches
|
||||
FitsTypeOf = check.FitsTypeOf
|
||||
HasLen = check.HasLen
|
||||
Implements = check.Implements
|
||||
IsNil = check.IsNil
|
||||
Matches = check.Matches
|
||||
Not = check.Not
|
||||
NotNil = check.NotNil
|
||||
PanicMatches = check.PanicMatches
|
||||
Panics = check.Panics
|
||||
)
|
||||
|
||||
// Equaler is an interface implemented if the type has a Equal method.
|
||||
// This is used to compare struct using shakers.Equals.
|
||||
type Equaler interface {
|
||||
Equal(Equaler) bool
|
||||
}
|
||||
|
||||
// Equals checker verifies the obtained value is equal to the specified one.
|
||||
// It's is smart in a wait that it supports several *types* (built-in, Equaler,
|
||||
// time.Time)
|
||||
//
|
||||
// c.Assert(myStruct, Equals, aStruct, check.Commentf("bouuuhh"))
|
||||
// c.Assert(myTime, Equals, aTime, check.Commentf("bouuuhh"))
|
||||
//
|
||||
var Equals check.Checker = &equalChecker{
|
||||
&check.CheckerInfo{
|
||||
Name: "Equals",
|
||||
Params: []string{"obtained", "expected"},
|
||||
},
|
||||
}
|
||||
|
||||
type equalChecker struct {
|
||||
*check.CheckerInfo
|
||||
}
|
||||
|
||||
func (checker *equalChecker) Check(params []interface{}, names []string) (bool, string) {
|
||||
return isEqual(params[0], params[1])
|
||||
}
|
||||
|
||||
func isEqual(obtained, expected interface{}) (bool, string) {
|
||||
switch obtained.(type) {
|
||||
case time.Time:
|
||||
return timeEquals(obtained, expected)
|
||||
case Equaler:
|
||||
return equalerEquals(obtained, expected)
|
||||
default:
|
||||
if reflect.TypeOf(obtained) != reflect.TypeOf(expected) {
|
||||
return false, "obtained value and expected value have not the same type."
|
||||
}
|
||||
return obtained == expected, ""
|
||||
}
|
||||
}
|
||||
|
||||
func equalerEquals(obtained, expected interface{}) (bool, string) {
|
||||
expectedEqualer, ok := expected.(Equaler)
|
||||
if !ok {
|
||||
return false, "expected value must be an Equaler - implementing Equal(Equaler)."
|
||||
}
|
||||
obtainedEqualer, ok := obtained.(Equaler)
|
||||
if !ok {
|
||||
return false, "obtained value must be an Equaler - implementing Equal(Equaler)."
|
||||
}
|
||||
return obtainedEqualer.Equal(expectedEqualer), ""
|
||||
}
|
||||
|
||||
// GreaterThan checker verifies the obtained value is greater than the specified one.
|
||||
// It's is smart in a wait that it supports several *types* (built-in, time.Time)
|
||||
//
|
||||
// c.Assert(myTime, GreaterThan, aTime, check.Commentf("bouuuhh"))
|
||||
// c.Assert(myInt, GreaterThan, 2, check.Commentf("bouuuhh"))
|
||||
//
|
||||
var GreaterThan check.Checker = &greaterThanChecker{
|
||||
&check.CheckerInfo{
|
||||
Name: "GreaterThan",
|
||||
Params: []string{"obtained", "expected"},
|
||||
},
|
||||
}
|
||||
|
||||
type greaterThanChecker struct {
|
||||
*check.CheckerInfo
|
||||
}
|
||||
|
||||
func (checker *greaterThanChecker) Check(params []interface{}, names []string) (bool, string) {
|
||||
return greaterThan(params[0], params[1])
|
||||
}
|
||||
|
||||
func greaterThan(obtained, expected interface{}) (bool, string) {
|
||||
if _, ok := obtained.(time.Time); ok {
|
||||
return isAfter(obtained, expected)
|
||||
}
|
||||
if reflect.TypeOf(obtained) != reflect.TypeOf(expected) {
|
||||
return false, "obtained value and expected value have not the same type."
|
||||
}
|
||||
switch v := obtained.(type) {
|
||||
case float32:
|
||||
return v > expected.(float32), ""
|
||||
case float64:
|
||||
return v > expected.(float64), ""
|
||||
case int:
|
||||
return v > expected.(int), ""
|
||||
case int8:
|
||||
return v > expected.(int8), ""
|
||||
case int16:
|
||||
return v > expected.(int16), ""
|
||||
case int32:
|
||||
return v > expected.(int32), ""
|
||||
case int64:
|
||||
return v > expected.(int64), ""
|
||||
case uint:
|
||||
return v > expected.(uint), ""
|
||||
case uint8:
|
||||
return v > expected.(uint8), ""
|
||||
case uint16:
|
||||
return v > expected.(uint16), ""
|
||||
case uint32:
|
||||
return v > expected.(uint32), ""
|
||||
case uint64:
|
||||
return v > expected.(uint64), ""
|
||||
default:
|
||||
return false, "obtained value type not supported."
|
||||
}
|
||||
}
|
||||
|
||||
// GreaterOrEqualThan checker verifies the obtained value is greater or equal than the specified one.
|
||||
// It's is smart in a wait that it supports several *types* (built-in, time.Time)
|
||||
//
|
||||
// c.Assert(myTime, GreaterOrEqualThan, aTime, check.Commentf("bouuuhh"))
|
||||
// c.Assert(myInt, GreaterOrEqualThan, 2, check.Commentf("bouuuhh"))
|
||||
//
|
||||
var GreaterOrEqualThan check.Checker = &greaterOrEqualThanChecker{
|
||||
&check.CheckerInfo{
|
||||
Name: "GreaterOrEqualThan",
|
||||
Params: []string{"obtained", "expected"},
|
||||
},
|
||||
}
|
||||
|
||||
type greaterOrEqualThanChecker struct {
|
||||
*check.CheckerInfo
|
||||
}
|
||||
|
||||
func (checker *greaterOrEqualThanChecker) Check(params []interface{}, names []string) (bool, string) {
|
||||
return greaterOrEqualThan(params[0], params[1])
|
||||
}
|
||||
|
||||
func greaterOrEqualThan(obtained, expected interface{}) (bool, string) {
|
||||
if _, ok := obtained.(time.Time); ok {
|
||||
return isAfter(obtained, expected)
|
||||
}
|
||||
if reflect.TypeOf(obtained) != reflect.TypeOf(expected) {
|
||||
return false, "obtained value and expected value have not the same type."
|
||||
}
|
||||
switch v := obtained.(type) {
|
||||
case float32:
|
||||
return v >= expected.(float32), ""
|
||||
case float64:
|
||||
return v >= expected.(float64), ""
|
||||
case int:
|
||||
return v >= expected.(int), ""
|
||||
case int8:
|
||||
return v >= expected.(int8), ""
|
||||
case int16:
|
||||
return v >= expected.(int16), ""
|
||||
case int32:
|
||||
return v >= expected.(int32), ""
|
||||
case int64:
|
||||
return v >= expected.(int64), ""
|
||||
case uint:
|
||||
return v >= expected.(uint), ""
|
||||
case uint8:
|
||||
return v >= expected.(uint8), ""
|
||||
case uint16:
|
||||
return v >= expected.(uint16), ""
|
||||
case uint32:
|
||||
return v >= expected.(uint32), ""
|
||||
case uint64:
|
||||
return v >= expected.(uint64), ""
|
||||
default:
|
||||
return false, "obtained value type not supported."
|
||||
}
|
||||
}
|
||||
|
||||
// LessThan checker verifies the obtained value is less than the specified one.
|
||||
// It's is smart in a wait that it supports several *types* (built-in, time.Time)
|
||||
//
|
||||
// c.Assert(myTime, LessThan, aTime, check.Commentf("bouuuhh"))
|
||||
// c.Assert(myInt, LessThan, 2, check.Commentf("bouuuhh"))
|
||||
//
|
||||
var LessThan check.Checker = &lessThanChecker{
|
||||
&check.CheckerInfo{
|
||||
Name: "LessThan",
|
||||
Params: []string{"obtained", "expected"},
|
||||
},
|
||||
}
|
||||
|
||||
type lessThanChecker struct {
|
||||
*check.CheckerInfo
|
||||
}
|
||||
|
||||
func (checker *lessThanChecker) Check(params []interface{}, names []string) (bool, string) {
|
||||
return lessThan(params[0], params[1])
|
||||
}
|
||||
|
||||
func lessThan(obtained, expected interface{}) (bool, string) {
|
||||
if _, ok := obtained.(time.Time); ok {
|
||||
return isBefore(obtained, expected)
|
||||
}
|
||||
if reflect.TypeOf(obtained) != reflect.TypeOf(expected) {
|
||||
return false, "obtained value and expected value have not the same type."
|
||||
}
|
||||
switch v := obtained.(type) {
|
||||
case float32:
|
||||
return v < expected.(float32), ""
|
||||
case float64:
|
||||
return v < expected.(float64), ""
|
||||
case int:
|
||||
return v < expected.(int), ""
|
||||
case int8:
|
||||
return v < expected.(int8), ""
|
||||
case int16:
|
||||
return v < expected.(int16), ""
|
||||
case int32:
|
||||
return v < expected.(int32), ""
|
||||
case int64:
|
||||
return v < expected.(int64), ""
|
||||
case uint:
|
||||
return v < expected.(uint), ""
|
||||
case uint8:
|
||||
return v < expected.(uint8), ""
|
||||
case uint16:
|
||||
return v < expected.(uint16), ""
|
||||
case uint32:
|
||||
return v < expected.(uint32), ""
|
||||
case uint64:
|
||||
return v < expected.(uint64), ""
|
||||
default:
|
||||
return false, "obtained value type not supported."
|
||||
}
|
||||
}
|
||||
|
||||
// LessOrEqualThan checker verifies the obtained value is less or equal than the specified one.
|
||||
// It's is smart in a wait that it supports several *types* (built-in, time.Time)
|
||||
//
|
||||
// c.Assert(myTime, LessThan, aTime, check.Commentf("bouuuhh"))
|
||||
// c.Assert(myInt, LessThan, 2, check.Commentf("bouuuhh"))
|
||||
//
|
||||
var LessOrEqualThan check.Checker = &lessOrEqualThanChecker{
|
||||
&check.CheckerInfo{
|
||||
Name: "LessOrEqualThan",
|
||||
Params: []string{"obtained", "expected"},
|
||||
},
|
||||
}
|
||||
|
||||
type lessOrEqualThanChecker struct {
|
||||
*check.CheckerInfo
|
||||
}
|
||||
|
||||
func (checker *lessOrEqualThanChecker) Check(params []interface{}, names []string) (bool, string) {
|
||||
return lessOrEqualThan(params[0], params[1])
|
||||
}
|
||||
|
||||
func lessOrEqualThan(obtained, expected interface{}) (bool, string) {
|
||||
if _, ok := obtained.(time.Time); ok {
|
||||
return isBefore(obtained, expected)
|
||||
}
|
||||
if reflect.TypeOf(obtained) != reflect.TypeOf(expected) {
|
||||
return false, "obtained value and expected value have not the same type."
|
||||
}
|
||||
switch v := obtained.(type) {
|
||||
case float32:
|
||||
return v <= expected.(float32), ""
|
||||
case float64:
|
||||
return v <= expected.(float64), ""
|
||||
case int:
|
||||
return v <= expected.(int), ""
|
||||
case int8:
|
||||
return v <= expected.(int8), ""
|
||||
case int16:
|
||||
return v <= expected.(int16), ""
|
||||
case int32:
|
||||
return v <= expected.(int32), ""
|
||||
case int64:
|
||||
return v <= expected.(int64), ""
|
||||
case uint:
|
||||
return v <= expected.(uint), ""
|
||||
case uint8:
|
||||
return v <= expected.(uint8), ""
|
||||
case uint16:
|
||||
return v <= expected.(uint16), ""
|
||||
case uint32:
|
||||
return v <= expected.(uint32), ""
|
||||
case uint64:
|
||||
return v <= expected.(uint64), ""
|
||||
default:
|
||||
return false, "obtained value type not supported."
|
||||
}
|
||||
}
|
4
vendor/src/github.com/vdemeester/shakers/glide.yaml
vendored
Normal file
4
vendor/src/github.com/vdemeester/shakers/glide.yaml
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
package: main
|
||||
import:
|
||||
- package: github.com/go-check/check
|
||||
ref: 11d3bc7aa68e238947792f30573146a3231fc0f1
|
168
vendor/src/github.com/vdemeester/shakers/string.go
vendored
Normal file
168
vendor/src/github.com/vdemeester/shakers/string.go
vendored
Normal file
|
@ -0,0 +1,168 @@
|
|||
// Package shakers provide some checker implementation the go-check.Checker interface.
|
||||
package shakers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// Contains checker verifies that obtained value contains a substring.
|
||||
var Contains check.Checker = &substringChecker{
|
||||
&check.CheckerInfo{
|
||||
Name: "Contains",
|
||||
Params: []string{"obtained", "substring"},
|
||||
},
|
||||
strings.Contains,
|
||||
}
|
||||
|
||||
// ContainsAny checker verifies that any Unicode code points in chars
|
||||
// are in the obtained string.
|
||||
var ContainsAny check.Checker = &substringChecker{
|
||||
&check.CheckerInfo{
|
||||
Name: "ContainsAny",
|
||||
Params: []string{"obtained", "chars"},
|
||||
},
|
||||
strings.ContainsAny,
|
||||
}
|
||||
|
||||
// HasPrefix checker verifies that obtained value has the specified substring as prefix
|
||||
var HasPrefix check.Checker = &substringChecker{
|
||||
&check.CheckerInfo{
|
||||
Name: "HasPrefix",
|
||||
Params: []string{"obtained", "prefix"},
|
||||
},
|
||||
strings.HasPrefix,
|
||||
}
|
||||
|
||||
// HasSuffix checker verifies that obtained value has the specified substring as prefix
|
||||
var HasSuffix check.Checker = &substringChecker{
|
||||
&check.CheckerInfo{
|
||||
Name: "HasSuffix",
|
||||
Params: []string{"obtained", "suffix"},
|
||||
},
|
||||
strings.HasSuffix,
|
||||
}
|
||||
|
||||
// EqualFold checker verifies that obtained value is, interpreted as UTF-8 strings, are equal under Unicode case-folding.
|
||||
var EqualFold check.Checker = &substringChecker{
|
||||
&check.CheckerInfo{
|
||||
Name: "EqualFold",
|
||||
Params: []string{"obtained", "expected"},
|
||||
},
|
||||
strings.EqualFold,
|
||||
}
|
||||
|
||||
type substringChecker struct {
|
||||
*check.CheckerInfo
|
||||
substringFunction func(string, string) bool
|
||||
}
|
||||
|
||||
func (checker *substringChecker) Check(params []interface{}, names []string) (bool, string) {
|
||||
obtained := params[0]
|
||||
substring := params[1]
|
||||
substringStr, ok := substring.(string)
|
||||
if !ok {
|
||||
return false, fmt.Sprintf("%s value must be a string.", names[1])
|
||||
}
|
||||
obtainedString, obtainedIsStr := obtained.(string)
|
||||
if !obtainedIsStr {
|
||||
if obtainedWithStringer, obtainedHasStringer := obtained.(fmt.Stringer); obtainedHasStringer {
|
||||
obtainedString, obtainedIsStr = obtainedWithStringer.String(), true
|
||||
}
|
||||
}
|
||||
if obtainedIsStr {
|
||||
return checker.substringFunction(obtainedString, substringStr), ""
|
||||
}
|
||||
return false, "obtained value is not a string and has no .String()."
|
||||
}
|
||||
|
||||
// IndexAny checker verifies that the index of the first instance of any Unicode code point from chars in the obtained value is equal to expected
|
||||
var IndexAny check.Checker = &substringCountChecker{
|
||||
&check.CheckerInfo{
|
||||
Name: "IndexAny",
|
||||
Params: []string{"obtained", "chars", "expected"},
|
||||
},
|
||||
strings.IndexAny,
|
||||
}
|
||||
|
||||
// Index checker verifies that the index of the first instance of sep in the obtained value is equal to expected
|
||||
var Index check.Checker = &substringCountChecker{
|
||||
&check.CheckerInfo{
|
||||
Name: "Index",
|
||||
Params: []string{"obtained", "sep", "expected"},
|
||||
},
|
||||
strings.Index,
|
||||
}
|
||||
|
||||
// Count checker verifies that obtained value has the specified number of non-overlapping instances of sep
|
||||
var Count check.Checker = &substringCountChecker{
|
||||
&check.CheckerInfo{
|
||||
Name: "Count",
|
||||
Params: []string{"obtained", "sep", "expected"},
|
||||
},
|
||||
strings.Count,
|
||||
}
|
||||
|
||||
type substringCountChecker struct {
|
||||
*check.CheckerInfo
|
||||
substringFunction func(string, string) int
|
||||
}
|
||||
|
||||
func (checker *substringCountChecker) Check(params []interface{}, names []string) (bool, string) {
|
||||
obtained := params[0]
|
||||
substring := params[1]
|
||||
expected := params[2]
|
||||
substringStr, ok := substring.(string)
|
||||
if !ok {
|
||||
return false, fmt.Sprintf("%s value must be a string.", names[1])
|
||||
}
|
||||
obtainedString, obtainedIsStr := obtained.(string)
|
||||
if !obtainedIsStr {
|
||||
if obtainedWithStringer, obtainedHasStringer := obtained.(fmt.Stringer); obtainedHasStringer {
|
||||
obtainedString, obtainedIsStr = obtainedWithStringer.String(), true
|
||||
}
|
||||
}
|
||||
if obtainedIsStr {
|
||||
return checker.substringFunction(obtainedString, substringStr) == expected, ""
|
||||
}
|
||||
return false, "obtained value is not a string and has no .String()."
|
||||
}
|
||||
|
||||
// IsLower checker verifies that the obtained value is in lower case
|
||||
var IsLower check.Checker = &stringTransformChecker{
|
||||
&check.CheckerInfo{
|
||||
Name: "IsLower",
|
||||
Params: []string{"obtained"},
|
||||
},
|
||||
strings.ToLower,
|
||||
}
|
||||
|
||||
// IsUpper checker verifies that the obtained value is in lower case
|
||||
var IsUpper check.Checker = &stringTransformChecker{
|
||||
&check.CheckerInfo{
|
||||
Name: "IsUpper",
|
||||
Params: []string{"obtained"},
|
||||
},
|
||||
strings.ToUpper,
|
||||
}
|
||||
|
||||
type stringTransformChecker struct {
|
||||
*check.CheckerInfo
|
||||
stringFunction func(string) string
|
||||
}
|
||||
|
||||
func (checker *stringTransformChecker) Check(params []interface{}, names []string) (bool, string) {
|
||||
obtained := params[0]
|
||||
obtainedString, obtainedIsStr := obtained.(string)
|
||||
if !obtainedIsStr {
|
||||
if obtainedWithStringer, obtainedHasStringer := obtained.(fmt.Stringer); obtainedHasStringer {
|
||||
obtainedString, obtainedIsStr = obtainedWithStringer.String(), true
|
||||
}
|
||||
}
|
||||
if obtainedIsStr {
|
||||
return checker.stringFunction(obtainedString) == obtainedString, ""
|
||||
}
|
||||
return false, "obtained value is not a string and has no .String()."
|
||||
}
|
234
vendor/src/github.com/vdemeester/shakers/time.go
vendored
Normal file
234
vendor/src/github.com/vdemeester/shakers/time.go
vendored
Normal file
|
@ -0,0 +1,234 @@
|
|||
package shakers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
// Default format when parsing (in addition to RFC and default time formats..)
|
||||
const shortForm = "2006-01-02"
|
||||
|
||||
// IsBefore checker verifies the specified value is before the specified time.
|
||||
// It is exclusive.
|
||||
//
|
||||
// c.Assert(myTime, IsBefore, theTime, check.Commentf("bouuuhhh"))
|
||||
//
|
||||
var IsBefore check.Checker = &isBeforeChecker{
|
||||
&check.CheckerInfo{
|
||||
Name: "IsBefore",
|
||||
Params: []string{"obtained", "expected"},
|
||||
},
|
||||
}
|
||||
|
||||
type isBeforeChecker struct {
|
||||
*check.CheckerInfo
|
||||
}
|
||||
|
||||
func (checker *isBeforeChecker) Check(params []interface{}, names []string) (bool, string) {
|
||||
return isBefore(params[0], params[1])
|
||||
}
|
||||
|
||||
func isBefore(value, t interface{}) (bool, string) {
|
||||
tTime, ok := parseTime(t)
|
||||
if !ok {
|
||||
return false, "expected must be a Time struct, or parseable."
|
||||
}
|
||||
valueTime, valueIsTime := parseTime(value)
|
||||
if valueIsTime {
|
||||
return valueTime.Before(tTime), ""
|
||||
}
|
||||
return false, "obtained value is not a time.Time struct or parseable as a time."
|
||||
}
|
||||
|
||||
// IsAfter checker verifies the specified value is before the specified time.
|
||||
// It is exclusive.
|
||||
//
|
||||
// c.Assert(myTime, IsAfter, theTime, check.Commentf("bouuuhhh"))
|
||||
//
|
||||
var IsAfter check.Checker = &isAfterChecker{
|
||||
&check.CheckerInfo{
|
||||
Name: "IsAfter",
|
||||
Params: []string{"obtained", "expected"},
|
||||
},
|
||||
}
|
||||
|
||||
type isAfterChecker struct {
|
||||
*check.CheckerInfo
|
||||
}
|
||||
|
||||
func (checker *isAfterChecker) Check(params []interface{}, names []string) (bool, string) {
|
||||
return isAfter(params[0], params[1])
|
||||
}
|
||||
|
||||
func isAfter(value, t interface{}) (bool, string) {
|
||||
tTime, ok := parseTime(t)
|
||||
if !ok {
|
||||
return false, "expected must be a Time struct, or parseable."
|
||||
}
|
||||
valueTime, valueIsTime := parseTime(value)
|
||||
if valueIsTime {
|
||||
return valueTime.After(tTime), ""
|
||||
}
|
||||
return false, "obtained value is not a time.Time struct or parseable as a time."
|
||||
}
|
||||
|
||||
// IsBetween checker verifies the specified time is between the specified start
|
||||
// and end. It's exclusive so if the specified time is at the tip of the interval.
|
||||
//
|
||||
// c.Assert(myTime, IsBetween, startTime, endTime, check.Commentf("bouuuhhh"))
|
||||
//
|
||||
var IsBetween check.Checker = &isBetweenChecker{
|
||||
&check.CheckerInfo{
|
||||
Name: "IsBetween",
|
||||
Params: []string{"obtained", "start", "end"},
|
||||
},
|
||||
}
|
||||
|
||||
type isBetweenChecker struct {
|
||||
*check.CheckerInfo
|
||||
}
|
||||
|
||||
func (checker *isBetweenChecker) Check(params []interface{}, names []string) (bool, string) {
|
||||
return isBetween(params[0], params[1], params[2])
|
||||
}
|
||||
|
||||
func isBetween(value, start, end interface{}) (bool, string) {
|
||||
startTime, ok := parseTime(start)
|
||||
if !ok {
|
||||
return false, "start must be a Time struct, or parseable."
|
||||
}
|
||||
endTime, ok := parseTime(end)
|
||||
if !ok {
|
||||
return false, "end must be a Time struct, or parseable."
|
||||
}
|
||||
valueTime, valueIsTime := parseTime(value)
|
||||
if valueIsTime {
|
||||
return valueTime.After(startTime) && valueTime.Before(endTime), ""
|
||||
}
|
||||
return false, "obtained value is not a time.Time struct or parseable as a time."
|
||||
}
|
||||
|
||||
// TimeEquals checker verifies the specified time is the equal to the expected
|
||||
// time.
|
||||
//
|
||||
// c.Assert(myTime, TimeEquals, expected, check.Commentf("bouhhh"))
|
||||
//
|
||||
// It's possible to ignore some part of the time (like hours, minutes, etc..) using
|
||||
// the TimeIgnore checker with it.
|
||||
//
|
||||
// c.Assert(myTime, TimeIgnore(TimeEquals, time.Hour), expected, check.Commentf("... bouh.."))
|
||||
//
|
||||
var TimeEquals check.Checker = &timeEqualsChecker{
|
||||
&check.CheckerInfo{
|
||||
Name: "TimeEquals",
|
||||
Params: []string{"obtained", "expected"},
|
||||
},
|
||||
}
|
||||
|
||||
type timeEqualsChecker struct {
|
||||
*check.CheckerInfo
|
||||
}
|
||||
|
||||
func (checker *timeEqualsChecker) Check(params []interface{}, names []string) (bool, string) {
|
||||
return timeEquals(params[0], params[1])
|
||||
}
|
||||
|
||||
func timeEquals(obtained, expected interface{}) (bool, string) {
|
||||
expectedTime, ok := parseTime(expected)
|
||||
if !ok {
|
||||
return false, "expected must be a Time struct, or parseable."
|
||||
}
|
||||
valueTime, valueIsTime := parseTime(obtained)
|
||||
if valueIsTime {
|
||||
return valueTime.Equal(expectedTime), ""
|
||||
}
|
||||
return false, "obtained value is not a time.Time struct or parseable as a time."
|
||||
}
|
||||
|
||||
// TimeIgnore checker will ignore some part of the time on the encapsulated checker.
|
||||
//
|
||||
// c.Assert(myTime, TimeIgnore(IsBetween, time.Second), start, end)
|
||||
//
|
||||
// FIXME use interface{} for ignore (to enable "Month", ..
|
||||
func TimeIgnore(checker check.Checker, ignore time.Duration) check.Checker {
|
||||
return &timeIgnoreChecker{
|
||||
sub: checker,
|
||||
ignore: ignore,
|
||||
}
|
||||
}
|
||||
|
||||
type timeIgnoreChecker struct {
|
||||
sub check.Checker
|
||||
ignore time.Duration
|
||||
}
|
||||
|
||||
func (checker *timeIgnoreChecker) Info() *check.CheckerInfo {
|
||||
info := *checker.sub.Info()
|
||||
info.Name = fmt.Sprintf("TimeIgnore(%s, %v)", info.Name, checker.ignore)
|
||||
return &info
|
||||
}
|
||||
|
||||
func (checker *timeIgnoreChecker) Check(params []interface{}, names []string) (bool, string) {
|
||||
// Naive implementation : all params are supposed to be date
|
||||
mParams := make([]interface{}, len(params))
|
||||
for index, param := range params {
|
||||
paramTime, ok := parseTime(param)
|
||||
if !ok {
|
||||
return false, fmt.Sprintf("%s must be a Time struct, or parseable.", names[index])
|
||||
}
|
||||
year := paramTime.Year()
|
||||
month := paramTime.Month()
|
||||
day := paramTime.Day()
|
||||
hour := paramTime.Hour()
|
||||
min := paramTime.Minute()
|
||||
sec := paramTime.Second()
|
||||
nsec := paramTime.Nanosecond()
|
||||
location := paramTime.Location()
|
||||
switch checker.ignore {
|
||||
case time.Hour:
|
||||
hour = 0
|
||||
fallthrough
|
||||
case time.Minute:
|
||||
min = 0
|
||||
fallthrough
|
||||
case time.Second:
|
||||
sec = 0
|
||||
fallthrough
|
||||
case time.Millisecond:
|
||||
fallthrough
|
||||
case time.Microsecond:
|
||||
fallthrough
|
||||
case time.Nanosecond:
|
||||
nsec = 0
|
||||
}
|
||||
mParams[index] = time.Date(year, month, day, hour, min, sec, nsec, location)
|
||||
}
|
||||
return checker.sub.Check(mParams, names)
|
||||
}
|
||||
|
||||
func parseTime(datetime interface{}) (time.Time, bool) {
|
||||
switch datetime.(type) {
|
||||
case time.Time:
|
||||
return datetime.(time.Time), true
|
||||
case string:
|
||||
return parseTimeAsString(datetime.(string))
|
||||
default:
|
||||
if datetimeWithStr, ok := datetime.(fmt.Stringer); ok {
|
||||
return parseTimeAsString(datetimeWithStr.String())
|
||||
}
|
||||
return time.Time{}, false
|
||||
}
|
||||
}
|
||||
|
||||
func parseTimeAsString(timeAsStr string) (time.Time, bool) {
|
||||
forms := []string{shortForm, time.RFC3339, time.RFC3339Nano, time.RFC822, time.RFC822Z}
|
||||
for _, form := range forms {
|
||||
datetime, err := time.Parse(form, timeAsStr)
|
||||
if err == nil {
|
||||
return datetime, true
|
||||
}
|
||||
}
|
||||
return time.Time{}, false
|
||||
}
|
Loading…
Reference in a new issue