httpexpect

package module
v2.0.0+incompatible Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 23, 2019 License: MIT Imports: 38 Imported by: 0

README

httpexpect GoDoc Gitter Travis Coveralls

Concise, declarative, and easy to use end-to-end HTTP and REST API testing for Go (golang).

Basically, httpexpect is a set of chainable builders for HTTP requests and assertions for HTTP responses and payload, on top of net/http and several utility packages.

Workflow:

  • Incrementally build HTTP requests.
  • Inspect HTTP responses.
  • Inspect response payload recursively.

Features

Request builder
  • URL path construction, with simple string interpolation provided by go-interpol package.
  • URL query parameters (encoding using go-querystring package).
  • Headers, cookies, payload: JSON, urlencoded or multipart forms (encoding using form package), plain text.
  • Custom reusable request builders.
Response assertions
  • Response status, predefined status ranges.
  • Headers, cookies, payload: JSON, JSONP, forms, text.
  • Round-trip time.
  • Custom reusable response matchers.
Payload assertions
  • Type-specific assertions, supported types: object, array, string, number, boolean, null, datetime.
  • Regular expressions.
  • Simple JSON queries (using subset of JSONPath), provided by jsonpath package.
  • JSON Schema validation, provided by gojsonschema package.
WebSocket support (thanks to @tyranron)
  • Upgrade an HTTP connection to a WebSocket connection (we use gorilla/websocket internally).
  • Interact with the WebSocket server.
  • Inspect WebSocket connection parameters and WebSocket messages.
Pretty printing
  • Verbose error messages.
  • JSON diff is produced on failure using gojsondiff package.
  • Failures are reported using testify (assert or require package) or standard testing package.
  • Dumping requests and responses in various formats, using httputil, http2curl, or simple compact logger.
Tuning
  • Tests can communicate with server via real HTTP client or invoke net/http or fasthttp handler directly.
  • Custom HTTP client, logger, printer, and failure reporter may be provided by user.
  • Custom HTTP request factory may be provided, e.g. from the Google App Engine testing.

Status

Stable branches are available on gopkg.in and will not introduce backward-incompatible changes.

Current stable branch is v2:

import "gopkg.in/gavv/httpexpect.v2"

Development is done in master branch on github:

import "github.com/gavv/httpexpect"

When the master is merged into a stable branch, a new version tag is assigned to the branch head. The versions are selected according to the semantic versioning scheme.

Documentation

Documentation is available on GoDoc. It contains an overview and reference.

Examples

See _examples directory for complete standalone examples.

  • fruits_test.go

    Testing a simple CRUD server made with bare net/http.

  • iris_test.go

    Testing a server made with iris framework. Example includes JSON queries and validation, URL and form parameters, basic auth, sessions, and streaming. Tests invoke the http.Handler directly.

  • echo_test.go

    Testing a server with JWT authentication made with echo framework. Tests use either HTTP client or invoke the http.Handler directly.

  • fasthttp_test.go

    Testing a server made with fasthttp package. Tests invoke the fasthttp.RequestHandler directly.

  • websocket_test.go

    Testing a WebSocket server based on gorilla/websocket. Tests invoke the http.Handler or fasthttp.RequestHandler directly.

  • gae_test.go

    Testing a server running under the Google App Engine.

Quick start

Hello, world!
package example

import (
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/gavv/httpexpect"
)

func TestFruits(t *testing.T) {
	// create http.Handler
	handler := FruitsHandler()

	// run server using httptest
	server := httptest.NewServer(handler)
	defer server.Close()

	// create httpexpect instance
	e := httpexpect.New(t, server.URL)

	// is it working?
	e.GET("/fruits").
		Expect().
		Status(http.StatusOK).JSON().Array().Empty()
}
JSON
orange := map[string]interface{}{
	"weight": 100,
}

e.PUT("/fruits/orange").WithJSON(orange).
	Expect().
	Status(http.StatusNoContent).NoContent()

e.GET("/fruits/orange").
	Expect().
	Status(http.StatusOK).
	JSON().Object().ContainsKey("weight").ValueEqual("weight", 100)

apple := map[string]interface{}{
	"colors": []interface{}{"green", "red"},
	"weight": 200,
}

e.PUT("/fruits/apple").WithJSON(apple).
	Expect().
	Status(http.StatusNoContent).NoContent()

obj := e.GET("/fruits/apple").
	Expect().
	Status(http.StatusOK).JSON().Object()

obj.Keys().ContainsOnly("colors", "weight")

obj.Value("colors").Array().Elements("green", "red")
obj.Value("colors").Array().Element(0).String().Equal("green")
obj.Value("colors").Array().Element(1).String().Equal("red")
obj.Value("colors").Array().First().String().Equal("green")
obj.Value("colors").Array().Last().String().Equal("red")
JSON Schema and JSON Path
schema := `{
	"type": "array",
	"items": {
		"type": "object",
		"properties": {
			...
			"private": {
				"type": "boolean"
			}
		}
	}
}`

repos := e.GET("/repos/octocat").
	Expect().
	Status(http.StatusOK).JSON()

// validate JSON schema
repos.Schema(schema)

// run JSONPath query and iterate results
for _, private := range repos.Path("$..private").Array().Iter() {
	private.Boolean().False()
}
Forms
// post form encoded from struct or map
e.POST("/form").WithForm(structOrMap).
	Expect().
	Status(http.StatusOK)

// set individual fields
e.POST("/form").WithFormField("foo", "hello").WithFormField("bar", 123).
	Expect().
	Status(http.StatusOK)

// multipart form
e.POST("/form").WithMultipart().
	WithFile("avatar", "./john.png").WithFormField("username", "john").
	Expect().
	Status(http.StatusOK)
URL construction
// construct path using ordered parameters
e.GET("/repos/{user}/{repo}", "octocat", "hello-world").
	Expect().
	Status(http.StatusOK)

// construct path using named parameters
e.GET("/repos/{user}/{repo}").
	WithPath("user", "octocat").WithPath("repo", "hello-world").
	Expect().
	Status(http.StatusOK)

// set query parameters
e.GET("/repos/{user}", "octocat").WithQuery("sort", "asc").
	Expect().
	Status(http.StatusOK)    // "/repos/octocat?sort=asc"
Headers
// set If-Match
e.POST("/users/john").WithHeader("If-Match", etag).WithJSON(john).
	Expect().
	Status(http.StatusOK)

// check ETag
e.GET("/users/john").
	Expect().
	Status(http.StatusOK).Header("ETag").NotEmpty()

// check Date
t := time.Now()

e.GET("/users/john").
	Expect().
	Status(http.StatusOK).Header("Date").DateTime().InRange(t, time.Now())
Cookies
// set cookie
t := time.Now()

e.POST("/users/john").WithCookie("session", sessionID).WithJSON(john).
	Expect().
	Status(http.StatusOK)

// check cookies
c := e.GET("/users/john").
	Expect().
	Status(http.StatusOK).Cookie("session")

c.Value().Equal(sessionID)
c.Domain().Equal("example.com")
c.Path().Equal("/")
c.Expires().InRange(t, t.Add(time.Hour * 24))
Regular expressions
// simple match
e.GET("/users/john").
	Expect().
	Header("Location").
	Match("http://(.+)/users/(.+)").Values("example.com", "john")

// check capture groups by index or name
m := e.GET("/users/john").
	Expect().
	Header("Location").Match("http://(?P<host>.+)/users/(?P<user>.+)")

m.Index(0).Equal("http://example.com/users/john")
m.Index(1).Equal("example.com")
m.Index(2).Equal("john")

m.Name("host").Equal("example.com")
m.Name("user").Equal("john")
Subdomains and per-request URL
e.GET("/path").WithURL("http://example.com").
	Expect().
	Status(http.StatusOK)

e.GET("/path").WithURL("http://subdomain.example.com").
	Expect().
	Status(http.StatusOK)
WebSocket support
ws := e.GET("/mysocket").WithWebsocketUpgrade().
	Expect().
	Status(http.StatusSwitchingProtocols).
	Websocket()
defer ws.Disconnect()

ws.WriteText("some request").
	Expect().
	TextMessage().Body().Equal("some response")

ws.CloseWithText("bye").
	Expect().
	CloseMessage().NoContent()
Reusable builders
e := httpexpect.New(t, "http://example.com")

r := e.POST("/login").WithForm(Login{"ford", "betelgeuse7"}).
	Expect().
	Status(http.StatusOK).JSON().Object()

token := r.Value("token").String().Raw()

auth := e.Builder(func (req *httpexpect.Request) {
	req.WithHeader("Authorization", "Bearer "+token)
})

auth.GET("/restricted").
	Expect().
	Status(http.StatusOK)

e.GET("/restricted").
	Expect().
	Status(http.StatusUnauthorized)
Reusable matchers
e := httpexpect.New(t, "http://example.com")

// every response should have this header
m := e.Matcher(func (resp *httpexpect.Response) {
	resp.Header("API-Version").NotEmpty()
})

m.GET("/some-path").
	Expect().
	Status(http.StatusOK)

m.GET("/bad-path").
	Expect().
	Status(http.StatusNotFound)
Custom config
e := httpexpect.WithConfig(httpexpect.Config{
	// prepend this url to all requests
	BaseURL: "http://example.com",

	// use http.Client with a cookie jar and timeout
	Client: &http.Client{
		Jar:     httpexpect.NewJar(),
		Timeout: time.Second * 30,
	},

	// use fatal failures
	Reporter: httpexpect.NewRequireReporter(t),

	// use verbose logging
	Printers: []httpexpect.Printer{
		httpexpect.NewCurlPrinter(t),
		httpexpect.NewDebugPrinter(t, true),
	},
})
Session support
// cookie jar is used to store cookies from server
e := httpexpect.WithConfig(httpexpect.Config{
	Reporter: httpexpect.NewAssertReporter(t),
	Client: &http.Client{
		Jar: httpexpect.NewJar(), // used by default if Client is nil
	},
})

// cookies are disabled
e := httpexpect.WithConfig(httpexpect.Config{
	Reporter: httpexpect.NewAssertReporter(t),
	Client: &http.Client{
		Jar: nil,
	},
})
Use HTTP handler directly
// invoke http.Handler directly using httpexpect.Binder
var handler http.Handler = MyHandler()

e := httpexpect.WithConfig(httpexpect.Config{
	Reporter: httpexpect.NewAssertReporter(t),
	Client: &http.Client{
		Transport: httpexpect.NewBinder(handler),
		Jar:       httpexpect.NewJar(),
	},
})

// invoke fasthttp.RequestHandler directly using httpexpect.FastBinder
var handler fasthttp.RequestHandler = myHandler()

e := httpexpect.WithConfig(httpexpect.Config{
	Reporter: httpexpect.NewAssertReporter(t),
	Client: &http.Client{
		Transport: httpexpect.NewFastBinder(handler),
		Jar:       httpexpect.NewJar(),
	},
})
Per-request client or handler
e := httpexpect.New(t, server.URL)

client := &http.Client{
	Transport: &http.Transport{
		DisableCompression: true,
	},
}

// overwrite client
e.GET("/path").WithClient(client).
	Expect().
	Status(http.StatusOK)

// construct client that invokes a handler directly and overwrite client
e.GET("/path").WithHandler(handler).
	Expect().
	Status(http.StatusOK)

Similar packages

Contributing

Feel free to report bugs, suggest improvements, and send pull requests! Please add documentation and tests for new features.

Update dependencies, build code, and run tests and linters:

$ make

Format code:

$ make fmt

License

MIT

Documentation

Overview

Package httpexpect helps with end-to-end HTTP and REST API testing.

Usage examples

See example directory:

Communication mode

There are two common ways to test API with httpexpect:

  • start HTTP server and instruct httpexpect to use HTTP client for communication
  • don't start server and instruct httpexpect to invoke http handler directly

The second approach works only if the server is a Go module and its handler can be imported in tests.

Concrete behaviour is determined by Client implementation passed to Config struct. If you're using http.Client, set its Transport field (http.RoundTriper) to one of the following:

  1. default (nil) - use HTTP transport from net/http (you should start server)
  2. httpexpect.Binder - invoke given http.Handler directly
  3. httpexpect.FastBinder - invoke given fasthttp.RequestHandler directly

Note that http handler can be usually obtained from http framework you're using. E.g., echo framework provides either http.Handler or fasthttp.RequestHandler.

You can also provide your own implementation of RequestFactory (creates http.Request), or Client (gets http.Request and returns http.Response).

If you're starting server from tests, it's very handy to use net/http/httptest.

Value equality

Whenever values are checked for equality in httpexpect, they are converted to "canonical form":

  • structs are converted to map[string]interface{}
  • type aliases are removed
  • numeric types are converted to float64
  • non-nil interfaces pointing to nil slices and maps are replaced with nil interfaces

This is equivalent to subsequently json.Marshal() and json.Unmarshal() the value and currently is implemented so.

Failure handling

When some check fails, failure is reported. If non-fatal failures are used (see Reporter interface), execution is continued and instance that was checked is marked as failed.

If specific instance is marked as failed, all subsequent checks are ignored for this instance and for any child instances retrieved after failure.

Example:

array := NewArray(NewAssertReporter(t), []interface{}{"foo", 123})

e0 := array.Element(0)  // success
e1 := array.Element(1)  // success

s0 := e0.String()  // success
s1 := e1.String()  // failure; e1 and s1 are marked as failed, e0 and s0 are not

s0.Equal("foo")    // success
s1.Equal("bar")    // this check is ignored because s1 is marked as failed

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewFastWebsocketDialer

func NewFastWebsocketDialer(handler fasthttp.RequestHandler) *websocket.Dialer

NewFastWebsocketDialer produces new websocket.Dialer which dials to bound fasthttp.RequestHandler without creating a real net.Conn.

func NewJar

func NewJar() http.CookieJar

NewJar returns a new http.CookieJar.

Returned jar is implemented in net/http/cookiejar. PublicSuffixList is implemented in golang.org/x/net/publicsuffix.

Note that this jar ignores cookies when request url is empty.

func NewWebsocketDialer

func NewWebsocketDialer(handler http.Handler) *websocket.Dialer

NewWebsocketDialer produces new websocket.Dialer which dials to bound http.Handler without creating a real net.Conn.

Types

type Array

type Array struct {
	// contains filtered or unexported fields
}

Array provides methods to inspect attached []interface{} object (Go representation of JSON array).

func NewArray

func NewArray(reporter Reporter, value []interface{}) *Array

NewArray returns a new Array given a reporter used to report failures and value to be inspected.

Both reporter and value should not be nil. If value is nil, failure is reported.

Example:

array := NewArray(t, []interface{}{"foo", 123})

func (*Array) Contains

func (a *Array) Contains(values ...interface{}) *Array

Contains succeeds if array contains all given elements (in any order). Before comparison, array and all elements are converted to canonical form.

Example:

array := NewArray(t, []interface{}{"foo", 123})
array.Contains(123, "foo")

func (*Array) ContainsOnly

func (a *Array) ContainsOnly(values ...interface{}) *Array

ContainsOnly succeeds if array contains all given elements, in any order, and only them. Before comparison, array and all elements are converted to canonical form.

Example:

array := NewArray(t, []interface{}{"foo", 123})
array.ContainsOnly(123, "foo")

This calls are equivalent:

array.ContainsOnly("a", "b")
array.ContainsOnly("b", "a")

func (*Array) Element

func (a *Array) Element(index int) *Value

Element returns a new Value object that may be used to inspect array element for given index.

If index is out of array bounds, Element reports failure and returns empty (but non-nil) value.

Example:

array := NewArray(t, []interface{}{"foo", 123})
array.Element(0).String().Equal("foo")
array.Element(1).Number().Equal(123)

func (*Array) Elements

func (a *Array) Elements(values ...interface{}) *Array

Elements succeeds if array contains all given elements, in given order, and only them. Before comparison, array and all elements are converted to canonical form.

For partial or unordered comparison, see Contains and ContainsOnly.

Example:

array := NewArray(t, []interface{}{"foo", 123})
array.Elements("foo", 123)

This calls are equivalent:

array.Elelems("a", "b")
array.Equal([]interface{}{"a", "b"})

func (*Array) Empty

func (a *Array) Empty() *Array

Empty succeeds if array is empty.

Example:

array := NewArray(t, []interface{}{})
array.Empty()

func (*Array) Equal

func (a *Array) Equal(value interface{}) *Array

Equal succeeds if array is equal to given Go slice. Before comparison, both array and value are converted to canonical form.

value should be a slice of any type.

Example:

array := NewArray(t, []interface{}{"foo", 123})
array.Equal([]interface{}{"foo", 123})

array := NewArray(t, []interface{}{"foo", "bar"})
array.Equal([]string{}{"foo", "bar"})

array := NewArray(t, []interface{}{123, 456})
array.Equal([]int{}{123, 456})

func (*Array) First

func (a *Array) First() *Value

First returns a new Value object that may be used to inspect first element of given array.

If given array is empty, First reports failure and returns empty (but non-nil) value.

Example:

array := NewArray(t, []interface{}{"foo", 123})
array.First().String().Equal("foo")

func (*Array) Iter

func (a *Array) Iter() []Value

Iter returns a new slice of Values attached to array elements.

Example:

strings := []interface{}{"foo", "bar"}
array := NewArray(t, strings)

for n, val := range array.Iter() {
    val.String().Equal(strings[n])
}

func (*Array) Last

func (a *Array) Last() *Value

Last returns a new Value object that may be used to inspect last element of given array.

If given array is empty, Last reports failure and returns empty (but non-nil) value.

Example:

array := NewArray(t, []interface{}{"foo", 123})
array.Last().Number().Equal(123)

func (*Array) Length

func (a *Array) Length() *Number

Length returns a new Number object that may be used to inspect array length.

Example:

array := NewArray(t, []interface{}{1, 2, 3})
array.Length().Equal(3)

func (*Array) NotContains

func (a *Array) NotContains(values ...interface{}) *Array

NotContains succeeds if array contains none of given elements. Before comparison, array and all elements are converted to canonical form.

Example:

array := NewArray(t, []interface{}{"foo", 123})
array.NotContains("bar")         // success
array.NotContains("bar", "foo")  // failure (array contains "foo")

func (*Array) NotEmpty

func (a *Array) NotEmpty() *Array

NotEmpty succeeds if array is non-empty.

Example:

array := NewArray(t, []interface{}{"foo", 123})
array.NotEmpty()

func (*Array) NotEqual

func (a *Array) NotEqual(value interface{}) *Array

NotEqual succeeds if array is not equal to given Go slice. Before comparison, both array and value are converted to canonical form.

value should be a slice of any type.

Example:

array := NewArray(t, []interface{}{"foo", 123})
array.NotEqual([]interface{}{123, "foo"})

func (*Array) Path

func (a *Array) Path(path string) *Value

Path is similar to Value.Path.

func (*Array) Raw

func (a *Array) Raw() []interface{}

Raw returns underlying value attached to Array. This is the value originally passed to NewArray, converted to canonical form.

Example:

array := NewArray(t, []interface{}{"foo", 123})
assert.Equal(t, []interface{}{"foo", 123.0}, array.Raw())

func (*Array) Schema

func (a *Array) Schema(schema interface{}) *Array

Schema is similar to Value.Schema.

type AssertReporter

type AssertReporter struct {
	// contains filtered or unexported fields
}

AssertReporter implements Reporter interface using `testify/assert' package. Failures are non-fatal with this reporter.

func NewAssertReporter

func NewAssertReporter(t assert.TestingT) *AssertReporter

NewAssertReporter returns a new AssertReporter object.

func (*AssertReporter) Errorf

func (r *AssertReporter) Errorf(message string, args ...interface{})

Errorf implements Reporter.Errorf.

type Binder

type Binder struct {
	// HTTP handler invoked for every request.
	Handler http.Handler
	// TLS connection state used for https:// requests.
	TLS *tls.ConnectionState
}

Binder implements networkless http.RoundTripper attached directly to http.Handler.

Binder emulates network communication by invoking given http.Handler directly. It passes httptest.ResponseRecorder as http.ResponseWriter to the handler, and then constructs http.Response from recorded data.

func NewBinder

func NewBinder(handler http.Handler) Binder

NewBinder returns a new Binder given a http.Handler.

Example:

client := &http.Client{
    Transport: NewBinder(handler),
}

func (Binder) RoundTrip

func (binder Binder) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip implements http.RoundTripper.RoundTrip.

type Boolean

type Boolean struct {
	// contains filtered or unexported fields
}

Boolean provides methods to inspect attached bool value (Go representation of JSON boolean).

func NewBoolean

func NewBoolean(reporter Reporter, value bool) *Boolean

NewBoolean returns a new Boolean given a reporter used to report failures and value to be inspected.

reporter should not be nil.

Example:

boolean := NewBoolean(t, true)

func (*Boolean) Equal

func (b *Boolean) Equal(value bool) *Boolean

Equal succeeds if boolean is equal to given value.

Example:

boolean := NewBoolean(t, true)
boolean.Equal(true)

func (*Boolean) False

func (b *Boolean) False() *Boolean

False succeeds if boolean is false.

Example:

boolean := NewBoolean(t, false)
boolean.False()

func (*Boolean) NotEqual

func (b *Boolean) NotEqual(value bool) *Boolean

NotEqual succeeds if boolean is not equal to given value.

Example:

boolean := NewBoolean(t, true)
boolean.NotEqual(false)

func (*Boolean) Path

func (b *Boolean) Path(path string) *Value

Path is similar to Value.Path.

func (*Boolean) Raw

func (b *Boolean) Raw() bool

Raw returns underlying value attached to Boolean. This is the value originally passed to NewBoolean.

Example:

boolean := NewBoolean(t, true)
assert.Equal(t, true, boolean.Raw())

func (*Boolean) Schema

func (b *Boolean) Schema(schema interface{}) *Boolean

Schema is similar to Value.Schema.

func (*Boolean) True

func (b *Boolean) True() *Boolean

True succeeds if boolean is true.

Example:

boolean := NewBoolean(t, true)
boolean.True()

type Client

type Client interface {
	// Do sends request and returns response.
	Do(*http.Request) (*http.Response, error)
}

Client is used to send http.Request and receive http.Response. http.Client implements this interface.

Binder and FastBinder may be used to obtain this interface implementation.

Example:

httpBinderClient := &http.Client{
  Transport: httpexpect.NewBinder(HTTPHandler),
}
fastBinderClient := &http.Client{
  Transport: httpexpect.NewFastBinder(FastHTTPHandler),
}

type CompactPrinter

type CompactPrinter struct {
	// contains filtered or unexported fields
}

CompactPrinter implements Printer. It prints requests in compact form.

func NewCompactPrinter

func NewCompactPrinter(logger Logger) CompactPrinter

NewCompactPrinter returns a new CompactPrinter given a logger.

func (CompactPrinter) Request

func (p CompactPrinter) Request(req *http.Request)

Request implements Printer.Request.

func (CompactPrinter) Response

Response implements Printer.Response.

type Config

type Config struct {
	// BaseURL is a URL to prepended to all request. My be empty. If
	// non-empty, trailing slash is allowed but not required and is
	// appended automatically.
	BaseURL string

	// RequestFactory is used to pass in a custom *http.Request generation func.
	// May be nil.
	//
	// You can use DefaultRequestFactory, or provide custom implementation.
	// Useful for Google App Engine testing for example.
	RequestFactory RequestFactory

	// Client is used to send http.Request and receive http.Response.
	// Should not be nil.
	//
	// You can use http.DefaultClient or http.Client, or provide
	// custom implementation.
	Client Client

	// WebsocketDialer is used to establish websocket.Conn and receive
	// http.Response of handshake result.
	// Should not be nil.
	//
	// You can use websocket.DefaultDialer or websocket.Dialer, or provide
	// custom implementation.
	WebsocketDialer WebsocketDialer

	// Reporter is used to report failures.
	// Should not be nil.
	//
	// You can use AssertReporter, RequireReporter (they use testify),
	// or testing.TB, or provide custom implementation.
	Reporter Reporter

	// Printers are used to print requests and responses.
	// May be nil.
	//
	// You can use CompactPrinter, DebugPrinter, CurlPrinter, or provide
	// custom implementation.
	//
	// You can also use builtin printers with alternative Logger if
	// you're happy with their format, but want to send logs somewhere
	// else instead of testing.TB.
	Printers []Printer
}

Config contains various settings.

type ContentOpts

type ContentOpts struct {
	// The media type Content-Type part, e.g. "application/json"
	MediaType string
	// The character set Content-Type part, e.g. "utf-8"
	Charset string
}

ContentOpts define parameters for matching the response content parameters.

type Cookie struct {
	// contains filtered or unexported fields
}

Cookie provides methods to inspect attached http.Cookie value.

func NewCookie

func NewCookie(reporter Reporter, value *http.Cookie) *Cookie

NewCookie returns a new Cookie object given a reporter used to report failures and cookie value to be inspected.

reporter and value should not be nil.

Example:

cookie := NewCookie(reporter, &http.Cookie{...})
cookie.Domain().Equal("example.com")
cookie.Path().Equal("/")
cookie.Expires().InRange(time.Now(), time.Now().Add(time.Hour * 24))

func (*Cookie) Domain

func (c *Cookie) Domain() *String

Domain returns a new String object that may be used to inspect cookie domain.

Example:

cookie := NewCookie(t, &http.Cookie{...})
cookie.Domain().Equal("example.com")

func (*Cookie) Expires

func (c *Cookie) Expires() *DateTime

Expires returns a new DateTime object that may be used to inspect cookie expiration date.

Example:

cookie := NewCookie(t, &http.Cookie{...})
cookie.Expires().InRange(time.Now(), time.Now().Add(time.Hour * 24))

func (*Cookie) MaxAge added in v1.1.0

func (c *Cookie) MaxAge() *Duration

MaxAge returns a new Duration object that may be used to inspect cookie Max-age field.

If MaxAge is not set, the returned Duration is unset. Whether a Duration is set or not can be chacked using its IsSet and NotSet methods.

If MaxAge is zero (which means delete cookie now), the returned Duration is set and equals to zero.

Example:

cookie := NewCookie(t, &http.Cookie{...})
cookie.MaxAge().IsSet()
cookie.MaxAge().InRange(time.Minute, time.Minute*10)

func (*Cookie) Name

func (c *Cookie) Name() *String

Name returns a new String object that may be used to inspect cookie name.

Example:

cookie := NewCookie(t, &http.Cookie{...})
cookie.Name().Equal("session")

func (*Cookie) Path

func (c *Cookie) Path() *String

Path returns a new String object that may be used to inspect cookie path.

Example:

cookie := NewCookie(t, &http.Cookie{...})
cookie.Path().Equal("/foo")

func (*Cookie) Raw

func (c *Cookie) Raw() *http.Cookie

Raw returns underlying http.Cookie value attached to Cookie. This is the value originally passed to NewCookie.

Example:

cookie := NewCookie(t, c)
assert.Equal(t, c, cookie.Raw())

func (*Cookie) Value

func (c *Cookie) Value() *String

Value returns a new String object that may be used to inspect cookie value.

Example:

cookie := NewCookie(t, &http.Cookie{...})
cookie.Value().Equal("gH6z7Y")

type CurlPrinter

type CurlPrinter struct {
	// contains filtered or unexported fields
}

CurlPrinter implements Printer. Uses http2curl to dump requests as curl commands.

func NewCurlPrinter

func NewCurlPrinter(logger Logger) CurlPrinter

NewCurlPrinter returns a new CurlPrinter given a logger.

func (CurlPrinter) Request

func (p CurlPrinter) Request(req *http.Request)

Request implements Printer.Request.

func (CurlPrinter) Response

func (CurlPrinter) Response(*http.Response, time.Duration)

Response implements Printer.Response.

type DateTime

type DateTime struct {
	// contains filtered or unexported fields
}

DateTime provides methods to inspect attached time.Time value.

func NewDateTime

func NewDateTime(reporter Reporter, value time.Time) *DateTime

NewDateTime returns a new DateTime object given a reporter used to report failures and time.Time value to be inspected.

reporter should not be nil.

Example:

dt := NewDateTime(reporter, time.Now())
dt.Le(time.Now())

time.Sleep(time.Second)
dt.Lt(time.Now())

func (*DateTime) Equal

func (dt *DateTime) Equal(value time.Time) *DateTime

Equal succeeds if DateTime is equal to given value.

Example:

dt := NewDateTime(t, time.Unix(0, 1))
dt.Equal(time.Unix(0, 1))

func (*DateTime) Ge

func (dt *DateTime) Ge(value time.Time) *DateTime

Ge succeeds if DateTime is greater than or equal to given value.

Example:

dt := NewDateTime(t, time.Unix(0, 2))
dt.Ge(time.Unix(0, 1))

func (*DateTime) Gt

func (dt *DateTime) Gt(value time.Time) *DateTime

Gt succeeds if DateTime is greater than given value.

Example:

dt := NewDateTime(t, time.Unix(0, 2))
dt.Gt(time.Unix(0, 1))

func (*DateTime) InRange

func (dt *DateTime) InRange(min, max time.Time) *DateTime

InRange succeeds if DateTime is in given range [min; max].

Example:

dt := NewDateTime(t, time.Unix(0, 2))
dt.InRange(time.Unix(0, 1), time.Unix(0, 3))
dt.InRange(time.Unix(0, 2), time.Unix(0, 2))

func (*DateTime) Le

func (dt *DateTime) Le(value time.Time) *DateTime

Le succeeds if DateTime is lesser than or equal to given value.

Example:

dt := NewDateTime(t, time.Unix(0, 1))
dt.Le(time.Unix(0, 2))

func (*DateTime) Lt

func (dt *DateTime) Lt(value time.Time) *DateTime

Lt succeeds if DateTime is lesser than given value.

Example:

dt := NewDateTime(t, time.Unix(0, 1))
dt.Lt(time.Unix(0, 2))

func (*DateTime) NotEqual

func (dt *DateTime) NotEqual(value time.Time) *DateTime

NotEqual succeeds if DateTime is not equal to given value.

Example:

dt := NewDateTime(t, time.Unix(0, 1))
dt.NotEqual(time.Unix(0, 2))

func (*DateTime) Raw

func (dt *DateTime) Raw() time.Time

Raw returns underlying time.Time value attached to DateTime. This is the value originally passed to NewDateTime.

Example:

dt := NewDateTime(t, timestamp)
assert.Equal(t, timestamp, dt.Raw())

type DebugPrinter

type DebugPrinter struct {
	// contains filtered or unexported fields
}

DebugPrinter implements Printer. Uses net/http/httputil to dump both requests and responses.

func NewDebugPrinter

func NewDebugPrinter(logger Logger, body bool) DebugPrinter

NewDebugPrinter returns a new DebugPrinter given a logger and body flag. If body is true, request and response body is also printed.

func (DebugPrinter) Request

func (p DebugPrinter) Request(req *http.Request)

Request implements Printer.Request.

func (DebugPrinter) Response

func (p DebugPrinter) Response(resp *http.Response, duration time.Duration)

Response implements Printer.Response.

func (DebugPrinter) WebsocketRead

func (p DebugPrinter) WebsocketRead(typ int, content []byte, closeCode int)

WebsocketRead implements WebsocketPrinter.WebsocketRead.

func (DebugPrinter) WebsocketWrite

func (p DebugPrinter) WebsocketWrite(typ int, content []byte, closeCode int)

WebsocketWrite implements WebsocketPrinter.WebsocketWrite.

type DefaultRequestFactory

type DefaultRequestFactory struct{}

DefaultRequestFactory is the default RequestFactory implementation which just calls http.NewRequest.

func (DefaultRequestFactory) NewRequest

func (DefaultRequestFactory) NewRequest(
	method, urlStr string, body io.Reader) (*http.Request, error)

NewRequest implements RequestFactory.NewRequest.

type Duration added in v1.1.0

type Duration struct {
	// contains filtered or unexported fields
}

Duration provides methods to inspect attached time.Duration value.

func NewDuration added in v1.1.0

func NewDuration(reporter Reporter, value time.Duration) *Duration

NewDuration returns a new Duration object given a reporter used to report failures and time.Duration value to be inspected.

reporter should not be nil.

Example:

d := NewDuration(reporter, time.Second)
d.Le(time.Minute)

func (*Duration) Equal added in v1.1.0

func (d *Duration) Equal(value time.Duration) *Duration

Equal succeeds if Duration is equal to given value.

Example:

d := NewDuration(t, time.Second)
d.Equal(time.Second)

func (*Duration) Ge added in v1.1.0

func (d *Duration) Ge(value time.Duration) *Duration

Ge succeeds if Duration is greater than or equal to given value.

Example:

d := NewDuration(t, time.Minute)
d.Ge(time.Second)

func (*Duration) Gt added in v1.1.0

func (d *Duration) Gt(value time.Duration) *Duration

Gt succeeds if Duration is greater than given value.

Example:

d := NewDuration(t, time.Minute)
d.Gt(time.Second)

func (*Duration) InRange added in v1.1.0

func (d *Duration) InRange(min, max time.Duration) *Duration

InRange succeeds if Duration is in given range [min; max].

Example:

d := NewDuration(t, time.Minute)
d.InRange(time.Second, time.Hour)
d.InRange(time.Minute, time.Minute)

func (*Duration) IsSet added in v1.1.0

func (d *Duration) IsSet() *Duration

IsSet succeeds if Duration is set.

Example:

d := NewDuration(t, time.Second)
d.IsSet()

func (*Duration) Le added in v1.1.0

func (d *Duration) Le(value time.Duration) *Duration

Le succeeds if Duration is lesser than or equal to given value.

Example:

d := NewDuration(t, time.Second)
d.Le(time.Minute)

func (*Duration) Lt added in v1.1.0

func (d *Duration) Lt(value time.Duration) *Duration

Lt succeeds if Duration is lesser than given value.

Example:

d := NewDuration(t, time.Second)
d.Lt(time.Minute)

func (*Duration) NotEqual added in v1.1.0

func (d *Duration) NotEqual(value time.Duration) *Duration

NotEqual succeeds if Duration is not equal to given value.

Example:

d := NewDuration(t, time.Second)
d.NotEqual(time.Minute)

func (*Duration) NotSet added in v1.1.0

func (d *Duration) NotSet() *Duration

NotSet succeeds if Duration is not set.

func (*Duration) Raw added in v1.1.0

func (d *Duration) Raw() time.Duration

Raw returns underlying time.Duration value attached to Duration. This is the value originally passed to NewDuration.

Example:

d := NewDuration(t, duration)
assert.Equal(t, timestamp, d.Raw())

type Expect

type Expect struct {
	// contains filtered or unexported fields
}

Expect is a toplevel object that contains user Config and allows to construct Request objects.

func New

func New(t LoggerReporter, baseURL string) *Expect

New returns a new Expect object.

baseURL specifies URL to prepended to all request. My be empty. If non-empty, trailing slash is allowed but not required and is appended automatically.

New is a shorthand for WithConfig. It uses:

  • CompactPrinter as Printer, with testing.TB as Logger
  • AssertReporter as Reporter
  • DefaultRequestFactory as RequestFactory

Client is set to a default client with a non-nil Jar:

&http.Client{
    Jar: httpexpect.NewJar(),
}

Example:

func TestSomething(t *testing.T) {
    e := httpexpect.New(t, "http://example.com/")

    e.GET("/path").
        Expect().
        Status(http.StatusOK)
}

func WithConfig

func WithConfig(config Config) *Expect

WithConfig returns a new Expect object with given config.

Reporter should not be nil.

If RequestFactory is nil, it's set to a DefaultRequestFactory instance.

If Client is nil, it's set to a default client with a non-nil Jar:

&http.Client{
    Jar: httpexpect.NewJar(),
}

If WebsocketDialer is nil, it's set to a default dialer:

&websocket.Dialer{}

Example:

func TestSomething(t *testing.T) {
    e := httpexpect.WithConfig(httpexpect.Config{
        BaseURL:  "http://example.com/",
        Client:   &http.Client{
            Transport: httpexpect.NewBinder(myHandler()),
            Jar:       httpexpect.NewJar(),
        },
        Reporter: httpexpect.NewAssertReporter(t),
        Printers: []httpexpect.Printer{
            httpexpect.NewCurlPrinter(t),
            httpexpect.NewDebugPrinter(t, true)
        },
    })

    e.GET("/path").
        Expect().
        Status(http.StatusOK)
}

func (*Expect) Array

func (e *Expect) Array(value []interface{}) *Array

Array is a shorthand for NewArray(e.config.Reporter, value).

func (*Expect) Boolean

func (e *Expect) Boolean(value bool) *Boolean

Boolean is a shorthand for NewBoolean(e.config.Reporter, value).

func (*Expect) Builder

func (e *Expect) Builder(builder func(*Request)) *Expect

Builder returns a copy of Expect instance with given builder attached to it. Returned copy contains all previously attached builders plus a new one. Builders are invoked from Request method, after constructing every new request.

Example:

e := httpexpect.New(t, "http://example.com")

token := e.POST("/login").WithForm(Login{"ford", "betelgeuse7"}).
    Expect().
    Status(http.StatusOK).JSON().Object().Value("token").String().Raw()

auth := e.Builder(func (req *httpexpect.Request) {
    req.WithHeader("Authorization", "Bearer "+token)
})

auth.GET("/restricted").
   Expect().
   Status(http.StatusOK)

func (*Expect) DELETE

func (e *Expect) DELETE(path string, pathargs ...interface{}) *Request

DELETE is a shorthand for e.Request("DELETE", path, pathargs...).

func (*Expect) GET

func (e *Expect) GET(path string, pathargs ...interface{}) *Request

GET is a shorthand for e.Request("GET", path, pathargs...).

func (*Expect) HEAD

func (e *Expect) HEAD(path string, pathargs ...interface{}) *Request

HEAD is a shorthand for e.Request("HEAD", path, pathargs...).

func (*Expect) Matcher

func (e *Expect) Matcher(matcher func(*Response)) *Expect

Matcher returns a copy of Expect instance with given matcher attached to it. Returned copy contains all previously attached matchers plus a new one. Matchers are invoked from Request.Expect method, after retrieving a new response.

Example:

 e := httpexpect.New(t, "http://example.com")

 m := e.Matcher(func (resp *httpexpect.Response) {
     resp.Header("API-Version").NotEmpty()
 })

 m.GET("/some-path").
	    Expect().
	    Status(http.StatusOK)

 m.GET("/bad-path").
	    Expect().
	    Status(http.StatusNotFound)

func (*Expect) Number

func (e *Expect) Number(value float64) *Number

Number is a shorthand for NewNumber(e.config.Reporter, value).

func (*Expect) OPTIONS

func (e *Expect) OPTIONS(path string, pathargs ...interface{}) *Request

OPTIONS is a shorthand for e.Request("OPTIONS", path, pathargs...).

func (*Expect) Object

func (e *Expect) Object(value map[string]interface{}) *Object

Object is a shorthand for NewObject(e.config.Reporter, value).

func (*Expect) PATCH

func (e *Expect) PATCH(path string, pathargs ...interface{}) *Request

PATCH is a shorthand for e.Request("PATCH", path, pathargs...).

func (*Expect) POST

func (e *Expect) POST(path string, pathargs ...interface{}) *Request

POST is a shorthand for e.Request("POST", path, pathargs...).

func (*Expect) PUT

func (e *Expect) PUT(path string, pathargs ...interface{}) *Request

PUT is a shorthand for e.Request("PUT", path, pathargs...).

func (*Expect) Request

func (e *Expect) Request(method, path string, pathargs ...interface{}) *Request

Request returns a new Request object. Arguments a similar to NewRequest. After creating request, all builders attached to Expect object are invoked. See Builder.

func (*Expect) String

func (e *Expect) String(value string) *String

String is a shorthand for NewString(e.config.Reporter, value).

func (*Expect) Value

func (e *Expect) Value(value interface{}) *Value

Value is a shorthand for NewValue(e.config.Reporter, value).

type FastBinder

type FastBinder struct {
	// FastHTTP handler invoked for every request.
	Handler fasthttp.RequestHandler
	// TLS connection state used for https:// requests.
	TLS *tls.ConnectionState
}

FastBinder implements networkless http.RoundTripper attached directly to fasthttp.RequestHandler.

FastBinder emulates network communication by invoking given fasthttp.RequestHandler directly. It converts http.Request to fasthttp.Request, invokes handler, and then converts fasthttp.Response to http.Response.

func NewFastBinder

func NewFastBinder(handler fasthttp.RequestHandler) FastBinder

NewFastBinder returns a new FastBinder given a fasthttp.RequestHandler.

Example:

client := &http.Client{
    Transport: NewFastBinder(fasthandler),
}

func (FastBinder) RoundTrip

func (binder FastBinder) RoundTrip(stdreq *http.Request) (*http.Response, error)

RoundTrip implements http.RoundTripper.RoundTrip.

type Logger

type Logger interface {
	// Logf writes message to log.
	Logf(fmt string, args ...interface{})
}

Logger is used as output backend for Printer. testing.TB implements this interface.

type LoggerReporter

type LoggerReporter interface {
	Logger
	Reporter
}

LoggerReporter combines Logger and Reporter interfaces.

type Match

type Match struct {
	// contains filtered or unexported fields
}

Match provides methods to inspect attached regexp match results.

func NewMatch

func NewMatch(reporter Reporter, submatches []string, names []string) *Match

NewMatch returns a new Match object given a reporter used to report failures and submatches to be inspected.

reporter should not be nil. submatches and names may be nil.

Example:

s := "http://example.com/users/john"
r := regexp.MustCompile(`http://(?P<host>.+)/users/(?P<user>.+)`)
m := NewMatch(reporter, r.FindStringSubmatch(s), r.SubexpNames())

m.NotEmpty()
m.Length().Equal(3)

m.Index(0).Equal("http://example.com/users/john")
m.Index(1).Equal("example.com")
m.Index(2).Equal("john")

m.Name("host").Equal("example.com")
m.Name("user").Equal("john")

func (*Match) Empty

func (m *Match) Empty() *Match

Empty succeeds if submatches array is empty.

Example:

m := NewMatch(t, submatches, names)
m.Empty()

func (*Match) Index

func (m *Match) Index(index int) *String

Index returns a new String object that may be used to inspect submatch with given index.

Note that submatch with index 0 contains the whole match. If index is out of bounds, Index reports failure and returns empty (but non-nil) value.

Example:

s := "http://example.com/users/john"

r := regexp.MustCompile(`http://(.+)/users/(.+)`)
m := NewMatch(t, r.FindStringSubmatch(s), nil)

m.Index(0).Equal("http://example.com/users/john")
m.Index(1).Equal("example.com")
m.Index(2).Equal("john")

func (*Match) Length

func (m *Match) Length() *Number

Length returns a new Number object that may be used to inspect number of submatches.

Example:

m := NewMatch(t, submatches, names)
m.Length().Equal(len(submatches))

func (*Match) Name

func (m *Match) Name(name string) *String

Name returns a new String object that may be used to inspect submatch with given name.

If there is no submatch with given name, Name reports failure and returns empty (but non-nil) value.

Example:

s := "http://example.com/users/john"

r := regexp.MustCompile(`http://(?P<host>.+)/users/(?P<user>.+)`)
m := NewMatch(t, r.FindStringSubmatch(s), r.SubexpNames())

m.Name("host").Equal("example.com")
m.Name("user").Equal("john")

func (*Match) NotEmpty

func (m *Match) NotEmpty() *Match

NotEmpty succeeds if submatches array is non-empty.

Example:

m := NewMatch(t, submatches, names)
m.NotEmpty()

func (*Match) NotValues

func (m *Match) NotValues(values ...string) *Match

NotValues succeeds if submatches array, starting from index 1, is not equal to given array.

Note that submatch with index 0 contains the whole match and is not included into this check.

Example:

s := "http://example.com/users/john"
r := regexp.MustCompile(`http://(.+)/users/(.+)`)
m := NewMatch(t, r.FindStringSubmatch(s), nil)
m.NotValues("example.com", "bob")

func (*Match) Raw

func (m *Match) Raw() []string

Raw returns underlying submatches attached to Match. This is the value originally passed to NewMatch.

Example:

m := NewMatch(t, submatches, names)
assert.Equal(t, submatches, m.Raw())

func (*Match) Values

func (m *Match) Values(values ...string) *Match

Values succeeds if submatches array, starting from index 1, is equal to given array.

Note that submatch with index 0 contains the whole match and is not included into this check.

Example:

s := "http://example.com/users/john"
r := regexp.MustCompile(`http://(.+)/users/(.+)`)
m := NewMatch(t, r.FindStringSubmatch(s), nil)
m.Values("example.com", "john")

type Number

type Number struct {
	// contains filtered or unexported fields
}

Number provides methods to inspect attached float64 value (Go representation of JSON number).

func NewNumber

func NewNumber(reporter Reporter, value float64) *Number

NewNumber returns a new Number given a reporter used to report failures and value to be inspected.

reporter should not be nil.

Example:

number := NewNumber(t, 123.4)

func (*Number) Equal

func (n *Number) Equal(value interface{}) *Number

Equal succeeds if number is equal to given value.

value should have numeric type convertible to float64. Before comparison, it is converted to float64.

Example:

number := NewNumber(t, 123)
number.Equal(float64(123))
number.Equal(int32(123))

func (*Number) EqualDelta

func (n *Number) EqualDelta(value, delta float64) *Number

EqualDelta succeeds if two numerals are within delta of each other.

Example:

number := NewNumber(t, 123.0)
number.EqualDelta(123.2, 0.3)

func (*Number) Ge

func (n *Number) Ge(value interface{}) *Number

Ge succeeds if number is greater than or equal to given value.

value should have numeric type convertible to float64. Before comparison, it is converted to float64.

Example:

number := NewNumber(t, 123)
number.Ge(float64(122))
number.Ge(int32(122))

func (*Number) Gt

func (n *Number) Gt(value interface{}) *Number

Gt succeeds if number is greater than given value.

value should have numeric type convertible to float64. Before comparison, it is converted to float64.

Example:

number := NewNumber(t, 123)
number.Gt(float64(122))
number.Gt(int32(122))

func (*Number) InRange

func (n *Number) InRange(min, max interface{}) *Number

InRange succeeds if number is in given range [min; max].

min and max should have numeric type convertible to float64. Before comparison, they are converted to float64.

Example:

number := NewNumber(t, 123)
number.InRange(float32(100), int32(200))  // success
number.InRange(100, 200)                  // success
number.InRange(123, 123)                  // success

func (*Number) Le

func (n *Number) Le(value interface{}) *Number

Le succeeds if number is lesser than or equal to given value.

value should have numeric type convertible to float64. Before comparison, it is converted to float64.

Example:

number := NewNumber(t, 123)
number.Le(float64(124))
number.Le(int32(124))

func (*Number) Lt

func (n *Number) Lt(value interface{}) *Number

Lt succeeds if number is lesser than given value.

value should have numeric type convertible to float64. Before comparison, it is converted to float64.

Example:

number := NewNumber(t, 123)
number.Lt(float64(124))
number.Lt(int32(124))

func (*Number) NotEqual

func (n *Number) NotEqual(value interface{}) *Number

NotEqual succeeds if number is not equal to given value.

value should have numeric type convertible to float64. Before comparison, it is converted to float64.

Example:

number := NewNumber(t, 123)
number.NotEqual(float64(321))
number.NotEqual(int32(321))

func (*Number) NotEqualDelta

func (n *Number) NotEqualDelta(value, delta float64) *Number

NotEqualDelta succeeds if two numerals are not within delta of each other.

Example:

number := NewNumber(t, 123.0)
number.NotEqualDelta(123.2, 0.1)

func (*Number) Path

func (n *Number) Path(path string) *Value

Path is similar to Value.Path.

func (*Number) Raw

func (n *Number) Raw() float64

Raw returns underlying value attached to Number. This is the value originally passed to NewNumber.

Example:

number := NewNumber(t, 123.4)
assert.Equal(t, 123.4, number.Raw())

func (*Number) Schema

func (n *Number) Schema(schema interface{}) *Number

Schema is similar to Value.Schema.

type Object

type Object struct {
	// contains filtered or unexported fields
}

Object provides methods to inspect attached map[string]interface{} object (Go representation of JSON object).

func NewObject

func NewObject(reporter Reporter, value map[string]interface{}) *Object

NewObject returns a new Object given a reporter used to report failures and value to be inspected.

Both reporter and value should not be nil. If value is nil, failure is reported.

Example:

object := NewObject(t, map[string]interface{}{"foo": 123})

func (*Object) ContainsKey

func (o *Object) ContainsKey(key string) *Object

ContainsKey succeeds if object contains given key.

Example:

object := NewObject(t, map[string]interface{}{"foo": 123})
object.ContainsKey("foo")

func (*Object) ContainsMap

func (o *Object) ContainsMap(value interface{}) *Object

ContainsMap succeeds if object contains given Go value. Before comparison, both object and value are converted to canonical form.

value should be map[string]interface{} or struct.

Example:

object := NewObject(t, map[string]interface{}{
    "foo": 123,
    "bar": []interface{}{"x", "y"},
    "bar": map[string]interface{}{
        "a": true,
        "b": false,
    },
})

object.ContainsMap(map[string]interface{}{  // success
    "foo": 123,
    "bar": map[string]interface{}{
        "a": true,
    },
})

object.ContainsMap(map[string]interface{}{  // failure
    "foo": 123,
    "qux": 456,
})

object.ContainsMap(map[string]interface{}{  // failure, slices should match exactly
    "bar": []interface{}{"x"},
})

func (*Object) Empty

func (o *Object) Empty() *Object

Empty succeeds if object is empty.

Example:

object := NewObject(t, map[string]interface{}{})
object.Empty()

func (*Object) Equal

func (o *Object) Equal(value interface{}) *Object

Equal succeeds if object is equal to given Go map or struct. Before comparison, both object and value are converted to canonical form.

value should be map[string]interface{} or struct.

Example:

object := NewObject(t, map[string]interface{}{"foo": 123})
object.Equal(map[string]interface{}{"foo": 123})

func (*Object) Keys

func (o *Object) Keys() *Array

Keys returns a new Array object that may be used to inspect objects keys.

Example:

object := NewObject(t, map[string]interface{}{"foo": 123, "bar": 456})
object.Keys().ContainsOnly("foo", "bar")

func (*Object) NotContainsKey

func (o *Object) NotContainsKey(key string) *Object

NotContainsKey succeeds if object doesn't contain given key.

Example:

object := NewObject(t, map[string]interface{}{"foo": 123})
object.NotContainsKey("bar")

func (*Object) NotContainsMap

func (o *Object) NotContainsMap(value interface{}) *Object

NotContainsMap succeeds if object doesn't contain given Go value. Before comparison, both object and value are converted to canonical form.

value should be map[string]interface{} or struct.

Example:

object := NewObject(t, map[string]interface{}{"foo": 123, "bar": 456})
object.NotContainsMap(map[string]interface{}{"foo": 123, "bar": "no-no-no"})

func (*Object) NotEmpty

func (o *Object) NotEmpty() *Object

NotEmpty succeeds if object is non-empty.

Example:

object := NewObject(t, map[string]interface{}{"foo": 123})
object.NotEmpty()

func (*Object) NotEqual

func (o *Object) NotEqual(v interface{}) *Object

NotEqual succeeds if object is not equal to given Go map or struct. Before comparison, both object and value are converted to canonical form.

value should be map[string]interface{} or struct.

Example:

object := NewObject(t, map[string]interface{}{"foo": 123})
object.Equal(map[string]interface{}{"bar": 123})

func (*Object) Path

func (o *Object) Path(path string) *Value

Path is similar to Value.Path.

func (*Object) Raw

func (o *Object) Raw() map[string]interface{}

Raw returns underlying value attached to Object. This is the value originally passed to NewObject, converted to canonical form.

Example:

object := NewObject(t, map[string]interface{}{"foo": 123})
assert.Equal(t, map[string]interface{}{"foo": 123.0}, object.Raw())

func (*Object) Schema

func (o *Object) Schema(schema interface{}) *Object

Schema is similar to Value.Schema.

func (*Object) Value

func (o *Object) Value(key string) *Value

Value returns a new Value object that may be used to inspect single value for given key.

Example:

object := NewObject(t, map[string]interface{}{"foo": 123})
object.Value("foo").Number().Equal(123)

func (*Object) ValueEqual

func (o *Object) ValueEqual(key string, value interface{}) *Object

ValueEqual succeeds if object's value for given key is equal to given Go value. Before comparison, both values are converted to canonical form.

value should be map[string]interface{} or struct.

Example:

object := NewObject(t, map[string]interface{}{"foo": 123})
object.ValueEqual("foo", 123)

func (*Object) ValueNotEqual

func (o *Object) ValueNotEqual(key string, value interface{}) *Object

ValueNotEqual succeeds if object's value for given key is not equal to given Go value. Before comparison, both values are converted to canonical form.

value should be map[string]interface{} or struct.

If object doesn't contain any value for given key, failure is reported.

Example:

object := NewObject(t, map[string]interface{}{"foo": 123})
object.ValueNotEqual("foo", "bad value")  // success
object.ValueNotEqual("bar", "bad value")  // failure! (key is missing)

func (*Object) Values

func (o *Object) Values() *Array

Values returns a new Array object that may be used to inspect objects values.

Example:

object := NewObject(t, map[string]interface{}{"foo": 123, "bar": 456})
object.Values().ContainsOnly(123, 456)

type Printer

type Printer interface {
	// Request is called before request is sent.
	Request(*http.Request)

	// Response is called after response is received.
	Response(*http.Response, time.Duration)
}

Printer is used to print requests and responses. CompactPrinter, DebugPrinter, and CurlPrinter implement this interface.

type Reporter

type Reporter interface {
	// Errorf reports failure.
	// Allowed to return normally or terminate test using t.FailNow().
	Errorf(message string, args ...interface{})
}

Reporter is used to report failures. testing.TB, AssertReporter, and RequireReporter implement this interface.

type Request

type Request struct {
	// contains filtered or unexported fields
}

Request provides methods to incrementally build http.Request object, send it, and receive response.

func NewRequest

func NewRequest(config Config, method, path string, pathargs ...interface{}) *Request

NewRequest returns a new Request object.

method defines the HTTP method (GET, POST, PUT, etc.). path defines url path.

Simple interpolation is allowed for {named} parameters in path:

  • if pathargs is given, it's used to substitute first len(pathargs) parameters, regardless of their names
  • if WithPath() or WithPathObject() is called, it's used to substitute given parameters by name

For example:

req := NewRequest(config, "POST", "/repos/{user}/{repo}", "gavv", "httpexpect")
// path will be "/repos/gavv/httpexpect"

Or:

req := NewRequest(config, "POST", "/repos/{user}/{repo}")
req.WithPath("user", "gavv")
req.WithPath("repo", "httpexpect")
// path will be "/repos/gavv/httpexpect"

After interpolation, path is urlencoded and appended to Config.BaseURL, separated by slash. If BaseURL ends with a slash and path (after interpolation) starts with a slash, only single slash is inserted.

func (*Request) Expect

func (r *Request) Expect() *Response

Expect constructs http.Request, sends it, receives http.Response, and returns a new Response object to inspect received response.

Request is sent using Config.Client interface, or Config.Dialer interface in case of WebSocket request.

Example:

req := NewRequest(config, "PUT", "http://example.com/path")
req.WithJSON(map[string]interface{}{"foo": 123})
resp := req.Expect()
resp.Status(http.StatusOK)

func (*Request) WithBasicAuth

func (r *Request) WithBasicAuth(username, password string) *Request

WithBasicAuth sets the request's Authorization header to use HTTP Basic Authentication with the provided username and password.

With HTTP Basic Authentication the provided username and password are not encrypted.

Example:

req := NewRequest(config, "PUT", "http://example.com/path")
req.WithBasicAuth("john", "secret")

func (*Request) WithBytes

func (r *Request) WithBytes(b []byte) *Request

WithBytes sets request body to given slice of bytes.

Example:

req := NewRequest(config, "PUT", "http://example.com/path")
req.WithHeader("Content-Type": "application/json")
req.WithBytes([]byte(`{"foo": 123}`))

func (*Request) WithChunked

func (r *Request) WithChunked(reader io.Reader) *Request

WithChunked enables chunked encoding and sets request body reader.

Expect() will read all available data from given reader. Content-Length is not set, and "chunked" Transfer-Encoding is used.

If protocol version is not at least HTTP/1.1 (required for chunked encoding), failure is reported.

Example:

req := NewRequest(config, "PUT", "http://example.com/upload")
fh, _ := os.Open("data")
defer fh.Close()
req.WithHeader("Content-Type": "application/octet-stream")
req.WithChunked(fh)

func (*Request) WithClient

func (r *Request) WithClient(client Client) *Request

WithClient sets client.

The new client overwrites Config.Client. It will be used once to send the request and receive a response.

Example:

req := NewRequest(config, "GET", "/path")
req.WithClient(&http.Client{
  Transport: &http.Transport{
    DisableCompression: true,
  },
})

func (*Request) WithCookie

func (r *Request) WithCookie(k, v string) *Request

WithCookie adds given single cookie to request.

Example:

req := NewRequest(config, "PUT", "http://example.com/path")
req.WithCookie("name", "value")

func (*Request) WithCookies

func (r *Request) WithCookies(cookies map[string]string) *Request

WithCookies adds given cookies to request.

Example:

req := NewRequest(config, "PUT", "http://example.com/path")
req.WithCookies(map[string]string{
    "foo": "aa",
    "bar": "bb",
})

func (*Request) WithFile

func (r *Request) WithFile(key, path string, reader ...io.Reader) *Request

WithFile sets Content-Type header to "multipart/form-data", reads given file and adds its contents to request body.

If reader is given, it's used to read file contents. Otherwise, os.Open() is used to read a file with given path.

Multiple WithForm(), WithFormField(), and WithFile() calls may be combined. WithMultipart() should be called before WithFile(), otherwise WithFile() fails.

Example:

req := NewRequest(config, "PUT", "http://example.com/path")
req.WithFile("avatar", "./john.png")

req := NewRequest(config, "PUT", "http://example.com/path")
fh, _ := os.Open("./john.png")
req.WithMultipart().
    WithFile("avatar", "john.png", fh)
fh.Close()

func (*Request) WithFileBytes

func (r *Request) WithFileBytes(key, path string, data []byte) *Request

WithFileBytes is like WithFile, but uses given slice of bytes as the file contents.

Example:

req := NewRequest(config, "PUT", "http://example.com/path")
fh, _ := os.Open("./john.png")
b, _ := ioutil.ReadAll(fh)
req.WithMultipart().
    WithFileBytes("avatar", "john.png", b)
fh.Close()

func (*Request) WithForm

func (r *Request) WithForm(object interface{}) *Request

WithForm sets Content-Type header to "application/x-www-form-urlencoded" or (if WithMultipart() was called) "multipart/form-data", converts given object to url.Values using github.com/ajg/form, and adds it to request body.

Various object types are supported, including maps and structs. Structs may contain "form" struct tag, similar to "json" struct tag for json.Marshal(). See https://github.com/ajg/form for details.

Multiple WithForm(), WithFormField(), and WithFile() calls may be combined. If WithMultipart() is called, it should be called first.

Example:

type MyForm struct {
    Foo int `form:"foo"`
}

req := NewRequest(config, "PUT", "http://example.com/path")
req.WithForm(MyForm{Foo: 123})

req := NewRequest(config, "PUT", "http://example.com/path")
req.WithForm(map[string]interface{}{"foo": 123})

func (*Request) WithFormField

func (r *Request) WithFormField(key string, value interface{}) *Request

WithFormField sets Content-Type header to "application/x-www-form-urlencoded" or (if WithMultipart() was called) "multipart/form-data", converts given value to string using fmt.Sprint(), and adds it to request body.

Multiple WithForm(), WithFormField(), and WithFile() calls may be combined. If WithMultipart() is called, it should be called first.

Example:

req := NewRequest(config, "PUT", "http://example.com/path")
req.WithFormField("foo", 123).
    WithFormField("bar", 456)

func (*Request) WithHandler

func (r *Request) WithHandler(handler http.Handler) *Request

WithHandler configures client to invoke the given handler directly.

If Config.Client is http.Client, then only its Transport field is overwritten because the client may contain some state shared among requests like a cookie jar. Otherwise, the whole client is overwritten with a new client.

Example:

req := NewRequest(config, "GET", "/path")
req.WithHandler(myServer.someHandler)

func (*Request) WithHeader

func (r *Request) WithHeader(k, v string) *Request

WithHeader adds given single header to request.

Example:

req := NewRequest(config, "PUT", "http://example.com/path")
req.WithHeader("Content-Type": "application/json")

func (*Request) WithHeaders

func (r *Request) WithHeaders(headers map[string]string) *Request

WithHeaders adds given headers to request.

Example:

req := NewRequest(config, "PUT", "http://example.com/path")
req.WithHeaders(map[string]string{
    "Content-Type": "application/json",
})

func (*Request) WithJSON

func (r *Request) WithJSON(object interface{}) *Request

WithJSON sets Content-Type header to "application/json; charset=utf-8" and sets body to object, marshaled using json.Marshal().

Example:

type MyJSON struct {
    Foo int `json:"foo"`
}

req := NewRequest(config, "PUT", "http://example.com/path")
req.WithJSON(MyJSON{Foo: 123})

req := NewRequest(config, "PUT", "http://example.com/path")
req.WithJSON(map[string]interface{}{"foo": 123})

func (*Request) WithMatcher

func (r *Request) WithMatcher(matcher func(*Response)) *Request

WithMatcher attaches a matcher to the request. All attached matchers are invoked in the Expect method for a newly created Response.

Example:

req := NewRequest(config, "GET", "/path")
req.WithMatcher(func (resp *httpexpect.Response) {
    resp.Header("API-Version").NotEmpty()
})

func (*Request) WithMultipart

func (r *Request) WithMultipart() *Request

WithMultipart sets Content-Type header to "multipart/form-data".

After this call, WithForm() and WithFormField() switch to multipart form instead of urlencoded form.

If WithMultipart() is called, it should be called before WithForm(), WithFormField(), and WithFile().

WithFile() always requires WithMultipart() to be called first.

Example:

req := NewRequest(config, "PUT", "http://example.com/path")
req.WithMultipart().
    WithForm(map[string]interface{}{"foo": 123})

func (*Request) WithPath

func (r *Request) WithPath(key string, value interface{}) *Request

WithPath substitutes named parameters in url path.

value is converted to string using fmt.Sprint(). If there is no named parameter '{key}' in url path, failure is reported.

Named parameters are case-insensitive.

Example:

req := NewRequest(config, "POST", "/repos/{user}/{repo}")
req.WithPath("user", "gavv")
req.WithPath("repo", "httpexpect")
// path will be "/repos/gavv/httpexpect"

func (*Request) WithPathObject

func (r *Request) WithPathObject(object interface{}) *Request

WithPathObject substitutes multiple named parameters in url path.

object should be map or struct. If object is struct, it's converted to map using https://github.com/fatih/structs. Structs may contain "path" struct tag, similar to "json" struct tag for json.Marshal().

Each map value is converted to string using fmt.Sprint(). If there is no named parameter for some map '{key}' in url path, failure is reported.

Named parameters are case-insensitive.

Example:

type MyPath struct {
    Login string `path:"user"`
    Repo  string
}

req := NewRequest(config, "POST", "/repos/{user}/{repo}")
req.WithPathObject(MyPath{"gavv", "httpexpect"})
// path will be "/repos/gavv/httpexpect"

req := NewRequest(config, "POST", "/repos/{user}/{repo}")
req.WithPathObject(map[string]string{"user": "gavv", "repo": "httpexpect"})
// path will be "/repos/gavv/httpexpect"

func (*Request) WithProto

func (r *Request) WithProto(proto string) *Request

WithProto sets HTTP protocol version.

proto should have form of "HTTP/{major}.{minor}", e.g. "HTTP/1.1".

Example:

req := NewRequest(config, "PUT", "http://example.com/path")
req.WithProto("HTTP/2.0")

func (*Request) WithQuery

func (r *Request) WithQuery(key string, value interface{}) *Request

WithQuery adds query parameter to request URL.

value is converted to string using fmt.Sprint() and urlencoded.

Example:

req := NewRequest(config, "PUT", "http://example.com/path")
req.WithQuery("a", 123)
req.WithQuery("b", "foo")
// URL is now http://example.com/path?a=123&b=foo

func (*Request) WithQueryObject

func (r *Request) WithQueryObject(object interface{}) *Request

WithQueryObject adds multiple query parameters to request URL.

object is converted to query string using github.com/google/go-querystring if it's a struct or pointer to struct, or github.com/ajg/form otherwise.

Various object types are supported. Structs may contain "url" struct tag, similar to "json" struct tag for json.Marshal().

Example:

type MyURL struct {
    A int    `url:"a"`
    B string `url:"b"`
}

req := NewRequest(config, "PUT", "http://example.com/path")
req.WithQueryObject(MyURL{A: 123, B: "foo"})
// URL is now http://example.com/path?a=123&b=foo

req := NewRequest(config, "PUT", "http://example.com/path")
req.WithQueryObject(map[string]interface{}{"a": 123, "b": "foo"})
// URL is now http://example.com/path?a=123&b=foo

func (*Request) WithQueryString

func (r *Request) WithQueryString(query string) *Request

WithQueryString parses given query string and adds it to request URL.

Example:

req := NewRequest(config, "PUT", "http://example.com/path")
req.WithQuery("a", 11)
req.WithQueryString("b=22&c=33")
// URL is now http://example.com/path?a=11&bb=22&c=33

func (*Request) WithText

func (r *Request) WithText(s string) *Request

WithText sets Content-Type header to "text/plain; charset=utf-8" and sets body to given string.

Example:

req := NewRequest(config, "PUT", "http://example.com/path")
req.WithText("hello, world!")

func (*Request) WithURL

func (r *Request) WithURL(urlStr string) *Request

WithURL sets request URL.

This URL overwrites Config.BaseURL. Request path passed to NewRequest() is appended to this URL, separated by slash if necessary.

Example:

req := NewRequest(config, "PUT", "/path")
req.WithURL("http://example.com")
// URL is now http://example.com/path

func (*Request) WithWebsocketDialer

func (r *Request) WithWebsocketDialer(dialer WebsocketDialer) *Request

WithWebsocketDialer sets the custom websocket dialer.

The new dialer overwrites Config.WebsocketDialer. It will be used once to establish the WebSocket connection and receive a response of handshake result.

Example:

req := NewRequest(config, "GET", "/path")
req.WithWebsocketUpgrade()
req.WithWebsocketDialer(&websocket.Dialer{
  EnableCompression: false,
})
ws := req.Expect().Status(http.StatusSwitchingProtocols).Websocket()
defer ws.Disconnect()

func (*Request) WithWebsocketUpgrade

func (r *Request) WithWebsocketUpgrade() *Request

WithWebsocketUpgrade enables upgrades the connection to websocket.

At least the following fields are added to the request header:

Upgrade: websocket
Connection: Upgrade

The actual set of header fields is define by the protocol implementation in the gorilla/websocket package.

The user should then call the Response.Websocket() method which returns the Websocket object. This object can be used to send messages to the server, to inspect the received messages, and to close the websocket.

Example:

req := NewRequest(config, "GET", "/path")
req.WithWebsocketUpgrade()
ws := req.Expect().Status(http.StatusSwitchingProtocols).Websocket()
defer ws.Disconnect()

type RequestFactory

type RequestFactory interface {
	NewRequest(method, urlStr string, body io.Reader) (*http.Request, error)
}

RequestFactory is used to create all http.Request objects. aetest.Instance from the Google App Engine implements this interface.

type RequireReporter

type RequireReporter struct {
	// contains filtered or unexported fields
}

RequireReporter implements Reporter interface using `testify/require' package. Failures fatal with this reporter.

func NewRequireReporter

func NewRequireReporter(t require.TestingT) *RequireReporter

NewRequireReporter returns a new RequireReporter object.

func (*RequireReporter) Errorf

func (r *RequireReporter) Errorf(message string, args ...interface{})

Errorf implements Reporter.Errorf.

type Response

type Response struct {
	// contains filtered or unexported fields
}

Response provides methods to inspect attached http.Response object.

func NewResponse

func NewResponse(
	reporter Reporter, response *http.Response, rtt ...time.Duration,
) *Response

NewResponse returns a new Response given a reporter used to report failures and http.Response to be inspected.

Both reporter and response should not be nil. If response is nil, failure is reported.

If rtt is given, it defines response round-trip time to be reported by response.RoundTripTime().

func (*Response) Body

func (r *Response) Body() *String

Body returns a new String object that may be used to inspect response body.

Example:

resp := NewResponse(t, response)
resp.Body().NotEmpty()
resp.Body().Length().Equal(100)

func (*Response) ContentEncoding

func (r *Response) ContentEncoding(encoding ...string) *Response

ContentEncoding succeeds if response has exactly given Content-Encoding list. Common values are empty, "gzip", "compress", "deflate", "identity" and "br".

func (*Response) ContentType

func (r *Response) ContentType(mediaType string, charset ...string) *Response

ContentType succeeds if response contains Content-Type header with given media type and charset.

If charset is omitted, and mediaType is non-empty, Content-Type header should contain empty or utf-8 charset.

If charset is omitted, and mediaType is also empty, Content-Type header should contain no charset.

func (*Response) Cookie

func (r *Response) Cookie(name string) *Cookie

Cookie returns a new Cookie object that may be used to inspect given cookie set by this response.

Note that this returns only cookies set by Set-Cookie headers of this response. It doesn't return session cookies from previous responses, which may be stored in a cookie jar.

Example:

resp := NewResponse(t, response)
resp.Cookie("session").Domain().Equal("example.com")

func (*Response) Cookies

func (r *Response) Cookies() *Array

Cookies returns a new Array object with all cookie names set by this response. Returned Array contains a String value for every cookie name.

Note that this returns only cookies set by Set-Cookie headers of this response. It doesn't return session cookies from previous responses, which may be stored in a cookie jar.

Example:

resp := NewResponse(t, response)
resp.Cookies().Contains("session")

func (*Response) Duration deprecated

func (r *Response) Duration() *Number

Deprecated: use RoundTripTime instead.

func (*Response) Form

func (r *Response) Form(opts ...ContentOpts) *Object

Form returns a new Object that may be used to inspect form contents of response.

Form succeeds if response contains "application/x-www-form-urlencoded" Content-Type header and if form may be decoded from response body. Decoding is performed using https://github.com/ajg/form.

Example:

resp := NewResponse(t, response)
resp.Form().Value("foo").Equal("bar")
resp.Form(ContentOpts{
  MediaType: "application/x-www-form-urlencoded",
}).Value("foo").Equal("bar")

func (*Response) Header

func (r *Response) Header(header string) *String

Header returns a new String object that may be used to inspect given header.

Example:

resp := NewResponse(t, response)
resp.Header("Content-Type").Equal("application-json")
resp.Header("Date").DateTime().Le(time.Now())

func (*Response) Headers

func (r *Response) Headers() *Object

Headers returns a new Object that may be used to inspect header map.

Example:

resp := NewResponse(t, response)
resp.Headers().Value("Content-Type").String().Equal("application-json")

func (*Response) JSON

func (r *Response) JSON(opts ...ContentOpts) *Value

JSON returns a new Value object that may be used to inspect JSON contents of response.

JSON succeeds if response contains "application/json" Content-Type header with empty or "utf-8" charset and if JSON may be decoded from response body.

Example:

resp := NewResponse(t, response)
resp.JSON().Array().Elements("foo", "bar")
resp.JSON(ContentOpts{
  MediaType: "application/json",
}).Array.Elements("foo", "bar")

func (*Response) JSONP

func (r *Response) JSONP(callback string, opts ...ContentOpts) *Value

JSONP returns a new Value object that may be used to inspect JSONP contents of response.

JSONP succeeds if response contains "application/javascript" Content-Type header with empty or "utf-8" charset and response body of the following form:

callback(<valid json>);

or:

callback(<valid json>)

Whitespaces are allowed.

Example:

resp := NewResponse(t, response)
resp.JSONP("myCallback").Array().Elements("foo", "bar")
resp.JSONP("myCallback", ContentOpts{
  MediaType: "application/javascript",
}).Array.Elements("foo", "bar")

func (*Response) NoContent

func (r *Response) NoContent() *Response

NoContent succeeds if response contains empty Content-Type header and empty body.

func (*Response) Raw

func (r *Response) Raw() *http.Response

Raw returns underlying http.Response object. This is the value originally passed to NewResponse.

func (*Response) RoundTripTime added in v1.1.0

func (r *Response) RoundTripTime() *Duration

RoundTripTime returns a new Duration object that may be used to inspect the round-trip time.

The returned duration is a time interval starting just before request is sent and ending right after response is received (handshake finished for WebSocket request), retrieved from a monotonic clock source.

Example:

resp := NewResponse(t, response, time.Duration(10000000))
resp.RoundTripTime().Lt(10 * time.Millisecond)

func (*Response) Status

func (r *Response) Status(status int) *Response

Status succeeds if response contains given status code.

Example:

resp := NewResponse(t, response)
resp.Status(http.StatusOK)

func (*Response) StatusRange

func (r *Response) StatusRange(rn StatusRange) *Response

StatusRange succeeds if response status belongs to given range.

Supported ranges:

  • Status1xx - Informational
  • Status2xx - Success
  • Status3xx - Redirection
  • Status4xx - Client Error
  • Status5xx - Server Error

See https://en.wikipedia.org/wiki/List_of_HTTP_status_codes.

Example:

resp := NewResponse(t, response)
resp.StatusRange(Status2xx)

func (*Response) Text

func (r *Response) Text(opts ...ContentOpts) *String

Text returns a new String object that may be used to inspect response body.

Text succeeds if response contains "text/plain" Content-Type header with empty or "utf-8" charset.

Example:

resp := NewResponse(t, response)
resp.Text().Equal("hello, world!")
resp.Text(ContentOpts{
  MediaType: "text/plain",
}).Equal("hello, world!")

func (*Response) TransferEncoding

func (r *Response) TransferEncoding(encoding ...string) *Response

TransferEncoding succeeds if response contains given Transfer-Encoding list. Common values are empty, "chunked" and "identity".

func (*Response) Websocket

func (r *Response) Websocket() *Websocket

Websocket returns Websocket object that can be used to interact with WebSocket server.

May be called only if the WithWebsocketUpgrade was called on the request. That is responsibility of the caller to explicitly close the websocket after use.

Example:

req := NewRequest(config, "GET", "/path")
req.WithWebsocketUpgrade()
ws := req.Expect().Websocket()
defer ws.Disconnect()

type StatusRange

type StatusRange int

StatusRange is enum for response status ranges.

const (
	// Status1xx defines "Informational" status codes.
	Status1xx StatusRange = 100

	// Status2xx defines "Success" status codes.
	Status2xx StatusRange = 200

	// Status3xx defines "Redirection" status codes.
	Status3xx StatusRange = 300

	// Status4xx defines "Client Error" status codes.
	Status4xx StatusRange = 400

	// Status5xx defines "Server Error" status codes.
	Status5xx StatusRange = 500
)

type String

type String struct {
	// contains filtered or unexported fields
}

String provides methods to inspect attached string value (Go representation of JSON string).

func NewString

func NewString(reporter Reporter, value string) *String

NewString returns a new String given a reporter used to report failures and value to be inspected.

reporter should not be nil.

Example:

str := NewString(t, "Hello")

func (*String) Contains

func (s *String) Contains(value string) *String

Contains succeeds if string contains given Go string as a substring.

Example:

str := NewString(t, "Hello")
str.Contains("ell")

func (*String) ContainsFold

func (s *String) ContainsFold(value string) *String

ContainsFold succeeds if string contains given Go string as a substring after applying Unicode case-folding (so it's a case-insensitive match).

Example:

str := NewString(t, "Hello")
str.ContainsFold("ELL")

func (*String) DateTime

func (s *String) DateTime(layout ...string) *DateTime

DateTime parses date/time from string an returns a new DateTime object.

If layout is given, DateTime() uses time.Parse() with given layout. Otherwise, it uses http.ParseTime(). If pasing error occurred, DateTime reports failure and returns empty (but non-nil) object.

Example:

str := NewString(t, "Tue, 15 Nov 1994 08:12:31 GMT")
str.DateTime().Lt(time.Now())

str := NewString(t, "15 Nov 94 08:12 GMT")
str.DateTime(time.RFC822).Lt(time.Now())

func (*String) Empty

func (s *String) Empty() *String

Empty succeeds if string is empty.

Example:

str := NewString(t, "")
str.Empty()

func (*String) Equal

func (s *String) Equal(value string) *String

Equal succeeds if string is equal to given Go string.

Example:

str := NewString(t, "Hello")
str.Equal("Hello")

func (*String) EqualFold

func (s *String) EqualFold(value string) *String

EqualFold succeeds if string is equal to given Go string after applying Unicode case-folding (so it's a case-insensitive match).

Example:

str := NewString(t, "Hello")
str.EqualFold("hELLo")

func (*String) Length

func (s *String) Length() *Number

Length returns a new Number object that may be used to inspect string length.

Example:

str := NewString(t, "Hello")
str.Length().Equal(5)

func (*String) Match

func (s *String) Match(re string) *Match

Match matches the string with given regexp and returns a new Match object with found submatches.

If regexp is invalid or string doesn't match regexp, Match fails and returns empty (but non-nil) object. regexp.Compile is used to construct regexp, and Regexp.FindStringSubmatch is used to construct matches.

Example:

s := NewString(t, "http://example.com/users/john")
m := s.Match(`http://(?P<host>.+)/users/(?P<user>.+)`)

m.NotEmpty()
m.Length().Equal(3)

m.Index(0).Equal("http://example.com/users/john")
m.Index(1).Equal("example.com")
m.Index(2).Equal("john")

m.Name("host").Equal("example.com")
m.Name("user").Equal("john")

func (*String) MatchAll

func (s *String) MatchAll(re string) []Match

MatchAll find all matches in string for given regexp and returns a list of found matches.

If regexp is invalid or string doesn't match regexp, MatchAll fails and returns empty (but non-nil) slice. regexp.Compile is used to construct regexp, and Regexp.FindAllStringSubmatch is used to find matches.

Example:

s := NewString(t,
   "http://example.com/users/john http://example.com/users/bob")

m := s.MatchAll(`http://(?P<host>\S+)/users/(?P<user>\S+)`)

m[0].Name("user").Equal("john")
m[1].Name("user").Equal("bob")

func (*String) NotContains

func (s *String) NotContains(value string) *String

NotContains succeeds if string doesn't contain Go string as a substring.

Example:

str := NewString(t, "Hello")
str.NotContains("bye")

func (*String) NotContainsFold

func (s *String) NotContainsFold(value string) *String

NotContainsFold succeeds if string doesn't contain given Go string as a substring after applying Unicode case-folding (so it's a case-insensitive match).

Example:

str := NewString(t, "Hello")
str.NotContainsFold("BYE")

func (*String) NotEmpty

func (s *String) NotEmpty() *String

NotEmpty succeeds if string is non-empty.

Example:

str := NewString(t, "Hello")
str.NotEmpty()

func (*String) NotEqual

func (s *String) NotEqual(value string) *String

NotEqual succeeds if string is not equal to given Go string.

Example:

str := NewString(t, "Hello")
str.NotEqual("Goodbye")

func (*String) NotEqualFold

func (s *String) NotEqualFold(value string) *String

NotEqualFold succeeds if string is not equal to given Go string after applying Unicode case-folding (so it's a case-insensitive match).

Example:

str := NewString(t, "Hello")
str.NotEqualFold("gOODBYe")

func (*String) NotMatch

func (s *String) NotMatch(re string) *String

NotMatch succeeds if the string doesn't match to given regexp.

regexp.Compile is used to construct regexp, and Regexp.MatchString is used to perform match.

Example:

s := NewString(t, "a")
s.NotMatch(`[^a]`)

func (*String) Path

func (s *String) Path(path string) *Value

Path is similar to Value.Path.

func (*String) Raw

func (s *String) Raw() string

Raw returns underlying value attached to String. This is the value originally passed to NewString.

Example:

str := NewString(t, "Hello")
assert.Equal(t, "Hello", str.Raw())

func (*String) Schema

func (s *String) Schema(schema interface{}) *String

Schema is similar to Value.Schema.

type Value

type Value struct {
	// contains filtered or unexported fields
}

Value provides methods to inspect attached interface{} object (Go representation of arbitrary JSON value) and cast it to concrete type.

func NewValue

func NewValue(reporter Reporter, value interface{}) *Value

NewValue returns a new Value given a reporter used to report failures and value to be inspected.

reporter should not be nil, but value may be nil.

Example:

value := NewValue(t, map[string]interface{}{"foo": 123})
value.Object()

value := NewValue(t, []interface{}{"foo", 123})
value.Array()

value := NewValue(t, "foo")
value.String()

value := NewValue(t, 123)
value.Number()

value := NewValue(t, true)
value.Boolean()

value := NewValue(t, nil)
value.Null()

func (*Value) Array

func (v *Value) Array() *Array

Array returns a new Array attached to underlying value.

If underlying value is not an array ([]interface{}), failure is reported and empty (but non-nil) value is returned.

Example:

value := NewValue(t, []interface{}{"foo", 123})
value.Array().Elements("foo", 123)

func (*Value) Boolean

func (v *Value) Boolean() *Boolean

Boolean returns a new Boolean attached to underlying value.

If underlying value is not a bool, failure is reported and empty (but non-nil) value is returned.

Example:

value := NewValue(t, true)
value.Boolean().True()

func (*Value) Equal

func (v *Value) Equal(value interface{}) *Value

Equal succeeds if value is equal to given Go value (e.g. map, slice, string, etc). Before comparison, both values are converted to canonical form.

Example:

value := NewValue(t, "foo")
value.Equal("foo")

func (*Value) NotEqual

func (v *Value) NotEqual(value interface{}) *Value

NotEqual succeeds if value is not equal to given Go value (e.g. map, slice, string, etc). Before comparison, both values are converted to canonical form.

Example:

value := NewValue(t, "foo")
value.NorEqual("bar")

func (*Value) NotNull

func (v *Value) NotNull() *Value

NotNull succeeds if value is not nil.

Note that non-nil interface{} that points to nil value (e.g. nil slice or map) is also treated as null value. Empty (non-nil) slice or map, empty string, and zero number are not treated as null value.

Example:

value := NewValue(t, "")
value.NotNull()

value := NewValue(t, make([]interface{}, 0)
value.Null()

func (*Value) Null

func (v *Value) Null() *Value

Null succeeds if value is nil.

Note that non-nil interface{} that points to nil value (e.g. nil slice or map) is also treated as null value. Empty (non-nil) slice or map, empty string, and zero number are not treated as null value.

Example:

value := NewValue(t, nil)
value.Null()

value := NewValue(t, []interface{}(nil))
value.Null()

func (*Value) Number

func (v *Value) Number() *Number

Number returns a new Number attached to underlying value.

If underlying value is not a number (numeric type convertible to float64), failure is reported and empty (but non-nil) value is returned.

Example:

value := NewValue(t, 123)
value.Number().InRange(100, 200)

func (*Value) Object

func (v *Value) Object() *Object

Object returns a new Object attached to underlying value.

If underlying value is not an object (map[string]interface{}), failure is reported and empty (but non-nil) value is returned.

Example:

value := NewValue(t, map[string]interface{}{"foo": 123})
value.Object().ContainsKey("foo")

func (*Value) Path

func (v *Value) Path(path string) *Value

Path returns a new Value object for child object(s) matching given JSONPath expression.

JSONPath is a simple XPath-like query language. See http://goessner.net/articles/JsonPath/.

We currently use https://github.com/yalp/jsonpath, which implements only a subset of JSONPath, yet useful for simple queries. It doesn't support filters and requires double quotes for strings.

Example 1:

json := `{"users": [{"name": "john"}, {"name": "bob"}]}`
value := NewValue(t, json)

value.Path("$.users[0].name").String().Equal("john")
value.Path("$.users[1].name").String().Equal("bob")

Example 2:

json := `{"yfGH2a": {"user": "john"}, "f7GsDd": {"user": "john"}}`
value := NewValue(t, json)

for _, user := range value.Path("$..user").Array().Iter() {
    user.String().Equal("john")
}

func (*Value) Raw

func (v *Value) Raw() interface{}

Raw returns underlying value attached to Value. This is the value originally passed to NewValue, converted to canonical form.

Example:

value := NewValue(t, "foo")
assert.Equal(t, "foo", number.Raw().(string))

func (*Value) Schema

func (v *Value) Schema(schema interface{}) *Value

Schema succeeds if value matches given JSON Schema.

JSON Schema specifies a JSON-based format to define the structure of JSON data. See http://json-schema.org/. We use https://github.com/xeipuuv/gojsonschema implementation.

schema should be one of the following:

  • go value that can be json.Marshal-ed to a valid schema
  • type convertible to string containing valid schema
  • type convertible to string containing valid http:// or file:// URI, pointing to reachable and valid schema

Example 1:

 schema := `{
   "type": "object",
   "properties": {
      "foo": {
          "type": "string"
      },
      "bar": {
          "type": "integer"
      }
  },
  "require": ["foo", "bar"]
}`

value := NewValue(t, map[string]interface{}{
    "foo": "a",
    "bar": 1,
})

value.Schema(schema)

Example 2:

value := NewValue(t, data)
value.Schema("http://example.com/schema.json")

func (*Value) String

func (v *Value) String() *String

String returns a new String attached to underlying value.

If underlying value is not a string, failure is reported and empty (but non-nil) value is returned.

Example:

value := NewValue(t, "foo")
value.String().EqualFold("FOO")

type Websocket

type Websocket struct {
	// contains filtered or unexported fields
}

Websocket provides methods to read from, write into and close WebSocket connection.

func NewWebsocket

func NewWebsocket(config Config, conn *websocket.Conn) *Websocket

NewWebsocket returns a new Websocket given a Config with Reporter and Printers, and websocket.Conn to be inspected and handled.

func (*Websocket) Close

func (c *Websocket) Close(code ...int) *Websocket

Close cleanly closes the underlying WebSocket connection by sending an empty close message and then waiting (with timeout) for the server to close the connection.

WebSocket close code may be optionally specified. If not, then "1000 - Normal Closure" will be used.

WebSocket close codes are defined in RFC 6455, section 11.7. See also https://godoc.org/github.com/gorilla/websocket#pkg-constants

It's okay to call this function multiple times.

Example:

conn := resp.Connection()
conn.Close(websocket.CloseUnsupportedData)

func (*Websocket) CloseWithBytes

func (c *Websocket) CloseWithBytes(b []byte, code ...int) *Websocket

CloseWithBytes cleanly closes the underlying WebSocket connection by sending given slice of bytes as a close message and then waiting (with timeout) for the server to close the connection.

WebSocket close code may be optionally specified. If not, then "1000 - Normal Closure" will be used.

WebSocket close codes are defined in RFC 6455, section 11.7. See also https://godoc.org/github.com/gorilla/websocket#pkg-constants

It's okay to call this function multiple times.

Example:

conn := resp.Connection()
conn.CloseWithBytes([]byte("bye!"), websocket.CloseGoingAway)

func (*Websocket) CloseWithJSON

func (c *Websocket) CloseWithJSON(
	object interface{}, code ...int,
) *Websocket

CloseWithJSON cleanly closes the underlying WebSocket connection by sending given object (marshaled using json.Marshal()) as a close message and then waiting (with timeout) for the server to close the connection.

WebSocket close code may be optionally specified. If not, then "1000 - Normal Closure" will be used.

WebSocket close codes are defined in RFC 6455, section 11.7. See also https://godoc.org/github.com/gorilla/websocket#pkg-constants

It's okay to call this function multiple times.

Example:

type MyJSON struct {
  Foo int `json:"foo"`
}

conn := resp.Connection()
conn.CloseWithJSON(MyJSON{Foo: 123}, websocket.CloseUnsupportedData)

func (*Websocket) CloseWithText

func (c *Websocket) CloseWithText(s string, code ...int) *Websocket

CloseWithText cleanly closes the underlying WebSocket connection by sending given text as a close message and then waiting (with timeout) for the server to close the connection.

WebSocket close code may be optionally specified. If not, then "1000 - Normal Closure" will be used.

WebSocket close codes are defined in RFC 6455, section 11.7. See also https://godoc.org/github.com/gorilla/websocket#pkg-constants

It's okay to call this function multiple times.

Example:

conn := resp.Connection()
conn.CloseWithText("bye!")

func (*Websocket) Disconnect

func (c *Websocket) Disconnect() *Websocket

Disconnect closes the underlying WebSocket connection without sending or waiting for a close message.

It's okay to call this function multiple times.

It's recommended to always call this function after connection usage is over to ensure that no resource leaks will happen.

Example:

conn := resp.Connection()
defer conn.Disconnect()

func (*Websocket) Expect

func (c *Websocket) Expect() *WebsocketMessage

Expect reads next message from WebSocket connection and returns a new WebsocketMessage object to inspect received message.

Example:

msg := conn.Expect()
msg.JSON().Object().ValueEqual("message", "hi")

func (*Websocket) Raw

func (c *Websocket) Raw() *websocket.Conn

Raw returns underlying websocket.Conn object. This is the value originally passed to NewConnection.

func (*Websocket) Subprotocol

func (c *Websocket) Subprotocol() *String

Subprotocol returns a new String object that may be used to inspect negotiated protocol for the connection.

func (*Websocket) WithReadTimeout

func (c *Websocket) WithReadTimeout(timeout time.Duration) *Websocket

WithReadTimeout sets timeout duration for WebSocket connection reads.

By default no timeout is used.

func (*Websocket) WithWriteTimeout

func (c *Websocket) WithWriteTimeout(timeout time.Duration) *Websocket

WithWriteTimeout sets timeout duration for WebSocket connection writes.

By default no timeout is used.

func (*Websocket) WithoutReadTimeout

func (c *Websocket) WithoutReadTimeout() *Websocket

WithoutReadTimeout removes timeout for WebSocket connection reads.

func (*Websocket) WithoutWriteTimeout

func (c *Websocket) WithoutWriteTimeout() *Websocket

WithoutWriteTimeout removes timeout for WebSocket connection writes.

If not used then DefaultWebsocketTimeout will be used.

func (*Websocket) WriteBytesBinary

func (c *Websocket) WriteBytesBinary(b []byte) *Websocket

WriteBytesBinary is a shorthand for c.WriteMessage(websocket.BinaryMessage, b).

func (*Websocket) WriteBytesText

func (c *Websocket) WriteBytesText(b []byte) *Websocket

WriteBytesText is a shorthand for c.WriteMessage(websocket.TextMessage, b).

func (*Websocket) WriteJSON

func (c *Websocket) WriteJSON(object interface{}) *Websocket

WriteJSON writes to the underlying WebSocket connection given object, marshaled using json.Marshal().

func (*Websocket) WriteMessage

func (c *Websocket) WriteMessage(
	typ int, content []byte, closeCode ...int,
) *Websocket

WriteMessage writes to the underlying WebSocket connection a message of given type with given content. Additionally, WebSocket close code may be specified for close messages.

WebSocket message types are defined in RFC 6455, section 11.8. See also https://godoc.org/github.com/gorilla/websocket#pkg-constants

WebSocket close codes are defined in RFC 6455, section 11.7. See also https://godoc.org/github.com/gorilla/websocket#pkg-constants

Example:

conn := resp.Connection()
conn.WriteMessage(websocket.CloseMessage, []byte("Namárië..."))

func (*Websocket) WriteText

func (c *Websocket) WriteText(s string) *Websocket

WriteText is a shorthand for c.WriteMessage(websocket.TextMessage, []byte(s)).

type WebsocketDialer

type WebsocketDialer interface {
	// Dial establishes new WebSocket connection and returns response
	// of handshake result.
	Dial(url string, reqH http.Header) (*websocket.Conn, *http.Response, error)
}

WebsocketDialer is used to establish websocket.Conn and receive http.Response of handshake result. websocket.Dialer implements this interface.

NewWebsocketDialer and NewFastWebsocketDialer may be used to obtain this interface implementation.

Example:

 e := httpexpect.WithConfig(httpexpect.Config{
   BaseURL:         "http://example.com",
   WebsocketDialer: httpexpect.NewWebsocketDialer(myHandler),
	})

type WebsocketMessage

type WebsocketMessage struct {
	// contains filtered or unexported fields
}

WebsocketMessage provides methods to inspect message read from WebSocket connection.

func NewWebsocketMessage

func NewWebsocketMessage(
	reporter Reporter, typ int, content []byte, closeCode ...int,
) *WebsocketMessage

NewWebsocketMessage returns a new WebsocketMessage object given a reporter used to report failures and the message parameters to be inspected.

reporter should not be nil.

Example:

m := NewWebsocketMessage(reporter, websocket.TextMessage, []byte("content"), 0)
m.TextMessage()

func (*WebsocketMessage) BinaryMessage

func (m *WebsocketMessage) BinaryMessage() *WebsocketMessage

BinaryMessage is a shorthand for m.Type(websocket.BinaryMessage).

func (*WebsocketMessage) Body

func (m *WebsocketMessage) Body() *String

Body returns a new String object that may be used to inspect WebSocket message content.

Example:

msg := conn.Expect()
msg.Body().NotEmpty()
msg.Body().Length().Equal(100)

func (*WebsocketMessage) CloseMessage

func (m *WebsocketMessage) CloseMessage() *WebsocketMessage

CloseMessage is a shorthand for m.Type(websocket.CloseMessage).

func (*WebsocketMessage) Code

func (m *WebsocketMessage) Code(code ...int) *WebsocketMessage

Code succeeds if WebSocket close code is one of the given.

Code fails if WebSocket message type is not "8 - Connection Close Frame".

WebSocket close codes are defined in RFC 6455, section 11.7. See also https://godoc.org/github.com/gorilla/websocket#pkg-constants

Example:

msg := conn.Expect().Closed()
msg.Code(websocket.CloseNormalClosure, websocket.CloseGoingAway)

func (*WebsocketMessage) JSON

func (m *WebsocketMessage) JSON() *Value

JSON returns a new Value object that may be used to inspect JSON contents of WebSocket message.

JSON succeeds if JSON may be decoded from message content.

Example:

msg := conn.Expect()
msg.JSON().Array().Elements("foo", "bar")

func (*WebsocketMessage) NoContent

func (m *WebsocketMessage) NoContent() *WebsocketMessage

NoContent succeeds if WebSocket message has no content (is empty).

func (*WebsocketMessage) NotBinaryMessage

func (m *WebsocketMessage) NotBinaryMessage() *WebsocketMessage

NotBinaryMessage is a shorthand for m.NotType(websocket.BinaryMessage).

func (*WebsocketMessage) NotCloseMessage

func (m *WebsocketMessage) NotCloseMessage() *WebsocketMessage

NotCloseMessage is a shorthand for m.NotType(websocket.CloseMessage).

func (*WebsocketMessage) NotCode

func (m *WebsocketMessage) NotCode(code ...int) *WebsocketMessage

NotCode succeeds if WebSocket close code is none of the given.

NotCode fails if WebSocket message type is not "8 - Connection Close Frame".

WebSocket close codes are defined in RFC 6455, section 11.7. See also https://godoc.org/github.com/gorilla/websocket#pkg-constants

Example:

msg := conn.Expect().Closed()
msg.NotCode(websocket.CloseAbnormalClosure, websocket.CloseNoStatusReceived)

func (*WebsocketMessage) NotTextMessage

func (m *WebsocketMessage) NotTextMessage() *WebsocketMessage

NotTextMessage is a shorthand for m.NotType(websocket.TextMessage).

func (*WebsocketMessage) NotType

func (m *WebsocketMessage) NotType(typ ...int) *WebsocketMessage

NotType succeeds if WebSocket message type is none of the given.

WebSocket message types are defined in RFC 6455, section 11.8. See also https://godoc.org/github.com/gorilla/websocket#pkg-constants

Example:

msg := conn.Expect()
msg.NotType(websocket.CloseMessage, websocket.BinaryMessage)

func (*WebsocketMessage) Raw

func (m *WebsocketMessage) Raw() (typ int, content []byte, closeCode int)

Raw returns underlying type, content and close code of WebSocket message. Theses values are originally read from WebSocket connection.

func (*WebsocketMessage) TextMessage

func (m *WebsocketMessage) TextMessage() *WebsocketMessage

TextMessage is a shorthand for m.Type(websocket.TextMessage).

func (*WebsocketMessage) Type

func (m *WebsocketMessage) Type(typ ...int) *WebsocketMessage

Type succeeds if WebSocket message type is one of the given.

WebSocket message types are defined in RFC 6455, section 11.8. See also https://godoc.org/github.com/gorilla/websocket#pkg-constants

Example:

msg := conn.Expect()
msg.Type(websocket.TextMessage, websocket.BinaryMessage)

type WebsocketPrinter

type WebsocketPrinter interface {
	Printer

	// WebsocketWrite is called before writes to WebSocket connection.
	WebsocketWrite(typ int, content []byte, closeCode int)

	// WebsocketRead is called after reads from WebSocket connection.
	WebsocketRead(typ int, content []byte, closeCode int)
}

WebsocketPrinter is used to print writes and reads of WebSocket connection.

If WebSocket connection is used, all Printers that also implement WebsocketPrinter are invoked on every WebSocket message read or written.

DebugPrinter implements this interface.

Directories

Path Synopsis
Package examples demonstrates httpexpect usage.
Package examples demonstrates httpexpect usage.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL