Write message using io.WriteCloser | Yes | No, see note 3 |
-Notes:
+Notes:
1. Large messages are fragmented in [Chrome's new WebSocket implementation](http://www.ietf.org/mail-archive/web/hybi/current/msg10503.html).
2. The application can get the type of a received data message by implementing
diff --git a/vendor/github.com/gorilla/websocket/client.go b/vendor/github.com/gorilla/websocket/client.go
index 43a87c75..2e32fd50 100644
--- a/vendor/github.com/gorilla/websocket/client.go
+++ b/vendor/github.com/gorilla/websocket/client.go
@@ -5,15 +5,15 @@
package websocket
import (
- "bufio"
"bytes"
+ "context"
"crypto/tls"
- "encoding/base64"
"errors"
"io"
"io/ioutil"
"net"
"net/http"
+ "net/http/httptrace"
"net/url"
"strings"
"time"
@@ -53,6 +53,10 @@ type Dialer struct {
// NetDial is nil, net.Dial is used.
NetDial func(network, addr string) (net.Conn, error)
+ // NetDialContext specifies the dial function for creating TCP connections. If
+ // NetDialContext is nil, net.DialContext is used.
+ NetDialContext func(ctx context.Context, network, addr string) (net.Conn, error)
+
// Proxy specifies a function to return a proxy for a given
// Request. If the function returns a non-nil error, the
// request is aborted with the provided error.
@@ -71,6 +75,17 @@ type Dialer struct {
// do not limit the size of the messages that can be sent or received.
ReadBufferSize, WriteBufferSize int
+ // WriteBufferPool is a pool of buffers for write operations. If the value
+ // is not set, then write buffers are allocated to the connection for the
+ // lifetime of the connection.
+ //
+ // A pool is most useful when the application has a modest volume of writes
+ // across a large number of connections.
+ //
+ // Applications should use a single pool for each unique value of
+ // WriteBufferSize.
+ WriteBufferPool BufferPool
+
// Subprotocols specifies the client's requested subprotocols.
Subprotocols []string
@@ -86,52 +101,13 @@ type Dialer struct {
Jar http.CookieJar
}
-var errMalformedURL = errors.New("malformed ws or wss URL")
-
-// parseURL parses the URL.
-//
-// This function is a replacement for the standard library url.Parse function.
-// In Go 1.4 and earlier, url.Parse loses information from the path.
-func parseURL(s string) (*url.URL, error) {
- // From the RFC:
- //
- // ws-URI = "ws:" "//" host [ ":" port ] path [ "?" query ]
- // wss-URI = "wss:" "//" host [ ":" port ] path [ "?" query ]
- var u url.URL
- switch {
- case strings.HasPrefix(s, "ws://"):
- u.Scheme = "ws"
- s = s[len("ws://"):]
- case strings.HasPrefix(s, "wss://"):
- u.Scheme = "wss"
- s = s[len("wss://"):]
- default:
- return nil, errMalformedURL
- }
-
- if i := strings.Index(s, "?"); i >= 0 {
- u.RawQuery = s[i+1:]
- s = s[:i]
- }
-
- if i := strings.Index(s, "/"); i >= 0 {
- u.Opaque = s[i:]
- s = s[:i]
- } else {
- u.Opaque = "/"
- }
-
- u.Host = s
-
- if strings.Contains(u.Host, "@") {
- // Don't bother parsing user information because user information is
- // not allowed in websocket URIs.
- return nil, errMalformedURL
- }
-
- return &u, nil
+// Dial creates a new client connection by calling DialContext with a background context.
+func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) {
+ return d.DialContext(context.Background(), urlStr, requestHeader)
}
+var errMalformedURL = errors.New("malformed ws or wss URL")
+
func hostPortNoPort(u *url.URL) (hostPort, hostNoPort string) {
hostPort = u.Host
hostNoPort = u.Host
@@ -150,26 +126,29 @@ func hostPortNoPort(u *url.URL) (hostPort, hostNoPort string) {
return hostPort, hostNoPort
}
-// DefaultDialer is a dialer with all fields set to the default zero values.
+// DefaultDialer is a dialer with all fields set to the default values.
var DefaultDialer = &Dialer{
- Proxy: http.ProxyFromEnvironment,
+ Proxy: http.ProxyFromEnvironment,
+ HandshakeTimeout: 45 * time.Second,
}
-// Dial creates a new client connection. Use requestHeader to specify the
+// nilDialer is dialer to use when receiver is nil.
+var nilDialer = *DefaultDialer
+
+// DialContext creates a new client connection. Use requestHeader to specify the
// origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies (Cookie).
// Use the response.Header to get the selected subprotocol
// (Sec-WebSocket-Protocol) and cookies (Set-Cookie).
//
+// The context will be used in the request and in the Dialer
+//
// If the WebSocket handshake fails, ErrBadHandshake is returned along with a
// non-nil *http.Response so that callers can handle redirects, authentication,
// etcetera. The response body may not contain the entire response and does not
// need to be closed by the application.
-func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) {
-
+func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) {
if d == nil {
- d = &Dialer{
- Proxy: http.ProxyFromEnvironment,
- }
+ d = &nilDialer
}
challengeKey, err := generateChallengeKey()
@@ -177,7 +156,7 @@ func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Re
return nil, nil, err
}
- u, err := parseURL(urlStr)
+ u, err := url.Parse(urlStr)
if err != nil {
return nil, nil, err
}
@@ -205,6 +184,7 @@ func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Re
Header: make(http.Header),
Host: u.Host,
}
+ req = req.WithContext(ctx)
// Set the cookies present in the cookie jar of the dialer
if d.Jar != nil {
@@ -237,45 +217,83 @@ func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Re
k == "Sec-Websocket-Extensions" ||
(k == "Sec-Websocket-Protocol" && len(d.Subprotocols) > 0):
return nil, nil, errors.New("websocket: duplicate header not allowed: " + k)
+ case k == "Sec-Websocket-Protocol":
+ req.Header["Sec-WebSocket-Protocol"] = vs
default:
req.Header[k] = vs
}
}
if d.EnableCompression {
- req.Header.Set("Sec-Websocket-Extensions", "permessage-deflate; server_no_context_takeover; client_no_context_takeover")
+ req.Header["Sec-WebSocket-Extensions"] = []string{"permessage-deflate; server_no_context_takeover; client_no_context_takeover"}
+ }
+
+ if d.HandshakeTimeout != 0 {
+ var cancel func()
+ ctx, cancel = context.WithTimeout(ctx, d.HandshakeTimeout)
+ defer cancel()
+ }
+
+ // Get network dial function.
+ var netDial func(network, add string) (net.Conn, error)
+
+ if d.NetDialContext != nil {
+ netDial = func(network, addr string) (net.Conn, error) {
+ return d.NetDialContext(ctx, network, addr)
+ }
+ } else if d.NetDial != nil {
+ netDial = d.NetDial
+ } else {
+ netDialer := &net.Dialer{}
+ netDial = func(network, addr string) (net.Conn, error) {
+ return netDialer.DialContext(ctx, network, addr)
+ }
+ }
+
+ // If needed, wrap the dial function to set the connection deadline.
+ if deadline, ok := ctx.Deadline(); ok {
+ forwardDial := netDial
+ netDial = func(network, addr string) (net.Conn, error) {
+ c, err := forwardDial(network, addr)
+ if err != nil {
+ return nil, err
+ }
+ err = c.SetDeadline(deadline)
+ if err != nil {
+ c.Close()
+ return nil, err
+ }
+ return c, nil
+ }
+ }
+
+ // If needed, wrap the dial function to connect through a proxy.
+ if d.Proxy != nil {
+ proxyURL, err := d.Proxy(req)
+ if err != nil {
+ return nil, nil, err
+ }
+ if proxyURL != nil {
+ dialer, err := proxy_FromURL(proxyURL, netDialerFunc(netDial))
+ if err != nil {
+ return nil, nil, err
+ }
+ netDial = dialer.Dial
+ }
}
hostPort, hostNoPort := hostPortNoPort(u)
-
- var proxyURL *url.URL
- // Check wether the proxy method has been configured
- if d.Proxy != nil {
- proxyURL, err = d.Proxy(req)
- }
- if err != nil {
- return nil, nil, err
+ trace := httptrace.ContextClientTrace(ctx)
+ if trace != nil && trace.GetConn != nil {
+ trace.GetConn(hostPort)
}
- var targetHostPort string
- if proxyURL != nil {
- targetHostPort, _ = hostPortNoPort(proxyURL)
- } else {
- targetHostPort = hostPort
+ netConn, err := netDial("tcp", hostPort)
+ if trace != nil && trace.GotConn != nil {
+ trace.GotConn(httptrace.GotConnInfo{
+ Conn: netConn,
+ })
}
-
- var deadline time.Time
- if d.HandshakeTimeout != 0 {
- deadline = time.Now().Add(d.HandshakeTimeout)
- }
-
- netDial := d.NetDial
- if netDial == nil {
- netDialer := &net.Dialer{Deadline: deadline}
- netDial = netDialer.Dial
- }
-
- netConn, err := netDial("tcp", targetHostPort)
if err != nil {
return nil, nil, err
}
@@ -286,42 +304,6 @@ func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Re
}
}()
- if err := netConn.SetDeadline(deadline); err != nil {
- return nil, nil, err
- }
-
- if proxyURL != nil {
- connectHeader := make(http.Header)
- if user := proxyURL.User; user != nil {
- proxyUser := user.Username()
- if proxyPassword, passwordSet := user.Password(); passwordSet {
- credential := base64.StdEncoding.EncodeToString([]byte(proxyUser + ":" + proxyPassword))
- connectHeader.Set("Proxy-Authorization", "Basic "+credential)
- }
- }
- connectReq := &http.Request{
- Method: "CONNECT",
- URL: &url.URL{Opaque: hostPort},
- Host: hostPort,
- Header: connectHeader,
- }
-
- connectReq.Write(netConn)
-
- // Read response.
- // Okay to use and discard buffered reader here, because
- // TLS server will not speak until spoken to.
- br := bufio.NewReader(netConn)
- resp, err := http.ReadResponse(br, connectReq)
- if err != nil {
- return nil, nil, err
- }
- if resp.StatusCode != 200 {
- f := strings.SplitN(resp.Status, " ", 2)
- return nil, nil, errors.New(f[1])
- }
- }
-
if u.Scheme == "https" {
cfg := cloneTLSConfig(d.TLSClientConfig)
if cfg.ServerName == "" {
@@ -329,22 +311,31 @@ func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Re
}
tlsConn := tls.Client(netConn, cfg)
netConn = tlsConn
- if err := tlsConn.Handshake(); err != nil {
- return nil, nil, err
+
+ var err error
+ if trace != nil {
+ err = doHandshakeWithTrace(trace, tlsConn, cfg)
+ } else {
+ err = doHandshake(tlsConn, cfg)
}
- if !cfg.InsecureSkipVerify {
- if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil {
- return nil, nil, err
- }
+
+ if err != nil {
+ return nil, nil, err
}
}
- conn := newConn(netConn, false, d.ReadBufferSize, d.WriteBufferSize)
+ conn := newConn(netConn, false, d.ReadBufferSize, d.WriteBufferSize, d.WriteBufferPool, nil, nil)
if err := req.Write(netConn); err != nil {
return nil, nil, err
}
+ if trace != nil && trace.GotFirstResponseByte != nil {
+ if peek, err := conn.br.Peek(1); err == nil && len(peek) == 1 {
+ trace.GotFirstResponseByte()
+ }
+ }
+
resp, err := http.ReadResponse(conn.br, req)
if err != nil {
return nil, nil, err
@@ -390,3 +381,15 @@ func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Re
netConn = nil // to avoid close in defer.
return conn, resp, nil
}
+
+func doHandshake(tlsConn *tls.Conn, cfg *tls.Config) error {
+ if err := tlsConn.Handshake(); err != nil {
+ return err
+ }
+ if !cfg.InsecureSkipVerify {
+ if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil {
+ return err
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/gorilla/websocket/conn.go b/vendor/github.com/gorilla/websocket/conn.go
index 97e1dbac..d2a21c14 100644
--- a/vendor/github.com/gorilla/websocket/conn.go
+++ b/vendor/github.com/gorilla/websocket/conn.go
@@ -76,7 +76,7 @@ const (
// is UTF-8 encoded text.
PingMessage = 9
- // PongMessage denotes a ping control message. The optional message payload
+ // PongMessage denotes a pong control message. The optional message payload
// is UTF-8 encoded text.
PongMessage = 10
)
@@ -100,9 +100,8 @@ func (e *netError) Error() string { return e.msg }
func (e *netError) Temporary() bool { return e.temporary }
func (e *netError) Timeout() bool { return e.timeout }
-// CloseError represents close frame.
+// CloseError represents a close message.
type CloseError struct {
-
// Code is defined in RFC 6455, section 11.7.
Code int
@@ -224,6 +223,20 @@ func isValidReceivedCloseCode(code int) bool {
return validReceivedCloseCodes[code] || (code >= 3000 && code <= 4999)
}
+// BufferPool represents a pool of buffers. The *sync.Pool type satisfies this
+// interface. The type of the value stored in a pool is not specified.
+type BufferPool interface {
+ // Get gets a value from the pool or returns nil if the pool is empty.
+ Get() interface{}
+ // Put adds a value to the pool.
+ Put(interface{})
+}
+
+// writePoolData is the type added to the write buffer pool. This wrapper is
+// used to prevent applications from peeking at and depending on the values
+// added to the pool.
+type writePoolData struct{ buf []byte }
+
// The Conn type represents a WebSocket connection.
type Conn struct {
conn net.Conn
@@ -233,6 +246,8 @@ type Conn struct {
// Write fields
mu chan bool // used as mutex to protect write to conn
writeBuf []byte // frame is constructed in this buffer.
+ writePool BufferPool
+ writeBufSize int
writeDeadline time.Time
writer io.WriteCloser // the current writer returned to the application
isWriting bool // for best-effort concurrent write detection
@@ -264,64 +279,29 @@ type Conn struct {
newDecompressionReader func(io.Reader) io.ReadCloser
}
-func newConn(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int) *Conn {
- return newConnBRW(conn, isServer, readBufferSize, writeBufferSize, nil)
-}
+func newConn(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int, writeBufferPool BufferPool, br *bufio.Reader, writeBuf []byte) *Conn {
-type writeHook struct {
- p []byte
-}
-
-func (wh *writeHook) Write(p []byte) (int, error) {
- wh.p = p
- return len(p), nil
-}
-
-func newConnBRW(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int, brw *bufio.ReadWriter) *Conn {
- mu := make(chan bool, 1)
- mu <- true
-
- var br *bufio.Reader
- if readBufferSize == 0 && brw != nil && brw.Reader != nil {
- // Reuse the supplied bufio.Reader if the buffer has a useful size.
- // This code assumes that peek on a reader returns
- // bufio.Reader.buf[:0].
- brw.Reader.Reset(conn)
- if p, err := brw.Reader.Peek(0); err == nil && cap(p) >= 256 {
- br = brw.Reader
- }
- }
if br == nil {
if readBufferSize == 0 {
readBufferSize = defaultReadBufferSize
- }
- if readBufferSize < maxControlFramePayloadSize {
+ } else if readBufferSize < maxControlFramePayloadSize {
+ // must be large enough for control frame
readBufferSize = maxControlFramePayloadSize
}
br = bufio.NewReaderSize(conn, readBufferSize)
}
- var writeBuf []byte
- if writeBufferSize == 0 && brw != nil && brw.Writer != nil {
- // Use the bufio.Writer's buffer if the buffer has a useful size. This
- // code assumes that bufio.Writer.buf[:1] is passed to the
- // bufio.Writer's underlying writer.
- var wh writeHook
- brw.Writer.Reset(&wh)
- brw.Writer.WriteByte(0)
- brw.Flush()
- if cap(wh.p) >= maxFrameHeaderSize+256 {
- writeBuf = wh.p[:cap(wh.p)]
- }
- }
-
- if writeBuf == nil {
- if writeBufferSize == 0 {
- writeBufferSize = defaultWriteBufferSize
- }
- writeBuf = make([]byte, writeBufferSize+maxFrameHeaderSize)
+ if writeBufferSize <= 0 {
+ writeBufferSize = defaultWriteBufferSize
+ }
+ writeBufferSize += maxFrameHeaderSize
+
+ if writeBuf == nil && writeBufferPool == nil {
+ writeBuf = make([]byte, writeBufferSize)
}
+ mu := make(chan bool, 1)
+ mu <- true
c := &Conn{
isServer: isServer,
br: br,
@@ -329,6 +309,8 @@ func newConnBRW(conn net.Conn, isServer bool, readBufferSize, writeBufferSize in
mu: mu,
readFinal: true,
writeBuf: writeBuf,
+ writePool: writeBufferPool,
+ writeBufSize: writeBufferSize,
enableWriteCompression: true,
compressionLevel: defaultCompressionLevel,
}
@@ -343,7 +325,8 @@ func (c *Conn) Subprotocol() string {
return c.subprotocol
}
-// Close closes the underlying network connection without sending or waiting for a close frame.
+// Close closes the underlying network connection without sending or waiting
+// for a close message.
func (c *Conn) Close() error {
return c.conn.Close()
}
@@ -370,7 +353,16 @@ func (c *Conn) writeFatal(err error) error {
return err
}
-func (c *Conn) write(frameType int, deadline time.Time, bufs ...[]byte) error {
+func (c *Conn) read(n int) ([]byte, error) {
+ p, err := c.br.Peek(n)
+ if err == io.EOF {
+ err = errUnexpectedEOF
+ }
+ c.br.Discard(len(p))
+ return p, err
+}
+
+func (c *Conn) write(frameType int, deadline time.Time, buf0, buf1 []byte) error {
<-c.mu
defer func() { c.mu <- true }()
@@ -382,15 +374,14 @@ func (c *Conn) write(frameType int, deadline time.Time, bufs ...[]byte) error {
}
c.conn.SetWriteDeadline(deadline)
- for _, buf := range bufs {
- if len(buf) > 0 {
- _, err := c.conn.Write(buf)
- if err != nil {
- return c.writeFatal(err)
- }
- }
+ if len(buf1) == 0 {
+ _, err = c.conn.Write(buf0)
+ } else {
+ err = c.writeBufs(buf0, buf1)
+ }
+ if err != nil {
+ return c.writeFatal(err)
}
-
if frameType == CloseMessage {
c.writeFatal(ErrCloseSent)
}
@@ -476,7 +467,19 @@ func (c *Conn) prepWrite(messageType int) error {
c.writeErrMu.Lock()
err := c.writeErr
c.writeErrMu.Unlock()
- return err
+ if err != nil {
+ return err
+ }
+
+ if c.writeBuf == nil {
+ wpd, ok := c.writePool.Get().(writePoolData)
+ if ok {
+ c.writeBuf = wpd.buf
+ } else {
+ c.writeBuf = make([]byte, c.writeBufSize)
+ }
+ }
+ return nil
}
// NextWriter returns a writer for the next message to send. The writer's Close
@@ -484,6 +487,9 @@ func (c *Conn) prepWrite(messageType int) error {
//
// There can be at most one open writer on a connection. NextWriter closes the
// previous writer if the application has not already done so.
+//
+// All message types (TextMessage, BinaryMessage, CloseMessage, PingMessage and
+// PongMessage) are supported.
func (c *Conn) NextWriter(messageType int) (io.WriteCloser, error) {
if err := c.prepWrite(messageType); err != nil {
return nil, err
@@ -599,6 +605,10 @@ func (w *messageWriter) flushFrame(final bool, extra []byte) error {
if final {
c.writer = nil
+ if c.writePool != nil {
+ c.writePool.Put(writePoolData{buf: c.writeBuf})
+ c.writeBuf = nil
+ }
return nil
}
@@ -764,7 +774,6 @@ func (c *Conn) SetWriteDeadline(t time.Time) error {
// Read methods
func (c *Conn) advanceFrame() (int, error) {
-
// 1. Skip remainder of previous frame.
if c.readRemaining > 0 {
@@ -1033,7 +1042,7 @@ func (c *Conn) SetReadDeadline(t time.Time) error {
}
// SetReadLimit sets the maximum size for a message read from the peer. If a
-// message exceeds the limit, the connection sends a close frame to the peer
+// message exceeds the limit, the connection sends a close message to the peer
// and returns ErrReadLimit to the application.
func (c *Conn) SetReadLimit(limit int64) {
c.readLimit = limit
@@ -1046,24 +1055,22 @@ func (c *Conn) CloseHandler() func(code int, text string) error {
// SetCloseHandler sets the handler for close messages received from the peer.
// The code argument to h is the received close code or CloseNoStatusReceived
-// if the close message is empty. The default close handler sends a close frame
-// back to the peer.
+// if the close message is empty. The default close handler sends a close
+// message back to the peer.
//
-// The application must read the connection to process close messages as
-// described in the section on Control Frames above.
+// The handler function is called from the NextReader, ReadMessage and message
+// reader Read methods. The application must read the connection to process
+// close messages as described in the section on Control Messages above.
//
-// The connection read methods return a CloseError when a close frame is
+// The connection read methods return a CloseError when a close message is
// received. Most applications should handle close messages as part of their
// normal error handling. Applications should only set a close handler when the
-// application must perform some action before sending a close frame back to
+// application must perform some action before sending a close message back to
// the peer.
func (c *Conn) SetCloseHandler(h func(code int, text string) error) {
if h == nil {
h = func(code int, text string) error {
- message := []byte{}
- if code != CloseNoStatusReceived {
- message = FormatCloseMessage(code, "")
- }
+ message := FormatCloseMessage(code, "")
c.WriteControl(CloseMessage, message, time.Now().Add(writeWait))
return nil
}
@@ -1077,11 +1084,12 @@ func (c *Conn) PingHandler() func(appData string) error {
}
// SetPingHandler sets the handler for ping messages received from the peer.
-// The appData argument to h is the PING frame application data. The default
+// The appData argument to h is the PING message application data. The default
// ping handler sends a pong to the peer.
//
-// The application must read the connection to process ping messages as
-// described in the section on Control Frames above.
+// The handler function is called from the NextReader, ReadMessage and message
+// reader Read methods. The application must read the connection to process
+// ping messages as described in the section on Control Messages above.
func (c *Conn) SetPingHandler(h func(appData string) error) {
if h == nil {
h = func(message string) error {
@@ -1103,11 +1111,12 @@ func (c *Conn) PongHandler() func(appData string) error {
}
// SetPongHandler sets the handler for pong messages received from the peer.
-// The appData argument to h is the PONG frame application data. The default
+// The appData argument to h is the PONG message application data. The default
// pong handler does nothing.
//
-// The application must read the connection to process ping messages as
-// described in the section on Control Frames above.
+// The handler function is called from the NextReader, ReadMessage and message
+// reader Read methods. The application must read the connection to process
+// pong messages as described in the section on Control Messages above.
func (c *Conn) SetPongHandler(h func(appData string) error) {
if h == nil {
h = func(string) error { return nil }
@@ -1141,7 +1150,14 @@ func (c *Conn) SetCompressionLevel(level int) error {
}
// FormatCloseMessage formats closeCode and text as a WebSocket close message.
+// An empty message is returned for code CloseNoStatusReceived.
func FormatCloseMessage(closeCode int, text string) []byte {
+ if closeCode == CloseNoStatusReceived {
+ // Return empty message because it's illegal to send
+ // CloseNoStatusReceived. Return non-nil value in case application
+ // checks for nil.
+ return []byte{}
+ }
buf := make([]byte, 2+len(text))
binary.BigEndian.PutUint16(buf, uint16(closeCode))
copy(buf[2:], text)
diff --git a/vendor/github.com/gorilla/websocket/conn_read_legacy.go b/vendor/github.com/gorilla/websocket/conn_read_legacy.go
deleted file mode 100644
index 018541cf..00000000
--- a/vendor/github.com/gorilla/websocket/conn_read_legacy.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !go1.5
-
-package websocket
-
-import "io"
-
-func (c *Conn) read(n int) ([]byte, error) {
- p, err := c.br.Peek(n)
- if err == io.EOF {
- err = errUnexpectedEOF
- }
- if len(p) > 0 {
- // advance over the bytes just read
- io.ReadFull(c.br, p)
- }
- return p, err
-}
diff --git a/vendor/github.com/gorilla/websocket/conn_read.go b/vendor/github.com/gorilla/websocket/conn_write.go
similarity index 52%
rename from vendor/github.com/gorilla/websocket/conn_read.go
rename to vendor/github.com/gorilla/websocket/conn_write.go
index 1ea15059..a509a21f 100644
--- a/vendor/github.com/gorilla/websocket/conn_read.go
+++ b/vendor/github.com/gorilla/websocket/conn_write.go
@@ -2,17 +2,14 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build go1.5
+// +build go1.8
package websocket
-import "io"
+import "net"
-func (c *Conn) read(n int) ([]byte, error) {
- p, err := c.br.Peek(n)
- if err == io.EOF {
- err = errUnexpectedEOF
- }
- c.br.Discard(len(p))
- return p, err
+func (c *Conn) writeBufs(bufs ...[]byte) error {
+ b := net.Buffers(bufs)
+ _, err := b.WriteTo(c.conn)
+ return err
}
diff --git a/vendor/github.com/gorilla/websocket/conn_write_legacy.go b/vendor/github.com/gorilla/websocket/conn_write_legacy.go
new file mode 100644
index 00000000..37edaff5
--- /dev/null
+++ b/vendor/github.com/gorilla/websocket/conn_write_legacy.go
@@ -0,0 +1,18 @@
+// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.8
+
+package websocket
+
+func (c *Conn) writeBufs(bufs ...[]byte) error {
+ for _, buf := range bufs {
+ if len(buf) > 0 {
+ if _, err := c.conn.Write(buf); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/gorilla/websocket/doc.go b/vendor/github.com/gorilla/websocket/doc.go
index e291a952..dcce1a63 100644
--- a/vendor/github.com/gorilla/websocket/doc.go
+++ b/vendor/github.com/gorilla/websocket/doc.go
@@ -6,9 +6,8 @@
//
// Overview
//
-// The Conn type represents a WebSocket connection. A server application uses
-// the Upgrade function from an Upgrader object with a HTTP request handler
-// to get a pointer to a Conn:
+// The Conn type represents a WebSocket connection. A server application calls
+// the Upgrader.Upgrade method from an HTTP request handler to get a *Conn:
//
// var upgrader = websocket.Upgrader{
// ReadBufferSize: 1024,
@@ -31,10 +30,12 @@
// for {
// messageType, p, err := conn.ReadMessage()
// if err != nil {
+// log.Println(err)
// return
// }
-// if err = conn.WriteMessage(messageType, p); err != nil {
-// return err
+// if err := conn.WriteMessage(messageType, p); err != nil {
+// log.Println(err)
+// return
// }
// }
//
@@ -85,20 +86,26 @@
// and pong. Call the connection WriteControl, WriteMessage or NextWriter
// methods to send a control message to the peer.
//
-// Connections handle received close messages by sending a close message to the
-// peer and returning a *CloseError from the the NextReader, ReadMessage or the
-// message Read method.
+// Connections handle received close messages by calling the handler function
+// set with the SetCloseHandler method and by returning a *CloseError from the
+// NextReader, ReadMessage or the message Read method. The default close
+// handler sends a close message to the peer.
//
-// Connections handle received ping and pong messages by invoking callback
-// functions set with SetPingHandler and SetPongHandler methods. The callback
-// functions are called from the NextReader, ReadMessage and the message Read
-// methods.
+// Connections handle received ping messages by calling the handler function
+// set with the SetPingHandler method. The default ping handler sends a pong
+// message to the peer.
//
-// The default ping handler sends a pong to the peer. The application's reading
-// goroutine can block for a short time while the handler writes the pong data
-// to the connection.
+// Connections handle received pong messages by calling the handler function
+// set with the SetPongHandler method. The default pong handler does nothing.
+// If an application sends ping messages, then the application should set a
+// pong handler to receive the corresponding pong.
//
-// The application must read the connection to process ping, pong and close
+// The control message handler functions are called from the NextReader,
+// ReadMessage and message reader Read methods. The default close and ping
+// handlers can block these methods for a short time when the handler writes to
+// the connection.
+//
+// The application must read the connection to process close, ping and pong
// messages sent from the peer. If the application is not otherwise interested
// in messages from the peer, then the application should start a goroutine to
// read and discard messages from the peer. A simple example is:
@@ -137,19 +144,12 @@
// method fails the WebSocket handshake with HTTP status 403.
//
// If the CheckOrigin field is nil, then the Upgrader uses a safe default: fail
-// the handshake if the Origin request header is present and not equal to the
-// Host request header.
+// the handshake if the Origin request header is present and the Origin host is
+// not equal to the Host request header.
//
-// An application can allow connections from any origin by specifying a
-// function that always returns true:
-//
-// var upgrader = websocket.Upgrader{
-// CheckOrigin: func(r *http.Request) bool { return true },
-// }
-//
-// The deprecated Upgrade function does not enforce an origin policy. It's the
-// application's responsibility to check the Origin header before calling
-// Upgrade.
+// The deprecated package-level Upgrade function does not perform origin
+// checking. The application is responsible for checking the Origin header
+// before calling the Upgrade function.
//
// Compression EXPERIMENTAL
//
diff --git a/vendor/github.com/gorilla/websocket/json.go b/vendor/github.com/gorilla/websocket/json.go
index 4f0e3687..dc2c1f64 100644
--- a/vendor/github.com/gorilla/websocket/json.go
+++ b/vendor/github.com/gorilla/websocket/json.go
@@ -9,12 +9,14 @@ import (
"io"
)
-// WriteJSON is deprecated, use c.WriteJSON instead.
+// WriteJSON writes the JSON encoding of v as a message.
+//
+// Deprecated: Use c.WriteJSON instead.
func WriteJSON(c *Conn, v interface{}) error {
return c.WriteJSON(v)
}
-// WriteJSON writes the JSON encoding of v to the connection.
+// WriteJSON writes the JSON encoding of v as a message.
//
// See the documentation for encoding/json Marshal for details about the
// conversion of Go values to JSON.
@@ -31,7 +33,10 @@ func (c *Conn) WriteJSON(v interface{}) error {
return err2
}
-// ReadJSON is deprecated, use c.ReadJSON instead.
+// ReadJSON reads the next JSON-encoded message from the connection and stores
+// it in the value pointed to by v.
+//
+// Deprecated: Use c.ReadJSON instead.
func ReadJSON(c *Conn, v interface{}) error {
return c.ReadJSON(v)
}
diff --git a/vendor/github.com/gorilla/websocket/mask.go b/vendor/github.com/gorilla/websocket/mask.go
index 6a88bbc7..577fce9e 100644
--- a/vendor/github.com/gorilla/websocket/mask.go
+++ b/vendor/github.com/gorilla/websocket/mask.go
@@ -11,7 +11,6 @@ import "unsafe"
const wordSize = int(unsafe.Sizeof(uintptr(0)))
func maskBytes(key [4]byte, pos int, b []byte) int {
-
// Mask one byte at a time for small buffers.
if len(b) < 2*wordSize {
for i := range b {
diff --git a/vendor/github.com/gorilla/websocket/prepared.go b/vendor/github.com/gorilla/websocket/prepared.go
index 1efffbd1..74ec565d 100644
--- a/vendor/github.com/gorilla/websocket/prepared.go
+++ b/vendor/github.com/gorilla/websocket/prepared.go
@@ -19,7 +19,6 @@ import (
type PreparedMessage struct {
messageType int
data []byte
- err error
mu sync.Mutex
frames map[prepareKey]*preparedFrame
}
diff --git a/vendor/github.com/gorilla/websocket/proxy.go b/vendor/github.com/gorilla/websocket/proxy.go
new file mode 100644
index 00000000..bf2478e4
--- /dev/null
+++ b/vendor/github.com/gorilla/websocket/proxy.go
@@ -0,0 +1,77 @@
+// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package websocket
+
+import (
+ "bufio"
+ "encoding/base64"
+ "errors"
+ "net"
+ "net/http"
+ "net/url"
+ "strings"
+)
+
+type netDialerFunc func(network, addr string) (net.Conn, error)
+
+func (fn netDialerFunc) Dial(network, addr string) (net.Conn, error) {
+ return fn(network, addr)
+}
+
+func init() {
+ proxy_RegisterDialerType("http", func(proxyURL *url.URL, forwardDialer proxy_Dialer) (proxy_Dialer, error) {
+ return &httpProxyDialer{proxyURL: proxyURL, fowardDial: forwardDialer.Dial}, nil
+ })
+}
+
+type httpProxyDialer struct {
+ proxyURL *url.URL
+ fowardDial func(network, addr string) (net.Conn, error)
+}
+
+func (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error) {
+ hostPort, _ := hostPortNoPort(hpd.proxyURL)
+ conn, err := hpd.fowardDial(network, hostPort)
+ if err != nil {
+ return nil, err
+ }
+
+ connectHeader := make(http.Header)
+ if user := hpd.proxyURL.User; user != nil {
+ proxyUser := user.Username()
+ if proxyPassword, passwordSet := user.Password(); passwordSet {
+ credential := base64.StdEncoding.EncodeToString([]byte(proxyUser + ":" + proxyPassword))
+ connectHeader.Set("Proxy-Authorization", "Basic "+credential)
+ }
+ }
+
+ connectReq := &http.Request{
+ Method: "CONNECT",
+ URL: &url.URL{Opaque: addr},
+ Host: addr,
+ Header: connectHeader,
+ }
+
+ if err := connectReq.Write(conn); err != nil {
+ conn.Close()
+ return nil, err
+ }
+
+ // Read response. It's OK to use and discard buffered reader here becaue
+ // the remote server does not speak until spoken to.
+ br := bufio.NewReader(conn)
+ resp, err := http.ReadResponse(br, connectReq)
+ if err != nil {
+ conn.Close()
+ return nil, err
+ }
+
+ if resp.StatusCode != 200 {
+ conn.Close()
+ f := strings.SplitN(resp.Status, " ", 2)
+ return nil, errors.New(f[1])
+ }
+ return conn, nil
+}
diff --git a/vendor/github.com/gorilla/websocket/server.go b/vendor/github.com/gorilla/websocket/server.go
index 3495e0f1..a761824b 100644
--- a/vendor/github.com/gorilla/websocket/server.go
+++ b/vendor/github.com/gorilla/websocket/server.go
@@ -7,7 +7,7 @@ package websocket
import (
"bufio"
"errors"
- "net"
+ "io"
"net/http"
"net/url"
"strings"
@@ -33,10 +33,23 @@ type Upgrader struct {
// or received.
ReadBufferSize, WriteBufferSize int
+ // WriteBufferPool is a pool of buffers for write operations. If the value
+ // is not set, then write buffers are allocated to the connection for the
+ // lifetime of the connection.
+ //
+ // A pool is most useful when the application has a modest volume of writes
+ // across a large number of connections.
+ //
+ // Applications should use a single pool for each unique value of
+ // WriteBufferSize.
+ WriteBufferPool BufferPool
+
// Subprotocols specifies the server's supported protocols in order of
- // preference. If this field is set, then the Upgrade method negotiates a
+ // preference. If this field is not nil, then the Upgrade method negotiates a
// subprotocol by selecting the first match in this list with a protocol
- // requested by the client.
+ // requested by the client. If there's no match, then no protocol is
+ // negotiated (the Sec-Websocket-Protocol header is not included in the
+ // handshake response).
Subprotocols []string
// Error specifies the function for generating HTTP error responses. If Error
@@ -44,8 +57,12 @@ type Upgrader struct {
Error func(w http.ResponseWriter, r *http.Request, status int, reason error)
// CheckOrigin returns true if the request Origin header is acceptable. If
- // CheckOrigin is nil, the host in the Origin header must not be set or
- // must match the host of the request.
+ // CheckOrigin is nil, then a safe default is used: return false if the
+ // Origin request header is present and the origin host is not equal to
+ // request Host header.
+ //
+ // A CheckOrigin function should carefully validate the request origin to
+ // prevent cross-site request forgery.
CheckOrigin func(r *http.Request) bool
// EnableCompression specify if the server should attempt to negotiate per
@@ -76,7 +93,7 @@ func checkSameOrigin(r *http.Request) bool {
if err != nil {
return false
}
- return u.Host == r.Host
+ return equalASCIIFold(u.Host, r.Host)
}
func (u *Upgrader) selectSubprotocol(r *http.Request, responseHeader http.Header) string {
@@ -99,42 +116,44 @@ func (u *Upgrader) selectSubprotocol(r *http.Request, responseHeader http.Header
//
// The responseHeader is included in the response to the client's upgrade
// request. Use the responseHeader to specify cookies (Set-Cookie) and the
-// application negotiated subprotocol (Sec-Websocket-Protocol).
+// application negotiated subprotocol (Sec-WebSocket-Protocol).
//
// If the upgrade fails, then Upgrade replies to the client with an HTTP error
// response.
func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*Conn, error) {
- if r.Method != "GET" {
- return u.returnError(w, r, http.StatusMethodNotAllowed, "websocket: not a websocket handshake: request method is not GET")
- }
-
- if _, ok := responseHeader["Sec-Websocket-Extensions"]; ok {
- return u.returnError(w, r, http.StatusInternalServerError, "websocket: application specific 'Sec-Websocket-Extensions' headers are unsupported")
- }
+ const badHandshake = "websocket: the client is not using the websocket protocol: "
if !tokenListContainsValue(r.Header, "Connection", "upgrade") {
- return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: 'upgrade' token not found in 'Connection' header")
+ return u.returnError(w, r, http.StatusBadRequest, badHandshake+"'upgrade' token not found in 'Connection' header")
}
if !tokenListContainsValue(r.Header, "Upgrade", "websocket") {
- return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: 'websocket' token not found in 'Upgrade' header")
+ return u.returnError(w, r, http.StatusBadRequest, badHandshake+"'websocket' token not found in 'Upgrade' header")
+ }
+
+ if r.Method != "GET" {
+ return u.returnError(w, r, http.StatusMethodNotAllowed, badHandshake+"request method is not GET")
}
if !tokenListContainsValue(r.Header, "Sec-Websocket-Version", "13") {
return u.returnError(w, r, http.StatusBadRequest, "websocket: unsupported version: 13 not found in 'Sec-Websocket-Version' header")
}
+ if _, ok := responseHeader["Sec-Websocket-Extensions"]; ok {
+ return u.returnError(w, r, http.StatusInternalServerError, "websocket: application specific 'Sec-WebSocket-Extensions' headers are unsupported")
+ }
+
checkOrigin := u.CheckOrigin
if checkOrigin == nil {
checkOrigin = checkSameOrigin
}
if !checkOrigin(r) {
- return u.returnError(w, r, http.StatusForbidden, "websocket: 'Origin' header value not allowed")
+ return u.returnError(w, r, http.StatusForbidden, "websocket: request origin not allowed by Upgrader.CheckOrigin")
}
challengeKey := r.Header.Get("Sec-Websocket-Key")
if challengeKey == "" {
- return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: `Sec-Websocket-Key' header is missing or blank")
+ return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: `Sec-WebSocket-Key' header is missing or blank")
}
subprotocol := u.selectSubprotocol(r, responseHeader)
@@ -151,17 +170,12 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade
}
}
- var (
- netConn net.Conn
- err error
- )
-
h, ok := w.(http.Hijacker)
if !ok {
return u.returnError(w, r, http.StatusInternalServerError, "websocket: response does not implement http.Hijacker")
}
var brw *bufio.ReadWriter
- netConn, brw, err = h.Hijack()
+ netConn, brw, err := h.Hijack()
if err != nil {
return u.returnError(w, r, http.StatusInternalServerError, err.Error())
}
@@ -171,7 +185,21 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade
return nil, errors.New("websocket: client sent data before handshake is complete")
}
- c := newConnBRW(netConn, true, u.ReadBufferSize, u.WriteBufferSize, brw)
+ var br *bufio.Reader
+ if u.ReadBufferSize == 0 && bufioReaderSize(netConn, brw.Reader) > 256 {
+ // Reuse hijacked buffered reader as connection reader.
+ br = brw.Reader
+ }
+
+ buf := bufioWriterBuffer(netConn, brw.Writer)
+
+ var writeBuf []byte
+ if u.WriteBufferPool == nil && u.WriteBufferSize == 0 && len(buf) >= maxFrameHeaderSize+256 {
+ // Reuse hijacked write buffer as connection buffer.
+ writeBuf = buf
+ }
+
+ c := newConn(netConn, true, u.ReadBufferSize, u.WriteBufferSize, u.WriteBufferPool, br, writeBuf)
c.subprotocol = subprotocol
if compress {
@@ -179,17 +207,23 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade
c.newDecompressionReader = decompressNoContextTakeover
}
- p := c.writeBuf[:0]
+ // Use larger of hijacked buffer and connection write buffer for header.
+ p := buf
+ if len(c.writeBuf) > len(p) {
+ p = c.writeBuf
+ }
+ p = p[:0]
+
p = append(p, "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "...)
p = append(p, computeAcceptKey(challengeKey)...)
p = append(p, "\r\n"...)
if c.subprotocol != "" {
- p = append(p, "Sec-Websocket-Protocol: "...)
+ p = append(p, "Sec-WebSocket-Protocol: "...)
p = append(p, c.subprotocol...)
p = append(p, "\r\n"...)
}
if compress {
- p = append(p, "Sec-Websocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover\r\n"...)
+ p = append(p, "Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover\r\n"...)
}
for k, vs := range responseHeader {
if k == "Sec-Websocket-Protocol" {
@@ -230,13 +264,14 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade
// Upgrade upgrades the HTTP server connection to the WebSocket protocol.
//
-// This function is deprecated, use websocket.Upgrader instead.
+// Deprecated: Use websocket.Upgrader instead.
//
-// The application is responsible for checking the request origin before
-// calling Upgrade. An example implementation of the same origin policy is:
+// Upgrade does not perform origin checking. The application is responsible for
+// checking the Origin header before calling Upgrade. An example implementation
+// of the same origin policy check is:
//
// if req.Header.Get("Origin") != "http://"+req.Host {
-// http.Error(w, "Origin not allowed", 403)
+// http.Error(w, "Origin not allowed", http.StatusForbidden)
// return
// }
//
@@ -289,3 +324,40 @@ func IsWebSocketUpgrade(r *http.Request) bool {
return tokenListContainsValue(r.Header, "Connection", "upgrade") &&
tokenListContainsValue(r.Header, "Upgrade", "websocket")
}
+
+// bufioReaderSize size returns the size of a bufio.Reader.
+func bufioReaderSize(originalReader io.Reader, br *bufio.Reader) int {
+ // This code assumes that peek on a reset reader returns
+ // bufio.Reader.buf[:0].
+ // TODO: Use bufio.Reader.Size() after Go 1.10
+ br.Reset(originalReader)
+ if p, err := br.Peek(0); err == nil {
+ return cap(p)
+ }
+ return 0
+}
+
+// writeHook is an io.Writer that records the last slice passed to it vio
+// io.Writer.Write.
+type writeHook struct {
+ p []byte
+}
+
+func (wh *writeHook) Write(p []byte) (int, error) {
+ wh.p = p
+ return len(p), nil
+}
+
+// bufioWriterBuffer grabs the buffer from a bufio.Writer.
+func bufioWriterBuffer(originalWriter io.Writer, bw *bufio.Writer) []byte {
+ // This code assumes that bufio.Writer.buf[:1] is passed to the
+ // bufio.Writer's underlying writer.
+ var wh writeHook
+ bw.Reset(&wh)
+ bw.WriteByte(0)
+ bw.Flush()
+
+ bw.Reset(originalWriter)
+
+ return wh.p[:cap(wh.p)]
+}
diff --git a/vendor/github.com/gorilla/websocket/trace.go b/vendor/github.com/gorilla/websocket/trace.go
new file mode 100644
index 00000000..834f122a
--- /dev/null
+++ b/vendor/github.com/gorilla/websocket/trace.go
@@ -0,0 +1,19 @@
+// +build go1.8
+
+package websocket
+
+import (
+ "crypto/tls"
+ "net/http/httptrace"
+)
+
+func doHandshakeWithTrace(trace *httptrace.ClientTrace, tlsConn *tls.Conn, cfg *tls.Config) error {
+ if trace.TLSHandshakeStart != nil {
+ trace.TLSHandshakeStart()
+ }
+ err := doHandshake(tlsConn, cfg)
+ if trace.TLSHandshakeDone != nil {
+ trace.TLSHandshakeDone(tlsConn.ConnectionState(), err)
+ }
+ return err
+}
diff --git a/vendor/github.com/gorilla/websocket/trace_17.go b/vendor/github.com/gorilla/websocket/trace_17.go
new file mode 100644
index 00000000..77d05a0b
--- /dev/null
+++ b/vendor/github.com/gorilla/websocket/trace_17.go
@@ -0,0 +1,12 @@
+// +build !go1.8
+
+package websocket
+
+import (
+ "crypto/tls"
+ "net/http/httptrace"
+)
+
+func doHandshakeWithTrace(trace *httptrace.ClientTrace, tlsConn *tls.Conn, cfg *tls.Config) error {
+ return doHandshake(tlsConn, cfg)
+}
diff --git a/vendor/github.com/gorilla/websocket/util.go b/vendor/github.com/gorilla/websocket/util.go
index 9a4908df..354001e1 100644
--- a/vendor/github.com/gorilla/websocket/util.go
+++ b/vendor/github.com/gorilla/websocket/util.go
@@ -11,6 +11,7 @@ import (
"io"
"net/http"
"strings"
+ "unicode/utf8"
)
var keyGUID = []byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11")
@@ -111,14 +112,14 @@ func nextTokenOrQuoted(s string) (value string, rest string) {
case escape:
escape = false
p[j] = b
- j += 1
+ j++
case b == '\\':
escape = true
case b == '"':
return string(p[:j]), s[i+1:]
default:
p[j] = b
- j += 1
+ j++
}
}
return "", ""
@@ -127,8 +128,31 @@ func nextTokenOrQuoted(s string) (value string, rest string) {
return "", ""
}
+// equalASCIIFold returns true if s is equal to t with ASCII case folding.
+func equalASCIIFold(s, t string) bool {
+ for s != "" && t != "" {
+ sr, size := utf8.DecodeRuneInString(s)
+ s = s[size:]
+ tr, size := utf8.DecodeRuneInString(t)
+ t = t[size:]
+ if sr == tr {
+ continue
+ }
+ if 'A' <= sr && sr <= 'Z' {
+ sr = sr + 'a' - 'A'
+ }
+ if 'A' <= tr && tr <= 'Z' {
+ tr = tr + 'a' - 'A'
+ }
+ if sr != tr {
+ return false
+ }
+ }
+ return s == t
+}
+
// tokenListContainsValue returns true if the 1#token header with the given
-// name contains token.
+// name contains a token equal to value with ASCII case folding.
func tokenListContainsValue(header http.Header, name string, value string) bool {
headers:
for _, s := range header[name] {
@@ -142,7 +166,7 @@ headers:
if s != "" && s[0] != ',' {
continue headers
}
- if strings.EqualFold(t, value) {
+ if equalASCIIFold(t, value) {
return true
}
if s == "" {
@@ -154,9 +178,8 @@ headers:
return false
}
-// parseExtensiosn parses WebSocket extensions from a header.
+// parseExtensions parses WebSocket extensions from a header.
func parseExtensions(header http.Header) []map[string]string {
-
// From RFC 6455:
//
// Sec-WebSocket-Extensions = extension-list
diff --git a/vendor/github.com/gorilla/websocket/x_net_proxy.go b/vendor/github.com/gorilla/websocket/x_net_proxy.go
new file mode 100644
index 00000000..2e668f6b
--- /dev/null
+++ b/vendor/github.com/gorilla/websocket/x_net_proxy.go
@@ -0,0 +1,473 @@
+// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT.
+//go:generate bundle -o x_net_proxy.go golang.org/x/net/proxy
+
+// Package proxy provides support for a variety of protocols to proxy network
+// data.
+//
+
+package websocket
+
+import (
+ "errors"
+ "io"
+ "net"
+ "net/url"
+ "os"
+ "strconv"
+ "strings"
+ "sync"
+)
+
+type proxy_direct struct{}
+
+// Direct is a direct proxy: one that makes network connections directly.
+var proxy_Direct = proxy_direct{}
+
+func (proxy_direct) Dial(network, addr string) (net.Conn, error) {
+ return net.Dial(network, addr)
+}
+
+// A PerHost directs connections to a default Dialer unless the host name
+// requested matches one of a number of exceptions.
+type proxy_PerHost struct {
+ def, bypass proxy_Dialer
+
+ bypassNetworks []*net.IPNet
+ bypassIPs []net.IP
+ bypassZones []string
+ bypassHosts []string
+}
+
+// NewPerHost returns a PerHost Dialer that directs connections to either
+// defaultDialer or bypass, depending on whether the connection matches one of
+// the configured rules.
+func proxy_NewPerHost(defaultDialer, bypass proxy_Dialer) *proxy_PerHost {
+ return &proxy_PerHost{
+ def: defaultDialer,
+ bypass: bypass,
+ }
+}
+
+// Dial connects to the address addr on the given network through either
+// defaultDialer or bypass.
+func (p *proxy_PerHost) Dial(network, addr string) (c net.Conn, err error) {
+ host, _, err := net.SplitHostPort(addr)
+ if err != nil {
+ return nil, err
+ }
+
+ return p.dialerForRequest(host).Dial(network, addr)
+}
+
+func (p *proxy_PerHost) dialerForRequest(host string) proxy_Dialer {
+ if ip := net.ParseIP(host); ip != nil {
+ for _, net := range p.bypassNetworks {
+ if net.Contains(ip) {
+ return p.bypass
+ }
+ }
+ for _, bypassIP := range p.bypassIPs {
+ if bypassIP.Equal(ip) {
+ return p.bypass
+ }
+ }
+ return p.def
+ }
+
+ for _, zone := range p.bypassZones {
+ if strings.HasSuffix(host, zone) {
+ return p.bypass
+ }
+ if host == zone[1:] {
+ // For a zone ".example.com", we match "example.com"
+ // too.
+ return p.bypass
+ }
+ }
+ for _, bypassHost := range p.bypassHosts {
+ if bypassHost == host {
+ return p.bypass
+ }
+ }
+ return p.def
+}
+
+// AddFromString parses a string that contains comma-separated values
+// specifying hosts that should use the bypass proxy. Each value is either an
+// IP address, a CIDR range, a zone (*.example.com) or a host name
+// (localhost). A best effort is made to parse the string and errors are
+// ignored.
+func (p *proxy_PerHost) AddFromString(s string) {
+ hosts := strings.Split(s, ",")
+ for _, host := range hosts {
+ host = strings.TrimSpace(host)
+ if len(host) == 0 {
+ continue
+ }
+ if strings.Contains(host, "/") {
+ // We assume that it's a CIDR address like 127.0.0.0/8
+ if _, net, err := net.ParseCIDR(host); err == nil {
+ p.AddNetwork(net)
+ }
+ continue
+ }
+ if ip := net.ParseIP(host); ip != nil {
+ p.AddIP(ip)
+ continue
+ }
+ if strings.HasPrefix(host, "*.") {
+ p.AddZone(host[1:])
+ continue
+ }
+ p.AddHost(host)
+ }
+}
+
+// AddIP specifies an IP address that will use the bypass proxy. Note that
+// this will only take effect if a literal IP address is dialed. A connection
+// to a named host will never match an IP.
+func (p *proxy_PerHost) AddIP(ip net.IP) {
+ p.bypassIPs = append(p.bypassIPs, ip)
+}
+
+// AddNetwork specifies an IP range that will use the bypass proxy. Note that
+// this will only take effect if a literal IP address is dialed. A connection
+// to a named host will never match.
+func (p *proxy_PerHost) AddNetwork(net *net.IPNet) {
+ p.bypassNetworks = append(p.bypassNetworks, net)
+}
+
+// AddZone specifies a DNS suffix that will use the bypass proxy. A zone of
+// "example.com" matches "example.com" and all of its subdomains.
+func (p *proxy_PerHost) AddZone(zone string) {
+ if strings.HasSuffix(zone, ".") {
+ zone = zone[:len(zone)-1]
+ }
+ if !strings.HasPrefix(zone, ".") {
+ zone = "." + zone
+ }
+ p.bypassZones = append(p.bypassZones, zone)
+}
+
+// AddHost specifies a host name that will use the bypass proxy.
+func (p *proxy_PerHost) AddHost(host string) {
+ if strings.HasSuffix(host, ".") {
+ host = host[:len(host)-1]
+ }
+ p.bypassHosts = append(p.bypassHosts, host)
+}
+
+// A Dialer is a means to establish a connection.
+type proxy_Dialer interface {
+ // Dial connects to the given address via the proxy.
+ Dial(network, addr string) (c net.Conn, err error)
+}
+
+// Auth contains authentication parameters that specific Dialers may require.
+type proxy_Auth struct {
+ User, Password string
+}
+
+// FromEnvironment returns the dialer specified by the proxy related variables in
+// the environment.
+func proxy_FromEnvironment() proxy_Dialer {
+ allProxy := proxy_allProxyEnv.Get()
+ if len(allProxy) == 0 {
+ return proxy_Direct
+ }
+
+ proxyURL, err := url.Parse(allProxy)
+ if err != nil {
+ return proxy_Direct
+ }
+ proxy, err := proxy_FromURL(proxyURL, proxy_Direct)
+ if err != nil {
+ return proxy_Direct
+ }
+
+ noProxy := proxy_noProxyEnv.Get()
+ if len(noProxy) == 0 {
+ return proxy
+ }
+
+ perHost := proxy_NewPerHost(proxy, proxy_Direct)
+ perHost.AddFromString(noProxy)
+ return perHost
+}
+
+// proxySchemes is a map from URL schemes to a function that creates a Dialer
+// from a URL with such a scheme.
+var proxy_proxySchemes map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error)
+
+// RegisterDialerType takes a URL scheme and a function to generate Dialers from
+// a URL with that scheme and a forwarding Dialer. Registered schemes are used
+// by FromURL.
+func proxy_RegisterDialerType(scheme string, f func(*url.URL, proxy_Dialer) (proxy_Dialer, error)) {
+ if proxy_proxySchemes == nil {
+ proxy_proxySchemes = make(map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error))
+ }
+ proxy_proxySchemes[scheme] = f
+}
+
+// FromURL returns a Dialer given a URL specification and an underlying
+// Dialer for it to make network requests.
+func proxy_FromURL(u *url.URL, forward proxy_Dialer) (proxy_Dialer, error) {
+ var auth *proxy_Auth
+ if u.User != nil {
+ auth = new(proxy_Auth)
+ auth.User = u.User.Username()
+ if p, ok := u.User.Password(); ok {
+ auth.Password = p
+ }
+ }
+
+ switch u.Scheme {
+ case "socks5":
+ return proxy_SOCKS5("tcp", u.Host, auth, forward)
+ }
+
+ // If the scheme doesn't match any of the built-in schemes, see if it
+ // was registered by another package.
+ if proxy_proxySchemes != nil {
+ if f, ok := proxy_proxySchemes[u.Scheme]; ok {
+ return f(u, forward)
+ }
+ }
+
+ return nil, errors.New("proxy: unknown scheme: " + u.Scheme)
+}
+
+var (
+ proxy_allProxyEnv = &proxy_envOnce{
+ names: []string{"ALL_PROXY", "all_proxy"},
+ }
+ proxy_noProxyEnv = &proxy_envOnce{
+ names: []string{"NO_PROXY", "no_proxy"},
+ }
+)
+
+// envOnce looks up an environment variable (optionally by multiple
+// names) once. It mitigates expensive lookups on some platforms
+// (e.g. Windows).
+// (Borrowed from net/http/transport.go)
+type proxy_envOnce struct {
+ names []string
+ once sync.Once
+ val string
+}
+
+func (e *proxy_envOnce) Get() string {
+ e.once.Do(e.init)
+ return e.val
+}
+
+func (e *proxy_envOnce) init() {
+ for _, n := range e.names {
+ e.val = os.Getenv(n)
+ if e.val != "" {
+ return
+ }
+ }
+}
+
+// SOCKS5 returns a Dialer that makes SOCKSv5 connections to the given address
+// with an optional username and password. See RFC 1928 and RFC 1929.
+func proxy_SOCKS5(network, addr string, auth *proxy_Auth, forward proxy_Dialer) (proxy_Dialer, error) {
+ s := &proxy_socks5{
+ network: network,
+ addr: addr,
+ forward: forward,
+ }
+ if auth != nil {
+ s.user = auth.User
+ s.password = auth.Password
+ }
+
+ return s, nil
+}
+
+type proxy_socks5 struct {
+ user, password string
+ network, addr string
+ forward proxy_Dialer
+}
+
+const proxy_socks5Version = 5
+
+const (
+ proxy_socks5AuthNone = 0
+ proxy_socks5AuthPassword = 2
+)
+
+const proxy_socks5Connect = 1
+
+const (
+ proxy_socks5IP4 = 1
+ proxy_socks5Domain = 3
+ proxy_socks5IP6 = 4
+)
+
+var proxy_socks5Errors = []string{
+ "",
+ "general failure",
+ "connection forbidden",
+ "network unreachable",
+ "host unreachable",
+ "connection refused",
+ "TTL expired",
+ "command not supported",
+ "address type not supported",
+}
+
+// Dial connects to the address addr on the given network via the SOCKS5 proxy.
+func (s *proxy_socks5) Dial(network, addr string) (net.Conn, error) {
+ switch network {
+ case "tcp", "tcp6", "tcp4":
+ default:
+ return nil, errors.New("proxy: no support for SOCKS5 proxy connections of type " + network)
+ }
+
+ conn, err := s.forward.Dial(s.network, s.addr)
+ if err != nil {
+ return nil, err
+ }
+ if err := s.connect(conn, addr); err != nil {
+ conn.Close()
+ return nil, err
+ }
+ return conn, nil
+}
+
+// connect takes an existing connection to a socks5 proxy server,
+// and commands the server to extend that connection to target,
+// which must be a canonical address with a host and port.
+func (s *proxy_socks5) connect(conn net.Conn, target string) error {
+ host, portStr, err := net.SplitHostPort(target)
+ if err != nil {
+ return err
+ }
+
+ port, err := strconv.Atoi(portStr)
+ if err != nil {
+ return errors.New("proxy: failed to parse port number: " + portStr)
+ }
+ if port < 1 || port > 0xffff {
+ return errors.New("proxy: port number out of range: " + portStr)
+ }
+
+ // the size here is just an estimate
+ buf := make([]byte, 0, 6+len(host))
+
+ buf = append(buf, proxy_socks5Version)
+ if len(s.user) > 0 && len(s.user) < 256 && len(s.password) < 256 {
+ buf = append(buf, 2 /* num auth methods */, proxy_socks5AuthNone, proxy_socks5AuthPassword)
+ } else {
+ buf = append(buf, 1 /* num auth methods */, proxy_socks5AuthNone)
+ }
+
+ if _, err := conn.Write(buf); err != nil {
+ return errors.New("proxy: failed to write greeting to SOCKS5 proxy at " + s.addr + ": " + err.Error())
+ }
+
+ if _, err := io.ReadFull(conn, buf[:2]); err != nil {
+ return errors.New("proxy: failed to read greeting from SOCKS5 proxy at " + s.addr + ": " + err.Error())
+ }
+ if buf[0] != 5 {
+ return errors.New("proxy: SOCKS5 proxy at " + s.addr + " has unexpected version " + strconv.Itoa(int(buf[0])))
+ }
+ if buf[1] == 0xff {
+ return errors.New("proxy: SOCKS5 proxy at " + s.addr + " requires authentication")
+ }
+
+ // See RFC 1929
+ if buf[1] == proxy_socks5AuthPassword {
+ buf = buf[:0]
+ buf = append(buf, 1 /* password protocol version */)
+ buf = append(buf, uint8(len(s.user)))
+ buf = append(buf, s.user...)
+ buf = append(buf, uint8(len(s.password)))
+ buf = append(buf, s.password...)
+
+ if _, err := conn.Write(buf); err != nil {
+ return errors.New("proxy: failed to write authentication request to SOCKS5 proxy at " + s.addr + ": " + err.Error())
+ }
+
+ if _, err := io.ReadFull(conn, buf[:2]); err != nil {
+ return errors.New("proxy: failed to read authentication reply from SOCKS5 proxy at " + s.addr + ": " + err.Error())
+ }
+
+ if buf[1] != 0 {
+ return errors.New("proxy: SOCKS5 proxy at " + s.addr + " rejected username/password")
+ }
+ }
+
+ buf = buf[:0]
+ buf = append(buf, proxy_socks5Version, proxy_socks5Connect, 0 /* reserved */)
+
+ if ip := net.ParseIP(host); ip != nil {
+ if ip4 := ip.To4(); ip4 != nil {
+ buf = append(buf, proxy_socks5IP4)
+ ip = ip4
+ } else {
+ buf = append(buf, proxy_socks5IP6)
+ }
+ buf = append(buf, ip...)
+ } else {
+ if len(host) > 255 {
+ return errors.New("proxy: destination host name too long: " + host)
+ }
+ buf = append(buf, proxy_socks5Domain)
+ buf = append(buf, byte(len(host)))
+ buf = append(buf, host...)
+ }
+ buf = append(buf, byte(port>>8), byte(port))
+
+ if _, err := conn.Write(buf); err != nil {
+ return errors.New("proxy: failed to write connect request to SOCKS5 proxy at " + s.addr + ": " + err.Error())
+ }
+
+ if _, err := io.ReadFull(conn, buf[:4]); err != nil {
+ return errors.New("proxy: failed to read connect reply from SOCKS5 proxy at " + s.addr + ": " + err.Error())
+ }
+
+ failure := "unknown error"
+ if int(buf[1]) < len(proxy_socks5Errors) {
+ failure = proxy_socks5Errors[buf[1]]
+ }
+
+ if len(failure) > 0 {
+ return errors.New("proxy: SOCKS5 proxy at " + s.addr + " failed to connect: " + failure)
+ }
+
+ bytesToDiscard := 0
+ switch buf[3] {
+ case proxy_socks5IP4:
+ bytesToDiscard = net.IPv4len
+ case proxy_socks5IP6:
+ bytesToDiscard = net.IPv6len
+ case proxy_socks5Domain:
+ _, err := io.ReadFull(conn, buf[:1])
+ if err != nil {
+ return errors.New("proxy: failed to read domain length from SOCKS5 proxy at " + s.addr + ": " + err.Error())
+ }
+ bytesToDiscard = int(buf[0])
+ default:
+ return errors.New("proxy: got unknown address type " + strconv.Itoa(int(buf[3])) + " from SOCKS5 proxy at " + s.addr)
+ }
+
+ if cap(buf) < bytesToDiscard {
+ buf = make([]byte, bytesToDiscard)
+ } else {
+ buf = buf[:bytesToDiscard]
+ }
+ if _, err := io.ReadFull(conn, buf); err != nil {
+ return errors.New("proxy: failed to read address from SOCKS5 proxy at " + s.addr + ": " + err.Error())
+ }
+
+ // Also need to discard the port number
+ if _, err := io.ReadFull(conn, buf[:2]); err != nil {
+ return errors.New("proxy: failed to read port from SOCKS5 proxy at " + s.addr + ": " + err.Error())
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/klauspost/cpuid/private-gen.go b/vendor/github.com/klauspost/cpuid/private-gen.go
deleted file mode 100644
index 437333d2..00000000
--- a/vendor/github.com/klauspost/cpuid/private-gen.go
+++ /dev/null
@@ -1,476 +0,0 @@
-// +build ignore
-
-package main
-
-import (
- "bytes"
- "fmt"
- "go/ast"
- "go/parser"
- "go/printer"
- "go/token"
- "io"
- "io/ioutil"
- "log"
- "os"
- "reflect"
- "strings"
- "unicode"
- "unicode/utf8"
-)
-
-var inFiles = []string{"cpuid.go", "cpuid_test.go"}
-var copyFiles = []string{"cpuid_amd64.s", "cpuid_386.s", "detect_ref.go", "detect_intel.go"}
-var fileSet = token.NewFileSet()
-var reWrites = []rewrite{
- initRewrite("CPUInfo -> cpuInfo"),
- initRewrite("Vendor -> vendor"),
- initRewrite("Flags -> flags"),
- initRewrite("Detect -> detect"),
- initRewrite("CPU -> cpu"),
-}
-var excludeNames = map[string]bool{"string": true, "join": true, "trim": true,
- // cpuid_test.go
- "t": true, "println": true, "logf": true, "log": true, "fatalf": true, "fatal": true,
-}
-
-var excludePrefixes = []string{"test", "benchmark"}
-
-func main() {
- Package := "private"
- parserMode := parser.ParseComments
- exported := make(map[string]rewrite)
- for _, file := range inFiles {
- in, err := os.Open(file)
- if err != nil {
- log.Fatalf("opening input", err)
- }
-
- src, err := ioutil.ReadAll(in)
- if err != nil {
- log.Fatalf("reading input", err)
- }
-
- astfile, err := parser.ParseFile(fileSet, file, src, parserMode)
- if err != nil {
- log.Fatalf("parsing input", err)
- }
-
- for _, rw := range reWrites {
- astfile = rw(astfile)
- }
-
- // Inspect the AST and print all identifiers and literals.
- var startDecl token.Pos
- var endDecl token.Pos
- ast.Inspect(astfile, func(n ast.Node) bool {
- var s string
- switch x := n.(type) {
- case *ast.Ident:
- if x.IsExported() {
- t := strings.ToLower(x.Name)
- for _, pre := range excludePrefixes {
- if strings.HasPrefix(t, pre) {
- return true
- }
- }
- if excludeNames[t] != true {
- //if x.Pos() > startDecl && x.Pos() < endDecl {
- exported[x.Name] = initRewrite(x.Name + " -> " + t)
- }
- }
-
- case *ast.GenDecl:
- if x.Tok == token.CONST && x.Lparen > 0 {
- startDecl = x.Lparen
- endDecl = x.Rparen
- // fmt.Printf("Decl:%s -> %s\n", fileSet.Position(startDecl), fileSet.Position(endDecl))
- }
- }
- if s != "" {
- fmt.Printf("%s:\t%s\n", fileSet.Position(n.Pos()), s)
- }
- return true
- })
-
- for _, rw := range exported {
- astfile = rw(astfile)
- }
-
- var buf bytes.Buffer
-
- printer.Fprint(&buf, fileSet, astfile)
-
- // Remove package documentation and insert information
- s := buf.String()
- ind := strings.Index(buf.String(), "\npackage cpuid")
- s = s[ind:]
- s = "// Generated, DO NOT EDIT,\n" +
- "// but copy it to your own project and rename the package.\n" +
- "// See more at http://github.com/klauspost/cpuid\n" +
- s
-
- outputName := Package + string(os.PathSeparator) + file
-
- err = ioutil.WriteFile(outputName, []byte(s), 0644)
- if err != nil {
- log.Fatalf("writing output: %s", err)
- }
- log.Println("Generated", outputName)
- }
-
- for _, file := range copyFiles {
- dst := ""
- if strings.HasPrefix(file, "cpuid") {
- dst = Package + string(os.PathSeparator) + file
- } else {
- dst = Package + string(os.PathSeparator) + "cpuid_" + file
- }
- err := copyFile(file, dst)
- if err != nil {
- log.Fatalf("copying file: %s", err)
- }
- log.Println("Copied", dst)
- }
-}
-
-// CopyFile copies a file from src to dst. If src and dst files exist, and are
-// the same, then return success. Copy the file contents from src to dst.
-func copyFile(src, dst string) (err error) {
- sfi, err := os.Stat(src)
- if err != nil {
- return
- }
- if !sfi.Mode().IsRegular() {
- // cannot copy non-regular files (e.g., directories,
- // symlinks, devices, etc.)
- return fmt.Errorf("CopyFile: non-regular source file %s (%q)", sfi.Name(), sfi.Mode().String())
- }
- dfi, err := os.Stat(dst)
- if err != nil {
- if !os.IsNotExist(err) {
- return
- }
- } else {
- if !(dfi.Mode().IsRegular()) {
- return fmt.Errorf("CopyFile: non-regular destination file %s (%q)", dfi.Name(), dfi.Mode().String())
- }
- if os.SameFile(sfi, dfi) {
- return
- }
- }
- err = copyFileContents(src, dst)
- return
-}
-
-// copyFileContents copies the contents of the file named src to the file named
-// by dst. The file will be created if it does not already exist. If the
-// destination file exists, all it's contents will be replaced by the contents
-// of the source file.
-func copyFileContents(src, dst string) (err error) {
- in, err := os.Open(src)
- if err != nil {
- return
- }
- defer in.Close()
- out, err := os.Create(dst)
- if err != nil {
- return
- }
- defer func() {
- cerr := out.Close()
- if err == nil {
- err = cerr
- }
- }()
- if _, err = io.Copy(out, in); err != nil {
- return
- }
- err = out.Sync()
- return
-}
-
-type rewrite func(*ast.File) *ast.File
-
-// Mostly copied from gofmt
-func initRewrite(rewriteRule string) rewrite {
- f := strings.Split(rewriteRule, "->")
- if len(f) != 2 {
- fmt.Fprintf(os.Stderr, "rewrite rule must be of the form 'pattern -> replacement'\n")
- os.Exit(2)
- }
- pattern := parseExpr(f[0], "pattern")
- replace := parseExpr(f[1], "replacement")
- return func(p *ast.File) *ast.File { return rewriteFile(pattern, replace, p) }
-}
-
-// parseExpr parses s as an expression.
-// It might make sense to expand this to allow statement patterns,
-// but there are problems with preserving formatting and also
-// with what a wildcard for a statement looks like.
-func parseExpr(s, what string) ast.Expr {
- x, err := parser.ParseExpr(s)
- if err != nil {
- fmt.Fprintf(os.Stderr, "parsing %s %s at %s\n", what, s, err)
- os.Exit(2)
- }
- return x
-}
-
-// Keep this function for debugging.
-/*
-func dump(msg string, val reflect.Value) {
- fmt.Printf("%s:\n", msg)
- ast.Print(fileSet, val.Interface())
- fmt.Println()
-}
-*/
-
-// rewriteFile applies the rewrite rule 'pattern -> replace' to an entire file.
-func rewriteFile(pattern, replace ast.Expr, p *ast.File) *ast.File {
- cmap := ast.NewCommentMap(fileSet, p, p.Comments)
- m := make(map[string]reflect.Value)
- pat := reflect.ValueOf(pattern)
- repl := reflect.ValueOf(replace)
-
- var rewriteVal func(val reflect.Value) reflect.Value
- rewriteVal = func(val reflect.Value) reflect.Value {
- // don't bother if val is invalid to start with
- if !val.IsValid() {
- return reflect.Value{}
- }
- for k := range m {
- delete(m, k)
- }
- val = apply(rewriteVal, val)
- if match(m, pat, val) {
- val = subst(m, repl, reflect.ValueOf(val.Interface().(ast.Node).Pos()))
- }
- return val
- }
-
- r := apply(rewriteVal, reflect.ValueOf(p)).Interface().(*ast.File)
- r.Comments = cmap.Filter(r).Comments() // recreate comments list
- return r
-}
-
-// set is a wrapper for x.Set(y); it protects the caller from panics if x cannot be changed to y.
-func set(x, y reflect.Value) {
- // don't bother if x cannot be set or y is invalid
- if !x.CanSet() || !y.IsValid() {
- return
- }
- defer func() {
- if x := recover(); x != nil {
- if s, ok := x.(string); ok &&
- (strings.Contains(s, "type mismatch") || strings.Contains(s, "not assignable")) {
- // x cannot be set to y - ignore this rewrite
- return
- }
- panic(x)
- }
- }()
- x.Set(y)
-}
-
-// Values/types for special cases.
-var (
- objectPtrNil = reflect.ValueOf((*ast.Object)(nil))
- scopePtrNil = reflect.ValueOf((*ast.Scope)(nil))
-
- identType = reflect.TypeOf((*ast.Ident)(nil))
- objectPtrType = reflect.TypeOf((*ast.Object)(nil))
- positionType = reflect.TypeOf(token.NoPos)
- callExprType = reflect.TypeOf((*ast.CallExpr)(nil))
- scopePtrType = reflect.TypeOf((*ast.Scope)(nil))
-)
-
-// apply replaces each AST field x in val with f(x), returning val.
-// To avoid extra conversions, f operates on the reflect.Value form.
-func apply(f func(reflect.Value) reflect.Value, val reflect.Value) reflect.Value {
- if !val.IsValid() {
- return reflect.Value{}
- }
-
- // *ast.Objects introduce cycles and are likely incorrect after
- // rewrite; don't follow them but replace with nil instead
- if val.Type() == objectPtrType {
- return objectPtrNil
- }
-
- // similarly for scopes: they are likely incorrect after a rewrite;
- // replace them with nil
- if val.Type() == scopePtrType {
- return scopePtrNil
- }
-
- switch v := reflect.Indirect(val); v.Kind() {
- case reflect.Slice:
- for i := 0; i < v.Len(); i++ {
- e := v.Index(i)
- set(e, f(e))
- }
- case reflect.Struct:
- for i := 0; i < v.NumField(); i++ {
- e := v.Field(i)
- set(e, f(e))
- }
- case reflect.Interface:
- e := v.Elem()
- set(v, f(e))
- }
- return val
-}
-
-func isWildcard(s string) bool {
- rune, size := utf8.DecodeRuneInString(s)
- return size == len(s) && unicode.IsLower(rune)
-}
-
-// match returns true if pattern matches val,
-// recording wildcard submatches in m.
-// If m == nil, match checks whether pattern == val.
-func match(m map[string]reflect.Value, pattern, val reflect.Value) bool {
- // Wildcard matches any expression. If it appears multiple
- // times in the pattern, it must match the same expression
- // each time.
- if m != nil && pattern.IsValid() && pattern.Type() == identType {
- name := pattern.Interface().(*ast.Ident).Name
- if isWildcard(name) && val.IsValid() {
- // wildcards only match valid (non-nil) expressions.
- if _, ok := val.Interface().(ast.Expr); ok && !val.IsNil() {
- if old, ok := m[name]; ok {
- return match(nil, old, val)
- }
- m[name] = val
- return true
- }
- }
- }
-
- // Otherwise, pattern and val must match recursively.
- if !pattern.IsValid() || !val.IsValid() {
- return !pattern.IsValid() && !val.IsValid()
- }
- if pattern.Type() != val.Type() {
- return false
- }
-
- // Special cases.
- switch pattern.Type() {
- case identType:
- // For identifiers, only the names need to match
- // (and none of the other *ast.Object information).
- // This is a common case, handle it all here instead
- // of recursing down any further via reflection.
- p := pattern.Interface().(*ast.Ident)
- v := val.Interface().(*ast.Ident)
- return p == nil && v == nil || p != nil && v != nil && p.Name == v.Name
- case objectPtrType, positionType:
- // object pointers and token positions always match
- return true
- case callExprType:
- // For calls, the Ellipsis fields (token.Position) must
- // match since that is how f(x) and f(x...) are different.
- // Check them here but fall through for the remaining fields.
- p := pattern.Interface().(*ast.CallExpr)
- v := val.Interface().(*ast.CallExpr)
- if p.Ellipsis.IsValid() != v.Ellipsis.IsValid() {
- return false
- }
- }
-
- p := reflect.Indirect(pattern)
- v := reflect.Indirect(val)
- if !p.IsValid() || !v.IsValid() {
- return !p.IsValid() && !v.IsValid()
- }
-
- switch p.Kind() {
- case reflect.Slice:
- if p.Len() != v.Len() {
- return false
- }
- for i := 0; i < p.Len(); i++ {
- if !match(m, p.Index(i), v.Index(i)) {
- return false
- }
- }
- return true
-
- case reflect.Struct:
- for i := 0; i < p.NumField(); i++ {
- if !match(m, p.Field(i), v.Field(i)) {
- return false
- }
- }
- return true
-
- case reflect.Interface:
- return match(m, p.Elem(), v.Elem())
- }
-
- // Handle token integers, etc.
- return p.Interface() == v.Interface()
-}
-
-// subst returns a copy of pattern with values from m substituted in place
-// of wildcards and pos used as the position of tokens from the pattern.
-// if m == nil, subst returns a copy of pattern and doesn't change the line
-// number information.
-func subst(m map[string]reflect.Value, pattern reflect.Value, pos reflect.Value) reflect.Value {
- if !pattern.IsValid() {
- return reflect.Value{}
- }
-
- // Wildcard gets replaced with map value.
- if m != nil && pattern.Type() == identType {
- name := pattern.Interface().(*ast.Ident).Name
- if isWildcard(name) {
- if old, ok := m[name]; ok {
- return subst(nil, old, reflect.Value{})
- }
- }
- }
-
- if pos.IsValid() && pattern.Type() == positionType {
- // use new position only if old position was valid in the first place
- if old := pattern.Interface().(token.Pos); !old.IsValid() {
- return pattern
- }
- return pos
- }
-
- // Otherwise copy.
- switch p := pattern; p.Kind() {
- case reflect.Slice:
- v := reflect.MakeSlice(p.Type(), p.Len(), p.Len())
- for i := 0; i < p.Len(); i++ {
- v.Index(i).Set(subst(m, p.Index(i), pos))
- }
- return v
-
- case reflect.Struct:
- v := reflect.New(p.Type()).Elem()
- for i := 0; i < p.NumField(); i++ {
- v.Field(i).Set(subst(m, p.Field(i), pos))
- }
- return v
-
- case reflect.Ptr:
- v := reflect.New(p.Type()).Elem()
- if elem := p.Elem(); elem.IsValid() {
- v.Set(subst(m, elem, pos).Addr())
- }
- return v
-
- case reflect.Interface:
- v := reflect.New(p.Type()).Elem()
- if elem := p.Elem(); elem.IsValid() {
- v.Set(subst(m, elem, pos))
- }
- return v
- }
-
- return pattern
-}
diff --git a/vendor/github.com/klauspost/reedsolomon/gentables.go b/vendor/github.com/klauspost/reedsolomon/gentables.go
deleted file mode 100644
index 843aadeb..00000000
--- a/vendor/github.com/klauspost/reedsolomon/gentables.go
+++ /dev/null
@@ -1,132 +0,0 @@
-//+build ignore
-
-package main
-
-import (
- "fmt"
-)
-
-var logTable = [fieldSize]int16{
- -1, 0, 1, 25, 2, 50, 26, 198,
- 3, 223, 51, 238, 27, 104, 199, 75,
- 4, 100, 224, 14, 52, 141, 239, 129,
- 28, 193, 105, 248, 200, 8, 76, 113,
- 5, 138, 101, 47, 225, 36, 15, 33,
- 53, 147, 142, 218, 240, 18, 130, 69,
- 29, 181, 194, 125, 106, 39, 249, 185,
- 201, 154, 9, 120, 77, 228, 114, 166,
- 6, 191, 139, 98, 102, 221, 48, 253,
- 226, 152, 37, 179, 16, 145, 34, 136,
- 54, 208, 148, 206, 143, 150, 219, 189,
- 241, 210, 19, 92, 131, 56, 70, 64,
- 30, 66, 182, 163, 195, 72, 126, 110,
- 107, 58, 40, 84, 250, 133, 186, 61,
- 202, 94, 155, 159, 10, 21, 121, 43,
- 78, 212, 229, 172, 115, 243, 167, 87,
- 7, 112, 192, 247, 140, 128, 99, 13,
- 103, 74, 222, 237, 49, 197, 254, 24,
- 227, 165, 153, 119, 38, 184, 180, 124,
- 17, 68, 146, 217, 35, 32, 137, 46,
- 55, 63, 209, 91, 149, 188, 207, 205,
- 144, 135, 151, 178, 220, 252, 190, 97,
- 242, 86, 211, 171, 20, 42, 93, 158,
- 132, 60, 57, 83, 71, 109, 65, 162,
- 31, 45, 67, 216, 183, 123, 164, 118,
- 196, 23, 73, 236, 127, 12, 111, 246,
- 108, 161, 59, 82, 41, 157, 85, 170,
- 251, 96, 134, 177, 187, 204, 62, 90,
- 203, 89, 95, 176, 156, 169, 160, 81,
- 11, 245, 22, 235, 122, 117, 44, 215,
- 79, 174, 213, 233, 230, 231, 173, 232,
- 116, 214, 244, 234, 168, 80, 88, 175,
-}
-
-const (
- // The number of elements in the field.
- fieldSize = 256
-
- // The polynomial used to generate the logarithm table.
- //
- // There are a number of polynomials that work to generate
- // a Galois field of 256 elements. The choice is arbitrary,
- // and we just use the first one.
- //
- // The possibilities are: 29, 43, 45, 77, 95, 99, 101, 105,
- //* 113, 135, 141, 169, 195, 207, 231, and 245.
- generatingPolynomial = 29
-)
-
-func main() {
- t := generateExpTable()
- fmt.Printf("var expTable = %#v\n", t)
- //t2 := generateMulTableSplit(t)
- //fmt.Printf("var mulTable = %#v\n", t2)
- low, high := generateMulTableHalf(t)
- fmt.Printf("var mulTableLow = %#v\n", low)
- fmt.Printf("var mulTableHigh = %#v\n", high)
-}
-
-/**
- * Generates the inverse log table.
- */
-func generateExpTable() []byte {
- result := make([]byte, fieldSize*2-2)
- for i := 1; i < fieldSize; i++ {
- log := logTable[i]
- result[log] = byte(i)
- result[log+fieldSize-1] = byte(i)
- }
- return result
-}
-
-func generateMulTable(expTable []byte) []byte {
- result := make([]byte, 256*256)
- for v := range result {
- a := byte(v & 0xff)
- b := byte(v >> 8)
- if a == 0 || b == 0 {
- result[v] = 0
- continue
- }
- logA := int(logTable[a])
- logB := int(logTable[b])
- result[v] = expTable[logA+logB]
- }
- return result
-}
-
-func generateMulTableSplit(expTable []byte) [256][256]byte {
- var result [256][256]byte
- for a := range result {
- for b := range result[a] {
- if a == 0 || b == 0 {
- result[a][b] = 0
- continue
- }
- logA := int(logTable[a])
- logB := int(logTable[b])
- result[a][b] = expTable[logA+logB]
- }
- }
- return result
-}
-
-func generateMulTableHalf(expTable []byte) (low [256][16]byte, high [256][16]byte) {
- for a := range low {
- for b := range low {
- result := 0
- if !(a == 0 || b == 0) {
- logA := int(logTable[a])
- logB := int(logTable[b])
- result = int(expTable[logA+logB])
- }
- if (b & 0xf) == b {
- low[a][b] = byte(result)
- }
- if (b & 0xf0) == b {
- high[a][b>>4] = byte(result)
- }
- }
- }
- return
-}
diff --git a/vendor/github.com/stretchr/testify/LICENSE b/vendor/github.com/stretchr/testify/LICENSE
index 473b670a..f38ec595 100644
--- a/vendor/github.com/stretchr/testify/LICENSE
+++ b/vendor/github.com/stretchr/testify/LICENSE
@@ -1,22 +1,21 @@
-Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell
+MIT License
-Please consider promoting this project if you find it useful.
+Copyright (c) 2012-2018 Mat Ryer and Tyler Bunnell
-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:
+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 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.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/stretchr/testify/assert/assertion_format.go b/vendor/github.com/stretchr/testify/assert/assertion_format.go
index ae06a54e..aa1c2b95 100644
--- a/vendor/github.com/stretchr/testify/assert/assertion_format.go
+++ b/vendor/github.com/stretchr/testify/assert/assertion_format.go
@@ -13,6 +13,9 @@ import (
// Conditionf uses a Comparison to assert a complex condition.
func Conditionf(t TestingT, comp Comparison, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return Condition(t, comp, append([]interface{}{msg}, args...)...)
}
@@ -23,11 +26,17 @@ func Conditionf(t TestingT, comp Comparison, msg string, args ...interface{}) bo
// assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted")
// assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted")
func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return Contains(t, s, contains, append([]interface{}{msg}, args...)...)
}
// DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
func DirExistsf(t TestingT, path string, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return DirExists(t, path, append([]interface{}{msg}, args...)...)
}
@@ -37,6 +46,9 @@ func DirExistsf(t TestingT, path string, msg string, args ...interface{}) bool {
//
// assert.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted")
func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return ElementsMatch(t, listA, listB, append([]interface{}{msg}, args...)...)
}
@@ -45,6 +57,9 @@ func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string
//
// assert.Emptyf(t, obj, "error message %s", "formatted")
func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return Empty(t, object, append([]interface{}{msg}, args...)...)
}
@@ -56,6 +71,9 @@ func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) boo
// referenced values (as opposed to the memory addresses). Function equality
// cannot be determined and will always fail.
func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return Equal(t, expected, actual, append([]interface{}{msg}, args...)...)
}
@@ -65,6 +83,9 @@ func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, ar
// actualObj, err := SomeFunction()
// assert.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted")
func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return EqualError(t, theError, errString, append([]interface{}{msg}, args...)...)
}
@@ -73,6 +94,9 @@ func EqualErrorf(t TestingT, theError error, errString string, msg string, args
//
// assert.EqualValuesf(t, uint32(123, "error message %s", "formatted"), int32(123))
func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return EqualValues(t, expected, actual, append([]interface{}{msg}, args...)...)
}
@@ -83,6 +107,9 @@ func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg stri
// assert.Equal(t, expectedErrorf, err)
// }
func Errorf(t TestingT, err error, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return Error(t, err, append([]interface{}{msg}, args...)...)
}
@@ -90,16 +117,25 @@ func Errorf(t TestingT, err error, msg string, args ...interface{}) bool {
//
// assert.Exactlyf(t, int32(123, "error message %s", "formatted"), int64(123))
func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return Exactly(t, expected, actual, append([]interface{}{msg}, args...)...)
}
// Failf reports a failure through
func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return Fail(t, failureMessage, append([]interface{}{msg}, args...)...)
}
// FailNowf fails test
func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return FailNow(t, failureMessage, append([]interface{}{msg}, args...)...)
}
@@ -107,31 +143,43 @@ func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}
//
// assert.Falsef(t, myBool, "error message %s", "formatted")
func Falsef(t TestingT, value bool, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return False(t, value, append([]interface{}{msg}, args...)...)
}
// FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
func FileExistsf(t TestingT, path string, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return FileExists(t, path, append([]interface{}{msg}, args...)...)
}
// HTTPBodyContainsf asserts that a specified handler returns a
// body that contains a string.
//
-// assert.HTTPBodyContainsf(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
+// assert.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
//
// Returns whether the assertion was successful (true) or not (false).
func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return HTTPBodyContains(t, handler, method, url, values, str, append([]interface{}{msg}, args...)...)
}
// HTTPBodyNotContainsf asserts that a specified handler returns a
// body that does not contain a string.
//
-// assert.HTTPBodyNotContainsf(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
+// assert.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
//
// Returns whether the assertion was successful (true) or not (false).
func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return HTTPBodyNotContains(t, handler, method, url, values, str, append([]interface{}{msg}, args...)...)
}
@@ -141,6 +189,9 @@ func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, u
//
// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return HTTPError(t, handler, method, url, values, append([]interface{}{msg}, args...)...)
}
@@ -150,6 +201,9 @@ func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string,
//
// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return HTTPRedirect(t, handler, method, url, values, append([]interface{}{msg}, args...)...)
}
@@ -159,6 +213,9 @@ func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url stri
//
// Returns whether the assertion was successful (true) or not (false).
func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return HTTPSuccess(t, handler, method, url, values, append([]interface{}{msg}, args...)...)
}
@@ -166,6 +223,9 @@ func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url strin
//
// assert.Implementsf(t, (*MyInterface, "error message %s", "formatted")(nil), new(MyObject))
func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return Implements(t, interfaceObject, object, append([]interface{}{msg}, args...)...)
}
@@ -173,31 +233,49 @@ func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, ms
//
// assert.InDeltaf(t, math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01)
func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return InDelta(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
}
// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
func InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return InDeltaMapValues(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
}
// InDeltaSlicef is the same as InDelta, except it compares two slices.
func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return InDeltaSlice(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
}
// InEpsilonf asserts that expected and actual have a relative error less than epsilon
func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return InEpsilon(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...)
}
// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices.
func InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return InEpsilonSlice(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...)
}
// IsTypef asserts that the specified objects are of the same type.
func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return IsType(t, expectedType, object, append([]interface{}{msg}, args...)...)
}
@@ -205,6 +283,9 @@ func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg strin
//
// assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted")
func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return JSONEq(t, expected, actual, append([]interface{}{msg}, args...)...)
}
@@ -213,6 +294,9 @@ func JSONEqf(t TestingT, expected string, actual string, msg string, args ...int
//
// assert.Lenf(t, mySlice, 3, "error message %s", "formatted")
func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return Len(t, object, length, append([]interface{}{msg}, args...)...)
}
@@ -220,6 +304,9 @@ func Lenf(t TestingT, object interface{}, length int, msg string, args ...interf
//
// assert.Nilf(t, err, "error message %s", "formatted")
func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return Nil(t, object, append([]interface{}{msg}, args...)...)
}
@@ -230,6 +317,9 @@ func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) bool
// assert.Equal(t, expectedObj, actualObj)
// }
func NoErrorf(t TestingT, err error, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return NoError(t, err, append([]interface{}{msg}, args...)...)
}
@@ -240,6 +330,9 @@ func NoErrorf(t TestingT, err error, msg string, args ...interface{}) bool {
// assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted")
// assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted")
func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return NotContains(t, s, contains, append([]interface{}{msg}, args...)...)
}
@@ -250,6 +343,9 @@ func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, a
// assert.Equal(t, "two", obj[1])
// }
func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return NotEmpty(t, object, append([]interface{}{msg}, args...)...)
}
@@ -260,6 +356,9 @@ func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{})
// Pointer variable equality is determined based on the equality of the
// referenced values (as opposed to the memory addresses).
func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return NotEqual(t, expected, actual, append([]interface{}{msg}, args...)...)
}
@@ -267,6 +366,9 @@ func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string,
//
// assert.NotNilf(t, err, "error message %s", "formatted")
func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return NotNil(t, object, append([]interface{}{msg}, args...)...)
}
@@ -274,6 +376,9 @@ func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) bo
//
// assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted")
func NotPanicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return NotPanics(t, f, append([]interface{}{msg}, args...)...)
}
@@ -282,6 +387,9 @@ func NotPanicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bo
// assert.NotRegexpf(t, regexp.MustCompile("starts", "error message %s", "formatted"), "it's starting")
// assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted")
func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return NotRegexp(t, rx, str, append([]interface{}{msg}, args...)...)
}
@@ -290,11 +398,17 @@ func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ..
//
// assert.NotSubsetf(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted")
func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return NotSubset(t, list, subset, append([]interface{}{msg}, args...)...)
}
// NotZerof asserts that i is not the zero value for its type.
func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return NotZero(t, i, append([]interface{}{msg}, args...)...)
}
@@ -302,6 +416,9 @@ func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) bool {
//
// assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted")
func Panicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return Panics(t, f, append([]interface{}{msg}, args...)...)
}
@@ -310,6 +427,9 @@ func Panicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool
//
// assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted")
func PanicsWithValuef(t TestingT, expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return PanicsWithValue(t, expected, f, append([]interface{}{msg}, args...)...)
}
@@ -318,6 +438,9 @@ func PanicsWithValuef(t TestingT, expected interface{}, f PanicTestFunc, msg str
// assert.Regexpf(t, regexp.MustCompile("start", "error message %s", "formatted"), "it's starting")
// assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted")
func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return Regexp(t, rx, str, append([]interface{}{msg}, args...)...)
}
@@ -326,6 +449,9 @@ func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...in
//
// assert.Subsetf(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted")
func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return Subset(t, list, subset, append([]interface{}{msg}, args...)...)
}
@@ -333,6 +459,9 @@ func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args
//
// assert.Truef(t, myBool, "error message %s", "formatted")
func Truef(t TestingT, value bool, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return True(t, value, append([]interface{}{msg}, args...)...)
}
@@ -340,10 +469,16 @@ func Truef(t TestingT, value bool, msg string, args ...interface{}) bool {
//
// assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted")
func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return WithinDuration(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
}
// Zerof asserts that i is the zero value for its type.
func Zerof(t TestingT, i interface{}, msg string, args ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
return Zero(t, i, append([]interface{}{msg}, args...)...)
}
diff --git a/vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl b/vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl
index c5cc66f4..d2bb0b81 100644
--- a/vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl
+++ b/vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl
@@ -1,4 +1,5 @@
{{.CommentFormat}}
func {{.DocInfo.Name}}f(t TestingT, {{.ParamsFormat}}) bool {
+ if h, ok := t.(tHelper); ok { h.Helper() }
return {{.DocInfo.Name}}(t, {{.ForwardedParamsFormat}})
}
diff --git a/vendor/github.com/stretchr/testify/assert/assertion_forward.go b/vendor/github.com/stretchr/testify/assert/assertion_forward.go
index ffa5428f..de39f794 100644
--- a/vendor/github.com/stretchr/testify/assert/assertion_forward.go
+++ b/vendor/github.com/stretchr/testify/assert/assertion_forward.go
@@ -13,11 +13,17 @@ import (
// Condition uses a Comparison to assert a complex condition.
func (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Condition(a.t, comp, msgAndArgs...)
}
// Conditionf uses a Comparison to assert a complex condition.
func (a *Assertions) Conditionf(comp Comparison, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Conditionf(a.t, comp, msg, args...)
}
@@ -28,6 +34,9 @@ func (a *Assertions) Conditionf(comp Comparison, msg string, args ...interface{}
// a.Contains(["Hello", "World"], "World")
// a.Contains({"Hello": "World"}, "Hello")
func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Contains(a.t, s, contains, msgAndArgs...)
}
@@ -38,16 +47,25 @@ func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ..
// a.Containsf(["Hello", "World"], "World", "error message %s", "formatted")
// a.Containsf({"Hello": "World"}, "Hello", "error message %s", "formatted")
func (a *Assertions) Containsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Containsf(a.t, s, contains, msg, args...)
}
// DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
func (a *Assertions) DirExists(path string, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return DirExists(a.t, path, msgAndArgs...)
}
// DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
func (a *Assertions) DirExistsf(path string, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return DirExistsf(a.t, path, msg, args...)
}
@@ -57,6 +75,9 @@ func (a *Assertions) DirExistsf(path string, msg string, args ...interface{}) bo
//
// a.ElementsMatch([1, 3, 2, 3], [1, 3, 3, 2])
func (a *Assertions) ElementsMatch(listA interface{}, listB interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return ElementsMatch(a.t, listA, listB, msgAndArgs...)
}
@@ -66,6 +87,9 @@ func (a *Assertions) ElementsMatch(listA interface{}, listB interface{}, msgAndA
//
// a.ElementsMatchf([1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted")
func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return ElementsMatchf(a.t, listA, listB, msg, args...)
}
@@ -74,6 +98,9 @@ func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg st
//
// a.Empty(obj)
func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Empty(a.t, object, msgAndArgs...)
}
@@ -82,6 +109,9 @@ func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool {
//
// a.Emptyf(obj, "error message %s", "formatted")
func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Emptyf(a.t, object, msg, args...)
}
@@ -93,6 +123,9 @@ func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{})
// referenced values (as opposed to the memory addresses). Function equality
// cannot be determined and will always fail.
func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Equal(a.t, expected, actual, msgAndArgs...)
}
@@ -102,6 +135,9 @@ func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs
// actualObj, err := SomeFunction()
// a.EqualError(err, expectedErrorString)
func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return EqualError(a.t, theError, errString, msgAndArgs...)
}
@@ -111,6 +147,9 @@ func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...
// actualObj, err := SomeFunction()
// a.EqualErrorf(err, expectedErrorString, "error message %s", "formatted")
func (a *Assertions) EqualErrorf(theError error, errString string, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return EqualErrorf(a.t, theError, errString, msg, args...)
}
@@ -119,6 +158,9 @@ func (a *Assertions) EqualErrorf(theError error, errString string, msg string, a
//
// a.EqualValues(uint32(123), int32(123))
func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return EqualValues(a.t, expected, actual, msgAndArgs...)
}
@@ -127,6 +169,9 @@ func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAn
//
// a.EqualValuesf(uint32(123, "error message %s", "formatted"), int32(123))
func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return EqualValuesf(a.t, expected, actual, msg, args...)
}
@@ -138,6 +183,9 @@ func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg
// referenced values (as opposed to the memory addresses). Function equality
// cannot be determined and will always fail.
func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Equalf(a.t, expected, actual, msg, args...)
}
@@ -148,6 +196,9 @@ func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string
// assert.Equal(t, expectedError, err)
// }
func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Error(a.t, err, msgAndArgs...)
}
@@ -158,6 +209,9 @@ func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool {
// assert.Equal(t, expectedErrorf, err)
// }
func (a *Assertions) Errorf(err error, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Errorf(a.t, err, msg, args...)
}
@@ -165,6 +219,9 @@ func (a *Assertions) Errorf(err error, msg string, args ...interface{}) bool {
//
// a.Exactly(int32(123), int64(123))
func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Exactly(a.t, expected, actual, msgAndArgs...)
}
@@ -172,26 +229,41 @@ func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArg
//
// a.Exactlyf(int32(123, "error message %s", "formatted"), int64(123))
func (a *Assertions) Exactlyf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Exactlyf(a.t, expected, actual, msg, args...)
}
// Fail reports a failure through
func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Fail(a.t, failureMessage, msgAndArgs...)
}
// FailNow fails test
func (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return FailNow(a.t, failureMessage, msgAndArgs...)
}
// FailNowf fails test
func (a *Assertions) FailNowf(failureMessage string, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return FailNowf(a.t, failureMessage, msg, args...)
}
// Failf reports a failure through
func (a *Assertions) Failf(failureMessage string, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Failf(a.t, failureMessage, msg, args...)
}
@@ -199,6 +271,9 @@ func (a *Assertions) Failf(failureMessage string, msg string, args ...interface{
//
// a.False(myBool)
func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return False(a.t, value, msgAndArgs...)
}
@@ -206,56 +281,77 @@ func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool {
//
// a.Falsef(myBool, "error message %s", "formatted")
func (a *Assertions) Falsef(value bool, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Falsef(a.t, value, msg, args...)
}
// FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
func (a *Assertions) FileExists(path string, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return FileExists(a.t, path, msgAndArgs...)
}
// FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
func (a *Assertions) FileExistsf(path string, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return FileExistsf(a.t, path, msg, args...)
}
// HTTPBodyContains asserts that a specified handler returns a
// body that contains a string.
//
-// a.HTTPBodyContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky")
+// a.HTTPBodyContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return HTTPBodyContains(a.t, handler, method, url, values, str, msgAndArgs...)
}
// HTTPBodyContainsf asserts that a specified handler returns a
// body that contains a string.
//
-// a.HTTPBodyContainsf(myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
+// a.HTTPBodyContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return HTTPBodyContainsf(a.t, handler, method, url, values, str, msg, args...)
}
// HTTPBodyNotContains asserts that a specified handler returns a
// body that does not contain a string.
//
-// a.HTTPBodyNotContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky")
+// a.HTTPBodyNotContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return HTTPBodyNotContains(a.t, handler, method, url, values, str, msgAndArgs...)
}
// HTTPBodyNotContainsf asserts that a specified handler returns a
// body that does not contain a string.
//
-// a.HTTPBodyNotContainsf(myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
+// a.HTTPBodyNotContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return HTTPBodyNotContainsf(a.t, handler, method, url, values, str, msg, args...)
}
@@ -265,6 +361,9 @@ func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method strin
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return HTTPError(a.t, handler, method, url, values, msgAndArgs...)
}
@@ -274,6 +373,9 @@ func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url stri
//
// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return HTTPErrorf(a.t, handler, method, url, values, msg, args...)
}
@@ -283,6 +385,9 @@ func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url str
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return HTTPRedirect(a.t, handler, method, url, values, msgAndArgs...)
}
@@ -292,6 +397,9 @@ func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url s
//
// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return HTTPRedirectf(a.t, handler, method, url, values, msg, args...)
}
@@ -301,6 +409,9 @@ func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return HTTPSuccess(a.t, handler, method, url, values, msgAndArgs...)
}
@@ -310,6 +421,9 @@ func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url st
//
// Returns whether the assertion was successful (true) or not (false).
func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return HTTPSuccessf(a.t, handler, method, url, values, msg, args...)
}
@@ -317,6 +431,9 @@ func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url s
//
// a.Implements((*MyInterface)(nil), new(MyObject))
func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Implements(a.t, interfaceObject, object, msgAndArgs...)
}
@@ -324,6 +441,9 @@ func (a *Assertions) Implements(interfaceObject interface{}, object interface{},
//
// a.Implementsf((*MyInterface, "error message %s", "formatted")(nil), new(MyObject))
func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Implementsf(a.t, interfaceObject, object, msg, args...)
}
@@ -331,26 +451,41 @@ func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}
//
// a.InDelta(math.Pi, (22 / 7.0), 0.01)
func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return InDelta(a.t, expected, actual, delta, msgAndArgs...)
}
// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
func (a *Assertions) InDeltaMapValues(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return InDeltaMapValues(a.t, expected, actual, delta, msgAndArgs...)
}
// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
func (a *Assertions) InDeltaMapValuesf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return InDeltaMapValuesf(a.t, expected, actual, delta, msg, args...)
}
// InDeltaSlice is the same as InDelta, except it compares two slices.
func (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...)
}
// InDeltaSlicef is the same as InDelta, except it compares two slices.
func (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return InDeltaSlicef(a.t, expected, actual, delta, msg, args...)
}
@@ -358,36 +493,57 @@ func (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, del
//
// a.InDeltaf(math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01)
func (a *Assertions) InDeltaf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return InDeltaf(a.t, expected, actual, delta, msg, args...)
}
// InEpsilon asserts that expected and actual have a relative error less than epsilon
func (a *Assertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...)
}
// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.
func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return InEpsilonSlice(a.t, expected, actual, epsilon, msgAndArgs...)
}
// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices.
func (a *Assertions) InEpsilonSlicef(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return InEpsilonSlicef(a.t, expected, actual, epsilon, msg, args...)
}
// InEpsilonf asserts that expected and actual have a relative error less than epsilon
func (a *Assertions) InEpsilonf(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return InEpsilonf(a.t, expected, actual, epsilon, msg, args...)
}
// IsType asserts that the specified objects are of the same type.
func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return IsType(a.t, expectedType, object, msgAndArgs...)
}
// IsTypef asserts that the specified objects are of the same type.
func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return IsTypef(a.t, expectedType, object, msg, args...)
}
@@ -395,6 +551,9 @@ func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg s
//
// a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return JSONEq(a.t, expected, actual, msgAndArgs...)
}
@@ -402,6 +561,9 @@ func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interf
//
// a.JSONEqf(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted")
func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return JSONEqf(a.t, expected, actual, msg, args...)
}
@@ -410,6 +572,9 @@ func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ..
//
// a.Len(mySlice, 3)
func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Len(a.t, object, length, msgAndArgs...)
}
@@ -418,6 +583,9 @@ func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface
//
// a.Lenf(mySlice, 3, "error message %s", "formatted")
func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Lenf(a.t, object, length, msg, args...)
}
@@ -425,6 +593,9 @@ func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...in
//
// a.Nil(err)
func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Nil(a.t, object, msgAndArgs...)
}
@@ -432,6 +603,9 @@ func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool {
//
// a.Nilf(err, "error message %s", "formatted")
func (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Nilf(a.t, object, msg, args...)
}
@@ -442,6 +616,9 @@ func (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) b
// assert.Equal(t, expectedObj, actualObj)
// }
func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return NoError(a.t, err, msgAndArgs...)
}
@@ -452,6 +629,9 @@ func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool {
// assert.Equal(t, expectedObj, actualObj)
// }
func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return NoErrorf(a.t, err, msg, args...)
}
@@ -462,6 +642,9 @@ func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) bool {
// a.NotContains(["Hello", "World"], "Earth")
// a.NotContains({"Hello": "World"}, "Earth")
func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return NotContains(a.t, s, contains, msgAndArgs...)
}
@@ -472,6 +655,9 @@ func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs
// a.NotContainsf(["Hello", "World"], "Earth", "error message %s", "formatted")
// a.NotContainsf({"Hello": "World"}, "Earth", "error message %s", "formatted")
func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return NotContainsf(a.t, s, contains, msg, args...)
}
@@ -482,6 +668,9 @@ func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg strin
// assert.Equal(t, "two", obj[1])
// }
func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return NotEmpty(a.t, object, msgAndArgs...)
}
@@ -492,6 +681,9 @@ func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) boo
// assert.Equal(t, "two", obj[1])
// }
func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return NotEmptyf(a.t, object, msg, args...)
}
@@ -502,6 +694,9 @@ func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface
// Pointer variable equality is determined based on the equality of the
// referenced values (as opposed to the memory addresses).
func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return NotEqual(a.t, expected, actual, msgAndArgs...)
}
@@ -512,6 +707,9 @@ func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndAr
// Pointer variable equality is determined based on the equality of the
// referenced values (as opposed to the memory addresses).
func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return NotEqualf(a.t, expected, actual, msg, args...)
}
@@ -519,6 +717,9 @@ func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg str
//
// a.NotNil(err)
func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return NotNil(a.t, object, msgAndArgs...)
}
@@ -526,6 +727,9 @@ func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool
//
// a.NotNilf(err, "error message %s", "formatted")
func (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return NotNilf(a.t, object, msg, args...)
}
@@ -533,6 +737,9 @@ func (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{}
//
// a.NotPanics(func(){ RemainCalm() })
func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return NotPanics(a.t, f, msgAndArgs...)
}
@@ -540,6 +747,9 @@ func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool
//
// a.NotPanicsf(func(){ RemainCalm() }, "error message %s", "formatted")
func (a *Assertions) NotPanicsf(f PanicTestFunc, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return NotPanicsf(a.t, f, msg, args...)
}
@@ -548,6 +758,9 @@ func (a *Assertions) NotPanicsf(f PanicTestFunc, msg string, args ...interface{}
// a.NotRegexp(regexp.MustCompile("starts"), "it's starting")
// a.NotRegexp("^start", "it's not starting")
func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return NotRegexp(a.t, rx, str, msgAndArgs...)
}
@@ -556,6 +769,9 @@ func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...in
// a.NotRegexpf(regexp.MustCompile("starts", "error message %s", "formatted"), "it's starting")
// a.NotRegexpf("^start", "it's not starting", "error message %s", "formatted")
func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return NotRegexpf(a.t, rx, str, msg, args...)
}
@@ -564,6 +780,9 @@ func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, arg
//
// a.NotSubset([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")
func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return NotSubset(a.t, list, subset, msgAndArgs...)
}
@@ -572,16 +791,25 @@ func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs
//
// a.NotSubsetf([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted")
func (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return NotSubsetf(a.t, list, subset, msg, args...)
}
// NotZero asserts that i is not the zero value for its type.
func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return NotZero(a.t, i, msgAndArgs...)
}
// NotZerof asserts that i is not the zero value for its type.
func (a *Assertions) NotZerof(i interface{}, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return NotZerof(a.t, i, msg, args...)
}
@@ -589,6 +817,9 @@ func (a *Assertions) NotZerof(i interface{}, msg string, args ...interface{}) bo
//
// a.Panics(func(){ GoCrazy() })
func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Panics(a.t, f, msgAndArgs...)
}
@@ -597,6 +828,9 @@ func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool {
//
// a.PanicsWithValue("crazy error", func(){ GoCrazy() })
func (a *Assertions) PanicsWithValue(expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return PanicsWithValue(a.t, expected, f, msgAndArgs...)
}
@@ -605,6 +839,9 @@ func (a *Assertions) PanicsWithValue(expected interface{}, f PanicTestFunc, msgA
//
// a.PanicsWithValuef("crazy error", func(){ GoCrazy() }, "error message %s", "formatted")
func (a *Assertions) PanicsWithValuef(expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return PanicsWithValuef(a.t, expected, f, msg, args...)
}
@@ -612,6 +849,9 @@ func (a *Assertions) PanicsWithValuef(expected interface{}, f PanicTestFunc, msg
//
// a.Panicsf(func(){ GoCrazy() }, "error message %s", "formatted")
func (a *Assertions) Panicsf(f PanicTestFunc, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Panicsf(a.t, f, msg, args...)
}
@@ -620,6 +860,9 @@ func (a *Assertions) Panicsf(f PanicTestFunc, msg string, args ...interface{}) b
// a.Regexp(regexp.MustCompile("start"), "it's starting")
// a.Regexp("start...$", "it's not starting")
func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Regexp(a.t, rx, str, msgAndArgs...)
}
@@ -628,6 +871,9 @@ func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...inter
// a.Regexpf(regexp.MustCompile("start", "error message %s", "formatted"), "it's starting")
// a.Regexpf("start...$", "it's not starting", "error message %s", "formatted")
func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Regexpf(a.t, rx, str, msg, args...)
}
@@ -636,6 +882,9 @@ func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args .
//
// a.Subset([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")
func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Subset(a.t, list, subset, msgAndArgs...)
}
@@ -644,6 +893,9 @@ func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...
//
// a.Subsetf([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted")
func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Subsetf(a.t, list, subset, msg, args...)
}
@@ -651,6 +903,9 @@ func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, a
//
// a.True(myBool)
func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return True(a.t, value, msgAndArgs...)
}
@@ -658,6 +913,9 @@ func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool {
//
// a.Truef(myBool, "error message %s", "formatted")
func (a *Assertions) Truef(value bool, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Truef(a.t, value, msg, args...)
}
@@ -665,6 +923,9 @@ func (a *Assertions) Truef(value bool, msg string, args ...interface{}) bool {
//
// a.WithinDuration(time.Now(), time.Now(), 10*time.Second)
func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return WithinDuration(a.t, expected, actual, delta, msgAndArgs...)
}
@@ -672,15 +933,24 @@ func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta
//
// a.WithinDurationf(time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted")
func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return WithinDurationf(a.t, expected, actual, delta, msg, args...)
}
// Zero asserts that i is the zero value for its type.
func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Zero(a.t, i, msgAndArgs...)
}
// Zerof asserts that i is the zero value for its type.
func (a *Assertions) Zerof(i interface{}, msg string, args ...interface{}) bool {
+ if h, ok := a.t.(tHelper); ok {
+ h.Helper()
+ }
return Zerof(a.t, i, msg, args...)
}
diff --git a/vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl b/vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl
index 99f9acfb..188bb9e1 100644
--- a/vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl
+++ b/vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl
@@ -1,4 +1,5 @@
{{.CommentWithoutT "a"}}
func (a *Assertions) {{.DocInfo.Name}}({{.Params}}) bool {
+ if h, ok := a.t.(tHelper); ok { h.Helper() }
return {{.DocInfo.Name}}(a.t, {{.ForwardedParams}})
}
diff --git a/vendor/github.com/stretchr/testify/assert/assertions.go b/vendor/github.com/stretchr/testify/assert/assertions.go
index 47bda778..9bd4a80e 100644
--- a/vendor/github.com/stretchr/testify/assert/assertions.go
+++ b/vendor/github.com/stretchr/testify/assert/assertions.go
@@ -27,6 +27,22 @@ type TestingT interface {
Errorf(format string, args ...interface{})
}
+// ComparisonAssertionFunc is a common function prototype when comparing two values. Can be useful
+// for table driven tests.
+type ComparisonAssertionFunc func(TestingT, interface{}, interface{}, ...interface{}) bool
+
+// ValueAssertionFunc is a common function prototype when validating a single value. Can be useful
+// for table driven tests.
+type ValueAssertionFunc func(TestingT, interface{}, ...interface{}) bool
+
+// BoolAssertionFunc is a common function prototype when validating a bool value. Can be useful
+// for table driven tests.
+type BoolAssertionFunc func(TestingT, bool, ...interface{}) bool
+
+// ErrorAssertionFunc is a common function prototype when validating an error value. Can be useful
+// for table driven tests.
+type ErrorAssertionFunc func(TestingT, error, ...interface{}) bool
+
// Comparison a custom function that returns true on success and false on failure
type Comparison func() (success bool)
@@ -38,21 +54,23 @@ type Comparison func() (success bool)
//
// This function does no assertion of any kind.
func ObjectsAreEqual(expected, actual interface{}) bool {
-
if expected == nil || actual == nil {
return expected == actual
}
- if exp, ok := expected.([]byte); ok {
- act, ok := actual.([]byte)
- if !ok {
- return false
- } else if exp == nil || act == nil {
- return exp == nil && act == nil
- }
- return bytes.Equal(exp, act)
- }
- return reflect.DeepEqual(expected, actual)
+ exp, ok := expected.([]byte)
+ if !ok {
+ return reflect.DeepEqual(expected, actual)
+ }
+
+ act, ok := actual.([]byte)
+ if !ok {
+ return false
+ }
+ if exp == nil || act == nil {
+ return exp == nil && act == nil
+ }
+ return bytes.Equal(exp, act)
}
// ObjectsAreEqualValues gets whether two objects are equal, or if their
@@ -156,27 +174,16 @@ func isTest(name, prefix string) bool {
return !unicode.IsLower(rune)
}
-// getWhitespaceString returns a string that is long enough to overwrite the default
-// output from the go testing framework.
-func getWhitespaceString() string {
-
- _, file, line, ok := runtime.Caller(1)
- if !ok {
- return ""
- }
- parts := strings.Split(file, "/")
- file = parts[len(parts)-1]
-
- return strings.Repeat(" ", len(fmt.Sprintf("%s:%d: ", file, line)))
-
-}
-
func messageFromMsgAndArgs(msgAndArgs ...interface{}) string {
if len(msgAndArgs) == 0 || msgAndArgs == nil {
return ""
}
if len(msgAndArgs) == 1 {
- return msgAndArgs[0].(string)
+ msg := msgAndArgs[0]
+ if msgAsStr, ok := msg.(string); ok {
+ return msgAsStr
+ }
+ return fmt.Sprintf("%+v", msg)
}
if len(msgAndArgs) > 1 {
return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...)
@@ -195,7 +202,7 @@ func indentMessageLines(message string, longestLabelLen int) string {
// no need to align first line because it starts at the correct location (after the label)
if i != 0 {
// append alignLen+1 spaces to align with "{{longestLabel}}:" before adding tab
- outBuf.WriteString("\n\r\t" + strings.Repeat(" ", longestLabelLen+1) + "\t")
+ outBuf.WriteString("\n\t" + strings.Repeat(" ", longestLabelLen+1) + "\t")
}
outBuf.WriteString(scanner.Text())
}
@@ -209,6 +216,9 @@ type failNower interface {
// FailNow fails test
func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
Fail(t, failureMessage, msgAndArgs...)
// We cannot extend TestingT with FailNow() and
@@ -227,8 +237,11 @@ func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool
// Fail reports a failure through
func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
content := []labeledContent{
- {"Error Trace", strings.Join(CallerInfo(), "\n\r\t\t\t")},
+ {"Error Trace", strings.Join(CallerInfo(), "\n\t\t\t")},
{"Error", failureMessage},
}
@@ -244,7 +257,7 @@ func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
content = append(content, labeledContent{"Messages", message})
}
- t.Errorf("%s", "\r"+getWhitespaceString()+labeledOutput(content...))
+ t.Errorf("\n%s", ""+labeledOutput(content...))
return false
}
@@ -256,7 +269,7 @@ type labeledContent struct {
// labeledOutput returns a string consisting of the provided labeledContent. Each labeled output is appended in the following manner:
//
-// \r\t{{label}}:{{align_spaces}}\t{{content}}\n
+// \t{{label}}:{{align_spaces}}\t{{content}}\n
//
// The initial carriage return is required to undo/erase any padding added by testing.T.Errorf. The "\t{{label}}:" is for the label.
// If a label is shorter than the longest label provided, padding spaces are added to make all the labels match in length. Once this
@@ -272,7 +285,7 @@ func labeledOutput(content ...labeledContent) string {
}
var output string
for _, v := range content {
- output += "\r\t" + v.label + ":" + strings.Repeat(" ", longestLabel-len(v.label)) + "\t" + indentMessageLines(v.content, longestLabel) + "\n"
+ output += "\t" + v.label + ":" + strings.Repeat(" ", longestLabel-len(v.label)) + "\t" + indentMessageLines(v.content, longestLabel) + "\n"
}
return output
}
@@ -281,6 +294,9 @@ func labeledOutput(content ...labeledContent) string {
//
// assert.Implements(t, (*MyInterface)(nil), new(MyObject))
func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
interfaceType := reflect.TypeOf(interfaceObject).Elem()
if object == nil {
@@ -295,6 +311,9 @@ func Implements(t TestingT, interfaceObject interface{}, object interface{}, msg
// IsType asserts that the specified objects are of the same type.
func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
if !ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType)) {
return Fail(t, fmt.Sprintf("Object expected to be of type %v, but was %v", reflect.TypeOf(expectedType), reflect.TypeOf(object)), msgAndArgs...)
@@ -311,6 +330,9 @@ func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs
// referenced values (as opposed to the memory addresses). Function equality
// cannot be determined and will always fail.
func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
if err := validateEqualArgs(expected, actual); err != nil {
return Fail(t, fmt.Sprintf("Invalid operation: %#v == %#v (%s)",
expected, actual, err), msgAndArgs...)
@@ -349,6 +371,9 @@ func formatUnequalValues(expected, actual interface{}) (e string, a string) {
//
// assert.EqualValues(t, uint32(123), int32(123))
func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
if !ObjectsAreEqualValues(expected, actual) {
diff := diff(expected, actual)
@@ -366,12 +391,15 @@ func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interfa
//
// assert.Exactly(t, int32(123), int64(123))
func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
aType := reflect.TypeOf(expected)
bType := reflect.TypeOf(actual)
if aType != bType {
- return Fail(t, fmt.Sprintf("Types expected to match exactly\n\r\t%v != %v", aType, bType), msgAndArgs...)
+ return Fail(t, fmt.Sprintf("Types expected to match exactly\n\t%v != %v", aType, bType), msgAndArgs...)
}
return Equal(t, expected, actual, msgAndArgs...)
@@ -382,12 +410,26 @@ func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}
//
// assert.NotNil(t, err)
func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
if !isNil(object) {
return true
}
return Fail(t, "Expected value not to be nil.", msgAndArgs...)
}
+// containsKind checks if a specified kind in the slice of kinds.
+func containsKind(kinds []reflect.Kind, kind reflect.Kind) bool {
+ for i := 0; i < len(kinds); i++ {
+ if kind == kinds[i] {
+ return true
+ }
+ }
+
+ return false
+}
+
// isNil checks if a specified object is nil or not, without Failing.
func isNil(object interface{}) bool {
if object == nil {
@@ -396,7 +438,14 @@ func isNil(object interface{}) bool {
value := reflect.ValueOf(object)
kind := value.Kind()
- if kind >= reflect.Chan && kind <= reflect.Slice && value.IsNil() {
+ isNilableKind := containsKind(
+ []reflect.Kind{
+ reflect.Chan, reflect.Func,
+ reflect.Interface, reflect.Map,
+ reflect.Ptr, reflect.Slice},
+ kind)
+
+ if isNilableKind && value.IsNil() {
return true
}
@@ -407,6 +456,9 @@ func isNil(object interface{}) bool {
//
// assert.Nil(t, err)
func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
if isNil(object) {
return true
}
@@ -446,6 +498,9 @@ func isEmpty(object interface{}) bool {
//
// assert.Empty(t, obj)
func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
pass := isEmpty(object)
if !pass {
@@ -463,6 +518,9 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
// assert.Equal(t, "two", obj[1])
// }
func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
pass := !isEmpty(object)
if !pass {
@@ -490,6 +548,9 @@ func getLen(x interface{}) (ok bool, length int) {
//
// assert.Len(t, mySlice, 3)
func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
ok, l := getLen(object)
if !ok {
return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", object), msgAndArgs...)
@@ -505,6 +566,14 @@ func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{})
//
// assert.True(t, myBool)
func True(t TestingT, value bool, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
+ if h, ok := t.(interface {
+ Helper()
+ }); ok {
+ h.Helper()
+ }
if value != true {
return Fail(t, "Should be true", msgAndArgs...)
@@ -518,6 +587,9 @@ func True(t TestingT, value bool, msgAndArgs ...interface{}) bool {
//
// assert.False(t, myBool)
func False(t TestingT, value bool, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
if value != false {
return Fail(t, "Should be false", msgAndArgs...)
@@ -534,6 +606,9 @@ func False(t TestingT, value bool, msgAndArgs ...interface{}) bool {
// Pointer variable equality is determined based on the equality of the
// referenced values (as opposed to the memory addresses).
func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
if err := validateEqualArgs(expected, actual); err != nil {
return Fail(t, fmt.Sprintf("Invalid operation: %#v != %#v (%s)",
expected, actual, err), msgAndArgs...)
@@ -592,6 +667,9 @@ func includeElement(list interface{}, element interface{}) (ok, found bool) {
// assert.Contains(t, ["Hello", "World"], "World")
// assert.Contains(t, {"Hello": "World"}, "Hello")
func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
ok, found := includeElement(s, contains)
if !ok {
@@ -612,6 +690,9 @@ func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bo
// assert.NotContains(t, ["Hello", "World"], "Earth")
// assert.NotContains(t, {"Hello": "World"}, "Earth")
func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
ok, found := includeElement(s, contains)
if !ok {
@@ -630,6 +711,9 @@ func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{})
//
// assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")
func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
if subset == nil {
return true // we consider nil to be equal to the nil set
}
@@ -671,6 +755,9 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok
//
// assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")
func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
if subset == nil {
return Fail(t, fmt.Sprintf("nil is the empty set which is a subset of every set"), msgAndArgs...)
}
@@ -713,6 +800,9 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{})
//
// assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2])
func ElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface{}) (ok bool) {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
if isEmpty(listA) && isEmpty(listB) {
return true
}
@@ -763,6 +853,9 @@ func ElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface
// Condition uses a Comparison to assert a complex condition.
func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
result := comp()
if !result {
Fail(t, "Condition failed!", msgAndArgs...)
@@ -800,9 +893,12 @@ func didPanic(f PanicTestFunc) (bool, interface{}) {
//
// assert.Panics(t, func(){ GoCrazy() })
func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
if funcDidPanic, panicValue := didPanic(f); !funcDidPanic {
- return Fail(t, fmt.Sprintf("func %#v should panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...)
+ return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...)
}
return true
@@ -813,13 +909,16 @@ func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
//
// assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() })
func PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
funcDidPanic, panicValue := didPanic(f)
if !funcDidPanic {
- return Fail(t, fmt.Sprintf("func %#v should panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...)
+ return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...)
}
if panicValue != expected {
- return Fail(t, fmt.Sprintf("func %#v should panic with value:\t%v\n\r\tPanic value:\t%v", f, expected, panicValue), msgAndArgs...)
+ return Fail(t, fmt.Sprintf("func %#v should panic with value:\t%#v\n\tPanic value:\t%#v", f, expected, panicValue), msgAndArgs...)
}
return true
@@ -829,9 +928,12 @@ func PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndAr
//
// assert.NotPanics(t, func(){ RemainCalm() })
func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
if funcDidPanic, panicValue := didPanic(f); funcDidPanic {
- return Fail(t, fmt.Sprintf("func %#v should not panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...)
+ return Fail(t, fmt.Sprintf("func %#v should not panic\n\tPanic value:\t%v", f, panicValue), msgAndArgs...)
}
return true
@@ -841,6 +943,9 @@ func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
//
// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second)
func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
dt := expected.Sub(actual)
if dt < -delta || dt > delta {
@@ -890,6 +995,9 @@ func toFloat(x interface{}) (float64, bool) {
//
// assert.InDelta(t, math.Pi, (22 / 7.0), 0.01)
func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
af, aok := toFloat(expected)
bf, bok := toFloat(actual)
@@ -916,6 +1024,9 @@ func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs
// InDeltaSlice is the same as InDelta, except it compares two slices.
func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
if expected == nil || actual == nil ||
reflect.TypeOf(actual).Kind() != reflect.Slice ||
reflect.TypeOf(expected).Kind() != reflect.Slice {
@@ -937,6 +1048,9 @@ func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAn
// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
func InDeltaMapValues(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
if expected == nil || actual == nil ||
reflect.TypeOf(actual).Kind() != reflect.Map ||
reflect.TypeOf(expected).Kind() != reflect.Map {
@@ -994,6 +1108,9 @@ func calcRelativeError(expected, actual interface{}) (float64, error) {
// InEpsilon asserts that expected and actual have a relative error less than epsilon
func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
actualEpsilon, err := calcRelativeError(expected, actual)
if err != nil {
return Fail(t, err.Error(), msgAndArgs...)
@@ -1008,6 +1125,9 @@ func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAnd
// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.
func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
if expected == nil || actual == nil ||
reflect.TypeOf(actual).Kind() != reflect.Slice ||
reflect.TypeOf(expected).Kind() != reflect.Slice {
@@ -1038,6 +1158,9 @@ func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, m
// assert.Equal(t, expectedObj, actualObj)
// }
func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
if err != nil {
return Fail(t, fmt.Sprintf("Received unexpected error:\n%+v", err), msgAndArgs...)
}
@@ -1052,6 +1175,9 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool {
// assert.Equal(t, expectedError, err)
// }
func Error(t TestingT, err error, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
if err == nil {
return Fail(t, "An error is expected but got nil.", msgAndArgs...)
@@ -1066,6 +1192,9 @@ func Error(t TestingT, err error, msgAndArgs ...interface{}) bool {
// actualObj, err := SomeFunction()
// assert.EqualError(t, err, expectedErrorString)
func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
if !Error(t, theError, msgAndArgs...) {
return false
}
@@ -1099,6 +1228,9 @@ func matchRegexp(rx interface{}, str interface{}) bool {
// assert.Regexp(t, regexp.MustCompile("start"), "it's starting")
// assert.Regexp(t, "start...$", "it's not starting")
func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
match := matchRegexp(rx, str)
@@ -1114,6 +1246,9 @@ func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface
// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting")
// assert.NotRegexp(t, "^start", "it's not starting")
func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
match := matchRegexp(rx, str)
if match {
@@ -1126,6 +1261,9 @@ func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interf
// Zero asserts that i is the zero value for its type.
func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
if i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) {
return Fail(t, fmt.Sprintf("Should be zero, but was %v", i), msgAndArgs...)
}
@@ -1134,6 +1272,9 @@ func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
// NotZero asserts that i is not the zero value for its type.
func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
if i == nil || reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) {
return Fail(t, fmt.Sprintf("Should not be zero, but was %v", i), msgAndArgs...)
}
@@ -1142,6 +1283,9 @@ func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
// FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
func FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
info, err := os.Lstat(path)
if err != nil {
if os.IsNotExist(err) {
@@ -1157,6 +1301,9 @@ func FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
// DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
func DirExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
info, err := os.Lstat(path)
if err != nil {
if os.IsNotExist(err) {
@@ -1174,6 +1321,9 @@ func DirExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
//
// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
var expectedJSONAsInterface, actualJSONAsInterface interface{}
if err := json.Unmarshal([]byte(expected), &expectedJSONAsInterface); err != nil {
@@ -1199,7 +1349,7 @@ func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) {
}
// diff returns a diff of both values as long as both are of the same type and
-// are a struct, map, slice or array. Otherwise it returns an empty string.
+// are a struct, map, slice, array or string. Otherwise it returns an empty string.
func diff(expected interface{}, actual interface{}) string {
if expected == nil || actual == nil {
return ""
@@ -1212,12 +1362,18 @@ func diff(expected interface{}, actual interface{}) string {
return ""
}
- if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array {
+ if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array && ek != reflect.String {
return ""
}
- e := spewConfig.Sdump(expected)
- a := spewConfig.Sdump(actual)
+ var e, a string
+ if et != reflect.TypeOf("") {
+ e = spewConfig.Sdump(expected)
+ a = spewConfig.Sdump(actual)
+ } else {
+ e = expected.(string)
+ a = actual.(string)
+ }
diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{
A: difflib.SplitLines(e),
@@ -1254,3 +1410,7 @@ var spewConfig = spew.ConfigState{
DisableCapacities: true,
SortKeys: true,
}
+
+type tHelper interface {
+ Helper()
+}
diff --git a/vendor/github.com/stretchr/testify/assert/http_assertions.go b/vendor/github.com/stretchr/testify/assert/http_assertions.go
index 3101e78d..df46fa77 100644
--- a/vendor/github.com/stretchr/testify/assert/http_assertions.go
+++ b/vendor/github.com/stretchr/testify/assert/http_assertions.go
@@ -12,10 +12,11 @@ import (
// an error if building a new request fails.
func httpCode(handler http.HandlerFunc, method, url string, values url.Values) (int, error) {
w := httptest.NewRecorder()
- req, err := http.NewRequest(method, url+"?"+values.Encode(), nil)
+ req, err := http.NewRequest(method, url, nil)
if err != nil {
return -1, err
}
+ req.URL.RawQuery = values.Encode()
handler(w, req)
return w.Code, nil
}
@@ -26,6 +27,9 @@ func httpCode(handler http.HandlerFunc, method, url string, values url.Values) (
//
// Returns whether the assertion was successful (true) or not (false).
func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
code, err := httpCode(handler, method, url, values)
if err != nil {
Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err))
@@ -46,6 +50,9 @@ func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, value
//
// Returns whether the assertion was successful (true) or not (false).
func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
code, err := httpCode(handler, method, url, values)
if err != nil {
Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err))
@@ -66,6 +73,9 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, valu
//
// Returns whether the assertion was successful (true) or not (false).
func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
code, err := httpCode(handler, method, url, values)
if err != nil {
Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err))
@@ -95,10 +105,13 @@ func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) s
// HTTPBodyContains asserts that a specified handler returns a
// body that contains a string.
//
-// assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
+// assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
//
// Returns whether the assertion was successful (true) or not (false).
func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
body := HTTPBody(handler, method, url, values)
contains := strings.Contains(body, fmt.Sprint(str))
@@ -112,10 +125,13 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string,
// HTTPBodyNotContains asserts that a specified handler returns a
// body that does not contain a string.
//
-// assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
+// assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
//
// Returns whether the assertion was successful (true) or not (false).
func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
+ if h, ok := t.(tHelper); ok {
+ h.Helper()
+ }
body := HTTPBody(handler, method, url, values)
contains := strings.Contains(body, fmt.Sprint(str))
diff --git a/vendor/golang.org/x/crypto/blowfish/cipher.go b/vendor/golang.org/x/crypto/blowfish/cipher.go
index 2641dadd..213bf204 100644
--- a/vendor/golang.org/x/crypto/blowfish/cipher.go
+++ b/vendor/golang.org/x/crypto/blowfish/cipher.go
@@ -3,6 +3,14 @@
// license that can be found in the LICENSE file.
// Package blowfish implements Bruce Schneier's Blowfish encryption algorithm.
+//
+// Blowfish is a legacy cipher and its short block size makes it vulnerable to
+// birthday bound attacks (see https://sweet32.info). It should only be used
+// where compatibility with legacy systems, not security, is the goal.
+//
+// Deprecated: any new system should use AES (from crypto/aes, if necessary in
+// an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
+// golang.org/x/crypto/chacha20poly1305).
package blowfish // import "golang.org/x/crypto/blowfish"
// The code is a port of Bruce Schneier's C implementation.
diff --git a/vendor/golang.org/x/crypto/cast5/cast5.go b/vendor/golang.org/x/crypto/cast5/cast5.go
index 0b4af37b..ddcbeb6f 100644
--- a/vendor/golang.org/x/crypto/cast5/cast5.go
+++ b/vendor/golang.org/x/crypto/cast5/cast5.go
@@ -2,8 +2,15 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Package cast5 implements CAST5, as defined in RFC 2144. CAST5 is a common
-// OpenPGP cipher.
+// Package cast5 implements CAST5, as defined in RFC 2144.
+//
+// CAST5 is a legacy cipher and its short block size makes it vulnerable to
+// birthday bound attacks (see https://sweet32.info). It should only be used
+// where compatibility with legacy systems, not security, is the goal.
+//
+// Deprecated: any new system should use AES (from crypto/aes, if necessary in
+// an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
+// golang.org/x/crypto/chacha20poly1305).
package cast5 // import "golang.org/x/crypto/cast5"
import "errors"
diff --git a/vendor/golang.org/x/crypto/internal/subtle/aliasing.go b/vendor/golang.org/x/crypto/internal/subtle/aliasing.go
new file mode 100644
index 00000000..f38797bf
--- /dev/null
+++ b/vendor/golang.org/x/crypto/internal/subtle/aliasing.go
@@ -0,0 +1,32 @@
+// Copyright 2018 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.
+
+// +build !appengine
+
+// Package subtle implements functions that are often useful in cryptographic
+// code but require careful thought to use correctly.
+package subtle // import "golang.org/x/crypto/internal/subtle"
+
+import "unsafe"
+
+// AnyOverlap reports whether x and y share memory at any (not necessarily
+// corresponding) index. The memory beyond the slice length is ignored.
+func AnyOverlap(x, y []byte) bool {
+ return len(x) > 0 && len(y) > 0 &&
+ uintptr(unsafe.Pointer(&x[0])) <= uintptr(unsafe.Pointer(&y[len(y)-1])) &&
+ uintptr(unsafe.Pointer(&y[0])) <= uintptr(unsafe.Pointer(&x[len(x)-1]))
+}
+
+// InexactOverlap reports whether x and y share memory at any non-corresponding
+// index. The memory beyond the slice length is ignored. Note that x and y can
+// have different lengths and still not have any inexact overlap.
+//
+// InexactOverlap can be used to implement the requirements of the crypto/cipher
+// AEAD, Block, BlockMode and Stream interfaces.
+func InexactOverlap(x, y []byte) bool {
+ if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
+ return false
+ }
+ return AnyOverlap(x, y)
+}
diff --git a/vendor/golang.org/x/crypto/internal/subtle/aliasing_appengine.go b/vendor/golang.org/x/crypto/internal/subtle/aliasing_appengine.go
new file mode 100644
index 00000000..0cc4a8a6
--- /dev/null
+++ b/vendor/golang.org/x/crypto/internal/subtle/aliasing_appengine.go
@@ -0,0 +1,35 @@
+// Copyright 2018 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.
+
+// +build appengine
+
+// Package subtle implements functions that are often useful in cryptographic
+// code but require careful thought to use correctly.
+package subtle // import "golang.org/x/crypto/internal/subtle"
+
+// This is the Google App Engine standard variant based on reflect
+// because the unsafe package and cgo are disallowed.
+
+import "reflect"
+
+// AnyOverlap reports whether x and y share memory at any (not necessarily
+// corresponding) index. The memory beyond the slice length is ignored.
+func AnyOverlap(x, y []byte) bool {
+ return len(x) > 0 && len(y) > 0 &&
+ reflect.ValueOf(&x[0]).Pointer() <= reflect.ValueOf(&y[len(y)-1]).Pointer() &&
+ reflect.ValueOf(&y[0]).Pointer() <= reflect.ValueOf(&x[len(x)-1]).Pointer()
+}
+
+// InexactOverlap reports whether x and y share memory at any non-corresponding
+// index. The memory beyond the slice length is ignored. Note that x and y can
+// have different lengths and still not have any inexact overlap.
+//
+// InexactOverlap can be used to implement the requirements of the crypto/cipher
+// AEAD, Block, BlockMode and Stream interfaces.
+func InexactOverlap(x, y []byte) bool {
+ if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
+ return false
+ }
+ return AnyOverlap(x, y)
+}
diff --git a/vendor/golang.org/x/crypto/salsa20/salsa20.go b/vendor/golang.org/x/crypto/salsa20/salsa20.go
index 0ee62485..6f9bb106 100644
--- a/vendor/golang.org/x/crypto/salsa20/salsa20.go
+++ b/vendor/golang.org/x/crypto/salsa20/salsa20.go
@@ -24,6 +24,7 @@ package salsa20 // import "golang.org/x/crypto/salsa20"
// TODO(agl): implement XORKeyStream12 and XORKeyStream8 - the reduced round variants of Salsa20.
import (
+ "golang.org/x/crypto/internal/subtle"
"golang.org/x/crypto/salsa20/salsa"
)
@@ -32,7 +33,10 @@ import (
// be either 8 or 24 bytes long.
func XORKeyStream(out, in []byte, nonce []byte, key *[32]byte) {
if len(out) < len(in) {
- in = in[:len(out)]
+ panic("salsa20: output smaller than input")
+ }
+ if subtle.InexactOverlap(out[:len(in)], in) {
+ panic("salsa20: invalid buffer overlap")
}
var subNonce [16]byte
diff --git a/vendor/golang.org/x/crypto/tea/cipher.go b/vendor/golang.org/x/crypto/tea/cipher.go
index ce223b2c..c1ff90e0 100644
--- a/vendor/golang.org/x/crypto/tea/cipher.go
+++ b/vendor/golang.org/x/crypto/tea/cipher.go
@@ -5,6 +5,14 @@
// Package tea implements the TEA algorithm, as defined in Needham and
// Wheeler's 1994 technical report, “TEA, a Tiny Encryption Algorithm”. See
// http://www.cix.co.uk/~klockstone/tea.pdf for details.
+//
+// TEA is a legacy cipher and its short block size makes it vulnerable to
+// birthday bound attacks (see https://sweet32.info). It should only be used
+// where compatibility with legacy systems, not security, is the goal.
+//
+// Deprecated: any new system should use AES (from crypto/aes, if necessary in
+// an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
+// golang.org/x/crypto/chacha20poly1305).
package tea
import (
diff --git a/vendor/golang.org/x/crypto/twofish/twofish.go b/vendor/golang.org/x/crypto/twofish/twofish.go
index 6db01fcf..1197d751 100644
--- a/vendor/golang.org/x/crypto/twofish/twofish.go
+++ b/vendor/golang.org/x/crypto/twofish/twofish.go
@@ -3,6 +3,12 @@
// license that can be found in the LICENSE file.
// Package twofish implements Bruce Schneier's Twofish encryption algorithm.
+//
+// Deprecated: Twofish is a legacy cipher and should not be used for new
+// applications. Also, this package does not and will not provide an optimized
+// implementation. Instead, use AES (from crypto/aes, if necessary in an AEAD
+// mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
+// golang.org/x/crypto/chacha20poly1305).
package twofish // import "golang.org/x/crypto/twofish"
// Twofish is defined in https://www.schneier.com/paper-twofish-paper.pdf [TWOFISH]
diff --git a/vendor/golang.org/x/crypto/xtea/cipher.go b/vendor/golang.org/x/crypto/xtea/cipher.go
index 1661cbea..a4c2fd02 100644
--- a/vendor/golang.org/x/crypto/xtea/cipher.go
+++ b/vendor/golang.org/x/crypto/xtea/cipher.go
@@ -4,6 +4,14 @@
// Package xtea implements XTEA encryption, as defined in Needham and Wheeler's
// 1997 technical report, "Tea extensions."
+//
+// XTEA is a legacy cipher and its short block size makes it vulnerable to
+// birthday bound attacks (see https://sweet32.info). It should only be used
+// where compatibility with legacy systems, not security, is the goal.
+//
+// Deprecated: any new system should use AES (from crypto/aes, if necessary in
+// an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
+// golang.org/x/crypto/chacha20poly1305).
package xtea // import "golang.org/x/crypto/xtea"
// For details, see http://www.cix.co.uk/~klockstone/xtea.pdf
diff --git a/vendor/golang.org/x/net/bpf/constants.go b/vendor/golang.org/x/net/bpf/constants.go
index b89ca352..12f3ee83 100644
--- a/vendor/golang.org/x/net/bpf/constants.go
+++ b/vendor/golang.org/x/net/bpf/constants.go
@@ -38,6 +38,7 @@ const (
type JumpTest uint16
// Supported operators for conditional jumps.
+// K can be RegX for JumpIfX
const (
// K == A
JumpEqual JumpTest = iota
@@ -134,12 +135,9 @@ const (
opMaskLoadDest = 0x01
opMaskLoadWidth = 0x18
opMaskLoadMode = 0xe0
- // opClsALU
- opMaskOperandSrc = 0x08
- opMaskOperator = 0xf0
- // opClsJump
- opMaskJumpConst = 0x0f
- opMaskJumpCond = 0xf0
+ // opClsALU & opClsJump
+ opMaskOperand = 0x08
+ opMaskOperator = 0xf0
)
const (
@@ -192,15 +190,21 @@ const (
opLoadWidth1
)
-// Operator defined by ALUOp*
+// Operand for ALU and Jump instructions
+type opOperand uint16
+// Supported operand sources.
const (
- opALUSrcConstant uint16 = iota << 3
- opALUSrcX
+ opOperandConstant opOperand = iota << 3
+ opOperandX
)
+// An jumpOp is a conditional jump condition.
+type jumpOp uint16
+
+// Supported jump conditions.
const (
- opJumpAlways = iota << 4
+ opJumpAlways jumpOp = iota << 4
opJumpEqual
opJumpGT
opJumpGE
diff --git a/vendor/golang.org/x/net/bpf/instructions.go b/vendor/golang.org/x/net/bpf/instructions.go
index f9dc0e8e..3cffcaa0 100644
--- a/vendor/golang.org/x/net/bpf/instructions.go
+++ b/vendor/golang.org/x/net/bpf/instructions.go
@@ -89,10 +89,14 @@ func (ri RawInstruction) Disassemble() Instruction {
case opClsALU:
switch op := ALUOp(ri.Op & opMaskOperator); op {
case ALUOpAdd, ALUOpSub, ALUOpMul, ALUOpDiv, ALUOpOr, ALUOpAnd, ALUOpShiftLeft, ALUOpShiftRight, ALUOpMod, ALUOpXor:
- if ri.Op&opMaskOperandSrc != 0 {
+ switch operand := opOperand(ri.Op & opMaskOperand); operand {
+ case opOperandX:
return ALUOpX{Op: op}
+ case opOperandConstant:
+ return ALUOpConstant{Op: op, Val: ri.K}
+ default:
+ return ri
}
- return ALUOpConstant{Op: op, Val: ri.K}
case aluOpNeg:
return NegateA{}
default:
@@ -100,63 +104,18 @@ func (ri RawInstruction) Disassemble() Instruction {
}
case opClsJump:
- if ri.Op&opMaskJumpConst != opClsJump {
- return ri
- }
- switch ri.Op & opMaskJumpCond {
+ switch op := jumpOp(ri.Op & opMaskOperator); op {
case opJumpAlways:
return Jump{Skip: ri.K}
- case opJumpEqual:
- if ri.Jt == 0 {
- return JumpIf{
- Cond: JumpNotEqual,
- Val: ri.K,
- SkipTrue: ri.Jf,
- SkipFalse: 0,
- }
- }
- return JumpIf{
- Cond: JumpEqual,
- Val: ri.K,
- SkipTrue: ri.Jt,
- SkipFalse: ri.Jf,
- }
- case opJumpGT:
- if ri.Jt == 0 {
- return JumpIf{
- Cond: JumpLessOrEqual,
- Val: ri.K,
- SkipTrue: ri.Jf,
- SkipFalse: 0,
- }
- }
- return JumpIf{
- Cond: JumpGreaterThan,
- Val: ri.K,
- SkipTrue: ri.Jt,
- SkipFalse: ri.Jf,
- }
- case opJumpGE:
- if ri.Jt == 0 {
- return JumpIf{
- Cond: JumpLessThan,
- Val: ri.K,
- SkipTrue: ri.Jf,
- SkipFalse: 0,
- }
- }
- return JumpIf{
- Cond: JumpGreaterOrEqual,
- Val: ri.K,
- SkipTrue: ri.Jt,
- SkipFalse: ri.Jf,
- }
- case opJumpSet:
- return JumpIf{
- Cond: JumpBitsSet,
- Val: ri.K,
- SkipTrue: ri.Jt,
- SkipFalse: ri.Jf,
+ case opJumpEqual, opJumpGT, opJumpGE, opJumpSet:
+ cond, skipTrue, skipFalse := jumpOpToTest(op, ri.Jt, ri.Jf)
+ switch operand := opOperand(ri.Op & opMaskOperand); operand {
+ case opOperandX:
+ return JumpIfX{Cond: cond, SkipTrue: skipTrue, SkipFalse: skipFalse}
+ case opOperandConstant:
+ return JumpIf{Cond: cond, Val: ri.K, SkipTrue: skipTrue, SkipFalse: skipFalse}
+ default:
+ return ri
}
default:
return ri
@@ -187,6 +146,41 @@ func (ri RawInstruction) Disassemble() Instruction {
}
}
+func jumpOpToTest(op jumpOp, skipTrue uint8, skipFalse uint8) (JumpTest, uint8, uint8) {
+ var test JumpTest
+
+ // Decode "fake" jump conditions that don't appear in machine code
+ // Ensures the Assemble -> Disassemble stage recreates the same instructions
+ // See https://github.com/golang/go/issues/18470
+ if skipTrue == 0 {
+ switch op {
+ case opJumpEqual:
+ test = JumpNotEqual
+ case opJumpGT:
+ test = JumpLessOrEqual
+ case opJumpGE:
+ test = JumpLessThan
+ case opJumpSet:
+ test = JumpBitsNotSet
+ }
+
+ return test, skipFalse, 0
+ }
+
+ switch op {
+ case opJumpEqual:
+ test = JumpEqual
+ case opJumpGT:
+ test = JumpGreaterThan
+ case opJumpGE:
+ test = JumpGreaterOrEqual
+ case opJumpSet:
+ test = JumpBitsSet
+ }
+
+ return test, skipTrue, skipFalse
+}
+
// LoadConstant loads Val into register Dst.
type LoadConstant struct {
Dst Register
@@ -413,7 +407,7 @@ type ALUOpConstant struct {
// Assemble implements the Instruction Assemble method.
func (a ALUOpConstant) Assemble() (RawInstruction, error) {
return RawInstruction{
- Op: opClsALU | opALUSrcConstant | uint16(a.Op),
+ Op: opClsALU | uint16(opOperandConstant) | uint16(a.Op),
K: a.Val,
}, nil
}
@@ -454,7 +448,7 @@ type ALUOpX struct {
// Assemble implements the Instruction Assemble method.
func (a ALUOpX) Assemble() (RawInstruction, error) {
return RawInstruction{
- Op: opClsALU | opALUSrcX | uint16(a.Op),
+ Op: opClsALU | uint16(opOperandX) | uint16(a.Op),
}, nil
}
@@ -509,7 +503,7 @@ type Jump struct {
// Assemble implements the Instruction Assemble method.
func (a Jump) Assemble() (RawInstruction, error) {
return RawInstruction{
- Op: opClsJump | opJumpAlways,
+ Op: opClsJump | uint16(opJumpAlways),
K: a.Skip,
}, nil
}
@@ -530,11 +524,39 @@ type JumpIf struct {
// Assemble implements the Instruction Assemble method.
func (a JumpIf) Assemble() (RawInstruction, error) {
+ return jumpToRaw(a.Cond, opOperandConstant, a.Val, a.SkipTrue, a.SkipFalse)
+}
+
+// String returns the instruction in assembler notation.
+func (a JumpIf) String() string {
+ return jumpToString(a.Cond, fmt.Sprintf("#%d", a.Val), a.SkipTrue, a.SkipFalse)
+}
+
+// JumpIfX skips the following Skip instructions in the program if A
+//