Merge remote-tracking branch 'upstream/master' into batchDelection
23
Makefile
@ -85,16 +85,9 @@ BUILDBIN=false
|
||||
MIGRATORFLAG=false
|
||||
|
||||
# version prepare
|
||||
VERSIONTAG=dev
|
||||
VERSIONFILEPATH=$(CURDIR)
|
||||
VERSIONFILENAME=VERSION
|
||||
GITCMD=$(shell which git)
|
||||
GITTAG=$(GITCMD) describe --tags
|
||||
GITTAGVERSION=$(shell git describe --tags || echo UNKNOWN)
|
||||
ifeq ($(DEVFLAG), true)
|
||||
VERSIONTAG=dev
|
||||
else
|
||||
VERSIONTAG=$(GITTAGVERSION)
|
||||
endif
|
||||
|
||||
#versions
|
||||
REGISTRYVERSION=v2.6.2
|
||||
@ -212,13 +205,13 @@ DOCKERSAVE_PARA=$(DOCKERIMAGENAME_ADMINSERVER):$(VERSIONTAG) \
|
||||
$(DOCKERIMAGENAME_JOBSERVICE):$(VERSIONTAG) \
|
||||
vmware/nginx-photon:$(NGINXVERSION) vmware/registry-photon:$(REGISTRYVERSION)-$(VERSIONTAG) \
|
||||
vmware/photon:$(PHOTONVERSION)
|
||||
PACKAGE_OFFLINE_PARA=-zcvf harbor-offline-installer-$(GITTAGVERSION).tgz \
|
||||
PACKAGE_OFFLINE_PARA=-zcvf harbor-offline-installer-$(VERSIONTAG).tgz \
|
||||
$(HARBORPKG)/common/templates $(HARBORPKG)/$(DOCKERIMGFILE).$(VERSIONTAG).tar.gz \
|
||||
$(HARBORPKG)/prepare $(HARBORPKG)/NOTICE \
|
||||
$(HARBORPKG)/LICENSE $(HARBORPKG)/install.sh \
|
||||
$(HARBORPKG)/harbor.cfg $(HARBORPKG)/$(DOCKERCOMPOSEFILENAME) \
|
||||
$(HARBORPKG)/ha
|
||||
PACKAGE_ONLINE_PARA=-zcvf harbor-online-installer-$(GITTAGVERSION).tgz \
|
||||
PACKAGE_ONLINE_PARA=-zcvf harbor-online-installer-$(VERSIONTAG).tgz \
|
||||
$(HARBORPKG)/common/templates $(HARBORPKG)/prepare \
|
||||
$(HARBORPKG)/LICENSE $(HARBORPKG)/NOTICE \
|
||||
$(HARBORPKG)/install.sh $(HARBORPKG)/$(DOCKERCOMPOSEFILENAME) \
|
||||
@ -243,7 +236,7 @@ ifeq ($(MIGRATORFLAG), true)
|
||||
endif
|
||||
|
||||
version:
|
||||
@printf $(GITTAGVERSION) > $(VERSIONFILEPATH)/$(VERSIONFILENAME);
|
||||
@printf $(VERSIONTAG) > $(VERSIONFILEPATH)/$(VERSIONFILENAME);
|
||||
|
||||
check_environment:
|
||||
@$(MAKEPATH)/$(CHECKENVCMD)
|
||||
@ -444,10 +437,10 @@ cleanversiontag:
|
||||
cleanpackage:
|
||||
@echo "cleaning harbor install package"
|
||||
@if [ -d $(BUILDPATH)/harbor ] ; then rm -rf $(BUILDPATH)/harbor ; fi
|
||||
@if [ -f $(BUILDPATH)/harbor-online-installer-$(GITTAGVERSION).tgz ] ; \
|
||||
then rm $(BUILDPATH)/harbor-online-installer-$(GITTAGVERSION).tgz ; fi
|
||||
@if [ -f $(BUILDPATH)/harbor-offline-installer-$(GITTAGVERSION).tgz ] ; \
|
||||
then rm $(BUILDPATH)/harbor-offline-installer-$(GITTAGVERSION).tgz ; fi
|
||||
@if [ -f $(BUILDPATH)/harbor-online-installer-$(VERSIONTAG).tgz ] ; \
|
||||
then rm $(BUILDPATH)/harbor-online-installer-$(VERSIONTAG).tgz ; fi
|
||||
@if [ -f $(BUILDPATH)/harbor-offline-installer-$(VERSIONTAG).tgz ] ; \
|
||||
then rm $(BUILDPATH)/harbor-offline-installer-$(VERSIONTAG).tgz ; fi
|
||||
|
||||
.PHONY: cleanall
|
||||
cleanall: cleanbinary cleanimage cleandockercomposefile cleanversiontag cleanpackage
|
||||
|
BIN
docs/img/create_rule.png
Normal file
After Width: | Height: | Size: 104 KiB |
BIN
docs/img/delete_rule.png
Normal file
After Width: | Height: | Size: 63 KiB |
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 104 KiB |
BIN
docs/img/list_stop_jobs.png
Normal file
After Width: | Height: | Size: 102 KiB |
BIN
docs/img/manage_endpoint.png
Normal file
After Width: | Height: | Size: 65 KiB |
BIN
docs/img/manage_replication.png
Normal file
After Width: | Height: | Size: 61 KiB |
BIN
docs/img/rule_under_project_view.png
Normal file
After Width: | Height: | Size: 112 KiB |
BIN
docs/img/start_replicate.png
Normal file
After Width: | Height: | Size: 64 KiB |
@ -108,4 +108,6 @@
|
||||
|
||||
If everything worked properly, you should see the administration console. Refer to **[Harbor User Guide](user_guide.md)** for how to use Harbor.
|
||||
|
||||
![Screenshot of after login](img/ovainstall/afterlogin.png)
|
||||
![Screenshot of after login](img/ovainstall/afterlogin.png)
|
||||
|
||||
Please run "tdnf distro-sync" command from time to time to keep the OS up to date.
|
@ -4,11 +4,11 @@ This guide walks you through the fundamentals of using Harbor. You'll learn how
|
||||
|
||||
* [Manage your projects.](#managing-projects)
|
||||
* [Manage members of a project.](#managing-members-of-a-project)
|
||||
* [Replicate projects to a remote registry.](#replicationg-images)
|
||||
* [Replicate projects to a remote registry.](#replicating-images)
|
||||
* [Search projects and repositories.](#searching-projects-and-repositories)
|
||||
* [Manage Harbor system if you are the system administrator:](#administrator-options)
|
||||
* [Manage users.](#managing-user)
|
||||
* [Manage destinations.](#managing-endpoint)
|
||||
* [Manage endpoints.](#managing-endpoint)
|
||||
* [Manage replication policies.](#managing-replication)
|
||||
* [Manage authentication.](#managing-authentication)
|
||||
* [Manage project creation.](#managing-project-creation)
|
||||
@ -59,9 +59,9 @@ Harbor supports two authentication modes:
|
||||
|
||||
Under this authentication mode, users whose credentials are stored in an external LDAP or AD server can log in to Harbor directly.
|
||||
|
||||
When an LDAP/AD user logs in by *username* and *password*, Harbor binds to the LDAP/AD server with the **"LDAP Search DN"** and **"LDAP Search Password"** described in [installation guide](installation_guide.md). If it succeeded, Harbor looks up the user under the LDAP entry **"LDAP Base DN"** including substree. The attribute (such as uid, cn) specified by **"LDAP UID"** is used to match a user with the *username*. If a match is found, the user's *password* is verified by a bind request to the LDAP/AD server.
|
||||
When an LDAP/AD user logs in by *username* and *password*, Harbor binds to the LDAP/AD server with the **"LDAP Search DN"** and **"LDAP Search Password"** described in [installation guide](installation_guide.md). If it succeeded, Harbor looks up the user under the LDAP entry **"LDAP Base DN"** including substree. The attribute (such as uid, cn) specified by **"LDAP UID"** is used to match a user with the *username*. If a match is found, the user's *password* is verified by a bind request to the LDAP/AD server. Uncheck **"LDAP Verify Cert"** if the LDAP/AD server uses a self-signed or an untrusted certificate.
|
||||
|
||||
Self-registration, changing password and resetting password are not supported under LDAP/AD authentication mode because the users are managed by LDAP or AD.
|
||||
Self-registration, deleting user, changing password and resetting password are not supported under LDAP/AD authentication mode because the users are managed by LDAP or AD.
|
||||
|
||||
## Managing projects
|
||||
A project in Harbor contains all repositories of an application. No images can be pushed to Harbor before the project is created. RBAC is applied to a project. There are two types of projects in Harbor:
|
||||
@ -97,7 +97,7 @@ Project properties can be changed by clicking "Configuration".
|
||||
|
||||
## Managing members of a project
|
||||
### Adding members
|
||||
You can add members with different roles to an existing project.
|
||||
You can add members with different roles to an existing project. You can add a LDAP/AD user to project members under LDAP/AD authentication mode.
|
||||
|
||||
![browse project](img/new_add_member.png)
|
||||
|
||||
@ -109,23 +109,51 @@ You can update or remove a member by clicking the icon on the left.
|
||||
## Replicating images
|
||||
Images replication is used to replicate repositories from one Harbor instance to another.
|
||||
|
||||
The function is project-oriented, and once the system administrator set a rule to one project, all repositories under the project will be replicated to the remote registry. Each repository will start a job to run. If the project does not exist on the remote registry, a new project will be created automatically, but if it already exists and the user configured in policy has no write privilege to it, the process will fail. When a new repository is pushed to this project or an existing repository is deleted from this project, the same operation will also be replicated to the destination. The member information will not be replicated.
|
||||
The function is project-oriented, and once the system administrator set a rule to one project, all repositories under the project that match the defined [filter](#replication-filter) patterns will be replicated to the remote registry when the [triggering condition](#replication-triggering-condition) is triggered. Each repository will start a job to run. If the project does not exist on the remote registry, a new project will be created automatically, but if it already exists and the user configured in policy has no write privilege to it, the process will fail. The member information will not be replicated.
|
||||
|
||||
There may be a bit of delay during replication according to the situation of the network. If replication job fails due to the network issue, the job will be re-scheduled a few minutes later.
|
||||
|
||||
**Note:** The replication feature is incompatible between Harbor instance before version 0.3.5(included) and after version 0.3.5.
|
||||
**Note:** The replication feature is incompatible between Harbor instance before version 0.3.5(included) and after version 0.3.5.
|
||||
|
||||
Replication can be configured by creating a rule. Click "Add Replication Rule" on the "Replication" tab and fill in the necessary fields. If there is no endpoint available in the list, you need to create one. Uncheck "Verify Remote Cert" if the remote registry uses a self-signed or an untrusted certificate. Click "OK" to create a replication rule for this project. If "Enable" is chosen, the project will be replicated to the remote registry immediately.
|
||||
### Creating a replication rule
|
||||
Replication can be configured by creating a rule. Click `NEW REPLICATION RULE` under `Administration->Replications` and fill in the necessary fields. You can choose different replication filters and triggering conditions according the different requirements. If there is no endpoint available in the list, you need to create one. Click `OK` to create a replication rule for the selected project. If `Replicate existing images immediately` is chosen, the existing images under the project will be replicated to the remote registry immediately.
|
||||
|
||||
![browse project](img/new_create_rule.png)
|
||||
#### Replication filter
|
||||
Two replication filters are supported:
|
||||
* **Repository**: Filter images according to the repository part of image name.
|
||||
* **Tag**: Filter images according to the tag part of image name.
|
||||
|
||||
You can enable, disable or delete a rule in the rule list view. Only rules which are disabled can be edited and only rules which are disabled and have no running jobs can be deleted. If a rule is disabled, the running jobs under it will be stopped.
|
||||
Two terms are supported in filter pattern:
|
||||
* **\***: Matches any sequence of non-separator characters `/`.
|
||||
* **?**: Matches any single non-separator character `/`.
|
||||
|
||||
Click a rule, jobs which belong to this rule will be listed. A job represents the progress of replicating the repository to the remote instance.
|
||||
#### Replication triggering condition
|
||||
* **Immediate**: When a new repository is pushed to the project, it is replicated to the remote registry immediately. Same to the deletion operation if the `Delete remote images when locally deleted` checkbox is selected.
|
||||
* **Scheduled**: Replicate the repositories daily or weekly. **Note**: The deletion operations are not replicated.
|
||||
* **Manual**: Replicate the repositories manually when needed. **Note**: The deletion operations are not replicated.
|
||||
|
||||
![browse project](img/new_rule_list.png)
|
||||
![browse project](img/create_rule.png)
|
||||
|
||||
### Listing and stopping replication jobs
|
||||
Click a rule, jobs which belong to this rule will be listed. A job represents the progress of replicating the repository to the remote instance. Click `STOP JOBS`, the pending/running/retrying jobs will be stopped.
|
||||
|
||||
![browse project](img/list_stop_jobs.png)
|
||||
|
||||
### Starting a replication manually
|
||||
Start a new replication by selecting the replication rule and clicking `REPLICATE`. If there is any pending/running job that belongs to the rule, new replication will not be started.
|
||||
|
||||
![browse project](img/start_replicate.png)
|
||||
|
||||
### Deleting the replication rule
|
||||
Select the replication rule and click `DELETE` to delete it. Only rules which have no pending/running/retrying jobs can be deleted.
|
||||
|
||||
![browse project](img/delete_rule.png)
|
||||
|
||||
|
||||
The system administrator can operate the replication rule defined for the specified project in `Replication` tab under `Projects` view. Project administrator has read-only privilege.
|
||||
|
||||
![browse project](img/rule_under_project_view.png)
|
||||
|
||||
**Video demo:** ![Image replication](img/demos/image_replication.png) [youtube](https://www.youtube.com/watch?v=1NPlzrm5ozE) , [Tencent Video](https://v.qq.com/x/page/a0553wc7fs9.html)
|
||||
|
||||
## Searching projects and repositories
|
||||
Entering a keyword in the search field at the top lists all matching projects and repositories. The search result includes both public and private repositories you have access to.
|
||||
@ -134,19 +162,19 @@ Entering a keyword in the search field at the top lists all matching projects an
|
||||
|
||||
## Administrator options
|
||||
### Managing user
|
||||
Administrator can add "Administrator" role to an ordinary user by click button on the left and select "Set as Administrator". To delete a user, select "Delete".
|
||||
Administrator can add "Administrator" role to an ordinary user by click button on the left and select "Set as Administrator". To delete a user, select "Delete". Deleting user is only supported under database authentication mode.
|
||||
|
||||
![browse project](img/new_set_admin_remove_user.png)
|
||||
|
||||
### Managing endpoint
|
||||
You can list, add, edit and delete endpoints in the "Endpoints" tab. Only endpoints which are not referenced by any enabled rules can be edited.
|
||||
You can list, add, edit and delete endpoints under `Administration->Registries`. Only endpoints which are not referenced by any rules can be deleted.
|
||||
|
||||
![browse project](img/new_manage_endpoint.png)
|
||||
![browse project](img/manage_endpoint.png)
|
||||
|
||||
### Managing replication
|
||||
You can list, edit, enable and disable rules in the "Replication" tab. Make sure the policy is disabled before you edit it.
|
||||
You can list, add, edit and delete rules under `Administration->Replications`.
|
||||
|
||||
![browse project](img/new_manage_replication.png)
|
||||
![browse project](img/manage_replication.png)
|
||||
|
||||
### Managing authentication
|
||||
You can change authentication mode between **Database**(default) and **LDAP** before any user is added, when there is at least one user(besides admin) in Harbor, you cannot change the authentication mode.
|
||||
|
17
src/Gopkg.lock
generated
@ -188,7 +188,19 @@
|
||||
"assert",
|
||||
"require"
|
||||
]
|
||||
revision = "4d4bfba8f1d1027c4fdbe371823030df51419987"
|
||||
revision = "b91bfb9ebec76498946beb6af7c0230c7cc7ba6c"
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/vmware/harbor"
|
||||
packages = [
|
||||
"src/common/models",
|
||||
"src/common/utils",
|
||||
"src/common/utils/log",
|
||||
"tests/apitests/apilib"
|
||||
]
|
||||
revision = "76f8882f546fa8f3c6a12a337dded196893dcb3f"
|
||||
version = "v1.3.0"
|
||||
|
||||
[[projects]]
|
||||
name = "golang.org/x/crypto"
|
||||
@ -207,6 +219,7 @@
|
||||
name = "golang.org/x/oauth2"
|
||||
packages = [
|
||||
".",
|
||||
"clientcredentials",
|
||||
"internal"
|
||||
]
|
||||
revision = "bb50c06baba3d0c76f9d125c0719093e315b5b44"
|
||||
@ -245,6 +258,6 @@
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "9c0f8cd26043afa12693fed0005998c7194c4ea77c8dae19c4363ebadfd600ef"
|
||||
inputs-digest = "1b5bec4304c99684de7fddc82ce9c81788e945f82455125110f32441a6ffd4cc"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
|
@ -51,3 +51,7 @@
|
||||
[[constraint]]
|
||||
name = "gopkg.in/ldap.v2"
|
||||
version = "2.5.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/stretchr/testify"
|
||||
version = "1.2.0"
|
||||
|
@ -15,12 +15,14 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/vmware/harbor/src/adminserver/systemcfg/store"
|
||||
"github.com/vmware/harbor/src/common"
|
||||
"github.com/vmware/harbor/src/common/dao"
|
||||
"github.com/vmware/harbor/src/common/models"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -47,6 +49,9 @@ var (
|
||||
common.LDAPVerifyCert: true,
|
||||
common.UAAVerifyCert: true,
|
||||
}
|
||||
mapKeys = map[string]bool{
|
||||
common.ScanAllPolicy: true,
|
||||
}
|
||||
)
|
||||
|
||||
type cfgStore struct {
|
||||
@ -90,6 +95,12 @@ func WrapperConfig(configEntries []*models.ConfigEntry) (map[string]interface{},
|
||||
return nil, err
|
||||
}
|
||||
config[entry.Key] = strvalue
|
||||
} else if mapKeys[entry.Key] {
|
||||
m := map[string]interface{}{}
|
||||
if err := json.Unmarshal([]byte(entry.Value), &m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config[entry.Key] = m
|
||||
} else {
|
||||
config[entry.Key] = entry.Value
|
||||
}
|
||||
@ -100,7 +111,10 @@ func WrapperConfig(configEntries []*models.ConfigEntry) (map[string]interface{},
|
||||
|
||||
// Write save configuration to database
|
||||
func (c *cfgStore) Write(config map[string]interface{}) error {
|
||||
configEntries, _ := TranslateConfig(config)
|
||||
configEntries, err := TranslateConfig(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return dao.SaveConfigEntries(configEntries)
|
||||
}
|
||||
|
||||
@ -119,6 +133,12 @@ func TranslateConfig(config map[string]interface{}) ([]models.ConfigEntry, error
|
||||
entry.Value = strconv.FormatBool(v.(bool))
|
||||
case float64:
|
||||
entry.Value = strconv.Itoa(int(v.(float64)))
|
||||
case map[string]interface{}:
|
||||
data, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
entry.Value = string(data)
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown type %v", v)
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "harbor-ui",
|
||||
"version": "0.6.24",
|
||||
"version": "0.6.25",
|
||||
"description": "Harbor shared UI components based on Clarity and Angular4",
|
||||
"scripts": {
|
||||
"start": "ng serve --host 0.0.0.0 --port 4500 --proxy-config proxy.config.json",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "harbor-ui",
|
||||
"version": "0.6.24",
|
||||
"version": "0.6.25",
|
||||
"description": "Harbor shared UI components based on Clarity and Angular4",
|
||||
"author": "VMware",
|
||||
"module": "index.js",
|
||||
|
@ -94,14 +94,16 @@ export class RepositoryComponent implements OnInit {
|
||||
|
||||
retrieve(state?: State) {
|
||||
toPromise<Repository>(this.repositoryService.getRepositories(this.projectId, this.repoName))
|
||||
.then(
|
||||
response => {
|
||||
if (response.metadata.xTotalCount > 0) {
|
||||
this.orgImageInfo = response.data[0].description;
|
||||
this.imageInfo = response.data[0].description;
|
||||
}
|
||||
})
|
||||
.catch(error => this.errorHandler.error(error));
|
||||
.then( response => {
|
||||
if (response.metadata.xTotalCount > 0) {
|
||||
this.orgImageInfo = response.data[0].description;
|
||||
this.imageInfo = response.data[0].description;
|
||||
}
|
||||
})
|
||||
.catch(error => this.errorHandler.error(error));
|
||||
toPromise<SystemInfo>(this.systemInfoService.getSystemInfo())
|
||||
.then(systemInfo => this.systemInfo = systemInfo)
|
||||
.catch(error => this.errorHandler.error(error));
|
||||
}
|
||||
|
||||
saveSignatures(event: {[key: string]: string[]}): void {
|
||||
|
@ -31,7 +31,7 @@
|
||||
"clarity-icons": "^0.10.17",
|
||||
"clarity-ui": "^0.10.17",
|
||||
"core-js": "^2.4.1",
|
||||
"harbor-ui": "0.6.27",
|
||||
"harbor-ui": "0.6.25",
|
||||
"intl": "^1.2.5",
|
||||
"mutationobserver-shim": "^0.3.2",
|
||||
"ngx-cookie": "^1.0.0",
|
||||
|
@ -8,7 +8,7 @@
|
||||
<label for="create_project_name" class="col-md-3 form-group-label-override required">{{'PROJECT.NAME' | translate}}</label>
|
||||
<label for="create_project_name" aria-haspopup="true" role="tooltip" [class.invalid]="!isNameValid" class="tooltip tooltip-validation tooltip-md tooltip-bottom-left">
|
||||
<input type="text" id="create_project_name" [(ngModel)]="project.name"
|
||||
name="create_project_name" size="36"
|
||||
name="create_project_name" size="255"
|
||||
required
|
||||
pattern="^[a-z0-9]+(?:[._-][a-z0-9]+)*$"
|
||||
minlength="2"
|
||||
|
1
src/vendor/github.com/astaxie/beego/controller.go
generated
vendored
@ -261,6 +261,7 @@ func (c *Controller) Abort(code string) {
|
||||
|
||||
// CustomAbort stops controller handler and show the error data, it's similar Aborts, but support status code and body.
|
||||
func (c *Controller) CustomAbort(status int, body string) {
|
||||
//This has to be kept if overwritten by dep tools
|
||||
c.Ctx.ResponseWriter.WriteHeader(status)
|
||||
// c.Ctx.Output.Status = status
|
||||
// first panic from ErrorMaps, is is user defined error functions.
|
||||
|
127
src/vendor/github.com/garyburd/redigo/redis/conn.go
generated
vendored
@ -17,6 +17,7 @@ package redis
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@ -30,7 +31,6 @@ import (
|
||||
|
||||
// conn is the low-level implementation of Conn
|
||||
type conn struct {
|
||||
|
||||
// Shared
|
||||
mu sync.Mutex
|
||||
pending int
|
||||
@ -75,6 +75,9 @@ type dialOptions struct {
|
||||
dial func(network, addr string) (net.Conn, error)
|
||||
db int
|
||||
password string
|
||||
useTLS bool
|
||||
skipVerify bool
|
||||
tlsConfig *tls.Config
|
||||
}
|
||||
|
||||
// DialReadTimeout specifies the timeout for reading a single command reply.
|
||||
@ -123,6 +126,30 @@ func DialPassword(password string) DialOption {
|
||||
}}
|
||||
}
|
||||
|
||||
// DialTLSConfig specifies the config to use when a TLS connection is dialed.
|
||||
// Has no effect when not dialing a TLS connection.
|
||||
func DialTLSConfig(c *tls.Config) DialOption {
|
||||
return DialOption{func(do *dialOptions) {
|
||||
do.tlsConfig = c
|
||||
}}
|
||||
}
|
||||
|
||||
// DialTLSSkipVerify disables server name verification when connecting over
|
||||
// TLS. Has no effect when not dialing a TLS connection.
|
||||
func DialTLSSkipVerify(skip bool) DialOption {
|
||||
return DialOption{func(do *dialOptions) {
|
||||
do.skipVerify = skip
|
||||
}}
|
||||
}
|
||||
|
||||
// DialUseTLS specifies whether TLS should be used when connecting to the
|
||||
// server. This option is ignore by DialURL.
|
||||
func DialUseTLS(useTLS bool) DialOption {
|
||||
return DialOption{func(do *dialOptions) {
|
||||
do.useTLS = useTLS
|
||||
}}
|
||||
}
|
||||
|
||||
// Dial connects to the Redis server at the given network and
|
||||
// address using the specified options.
|
||||
func Dial(network, address string, options ...DialOption) (Conn, error) {
|
||||
@ -137,6 +164,26 @@ func Dial(network, address string, options ...DialOption) (Conn, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if do.useTLS {
|
||||
tlsConfig := cloneTLSClientConfig(do.tlsConfig, do.skipVerify)
|
||||
if tlsConfig.ServerName == "" {
|
||||
host, _, err := net.SplitHostPort(address)
|
||||
if err != nil {
|
||||
netConn.Close()
|
||||
return nil, err
|
||||
}
|
||||
tlsConfig.ServerName = host
|
||||
}
|
||||
|
||||
tlsConn := tls.Client(netConn, tlsConfig)
|
||||
if err := tlsConn.Handshake(); err != nil {
|
||||
netConn.Close()
|
||||
return nil, err
|
||||
}
|
||||
netConn = tlsConn
|
||||
}
|
||||
|
||||
c := &conn{
|
||||
conn: netConn,
|
||||
bw: bufio.NewWriter(netConn),
|
||||
@ -173,7 +220,7 @@ func DialURL(rawurl string, options ...DialOption) (Conn, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if u.Scheme != "redis" {
|
||||
if u.Scheme != "redis" && u.Scheme != "rediss" {
|
||||
return nil, fmt.Errorf("invalid redis URL scheme: %s", u.Scheme)
|
||||
}
|
||||
|
||||
@ -213,6 +260,8 @@ func DialURL(rawurl string, options ...DialOption) (Conn, error) {
|
||||
return nil, fmt.Errorf("invalid database: %s", u.Path[1:])
|
||||
}
|
||||
|
||||
options = append(options, DialUseTLS(u.Scheme == "rediss"))
|
||||
|
||||
return Dial("tcp", address, options...)
|
||||
}
|
||||
|
||||
@ -296,39 +345,55 @@ func (c *conn) writeFloat64(n float64) error {
|
||||
return c.writeBytes(strconv.AppendFloat(c.numScratch[:0], n, 'g', -1, 64))
|
||||
}
|
||||
|
||||
func (c *conn) writeCommand(cmd string, args []interface{}) (err error) {
|
||||
func (c *conn) writeCommand(cmd string, args []interface{}) error {
|
||||
c.writeLen('*', 1+len(args))
|
||||
err = c.writeString(cmd)
|
||||
if err := c.writeString(cmd); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, arg := range args {
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
switch arg := arg.(type) {
|
||||
case string:
|
||||
err = c.writeString(arg)
|
||||
case []byte:
|
||||
err = c.writeBytes(arg)
|
||||
case int:
|
||||
err = c.writeInt64(int64(arg))
|
||||
case int64:
|
||||
err = c.writeInt64(arg)
|
||||
case float64:
|
||||
err = c.writeFloat64(arg)
|
||||
case bool:
|
||||
if arg {
|
||||
err = c.writeString("1")
|
||||
} else {
|
||||
err = c.writeString("0")
|
||||
}
|
||||
case nil:
|
||||
err = c.writeString("")
|
||||
default:
|
||||
var buf bytes.Buffer
|
||||
fmt.Fprint(&buf, arg)
|
||||
err = c.writeBytes(buf.Bytes())
|
||||
if err := c.writeArg(arg, true); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return err
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *conn) writeArg(arg interface{}, argumentTypeOK bool) (err error) {
|
||||
switch arg := arg.(type) {
|
||||
case string:
|
||||
return c.writeString(arg)
|
||||
case []byte:
|
||||
return c.writeBytes(arg)
|
||||
case int:
|
||||
return c.writeInt64(int64(arg))
|
||||
case int64:
|
||||
return c.writeInt64(arg)
|
||||
case float64:
|
||||
return c.writeFloat64(arg)
|
||||
case bool:
|
||||
if arg {
|
||||
return c.writeString("1")
|
||||
} else {
|
||||
return c.writeString("0")
|
||||
}
|
||||
case nil:
|
||||
return c.writeString("")
|
||||
case Argument:
|
||||
if argumentTypeOK {
|
||||
return c.writeArg(arg.RedisArg(), false)
|
||||
}
|
||||
// See comment in default clause below.
|
||||
var buf bytes.Buffer
|
||||
fmt.Fprint(&buf, arg)
|
||||
return c.writeBytes(buf.Bytes())
|
||||
default:
|
||||
// This default clause is intended to handle builtin numeric types.
|
||||
// The function should return an error for other types, but this is not
|
||||
// done for compatibility with previous versions of the package.
|
||||
var buf bytes.Buffer
|
||||
fmt.Fprint(&buf, arg)
|
||||
return c.writeBytes(buf.Bytes())
|
||||
}
|
||||
}
|
||||
|
||||
type protocolError string
|
||||
|
17
src/vendor/github.com/garyburd/redigo/redis/doc.go
generated
vendored
@ -38,7 +38,7 @@
|
||||
//
|
||||
// n, err := conn.Do("APPEND", "key", "value")
|
||||
//
|
||||
// The Do method converts command arguments to binary strings for transmission
|
||||
// The Do method converts command arguments to bulk strings for transmission
|
||||
// to the server as follows:
|
||||
//
|
||||
// Go Type Conversion
|
||||
@ -48,7 +48,7 @@
|
||||
// float64 strconv.FormatFloat(v, 'g', -1, 64)
|
||||
// bool true -> "1", false -> "0"
|
||||
// nil ""
|
||||
// all other types fmt.Print(v)
|
||||
// all other types fmt.Fprint(w, v)
|
||||
//
|
||||
// Redis command reply types are represented using the following Go types:
|
||||
//
|
||||
@ -99,7 +99,7 @@
|
||||
//
|
||||
// Concurrency
|
||||
//
|
||||
// Connections support one concurrent caller to the Recieve method and one
|
||||
// Connections support one concurrent caller to the Receive method and one
|
||||
// concurrent caller to the Send and Flush methods. No other concurrency is
|
||||
// supported including concurrent calls to the Do method.
|
||||
//
|
||||
@ -127,7 +127,7 @@
|
||||
// send and flush a subscription management command. The receive method
|
||||
// converts a pushed message to convenient types for use in a type switch.
|
||||
//
|
||||
// psc := redis.PubSubConn{c}
|
||||
// psc := redis.PubSubConn{Conn: c}
|
||||
// psc.Subscribe("example")
|
||||
// for {
|
||||
// switch v := psc.Receive().(type) {
|
||||
@ -165,4 +165,13 @@
|
||||
// if _, err := redis.Scan(reply, &value1, &value2); err != nil {
|
||||
// // handle error
|
||||
// }
|
||||
//
|
||||
// Errors
|
||||
//
|
||||
// Connection methods return error replies from the server as type redis.Error.
|
||||
//
|
||||
// Call the connection Err() method to determine if the connection encountered
|
||||
// non-recoverable error such as a network error or protocol parsing error. If
|
||||
// Err() returns a non-nil value, then the connection is not usable and should
|
||||
// be closed.
|
||||
package redis // import "github.com/garyburd/redigo/redis"
|
||||
|
111
src/vendor/github.com/garyburd/redigo/redis/pool.go
generated
vendored
@ -46,40 +46,26 @@ var (
|
||||
//
|
||||
// The following example shows how to use a pool in a web application. The
|
||||
// application creates a pool at application startup and makes it available to
|
||||
// request handlers using a global variable.
|
||||
// request handlers using a package level variable. The pool configuration used
|
||||
// here is an example, not a recommendation.
|
||||
//
|
||||
// func newPool(server, password string) *redis.Pool {
|
||||
// return &redis.Pool{
|
||||
// MaxIdle: 3,
|
||||
// IdleTimeout: 240 * time.Second,
|
||||
// Dial: func () (redis.Conn, error) {
|
||||
// c, err := redis.Dial("tcp", server)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// if _, err := c.Do("AUTH", password); err != nil {
|
||||
// c.Close()
|
||||
// return nil, err
|
||||
// }
|
||||
// return c, err
|
||||
// },
|
||||
// TestOnBorrow: func(c redis.Conn, t time.Time) error {
|
||||
// _, err := c.Do("PING")
|
||||
// return err
|
||||
// },
|
||||
// }
|
||||
// func newPool(addr string) *redis.Pool {
|
||||
// return &redis.Pool{
|
||||
// MaxIdle: 3,
|
||||
// IdleTimeout: 240 * time.Second,
|
||||
// Dial: func () (redis.Conn, error) { return redis.Dial("tcp", addr) },
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// var (
|
||||
// pool *redis.Pool
|
||||
// redisServer = flag.String("redisServer", ":6379", "")
|
||||
// redisPassword = flag.String("redisPassword", "", "")
|
||||
// pool *redis.Pool
|
||||
// redisServer = flag.String("redisServer", ":6379", "")
|
||||
// )
|
||||
//
|
||||
// func main() {
|
||||
// flag.Parse()
|
||||
// pool = newPool(*redisServer, *redisPassword)
|
||||
// ...
|
||||
// flag.Parse()
|
||||
// pool = newPool(*redisServer)
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// A request handler gets a connection from the pool and closes the connection
|
||||
@ -88,11 +74,47 @@ var (
|
||||
// func serveHome(w http.ResponseWriter, r *http.Request) {
|
||||
// conn := pool.Get()
|
||||
// defer conn.Close()
|
||||
// ....
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// Use the Dial function to authenticate connections with the AUTH command or
|
||||
// select a database with the SELECT command:
|
||||
//
|
||||
// pool := &redis.Pool{
|
||||
// // Other pool configuration not shown in this example.
|
||||
// Dial: func () (redis.Conn, error) {
|
||||
// c, err := redis.Dial("tcp", server)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// if _, err := c.Do("AUTH", password); err != nil {
|
||||
// c.Close()
|
||||
// return nil, err
|
||||
// }
|
||||
// if _, err := c.Do("SELECT", db); err != nil {
|
||||
// c.Close()
|
||||
// return nil, err
|
||||
// }
|
||||
// return c, nil
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Use the TestOnBorrow function to check the health of an idle connection
|
||||
// before the connection is returned to the application. This example PINGs
|
||||
// connections that have been idle more than a minute:
|
||||
//
|
||||
// pool := &redis.Pool{
|
||||
// // Other pool configuration not shown in this example.
|
||||
// TestOnBorrow: func(c redis.Conn, t time.Time) error {
|
||||
// if time.Since(t) < time.Minute {
|
||||
// return nil
|
||||
// }
|
||||
// _, err := c.Do("PING")
|
||||
// return err
|
||||
// },
|
||||
// }
|
||||
//
|
||||
type Pool struct {
|
||||
|
||||
// Dial is an application supplied function for creating and configuring a
|
||||
// connection.
|
||||
//
|
||||
@ -158,7 +180,27 @@ func (p *Pool) Get() Conn {
|
||||
return &pooledConnection{p: p, c: c}
|
||||
}
|
||||
|
||||
// ActiveCount returns the number of active connections in the pool.
|
||||
// PoolStats contains pool statistics.
|
||||
type PoolStats struct {
|
||||
// ActiveCount is the number of connections in the pool. The count includes idle connections and connections in use.
|
||||
ActiveCount int
|
||||
// IdleCount is the number of idle connections in the pool.
|
||||
IdleCount int
|
||||
}
|
||||
|
||||
// Stats returns pool's statistics.
|
||||
func (p *Pool) Stats() PoolStats {
|
||||
p.mu.Lock()
|
||||
stats := PoolStats{
|
||||
ActiveCount: p.active,
|
||||
IdleCount: p.idle.Len(),
|
||||
}
|
||||
p.mu.Unlock()
|
||||
|
||||
return stats
|
||||
}
|
||||
|
||||
// ActiveCount returns the number of connections in the pool. The count includes idle connections and connections in use.
|
||||
func (p *Pool) ActiveCount() int {
|
||||
p.mu.Lock()
|
||||
active := p.active
|
||||
@ -166,6 +208,14 @@ func (p *Pool) ActiveCount() int {
|
||||
return active
|
||||
}
|
||||
|
||||
// IdleCount returns the number of idle connections in the pool.
|
||||
func (p *Pool) IdleCount() int {
|
||||
p.mu.Lock()
|
||||
idle := p.idle.Len()
|
||||
p.mu.Unlock()
|
||||
return idle
|
||||
}
|
||||
|
||||
// Close releases the resources used by the pool.
|
||||
func (p *Pool) Close() error {
|
||||
p.mu.Lock()
|
||||
@ -218,7 +268,6 @@ func (p *Pool) get() (Conn, error) {
|
||||
}
|
||||
|
||||
for {
|
||||
|
||||
// Get idle connection.
|
||||
|
||||
for i, n := 0, p.idle.Len(); i < n; i++ {
|
||||
|
6
src/vendor/github.com/garyburd/redigo/redis/pubsub.go
generated
vendored
@ -18,7 +18,6 @@ import "errors"
|
||||
|
||||
// Subscription represents a subscribe or unsubscribe notification.
|
||||
type Subscription struct {
|
||||
|
||||
// Kind is "subscribe", "unsubscribe", "psubscribe" or "punsubscribe"
|
||||
Kind string
|
||||
|
||||
@ -31,7 +30,6 @@ type Subscription struct {
|
||||
|
||||
// Message represents a message notification.
|
||||
type Message struct {
|
||||
|
||||
// The originating channel.
|
||||
Channel string
|
||||
|
||||
@ -41,7 +39,6 @@ type Message struct {
|
||||
|
||||
// PMessage represents a pmessage notification.
|
||||
type PMessage struct {
|
||||
|
||||
// The matched pattern.
|
||||
Pattern string
|
||||
|
||||
@ -94,6 +91,9 @@ func (c PubSubConn) PUnsubscribe(channel ...interface{}) error {
|
||||
}
|
||||
|
||||
// Ping sends a PING to the server with the specified data.
|
||||
//
|
||||
// The connection must be subscribed to at least one channel or pattern when
|
||||
// calling this method.
|
||||
func (c PubSubConn) Ping(data string) error {
|
||||
c.Conn.Send("PING", data)
|
||||
return c.Conn.Flush()
|
||||
|
25
src/vendor/github.com/garyburd/redigo/redis/redis.go
generated
vendored
@ -24,10 +24,7 @@ type Conn interface {
|
||||
// Close closes the connection.
|
||||
Close() error
|
||||
|
||||
// Err returns a non-nil value if the connection is broken. The returned
|
||||
// value is either the first non-nil value returned from the underlying
|
||||
// network connection or a protocol parsing error. Applications should
|
||||
// close broken connections.
|
||||
// Err returns a non-nil value when the connection is not usable.
|
||||
Err() error
|
||||
|
||||
// Do sends a command to the server and returns the received reply.
|
||||
@ -42,3 +39,23 @@ type Conn interface {
|
||||
// Receive receives a single reply from the Redis server
|
||||
Receive() (reply interface{}, err error)
|
||||
}
|
||||
|
||||
// Argument is the interface implemented by an object which wants to control how
|
||||
// the object is converted to Redis bulk strings.
|
||||
type Argument interface {
|
||||
// RedisArg returns a value to be encoded as a bulk string per the
|
||||
// conversions listed in the section 'Executing Commands'.
|
||||
// Implementations should typically return a []byte or string.
|
||||
RedisArg() interface{}
|
||||
}
|
||||
|
||||
// Scanner is implemented by an object which wants to control its value is
|
||||
// interpreted when read from Redis.
|
||||
type Scanner interface {
|
||||
// RedisScan assigns a value from a Redis value. The argument src is one of
|
||||
// the reply types listed in the section `Executing Commands`.
|
||||
//
|
||||
// An error should be returned if the value cannot be stored without
|
||||
// loss of information.
|
||||
RedisScan(src interface{}) error
|
||||
}
|
||||
|
202
src/vendor/github.com/garyburd/redigo/redis/reply.go
generated
vendored
@ -243,34 +243,67 @@ func Values(reply interface{}, err error) ([]interface{}, error) {
|
||||
return nil, fmt.Errorf("redigo: unexpected type for Values, got type %T", reply)
|
||||
}
|
||||
|
||||
func sliceHelper(reply interface{}, err error, name string, makeSlice func(int), assign func(int, interface{}) error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch reply := reply.(type) {
|
||||
case []interface{}:
|
||||
makeSlice(len(reply))
|
||||
for i := range reply {
|
||||
if reply[i] == nil {
|
||||
continue
|
||||
}
|
||||
if err := assign(i, reply[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
case nil:
|
||||
return ErrNil
|
||||
case Error:
|
||||
return reply
|
||||
}
|
||||
return fmt.Errorf("redigo: unexpected type for %s, got type %T", name, reply)
|
||||
}
|
||||
|
||||
// Float64s is a helper that converts an array command reply to a []float64. If
|
||||
// err is not equal to nil, then Float64s returns nil, err. Nil array items are
|
||||
// converted to 0 in the output slice. Floats64 returns an error if an array
|
||||
// item is not a bulk string or nil.
|
||||
func Float64s(reply interface{}, err error) ([]float64, error) {
|
||||
var result []float64
|
||||
err = sliceHelper(reply, err, "Float64s", func(n int) { result = make([]float64, n) }, func(i int, v interface{}) error {
|
||||
p, ok := v.([]byte)
|
||||
if !ok {
|
||||
return fmt.Errorf("redigo: unexpected element type for Floats64, got type %T", v)
|
||||
}
|
||||
f, err := strconv.ParseFloat(string(p), 64)
|
||||
result[i] = f
|
||||
return err
|
||||
})
|
||||
return result, err
|
||||
}
|
||||
|
||||
// Strings is a helper that converts an array command reply to a []string. If
|
||||
// err is not equal to nil, then Strings returns nil, err. Nil array items are
|
||||
// converted to "" in the output slice. Strings returns an error if an array
|
||||
// item is not a bulk string or nil.
|
||||
func Strings(reply interface{}, err error) ([]string, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch reply := reply.(type) {
|
||||
case []interface{}:
|
||||
result := make([]string, len(reply))
|
||||
for i := range reply {
|
||||
if reply[i] == nil {
|
||||
continue
|
||||
}
|
||||
p, ok := reply[i].([]byte)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("redigo: unexpected element type for Strings, got type %T", reply[i])
|
||||
}
|
||||
result[i] = string(p)
|
||||
var result []string
|
||||
err = sliceHelper(reply, err, "Strings", func(n int) { result = make([]string, n) }, func(i int, v interface{}) error {
|
||||
switch v := v.(type) {
|
||||
case string:
|
||||
result[i] = v
|
||||
return nil
|
||||
case []byte:
|
||||
result[i] = string(v)
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("redigo: unexpected element type for Strings, got type %T", v)
|
||||
}
|
||||
return result, nil
|
||||
case nil:
|
||||
return nil, ErrNil
|
||||
case Error:
|
||||
return nil, reply
|
||||
}
|
||||
return nil, fmt.Errorf("redigo: unexpected type for Strings, got type %T", reply)
|
||||
})
|
||||
return result, err
|
||||
}
|
||||
|
||||
// ByteSlices is a helper that converts an array command reply to a [][]byte.
|
||||
@ -278,43 +311,64 @@ func Strings(reply interface{}, err error) ([]string, error) {
|
||||
// items are stay nil. ByteSlices returns an error if an array item is not a
|
||||
// bulk string or nil.
|
||||
func ByteSlices(reply interface{}, err error) ([][]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch reply := reply.(type) {
|
||||
case []interface{}:
|
||||
result := make([][]byte, len(reply))
|
||||
for i := range reply {
|
||||
if reply[i] == nil {
|
||||
continue
|
||||
}
|
||||
p, ok := reply[i].([]byte)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("redigo: unexpected element type for ByteSlices, got type %T", reply[i])
|
||||
}
|
||||
result[i] = p
|
||||
var result [][]byte
|
||||
err = sliceHelper(reply, err, "ByteSlices", func(n int) { result = make([][]byte, n) }, func(i int, v interface{}) error {
|
||||
p, ok := v.([]byte)
|
||||
if !ok {
|
||||
return fmt.Errorf("redigo: unexpected element type for ByteSlices, got type %T", v)
|
||||
}
|
||||
return result, nil
|
||||
case nil:
|
||||
return nil, ErrNil
|
||||
case Error:
|
||||
return nil, reply
|
||||
}
|
||||
return nil, fmt.Errorf("redigo: unexpected type for ByteSlices, got type %T", reply)
|
||||
result[i] = p
|
||||
return nil
|
||||
})
|
||||
return result, err
|
||||
}
|
||||
|
||||
// Ints is a helper that converts an array command reply to a []int. If
|
||||
// err is not equal to nil, then Ints returns nil, err.
|
||||
// Int64s is a helper that converts an array command reply to a []int64.
|
||||
// If err is not equal to nil, then Int64s returns nil, err. Nil array
|
||||
// items are stay nil. Int64s returns an error if an array item is not a
|
||||
// bulk string or nil.
|
||||
func Int64s(reply interface{}, err error) ([]int64, error) {
|
||||
var result []int64
|
||||
err = sliceHelper(reply, err, "Int64s", func(n int) { result = make([]int64, n) }, func(i int, v interface{}) error {
|
||||
switch v := v.(type) {
|
||||
case int64:
|
||||
result[i] = v
|
||||
return nil
|
||||
case []byte:
|
||||
n, err := strconv.ParseInt(string(v), 10, 64)
|
||||
result[i] = n
|
||||
return err
|
||||
default:
|
||||
return fmt.Errorf("redigo: unexpected element type for Int64s, got type %T", v)
|
||||
}
|
||||
})
|
||||
return result, err
|
||||
}
|
||||
|
||||
// Ints is a helper that converts an array command reply to a []in.
|
||||
// If err is not equal to nil, then Ints returns nil, err. Nil array
|
||||
// items are stay nil. Ints returns an error if an array item is not a
|
||||
// bulk string or nil.
|
||||
func Ints(reply interface{}, err error) ([]int, error) {
|
||||
var ints []int
|
||||
values, err := Values(reply, err)
|
||||
if err != nil {
|
||||
return ints, err
|
||||
}
|
||||
if err := ScanSlice(values, &ints); err != nil {
|
||||
return ints, err
|
||||
}
|
||||
return ints, nil
|
||||
var result []int
|
||||
err = sliceHelper(reply, err, "Ints", func(n int) { result = make([]int, n) }, func(i int, v interface{}) error {
|
||||
switch v := v.(type) {
|
||||
case int64:
|
||||
n := int(v)
|
||||
if int64(n) != v {
|
||||
return strconv.ErrRange
|
||||
}
|
||||
result[i] = n
|
||||
return nil
|
||||
case []byte:
|
||||
n, err := strconv.Atoi(string(v))
|
||||
result[i] = n
|
||||
return err
|
||||
default:
|
||||
return fmt.Errorf("redigo: unexpected element type for Ints, got type %T", v)
|
||||
}
|
||||
})
|
||||
return result, err
|
||||
}
|
||||
|
||||
// StringMap is a helper that converts an array of strings (alternating key, value)
|
||||
@ -333,7 +387,7 @@ func StringMap(result interface{}, err error) (map[string]string, error) {
|
||||
key, okKey := values[i].([]byte)
|
||||
value, okValue := values[i+1].([]byte)
|
||||
if !okKey || !okValue {
|
||||
return nil, errors.New("redigo: ScanMap key not a bulk string value")
|
||||
return nil, errors.New("redigo: StringMap key not a bulk string value")
|
||||
}
|
||||
m[string(key)] = string(value)
|
||||
}
|
||||
@ -355,7 +409,7 @@ func IntMap(result interface{}, err error) (map[string]int, error) {
|
||||
for i := 0; i < len(values); i += 2 {
|
||||
key, ok := values[i].([]byte)
|
||||
if !ok {
|
||||
return nil, errors.New("redigo: ScanMap key not a bulk string value")
|
||||
return nil, errors.New("redigo: IntMap key not a bulk string value")
|
||||
}
|
||||
value, err := Int(values[i+1], nil)
|
||||
if err != nil {
|
||||
@ -381,7 +435,7 @@ func Int64Map(result interface{}, err error) (map[string]int64, error) {
|
||||
for i := 0; i < len(values); i += 2 {
|
||||
key, ok := values[i].([]byte)
|
||||
if !ok {
|
||||
return nil, errors.New("redigo: ScanMap key not a bulk string value")
|
||||
return nil, errors.New("redigo: Int64Map key not a bulk string value")
|
||||
}
|
||||
value, err := Int64(values[i+1], nil)
|
||||
if err != nil {
|
||||
@ -391,3 +445,35 @@ func Int64Map(result interface{}, err error) (map[string]int64, error) {
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// Positions is a helper that converts an array of positions (lat, long)
|
||||
// into a [][2]float64. The GEOPOS command returns replies in this format.
|
||||
func Positions(result interface{}, err error) ([]*[2]float64, error) {
|
||||
values, err := Values(result, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
positions := make([]*[2]float64, len(values))
|
||||
for i := range values {
|
||||
if values[i] == nil {
|
||||
continue
|
||||
}
|
||||
p, ok := values[i].([]interface{})
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("redigo: unexpected element type for interface slice, got type %T", values[i])
|
||||
}
|
||||
if len(p) != 2 {
|
||||
return nil, fmt.Errorf("redigo: unexpected number of values for a member position, got %d", len(p))
|
||||
}
|
||||
lat, err := Float64(p[0], nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
long, err := Float64(p[1], nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
positions[i] = &[2]float64{lat, long}
|
||||
}
|
||||
return positions, nil
|
||||
}
|
||||
|
34
src/vendor/github.com/garyburd/redigo/redis/scan.go
generated
vendored
@ -110,6 +110,25 @@ func convertAssignInt(d reflect.Value, s int64) (err error) {
|
||||
}
|
||||
|
||||
func convertAssignValue(d reflect.Value, s interface{}) (err error) {
|
||||
if d.Kind() != reflect.Ptr {
|
||||
if d.CanAddr() {
|
||||
d2 := d.Addr()
|
||||
if d2.CanInterface() {
|
||||
if scanner, ok := d2.Interface().(Scanner); ok {
|
||||
return scanner.RedisScan(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if d.CanInterface() {
|
||||
// Already a reflect.Ptr
|
||||
if d.IsNil() {
|
||||
d.Set(reflect.New(d.Type().Elem()))
|
||||
}
|
||||
if scanner, ok := d.Interface().(Scanner); ok {
|
||||
return scanner.RedisScan(s)
|
||||
}
|
||||
}
|
||||
|
||||
switch s := s.(type) {
|
||||
case []byte:
|
||||
err = convertAssignBulkString(d, s)
|
||||
@ -135,11 +154,15 @@ func convertAssignArray(d reflect.Value, s []interface{}) error {
|
||||
}
|
||||
|
||||
func convertAssign(d interface{}, s interface{}) (err error) {
|
||||
if scanner, ok := d.(Scanner); ok {
|
||||
return scanner.RedisScan(s)
|
||||
}
|
||||
|
||||
// Handle the most common destination types using type switches and
|
||||
// fall back to reflection for all other types.
|
||||
switch s := s.(type) {
|
||||
case nil:
|
||||
// ingore
|
||||
// ignore
|
||||
case []byte:
|
||||
switch d := d.(type) {
|
||||
case *string:
|
||||
@ -186,7 +209,11 @@ func convertAssign(d interface{}, s interface{}) (err error) {
|
||||
case string:
|
||||
switch d := d.(type) {
|
||||
case *string:
|
||||
*d = string(s)
|
||||
*d = s
|
||||
case *interface{}:
|
||||
*d = s
|
||||
case nil:
|
||||
// skip value
|
||||
default:
|
||||
err = cannotConvert(reflect.ValueOf(d), s)
|
||||
}
|
||||
@ -215,6 +242,8 @@ func convertAssign(d interface{}, s interface{}) (err error) {
|
||||
|
||||
// Scan copies from src to the values pointed at by dest.
|
||||
//
|
||||
// Scan uses RedisScan if available otherwise:
|
||||
//
|
||||
// The values pointed at by dest must be an integer, float, boolean, string,
|
||||
// []byte, interface{} or slices of these types. Scan uses the standard strconv
|
||||
// package to convert bulk strings to numeric and boolean types.
|
||||
@ -355,6 +384,7 @@ var errScanStructValue = errors.New("redigo.ScanStruct: value must be non-nil po
|
||||
//
|
||||
// Fields with the tag redis:"-" are ignored.
|
||||
//
|
||||
// Each field uses RedisScan if available otherwise:
|
||||
// Integer, float, boolean, string and []byte fields are supported. Scan uses the
|
||||
// standard strconv package to convert bulk string values to numeric and
|
||||
// boolean types.
|
||||
|
5
src/vendor/github.com/garyburd/redigo/redis/script.go
generated
vendored
@ -55,6 +55,11 @@ func (s *Script) args(spec string, keysAndArgs []interface{}) []interface{} {
|
||||
return args
|
||||
}
|
||||
|
||||
// Hash returns the script hash.
|
||||
func (s *Script) Hash() string {
|
||||
return s.hash
|
||||
}
|
||||
|
||||
// Do evaluates the script. Under the covers, Do optimistically evaluates the
|
||||
// script using the EVALSHA command. If the command fails because the script is
|
||||
// not loaded, then Do evaluates the script using the EVAL command (thus
|
||||
|
23
src/vendor/github.com/stretchr/objx/LICENSE.md
generated
vendored
@ -1,23 +0,0 @@
|
||||
objx - by Mat Ryer and Tyler Bunnell
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Stretchr, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
3
src/vendor/github.com/stretchr/objx/README.md
generated
vendored
@ -1,3 +0,0 @@
|
||||
# objx
|
||||
|
||||
* Jump into the [API Documentation](http://godoc.org/github.com/stretchr/objx)
|
179
src/vendor/github.com/stretchr/objx/accessors.go
generated
vendored
@ -1,179 +0,0 @@
|
||||
package objx
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// arrayAccesRegexString is the regex used to extract the array number
|
||||
// from the access path
|
||||
const arrayAccesRegexString = `^(.+)\[([0-9]+)\]$`
|
||||
|
||||
// arrayAccesRegex is the compiled arrayAccesRegexString
|
||||
var arrayAccesRegex = regexp.MustCompile(arrayAccesRegexString)
|
||||
|
||||
// Get gets the value using the specified selector and
|
||||
// returns it inside a new Obj object.
|
||||
//
|
||||
// If it cannot find the value, Get will return a nil
|
||||
// value inside an instance of Obj.
|
||||
//
|
||||
// Get can only operate directly on map[string]interface{} and []interface.
|
||||
//
|
||||
// Example
|
||||
//
|
||||
// To access the title of the third chapter of the second book, do:
|
||||
//
|
||||
// o.Get("books[1].chapters[2].title")
|
||||
func (m Map) Get(selector string) *Value {
|
||||
rawObj := access(m, selector, nil, false, false)
|
||||
return &Value{data: rawObj}
|
||||
}
|
||||
|
||||
// Set sets the value using the specified selector and
|
||||
// returns the object on which Set was called.
|
||||
//
|
||||
// Set can only operate directly on map[string]interface{} and []interface
|
||||
//
|
||||
// Example
|
||||
//
|
||||
// To set the title of the third chapter of the second book, do:
|
||||
//
|
||||
// o.Set("books[1].chapters[2].title","Time to Go")
|
||||
func (m Map) Set(selector string, value interface{}) Map {
|
||||
access(m, selector, value, true, false)
|
||||
return m
|
||||
}
|
||||
|
||||
// access accesses the object using the selector and performs the
|
||||
// appropriate action.
|
||||
func access(current, selector, value interface{}, isSet, panics bool) interface{} {
|
||||
|
||||
switch selector.(type) {
|
||||
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
|
||||
|
||||
if array, ok := current.([]interface{}); ok {
|
||||
index := intFromInterface(selector)
|
||||
|
||||
if index >= len(array) {
|
||||
if panics {
|
||||
panic(fmt.Sprintf("objx: Index %d is out of range. Slice only contains %d items.", index, len(array)))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
return array[index]
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
case string:
|
||||
|
||||
selStr := selector.(string)
|
||||
selSegs := strings.SplitN(selStr, PathSeparator, 2)
|
||||
thisSel := selSegs[0]
|
||||
index := -1
|
||||
var err error
|
||||
|
||||
// https://github.com/stretchr/objx/issues/12
|
||||
if strings.Contains(thisSel, "[") {
|
||||
|
||||
arrayMatches := arrayAccesRegex.FindStringSubmatch(thisSel)
|
||||
|
||||
if len(arrayMatches) > 0 {
|
||||
|
||||
// Get the key into the map
|
||||
thisSel = arrayMatches[1]
|
||||
|
||||
// Get the index into the array at the key
|
||||
index, err = strconv.Atoi(arrayMatches[2])
|
||||
|
||||
if err != nil {
|
||||
// This should never happen. If it does, something has gone
|
||||
// seriously wrong. Panic.
|
||||
panic("objx: Array index is not an integer. Must use array[int].")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if curMap, ok := current.(Map); ok {
|
||||
current = map[string]interface{}(curMap)
|
||||
}
|
||||
|
||||
// get the object in question
|
||||
switch current.(type) {
|
||||
case map[string]interface{}:
|
||||
curMSI := current.(map[string]interface{})
|
||||
if len(selSegs) <= 1 && isSet {
|
||||
curMSI[thisSel] = value
|
||||
return nil
|
||||
} else {
|
||||
current = curMSI[thisSel]
|
||||
}
|
||||
default:
|
||||
current = nil
|
||||
}
|
||||
|
||||
if current == nil && panics {
|
||||
panic(fmt.Sprintf("objx: '%v' invalid on object.", selector))
|
||||
}
|
||||
|
||||
// do we need to access the item of an array?
|
||||
if index > -1 {
|
||||
if array, ok := current.([]interface{}); ok {
|
||||
if index < len(array) {
|
||||
current = array[index]
|
||||
} else {
|
||||
if panics {
|
||||
panic(fmt.Sprintf("objx: Index %d is out of range. Slice only contains %d items.", index, len(array)))
|
||||
}
|
||||
current = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(selSegs) > 1 {
|
||||
current = access(current, selSegs[1], value, isSet, panics)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return current
|
||||
|
||||
}
|
||||
|
||||
// intFromInterface converts an interface object to the largest
|
||||
// representation of an unsigned integer using a type switch and
|
||||
// assertions
|
||||
func intFromInterface(selector interface{}) int {
|
||||
var value int
|
||||
switch selector.(type) {
|
||||
case int:
|
||||
value = selector.(int)
|
||||
case int8:
|
||||
value = int(selector.(int8))
|
||||
case int16:
|
||||
value = int(selector.(int16))
|
||||
case int32:
|
||||
value = int(selector.(int32))
|
||||
case int64:
|
||||
value = int(selector.(int64))
|
||||
case uint:
|
||||
value = int(selector.(uint))
|
||||
case uint8:
|
||||
value = int(selector.(uint8))
|
||||
case uint16:
|
||||
value = int(selector.(uint16))
|
||||
case uint32:
|
||||
value = int(selector.(uint32))
|
||||
case uint64:
|
||||
value = int(selector.(uint64))
|
||||
default:
|
||||
panic("objx: array access argument is not an integer type (this should never happen)")
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
13
src/vendor/github.com/stretchr/objx/constants.go
generated
vendored
@ -1,13 +0,0 @@
|
||||
package objx
|
||||
|
||||
const (
|
||||
// PathSeparator is the character used to separate the elements
|
||||
// of the keypath.
|
||||
//
|
||||
// For example, `location.address.city`
|
||||
PathSeparator string = "."
|
||||
|
||||
// SignatureSeparator is the character that is used to
|
||||
// separate the Base64 string from the security signature.
|
||||
SignatureSeparator = "_"
|
||||
)
|
117
src/vendor/github.com/stretchr/objx/conversions.go
generated
vendored
@ -1,117 +0,0 @@
|
||||
package objx
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// JSON converts the contained object to a JSON string
|
||||
// representation
|
||||
func (m Map) JSON() (string, error) {
|
||||
|
||||
result, err := json.Marshal(m)
|
||||
|
||||
if err != nil {
|
||||
err = errors.New("objx: JSON encode failed with: " + err.Error())
|
||||
}
|
||||
|
||||
return string(result), err
|
||||
|
||||
}
|
||||
|
||||
// MustJSON converts the contained object to a JSON string
|
||||
// representation and panics if there is an error
|
||||
func (m Map) MustJSON() string {
|
||||
result, err := m.JSON()
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Base64 converts the contained object to a Base64 string
|
||||
// representation of the JSON string representation
|
||||
func (m Map) Base64() (string, error) {
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
jsonData, err := m.JSON()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
encoder := base64.NewEncoder(base64.StdEncoding, &buf)
|
||||
encoder.Write([]byte(jsonData))
|
||||
encoder.Close()
|
||||
|
||||
return buf.String(), nil
|
||||
|
||||
}
|
||||
|
||||
// MustBase64 converts the contained object to a Base64 string
|
||||
// representation of the JSON string representation and panics
|
||||
// if there is an error
|
||||
func (m Map) MustBase64() string {
|
||||
result, err := m.Base64()
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// SignedBase64 converts the contained object to a Base64 string
|
||||
// representation of the JSON string representation and signs it
|
||||
// using the provided key.
|
||||
func (m Map) SignedBase64(key string) (string, error) {
|
||||
|
||||
base64, err := m.Base64()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
sig := HashWithKey(base64, key)
|
||||
|
||||
return base64 + SignatureSeparator + sig, nil
|
||||
|
||||
}
|
||||
|
||||
// MustSignedBase64 converts the contained object to a Base64 string
|
||||
// representation of the JSON string representation and signs it
|
||||
// using the provided key and panics if there is an error
|
||||
func (m Map) MustSignedBase64(key string) string {
|
||||
result, err := m.SignedBase64(key)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/*
|
||||
URL Query
|
||||
------------------------------------------------
|
||||
*/
|
||||
|
||||
// URLValues creates a url.Values object from an Obj. This
|
||||
// function requires that the wrapped object be a map[string]interface{}
|
||||
func (m Map) URLValues() url.Values {
|
||||
|
||||
vals := make(url.Values)
|
||||
|
||||
for k, v := range m {
|
||||
//TODO: can this be done without sprintf?
|
||||
vals.Set(k, fmt.Sprintf("%v", v))
|
||||
}
|
||||
|
||||
return vals
|
||||
}
|
||||
|
||||
// URLQuery gets an encoded URL query representing the given
|
||||
// Obj. This function requires that the wrapped object be a
|
||||
// map[string]interface{}
|
||||
func (m Map) URLQuery() (string, error) {
|
||||
return m.URLValues().Encode(), nil
|
||||
}
|
72
src/vendor/github.com/stretchr/objx/doc.go
generated
vendored
@ -1,72 +0,0 @@
|
||||
// objx - Go package for dealing with maps, slices, JSON and other data.
|
||||
//
|
||||
// Overview
|
||||
//
|
||||
// Objx provides the `objx.Map` type, which is a `map[string]interface{}` that exposes
|
||||
// a powerful `Get` method (among others) that allows you to easily and quickly get
|
||||
// access to data within the map, without having to worry too much about type assertions,
|
||||
// missing data, default values etc.
|
||||
//
|
||||
// Pattern
|
||||
//
|
||||
// Objx uses a preditable pattern to make access data from within `map[string]interface{}'s
|
||||
// easy.
|
||||
//
|
||||
// Call one of the `objx.` functions to create your `objx.Map` to get going:
|
||||
//
|
||||
// m, err := objx.FromJSON(json)
|
||||
//
|
||||
// NOTE: Any methods or functions with the `Must` prefix will panic if something goes wrong,
|
||||
// the rest will be optimistic and try to figure things out without panicking.
|
||||
//
|
||||
// Use `Get` to access the value you're interested in. You can use dot and array
|
||||
// notation too:
|
||||
//
|
||||
// m.Get("places[0].latlng")
|
||||
//
|
||||
// Once you have saught the `Value` you're interested in, you can use the `Is*` methods
|
||||
// to determine its type.
|
||||
//
|
||||
// if m.Get("code").IsStr() { /* ... */ }
|
||||
//
|
||||
// Or you can just assume the type, and use one of the strong type methods to
|
||||
// extract the real value:
|
||||
//
|
||||
// m.Get("code").Int()
|
||||
//
|
||||
// If there's no value there (or if it's the wrong type) then a default value
|
||||
// will be returned, or you can be explicit about the default value.
|
||||
//
|
||||
// Get("code").Int(-1)
|
||||
//
|
||||
// If you're dealing with a slice of data as a value, Objx provides many useful
|
||||
// methods for iterating, manipulating and selecting that data. You can find out more
|
||||
// by exploring the index below.
|
||||
//
|
||||
// Reading data
|
||||
//
|
||||
// A simple example of how to use Objx:
|
||||
//
|
||||
// // use MustFromJSON to make an objx.Map from some JSON
|
||||
// m := objx.MustFromJSON(`{"name": "Mat", "age": 30}`)
|
||||
//
|
||||
// // get the details
|
||||
// name := m.Get("name").Str()
|
||||
// age := m.Get("age").Int()
|
||||
//
|
||||
// // get their nickname (or use their name if they
|
||||
// // don't have one)
|
||||
// nickname := m.Get("nickname").Str(name)
|
||||
//
|
||||
// Ranging
|
||||
//
|
||||
// Since `objx.Map` is a `map[string]interface{}` you can treat it as such. For
|
||||
// example, to `range` the data, do what you would expect:
|
||||
//
|
||||
// m := objx.MustFromJSON(json)
|
||||
// for key, value := range m {
|
||||
//
|
||||
// /* ... do your magic ... */
|
||||
//
|
||||
// }
|
||||
package objx
|
222
src/vendor/github.com/stretchr/objx/map.go
generated
vendored
@ -1,222 +0,0 @@
|
||||
package objx
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// MSIConvertable is an interface that defines methods for converting your
|
||||
// custom types to a map[string]interface{} representation.
|
||||
type MSIConvertable interface {
|
||||
// MSI gets a map[string]interface{} (msi) representing the
|
||||
// object.
|
||||
MSI() map[string]interface{}
|
||||
}
|
||||
|
||||
// Map provides extended functionality for working with
|
||||
// untyped data, in particular map[string]interface (msi).
|
||||
type Map map[string]interface{}
|
||||
|
||||
// Value returns the internal value instance
|
||||
func (m Map) Value() *Value {
|
||||
return &Value{data: m}
|
||||
}
|
||||
|
||||
// Nil represents a nil Map.
|
||||
var Nil Map = New(nil)
|
||||
|
||||
// New creates a new Map containing the map[string]interface{} in the data argument.
|
||||
// If the data argument is not a map[string]interface, New attempts to call the
|
||||
// MSI() method on the MSIConvertable interface to create one.
|
||||
func New(data interface{}) Map {
|
||||
if _, ok := data.(map[string]interface{}); !ok {
|
||||
if converter, ok := data.(MSIConvertable); ok {
|
||||
data = converter.MSI()
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return Map(data.(map[string]interface{}))
|
||||
}
|
||||
|
||||
// MSI creates a map[string]interface{} and puts it inside a new Map.
|
||||
//
|
||||
// The arguments follow a key, value pattern.
|
||||
//
|
||||
// Panics
|
||||
//
|
||||
// Panics if any key arugment is non-string or if there are an odd number of arguments.
|
||||
//
|
||||
// Example
|
||||
//
|
||||
// To easily create Maps:
|
||||
//
|
||||
// m := objx.MSI("name", "Mat", "age", 29, "subobj", objx.MSI("active", true))
|
||||
//
|
||||
// // creates an Map equivalent to
|
||||
// m := objx.New(map[string]interface{}{"name": "Mat", "age": 29, "subobj": map[string]interface{}{"active": true}})
|
||||
func MSI(keyAndValuePairs ...interface{}) Map {
|
||||
|
||||
newMap := make(map[string]interface{})
|
||||
keyAndValuePairsLen := len(keyAndValuePairs)
|
||||
|
||||
if keyAndValuePairsLen%2 != 0 {
|
||||
panic("objx: MSI must have an even number of arguments following the 'key, value' pattern.")
|
||||
}
|
||||
|
||||
for i := 0; i < keyAndValuePairsLen; i = i + 2 {
|
||||
|
||||
key := keyAndValuePairs[i]
|
||||
value := keyAndValuePairs[i+1]
|
||||
|
||||
// make sure the key is a string
|
||||
keyString, keyStringOK := key.(string)
|
||||
if !keyStringOK {
|
||||
panic("objx: MSI must follow 'string, interface{}' pattern. " + keyString + " is not a valid key.")
|
||||
}
|
||||
|
||||
newMap[keyString] = value
|
||||
|
||||
}
|
||||
|
||||
return New(newMap)
|
||||
}
|
||||
|
||||
// ****** Conversion Constructors
|
||||
|
||||
// MustFromJSON creates a new Map containing the data specified in the
|
||||
// jsonString.
|
||||
//
|
||||
// Panics if the JSON is invalid.
|
||||
func MustFromJSON(jsonString string) Map {
|
||||
o, err := FromJSON(jsonString)
|
||||
|
||||
if err != nil {
|
||||
panic("objx: MustFromJSON failed with error: " + err.Error())
|
||||
}
|
||||
|
||||
return o
|
||||
}
|
||||
|
||||
// FromJSON creates a new Map containing the data specified in the
|
||||
// jsonString.
|
||||
//
|
||||
// Returns an error if the JSON is invalid.
|
||||
func FromJSON(jsonString string) (Map, error) {
|
||||
|
||||
var data interface{}
|
||||
err := json.Unmarshal([]byte(jsonString), &data)
|
||||
|
||||
if err != nil {
|
||||
return Nil, err
|
||||
}
|
||||
|
||||
return New(data), nil
|
||||
|
||||
}
|
||||
|
||||
// FromBase64 creates a new Obj containing the data specified
|
||||
// in the Base64 string.
|
||||
//
|
||||
// The string is an encoded JSON string returned by Base64
|
||||
func FromBase64(base64String string) (Map, error) {
|
||||
|
||||
decoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(base64String))
|
||||
|
||||
decoded, err := ioutil.ReadAll(decoder)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return FromJSON(string(decoded))
|
||||
}
|
||||
|
||||
// MustFromBase64 creates a new Obj containing the data specified
|
||||
// in the Base64 string and panics if there is an error.
|
||||
//
|
||||
// The string is an encoded JSON string returned by Base64
|
||||
func MustFromBase64(base64String string) Map {
|
||||
|
||||
result, err := FromBase64(base64String)
|
||||
|
||||
if err != nil {
|
||||
panic("objx: MustFromBase64 failed with error: " + err.Error())
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// FromSignedBase64 creates a new Obj containing the data specified
|
||||
// in the Base64 string.
|
||||
//
|
||||
// The string is an encoded JSON string returned by SignedBase64
|
||||
func FromSignedBase64(base64String, key string) (Map, error) {
|
||||
parts := strings.Split(base64String, SignatureSeparator)
|
||||
if len(parts) != 2 {
|
||||
return nil, errors.New("objx: Signed base64 string is malformed.")
|
||||
}
|
||||
|
||||
sig := HashWithKey(parts[0], key)
|
||||
if parts[1] != sig {
|
||||
return nil, errors.New("objx: Signature for base64 data does not match.")
|
||||
}
|
||||
|
||||
return FromBase64(parts[0])
|
||||
}
|
||||
|
||||
// MustFromSignedBase64 creates a new Obj containing the data specified
|
||||
// in the Base64 string and panics if there is an error.
|
||||
//
|
||||
// The string is an encoded JSON string returned by Base64
|
||||
func MustFromSignedBase64(base64String, key string) Map {
|
||||
|
||||
result, err := FromSignedBase64(base64String, key)
|
||||
|
||||
if err != nil {
|
||||
panic("objx: MustFromSignedBase64 failed with error: " + err.Error())
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// FromURLQuery generates a new Obj by parsing the specified
|
||||
// query.
|
||||
//
|
||||
// For queries with multiple values, the first value is selected.
|
||||
func FromURLQuery(query string) (Map, error) {
|
||||
|
||||
vals, err := url.ParseQuery(query)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m := make(map[string]interface{})
|
||||
for k, vals := range vals {
|
||||
m[k] = vals[0]
|
||||
}
|
||||
|
||||
return New(m), nil
|
||||
}
|
||||
|
||||
// MustFromURLQuery generates a new Obj by parsing the specified
|
||||
// query.
|
||||
//
|
||||
// For queries with multiple values, the first value is selected.
|
||||
//
|
||||
// Panics if it encounters an error
|
||||
func MustFromURLQuery(query string) Map {
|
||||
|
||||
o, err := FromURLQuery(query)
|
||||
|
||||
if err != nil {
|
||||
panic("objx: MustFromURLQuery failed with error: " + err.Error())
|
||||
}
|
||||
|
||||
return o
|
||||
|
||||
}
|
81
src/vendor/github.com/stretchr/objx/mutations.go
generated
vendored
@ -1,81 +0,0 @@
|
||||
package objx
|
||||
|
||||
// Exclude returns a new Map with the keys in the specified []string
|
||||
// excluded.
|
||||
func (d Map) Exclude(exclude []string) Map {
|
||||
|
||||
excluded := make(Map)
|
||||
for k, v := range d {
|
||||
var shouldInclude bool = true
|
||||
for _, toExclude := range exclude {
|
||||
if k == toExclude {
|
||||
shouldInclude = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if shouldInclude {
|
||||
excluded[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
return excluded
|
||||
}
|
||||
|
||||
// Copy creates a shallow copy of the Obj.
|
||||
func (m Map) Copy() Map {
|
||||
copied := make(map[string]interface{})
|
||||
for k, v := range m {
|
||||
copied[k] = v
|
||||
}
|
||||
return New(copied)
|
||||
}
|
||||
|
||||
// Merge blends the specified map with a copy of this map and returns the result.
|
||||
//
|
||||
// Keys that appear in both will be selected from the specified map.
|
||||
// This method requires that the wrapped object be a map[string]interface{}
|
||||
func (m Map) Merge(merge Map) Map {
|
||||
return m.Copy().MergeHere(merge)
|
||||
}
|
||||
|
||||
// Merge blends the specified map with this map and returns the current map.
|
||||
//
|
||||
// Keys that appear in both will be selected from the specified map. The original map
|
||||
// will be modified. This method requires that
|
||||
// the wrapped object be a map[string]interface{}
|
||||
func (m Map) MergeHere(merge Map) Map {
|
||||
|
||||
for k, v := range merge {
|
||||
m[k] = v
|
||||
}
|
||||
|
||||
return m
|
||||
|
||||
}
|
||||
|
||||
// Transform builds a new Obj giving the transformer a chance
|
||||
// to change the keys and values as it goes. This method requires that
|
||||
// the wrapped object be a map[string]interface{}
|
||||
func (m Map) Transform(transformer func(key string, value interface{}) (string, interface{})) Map {
|
||||
newMap := make(map[string]interface{})
|
||||
for k, v := range m {
|
||||
modifiedKey, modifiedVal := transformer(k, v)
|
||||
newMap[modifiedKey] = modifiedVal
|
||||
}
|
||||
return New(newMap)
|
||||
}
|
||||
|
||||
// TransformKeys builds a new map using the specified key mapping.
|
||||
//
|
||||
// Unspecified keys will be unaltered.
|
||||
// This method requires that the wrapped object be a map[string]interface{}
|
||||
func (m Map) TransformKeys(mapping map[string]string) Map {
|
||||
return m.Transform(func(key string, value interface{}) (string, interface{}) {
|
||||
|
||||
if newKey, ok := mapping[key]; ok {
|
||||
return newKey, value
|
||||
}
|
||||
|
||||
return key, value
|
||||
})
|
||||
}
|
14
src/vendor/github.com/stretchr/objx/security.go
generated
vendored
@ -1,14 +0,0 @@
|
||||
package objx
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
)
|
||||
|
||||
// HashWithKey hashes the specified string using the security
|
||||
// key.
|
||||
func HashWithKey(data, key string) string {
|
||||
hash := sha1.New()
|
||||
hash.Write([]byte(data + ":" + key))
|
||||
return hex.EncodeToString(hash.Sum(nil))
|
||||
}
|
17
src/vendor/github.com/stretchr/objx/tests.go
generated
vendored
@ -1,17 +0,0 @@
|
||||
package objx
|
||||
|
||||
// Has gets whether there is something at the specified selector
|
||||
// or not.
|
||||
//
|
||||
// If m is nil, Has will always return false.
|
||||
func (m Map) Has(selector string) bool {
|
||||
if m == nil {
|
||||
return false
|
||||
}
|
||||
return !m.Get(selector).IsNil()
|
||||
}
|
||||
|
||||
// IsNil gets whether the data is nil or not.
|
||||
func (v *Value) IsNil() bool {
|
||||
return v == nil || v.data == nil
|
||||
}
|
2881
src/vendor/github.com/stretchr/objx/type_specific_codegen.go
generated
vendored
56
src/vendor/github.com/stretchr/objx/value.go
generated
vendored
@ -1,56 +0,0 @@
|
||||
package objx
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Value provides methods for extracting interface{} data in various
|
||||
// types.
|
||||
type Value struct {
|
||||
// data contains the raw data being managed by this Value
|
||||
data interface{}
|
||||
}
|
||||
|
||||
// Data returns the raw data contained by this Value
|
||||
func (v *Value) Data() interface{} {
|
||||
return v.data
|
||||
}
|
||||
|
||||
// String returns the value always as a string
|
||||
func (v *Value) String() string {
|
||||
switch {
|
||||
case v.IsStr():
|
||||
return v.Str()
|
||||
case v.IsBool():
|
||||
return strconv.FormatBool(v.Bool())
|
||||
case v.IsFloat32():
|
||||
return strconv.FormatFloat(float64(v.Float32()), 'f', -1, 32)
|
||||
case v.IsFloat64():
|
||||
return strconv.FormatFloat(v.Float64(), 'f', -1, 64)
|
||||
case v.IsInt():
|
||||
return strconv.FormatInt(int64(v.Int()), 10)
|
||||
case v.IsInt():
|
||||
return strconv.FormatInt(int64(v.Int()), 10)
|
||||
case v.IsInt8():
|
||||
return strconv.FormatInt(int64(v.Int8()), 10)
|
||||
case v.IsInt16():
|
||||
return strconv.FormatInt(int64(v.Int16()), 10)
|
||||
case v.IsInt32():
|
||||
return strconv.FormatInt(int64(v.Int32()), 10)
|
||||
case v.IsInt64():
|
||||
return strconv.FormatInt(v.Int64(), 10)
|
||||
case v.IsUint():
|
||||
return strconv.FormatUint(uint64(v.Uint()), 10)
|
||||
case v.IsUint8():
|
||||
return strconv.FormatUint(uint64(v.Uint8()), 10)
|
||||
case v.IsUint16():
|
||||
return strconv.FormatUint(uint64(v.Uint16()), 10)
|
||||
case v.IsUint32():
|
||||
return strconv.FormatUint(uint64(v.Uint32()), 10)
|
||||
case v.IsUint64():
|
||||
return strconv.FormatUint(v.Uint64(), 10)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%#v", v.Data())
|
||||
}
|
7
src/vendor/github.com/stretchr/testify/.travis.gofmt.sh
generated
vendored
Executable file
@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ -n "$(gofmt -l .)" ]; then
|
||||
echo "Go code is not formatted:"
|
||||
gofmt -d .
|
||||
exit 1
|
||||
fi
|
13
src/vendor/github.com/stretchr/testify/.travis.gogenerate.sh
generated
vendored
Executable file
@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [[ "$TRAVIS_GO_VERSION" =~ ^1\.[45](\..*)?$ ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
go get github.com/ernesto-jimenez/gogen/imports
|
||||
go generate ./...
|
||||
if [ -n "$(git diff)" ]; then
|
||||
echo "Go generate had not been run"
|
||||
git diff
|
||||
exit 1
|
||||
fi
|
10
src/vendor/github.com/stretchr/testify/.travis.govet.sh
generated
vendored
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd "$(dirname $0)"
|
||||
DIRS=". assert require mock _codegen"
|
||||
set -e
|
||||
for subdir in $DIRS; do
|
||||
pushd $subdir
|
||||
go vet
|
||||
popd
|
||||
done
|
13
src/vendor/github.com/stretchr/testify/.travis.yml
generated
vendored
@ -3,14 +3,13 @@ language: go
|
||||
sudo: false
|
||||
|
||||
go:
|
||||
- 1.1
|
||||
- 1.2
|
||||
- 1.3
|
||||
- 1.4
|
||||
- 1.5
|
||||
- 1.6
|
||||
- 1.7
|
||||
- 1.8
|
||||
- 1.9
|
||||
- tip
|
||||
|
||||
script:
|
||||
- go test -v ./...
|
||||
- ./.travis.gogenerate.sh
|
||||
- ./.travis.gofmt.sh
|
||||
- ./.travis.govet.sh
|
||||
- go test -v -race ./...
|
||||
|
23
src/vendor/github.com/stretchr/testify/Godeps/Godeps.json
generated
vendored
@ -1,23 +0,0 @@
|
||||
{
|
||||
"ImportPath": "github.com/stretchr/testify",
|
||||
"GoVersion": "go1.5",
|
||||
"GodepVersion": "v74",
|
||||
"Packages": [
|
||||
"./..."
|
||||
],
|
||||
"Deps": [
|
||||
{
|
||||
"ImportPath": "github.com/davecgh/go-spew/spew",
|
||||
"Comment": "v1.0.0-3-g6d21280",
|
||||
"Rev": "04cdfd42973bb9c8589fd6a731800cf222fde1a9"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/pmezard/go-difflib/difflib",
|
||||
"Rev": "d8ed2627bdf02c080bf22230dbb337003b7aba2d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/stretchr/objx",
|
||||
"Rev": "cbeaeb16a013161a98496fad62933b1d21786672"
|
||||
}
|
||||
]
|
||||
}
|
5
src/vendor/github.com/stretchr/testify/Godeps/Readme
generated
vendored
@ -1,5 +0,0 @@
|
||||
This directory tree is generated automatically by godep.
|
||||
|
||||
Please do not edit.
|
||||
|
||||
See https://github.com/tools/godep for more information.
|
25
src/vendor/github.com/stretchr/testify/Gopkg.lock
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/davecgh/go-spew"
|
||||
packages = ["spew"]
|
||||
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/pmezard/go-difflib"
|
||||
packages = ["difflib"]
|
||||
revision = "d8ed2627bdf02c080bf22230dbb337003b7aba2d"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/stretchr/objx"
|
||||
packages = ["."]
|
||||
revision = "cbeaeb16a013161a98496fad62933b1d21786672"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "6bd8fb1f11a0d3df245fc01bd8853f6dac40b83457e780f7978ca30244647c7b"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
26
src/vendor/github.com/stretchr/testify/Gopkg.toml
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
|
||||
# Gopkg.toml example
|
||||
#
|
||||
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||
# for detailed Gopkg.toml documentation.
|
||||
#
|
||||
# required = ["github.com/user/thing/cmd/thing"]
|
||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project"
|
||||
# version = "1.0.0"
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project2"
|
||||
# branch = "dev"
|
||||
# source = "github.com/myfork/project2"
|
||||
#
|
||||
# [[override]]
|
||||
# name = "github.com/x/y"
|
||||
# version = "2.4.0"
|
||||
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/davecgh/go-spew"
|
||||
version = ">=1.0.0, <=3.0.0-g6d21280"
|
22
src/vendor/github.com/stretchr/testify/LICENCE.txt
generated
vendored
@ -1,22 +0,0 @@
|
||||
Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell
|
||||
|
||||
Please consider promoting this project if you find it useful.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
|
||||
OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
23
src/vendor/github.com/stretchr/testify/_codegen/main.go
generated
vendored
@ -20,6 +20,7 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"regexp"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
@ -28,6 +29,7 @@ import (
|
||||
|
||||
var (
|
||||
pkg = flag.String("assert-path", "github.com/stretchr/testify/assert", "Path to the assert package")
|
||||
includeF = flag.Bool("include-format-funcs", false, "include format functions such as Errorf and Equalf")
|
||||
outputPkg = flag.String("output-package", "", "package for the resulting code")
|
||||
tmplFile = flag.String("template", "", "What file to load the function template from")
|
||||
out = flag.String("out", "", "What file to write the source code to")
|
||||
@ -157,6 +159,11 @@ func analyzeCode(scope *types.Scope, docs *doc.Package) (imports.Importer, []tes
|
||||
continue
|
||||
}
|
||||
|
||||
// Skip functions ending with f
|
||||
if strings.HasSuffix(fdocs.Name, "f") && !*includeF {
|
||||
continue
|
||||
}
|
||||
|
||||
funcs = append(funcs, testFunc{*outputPkg, fdocs, fn})
|
||||
importer.AddImportsFrom(sig.Params())
|
||||
}
|
||||
@ -264,10 +271,26 @@ func (f *testFunc) ForwardedParams() string {
|
||||
return p
|
||||
}
|
||||
|
||||
func (f *testFunc) ParamsFormat() string {
|
||||
return strings.Replace(f.Params(), "msgAndArgs", "msg string, args", 1)
|
||||
}
|
||||
|
||||
func (f *testFunc) ForwardedParamsFormat() string {
|
||||
return strings.Replace(f.ForwardedParams(), "msgAndArgs", "append([]interface{}{msg}, args...)", 1)
|
||||
}
|
||||
|
||||
func (f *testFunc) Comment() string {
|
||||
return "// " + strings.Replace(strings.TrimSpace(f.DocInfo.Doc), "\n", "\n// ", -1)
|
||||
}
|
||||
|
||||
func (f *testFunc) CommentFormat() string {
|
||||
search := fmt.Sprintf("%s", f.DocInfo.Name)
|
||||
replace := fmt.Sprintf("%sf", f.DocInfo.Name)
|
||||
comment := strings.Replace(f.Comment(), search, replace, -1)
|
||||
exp := regexp.MustCompile(replace + `\(((\(\)|[^)])+)\)`)
|
||||
return exp.ReplaceAllString(comment, replace+`($1, "error message %s", "formatted")`)
|
||||
}
|
||||
|
||||
func (f *testFunc) CommentWithoutT(receiver string) string {
|
||||
search := fmt.Sprintf("assert.%s(t, ", f.DocInfo.Name)
|
||||
replace := fmt.Sprintf("%s.%s(", receiver, f.DocInfo.Name)
|
||||
|
405
src/vendor/github.com/stretchr/testify/assert/assertion_format.go
generated
vendored
Normal file
@ -0,0 +1,405 @@
|
||||
/*
|
||||
* CODE GENERATED AUTOMATICALLY WITH github.com/stretchr/testify/_codegen
|
||||
* THIS FILE MUST NOT BE EDITED BY HAND
|
||||
*/
|
||||
|
||||
package assert
|
||||
|
||||
import (
|
||||
http "net/http"
|
||||
url "net/url"
|
||||
time "time"
|
||||
)
|
||||
|
||||
// Conditionf uses a Comparison to assert a complex condition.
|
||||
func Conditionf(t TestingT, comp Comparison, msg string, args ...interface{}) bool {
|
||||
return Condition(t, comp, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// Containsf asserts that the specified string, list(array, slice...) or map contains the
|
||||
// specified substring or element.
|
||||
//
|
||||
// assert.Containsf(t, "Hello World", "World", "error message %s", "formatted")
|
||||
// assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted")
|
||||
// assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool {
|
||||
return Contains(t, s, contains, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
|
||||
func DirExistsf(t TestingT, path string, msg string, args ...interface{}) bool {
|
||||
return DirExists(t, path, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified
|
||||
// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,
|
||||
// the number of appearances of each of them in both lists should match.
|
||||
//
|
||||
// assert.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted"))
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) bool {
|
||||
return ElementsMatch(t, listA, listB, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
//
|
||||
// assert.Emptyf(t, obj, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
||||
return Empty(t, object, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// Equalf asserts that two objects are equal.
|
||||
//
|
||||
// assert.Equalf(t, 123, 123, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
//
|
||||
// Pointer variable equality is determined based on the equality of the
|
||||
// referenced values (as opposed to the memory addresses). Function equality
|
||||
// cannot be determined and will always fail.
|
||||
func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
||||
return Equal(t, expected, actual, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// EqualErrorf asserts that a function returned an error (i.e. not `nil`)
|
||||
// and that it is equal to the provided error.
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// assert.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) bool {
|
||||
return EqualError(t, theError, errString, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// EqualValuesf asserts that two objects are equal or convertable to the same types
|
||||
// and equal.
|
||||
//
|
||||
// assert.EqualValuesf(t, uint32(123, "error message %s", "formatted"), int32(123))
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
||||
return EqualValues(t, expected, actual, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// Errorf asserts that a function returned an error (i.e. not `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// if assert.Errorf(t, err, "error message %s", "formatted") {
|
||||
// assert.Equal(t, expectedErrorf, err)
|
||||
// }
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Errorf(t TestingT, err error, msg string, args ...interface{}) bool {
|
||||
return Error(t, err, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// Exactlyf asserts that two objects are equal in value and type.
|
||||
//
|
||||
// assert.Exactlyf(t, int32(123, "error message %s", "formatted"), int64(123))
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
||||
return Exactly(t, expected, actual, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// Failf reports a failure through
|
||||
func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) bool {
|
||||
return Fail(t, failureMessage, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// FailNowf fails test
|
||||
func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}) bool {
|
||||
return FailNow(t, failureMessage, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// Falsef asserts that the specified value is false.
|
||||
//
|
||||
// assert.Falsef(t, myBool, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Falsef(t TestingT, value bool, msg string, args ...interface{}) bool {
|
||||
return False(t, value, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
|
||||
func FileExistsf(t TestingT, path string, msg string, args ...interface{}) bool {
|
||||
return FileExists(t, path, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// HTTPBodyContainsf asserts that a specified handler returns a
|
||||
// body that contains a string.
|
||||
//
|
||||
// assert.HTTPBodyContainsf(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {
|
||||
return HTTPBodyContains(t, handler, method, url, values, str, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// HTTPBodyNotContainsf asserts that a specified handler returns a
|
||||
// body that does not contain a string.
|
||||
//
|
||||
// assert.HTTPBodyNotContainsf(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {
|
||||
return HTTPBodyNotContains(t, handler, method, url, values, str, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// HTTPErrorf asserts that a specified handler returns an error status code.
|
||||
//
|
||||
// assert.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
//
|
||||
// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
|
||||
func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
|
||||
return HTTPError(t, handler, method, url, values, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// HTTPRedirectf asserts that a specified handler returns a redirect status code.
|
||||
//
|
||||
// assert.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
//
|
||||
// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
|
||||
func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
|
||||
return HTTPRedirect(t, handler, method, url, values, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// HTTPSuccessf asserts that a specified handler returns a success status code.
|
||||
//
|
||||
// assert.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
|
||||
return HTTPSuccess(t, handler, method, url, values, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// Implementsf asserts that an object is implemented by the specified interface.
|
||||
//
|
||||
// assert.Implementsf(t, (*MyInterface, "error message %s", "formatted")(nil), new(MyObject))
|
||||
func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool {
|
||||
return Implements(t, interfaceObject, object, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// InDeltaf asserts that the two numerals are within delta of each other.
|
||||
//
|
||||
// assert.InDeltaf(t, math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
|
||||
return InDelta(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
|
||||
func InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
|
||||
return InDeltaMapValues(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// InDeltaSlicef is the same as InDelta, except it compares two slices.
|
||||
func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
|
||||
return InDeltaSlice(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// InEpsilonf asserts that expected and actual have a relative error less than epsilon
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {
|
||||
return InEpsilon(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices.
|
||||
func InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {
|
||||
return InEpsilonSlice(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// IsTypef asserts that the specified objects are of the same type.
|
||||
func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) bool {
|
||||
return IsType(t, expectedType, object, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// JSONEqf asserts that two JSON strings are equivalent.
|
||||
//
|
||||
// assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool {
|
||||
return JSONEq(t, expected, actual, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// Lenf asserts that the specified object has specific length.
|
||||
// Lenf also fails if the object has a type that len() not accept.
|
||||
//
|
||||
// assert.Lenf(t, mySlice, 3, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) bool {
|
||||
return Len(t, object, length, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// Nilf asserts that the specified object is nil.
|
||||
//
|
||||
// assert.Nilf(t, err, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
||||
return Nil(t, object, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// NoErrorf asserts that a function returned no error (i.e. `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// if assert.NoErrorf(t, err, "error message %s", "formatted") {
|
||||
// assert.Equal(t, expectedObj, actualObj)
|
||||
// }
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NoErrorf(t TestingT, err error, msg string, args ...interface{}) bool {
|
||||
return NoError(t, err, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the
|
||||
// specified substring or element.
|
||||
//
|
||||
// assert.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted")
|
||||
// assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted")
|
||||
// assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool {
|
||||
return NotContains(t, s, contains, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
//
|
||||
// if assert.NotEmptyf(t, obj, "error message %s", "formatted") {
|
||||
// assert.Equal(t, "two", obj[1])
|
||||
// }
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
||||
return NotEmpty(t, object, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// NotEqualf asserts that the specified values are NOT equal.
|
||||
//
|
||||
// assert.NotEqualf(t, obj1, obj2, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
//
|
||||
// Pointer variable equality is determined based on the equality of the
|
||||
// referenced values (as opposed to the memory addresses).
|
||||
func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
||||
return NotEqual(t, expected, actual, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// NotNilf asserts that the specified object is not nil.
|
||||
//
|
||||
// assert.NotNilf(t, err, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
||||
return NotNil(t, object, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic.
|
||||
//
|
||||
// assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NotPanicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool {
|
||||
return NotPanics(t, f, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// NotRegexpf asserts that a specified regexp does not match a string.
|
||||
//
|
||||
// assert.NotRegexpf(t, regexp.MustCompile("starts", "error message %s", "formatted"), "it's starting")
|
||||
// assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool {
|
||||
return NotRegexp(t, rx, str, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// NotSubsetf asserts that the specified list(array, slice...) contains not all
|
||||
// elements given in the specified subset(array, slice...).
|
||||
//
|
||||
// assert.NotSubsetf(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool {
|
||||
return NotSubset(t, list, subset, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// NotZerof asserts that i is not the zero value for its type and returns the truth.
|
||||
func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) bool {
|
||||
return NotZero(t, i, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// Panicsf asserts that the code inside the specified PanicTestFunc panics.
|
||||
//
|
||||
// assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Panicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool {
|
||||
return Panics(t, f, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that
|
||||
// the recovered panic value equals the expected panic value.
|
||||
//
|
||||
// assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func PanicsWithValuef(t TestingT, expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool {
|
||||
return PanicsWithValue(t, expected, f, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// Regexpf asserts that a specified regexp matches a string.
|
||||
//
|
||||
// assert.Regexpf(t, regexp.MustCompile("start", "error message %s", "formatted"), "it's starting")
|
||||
// assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool {
|
||||
return Regexp(t, rx, str, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// Subsetf asserts that the specified list(array, slice...) contains all
|
||||
// elements given in the specified subset(array, slice...).
|
||||
//
|
||||
// assert.Subsetf(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool {
|
||||
return Subset(t, list, subset, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// Truef asserts that the specified value is true.
|
||||
//
|
||||
// assert.Truef(t, myBool, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Truef(t TestingT, value bool, msg string, args ...interface{}) bool {
|
||||
return True(t, value, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// WithinDurationf asserts that the two times are within duration delta of each other.
|
||||
//
|
||||
// assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool {
|
||||
return WithinDuration(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// Zerof asserts that i is the zero value for its type and returns the truth.
|
||||
func Zerof(t TestingT, i interface{}, msg string, args ...interface{}) bool {
|
||||
return Zero(t, i, append([]interface{}{msg}, args...)...)
|
||||
}
|
4
src/vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
{{.CommentFormat}}
|
||||
func {{.DocInfo.Name}}f(t TestingT, {{.ParamsFormat}}) bool {
|
||||
return {{.DocInfo.Name}}(t, {{.ForwardedParamsFormat}})
|
||||
}
|
524
src/vendor/github.com/stretchr/testify/assert/assertion_forward.go
generated
vendored
@ -16,18 +16,67 @@ func (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) bool
|
||||
return Condition(a.t, comp, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Conditionf uses a Comparison to assert a complex condition.
|
||||
func (a *Assertions) Conditionf(comp Comparison, msg string, args ...interface{}) bool {
|
||||
return Conditionf(a.t, comp, msg, args...)
|
||||
}
|
||||
|
||||
// Contains asserts that the specified string, list(array, slice...) or map contains the
|
||||
// specified substring or element.
|
||||
//
|
||||
// a.Contains("Hello World", "World", "But 'Hello World' does contain 'World'")
|
||||
// a.Contains(["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'")
|
||||
// a.Contains({"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'")
|
||||
// a.Contains("Hello World", "World")
|
||||
// a.Contains(["Hello", "World"], "World")
|
||||
// a.Contains({"Hello": "World"}, "Hello")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool {
|
||||
return Contains(a.t, s, contains, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Containsf asserts that the specified string, list(array, slice...) or map contains the
|
||||
// specified substring or element.
|
||||
//
|
||||
// a.Containsf("Hello World", "World", "error message %s", "formatted")
|
||||
// a.Containsf(["Hello", "World"], "World", "error message %s", "formatted")
|
||||
// a.Containsf({"Hello": "World"}, "Hello", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Containsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool {
|
||||
return Containsf(a.t, s, contains, msg, args...)
|
||||
}
|
||||
|
||||
// DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
|
||||
func (a *Assertions) DirExists(path string, msgAndArgs ...interface{}) bool {
|
||||
return DirExists(a.t, path, msgAndArgs...)
|
||||
}
|
||||
|
||||
// DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
|
||||
func (a *Assertions) DirExistsf(path string, msg string, args ...interface{}) bool {
|
||||
return DirExistsf(a.t, path, msg, args...)
|
||||
}
|
||||
|
||||
// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified
|
||||
// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,
|
||||
// the number of appearances of each of them in both lists should match.
|
||||
//
|
||||
// a.ElementsMatch([1, 3, 2, 3], [1, 3, 3, 2]))
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) ElementsMatch(listA interface{}, listB interface{}, msgAndArgs ...interface{}) bool {
|
||||
return ElementsMatch(a.t, listA, listB, msgAndArgs...)
|
||||
}
|
||||
|
||||
// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified
|
||||
// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,
|
||||
// the number of appearances of each of them in both lists should match.
|
||||
//
|
||||
// a.ElementsMatchf([1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted"))
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg string, args ...interface{}) bool {
|
||||
return ElementsMatchf(a.t, listA, listB, msg, args...)
|
||||
}
|
||||
|
||||
// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
//
|
||||
@ -38,14 +87,25 @@ func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool {
|
||||
return Empty(a.t, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
//
|
||||
// a.Emptyf(obj, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) bool {
|
||||
return Emptyf(a.t, object, msg, args...)
|
||||
}
|
||||
|
||||
// Equal asserts that two objects are equal.
|
||||
//
|
||||
// a.Equal(123, 123, "123 and 123 should be equal")
|
||||
// a.Equal(123, 123)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
//
|
||||
// Pointer variable equality is determined based on the equality of the
|
||||
// referenced values (as opposed to the memory addresses).
|
||||
// referenced values (as opposed to the memory addresses). Function equality
|
||||
// cannot be determined and will always fail.
|
||||
func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
|
||||
return Equal(a.t, expected, actual, msgAndArgs...)
|
||||
}
|
||||
@ -54,28 +114,62 @@ func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs
|
||||
// and that it is equal to the provided error.
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// a.EqualError(err, expectedErrorString, "An error was expected")
|
||||
// a.EqualError(err, expectedErrorString)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool {
|
||||
return EqualError(a.t, theError, errString, msgAndArgs...)
|
||||
}
|
||||
|
||||
// EqualErrorf asserts that a function returned an error (i.e. not `nil`)
|
||||
// and that it is equal to the provided error.
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// a.EqualErrorf(err, expectedErrorString, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) EqualErrorf(theError error, errString string, msg string, args ...interface{}) bool {
|
||||
return EqualErrorf(a.t, theError, errString, msg, args...)
|
||||
}
|
||||
|
||||
// EqualValues asserts that two objects are equal or convertable to the same types
|
||||
// and equal.
|
||||
//
|
||||
// a.EqualValues(uint32(123), int32(123), "123 and 123 should be equal")
|
||||
// a.EqualValues(uint32(123), int32(123))
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
|
||||
return EqualValues(a.t, expected, actual, msgAndArgs...)
|
||||
}
|
||||
|
||||
// EqualValuesf asserts that two objects are equal or convertable to the same types
|
||||
// and equal.
|
||||
//
|
||||
// a.EqualValuesf(uint32(123, "error message %s", "formatted"), int32(123))
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
||||
return EqualValuesf(a.t, expected, actual, msg, args...)
|
||||
}
|
||||
|
||||
// Equalf asserts that two objects are equal.
|
||||
//
|
||||
// a.Equalf(123, 123, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
//
|
||||
// Pointer variable equality is determined based on the equality of the
|
||||
// referenced values (as opposed to the memory addresses). Function equality
|
||||
// cannot be determined and will always fail.
|
||||
func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
||||
return Equalf(a.t, expected, actual, msg, args...)
|
||||
}
|
||||
|
||||
// Error asserts that a function returned an error (i.e. not `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// if a.Error(err, "An error was expected") {
|
||||
// assert.Equal(t, err, expectedError)
|
||||
// if a.Error(err) {
|
||||
// assert.Equal(t, expectedError, err)
|
||||
// }
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
@ -83,15 +177,36 @@ func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool {
|
||||
return Error(a.t, err, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Exactly asserts that two objects are equal is value and type.
|
||||
// Errorf asserts that a function returned an error (i.e. not `nil`).
|
||||
//
|
||||
// a.Exactly(int32(123), int64(123), "123 and 123 should NOT be equal")
|
||||
// actualObj, err := SomeFunction()
|
||||
// if a.Errorf(err, "error message %s", "formatted") {
|
||||
// assert.Equal(t, expectedErrorf, err)
|
||||
// }
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Errorf(err error, msg string, args ...interface{}) bool {
|
||||
return Errorf(a.t, err, msg, args...)
|
||||
}
|
||||
|
||||
// Exactly asserts that two objects are equal in value and type.
|
||||
//
|
||||
// a.Exactly(int32(123), int64(123))
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
|
||||
return Exactly(a.t, expected, actual, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Exactlyf asserts that two objects are equal in value and type.
|
||||
//
|
||||
// a.Exactlyf(int32(123, "error message %s", "formatted"), int64(123))
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Exactlyf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
||||
return Exactlyf(a.t, expected, actual, msg, args...)
|
||||
}
|
||||
|
||||
// Fail reports a failure through
|
||||
func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) bool {
|
||||
return Fail(a.t, failureMessage, msgAndArgs...)
|
||||
@ -102,23 +217,62 @@ func (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) b
|
||||
return FailNow(a.t, failureMessage, msgAndArgs...)
|
||||
}
|
||||
|
||||
// FailNowf fails test
|
||||
func (a *Assertions) FailNowf(failureMessage string, msg string, args ...interface{}) bool {
|
||||
return FailNowf(a.t, failureMessage, msg, args...)
|
||||
}
|
||||
|
||||
// Failf reports a failure through
|
||||
func (a *Assertions) Failf(failureMessage string, msg string, args ...interface{}) bool {
|
||||
return Failf(a.t, failureMessage, msg, args...)
|
||||
}
|
||||
|
||||
// False asserts that the specified value is false.
|
||||
//
|
||||
// a.False(myBool, "myBool should be false")
|
||||
// a.False(myBool)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool {
|
||||
return False(a.t, value, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Falsef asserts that the specified value is false.
|
||||
//
|
||||
// a.Falsef(myBool, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Falsef(value bool, msg string, args ...interface{}) bool {
|
||||
return Falsef(a.t, value, msg, args...)
|
||||
}
|
||||
|
||||
// FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
|
||||
func (a *Assertions) FileExists(path string, msgAndArgs ...interface{}) bool {
|
||||
return FileExists(a.t, path, msgAndArgs...)
|
||||
}
|
||||
|
||||
// FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
|
||||
func (a *Assertions) FileExistsf(path string, msg string, args ...interface{}) bool {
|
||||
return FileExistsf(a.t, path, msg, args...)
|
||||
}
|
||||
|
||||
// HTTPBodyContains asserts that a specified handler returns a
|
||||
// body that contains a string.
|
||||
//
|
||||
// a.HTTPBodyContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) bool {
|
||||
return HTTPBodyContains(a.t, handler, method, url, values, str)
|
||||
func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
|
||||
return HTTPBodyContains(a.t, handler, method, url, values, str, msgAndArgs...)
|
||||
}
|
||||
|
||||
// HTTPBodyContainsf asserts that a specified handler returns a
|
||||
// body that contains a string.
|
||||
//
|
||||
// a.HTTPBodyContainsf(myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {
|
||||
return HTTPBodyContainsf(a.t, handler, method, url, values, str, msg, args...)
|
||||
}
|
||||
|
||||
// HTTPBodyNotContains asserts that a specified handler returns a
|
||||
@ -127,8 +281,18 @@ func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, u
|
||||
// a.HTTPBodyNotContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) bool {
|
||||
return HTTPBodyNotContains(a.t, handler, method, url, values, str)
|
||||
func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
|
||||
return HTTPBodyNotContains(a.t, handler, method, url, values, str, msgAndArgs...)
|
||||
}
|
||||
|
||||
// HTTPBodyNotContainsf asserts that a specified handler returns a
|
||||
// body that does not contain a string.
|
||||
//
|
||||
// a.HTTPBodyNotContainsf(myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {
|
||||
return HTTPBodyNotContainsf(a.t, handler, method, url, values, str, msg, args...)
|
||||
}
|
||||
|
||||
// HTTPError asserts that a specified handler returns an error status code.
|
||||
@ -136,8 +300,17 @@ func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string
|
||||
// a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values) bool {
|
||||
return HTTPError(a.t, handler, method, url, values)
|
||||
func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool {
|
||||
return HTTPError(a.t, handler, method, url, values, msgAndArgs...)
|
||||
}
|
||||
|
||||
// HTTPErrorf asserts that a specified handler returns an error status code.
|
||||
//
|
||||
// a.HTTPErrorf(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
//
|
||||
// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
|
||||
func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
|
||||
return HTTPErrorf(a.t, handler, method, url, values, msg, args...)
|
||||
}
|
||||
|
||||
// HTTPRedirect asserts that a specified handler returns a redirect status code.
|
||||
@ -145,8 +318,17 @@ func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url stri
|
||||
// a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values) bool {
|
||||
return HTTPRedirect(a.t, handler, method, url, values)
|
||||
func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool {
|
||||
return HTTPRedirect(a.t, handler, method, url, values, msgAndArgs...)
|
||||
}
|
||||
|
||||
// HTTPRedirectf asserts that a specified handler returns a redirect status code.
|
||||
//
|
||||
// a.HTTPRedirectf(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
//
|
||||
// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
|
||||
func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
|
||||
return HTTPRedirectf(a.t, handler, method, url, values, msg, args...)
|
||||
}
|
||||
|
||||
// HTTPSuccess asserts that a specified handler returns a success status code.
|
||||
@ -154,17 +336,33 @@ func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url s
|
||||
// a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values) bool {
|
||||
return HTTPSuccess(a.t, handler, method, url, values)
|
||||
func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool {
|
||||
return HTTPSuccess(a.t, handler, method, url, values, msgAndArgs...)
|
||||
}
|
||||
|
||||
// HTTPSuccessf asserts that a specified handler returns a success status code.
|
||||
//
|
||||
// a.HTTPSuccessf(myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
|
||||
return HTTPSuccessf(a.t, handler, method, url, values, msg, args...)
|
||||
}
|
||||
|
||||
// Implements asserts that an object is implemented by the specified interface.
|
||||
//
|
||||
// a.Implements((*MyInterface)(nil), new(MyObject), "MyObject")
|
||||
// a.Implements((*MyInterface)(nil), new(MyObject))
|
||||
func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
return Implements(a.t, interfaceObject, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Implementsf asserts that an object is implemented by the specified interface.
|
||||
//
|
||||
// a.Implementsf((*MyInterface, "error message %s", "formatted")(nil), new(MyObject))
|
||||
func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool {
|
||||
return Implementsf(a.t, interfaceObject, object, msg, args...)
|
||||
}
|
||||
|
||||
// InDelta asserts that the two numerals are within delta of each other.
|
||||
//
|
||||
// a.InDelta(math.Pi, (22 / 7.0), 0.01)
|
||||
@ -174,11 +372,35 @@ func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta flo
|
||||
return InDelta(a.t, expected, actual, delta, msgAndArgs...)
|
||||
}
|
||||
|
||||
// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
|
||||
func (a *Assertions) InDeltaMapValues(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
|
||||
return InDeltaMapValues(a.t, expected, actual, delta, msgAndArgs...)
|
||||
}
|
||||
|
||||
// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
|
||||
func (a *Assertions) InDeltaMapValuesf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
|
||||
return InDeltaMapValuesf(a.t, expected, actual, delta, msg, args...)
|
||||
}
|
||||
|
||||
// InDeltaSlice is the same as InDelta, except it compares two slices.
|
||||
func (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
|
||||
return InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...)
|
||||
}
|
||||
|
||||
// InDeltaSlicef is the same as InDelta, except it compares two slices.
|
||||
func (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
|
||||
return InDeltaSlicef(a.t, expected, actual, delta, msg, args...)
|
||||
}
|
||||
|
||||
// InDeltaf asserts that the two numerals are within delta of each other.
|
||||
//
|
||||
// a.InDeltaf(math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) InDeltaf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
|
||||
return InDeltaf(a.t, expected, actual, delta, msg, args...)
|
||||
}
|
||||
|
||||
// InEpsilon asserts that expected and actual have a relative error less than epsilon
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
@ -191,11 +413,28 @@ func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, ep
|
||||
return InEpsilonSlice(a.t, expected, actual, epsilon, msgAndArgs...)
|
||||
}
|
||||
|
||||
// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices.
|
||||
func (a *Assertions) InEpsilonSlicef(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {
|
||||
return InEpsilonSlicef(a.t, expected, actual, epsilon, msg, args...)
|
||||
}
|
||||
|
||||
// InEpsilonf asserts that expected and actual have a relative error less than epsilon
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) InEpsilonf(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {
|
||||
return InEpsilonf(a.t, expected, actual, epsilon, msg, args...)
|
||||
}
|
||||
|
||||
// IsType asserts that the specified objects are of the same type.
|
||||
func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
return IsType(a.t, expectedType, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// IsTypef asserts that the specified objects are of the same type.
|
||||
func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg string, args ...interface{}) bool {
|
||||
return IsTypef(a.t, expectedType, object, msg, args...)
|
||||
}
|
||||
|
||||
// JSONEq asserts that two JSON strings are equivalent.
|
||||
//
|
||||
// a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
||||
@ -205,30 +444,58 @@ func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interf
|
||||
return JSONEq(a.t, expected, actual, msgAndArgs...)
|
||||
}
|
||||
|
||||
// JSONEqf asserts that two JSON strings are equivalent.
|
||||
//
|
||||
// a.JSONEqf(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ...interface{}) bool {
|
||||
return JSONEqf(a.t, expected, actual, msg, args...)
|
||||
}
|
||||
|
||||
// Len asserts that the specified object has specific length.
|
||||
// Len also fails if the object has a type that len() not accept.
|
||||
//
|
||||
// a.Len(mySlice, 3, "The size of slice is not 3")
|
||||
// a.Len(mySlice, 3)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool {
|
||||
return Len(a.t, object, length, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Lenf asserts that the specified object has specific length.
|
||||
// Lenf also fails if the object has a type that len() not accept.
|
||||
//
|
||||
// a.Lenf(mySlice, 3, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...interface{}) bool {
|
||||
return Lenf(a.t, object, length, msg, args...)
|
||||
}
|
||||
|
||||
// Nil asserts that the specified object is nil.
|
||||
//
|
||||
// a.Nil(err, "err should be nothing")
|
||||
// a.Nil(err)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool {
|
||||
return Nil(a.t, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Nilf asserts that the specified object is nil.
|
||||
//
|
||||
// a.Nilf(err, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) bool {
|
||||
return Nilf(a.t, object, msg, args...)
|
||||
}
|
||||
|
||||
// NoError asserts that a function returned no error (i.e. `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// if a.NoError(err) {
|
||||
// assert.Equal(t, actualObj, expectedObj)
|
||||
// assert.Equal(t, expectedObj, actualObj)
|
||||
// }
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
@ -236,18 +503,42 @@ func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool {
|
||||
return NoError(a.t, err, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NoErrorf asserts that a function returned no error (i.e. `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// if a.NoErrorf(err, "error message %s", "formatted") {
|
||||
// assert.Equal(t, expectedObj, actualObj)
|
||||
// }
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) bool {
|
||||
return NoErrorf(a.t, err, msg, args...)
|
||||
}
|
||||
|
||||
// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the
|
||||
// specified substring or element.
|
||||
//
|
||||
// a.NotContains("Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'")
|
||||
// a.NotContains(["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'")
|
||||
// a.NotContains({"Hello": "World"}, "Earth", "But {'Hello': 'World'} does NOT contain 'Earth'")
|
||||
// a.NotContains("Hello World", "Earth")
|
||||
// a.NotContains(["Hello", "World"], "Earth")
|
||||
// a.NotContains({"Hello": "World"}, "Earth")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool {
|
||||
return NotContains(a.t, s, contains, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the
|
||||
// specified substring or element.
|
||||
//
|
||||
// a.NotContainsf("Hello World", "Earth", "error message %s", "formatted")
|
||||
// a.NotContainsf(["Hello", "World"], "Earth", "error message %s", "formatted")
|
||||
// a.NotContainsf({"Hello": "World"}, "Earth", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool {
|
||||
return NotContainsf(a.t, s, contains, msg, args...)
|
||||
}
|
||||
|
||||
// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
//
|
||||
@ -260,9 +551,21 @@ func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) boo
|
||||
return NotEmpty(a.t, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
//
|
||||
// if a.NotEmptyf(obj, "error message %s", "formatted") {
|
||||
// assert.Equal(t, "two", obj[1])
|
||||
// }
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface{}) bool {
|
||||
return NotEmptyf(a.t, object, msg, args...)
|
||||
}
|
||||
|
||||
// NotEqual asserts that the specified values are NOT equal.
|
||||
//
|
||||
// a.NotEqual(obj1, obj2, "two objects shouldn't be equal")
|
||||
// a.NotEqual(obj1, obj2)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
//
|
||||
@ -272,26 +575,54 @@ func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndAr
|
||||
return NotEqual(a.t, expected, actual, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotEqualf asserts that the specified values are NOT equal.
|
||||
//
|
||||
// a.NotEqualf(obj1, obj2, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
//
|
||||
// Pointer variable equality is determined based on the equality of the
|
||||
// referenced values (as opposed to the memory addresses).
|
||||
func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
||||
return NotEqualf(a.t, expected, actual, msg, args...)
|
||||
}
|
||||
|
||||
// NotNil asserts that the specified object is not nil.
|
||||
//
|
||||
// a.NotNil(err, "err should be something")
|
||||
// a.NotNil(err)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool {
|
||||
return NotNil(a.t, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotNilf asserts that the specified object is not nil.
|
||||
//
|
||||
// a.NotNilf(err, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{}) bool {
|
||||
return NotNilf(a.t, object, msg, args...)
|
||||
}
|
||||
|
||||
// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.
|
||||
//
|
||||
// a.NotPanics(func(){
|
||||
// RemainCalm()
|
||||
// }, "Calling RemainCalm() should NOT panic")
|
||||
// a.NotPanics(func(){ RemainCalm() })
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool {
|
||||
return NotPanics(a.t, f, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic.
|
||||
//
|
||||
// a.NotPanicsf(func(){ RemainCalm() }, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NotPanicsf(f PanicTestFunc, msg string, args ...interface{}) bool {
|
||||
return NotPanicsf(a.t, f, msg, args...)
|
||||
}
|
||||
|
||||
// NotRegexp asserts that a specified regexp does not match a string.
|
||||
//
|
||||
// a.NotRegexp(regexp.MustCompile("starts"), "it's starting")
|
||||
@ -302,22 +633,84 @@ func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...in
|
||||
return NotRegexp(a.t, rx, str, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotRegexpf asserts that a specified regexp does not match a string.
|
||||
//
|
||||
// a.NotRegexpf(regexp.MustCompile("starts", "error message %s", "formatted"), "it's starting")
|
||||
// a.NotRegexpf("^start", "it's not starting", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool {
|
||||
return NotRegexpf(a.t, rx, str, msg, args...)
|
||||
}
|
||||
|
||||
// NotSubset asserts that the specified list(array, slice...) contains not all
|
||||
// elements given in the specified subset(array, slice...).
|
||||
//
|
||||
// a.NotSubset([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool {
|
||||
return NotSubset(a.t, list, subset, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotSubsetf asserts that the specified list(array, slice...) contains not all
|
||||
// elements given in the specified subset(array, slice...).
|
||||
//
|
||||
// a.NotSubsetf([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool {
|
||||
return NotSubsetf(a.t, list, subset, msg, args...)
|
||||
}
|
||||
|
||||
// NotZero asserts that i is not the zero value for its type and returns the truth.
|
||||
func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) bool {
|
||||
return NotZero(a.t, i, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotZerof asserts that i is not the zero value for its type and returns the truth.
|
||||
func (a *Assertions) NotZerof(i interface{}, msg string, args ...interface{}) bool {
|
||||
return NotZerof(a.t, i, msg, args...)
|
||||
}
|
||||
|
||||
// Panics asserts that the code inside the specified PanicTestFunc panics.
|
||||
//
|
||||
// a.Panics(func(){
|
||||
// GoCrazy()
|
||||
// }, "Calling GoCrazy() should panic")
|
||||
// a.Panics(func(){ GoCrazy() })
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool {
|
||||
return Panics(a.t, f, msgAndArgs...)
|
||||
}
|
||||
|
||||
// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that
|
||||
// the recovered panic value equals the expected panic value.
|
||||
//
|
||||
// a.PanicsWithValue("crazy error", func(){ GoCrazy() })
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) PanicsWithValue(expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool {
|
||||
return PanicsWithValue(a.t, expected, f, msgAndArgs...)
|
||||
}
|
||||
|
||||
// PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that
|
||||
// the recovered panic value equals the expected panic value.
|
||||
//
|
||||
// a.PanicsWithValuef("crazy error", func(){ GoCrazy() }, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) PanicsWithValuef(expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool {
|
||||
return PanicsWithValuef(a.t, expected, f, msg, args...)
|
||||
}
|
||||
|
||||
// Panicsf asserts that the code inside the specified PanicTestFunc panics.
|
||||
//
|
||||
// a.Panicsf(func(){ GoCrazy() }, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Panicsf(f PanicTestFunc, msg string, args ...interface{}) bool {
|
||||
return Panicsf(a.t, f, msg, args...)
|
||||
}
|
||||
|
||||
// Regexp asserts that a specified regexp matches a string.
|
||||
//
|
||||
// a.Regexp(regexp.MustCompile("start"), "it's starting")
|
||||
@ -328,25 +721,78 @@ func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...inter
|
||||
return Regexp(a.t, rx, str, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Regexpf asserts that a specified regexp matches a string.
|
||||
//
|
||||
// a.Regexpf(regexp.MustCompile("start", "error message %s", "formatted"), "it's starting")
|
||||
// a.Regexpf("start...$", "it's not starting", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool {
|
||||
return Regexpf(a.t, rx, str, msg, args...)
|
||||
}
|
||||
|
||||
// Subset asserts that the specified list(array, slice...) contains all
|
||||
// elements given in the specified subset(array, slice...).
|
||||
//
|
||||
// a.Subset([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool {
|
||||
return Subset(a.t, list, subset, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Subsetf asserts that the specified list(array, slice...) contains all
|
||||
// elements given in the specified subset(array, slice...).
|
||||
//
|
||||
// a.Subsetf([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool {
|
||||
return Subsetf(a.t, list, subset, msg, args...)
|
||||
}
|
||||
|
||||
// True asserts that the specified value is true.
|
||||
//
|
||||
// a.True(myBool, "myBool should be true")
|
||||
// a.True(myBool)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool {
|
||||
return True(a.t, value, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Truef asserts that the specified value is true.
|
||||
//
|
||||
// a.Truef(myBool, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Truef(value bool, msg string, args ...interface{}) bool {
|
||||
return Truef(a.t, value, msg, args...)
|
||||
}
|
||||
|
||||
// WithinDuration asserts that the two times are within duration delta of each other.
|
||||
//
|
||||
// a.WithinDuration(time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s")
|
||||
// a.WithinDuration(time.Now(), time.Now(), 10*time.Second)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool {
|
||||
return WithinDuration(a.t, expected, actual, delta, msgAndArgs...)
|
||||
}
|
||||
|
||||
// WithinDurationf asserts that the two times are within duration delta of each other.
|
||||
//
|
||||
// a.WithinDurationf(time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool {
|
||||
return WithinDurationf(a.t, expected, actual, delta, msg, args...)
|
||||
}
|
||||
|
||||
// Zero asserts that i is the zero value for its type and returns the truth.
|
||||
func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) bool {
|
||||
return Zero(a.t, i, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Zerof asserts that i is the zero value for its type and returns the truth.
|
||||
func (a *Assertions) Zerof(i interface{}, msg string, args ...interface{}) bool {
|
||||
return Zerof(a.t, i, msg, args...)
|
||||
}
|
||||
|
427
src/vendor/github.com/stretchr/testify/assert/assertions.go
generated
vendored
@ -4,8 +4,10 @@ import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"runtime"
|
||||
@ -18,6 +20,8 @@ import (
|
||||
"github.com/pmezard/go-difflib/difflib"
|
||||
)
|
||||
|
||||
//go:generate go run ../_codegen/main.go -output-package=assert -template=assertion_format.go.tmpl
|
||||
|
||||
// TestingT is an interface wrapper around *testing.T
|
||||
type TestingT interface {
|
||||
Errorf(format string, args ...interface{})
|
||||
@ -38,7 +42,15 @@ func ObjectsAreEqual(expected, actual interface{}) bool {
|
||||
if expected == nil || actual == nil {
|
||||
return expected == actual
|
||||
}
|
||||
|
||||
if exp, ok := expected.([]byte); ok {
|
||||
act, ok := actual.([]byte)
|
||||
if !ok {
|
||||
return false
|
||||
} else if exp == nil || act == nil {
|
||||
return exp == nil && act == nil
|
||||
}
|
||||
return bytes.Equal(exp, act)
|
||||
}
|
||||
return reflect.DeepEqual(expected, actual)
|
||||
|
||||
}
|
||||
@ -108,10 +120,12 @@ func CallerInfo() []string {
|
||||
}
|
||||
|
||||
parts := strings.Split(file, "/")
|
||||
dir := parts[len(parts)-2]
|
||||
file = parts[len(parts)-1]
|
||||
if (dir != "assert" && dir != "mock" && dir != "require") || file == "mock_test.go" {
|
||||
callers = append(callers, fmt.Sprintf("%s:%d", file, line))
|
||||
if len(parts) > 1 {
|
||||
dir := parts[len(parts)-2]
|
||||
if (dir != "assert" && dir != "mock" && dir != "require") || file == "mock_test.go" {
|
||||
callers = append(callers, fmt.Sprintf("%s:%d", file, line))
|
||||
}
|
||||
}
|
||||
|
||||
// Drop the package
|
||||
@ -181,7 +195,7 @@ func indentMessageLines(message string, longestLabelLen int) string {
|
||||
// no need to align first line because it starts at the correct location (after the label)
|
||||
if i != 0 {
|
||||
// append alignLen+1 spaces to align with "{{longestLabel}}:" before adding tab
|
||||
outBuf.WriteString("\n\r\t" + strings.Repeat(" ", longestLabelLen +1) + "\t")
|
||||
outBuf.WriteString("\n\r\t" + strings.Repeat(" ", longestLabelLen+1) + "\t")
|
||||
}
|
||||
outBuf.WriteString(scanner.Text())
|
||||
}
|
||||
@ -218,18 +232,25 @@ func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
|
||||
{"Error", failureMessage},
|
||||
}
|
||||
|
||||
// Add test name if the Go version supports it
|
||||
if n, ok := t.(interface {
|
||||
Name() string
|
||||
}); ok {
|
||||
content = append(content, labeledContent{"Test", n.Name()})
|
||||
}
|
||||
|
||||
message := messageFromMsgAndArgs(msgAndArgs...)
|
||||
if len(message) > 0 {
|
||||
content = append(content, labeledContent{"Messages", message})
|
||||
}
|
||||
|
||||
t.Errorf("\r" + getWhitespaceString() + labeledOutput(content...))
|
||||
t.Errorf("%s", "\r"+getWhitespaceString()+labeledOutput(content...))
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
type labeledContent struct {
|
||||
label string
|
||||
label string
|
||||
content string
|
||||
}
|
||||
|
||||
@ -258,17 +279,18 @@ func labeledOutput(content ...labeledContent) string {
|
||||
|
||||
// Implements asserts that an object is implemented by the specified interface.
|
||||
//
|
||||
// assert.Implements(t, (*MyInterface)(nil), new(MyObject), "MyObject")
|
||||
// assert.Implements(t, (*MyInterface)(nil), new(MyObject))
|
||||
func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
|
||||
interfaceType := reflect.TypeOf(interfaceObject).Elem()
|
||||
|
||||
if object == nil {
|
||||
return Fail(t, fmt.Sprintf("Cannot check if nil implements %v", interfaceType), msgAndArgs...)
|
||||
}
|
||||
if !reflect.TypeOf(object).Implements(interfaceType) {
|
||||
return Fail(t, fmt.Sprintf("%T must implement %v", object, interfaceType), msgAndArgs...)
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
// IsType asserts that the specified objects are of the same type.
|
||||
@ -283,20 +305,25 @@ func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs
|
||||
|
||||
// Equal asserts that two objects are equal.
|
||||
//
|
||||
// assert.Equal(t, 123, 123, "123 and 123 should be equal")
|
||||
// assert.Equal(t, 123, 123)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
//
|
||||
// Pointer variable equality is determined based on the equality of the
|
||||
// referenced values (as opposed to the memory addresses).
|
||||
// referenced values (as opposed to the memory addresses). Function equality
|
||||
// cannot be determined and will always fail.
|
||||
func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
|
||||
if err := validateEqualArgs(expected, actual); err != nil {
|
||||
return Fail(t, fmt.Sprintf("Invalid operation: %#v == %#v (%s)",
|
||||
expected, actual, err), msgAndArgs...)
|
||||
}
|
||||
|
||||
if !ObjectsAreEqual(expected, actual) {
|
||||
diff := diff(expected, actual)
|
||||
expected, actual = formatUnequalValues(expected, actual)
|
||||
return Fail(t, fmt.Sprintf("Not equal: \n"+
|
||||
"expected: %s\n"+
|
||||
"received: %s%s", expected, actual, diff), msgAndArgs...)
|
||||
"actual : %s%s", expected, actual, diff), msgAndArgs...)
|
||||
}
|
||||
|
||||
return true
|
||||
@ -322,7 +349,7 @@ func formatUnequalValues(expected, actual interface{}) (e string, a string) {
|
||||
// EqualValues asserts that two objects are equal or convertable to the same types
|
||||
// and equal.
|
||||
//
|
||||
// assert.EqualValues(t, uint32(123), int32(123), "123 and 123 should be equal")
|
||||
// assert.EqualValues(t, uint32(123), int32(123))
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
|
||||
@ -332,16 +359,16 @@ func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interfa
|
||||
expected, actual = formatUnequalValues(expected, actual)
|
||||
return Fail(t, fmt.Sprintf("Not equal: \n"+
|
||||
"expected: %s\n"+
|
||||
"received: %s%s", expected, actual, diff), msgAndArgs...)
|
||||
"actual : %s%s", expected, actual, diff), msgAndArgs...)
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
// Exactly asserts that two objects are equal is value and type.
|
||||
// Exactly asserts that two objects are equal in value and type.
|
||||
//
|
||||
// assert.Exactly(t, int32(123), int64(123), "123 and 123 should NOT be equal")
|
||||
// assert.Exactly(t, int32(123), int64(123))
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
|
||||
@ -359,7 +386,7 @@ func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}
|
||||
|
||||
// NotNil asserts that the specified object is not nil.
|
||||
//
|
||||
// assert.NotNil(t, err, "err should be something")
|
||||
// assert.NotNil(t, err)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
@ -386,7 +413,7 @@ func isNil(object interface{}) bool {
|
||||
|
||||
// Nil asserts that the specified object is nil.
|
||||
//
|
||||
// assert.Nil(t, err, "err should be nothing")
|
||||
// assert.Nil(t, err)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
@ -396,66 +423,32 @@ func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
return Fail(t, fmt.Sprintf("Expected nil, but got: %#v", object), msgAndArgs...)
|
||||
}
|
||||
|
||||
var numericZeros = []interface{}{
|
||||
int(0),
|
||||
int8(0),
|
||||
int16(0),
|
||||
int32(0),
|
||||
int64(0),
|
||||
uint(0),
|
||||
uint8(0),
|
||||
uint16(0),
|
||||
uint32(0),
|
||||
uint64(0),
|
||||
float32(0),
|
||||
float64(0),
|
||||
}
|
||||
|
||||
// isEmpty gets whether the specified object is considered empty or not.
|
||||
func isEmpty(object interface{}) bool {
|
||||
|
||||
// get nil case out of the way
|
||||
if object == nil {
|
||||
return true
|
||||
} else if object == "" {
|
||||
return true
|
||||
} else if object == false {
|
||||
return true
|
||||
}
|
||||
|
||||
for _, v := range numericZeros {
|
||||
if object == v {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
objValue := reflect.ValueOf(object)
|
||||
|
||||
switch objValue.Kind() {
|
||||
case reflect.Map:
|
||||
fallthrough
|
||||
case reflect.Slice, reflect.Chan:
|
||||
{
|
||||
return (objValue.Len() == 0)
|
||||
}
|
||||
case reflect.Struct:
|
||||
switch object.(type) {
|
||||
case time.Time:
|
||||
return object.(time.Time).IsZero()
|
||||
}
|
||||
// collection types are empty when they have no element
|
||||
case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:
|
||||
return objValue.Len() == 0
|
||||
// pointers are empty if nil or if the value they point to is empty
|
||||
case reflect.Ptr:
|
||||
{
|
||||
if objValue.IsNil() {
|
||||
return true
|
||||
}
|
||||
switch object.(type) {
|
||||
case *time.Time:
|
||||
return object.(*time.Time).IsZero()
|
||||
default:
|
||||
return false
|
||||
}
|
||||
if objValue.IsNil() {
|
||||
return true
|
||||
}
|
||||
deref := objValue.Elem().Interface()
|
||||
return isEmpty(deref)
|
||||
// for all other types, compare against the zero value
|
||||
default:
|
||||
zero := reflect.Zero(objValue.Type())
|
||||
return reflect.DeepEqual(object, zero.Interface())
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either
|
||||
@ -509,7 +502,7 @@ func getLen(x interface{}) (ok bool, length int) {
|
||||
// Len asserts that the specified object has specific length.
|
||||
// Len also fails if the object has a type that len() not accept.
|
||||
//
|
||||
// assert.Len(t, mySlice, 3, "The size of slice is not 3")
|
||||
// assert.Len(t, mySlice, 3)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool {
|
||||
@ -526,7 +519,7 @@ func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{})
|
||||
|
||||
// True asserts that the specified value is true.
|
||||
//
|
||||
// assert.True(t, myBool, "myBool should be true")
|
||||
// assert.True(t, myBool)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func True(t TestingT, value bool, msgAndArgs ...interface{}) bool {
|
||||
@ -541,7 +534,7 @@ func True(t TestingT, value bool, msgAndArgs ...interface{}) bool {
|
||||
|
||||
// False asserts that the specified value is false.
|
||||
//
|
||||
// assert.False(t, myBool, "myBool should be false")
|
||||
// assert.False(t, myBool)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func False(t TestingT, value bool, msgAndArgs ...interface{}) bool {
|
||||
@ -556,13 +549,17 @@ func False(t TestingT, value bool, msgAndArgs ...interface{}) bool {
|
||||
|
||||
// NotEqual asserts that the specified values are NOT equal.
|
||||
//
|
||||
// assert.NotEqual(t, obj1, obj2, "two objects shouldn't be equal")
|
||||
// assert.NotEqual(t, obj1, obj2)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
//
|
||||
// Pointer variable equality is determined based on the equality of the
|
||||
// referenced values (as opposed to the memory addresses).
|
||||
func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
|
||||
if err := validateEqualArgs(expected, actual); err != nil {
|
||||
return Fail(t, fmt.Sprintf("Invalid operation: %#v != %#v (%s)",
|
||||
expected, actual, err), msgAndArgs...)
|
||||
}
|
||||
|
||||
if ObjectsAreEqual(expected, actual) {
|
||||
return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...)
|
||||
@ -613,9 +610,9 @@ func includeElement(list interface{}, element interface{}) (ok, found bool) {
|
||||
// Contains asserts that the specified string, list(array, slice...) or map contains the
|
||||
// specified substring or element.
|
||||
//
|
||||
// assert.Contains(t, "Hello World", "World", "But 'Hello World' does contain 'World'")
|
||||
// assert.Contains(t, ["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'")
|
||||
// assert.Contains(t, {"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'")
|
||||
// assert.Contains(t, "Hello World", "World")
|
||||
// assert.Contains(t, ["Hello", "World"], "World")
|
||||
// assert.Contains(t, {"Hello": "World"}, "Hello")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {
|
||||
@ -635,9 +632,9 @@ func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bo
|
||||
// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the
|
||||
// specified substring or element.
|
||||
//
|
||||
// assert.NotContains(t, "Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'")
|
||||
// assert.NotContains(t, ["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'")
|
||||
// assert.NotContains(t, {"Hello": "World"}, "Earth", "But {'Hello': 'World'} does NOT contain 'Earth'")
|
||||
// assert.NotContains(t, "Hello World", "Earth")
|
||||
// assert.NotContains(t, ["Hello", "World"], "Earth")
|
||||
// assert.NotContains(t, {"Hello": "World"}, "Earth")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {
|
||||
@ -654,6 +651,148 @@ func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{})
|
||||
|
||||
}
|
||||
|
||||
// Subset asserts that the specified list(array, slice...) contains all
|
||||
// elements given in the specified subset(array, slice...).
|
||||
//
|
||||
// assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {
|
||||
if subset == nil {
|
||||
return true // we consider nil to be equal to the nil set
|
||||
}
|
||||
|
||||
subsetValue := reflect.ValueOf(subset)
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
ok = false
|
||||
}
|
||||
}()
|
||||
|
||||
listKind := reflect.TypeOf(list).Kind()
|
||||
subsetKind := reflect.TypeOf(subset).Kind()
|
||||
|
||||
if listKind != reflect.Array && listKind != reflect.Slice {
|
||||
return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...)
|
||||
}
|
||||
|
||||
if subsetKind != reflect.Array && subsetKind != reflect.Slice {
|
||||
return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...)
|
||||
}
|
||||
|
||||
for i := 0; i < subsetValue.Len(); i++ {
|
||||
element := subsetValue.Index(i).Interface()
|
||||
ok, found := includeElement(list, element)
|
||||
if !ok {
|
||||
return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", list), msgAndArgs...)
|
||||
}
|
||||
if !found {
|
||||
return Fail(t, fmt.Sprintf("\"%s\" does not contain \"%s\"", list, element), msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// NotSubset asserts that the specified list(array, slice...) contains not all
|
||||
// elements given in the specified subset(array, slice...).
|
||||
//
|
||||
// assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {
|
||||
if subset == nil {
|
||||
return Fail(t, fmt.Sprintf("nil is the empty set which is a subset of every set"), msgAndArgs...)
|
||||
}
|
||||
|
||||
subsetValue := reflect.ValueOf(subset)
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
ok = false
|
||||
}
|
||||
}()
|
||||
|
||||
listKind := reflect.TypeOf(list).Kind()
|
||||
subsetKind := reflect.TypeOf(subset).Kind()
|
||||
|
||||
if listKind != reflect.Array && listKind != reflect.Slice {
|
||||
return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...)
|
||||
}
|
||||
|
||||
if subsetKind != reflect.Array && subsetKind != reflect.Slice {
|
||||
return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...)
|
||||
}
|
||||
|
||||
for i := 0; i < subsetValue.Len(); i++ {
|
||||
element := subsetValue.Index(i).Interface()
|
||||
ok, found := includeElement(list, element)
|
||||
if !ok {
|
||||
return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", list), msgAndArgs...)
|
||||
}
|
||||
if !found {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...)
|
||||
}
|
||||
|
||||
// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified
|
||||
// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,
|
||||
// the number of appearances of each of them in both lists should match.
|
||||
//
|
||||
// assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2]))
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func ElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface{}) (ok bool) {
|
||||
if isEmpty(listA) && isEmpty(listB) {
|
||||
return true
|
||||
}
|
||||
|
||||
aKind := reflect.TypeOf(listA).Kind()
|
||||
bKind := reflect.TypeOf(listB).Kind()
|
||||
|
||||
if aKind != reflect.Array && aKind != reflect.Slice {
|
||||
return Fail(t, fmt.Sprintf("%q has an unsupported type %s", listA, aKind), msgAndArgs...)
|
||||
}
|
||||
|
||||
if bKind != reflect.Array && bKind != reflect.Slice {
|
||||
return Fail(t, fmt.Sprintf("%q has an unsupported type %s", listB, bKind), msgAndArgs...)
|
||||
}
|
||||
|
||||
aValue := reflect.ValueOf(listA)
|
||||
bValue := reflect.ValueOf(listB)
|
||||
|
||||
aLen := aValue.Len()
|
||||
bLen := bValue.Len()
|
||||
|
||||
if aLen != bLen {
|
||||
return Fail(t, fmt.Sprintf("lengths don't match: %d != %d", aLen, bLen), msgAndArgs...)
|
||||
}
|
||||
|
||||
// Mark indexes in bValue that we already used
|
||||
visited := make([]bool, bLen)
|
||||
for i := 0; i < aLen; i++ {
|
||||
element := aValue.Index(i).Interface()
|
||||
found := false
|
||||
for j := 0; j < bLen; j++ {
|
||||
if visited[j] {
|
||||
continue
|
||||
}
|
||||
if ObjectsAreEqual(bValue.Index(j).Interface(), element) {
|
||||
visited[j] = true
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return Fail(t, fmt.Sprintf("element %s appears more times in %s than in %s", element, aValue, bValue), msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// Condition uses a Comparison to assert a complex condition.
|
||||
func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool {
|
||||
result := comp()
|
||||
@ -691,9 +830,7 @@ func didPanic(f PanicTestFunc) (bool, interface{}) {
|
||||
|
||||
// Panics asserts that the code inside the specified PanicTestFunc panics.
|
||||
//
|
||||
// assert.Panics(t, func(){
|
||||
// GoCrazy()
|
||||
// }, "Calling GoCrazy() should panic")
|
||||
// assert.Panics(t, func(){ GoCrazy() })
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
|
||||
@ -705,11 +842,28 @@ func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that
|
||||
// the recovered panic value equals the expected panic value.
|
||||
//
|
||||
// assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() })
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool {
|
||||
|
||||
funcDidPanic, panicValue := didPanic(f)
|
||||
if !funcDidPanic {
|
||||
return Fail(t, fmt.Sprintf("func %#v should panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...)
|
||||
}
|
||||
if panicValue != expected {
|
||||
return Fail(t, fmt.Sprintf("func %#v should panic with value:\t%v\n\r\tPanic value:\t%v", f, expected, panicValue), msgAndArgs...)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.
|
||||
//
|
||||
// assert.NotPanics(t, func(){
|
||||
// RemainCalm()
|
||||
// }, "Calling RemainCalm() should NOT panic")
|
||||
// assert.NotPanics(t, func(){ RemainCalm() })
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
|
||||
@ -723,7 +877,7 @@ func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
|
||||
|
||||
// WithinDuration asserts that the two times are within duration delta of each other.
|
||||
//
|
||||
// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s")
|
||||
// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool {
|
||||
@ -763,6 +917,8 @@ func toFloat(x interface{}) (float64, bool) {
|
||||
xf = float64(xn)
|
||||
case float64:
|
||||
xf = float64(xn)
|
||||
case time.Duration:
|
||||
xf = float64(xn)
|
||||
default:
|
||||
xok = false
|
||||
}
|
||||
@ -785,7 +941,7 @@ func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs
|
||||
}
|
||||
|
||||
if math.IsNaN(af) {
|
||||
return Fail(t, fmt.Sprintf("Actual must not be NaN"), msgAndArgs...)
|
||||
return Fail(t, fmt.Sprintf("Expected must not be NaN"), msgAndArgs...)
|
||||
}
|
||||
|
||||
if math.IsNaN(bf) {
|
||||
@ -812,7 +968,7 @@ func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAn
|
||||
expectedSlice := reflect.ValueOf(expected)
|
||||
|
||||
for i := 0; i < actualSlice.Len(); i++ {
|
||||
result := InDelta(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), delta)
|
||||
result := InDelta(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), delta, msgAndArgs...)
|
||||
if !result {
|
||||
return result
|
||||
}
|
||||
@ -821,6 +977,47 @@ func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAn
|
||||
return true
|
||||
}
|
||||
|
||||
// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
|
||||
func InDeltaMapValues(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
|
||||
if expected == nil || actual == nil ||
|
||||
reflect.TypeOf(actual).Kind() != reflect.Map ||
|
||||
reflect.TypeOf(expected).Kind() != reflect.Map {
|
||||
return Fail(t, "Arguments must be maps", msgAndArgs...)
|
||||
}
|
||||
|
||||
expectedMap := reflect.ValueOf(expected)
|
||||
actualMap := reflect.ValueOf(actual)
|
||||
|
||||
if expectedMap.Len() != actualMap.Len() {
|
||||
return Fail(t, "Arguments must have the same numbe of keys", msgAndArgs...)
|
||||
}
|
||||
|
||||
for _, k := range expectedMap.MapKeys() {
|
||||
ev := expectedMap.MapIndex(k)
|
||||
av := actualMap.MapIndex(k)
|
||||
|
||||
if !ev.IsValid() {
|
||||
return Fail(t, fmt.Sprintf("missing key %q in expected map", k), msgAndArgs...)
|
||||
}
|
||||
|
||||
if !av.IsValid() {
|
||||
return Fail(t, fmt.Sprintf("missing key %q in actual map", k), msgAndArgs...)
|
||||
}
|
||||
|
||||
if !InDelta(
|
||||
t,
|
||||
ev.Interface(),
|
||||
av.Interface(),
|
||||
delta,
|
||||
msgAndArgs...,
|
||||
) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func calcRelativeError(expected, actual interface{}) (float64, error) {
|
||||
af, aok := toFloat(expected)
|
||||
if !aok {
|
||||
@ -831,7 +1028,7 @@ func calcRelativeError(expected, actual interface{}) (float64, error) {
|
||||
}
|
||||
bf, bok := toFloat(actual)
|
||||
if !bok {
|
||||
return 0, fmt.Errorf("expected value %q cannot be converted to float", actual)
|
||||
return 0, fmt.Errorf("actual value %q cannot be converted to float", actual)
|
||||
}
|
||||
|
||||
return math.Abs(af-bf) / math.Abs(af), nil
|
||||
@ -847,7 +1044,7 @@ func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAnd
|
||||
}
|
||||
if actualEpsilon > epsilon {
|
||||
return Fail(t, fmt.Sprintf("Relative error is too high: %#v (expected)\n"+
|
||||
" < %#v (actual)", actualEpsilon, epsilon), msgAndArgs...)
|
||||
" < %#v (actual)", epsilon, actualEpsilon), msgAndArgs...)
|
||||
}
|
||||
|
||||
return true
|
||||
@ -882,7 +1079,7 @@ func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, m
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// if assert.NoError(t, err) {
|
||||
// assert.Equal(t, actualObj, expectedObj)
|
||||
// assert.Equal(t, expectedObj, actualObj)
|
||||
// }
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
@ -897,8 +1094,8 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool {
|
||||
// Error asserts that a function returned an error (i.e. not `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// if assert.Error(t, err, "An error was expected") {
|
||||
// assert.Equal(t, err, expectedError)
|
||||
// if assert.Error(t, err) {
|
||||
// assert.Equal(t, expectedError, err)
|
||||
// }
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
@ -915,7 +1112,7 @@ func Error(t TestingT, err error, msgAndArgs ...interface{}) bool {
|
||||
// and that it is equal to the provided error.
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// assert.EqualError(t, err, expectedErrorString, "An error was expected")
|
||||
// assert.EqualError(t, err, expectedErrorString)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool {
|
||||
@ -928,7 +1125,7 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte
|
||||
if expected != actual {
|
||||
return Fail(t, fmt.Sprintf("Error message not equal:\n"+
|
||||
"expected: %q\n"+
|
||||
"received: %q", expected, actual), msgAndArgs...)
|
||||
"actual : %q", expected, actual), msgAndArgs...)
|
||||
}
|
||||
return true
|
||||
}
|
||||
@ -997,6 +1194,36 @@ func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
|
||||
func FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
|
||||
info, err := os.Lstat(path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return Fail(t, fmt.Sprintf("unable to find file %q", path), msgAndArgs...)
|
||||
}
|
||||
return Fail(t, fmt.Sprintf("error when running os.Lstat(%q): %s", path, err), msgAndArgs...)
|
||||
}
|
||||
if info.IsDir() {
|
||||
return Fail(t, fmt.Sprintf("%q is a directory", path), msgAndArgs...)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
|
||||
func DirExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
|
||||
info, err := os.Lstat(path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return Fail(t, fmt.Sprintf("unable to find file %q", path), msgAndArgs...)
|
||||
}
|
||||
return Fail(t, fmt.Sprintf("error when running os.Lstat(%q): %s", path, err), msgAndArgs...)
|
||||
}
|
||||
if !info.IsDir() {
|
||||
return Fail(t, fmt.Sprintf("%q is a file", path), msgAndArgs...)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// JSONEq asserts that two JSON strings are equivalent.
|
||||
//
|
||||
// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
||||
@ -1061,6 +1288,22 @@ func diff(expected interface{}, actual interface{}) string {
|
||||
return "\n\nDiff:\n" + diff
|
||||
}
|
||||
|
||||
// validateEqualArgs checks whether provided arguments can be safely used in the
|
||||
// Equal/NotEqual functions.
|
||||
func validateEqualArgs(expected, actual interface{}) error {
|
||||
if isFunction(expected) || isFunction(actual) {
|
||||
return errors.New("cannot take func type as argument")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func isFunction(arg interface{}) bool {
|
||||
if arg == nil {
|
||||
return false
|
||||
}
|
||||
return reflect.TypeOf(arg).Kind() == reflect.Func
|
||||
}
|
||||
|
||||
var spewConfig = spew.ConfigState{
|
||||
Indent: " ",
|
||||
DisablePointerAddresses: true,
|
||||
|
308
src/vendor/github.com/stretchr/testify/assert/assertions_test.go
generated
vendored
@ -155,6 +155,9 @@ func TestImplements(t *testing.T) {
|
||||
if Implements(mockT, (*AssertionTesterInterface)(nil), new(AssertionTesterNonConformingObject)) {
|
||||
t.Error("Implements method should return false: AssertionTesterNonConformingObject does not implements AssertionTesterInterface")
|
||||
}
|
||||
if Implements(mockT, (*AssertionTesterInterface)(nil), nil) {
|
||||
t.Error("Implements method should return false: nil does not implement AssertionTesterInterface")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -254,8 +257,8 @@ func TestEqualFormatting(t *testing.T) {
|
||||
msgAndArgs []interface{}
|
||||
want string
|
||||
}{
|
||||
{equalWant: "want", equalGot: "got", want: "\tassertions.go:[0-9]+: \r \r\tError Trace:\t\n\t\t\r\tError: \tNot equal: \n\t\t\r\t \texpected: \"want\"\n\t\t\r\t \treceived: \"got\"\n"},
|
||||
{equalWant: "want", equalGot: "got", msgAndArgs: []interface{}{"hello, %v!", "world"}, want: "\tassertions.go:[0-9]+: \r \r\tError Trace:\t\n\t\t\r\tError: \tNot equal: \n\t\t\r\t \texpected: \"want\"\n\t\t\r\t \treceived: \"got\"\n\t\t\r\tMessages: \thello, world!\n"},
|
||||
{equalWant: "want", equalGot: "got", want: "\tassertions.go:[0-9]+: \r \r\tError Trace:\t\n\t\t\r\tError: \tNot equal: \n\t\t\r\t \texpected: \"want\"\n\t\t\r\t \tactual : \"got\"\n"},
|
||||
{equalWant: "want", equalGot: "got", msgAndArgs: []interface{}{"hello, %v!", "world"}, want: "\tassertions.go:[0-9]+: \r \r\tError Trace:\t\n\t\t\r\tError: \tNot equal: \n\t\t\r\t \texpected: \"want\"\n\t\t\r\t \tactual : \"got\"\n\t\t\r\tMessages: \thello, world!\n"},
|
||||
} {
|
||||
mockT := &bufferT{}
|
||||
Equal(mockT, currCase.equalWant, currCase.equalGot, currCase.msgAndArgs...)
|
||||
@ -396,8 +399,8 @@ func TestNotEqual(t *testing.T) {
|
||||
}
|
||||
funcA := func() int { return 23 }
|
||||
funcB := func() int { return 42 }
|
||||
if !NotEqual(mockT, funcA, funcB) {
|
||||
t.Error("NotEqual should return true")
|
||||
if NotEqual(mockT, funcA, funcB) {
|
||||
t.Error("NotEqual should return false")
|
||||
}
|
||||
|
||||
if NotEqual(mockT, "Hello World", "Hello World") {
|
||||
@ -493,6 +496,74 @@ func TestNotContains(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSubset(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
|
||||
if !Subset(mockT, []int{1, 2, 3}, nil) {
|
||||
t.Error("Subset should return true: given subset is nil")
|
||||
}
|
||||
if !Subset(mockT, []int{1, 2, 3}, []int{}) {
|
||||
t.Error("Subset should return true: any set contains the nil set")
|
||||
}
|
||||
if !Subset(mockT, []int{1, 2, 3}, []int{1, 2}) {
|
||||
t.Error("Subset should return true: [1, 2, 3] contains [1, 2]")
|
||||
}
|
||||
if !Subset(mockT, []int{1, 2, 3}, []int{1, 2, 3}) {
|
||||
t.Error("Subset should return true: [1, 2, 3] contains [1, 2, 3]")
|
||||
}
|
||||
if !Subset(mockT, []string{"hello", "world"}, []string{"hello"}) {
|
||||
t.Error("Subset should return true: [\"hello\", \"world\"] contains [\"hello\"]")
|
||||
}
|
||||
|
||||
if Subset(mockT, []string{"hello", "world"}, []string{"hello", "testify"}) {
|
||||
t.Error("Subset should return false: [\"hello\", \"world\"] does not contain [\"hello\", \"testify\"]")
|
||||
}
|
||||
if Subset(mockT, []int{1, 2, 3}, []int{4, 5}) {
|
||||
t.Error("Subset should return false: [1, 2, 3] does not contain [4, 5]")
|
||||
}
|
||||
if Subset(mockT, []int{1, 2, 3}, []int{1, 5}) {
|
||||
t.Error("Subset should return false: [1, 2, 3] does not contain [1, 5]")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotSubset(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
|
||||
if NotSubset(mockT, []int{1, 2, 3}, nil) {
|
||||
t.Error("NotSubset should return false: given subset is nil")
|
||||
}
|
||||
if NotSubset(mockT, []int{1, 2, 3}, []int{}) {
|
||||
t.Error("NotSubset should return false: any set contains the nil set")
|
||||
}
|
||||
if NotSubset(mockT, []int{1, 2, 3}, []int{1, 2}) {
|
||||
t.Error("NotSubset should return false: [1, 2, 3] contains [1, 2]")
|
||||
}
|
||||
if NotSubset(mockT, []int{1, 2, 3}, []int{1, 2, 3}) {
|
||||
t.Error("NotSubset should return false: [1, 2, 3] contains [1, 2, 3]")
|
||||
}
|
||||
if NotSubset(mockT, []string{"hello", "world"}, []string{"hello"}) {
|
||||
t.Error("NotSubset should return false: [\"hello\", \"world\"] contains [\"hello\"]")
|
||||
}
|
||||
|
||||
if !NotSubset(mockT, []string{"hello", "world"}, []string{"hello", "testify"}) {
|
||||
t.Error("NotSubset should return true: [\"hello\", \"world\"] does not contain [\"hello\", \"testify\"]")
|
||||
}
|
||||
if !NotSubset(mockT, []int{1, 2, 3}, []int{4, 5}) {
|
||||
t.Error("NotSubset should return true: [1, 2, 3] does not contain [4, 5]")
|
||||
}
|
||||
if !NotSubset(mockT, []int{1, 2, 3}, []int{1, 5}) {
|
||||
t.Error("NotSubset should return true: [1, 2, 3] does not contain [1, 5]")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotSubsetNil(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
NotSubset(mockT, []string{"foo"}, nil)
|
||||
if !mockT.Failed() {
|
||||
t.Error("NotSubset on nil set should have failed the test")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_includeElement(t *testing.T) {
|
||||
|
||||
list1 := []string{"Foo", "Bar"}
|
||||
@ -544,6 +615,57 @@ func Test_includeElement(t *testing.T) {
|
||||
False(t, found)
|
||||
}
|
||||
|
||||
func TestElementsMatch(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
|
||||
if !ElementsMatch(mockT, nil, nil) {
|
||||
t.Error("ElementsMatch should return true")
|
||||
}
|
||||
if !ElementsMatch(mockT, []int{}, []int{}) {
|
||||
t.Error("ElementsMatch should return true")
|
||||
}
|
||||
if !ElementsMatch(mockT, []int{1}, []int{1}) {
|
||||
t.Error("ElementsMatch should return true")
|
||||
}
|
||||
if !ElementsMatch(mockT, []int{1, 1}, []int{1, 1}) {
|
||||
t.Error("ElementsMatch should return true")
|
||||
}
|
||||
if !ElementsMatch(mockT, []int{1, 2}, []int{1, 2}) {
|
||||
t.Error("ElementsMatch should return true")
|
||||
}
|
||||
if !ElementsMatch(mockT, []int{1, 2}, []int{2, 1}) {
|
||||
t.Error("ElementsMatch should return true")
|
||||
}
|
||||
if !ElementsMatch(mockT, [2]int{1, 2}, [2]int{2, 1}) {
|
||||
t.Error("ElementsMatch should return true")
|
||||
}
|
||||
if !ElementsMatch(mockT, []string{"hello", "world"}, []string{"world", "hello"}) {
|
||||
t.Error("ElementsMatch should return true")
|
||||
}
|
||||
if !ElementsMatch(mockT, []string{"hello", "hello"}, []string{"hello", "hello"}) {
|
||||
t.Error("ElementsMatch should return true")
|
||||
}
|
||||
if !ElementsMatch(mockT, []string{"hello", "hello", "world"}, []string{"hello", "world", "hello"}) {
|
||||
t.Error("ElementsMatch should return true")
|
||||
}
|
||||
if !ElementsMatch(mockT, [3]string{"hello", "hello", "world"}, [3]string{"hello", "world", "hello"}) {
|
||||
t.Error("ElementsMatch should return true")
|
||||
}
|
||||
if !ElementsMatch(mockT, []int{}, nil) {
|
||||
t.Error("ElementsMatch should return true")
|
||||
}
|
||||
|
||||
if ElementsMatch(mockT, []int{1}, []int{1, 1}) {
|
||||
t.Error("ElementsMatch should return false")
|
||||
}
|
||||
if ElementsMatch(mockT, []int{1, 2}, []int{2, 2}) {
|
||||
t.Error("ElementsMatch should return false")
|
||||
}
|
||||
if ElementsMatch(mockT, []string{"hello", "hello"}, []string{"hello"}) {
|
||||
t.Error("ElementsMatch should return false")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCondition(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
|
||||
@ -589,6 +711,28 @@ func TestPanics(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestPanicsWithValue(t *testing.T) {
|
||||
|
||||
mockT := new(testing.T)
|
||||
|
||||
if !PanicsWithValue(mockT, "Panic!", func() {
|
||||
panic("Panic!")
|
||||
}) {
|
||||
t.Error("PanicsWithValue should return true")
|
||||
}
|
||||
|
||||
if PanicsWithValue(mockT, "Panic!", func() {
|
||||
}) {
|
||||
t.Error("PanicsWithValue should return false")
|
||||
}
|
||||
|
||||
if PanicsWithValue(mockT, "at the disco", func() {
|
||||
panic("Panic!")
|
||||
}) {
|
||||
t.Error("PanicsWithValue should return false")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotPanics(t *testing.T) {
|
||||
|
||||
mockT := new(testing.T)
|
||||
@ -630,7 +774,7 @@ func TestNoError(t *testing.T) {
|
||||
}()
|
||||
|
||||
if err == nil { // err is not nil here!
|
||||
t.Errorf("Error should be nil due to empty interface", err)
|
||||
t.Errorf("Error should be nil due to empty interface: %s", err)
|
||||
}
|
||||
|
||||
False(t, NoError(mockT, err), "NoError should fail with empty error interface")
|
||||
@ -654,6 +798,9 @@ func TestError(t *testing.T) {
|
||||
|
||||
True(t, Error(mockT, err), "Error with error should return True")
|
||||
|
||||
// go vet check
|
||||
True(t, Errorf(mockT, err, "example with %s", "formatted message"), "Errorf with error should rturn True")
|
||||
|
||||
// returning an empty error interface
|
||||
err = func() error {
|
||||
var err *customError
|
||||
@ -664,7 +811,7 @@ func TestError(t *testing.T) {
|
||||
}()
|
||||
|
||||
if err == nil { // err is not nil here!
|
||||
t.Errorf("Error should be nil due to empty interface", err)
|
||||
t.Errorf("Error should be nil due to empty interface: %s", err)
|
||||
}
|
||||
|
||||
True(t, Error(mockT, err), "Error should pass with empty error interface")
|
||||
@ -721,6 +868,15 @@ func TestEmpty(t *testing.T) {
|
||||
var tiNP time.Time
|
||||
var s *string
|
||||
var f *os.File
|
||||
sP := &s
|
||||
x := 1
|
||||
xP := &x
|
||||
|
||||
type TString string
|
||||
type TStruct struct {
|
||||
x int
|
||||
s []int
|
||||
}
|
||||
|
||||
True(t, Empty(mockT, ""), "Empty string is empty")
|
||||
True(t, Empty(mockT, nil), "Nil is empty")
|
||||
@ -732,6 +888,9 @@ func TestEmpty(t *testing.T) {
|
||||
True(t, Empty(mockT, f), "Nil os.File pointer is empty")
|
||||
True(t, Empty(mockT, tiP), "Nil time.Time pointer is empty")
|
||||
True(t, Empty(mockT, tiNP), "time.Time is empty")
|
||||
True(t, Empty(mockT, TStruct{}), "struct with zero values is empty")
|
||||
True(t, Empty(mockT, TString("")), "empty aliased string is empty")
|
||||
True(t, Empty(mockT, sP), "ptr to nil value is empty")
|
||||
|
||||
False(t, Empty(mockT, "something"), "Non Empty string is not empty")
|
||||
False(t, Empty(mockT, errors.New("something")), "Non nil object is not empty")
|
||||
@ -739,6 +898,9 @@ func TestEmpty(t *testing.T) {
|
||||
False(t, Empty(mockT, 1), "Non-zero int value is not empty")
|
||||
False(t, Empty(mockT, true), "True value is not empty")
|
||||
False(t, Empty(mockT, chWithValue), "Channel with values is not empty")
|
||||
False(t, Empty(mockT, TStruct{x: 1}), "struct with initialized values is empty")
|
||||
False(t, Empty(mockT, TString("abc")), "non-empty aliased string is empty")
|
||||
False(t, Empty(mockT, xP), "ptr to non-nil value is not empty")
|
||||
}
|
||||
|
||||
func TestNotEmpty(t *testing.T) {
|
||||
@ -945,6 +1107,82 @@ func TestInDeltaSlice(t *testing.T) {
|
||||
False(t, InDeltaSlice(mockT, "", nil, 1), "Expected non numeral slices to fail")
|
||||
}
|
||||
|
||||
func TestInDeltaMapValues(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
|
||||
for _, tc := range []struct {
|
||||
title string
|
||||
expect interface{}
|
||||
actual interface{}
|
||||
f func(TestingT, bool, ...interface{}) bool
|
||||
delta float64
|
||||
}{
|
||||
{
|
||||
title: "Within delta",
|
||||
expect: map[string]float64{
|
||||
"foo": 1.0,
|
||||
"bar": 2.0,
|
||||
},
|
||||
actual: map[string]float64{
|
||||
"foo": 1.01,
|
||||
"bar": 1.99,
|
||||
},
|
||||
delta: 0.1,
|
||||
f: True,
|
||||
},
|
||||
{
|
||||
title: "Within delta",
|
||||
expect: map[int]float64{
|
||||
1: 1.0,
|
||||
2: 2.0,
|
||||
},
|
||||
actual: map[int]float64{
|
||||
1: 1.0,
|
||||
2: 1.99,
|
||||
},
|
||||
delta: 0.1,
|
||||
f: True,
|
||||
},
|
||||
{
|
||||
title: "Different number of keys",
|
||||
expect: map[int]float64{
|
||||
1: 1.0,
|
||||
2: 2.0,
|
||||
},
|
||||
actual: map[int]float64{
|
||||
1: 1.0,
|
||||
},
|
||||
delta: 0.1,
|
||||
f: False,
|
||||
},
|
||||
{
|
||||
title: "Within delta with zero value",
|
||||
expect: map[string]float64{
|
||||
"zero": 0.0,
|
||||
},
|
||||
actual: map[string]float64{
|
||||
"zero": 0.0,
|
||||
},
|
||||
delta: 0.1,
|
||||
f: True,
|
||||
},
|
||||
{
|
||||
title: "With missing key with zero value",
|
||||
expect: map[string]float64{
|
||||
"zero": 0.0,
|
||||
"foo": 0.0,
|
||||
},
|
||||
actual: map[string]float64{
|
||||
"zero": 0.0,
|
||||
"bar": 0.0,
|
||||
},
|
||||
f: False,
|
||||
},
|
||||
} {
|
||||
tc.f(t, InDeltaMapValues(mockT, tc.expect, tc.actual, tc.delta), tc.title+"\n"+diff(tc.expect, tc.actual))
|
||||
}
|
||||
}
|
||||
|
||||
func TestInEpsilon(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
|
||||
@ -960,6 +1198,7 @@ func TestInEpsilon(t *testing.T) {
|
||||
{uint64(100), uint8(101), 0.01},
|
||||
{0.1, -0.1, 2},
|
||||
{0.1, 0, 2},
|
||||
{time.Second, time.Second + time.Millisecond, 0.002},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
@ -978,6 +1217,7 @@ func TestInEpsilon(t *testing.T) {
|
||||
{2.1, "bla-bla", 0},
|
||||
{0.1, -0.1, 1.99},
|
||||
{0, 0.1, 2}, // expected must be different to zero
|
||||
{time.Second, time.Second + 10*time.Millisecond, 0.002},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
@ -1081,6 +1321,28 @@ func TestNotZero(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFileExists(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
True(t, FileExists(mockT, "assertions.go"))
|
||||
|
||||
mockT = new(testing.T)
|
||||
False(t, FileExists(mockT, "random_file"))
|
||||
|
||||
mockT = new(testing.T)
|
||||
False(t, FileExists(mockT, "../_codegen"))
|
||||
}
|
||||
|
||||
func TestDirExists(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
False(t, DirExists(mockT, "assertions.go"))
|
||||
|
||||
mockT = new(testing.T)
|
||||
False(t, DirExists(mockT, "random_dir"))
|
||||
|
||||
mockT = new(testing.T)
|
||||
True(t, DirExists(mockT, "../_codegen"))
|
||||
}
|
||||
|
||||
func TestJSONEq_EqualSONString(t *testing.T) {
|
||||
mockT := new(testing.T)
|
||||
True(t, JSONEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`))
|
||||
@ -1283,3 +1545,37 @@ func TestFailNowWithFullTestingT(t *testing.T) {
|
||||
FailNow(mockT, "failed")
|
||||
}, "should call mockT.FailNow() rather than panicking")
|
||||
}
|
||||
|
||||
func TestBytesEqual(t *testing.T) {
|
||||
var cases = []struct {
|
||||
a, b []byte
|
||||
}{
|
||||
{make([]byte, 2), make([]byte, 2)},
|
||||
{make([]byte, 2), make([]byte, 2, 3)},
|
||||
{nil, make([]byte, 0)},
|
||||
}
|
||||
for i, c := range cases {
|
||||
Equal(t, reflect.DeepEqual(c.a, c.b), ObjectsAreEqual(c.a, c.b), "case %d failed", i+1)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkBytesEqual(b *testing.B) {
|
||||
const size = 1024 * 8
|
||||
s := make([]byte, size)
|
||||
for i := range s {
|
||||
s[i] = byte(i % 255)
|
||||
}
|
||||
s2 := make([]byte, size)
|
||||
copy(s2, s)
|
||||
|
||||
mockT := &mockFailNowTestingT{}
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
Equal(mockT, s, s2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEqualArgsValidation(t *testing.T) {
|
||||
err := validateEqualArgs(time.Now, time.Now)
|
||||
EqualError(t, err, "cannot take func type as argument")
|
||||
}
|
||||
|
2
src/vendor/github.com/stretchr/testify/assert/forward_assertions.go
generated
vendored
@ -13,4 +13,4 @@ func New(t TestingT) *Assertions {
|
||||
}
|
||||
}
|
||||
|
||||
//go:generate go run ../_codegen/main.go -output-package=assert -template=assertion_forward.go.tmpl
|
||||
//go:generate go run ../_codegen/main.go -output-package=assert -template=assertion_forward.go.tmpl -include-format-funcs
|
||||
|
59
src/vendor/github.com/stretchr/testify/assert/http_assertions.go
generated
vendored
@ -8,16 +8,16 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// httpCode is a helper that returns HTTP code of the response. It returns -1
|
||||
// if building a new request fails.
|
||||
func httpCode(handler http.HandlerFunc, method, url string, values url.Values) int {
|
||||
// httpCode is a helper that returns HTTP code of the response. It returns -1 and
|
||||
// an error if building a new request fails.
|
||||
func httpCode(handler http.HandlerFunc, method, url string, values url.Values) (int, error) {
|
||||
w := httptest.NewRecorder()
|
||||
req, err := http.NewRequest(method, url+"?"+values.Encode(), nil)
|
||||
if err != nil {
|
||||
return -1
|
||||
return -1, err
|
||||
}
|
||||
handler(w, req)
|
||||
return w.Code
|
||||
return w.Code, nil
|
||||
}
|
||||
|
||||
// HTTPSuccess asserts that a specified handler returns a success status code.
|
||||
@ -25,12 +25,19 @@ func httpCode(handler http.HandlerFunc, method, url string, values url.Values) i
|
||||
// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool {
|
||||
code := httpCode(handler, method, url, values)
|
||||
if code == -1 {
|
||||
func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
|
||||
code, err := httpCode(handler, method, url, values)
|
||||
if err != nil {
|
||||
Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err))
|
||||
return false
|
||||
}
|
||||
return code >= http.StatusOK && code <= http.StatusPartialContent
|
||||
|
||||
isSuccessCode := code >= http.StatusOK && code <= http.StatusPartialContent
|
||||
if !isSuccessCode {
|
||||
Fail(t, fmt.Sprintf("Expected HTTP success status code for %q but received %d", url+"?"+values.Encode(), code))
|
||||
}
|
||||
|
||||
return isSuccessCode
|
||||
}
|
||||
|
||||
// HTTPRedirect asserts that a specified handler returns a redirect status code.
|
||||
@ -38,12 +45,19 @@ func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, value
|
||||
// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool {
|
||||
code := httpCode(handler, method, url, values)
|
||||
if code == -1 {
|
||||
func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
|
||||
code, err := httpCode(handler, method, url, values)
|
||||
if err != nil {
|
||||
Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err))
|
||||
return false
|
||||
}
|
||||
return code >= http.StatusMultipleChoices && code <= http.StatusTemporaryRedirect
|
||||
|
||||
isRedirectCode := code >= http.StatusMultipleChoices && code <= http.StatusTemporaryRedirect
|
||||
if !isRedirectCode {
|
||||
Fail(t, fmt.Sprintf("Expected HTTP redirect status code for %q but received %d", url+"?"+values.Encode(), code))
|
||||
}
|
||||
|
||||
return isRedirectCode
|
||||
}
|
||||
|
||||
// HTTPError asserts that a specified handler returns an error status code.
|
||||
@ -51,12 +65,19 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, valu
|
||||
// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool {
|
||||
code := httpCode(handler, method, url, values)
|
||||
if code == -1 {
|
||||
func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
|
||||
code, err := httpCode(handler, method, url, values)
|
||||
if err != nil {
|
||||
Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err))
|
||||
return false
|
||||
}
|
||||
return code >= http.StatusBadRequest
|
||||
|
||||
isErrorCode := code >= http.StatusBadRequest
|
||||
if !isErrorCode {
|
||||
Fail(t, fmt.Sprintf("Expected HTTP error status code for %q but received %d", url+"?"+values.Encode(), code))
|
||||
}
|
||||
|
||||
return isErrorCode
|
||||
}
|
||||
|
||||
// HTTPBody is a helper that returns HTTP body of the response. It returns
|
||||
@ -77,7 +98,7 @@ func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) s
|
||||
// assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool {
|
||||
func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
|
||||
body := HTTPBody(handler, method, url, values)
|
||||
|
||||
contains := strings.Contains(body, fmt.Sprint(str))
|
||||
@ -94,7 +115,7 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string,
|
||||
// assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool {
|
||||
func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
|
||||
body := HTTPBody(handler, method, url, values)
|
||||
|
||||
contains := strings.Contains(body, fmt.Sprint(str))
|
||||
|
53
src/vendor/github.com/stretchr/testify/assert/http_assertions_test.go
generated
vendored
@ -19,21 +19,52 @@ func httpError(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
func TestHTTPStatuses(t *testing.T) {
|
||||
func TestHTTPSuccess(t *testing.T) {
|
||||
assert := New(t)
|
||||
mockT := new(testing.T)
|
||||
|
||||
assert.Equal(HTTPSuccess(mockT, httpOK, "GET", "/", nil), true)
|
||||
assert.Equal(HTTPSuccess(mockT, httpRedirect, "GET", "/", nil), false)
|
||||
assert.Equal(HTTPSuccess(mockT, httpError, "GET", "/", nil), false)
|
||||
mockT1 := new(testing.T)
|
||||
assert.Equal(HTTPSuccess(mockT1, httpOK, "GET", "/", nil), true)
|
||||
assert.False(mockT1.Failed())
|
||||
|
||||
assert.Equal(HTTPRedirect(mockT, httpOK, "GET", "/", nil), false)
|
||||
assert.Equal(HTTPRedirect(mockT, httpRedirect, "GET", "/", nil), true)
|
||||
assert.Equal(HTTPRedirect(mockT, httpError, "GET", "/", nil), false)
|
||||
mockT2 := new(testing.T)
|
||||
assert.Equal(HTTPSuccess(mockT2, httpRedirect, "GET", "/", nil), false)
|
||||
assert.True(mockT2.Failed())
|
||||
|
||||
assert.Equal(HTTPError(mockT, httpOK, "GET", "/", nil), false)
|
||||
assert.Equal(HTTPError(mockT, httpRedirect, "GET", "/", nil), false)
|
||||
assert.Equal(HTTPError(mockT, httpError, "GET", "/", nil), true)
|
||||
mockT3 := new(testing.T)
|
||||
assert.Equal(HTTPSuccess(mockT3, httpError, "GET", "/", nil), false)
|
||||
assert.True(mockT3.Failed())
|
||||
}
|
||||
|
||||
func TestHTTPRedirect(t *testing.T) {
|
||||
assert := New(t)
|
||||
|
||||
mockT1 := new(testing.T)
|
||||
assert.Equal(HTTPRedirect(mockT1, httpOK, "GET", "/", nil), false)
|
||||
assert.True(mockT1.Failed())
|
||||
|
||||
mockT2 := new(testing.T)
|
||||
assert.Equal(HTTPRedirect(mockT2, httpRedirect, "GET", "/", nil), true)
|
||||
assert.False(mockT2.Failed())
|
||||
|
||||
mockT3 := new(testing.T)
|
||||
assert.Equal(HTTPRedirect(mockT3, httpError, "GET", "/", nil), false)
|
||||
assert.True(mockT3.Failed())
|
||||
}
|
||||
|
||||
func TestHTTPError(t *testing.T) {
|
||||
assert := New(t)
|
||||
|
||||
mockT1 := new(testing.T)
|
||||
assert.Equal(HTTPError(mockT1, httpOK, "GET", "/", nil), false)
|
||||
assert.True(mockT1.Failed())
|
||||
|
||||
mockT2 := new(testing.T)
|
||||
assert.Equal(HTTPError(mockT2, httpRedirect, "GET", "/", nil), false)
|
||||
assert.True(mockT2.Failed())
|
||||
|
||||
mockT3 := new(testing.T)
|
||||
assert.Equal(HTTPError(mockT3, httpError, "GET", "/", nil), true)
|
||||
assert.False(mockT3.Failed())
|
||||
}
|
||||
|
||||
func TestHTTPStatusesWrapper(t *testing.T) {
|
||||
|
124
src/vendor/github.com/stretchr/testify/mock/mock.go
generated
vendored
@ -1,6 +1,7 @@
|
||||
package mock
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
@ -48,10 +49,15 @@ type Call struct {
|
||||
// Amount of times this call has been called
|
||||
totalCalls int
|
||||
|
||||
// Call to this method can be optional
|
||||
optional bool
|
||||
|
||||
// Holds a channel that will be used to block the Return until it either
|
||||
// receives a message or is closed. nil means it returns immediately.
|
||||
WaitFor <-chan time.Time
|
||||
|
||||
waitTime time.Duration
|
||||
|
||||
// Holds a handler used to manipulate arguments content that are passed by
|
||||
// reference. It's useful when mocking methods such as unmarshalers or
|
||||
// decoders.
|
||||
@ -130,7 +136,10 @@ func (c *Call) WaitUntil(w <-chan time.Time) *Call {
|
||||
//
|
||||
// Mock.On("MyMethod", arg1, arg2).After(time.Second)
|
||||
func (c *Call) After(d time.Duration) *Call {
|
||||
return c.WaitUntil(time.After(d))
|
||||
c.lock()
|
||||
defer c.unlock()
|
||||
c.waitTime = d
|
||||
return c
|
||||
}
|
||||
|
||||
// Run sets a handler to be called before returning. It can be used when
|
||||
@ -141,13 +150,22 @@ func (c *Call) After(d time.Duration) *Call {
|
||||
// arg := args.Get(0).(*map[string]interface{})
|
||||
// arg["foo"] = "bar"
|
||||
// })
|
||||
func (c *Call) Run(fn func(Arguments)) *Call {
|
||||
func (c *Call) Run(fn func(args Arguments)) *Call {
|
||||
c.lock()
|
||||
defer c.unlock()
|
||||
c.RunFn = fn
|
||||
return c
|
||||
}
|
||||
|
||||
// Maybe allows the method call to be optional. Not calling an optional method
|
||||
// will not cause an error while asserting expectations
|
||||
func (c *Call) Maybe() *Call {
|
||||
c.lock()
|
||||
defer c.unlock()
|
||||
c.optional = true
|
||||
return c
|
||||
}
|
||||
|
||||
// On chains a new expectation description onto the mocked interface. This
|
||||
// allows syntax like.
|
||||
//
|
||||
@ -214,8 +232,6 @@ func (m *Mock) On(methodName string, arguments ...interface{}) *Call {
|
||||
// */
|
||||
|
||||
func (m *Mock) findExpectedCall(method string, arguments ...interface{}) (int, *Call) {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
for i, call := range m.ExpectedCalls {
|
||||
if call.Method == method && call.Repeatability > -1 {
|
||||
|
||||
@ -287,8 +303,16 @@ func (m *Mock) Called(arguments ...interface{}) Arguments {
|
||||
}
|
||||
parts := strings.Split(functionPath, ".")
|
||||
functionName := parts[len(parts)-1]
|
||||
return m.MethodCalled(functionName, arguments...)
|
||||
}
|
||||
|
||||
found, call := m.findExpectedCall(functionName, arguments...)
|
||||
// MethodCalled tells the mock object that the given method has been called, and gets
|
||||
// an array of arguments to return. Panics if the call is unexpected (i.e. not preceded
|
||||
// by appropriate .On .Return() calls)
|
||||
// If Call.WaitFor is set, blocks until the channel is closed or receives a message.
|
||||
func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Arguments {
|
||||
m.mutex.Lock()
|
||||
found, call := m.findExpectedCall(methodName, arguments...)
|
||||
|
||||
if found < 0 {
|
||||
// we have to fail here - because we don't know what to do
|
||||
@ -298,45 +322,47 @@ func (m *Mock) Called(arguments ...interface{}) Arguments {
|
||||
// b) the arguments are not what was expected, or
|
||||
// c) the developer has forgotten to add an accompanying On...Return pair.
|
||||
|
||||
closestFound, closestCall := m.findClosestCall(functionName, arguments...)
|
||||
closestFound, closestCall := m.findClosestCall(methodName, arguments...)
|
||||
m.mutex.Unlock()
|
||||
|
||||
if closestFound {
|
||||
panic(fmt.Sprintf("\n\nmock: Unexpected Method Call\n-----------------------------\n\n%s\n\nThe closest call I have is: \n\n%s\n\n%s\n", callString(functionName, arguments, true), callString(functionName, closestCall.Arguments, true), diffArguments(arguments, closestCall.Arguments)))
|
||||
panic(fmt.Sprintf("\n\nmock: Unexpected Method Call\n-----------------------------\n\n%s\n\nThe closest call I have is: \n\n%s\n\n%s\n", callString(methodName, arguments, true), callString(methodName, closestCall.Arguments, true), diffArguments(closestCall.Arguments, arguments)))
|
||||
} else {
|
||||
panic(fmt.Sprintf("\nassert: mock: I don't know what to return because the method call was unexpected.\n\tEither do Mock.On(\"%s\").Return(...) first, or remove the %s() call.\n\tThis method was unexpected:\n\t\t%s\n\tat: %s", functionName, functionName, callString(functionName, arguments, true), assert.CallerInfo()))
|
||||
panic(fmt.Sprintf("\nassert: mock: I don't know what to return because the method call was unexpected.\n\tEither do Mock.On(\"%s\").Return(...) first, or remove the %s() call.\n\tThis method was unexpected:\n\t\t%s\n\tat: %s", methodName, methodName, callString(methodName, arguments, true), assert.CallerInfo()))
|
||||
}
|
||||
} else {
|
||||
m.mutex.Lock()
|
||||
switch {
|
||||
case call.Repeatability == 1:
|
||||
call.Repeatability = -1
|
||||
call.totalCalls++
|
||||
|
||||
case call.Repeatability > 1:
|
||||
call.Repeatability--
|
||||
call.totalCalls++
|
||||
|
||||
case call.Repeatability == 0:
|
||||
call.totalCalls++
|
||||
}
|
||||
m.mutex.Unlock()
|
||||
}
|
||||
|
||||
if call.Repeatability == 1 {
|
||||
call.Repeatability = -1
|
||||
} else if call.Repeatability > 1 {
|
||||
call.Repeatability--
|
||||
}
|
||||
call.totalCalls++
|
||||
|
||||
// add the call
|
||||
m.mutex.Lock()
|
||||
m.Calls = append(m.Calls, *newCall(m, functionName, arguments...))
|
||||
m.Calls = append(m.Calls, *newCall(m, methodName, arguments...))
|
||||
m.mutex.Unlock()
|
||||
|
||||
// block if specified
|
||||
if call.WaitFor != nil {
|
||||
<-call.WaitFor
|
||||
} else {
|
||||
time.Sleep(call.waitTime)
|
||||
}
|
||||
|
||||
if call.RunFn != nil {
|
||||
call.RunFn(arguments)
|
||||
m.mutex.Lock()
|
||||
runFn := call.RunFn
|
||||
m.mutex.Unlock()
|
||||
|
||||
if runFn != nil {
|
||||
runFn(arguments)
|
||||
}
|
||||
|
||||
return call.ReturnArguments
|
||||
m.mutex.Lock()
|
||||
returnArgs := call.ReturnArguments
|
||||
m.mutex.Unlock()
|
||||
|
||||
return returnArgs
|
||||
}
|
||||
|
||||
/*
|
||||
@ -368,25 +394,25 @@ func AssertExpectationsForObjects(t TestingT, testObjects ...interface{}) bool {
|
||||
// AssertExpectations asserts that everything specified with On and Return was
|
||||
// in fact called as expected. Calls may have occurred in any order.
|
||||
func (m *Mock) AssertExpectations(t TestingT) bool {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
var somethingMissing bool
|
||||
var failedExpectations int
|
||||
|
||||
// iterate through each expectation
|
||||
expectedCalls := m.expectedCalls()
|
||||
for _, expectedCall := range expectedCalls {
|
||||
if !m.methodWasCalled(expectedCall.Method, expectedCall.Arguments) && expectedCall.totalCalls == 0 {
|
||||
if !expectedCall.optional && !m.methodWasCalled(expectedCall.Method, expectedCall.Arguments) && expectedCall.totalCalls == 0 {
|
||||
somethingMissing = true
|
||||
failedExpectations++
|
||||
t.Logf("\u274C\t%s(%s)", expectedCall.Method, expectedCall.Arguments.String())
|
||||
} else {
|
||||
m.mutex.Lock()
|
||||
if expectedCall.Repeatability > 0 {
|
||||
somethingMissing = true
|
||||
failedExpectations++
|
||||
} else {
|
||||
t.Logf("\u2705\t%s(%s)", expectedCall.Method, expectedCall.Arguments.String())
|
||||
}
|
||||
m.mutex.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
@ -399,6 +425,8 @@ func (m *Mock) AssertExpectations(t TestingT) bool {
|
||||
|
||||
// AssertNumberOfCalls asserts that the method was called expectedCalls times.
|
||||
func (m *Mock) AssertNumberOfCalls(t TestingT, methodName string, expectedCalls int) bool {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
var actualCalls int
|
||||
for _, call := range m.calls() {
|
||||
if call.Method == methodName {
|
||||
@ -411,6 +439,8 @@ func (m *Mock) AssertNumberOfCalls(t TestingT, methodName string, expectedCalls
|
||||
// AssertCalled asserts that the method was called.
|
||||
// It can produce a false result when an argument is a pointer type and the underlying value changed after calling the mocked method.
|
||||
func (m *Mock) AssertCalled(t TestingT, methodName string, arguments ...interface{}) bool {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
if !assert.True(t, m.methodWasCalled(methodName, arguments), fmt.Sprintf("The \"%s\" method should have been called with %d argument(s), but was not.", methodName, len(arguments))) {
|
||||
t.Logf("%v", m.expectedCalls())
|
||||
return false
|
||||
@ -421,6 +451,8 @@ func (m *Mock) AssertCalled(t TestingT, methodName string, arguments ...interfac
|
||||
// AssertNotCalled asserts that the method was not called.
|
||||
// It can produce a false result when an argument is a pointer type and the underlying value changed after calling the mocked method.
|
||||
func (m *Mock) AssertNotCalled(t TestingT, methodName string, arguments ...interface{}) bool {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
if !assert.False(t, m.methodWasCalled(methodName, arguments), fmt.Sprintf("The \"%s\" method was called with %d argument(s), but should NOT have been.", methodName, len(arguments))) {
|
||||
t.Logf("%v", m.expectedCalls())
|
||||
return false
|
||||
@ -446,14 +478,10 @@ func (m *Mock) methodWasCalled(methodName string, expected []interface{}) bool {
|
||||
}
|
||||
|
||||
func (m *Mock) expectedCalls() []*Call {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
return append([]*Call{}, m.ExpectedCalls...)
|
||||
}
|
||||
|
||||
func (m *Mock) calls() []Call {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
return append([]Call{}, m.Calls...)
|
||||
}
|
||||
|
||||
@ -492,9 +520,25 @@ type argumentMatcher struct {
|
||||
|
||||
func (f argumentMatcher) Matches(argument interface{}) bool {
|
||||
expectType := f.fn.Type().In(0)
|
||||
expectTypeNilSupported := false
|
||||
switch expectType.Kind() {
|
||||
case reflect.Interface, reflect.Chan, reflect.Func, reflect.Map, reflect.Slice, reflect.Ptr:
|
||||
expectTypeNilSupported = true
|
||||
}
|
||||
|
||||
if reflect.TypeOf(argument).AssignableTo(expectType) {
|
||||
result := f.fn.Call([]reflect.Value{reflect.ValueOf(argument)})
|
||||
argType := reflect.TypeOf(argument)
|
||||
var arg reflect.Value
|
||||
if argType == nil {
|
||||
arg = reflect.New(expectType).Elem()
|
||||
} else {
|
||||
arg = reflect.ValueOf(argument)
|
||||
}
|
||||
|
||||
if argType == nil && !expectTypeNilSupported {
|
||||
panic(errors.New("attempting to call matcher with nil for non-nil expected type"))
|
||||
}
|
||||
if argType == nil || argType.AssignableTo(expectType) {
|
||||
result := f.fn.Call([]reflect.Value{arg})
|
||||
return result[0].Bool()
|
||||
}
|
||||
return false
|
||||
@ -514,7 +558,7 @@ func (f argumentMatcher) String() string {
|
||||
//
|
||||
// |fn|, must be a function accepting a single argument (of the expected type)
|
||||
// which returns a bool. If |fn| doesn't match the required signature,
|
||||
// MathedBy() panics.
|
||||
// MatchedBy() panics.
|
||||
func MatchedBy(fn interface{}) argumentMatcher {
|
||||
fnType := reflect.TypeOf(fn)
|
||||
|
||||
@ -715,6 +759,10 @@ func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) {
|
||||
}
|
||||
|
||||
func diffArguments(expected Arguments, actual Arguments) string {
|
||||
if len(expected) != len(actual) {
|
||||
return fmt.Sprintf("Provided %v arguments, mocked for %v arguments", len(expected), len(actual))
|
||||
}
|
||||
|
||||
for x := range expected {
|
||||
if diffString := diff(expected[x], actual[x]); diffString != "" {
|
||||
return fmt.Sprintf("Difference found in argument %v:\n\n%s", x, diffString)
|
||||
|
210
src/vendor/github.com/stretchr/testify/mock/mock_test.go
generated
vendored
@ -2,10 +2,13 @@ package mock
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"fmt"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
/*
|
||||
@ -40,6 +43,26 @@ func (i *TestExampleImplementation) TheExampleMethod3(et *ExampleType) error {
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (i *TestExampleImplementation) TheExampleMethod4(v ExampleInterface) error {
|
||||
args := i.Called(v)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (i *TestExampleImplementation) TheExampleMethod5(ch chan struct{}) error {
|
||||
args := i.Called(ch)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (i *TestExampleImplementation) TheExampleMethod6(m map[string]bool) error {
|
||||
args := i.Called(m)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (i *TestExampleImplementation) TheExampleMethod7(slice []bool) error {
|
||||
args := i.Called(slice)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (i *TestExampleImplementation) TheExampleMethodFunc(fn func(string) error) error {
|
||||
args := i.Called(fn)
|
||||
return args.Error(0)
|
||||
@ -55,6 +78,11 @@ func (i *TestExampleImplementation) TheExampleMethodVariadicInterface(a ...inter
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (i *TestExampleImplementation) TheExampleMethodMixedVariadic(a int, b ...int) error {
|
||||
args := i.Called(a, b)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
type ExampleFuncType func(string) error
|
||||
|
||||
func (i *TestExampleImplementation) TheExampleMethodFuncType(fn ExampleFuncType) error {
|
||||
@ -174,15 +202,20 @@ func Test_Mock_On_WithPtrArgMatcher(t *testing.T) {
|
||||
var mockedService TestExampleImplementation
|
||||
|
||||
mockedService.On("TheExampleMethod3",
|
||||
MatchedBy(func(a *ExampleType) bool { return a.ran == true }),
|
||||
MatchedBy(func(a *ExampleType) bool { return a != nil && a.ran == true }),
|
||||
).Return(nil)
|
||||
|
||||
mockedService.On("TheExampleMethod3",
|
||||
MatchedBy(func(a *ExampleType) bool { return a.ran == false }),
|
||||
MatchedBy(func(a *ExampleType) bool { return a != nil && a.ran == false }),
|
||||
).Return(errors.New("error"))
|
||||
|
||||
mockedService.On("TheExampleMethod3",
|
||||
MatchedBy(func(a *ExampleType) bool { return a == nil }),
|
||||
).Return(errors.New("error2"))
|
||||
|
||||
assert.Equal(t, mockedService.TheExampleMethod3(&ExampleType{true}), nil)
|
||||
assert.EqualError(t, mockedService.TheExampleMethod3(&ExampleType{false}), "error")
|
||||
assert.EqualError(t, mockedService.TheExampleMethod3(nil), "error2")
|
||||
}
|
||||
|
||||
func Test_Mock_On_WithFuncArgMatcher(t *testing.T) {
|
||||
@ -191,17 +224,62 @@ func Test_Mock_On_WithFuncArgMatcher(t *testing.T) {
|
||||
fixture1, fixture2 := errors.New("fixture1"), errors.New("fixture2")
|
||||
|
||||
mockedService.On("TheExampleMethodFunc",
|
||||
MatchedBy(func(a func(string) error) bool { return a("string") == fixture1 }),
|
||||
MatchedBy(func(a func(string) error) bool { return a != nil && a("string") == fixture1 }),
|
||||
).Return(errors.New("fixture1"))
|
||||
|
||||
mockedService.On("TheExampleMethodFunc",
|
||||
MatchedBy(func(a func(string) error) bool { return a("string") == fixture2 }),
|
||||
MatchedBy(func(a func(string) error) bool { return a != nil && a("string") == fixture2 }),
|
||||
).Return(errors.New("fixture2"))
|
||||
|
||||
mockedService.On("TheExampleMethodFunc",
|
||||
MatchedBy(func(a func(string) error) bool { return a == nil }),
|
||||
).Return(errors.New("fixture3"))
|
||||
|
||||
assert.EqualError(t, mockedService.TheExampleMethodFunc(
|
||||
func(string) error { return fixture1 }), "fixture1")
|
||||
assert.EqualError(t, mockedService.TheExampleMethodFunc(
|
||||
func(string) error { return fixture2 }), "fixture2")
|
||||
assert.EqualError(t, mockedService.TheExampleMethodFunc(nil), "fixture3")
|
||||
}
|
||||
|
||||
func Test_Mock_On_WithInterfaceArgMatcher(t *testing.T) {
|
||||
var mockedService TestExampleImplementation
|
||||
|
||||
mockedService.On("TheExampleMethod4",
|
||||
MatchedBy(func(a ExampleInterface) bool { return a == nil }),
|
||||
).Return(errors.New("fixture1"))
|
||||
|
||||
assert.EqualError(t, mockedService.TheExampleMethod4(nil), "fixture1")
|
||||
}
|
||||
|
||||
func Test_Mock_On_WithChannelArgMatcher(t *testing.T) {
|
||||
var mockedService TestExampleImplementation
|
||||
|
||||
mockedService.On("TheExampleMethod5",
|
||||
MatchedBy(func(ch chan struct{}) bool { return ch == nil }),
|
||||
).Return(errors.New("fixture1"))
|
||||
|
||||
assert.EqualError(t, mockedService.TheExampleMethod5(nil), "fixture1")
|
||||
}
|
||||
|
||||
func Test_Mock_On_WithMapArgMatcher(t *testing.T) {
|
||||
var mockedService TestExampleImplementation
|
||||
|
||||
mockedService.On("TheExampleMethod6",
|
||||
MatchedBy(func(m map[string]bool) bool { return m == nil }),
|
||||
).Return(errors.New("fixture1"))
|
||||
|
||||
assert.EqualError(t, mockedService.TheExampleMethod6(nil), "fixture1")
|
||||
}
|
||||
|
||||
func Test_Mock_On_WithSliceArgMatcher(t *testing.T) {
|
||||
var mockedService TestExampleImplementation
|
||||
|
||||
mockedService.On("TheExampleMethod7",
|
||||
MatchedBy(func(slice []bool) bool { return slice == nil }),
|
||||
).Return(errors.New("fixture1"))
|
||||
|
||||
assert.EqualError(t, mockedService.TheExampleMethod7(nil), "fixture1")
|
||||
}
|
||||
|
||||
func Test_Mock_On_WithVariadicFunc(t *testing.T) {
|
||||
@ -226,6 +304,29 @@ func Test_Mock_On_WithVariadicFunc(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func Test_Mock_On_WithMixedVariadicFunc(t *testing.T) {
|
||||
|
||||
// make a test impl object
|
||||
var mockedService = new(TestExampleImplementation)
|
||||
|
||||
c := mockedService.
|
||||
On("TheExampleMethodMixedVariadic", 1, []int{2, 3, 4}).
|
||||
Return(nil)
|
||||
|
||||
assert.Equal(t, []*Call{c}, mockedService.ExpectedCalls)
|
||||
assert.Equal(t, 2, len(c.Arguments))
|
||||
assert.Equal(t, 1, c.Arguments[0])
|
||||
assert.Equal(t, []int{2, 3, 4}, c.Arguments[1])
|
||||
|
||||
assert.NotPanics(t, func() {
|
||||
mockedService.TheExampleMethodMixedVariadic(1, 2, 3, 4)
|
||||
})
|
||||
assert.Panics(t, func() {
|
||||
mockedService.TheExampleMethodMixedVariadic(1, 2, 3, 5)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func Test_Mock_On_WithVariadicFuncWithInterface(t *testing.T) {
|
||||
|
||||
// make a test impl object
|
||||
@ -726,7 +827,7 @@ func Test_AssertExpectationsForObjects_Helper(t *testing.T) {
|
||||
mockedService2.Called(2)
|
||||
mockedService3.Called(3)
|
||||
|
||||
assert.True(t, AssertExpectationsForObjects(t, mockedService1.Mock, mockedService2.Mock, mockedService3.Mock))
|
||||
assert.True(t, AssertExpectationsForObjects(t, &mockedService1.Mock, &mockedService2.Mock, &mockedService3.Mock))
|
||||
assert.True(t, AssertExpectationsForObjects(t, mockedService1, mockedService2, mockedService3))
|
||||
|
||||
}
|
||||
@ -745,7 +846,7 @@ func Test_AssertExpectationsForObjects_Helper_Failed(t *testing.T) {
|
||||
mockedService3.Called(3)
|
||||
|
||||
tt := new(testing.T)
|
||||
assert.False(t, AssertExpectationsForObjects(tt, mockedService1.Mock, mockedService2.Mock, mockedService3.Mock))
|
||||
assert.False(t, AssertExpectationsForObjects(tt, &mockedService1.Mock, &mockedService2.Mock, &mockedService3.Mock))
|
||||
assert.False(t, AssertExpectationsForObjects(tt, mockedService1, mockedService2, mockedService3))
|
||||
|
||||
}
|
||||
@ -969,6 +1070,31 @@ func Test_Mock_AssertNotCalled(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func Test_Mock_AssertOptional(t *testing.T) {
|
||||
// Optional called
|
||||
var ms1 = new(TestExampleImplementation)
|
||||
ms1.On("TheExampleMethod", 1, 2, 3).Maybe().Return(4, nil)
|
||||
ms1.TheExampleMethod(1, 2, 3)
|
||||
|
||||
tt1 := new(testing.T)
|
||||
assert.Equal(t, true, ms1.AssertExpectations(tt1))
|
||||
|
||||
// Optional not called
|
||||
var ms2 = new(TestExampleImplementation)
|
||||
ms2.On("TheExampleMethod", 1, 2, 3).Maybe().Return(4, nil)
|
||||
|
||||
tt2 := new(testing.T)
|
||||
assert.Equal(t, true, ms2.AssertExpectations(tt2))
|
||||
|
||||
// Non-optional called
|
||||
var ms3 = new(TestExampleImplementation)
|
||||
ms3.On("TheExampleMethod", 1, 2, 3).Return(4, nil)
|
||||
ms3.TheExampleMethod(1, 2, 3)
|
||||
|
||||
tt3 := new(testing.T)
|
||||
assert.Equal(t, true, ms3.AssertExpectations(tt3))
|
||||
}
|
||||
|
||||
/*
|
||||
Arguments helper methods
|
||||
*/
|
||||
@ -1156,3 +1282,71 @@ func Test_WaitUntil_Parallel(t *testing.T) {
|
||||
// Allow the first call to execute, so the second one executes afterwards
|
||||
ch2 <- time.Now()
|
||||
}
|
||||
|
||||
func Test_MockMethodCalled(t *testing.T) {
|
||||
m := new(Mock)
|
||||
m.On("foo", "hello").Return("world")
|
||||
|
||||
retArgs := m.MethodCalled("foo", "hello")
|
||||
require.True(t, len(retArgs) == 1)
|
||||
require.Equal(t, "world", retArgs[0])
|
||||
m.AssertExpectations(t)
|
||||
}
|
||||
|
||||
// Test to validate fix for racy concurrent call access in MethodCalled()
|
||||
func Test_MockReturnAndCalledConcurrent(t *testing.T) {
|
||||
iterations := 1000
|
||||
m := &Mock{}
|
||||
call := m.On("ConcurrencyTestMethod")
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(2)
|
||||
|
||||
go func() {
|
||||
for i := 0; i < iterations; i++ {
|
||||
call.Return(10)
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
go func() {
|
||||
for i := 0; i < iterations; i++ {
|
||||
ConcurrencyTestMethod(m)
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
type timer struct{ Mock }
|
||||
|
||||
func (s *timer) GetTime(i int) string {
|
||||
return s.Called(i).Get(0).(string)
|
||||
}
|
||||
|
||||
func TestAfterTotalWaitTimeWhileExecution(t *testing.T) {
|
||||
waitDuration := 1
|
||||
total, waitMs := 5, time.Millisecond*time.Duration(waitDuration)
|
||||
aTimer := new(timer)
|
||||
for i := 0; i < total; i++ {
|
||||
aTimer.On("GetTime", i).After(waitMs).Return(fmt.Sprintf("Time%d", i)).Once()
|
||||
}
|
||||
time.Sleep(waitMs)
|
||||
start := time.Now()
|
||||
var results []string
|
||||
|
||||
for i := 0; i < total; i++ {
|
||||
results = append(results, aTimer.GetTime(i))
|
||||
}
|
||||
|
||||
end := time.Now()
|
||||
elapsedTime := end.Sub(start)
|
||||
assert.True(t, elapsedTime > waitMs, fmt.Sprintf("Total elapsed time:%v should be atleast greater than %v", elapsedTime, waitMs))
|
||||
assert.Equal(t, total, len(results))
|
||||
for i, _ := range results {
|
||||
assert.Equal(t, fmt.Sprintf("Time%d", i), results[i], "Return value of method should be same")
|
||||
}
|
||||
}
|
||||
|
||||
func ConcurrencyTestMethod(m *Mock) {
|
||||
m.Called()
|
||||
}
|
||||
|
2
src/vendor/github.com/stretchr/testify/require/forward_requirements.go
generated
vendored
@ -13,4 +13,4 @@ func New(t TestingT) *Assertions {
|
||||
}
|
||||
}
|
||||
|
||||
//go:generate go run ../_codegen/main.go -output-package=require -template=require_forward.go.tmpl
|
||||
//go:generate go run ../_codegen/main.go -output-package=require -template=require_forward.go.tmpl -include-format-funcs
|
||||
|
628
src/vendor/github.com/stretchr/testify/require/require.go
generated
vendored
@ -19,12 +19,19 @@ func Condition(t TestingT, comp assert.Comparison, msgAndArgs ...interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// Conditionf uses a Comparison to assert a complex condition.
|
||||
func Conditionf(t TestingT, comp assert.Comparison, msg string, args ...interface{}) {
|
||||
if !assert.Conditionf(t, comp, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// Contains asserts that the specified string, list(array, slice...) or map contains the
|
||||
// specified substring or element.
|
||||
//
|
||||
// assert.Contains(t, "Hello World", "World", "But 'Hello World' does contain 'World'")
|
||||
// assert.Contains(t, ["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'")
|
||||
// assert.Contains(t, {"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'")
|
||||
// assert.Contains(t, "Hello World", "World")
|
||||
// assert.Contains(t, ["Hello", "World"], "World")
|
||||
// assert.Contains(t, {"Hello": "World"}, "Hello")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) {
|
||||
@ -33,6 +40,60 @@ func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...int
|
||||
}
|
||||
}
|
||||
|
||||
// Containsf asserts that the specified string, list(array, slice...) or map contains the
|
||||
// specified substring or element.
|
||||
//
|
||||
// assert.Containsf(t, "Hello World", "World", "error message %s", "formatted")
|
||||
// assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted")
|
||||
// assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) {
|
||||
if !assert.Containsf(t, s, contains, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
|
||||
func DirExists(t TestingT, path string, msgAndArgs ...interface{}) {
|
||||
if !assert.DirExists(t, path, msgAndArgs...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
|
||||
func DirExistsf(t TestingT, path string, msg string, args ...interface{}) {
|
||||
if !assert.DirExistsf(t, path, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified
|
||||
// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,
|
||||
// the number of appearances of each of them in both lists should match.
|
||||
//
|
||||
// assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2]))
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func ElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs ...interface{}) {
|
||||
if !assert.ElementsMatch(t, listA, listB, msgAndArgs...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified
|
||||
// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,
|
||||
// the number of appearances of each of them in both lists should match.
|
||||
//
|
||||
// assert.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted"))
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) {
|
||||
if !assert.ElementsMatchf(t, listA, listB, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
//
|
||||
@ -45,14 +106,27 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
//
|
||||
// assert.Emptyf(t, obj, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) {
|
||||
if !assert.Emptyf(t, object, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// Equal asserts that two objects are equal.
|
||||
//
|
||||
// assert.Equal(t, 123, 123, "123 and 123 should be equal")
|
||||
// assert.Equal(t, 123, 123)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
//
|
||||
// Pointer variable equality is determined based on the equality of the
|
||||
// referenced values (as opposed to the memory addresses).
|
||||
// referenced values (as opposed to the memory addresses). Function equality
|
||||
// cannot be determined and will always fail.
|
||||
func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
|
||||
if !assert.Equal(t, expected, actual, msgAndArgs...) {
|
||||
t.FailNow()
|
||||
@ -63,7 +137,7 @@ func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...i
|
||||
// and that it is equal to the provided error.
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// assert.EqualError(t, err, expectedErrorString, "An error was expected")
|
||||
// assert.EqualError(t, err, expectedErrorString)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) {
|
||||
@ -72,10 +146,23 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte
|
||||
}
|
||||
}
|
||||
|
||||
// EqualErrorf asserts that a function returned an error (i.e. not `nil`)
|
||||
// and that it is equal to the provided error.
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// assert.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) {
|
||||
if !assert.EqualErrorf(t, theError, errString, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// EqualValues asserts that two objects are equal or convertable to the same types
|
||||
// and equal.
|
||||
//
|
||||
// assert.EqualValues(t, uint32(123), int32(123), "123 and 123 should be equal")
|
||||
// assert.EqualValues(t, uint32(123), int32(123))
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
|
||||
@ -84,11 +171,38 @@ func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArg
|
||||
}
|
||||
}
|
||||
|
||||
// EqualValuesf asserts that two objects are equal or convertable to the same types
|
||||
// and equal.
|
||||
//
|
||||
// assert.EqualValuesf(t, uint32(123, "error message %s", "formatted"), int32(123))
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {
|
||||
if !assert.EqualValuesf(t, expected, actual, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// Equalf asserts that two objects are equal.
|
||||
//
|
||||
// assert.Equalf(t, 123, 123, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
//
|
||||
// Pointer variable equality is determined based on the equality of the
|
||||
// referenced values (as opposed to the memory addresses). Function equality
|
||||
// cannot be determined and will always fail.
|
||||
func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {
|
||||
if !assert.Equalf(t, expected, actual, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// Error asserts that a function returned an error (i.e. not `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// if assert.Error(t, err, "An error was expected") {
|
||||
// assert.Equal(t, err, expectedError)
|
||||
// if assert.Error(t, err) {
|
||||
// assert.Equal(t, expectedError, err)
|
||||
// }
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
@ -98,9 +212,23 @@ func Error(t TestingT, err error, msgAndArgs ...interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// Exactly asserts that two objects are equal is value and type.
|
||||
// Errorf asserts that a function returned an error (i.e. not `nil`).
|
||||
//
|
||||
// assert.Exactly(t, int32(123), int64(123), "123 and 123 should NOT be equal")
|
||||
// actualObj, err := SomeFunction()
|
||||
// if assert.Errorf(t, err, "error message %s", "formatted") {
|
||||
// assert.Equal(t, expectedErrorf, err)
|
||||
// }
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Errorf(t TestingT, err error, msg string, args ...interface{}) {
|
||||
if !assert.Errorf(t, err, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// Exactly asserts that two objects are equal in value and type.
|
||||
//
|
||||
// assert.Exactly(t, int32(123), int64(123))
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
|
||||
@ -109,6 +237,17 @@ func Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs ..
|
||||
}
|
||||
}
|
||||
|
||||
// Exactlyf asserts that two objects are equal in value and type.
|
||||
//
|
||||
// assert.Exactlyf(t, int32(123, "error message %s", "formatted"), int64(123))
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {
|
||||
if !assert.Exactlyf(t, expected, actual, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// Fail reports a failure through
|
||||
func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) {
|
||||
if !assert.Fail(t, failureMessage, msgAndArgs...) {
|
||||
@ -123,9 +262,23 @@ func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// FailNowf fails test
|
||||
func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}) {
|
||||
if !assert.FailNowf(t, failureMessage, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// Failf reports a failure through
|
||||
func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) {
|
||||
if !assert.Failf(t, failureMessage, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// False asserts that the specified value is false.
|
||||
//
|
||||
// assert.False(t, myBool, "myBool should be false")
|
||||
// assert.False(t, myBool)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func False(t TestingT, value bool, msgAndArgs ...interface{}) {
|
||||
@ -134,14 +287,51 @@ func False(t TestingT, value bool, msgAndArgs ...interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// Falsef asserts that the specified value is false.
|
||||
//
|
||||
// assert.Falsef(t, myBool, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Falsef(t TestingT, value bool, msg string, args ...interface{}) {
|
||||
if !assert.Falsef(t, value, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
|
||||
func FileExists(t TestingT, path string, msgAndArgs ...interface{}) {
|
||||
if !assert.FileExists(t, path, msgAndArgs...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
|
||||
func FileExistsf(t TestingT, path string, msg string, args ...interface{}) {
|
||||
if !assert.FileExistsf(t, path, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// HTTPBodyContains asserts that a specified handler returns a
|
||||
// body that contains a string.
|
||||
//
|
||||
// assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) {
|
||||
if !assert.HTTPBodyContains(t, handler, method, url, values, str) {
|
||||
func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) {
|
||||
if !assert.HTTPBodyContains(t, handler, method, url, values, str, msgAndArgs...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// HTTPBodyContainsf asserts that a specified handler returns a
|
||||
// body that contains a string.
|
||||
//
|
||||
// assert.HTTPBodyContainsf(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) {
|
||||
if !assert.HTTPBodyContainsf(t, handler, method, url, values, str, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
@ -152,8 +342,20 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url s
|
||||
// assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) {
|
||||
if !assert.HTTPBodyNotContains(t, handler, method, url, values, str) {
|
||||
func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) {
|
||||
if !assert.HTTPBodyNotContains(t, handler, method, url, values, str, msgAndArgs...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// HTTPBodyNotContainsf asserts that a specified handler returns a
|
||||
// body that does not contain a string.
|
||||
//
|
||||
// assert.HTTPBodyNotContainsf(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) {
|
||||
if !assert.HTTPBodyNotContainsf(t, handler, method, url, values, str, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
@ -163,8 +365,19 @@ func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, ur
|
||||
// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values) {
|
||||
if !assert.HTTPError(t, handler, method, url, values) {
|
||||
func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {
|
||||
if !assert.HTTPError(t, handler, method, url, values, msgAndArgs...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// HTTPErrorf asserts that a specified handler returns an error status code.
|
||||
//
|
||||
// assert.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
//
|
||||
// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
|
||||
func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {
|
||||
if !assert.HTTPErrorf(t, handler, method, url, values, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
@ -174,8 +387,19 @@ func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string,
|
||||
// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values) {
|
||||
if !assert.HTTPRedirect(t, handler, method, url, values) {
|
||||
func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {
|
||||
if !assert.HTTPRedirect(t, handler, method, url, values, msgAndArgs...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// HTTPRedirectf asserts that a specified handler returns a redirect status code.
|
||||
//
|
||||
// assert.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
//
|
||||
// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
|
||||
func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {
|
||||
if !assert.HTTPRedirectf(t, handler, method, url, values, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
@ -185,21 +409,41 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url strin
|
||||
// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values) {
|
||||
if !assert.HTTPSuccess(t, handler, method, url, values) {
|
||||
func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {
|
||||
if !assert.HTTPSuccess(t, handler, method, url, values, msgAndArgs...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// HTTPSuccessf asserts that a specified handler returns a success status code.
|
||||
//
|
||||
// assert.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {
|
||||
if !assert.HTTPSuccessf(t, handler, method, url, values, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// Implements asserts that an object is implemented by the specified interface.
|
||||
//
|
||||
// assert.Implements(t, (*MyInterface)(nil), new(MyObject), "MyObject")
|
||||
// assert.Implements(t, (*MyInterface)(nil), new(MyObject))
|
||||
func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) {
|
||||
if !assert.Implements(t, interfaceObject, object, msgAndArgs...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// Implementsf asserts that an object is implemented by the specified interface.
|
||||
//
|
||||
// assert.Implementsf(t, (*MyInterface, "error message %s", "formatted")(nil), new(MyObject))
|
||||
func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) {
|
||||
if !assert.Implementsf(t, interfaceObject, object, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// InDelta asserts that the two numerals are within delta of each other.
|
||||
//
|
||||
// assert.InDelta(t, math.Pi, (22 / 7.0), 0.01)
|
||||
@ -211,6 +455,20 @@ func InDelta(t TestingT, expected interface{}, actual interface{}, delta float64
|
||||
}
|
||||
}
|
||||
|
||||
// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
|
||||
func InDeltaMapValues(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
|
||||
if !assert.InDeltaMapValues(t, expected, actual, delta, msgAndArgs...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
|
||||
func InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {
|
||||
if !assert.InDeltaMapValuesf(t, expected, actual, delta, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// InDeltaSlice is the same as InDelta, except it compares two slices.
|
||||
func InDeltaSlice(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
|
||||
if !assert.InDeltaSlice(t, expected, actual, delta, msgAndArgs...) {
|
||||
@ -218,6 +476,24 @@ func InDeltaSlice(t TestingT, expected interface{}, actual interface{}, delta fl
|
||||
}
|
||||
}
|
||||
|
||||
// InDeltaSlicef is the same as InDelta, except it compares two slices.
|
||||
func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {
|
||||
if !assert.InDeltaSlicef(t, expected, actual, delta, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// InDeltaf asserts that the two numerals are within delta of each other.
|
||||
//
|
||||
// assert.InDeltaf(t, math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {
|
||||
if !assert.InDeltaf(t, expected, actual, delta, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// InEpsilon asserts that expected and actual have a relative error less than epsilon
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
@ -234,6 +510,22 @@ func InEpsilonSlice(t TestingT, expected interface{}, actual interface{}, epsilo
|
||||
}
|
||||
}
|
||||
|
||||
// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices.
|
||||
func InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) {
|
||||
if !assert.InEpsilonSlicef(t, expected, actual, epsilon, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// InEpsilonf asserts that expected and actual have a relative error less than epsilon
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) {
|
||||
if !assert.InEpsilonf(t, expected, actual, epsilon, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// IsType asserts that the specified objects are of the same type.
|
||||
func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) {
|
||||
if !assert.IsType(t, expectedType, object, msgAndArgs...) {
|
||||
@ -241,6 +533,13 @@ func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs
|
||||
}
|
||||
}
|
||||
|
||||
// IsTypef asserts that the specified objects are of the same type.
|
||||
func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) {
|
||||
if !assert.IsTypef(t, expectedType, object, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// JSONEq asserts that two JSON strings are equivalent.
|
||||
//
|
||||
// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
||||
@ -252,10 +551,21 @@ func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{
|
||||
}
|
||||
}
|
||||
|
||||
// JSONEqf asserts that two JSON strings are equivalent.
|
||||
//
|
||||
// assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) {
|
||||
if !assert.JSONEqf(t, expected, actual, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// Len asserts that the specified object has specific length.
|
||||
// Len also fails if the object has a type that len() not accept.
|
||||
//
|
||||
// assert.Len(t, mySlice, 3, "The size of slice is not 3")
|
||||
// assert.Len(t, mySlice, 3)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) {
|
||||
@ -264,9 +574,21 @@ func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{})
|
||||
}
|
||||
}
|
||||
|
||||
// Lenf asserts that the specified object has specific length.
|
||||
// Lenf also fails if the object has a type that len() not accept.
|
||||
//
|
||||
// assert.Lenf(t, mySlice, 3, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) {
|
||||
if !assert.Lenf(t, object, length, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// Nil asserts that the specified object is nil.
|
||||
//
|
||||
// assert.Nil(t, err, "err should be nothing")
|
||||
// assert.Nil(t, err)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) {
|
||||
@ -275,11 +597,22 @@ func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// Nilf asserts that the specified object is nil.
|
||||
//
|
||||
// assert.Nilf(t, err, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) {
|
||||
if !assert.Nilf(t, object, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// NoError asserts that a function returned no error (i.e. `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// if assert.NoError(t, err) {
|
||||
// assert.Equal(t, actualObj, expectedObj)
|
||||
// assert.Equal(t, expectedObj, actualObj)
|
||||
// }
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
@ -289,12 +622,26 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// NoErrorf asserts that a function returned no error (i.e. `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// if assert.NoErrorf(t, err, "error message %s", "formatted") {
|
||||
// assert.Equal(t, expectedObj, actualObj)
|
||||
// }
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NoErrorf(t TestingT, err error, msg string, args ...interface{}) {
|
||||
if !assert.NoErrorf(t, err, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the
|
||||
// specified substring or element.
|
||||
//
|
||||
// assert.NotContains(t, "Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'")
|
||||
// assert.NotContains(t, ["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'")
|
||||
// assert.NotContains(t, {"Hello": "World"}, "Earth", "But {'Hello': 'World'} does NOT contain 'Earth'")
|
||||
// assert.NotContains(t, "Hello World", "Earth")
|
||||
// assert.NotContains(t, ["Hello", "World"], "Earth")
|
||||
// assert.NotContains(t, {"Hello": "World"}, "Earth")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) {
|
||||
@ -303,6 +650,20 @@ func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...
|
||||
}
|
||||
}
|
||||
|
||||
// NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the
|
||||
// specified substring or element.
|
||||
//
|
||||
// assert.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted")
|
||||
// assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted")
|
||||
// assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) {
|
||||
if !assert.NotContainsf(t, s, contains, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
//
|
||||
@ -317,9 +678,23 @@ func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
//
|
||||
// if assert.NotEmptyf(t, obj, "error message %s", "formatted") {
|
||||
// assert.Equal(t, "two", obj[1])
|
||||
// }
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) {
|
||||
if !assert.NotEmptyf(t, object, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// NotEqual asserts that the specified values are NOT equal.
|
||||
//
|
||||
// assert.NotEqual(t, obj1, obj2, "two objects shouldn't be equal")
|
||||
// assert.NotEqual(t, obj1, obj2)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
//
|
||||
@ -331,9 +706,23 @@ func NotEqual(t TestingT, expected interface{}, actual interface{}, msgAndArgs .
|
||||
}
|
||||
}
|
||||
|
||||
// NotEqualf asserts that the specified values are NOT equal.
|
||||
//
|
||||
// assert.NotEqualf(t, obj1, obj2, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
//
|
||||
// Pointer variable equality is determined based on the equality of the
|
||||
// referenced values (as opposed to the memory addresses).
|
||||
func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {
|
||||
if !assert.NotEqualf(t, expected, actual, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// NotNil asserts that the specified object is not nil.
|
||||
//
|
||||
// assert.NotNil(t, err, "err should be something")
|
||||
// assert.NotNil(t, err)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) {
|
||||
@ -342,11 +731,20 @@ func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// NotNilf asserts that the specified object is not nil.
|
||||
//
|
||||
// assert.NotNilf(t, err, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) {
|
||||
if !assert.NotNilf(t, object, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.
|
||||
//
|
||||
// assert.NotPanics(t, func(){
|
||||
// RemainCalm()
|
||||
// }, "Calling RemainCalm() should NOT panic")
|
||||
// assert.NotPanics(t, func(){ RemainCalm() })
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) {
|
||||
@ -355,6 +753,17 @@ func NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic.
|
||||
//
|
||||
// assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NotPanicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) {
|
||||
if !assert.NotPanicsf(t, f, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// NotRegexp asserts that a specified regexp does not match a string.
|
||||
//
|
||||
// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting")
|
||||
@ -367,6 +776,42 @@ func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interf
|
||||
}
|
||||
}
|
||||
|
||||
// NotRegexpf asserts that a specified regexp does not match a string.
|
||||
//
|
||||
// assert.NotRegexpf(t, regexp.MustCompile("starts", "error message %s", "formatted"), "it's starting")
|
||||
// assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) {
|
||||
if !assert.NotRegexpf(t, rx, str, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// NotSubset asserts that the specified list(array, slice...) contains not all
|
||||
// elements given in the specified subset(array, slice...).
|
||||
//
|
||||
// assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) {
|
||||
if !assert.NotSubset(t, list, subset, msgAndArgs...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// NotSubsetf asserts that the specified list(array, slice...) contains not all
|
||||
// elements given in the specified subset(array, slice...).
|
||||
//
|
||||
// assert.NotSubsetf(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) {
|
||||
if !assert.NotSubsetf(t, list, subset, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// NotZero asserts that i is not the zero value for its type and returns the truth.
|
||||
func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) {
|
||||
if !assert.NotZero(t, i, msgAndArgs...) {
|
||||
@ -374,11 +819,16 @@ func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// NotZerof asserts that i is not the zero value for its type and returns the truth.
|
||||
func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) {
|
||||
if !assert.NotZerof(t, i, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// Panics asserts that the code inside the specified PanicTestFunc panics.
|
||||
//
|
||||
// assert.Panics(t, func(){
|
||||
// GoCrazy()
|
||||
// }, "Calling GoCrazy() should panic")
|
||||
// assert.Panics(t, func(){ GoCrazy() })
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) {
|
||||
@ -387,6 +837,41 @@ func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that
|
||||
// the recovered panic value equals the expected panic value.
|
||||
//
|
||||
// assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() })
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func PanicsWithValue(t TestingT, expected interface{}, f assert.PanicTestFunc, msgAndArgs ...interface{}) {
|
||||
if !assert.PanicsWithValue(t, expected, f, msgAndArgs...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that
|
||||
// the recovered panic value equals the expected panic value.
|
||||
//
|
||||
// assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func PanicsWithValuef(t TestingT, expected interface{}, f assert.PanicTestFunc, msg string, args ...interface{}) {
|
||||
if !assert.PanicsWithValuef(t, expected, f, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// Panicsf asserts that the code inside the specified PanicTestFunc panics.
|
||||
//
|
||||
// assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Panicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) {
|
||||
if !assert.Panicsf(t, f, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// Regexp asserts that a specified regexp matches a string.
|
||||
//
|
||||
// assert.Regexp(t, regexp.MustCompile("start"), "it's starting")
|
||||
@ -399,9 +884,45 @@ func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface
|
||||
}
|
||||
}
|
||||
|
||||
// Regexpf asserts that a specified regexp matches a string.
|
||||
//
|
||||
// assert.Regexpf(t, regexp.MustCompile("start", "error message %s", "formatted"), "it's starting")
|
||||
// assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) {
|
||||
if !assert.Regexpf(t, rx, str, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// Subset asserts that the specified list(array, slice...) contains all
|
||||
// elements given in the specified subset(array, slice...).
|
||||
//
|
||||
// assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) {
|
||||
if !assert.Subset(t, list, subset, msgAndArgs...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// Subsetf asserts that the specified list(array, slice...) contains all
|
||||
// elements given in the specified subset(array, slice...).
|
||||
//
|
||||
// assert.Subsetf(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) {
|
||||
if !assert.Subsetf(t, list, subset, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// True asserts that the specified value is true.
|
||||
//
|
||||
// assert.True(t, myBool, "myBool should be true")
|
||||
// assert.True(t, myBool)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func True(t TestingT, value bool, msgAndArgs ...interface{}) {
|
||||
@ -410,9 +931,20 @@ func True(t TestingT, value bool, msgAndArgs ...interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// Truef asserts that the specified value is true.
|
||||
//
|
||||
// assert.Truef(t, myBool, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func Truef(t TestingT, value bool, msg string, args ...interface{}) {
|
||||
if !assert.Truef(t, value, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// WithinDuration asserts that the two times are within duration delta of each other.
|
||||
//
|
||||
// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s")
|
||||
// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) {
|
||||
@ -421,9 +953,27 @@ func WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time
|
||||
}
|
||||
}
|
||||
|
||||
// WithinDurationf asserts that the two times are within duration delta of each other.
|
||||
//
|
||||
// assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) {
|
||||
if !assert.WithinDurationf(t, expected, actual, delta, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// Zero asserts that i is the zero value for its type and returns the truth.
|
||||
func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) {
|
||||
if !assert.Zero(t, i, msgAndArgs...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
// Zerof asserts that i is the zero value for its type and returns the truth.
|
||||
func Zerof(t TestingT, i interface{}, msg string, args ...interface{}) {
|
||||
if !assert.Zerof(t, i, msg, args...) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
524
src/vendor/github.com/stretchr/testify/require/require_forward.go
generated
vendored
@ -17,18 +17,67 @@ func (a *Assertions) Condition(comp assert.Comparison, msgAndArgs ...interface{}
|
||||
Condition(a.t, comp, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Conditionf uses a Comparison to assert a complex condition.
|
||||
func (a *Assertions) Conditionf(comp assert.Comparison, msg string, args ...interface{}) {
|
||||
Conditionf(a.t, comp, msg, args...)
|
||||
}
|
||||
|
||||
// Contains asserts that the specified string, list(array, slice...) or map contains the
|
||||
// specified substring or element.
|
||||
//
|
||||
// a.Contains("Hello World", "World", "But 'Hello World' does contain 'World'")
|
||||
// a.Contains(["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'")
|
||||
// a.Contains({"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'")
|
||||
// a.Contains("Hello World", "World")
|
||||
// a.Contains(["Hello", "World"], "World")
|
||||
// a.Contains({"Hello": "World"}, "Hello")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) {
|
||||
Contains(a.t, s, contains, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Containsf asserts that the specified string, list(array, slice...) or map contains the
|
||||
// specified substring or element.
|
||||
//
|
||||
// a.Containsf("Hello World", "World", "error message %s", "formatted")
|
||||
// a.Containsf(["Hello", "World"], "World", "error message %s", "formatted")
|
||||
// a.Containsf({"Hello": "World"}, "Hello", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Containsf(s interface{}, contains interface{}, msg string, args ...interface{}) {
|
||||
Containsf(a.t, s, contains, msg, args...)
|
||||
}
|
||||
|
||||
// DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
|
||||
func (a *Assertions) DirExists(path string, msgAndArgs ...interface{}) {
|
||||
DirExists(a.t, path, msgAndArgs...)
|
||||
}
|
||||
|
||||
// DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
|
||||
func (a *Assertions) DirExistsf(path string, msg string, args ...interface{}) {
|
||||
DirExistsf(a.t, path, msg, args...)
|
||||
}
|
||||
|
||||
// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified
|
||||
// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,
|
||||
// the number of appearances of each of them in both lists should match.
|
||||
//
|
||||
// a.ElementsMatch([1, 3, 2, 3], [1, 3, 3, 2]))
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) ElementsMatch(listA interface{}, listB interface{}, msgAndArgs ...interface{}) {
|
||||
ElementsMatch(a.t, listA, listB, msgAndArgs...)
|
||||
}
|
||||
|
||||
// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified
|
||||
// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,
|
||||
// the number of appearances of each of them in both lists should match.
|
||||
//
|
||||
// a.ElementsMatchf([1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted"))
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg string, args ...interface{}) {
|
||||
ElementsMatchf(a.t, listA, listB, msg, args...)
|
||||
}
|
||||
|
||||
// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
//
|
||||
@ -39,14 +88,25 @@ func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) {
|
||||
Empty(a.t, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
//
|
||||
// a.Emptyf(obj, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) {
|
||||
Emptyf(a.t, object, msg, args...)
|
||||
}
|
||||
|
||||
// Equal asserts that two objects are equal.
|
||||
//
|
||||
// a.Equal(123, 123, "123 and 123 should be equal")
|
||||
// a.Equal(123, 123)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
//
|
||||
// Pointer variable equality is determined based on the equality of the
|
||||
// referenced values (as opposed to the memory addresses).
|
||||
// referenced values (as opposed to the memory addresses). Function equality
|
||||
// cannot be determined and will always fail.
|
||||
func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
|
||||
Equal(a.t, expected, actual, msgAndArgs...)
|
||||
}
|
||||
@ -55,28 +115,62 @@ func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs
|
||||
// and that it is equal to the provided error.
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// a.EqualError(err, expectedErrorString, "An error was expected")
|
||||
// a.EqualError(err, expectedErrorString)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) {
|
||||
EqualError(a.t, theError, errString, msgAndArgs...)
|
||||
}
|
||||
|
||||
// EqualErrorf asserts that a function returned an error (i.e. not `nil`)
|
||||
// and that it is equal to the provided error.
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// a.EqualErrorf(err, expectedErrorString, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) EqualErrorf(theError error, errString string, msg string, args ...interface{}) {
|
||||
EqualErrorf(a.t, theError, errString, msg, args...)
|
||||
}
|
||||
|
||||
// EqualValues asserts that two objects are equal or convertable to the same types
|
||||
// and equal.
|
||||
//
|
||||
// a.EqualValues(uint32(123), int32(123), "123 and 123 should be equal")
|
||||
// a.EqualValues(uint32(123), int32(123))
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
|
||||
EqualValues(a.t, expected, actual, msgAndArgs...)
|
||||
}
|
||||
|
||||
// EqualValuesf asserts that two objects are equal or convertable to the same types
|
||||
// and equal.
|
||||
//
|
||||
// a.EqualValuesf(uint32(123, "error message %s", "formatted"), int32(123))
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) {
|
||||
EqualValuesf(a.t, expected, actual, msg, args...)
|
||||
}
|
||||
|
||||
// Equalf asserts that two objects are equal.
|
||||
//
|
||||
// a.Equalf(123, 123, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
//
|
||||
// Pointer variable equality is determined based on the equality of the
|
||||
// referenced values (as opposed to the memory addresses). Function equality
|
||||
// cannot be determined and will always fail.
|
||||
func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string, args ...interface{}) {
|
||||
Equalf(a.t, expected, actual, msg, args...)
|
||||
}
|
||||
|
||||
// Error asserts that a function returned an error (i.e. not `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// if a.Error(err, "An error was expected") {
|
||||
// assert.Equal(t, err, expectedError)
|
||||
// if a.Error(err) {
|
||||
// assert.Equal(t, expectedError, err)
|
||||
// }
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
@ -84,15 +178,36 @@ func (a *Assertions) Error(err error, msgAndArgs ...interface{}) {
|
||||
Error(a.t, err, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Exactly asserts that two objects are equal is value and type.
|
||||
// Errorf asserts that a function returned an error (i.e. not `nil`).
|
||||
//
|
||||
// a.Exactly(int32(123), int64(123), "123 and 123 should NOT be equal")
|
||||
// actualObj, err := SomeFunction()
|
||||
// if a.Errorf(err, "error message %s", "formatted") {
|
||||
// assert.Equal(t, expectedErrorf, err)
|
||||
// }
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Errorf(err error, msg string, args ...interface{}) {
|
||||
Errorf(a.t, err, msg, args...)
|
||||
}
|
||||
|
||||
// Exactly asserts that two objects are equal in value and type.
|
||||
//
|
||||
// a.Exactly(int32(123), int64(123))
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
|
||||
Exactly(a.t, expected, actual, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Exactlyf asserts that two objects are equal in value and type.
|
||||
//
|
||||
// a.Exactlyf(int32(123, "error message %s", "formatted"), int64(123))
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Exactlyf(expected interface{}, actual interface{}, msg string, args ...interface{}) {
|
||||
Exactlyf(a.t, expected, actual, msg, args...)
|
||||
}
|
||||
|
||||
// Fail reports a failure through
|
||||
func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) {
|
||||
Fail(a.t, failureMessage, msgAndArgs...)
|
||||
@ -103,23 +218,62 @@ func (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) {
|
||||
FailNow(a.t, failureMessage, msgAndArgs...)
|
||||
}
|
||||
|
||||
// FailNowf fails test
|
||||
func (a *Assertions) FailNowf(failureMessage string, msg string, args ...interface{}) {
|
||||
FailNowf(a.t, failureMessage, msg, args...)
|
||||
}
|
||||
|
||||
// Failf reports a failure through
|
||||
func (a *Assertions) Failf(failureMessage string, msg string, args ...interface{}) {
|
||||
Failf(a.t, failureMessage, msg, args...)
|
||||
}
|
||||
|
||||
// False asserts that the specified value is false.
|
||||
//
|
||||
// a.False(myBool, "myBool should be false")
|
||||
// a.False(myBool)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) False(value bool, msgAndArgs ...interface{}) {
|
||||
False(a.t, value, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Falsef asserts that the specified value is false.
|
||||
//
|
||||
// a.Falsef(myBool, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Falsef(value bool, msg string, args ...interface{}) {
|
||||
Falsef(a.t, value, msg, args...)
|
||||
}
|
||||
|
||||
// FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
|
||||
func (a *Assertions) FileExists(path string, msgAndArgs ...interface{}) {
|
||||
FileExists(a.t, path, msgAndArgs...)
|
||||
}
|
||||
|
||||
// FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
|
||||
func (a *Assertions) FileExistsf(path string, msg string, args ...interface{}) {
|
||||
FileExistsf(a.t, path, msg, args...)
|
||||
}
|
||||
|
||||
// HTTPBodyContains asserts that a specified handler returns a
|
||||
// body that contains a string.
|
||||
//
|
||||
// a.HTTPBodyContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) {
|
||||
HTTPBodyContains(a.t, handler, method, url, values, str)
|
||||
func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) {
|
||||
HTTPBodyContains(a.t, handler, method, url, values, str, msgAndArgs...)
|
||||
}
|
||||
|
||||
// HTTPBodyContainsf asserts that a specified handler returns a
|
||||
// body that contains a string.
|
||||
//
|
||||
// a.HTTPBodyContainsf(myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) {
|
||||
HTTPBodyContainsf(a.t, handler, method, url, values, str, msg, args...)
|
||||
}
|
||||
|
||||
// HTTPBodyNotContains asserts that a specified handler returns a
|
||||
@ -128,8 +282,18 @@ func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, u
|
||||
// a.HTTPBodyNotContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) {
|
||||
HTTPBodyNotContains(a.t, handler, method, url, values, str)
|
||||
func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) {
|
||||
HTTPBodyNotContains(a.t, handler, method, url, values, str, msgAndArgs...)
|
||||
}
|
||||
|
||||
// HTTPBodyNotContainsf asserts that a specified handler returns a
|
||||
// body that does not contain a string.
|
||||
//
|
||||
// a.HTTPBodyNotContainsf(myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) {
|
||||
HTTPBodyNotContainsf(a.t, handler, method, url, values, str, msg, args...)
|
||||
}
|
||||
|
||||
// HTTPError asserts that a specified handler returns an error status code.
|
||||
@ -137,8 +301,17 @@ func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string
|
||||
// a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values) {
|
||||
HTTPError(a.t, handler, method, url, values)
|
||||
func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {
|
||||
HTTPError(a.t, handler, method, url, values, msgAndArgs...)
|
||||
}
|
||||
|
||||
// HTTPErrorf asserts that a specified handler returns an error status code.
|
||||
//
|
||||
// a.HTTPErrorf(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
//
|
||||
// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
|
||||
func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {
|
||||
HTTPErrorf(a.t, handler, method, url, values, msg, args...)
|
||||
}
|
||||
|
||||
// HTTPRedirect asserts that a specified handler returns a redirect status code.
|
||||
@ -146,8 +319,17 @@ func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url stri
|
||||
// a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values) {
|
||||
HTTPRedirect(a.t, handler, method, url, values)
|
||||
func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {
|
||||
HTTPRedirect(a.t, handler, method, url, values, msgAndArgs...)
|
||||
}
|
||||
|
||||
// HTTPRedirectf asserts that a specified handler returns a redirect status code.
|
||||
//
|
||||
// a.HTTPRedirectf(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
//
|
||||
// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
|
||||
func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {
|
||||
HTTPRedirectf(a.t, handler, method, url, values, msg, args...)
|
||||
}
|
||||
|
||||
// HTTPSuccess asserts that a specified handler returns a success status code.
|
||||
@ -155,17 +337,33 @@ func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url s
|
||||
// a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values) {
|
||||
HTTPSuccess(a.t, handler, method, url, values)
|
||||
func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {
|
||||
HTTPSuccess(a.t, handler, method, url, values, msgAndArgs...)
|
||||
}
|
||||
|
||||
// HTTPSuccessf asserts that a specified handler returns a success status code.
|
||||
//
|
||||
// a.HTTPSuccessf(myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {
|
||||
HTTPSuccessf(a.t, handler, method, url, values, msg, args...)
|
||||
}
|
||||
|
||||
// Implements asserts that an object is implemented by the specified interface.
|
||||
//
|
||||
// a.Implements((*MyInterface)(nil), new(MyObject), "MyObject")
|
||||
// a.Implements((*MyInterface)(nil), new(MyObject))
|
||||
func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) {
|
||||
Implements(a.t, interfaceObject, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Implementsf asserts that an object is implemented by the specified interface.
|
||||
//
|
||||
// a.Implementsf((*MyInterface, "error message %s", "formatted")(nil), new(MyObject))
|
||||
func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) {
|
||||
Implementsf(a.t, interfaceObject, object, msg, args...)
|
||||
}
|
||||
|
||||
// InDelta asserts that the two numerals are within delta of each other.
|
||||
//
|
||||
// a.InDelta(math.Pi, (22 / 7.0), 0.01)
|
||||
@ -175,11 +373,35 @@ func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta flo
|
||||
InDelta(a.t, expected, actual, delta, msgAndArgs...)
|
||||
}
|
||||
|
||||
// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
|
||||
func (a *Assertions) InDeltaMapValues(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
|
||||
InDeltaMapValues(a.t, expected, actual, delta, msgAndArgs...)
|
||||
}
|
||||
|
||||
// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
|
||||
func (a *Assertions) InDeltaMapValuesf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {
|
||||
InDeltaMapValuesf(a.t, expected, actual, delta, msg, args...)
|
||||
}
|
||||
|
||||
// InDeltaSlice is the same as InDelta, except it compares two slices.
|
||||
func (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
|
||||
InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...)
|
||||
}
|
||||
|
||||
// InDeltaSlicef is the same as InDelta, except it compares two slices.
|
||||
func (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {
|
||||
InDeltaSlicef(a.t, expected, actual, delta, msg, args...)
|
||||
}
|
||||
|
||||
// InDeltaf asserts that the two numerals are within delta of each other.
|
||||
//
|
||||
// a.InDeltaf(math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) InDeltaf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {
|
||||
InDeltaf(a.t, expected, actual, delta, msg, args...)
|
||||
}
|
||||
|
||||
// InEpsilon asserts that expected and actual have a relative error less than epsilon
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
@ -192,11 +414,28 @@ func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, ep
|
||||
InEpsilonSlice(a.t, expected, actual, epsilon, msgAndArgs...)
|
||||
}
|
||||
|
||||
// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices.
|
||||
func (a *Assertions) InEpsilonSlicef(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) {
|
||||
InEpsilonSlicef(a.t, expected, actual, epsilon, msg, args...)
|
||||
}
|
||||
|
||||
// InEpsilonf asserts that expected and actual have a relative error less than epsilon
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) InEpsilonf(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) {
|
||||
InEpsilonf(a.t, expected, actual, epsilon, msg, args...)
|
||||
}
|
||||
|
||||
// IsType asserts that the specified objects are of the same type.
|
||||
func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) {
|
||||
IsType(a.t, expectedType, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// IsTypef asserts that the specified objects are of the same type.
|
||||
func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg string, args ...interface{}) {
|
||||
IsTypef(a.t, expectedType, object, msg, args...)
|
||||
}
|
||||
|
||||
// JSONEq asserts that two JSON strings are equivalent.
|
||||
//
|
||||
// a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
||||
@ -206,30 +445,58 @@ func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interf
|
||||
JSONEq(a.t, expected, actual, msgAndArgs...)
|
||||
}
|
||||
|
||||
// JSONEqf asserts that two JSON strings are equivalent.
|
||||
//
|
||||
// a.JSONEqf(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ...interface{}) {
|
||||
JSONEqf(a.t, expected, actual, msg, args...)
|
||||
}
|
||||
|
||||
// Len asserts that the specified object has specific length.
|
||||
// Len also fails if the object has a type that len() not accept.
|
||||
//
|
||||
// a.Len(mySlice, 3, "The size of slice is not 3")
|
||||
// a.Len(mySlice, 3)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) {
|
||||
Len(a.t, object, length, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Lenf asserts that the specified object has specific length.
|
||||
// Lenf also fails if the object has a type that len() not accept.
|
||||
//
|
||||
// a.Lenf(mySlice, 3, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...interface{}) {
|
||||
Lenf(a.t, object, length, msg, args...)
|
||||
}
|
||||
|
||||
// Nil asserts that the specified object is nil.
|
||||
//
|
||||
// a.Nil(err, "err should be nothing")
|
||||
// a.Nil(err)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) {
|
||||
Nil(a.t, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Nilf asserts that the specified object is nil.
|
||||
//
|
||||
// a.Nilf(err, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) {
|
||||
Nilf(a.t, object, msg, args...)
|
||||
}
|
||||
|
||||
// NoError asserts that a function returned no error (i.e. `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// if a.NoError(err) {
|
||||
// assert.Equal(t, actualObj, expectedObj)
|
||||
// assert.Equal(t, expectedObj, actualObj)
|
||||
// }
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
@ -237,18 +504,42 @@ func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) {
|
||||
NoError(a.t, err, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NoErrorf asserts that a function returned no error (i.e. `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// if a.NoErrorf(err, "error message %s", "formatted") {
|
||||
// assert.Equal(t, expectedObj, actualObj)
|
||||
// }
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) {
|
||||
NoErrorf(a.t, err, msg, args...)
|
||||
}
|
||||
|
||||
// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the
|
||||
// specified substring or element.
|
||||
//
|
||||
// a.NotContains("Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'")
|
||||
// a.NotContains(["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'")
|
||||
// a.NotContains({"Hello": "World"}, "Earth", "But {'Hello': 'World'} does NOT contain 'Earth'")
|
||||
// a.NotContains("Hello World", "Earth")
|
||||
// a.NotContains(["Hello", "World"], "Earth")
|
||||
// a.NotContains({"Hello": "World"}, "Earth")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) {
|
||||
NotContains(a.t, s, contains, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the
|
||||
// specified substring or element.
|
||||
//
|
||||
// a.NotContainsf("Hello World", "Earth", "error message %s", "formatted")
|
||||
// a.NotContainsf(["Hello", "World"], "Earth", "error message %s", "formatted")
|
||||
// a.NotContainsf({"Hello": "World"}, "Earth", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg string, args ...interface{}) {
|
||||
NotContainsf(a.t, s, contains, msg, args...)
|
||||
}
|
||||
|
||||
// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
//
|
||||
@ -261,9 +552,21 @@ func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) {
|
||||
NotEmpty(a.t, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
//
|
||||
// if a.NotEmptyf(obj, "error message %s", "formatted") {
|
||||
// assert.Equal(t, "two", obj[1])
|
||||
// }
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface{}) {
|
||||
NotEmptyf(a.t, object, msg, args...)
|
||||
}
|
||||
|
||||
// NotEqual asserts that the specified values are NOT equal.
|
||||
//
|
||||
// a.NotEqual(obj1, obj2, "two objects shouldn't be equal")
|
||||
// a.NotEqual(obj1, obj2)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
//
|
||||
@ -273,26 +576,54 @@ func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndAr
|
||||
NotEqual(a.t, expected, actual, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotEqualf asserts that the specified values are NOT equal.
|
||||
//
|
||||
// a.NotEqualf(obj1, obj2, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
//
|
||||
// Pointer variable equality is determined based on the equality of the
|
||||
// referenced values (as opposed to the memory addresses).
|
||||
func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg string, args ...interface{}) {
|
||||
NotEqualf(a.t, expected, actual, msg, args...)
|
||||
}
|
||||
|
||||
// NotNil asserts that the specified object is not nil.
|
||||
//
|
||||
// a.NotNil(err, "err should be something")
|
||||
// a.NotNil(err)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) {
|
||||
NotNil(a.t, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotNilf asserts that the specified object is not nil.
|
||||
//
|
||||
// a.NotNilf(err, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{}) {
|
||||
NotNilf(a.t, object, msg, args...)
|
||||
}
|
||||
|
||||
// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.
|
||||
//
|
||||
// a.NotPanics(func(){
|
||||
// RemainCalm()
|
||||
// }, "Calling RemainCalm() should NOT panic")
|
||||
// a.NotPanics(func(){ RemainCalm() })
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NotPanics(f assert.PanicTestFunc, msgAndArgs ...interface{}) {
|
||||
NotPanics(a.t, f, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic.
|
||||
//
|
||||
// a.NotPanicsf(func(){ RemainCalm() }, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NotPanicsf(f assert.PanicTestFunc, msg string, args ...interface{}) {
|
||||
NotPanicsf(a.t, f, msg, args...)
|
||||
}
|
||||
|
||||
// NotRegexp asserts that a specified regexp does not match a string.
|
||||
//
|
||||
// a.NotRegexp(regexp.MustCompile("starts"), "it's starting")
|
||||
@ -303,22 +634,84 @@ func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...in
|
||||
NotRegexp(a.t, rx, str, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotRegexpf asserts that a specified regexp does not match a string.
|
||||
//
|
||||
// a.NotRegexpf(regexp.MustCompile("starts", "error message %s", "formatted"), "it's starting")
|
||||
// a.NotRegexpf("^start", "it's not starting", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, args ...interface{}) {
|
||||
NotRegexpf(a.t, rx, str, msg, args...)
|
||||
}
|
||||
|
||||
// NotSubset asserts that the specified list(array, slice...) contains not all
|
||||
// elements given in the specified subset(array, slice...).
|
||||
//
|
||||
// a.NotSubset([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) {
|
||||
NotSubset(a.t, list, subset, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotSubsetf asserts that the specified list(array, slice...) contains not all
|
||||
// elements given in the specified subset(array, slice...).
|
||||
//
|
||||
// a.NotSubsetf([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) {
|
||||
NotSubsetf(a.t, list, subset, msg, args...)
|
||||
}
|
||||
|
||||
// NotZero asserts that i is not the zero value for its type and returns the truth.
|
||||
func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) {
|
||||
NotZero(a.t, i, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotZerof asserts that i is not the zero value for its type and returns the truth.
|
||||
func (a *Assertions) NotZerof(i interface{}, msg string, args ...interface{}) {
|
||||
NotZerof(a.t, i, msg, args...)
|
||||
}
|
||||
|
||||
// Panics asserts that the code inside the specified PanicTestFunc panics.
|
||||
//
|
||||
// a.Panics(func(){
|
||||
// GoCrazy()
|
||||
// }, "Calling GoCrazy() should panic")
|
||||
// a.Panics(func(){ GoCrazy() })
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Panics(f assert.PanicTestFunc, msgAndArgs ...interface{}) {
|
||||
Panics(a.t, f, msgAndArgs...)
|
||||
}
|
||||
|
||||
// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that
|
||||
// the recovered panic value equals the expected panic value.
|
||||
//
|
||||
// a.PanicsWithValue("crazy error", func(){ GoCrazy() })
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) PanicsWithValue(expected interface{}, f assert.PanicTestFunc, msgAndArgs ...interface{}) {
|
||||
PanicsWithValue(a.t, expected, f, msgAndArgs...)
|
||||
}
|
||||
|
||||
// PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that
|
||||
// the recovered panic value equals the expected panic value.
|
||||
//
|
||||
// a.PanicsWithValuef("crazy error", func(){ GoCrazy() }, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) PanicsWithValuef(expected interface{}, f assert.PanicTestFunc, msg string, args ...interface{}) {
|
||||
PanicsWithValuef(a.t, expected, f, msg, args...)
|
||||
}
|
||||
|
||||
// Panicsf asserts that the code inside the specified PanicTestFunc panics.
|
||||
//
|
||||
// a.Panicsf(func(){ GoCrazy() }, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Panicsf(f assert.PanicTestFunc, msg string, args ...interface{}) {
|
||||
Panicsf(a.t, f, msg, args...)
|
||||
}
|
||||
|
||||
// Regexp asserts that a specified regexp matches a string.
|
||||
//
|
||||
// a.Regexp(regexp.MustCompile("start"), "it's starting")
|
||||
@ -329,25 +722,78 @@ func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...inter
|
||||
Regexp(a.t, rx, str, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Regexpf asserts that a specified regexp matches a string.
|
||||
//
|
||||
// a.Regexpf(regexp.MustCompile("start", "error message %s", "formatted"), "it's starting")
|
||||
// a.Regexpf("start...$", "it's not starting", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args ...interface{}) {
|
||||
Regexpf(a.t, rx, str, msg, args...)
|
||||
}
|
||||
|
||||
// Subset asserts that the specified list(array, slice...) contains all
|
||||
// elements given in the specified subset(array, slice...).
|
||||
//
|
||||
// a.Subset([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) {
|
||||
Subset(a.t, list, subset, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Subsetf asserts that the specified list(array, slice...) contains all
|
||||
// elements given in the specified subset(array, slice...).
|
||||
//
|
||||
// a.Subsetf([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) {
|
||||
Subsetf(a.t, list, subset, msg, args...)
|
||||
}
|
||||
|
||||
// True asserts that the specified value is true.
|
||||
//
|
||||
// a.True(myBool, "myBool should be true")
|
||||
// a.True(myBool)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) True(value bool, msgAndArgs ...interface{}) {
|
||||
True(a.t, value, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Truef asserts that the specified value is true.
|
||||
//
|
||||
// a.Truef(myBool, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) Truef(value bool, msg string, args ...interface{}) {
|
||||
Truef(a.t, value, msg, args...)
|
||||
}
|
||||
|
||||
// WithinDuration asserts that the two times are within duration delta of each other.
|
||||
//
|
||||
// a.WithinDuration(time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s")
|
||||
// a.WithinDuration(time.Now(), time.Now(), 10*time.Second)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) {
|
||||
WithinDuration(a.t, expected, actual, delta, msgAndArgs...)
|
||||
}
|
||||
|
||||
// WithinDurationf asserts that the two times are within duration delta of each other.
|
||||
//
|
||||
// a.WithinDurationf(time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) {
|
||||
WithinDurationf(a.t, expected, actual, delta, msg, args...)
|
||||
}
|
||||
|
||||
// Zero asserts that i is the zero value for its type and returns the truth.
|
||||
func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) {
|
||||
Zero(a.t, i, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Zerof asserts that i is the zero value for its type and returns the truth.
|
||||
func (a *Assertions) Zerof(i interface{}, msg string, args ...interface{}) {
|
||||
Zerof(a.t, i, msg, args...)
|
||||
}
|
||||
|
2
src/vendor/github.com/stretchr/testify/require/requirements.go
generated
vendored
@ -6,4 +6,4 @@ type TestingT interface {
|
||||
FailNow()
|
||||
}
|
||||
|
||||
//go:generate go run ../_codegen/main.go -output-package=require -template=require.go.tmpl
|
||||
//go:generate go run ../_codegen/main.go -output-package=require -template=require.go.tmpl -include-format-funcs
|
||||
|
21
src/vendor/github.com/stretchr/testify/suite/suite.go
generated
vendored
@ -12,6 +12,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var allTestsFilter = func(_, _ string) (bool, error) { return true, nil }
|
||||
var matchMethod = flag.String("testify.m", "", "regular expression to select tests of the testify suite to run")
|
||||
|
||||
// Suite is a basic testing suite with methods for storing and
|
||||
@ -104,10 +105,20 @@ func Run(t *testing.T, suite TestingSuite) {
|
||||
tests = append(tests, test)
|
||||
}
|
||||
}
|
||||
runTests(t, tests)
|
||||
}
|
||||
|
||||
if !testing.RunTests(func(_, _ string) (bool, error) { return true, nil },
|
||||
tests) {
|
||||
t.Fail()
|
||||
func runTests(t testing.TB, tests []testing.InternalTest) {
|
||||
r, ok := t.(runner)
|
||||
if !ok { // backwards compatibility with Go 1.6 and below
|
||||
if !testing.RunTests(allTestsFilter, tests) {
|
||||
t.Fail()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
r.Run(test.Name, test.F)
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,3 +130,7 @@ func methodFilter(name string) (bool, error) {
|
||||
}
|
||||
return regexp.MatchString(*matchMethod, name)
|
||||
}
|
||||
|
||||
type runner interface {
|
||||
Run(name string, f func(t *testing.T)) bool
|
||||
}
|
||||
|
18
src/vendor/github.com/stretchr/testify/suite/suite_test.go
generated
vendored
@ -8,6 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// SuiteRequireTwice is intended to test the usage of suite.Require in two
|
||||
@ -19,7 +20,7 @@ type SuiteRequireTwice struct{ Suite }
|
||||
// A regression would result on these tests panicking rather than failing.
|
||||
func TestSuiteRequireTwice(t *testing.T) {
|
||||
ok := testing.RunTests(
|
||||
func(_, _ string) (bool, error) { return true, nil },
|
||||
allTestsFilter,
|
||||
[]testing.InternalTest{{
|
||||
Name: "TestSuiteRequireTwice",
|
||||
F: func(t *testing.T) {
|
||||
@ -267,16 +268,19 @@ func (sc *StdoutCapture) StopCapture() (string, error) {
|
||||
}
|
||||
|
||||
func TestSuiteLogging(t *testing.T) {
|
||||
testT := testing.T{}
|
||||
|
||||
suiteLoggingTester := new(SuiteLoggingTester)
|
||||
|
||||
capture := StdoutCapture{}
|
||||
internalTest := testing.InternalTest{
|
||||
Name: "SomeTest",
|
||||
F: func(subT *testing.T) {
|
||||
Run(subT, suiteLoggingTester)
|
||||
},
|
||||
}
|
||||
capture.StartCapture()
|
||||
Run(&testT, suiteLoggingTester)
|
||||
testing.RunTests(allTestsFilter, []testing.InternalTest{internalTest})
|
||||
output, err := capture.StopCapture()
|
||||
|
||||
assert.Nil(t, err, "Got an error trying to capture stdout!")
|
||||
require.NoError(t, err, "Got an error trying to capture stdout and stderr!")
|
||||
require.NotEmpty(t, output, "output content must not be empty")
|
||||
|
||||
// Failed tests' output is always printed
|
||||
assert.Contains(t, output, "TESTLOGFAIL")
|
||||
|
22
src/vendor/gopkg.in/stretchr/testify.v1/LICENCE.txt
generated
vendored
@ -1,22 +0,0 @@
|
||||
Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell
|
||||
|
||||
Please consider promoting this project if you find it useful.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
|
||||
OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
src/vendor/gopkg.in/stretchr/testify.v1/LICENSE
generated
vendored
@ -1,22 +0,0 @@
|
||||
Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell
|
||||
|
||||
Please consider promoting this project if you find it useful.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
|
||||
OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
332
src/vendor/gopkg.in/stretchr/testify.v1/README.md
generated
vendored
@ -1,332 +0,0 @@
|
||||
Testify - Thou Shalt Write Tests
|
||||
================================
|
||||
|
||||
[![Build Status](https://travis-ci.org/stretchr/testify.svg)](https://travis-ci.org/stretchr/testify) [![Go Report Card](https://goreportcard.com/badge/github.com/stretchr/testify)](https://goreportcard.com/report/github.com/stretchr/testify) [![GoDoc](https://godoc.org/github.com/stretchr/testify?status.svg)](https://godoc.org/github.com/stretchr/testify)
|
||||
|
||||
Go code (golang) set of packages that provide many tools for testifying that your code will behave as you intend.
|
||||
|
||||
Features include:
|
||||
|
||||
* [Easy assertions](#assert-package)
|
||||
* [Mocking](#mock-package)
|
||||
* [HTTP response trapping](#http-package)
|
||||
* [Testing suite interfaces and functions](#suite-package)
|
||||
|
||||
Get started:
|
||||
|
||||
* Install testify with [one line of code](#installation), or [update it with another](#staying-up-to-date)
|
||||
* For an introduction to writing test code in Go, see http://golang.org/doc/code.html#Testing
|
||||
* Check out the API Documentation http://godoc.org/github.com/stretchr/testify
|
||||
* To make your testing life easier, check out our other project, [gorc](http://github.com/stretchr/gorc)
|
||||
* A little about [Test-Driven Development (TDD)](http://en.wikipedia.org/wiki/Test-driven_development)
|
||||
|
||||
|
||||
|
||||
[`assert`](http://godoc.org/github.com/stretchr/testify/assert "API documentation") package
|
||||
-------------------------------------------------------------------------------------------
|
||||
|
||||
The `assert` package provides some helpful methods that allow you to write better test code in Go.
|
||||
|
||||
* Prints friendly, easy to read failure descriptions
|
||||
* Allows for very readable code
|
||||
* Optionally annotate each assertion with a message
|
||||
|
||||
See it in action:
|
||||
|
||||
```go
|
||||
package yours
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSomething(t *testing.T) {
|
||||
|
||||
// assert equality
|
||||
assert.Equal(t, 123, 123, "they should be equal")
|
||||
|
||||
// assert inequality
|
||||
assert.NotEqual(t, 123, 456, "they should not be equal")
|
||||
|
||||
// assert for nil (good for errors)
|
||||
assert.Nil(t, object)
|
||||
|
||||
// assert for not nil (good when you expect something)
|
||||
if assert.NotNil(t, object) {
|
||||
|
||||
// now we know that object isn't nil, we are safe to make
|
||||
// further assertions without causing any errors
|
||||
assert.Equal(t, "Something", object.Value)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
* Every assert func takes the `testing.T` object as the first argument. This is how it writes the errors out through the normal `go test` capabilities.
|
||||
* Every assert func returns a bool indicating whether the assertion was successful or not, this is useful for if you want to go on making further assertions under certain conditions.
|
||||
|
||||
if you assert many times, use the below:
|
||||
|
||||
```go
|
||||
package yours
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSomething(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
// assert equality
|
||||
assert.Equal(123, 123, "they should be equal")
|
||||
|
||||
// assert inequality
|
||||
assert.NotEqual(123, 456, "they should not be equal")
|
||||
|
||||
// assert for nil (good for errors)
|
||||
assert.Nil(object)
|
||||
|
||||
// assert for not nil (good when you expect something)
|
||||
if assert.NotNil(object) {
|
||||
|
||||
// now we know that object isn't nil, we are safe to make
|
||||
// further assertions without causing any errors
|
||||
assert.Equal("Something", object.Value)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[`require`](http://godoc.org/github.com/stretchr/testify/require "API documentation") package
|
||||
---------------------------------------------------------------------------------------------
|
||||
|
||||
The `require` package provides same global functions as the `assert` package, but instead of returning a boolean result they terminate current test.
|
||||
|
||||
See [t.FailNow](http://golang.org/pkg/testing/#T.FailNow) for details.
|
||||
|
||||
|
||||
[`http`](http://godoc.org/github.com/stretchr/testify/http "API documentation") package
|
||||
---------------------------------------------------------------------------------------
|
||||
|
||||
The `http` package contains test objects useful for testing code that relies on the `net/http` package. Check out the [(deprecated) API documentation for the `http` package](http://godoc.org/github.com/stretchr/testify/http).
|
||||
|
||||
We recommend you use [httptest](http://golang.org/pkg/net/http/httptest) instead.
|
||||
|
||||
[`mock`](http://godoc.org/github.com/stretchr/testify/mock "API documentation") package
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
The `mock` package provides a mechanism for easily writing mock objects that can be used in place of real objects when writing test code.
|
||||
|
||||
An example test function that tests a piece of code that relies on an external object `testObj`, can setup expectations (testify) and assert that they indeed happened:
|
||||
|
||||
```go
|
||||
package yours
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
/*
|
||||
Test objects
|
||||
*/
|
||||
|
||||
// MyMockedObject is a mocked object that implements an interface
|
||||
// that describes an object that the code I am testing relies on.
|
||||
type MyMockedObject struct{
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// DoSomething is a method on MyMockedObject that implements some interface
|
||||
// and just records the activity, and returns what the Mock object tells it to.
|
||||
//
|
||||
// In the real object, this method would do something useful, but since this
|
||||
// is a mocked object - we're just going to stub it out.
|
||||
//
|
||||
// NOTE: This method is not being tested here, code that uses this object is.
|
||||
func (m *MyMockedObject) DoSomething(number int) (bool, error) {
|
||||
|
||||
args := m.Called(number)
|
||||
return args.Bool(0), args.Error(1)
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Actual test functions
|
||||
*/
|
||||
|
||||
// TestSomething is an example of how to use our test object to
|
||||
// make assertions about some target code we are testing.
|
||||
func TestSomething(t *testing.T) {
|
||||
|
||||
// create an instance of our test object
|
||||
testObj := new(MyMockedObject)
|
||||
|
||||
// setup expectations
|
||||
testObj.On("DoSomething", 123).Return(true, nil)
|
||||
|
||||
// call the code we are testing
|
||||
targetFuncThatDoesSomethingWithObj(testObj)
|
||||
|
||||
// assert that the expectations were met
|
||||
testObj.AssertExpectations(t)
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
For more information on how to write mock code, check out the [API documentation for the `mock` package](http://godoc.org/github.com/stretchr/testify/mock).
|
||||
|
||||
You can use the [mockery tool](http://github.com/vektra/mockery) to autogenerate the mock code against an interface as well, making using mocks much quicker.
|
||||
|
||||
[`suite`](http://godoc.org/github.com/stretchr/testify/suite "API documentation") package
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
The `suite` package provides functionality that you might be used to from more common object oriented languages. With it, you can build a testing suite as a struct, build setup/teardown methods and testing methods on your struct, and run them with 'go test' as per normal.
|
||||
|
||||
An example suite is shown below:
|
||||
|
||||
```go
|
||||
// Basic imports
|
||||
import (
|
||||
"testing"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
// Define the suite, and absorb the built-in basic suite
|
||||
// functionality from testify - including a T() method which
|
||||
// returns the current testing context
|
||||
type ExampleTestSuite struct {
|
||||
suite.Suite
|
||||
VariableThatShouldStartAtFive int
|
||||
}
|
||||
|
||||
// Make sure that VariableThatShouldStartAtFive is set to five
|
||||
// before each test
|
||||
func (suite *ExampleTestSuite) SetupTest() {
|
||||
suite.VariableThatShouldStartAtFive = 5
|
||||
}
|
||||
|
||||
// All methods that begin with "Test" are run as tests within a
|
||||
// suite.
|
||||
func (suite *ExampleTestSuite) TestExample() {
|
||||
assert.Equal(suite.T(), 5, suite.VariableThatShouldStartAtFive)
|
||||
}
|
||||
|
||||
// In order for 'go test' to run this suite, we need to create
|
||||
// a normal test function and pass our suite to suite.Run
|
||||
func TestExampleTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(ExampleTestSuite))
|
||||
}
|
||||
```
|
||||
|
||||
For a more complete example, using all of the functionality provided by the suite package, look at our [example testing suite](https://github.com/stretchr/testify/blob/master/suite/suite_test.go)
|
||||
|
||||
For more information on writing suites, check out the [API documentation for the `suite` package](http://godoc.org/github.com/stretchr/testify/suite).
|
||||
|
||||
`Suite` object has assertion methods:
|
||||
|
||||
```go
|
||||
// Basic imports
|
||||
import (
|
||||
"testing"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
// Define the suite, and absorb the built-in basic suite
|
||||
// functionality from testify - including assertion methods.
|
||||
type ExampleTestSuite struct {
|
||||
suite.Suite
|
||||
VariableThatShouldStartAtFive int
|
||||
}
|
||||
|
||||
// Make sure that VariableThatShouldStartAtFive is set to five
|
||||
// before each test
|
||||
func (suite *ExampleTestSuite) SetupTest() {
|
||||
suite.VariableThatShouldStartAtFive = 5
|
||||
}
|
||||
|
||||
// All methods that begin with "Test" are run as tests within a
|
||||
// suite.
|
||||
func (suite *ExampleTestSuite) TestExample() {
|
||||
suite.Equal(suite.VariableThatShouldStartAtFive, 5)
|
||||
}
|
||||
|
||||
// In order for 'go test' to run this suite, we need to create
|
||||
// a normal test function and pass our suite to suite.Run
|
||||
func TestExampleTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(ExampleTestSuite))
|
||||
}
|
||||
```
|
||||
|
||||
------
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
To install Testify, use `go get`:
|
||||
|
||||
* Latest version: go get github.com/stretchr/testify
|
||||
* Specific version: go get gopkg.in/stretchr/testify.v1
|
||||
|
||||
This will then make the following packages available to you:
|
||||
|
||||
github.com/stretchr/testify/assert
|
||||
github.com/stretchr/testify/mock
|
||||
github.com/stretchr/testify/http
|
||||
|
||||
Import the `testify/assert` package into your code using this template:
|
||||
|
||||
```go
|
||||
package yours
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSomething(t *testing.T) {
|
||||
|
||||
assert.True(t, true, "True is true!")
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
------
|
||||
|
||||
Staying up to date
|
||||
==================
|
||||
|
||||
To update Testify to the latest version, use `go get -u github.com/stretchr/testify`.
|
||||
|
||||
------
|
||||
|
||||
Version History
|
||||
===============
|
||||
|
||||
* 1.0 - New package versioning strategy adopted.
|
||||
|
||||
------
|
||||
|
||||
Contributing
|
||||
============
|
||||
|
||||
Please feel free to submit issues, fork the repository and send pull requests!
|
||||
|
||||
When submitting an issue, we ask that you please include a complete test function that demonstrates the issue. Extra credit for those using Testify to write the test code that demonstrates it.
|
||||
|
||||
------
|
||||
|
||||
Licence
|
||||
=======
|
||||
Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell
|
||||
|
||||
Please consider promoting this project if you find it useful.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
src/vendor/gopkg.in/stretchr/testify.v1/doc.go
generated
vendored
@ -1,22 +0,0 @@
|
||||
// Package testify is a set of packages that provide many tools for testifying that your code will behave as you intend.
|
||||
//
|
||||
// testify contains the following packages:
|
||||
//
|
||||
// The assert package provides a comprehensive set of assertion functions that tie in to the Go testing system.
|
||||
//
|
||||
// The http package contains tools to make it easier to test http activity using the Go testing system.
|
||||
//
|
||||
// The mock package provides a system by which it is possible to mock your objects and verify calls are happening as expected.
|
||||
//
|
||||
// The suite package provides a basic structure for using structs as testing suites, and methods on those structs as tests. It includes setup/teardown functionality in the way of interfaces.
|
||||
package testify
|
||||
|
||||
// blank imports help docs.
|
||||
import (
|
||||
// assert package
|
||||
_ "github.com/stretchr/testify/assert"
|
||||
// http package
|
||||
_ "github.com/stretchr/testify/http"
|
||||
// mock package
|
||||
_ "github.com/stretchr/testify/mock"
|
||||
)
|
@ -27,6 +27,14 @@ export DRONE_SERVER=$DRONE_SERVER
|
||||
export DRONE_TOKEN=$DRONE_TOKEN
|
||||
buildinfo=$(drone build info vmware/harbor $DRONE_BUILD_NUMBER)
|
||||
echo $buildinfo
|
||||
git_commit=$(git rev-parse --short=8 HEAD)
|
||||
if [ $DRONE_BUILD_EVENT == "tag" ]; then
|
||||
build_number=$(git describe --abbrev=0 --tags)
|
||||
else
|
||||
build_number=$DRONE_BUILD_NUMBER-$git_commit
|
||||
fi
|
||||
echo build_number
|
||||
export HARBOR_BUILD_NUMBER=$build_number
|
||||
upload_build=false
|
||||
nightly_run=false
|
||||
upload_latest_build=false
|
||||
|
158
tests/nightly-test/deployment/deployer.py
Normal file
@ -0,0 +1,158 @@
|
||||
import abc
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import subprocess
|
||||
from datetime import datetime
|
||||
dir_path = os.path.dirname(os.path.realpath(__file__))
|
||||
sys.path.append(dir_path + '../utils')
|
||||
import govc_utils
|
||||
import nlogging
|
||||
logger = nlogging.create_logger(__name__)
|
||||
|
||||
class Deployer(object):
|
||||
__metaclass__ = abc.ABCMeta
|
||||
|
||||
@abc.abstractmethod
|
||||
def deploy(self):
|
||||
return
|
||||
|
||||
@abc.abstractmethod
|
||||
def destory(self):
|
||||
return
|
||||
|
||||
class OVADeployer(Deployer):
|
||||
|
||||
def __init__(self, vc_host, vc_user, vc_password, ds, cluster, ova_path, ova_name, ova_root_password, count,
|
||||
dry_run, auth_mode, ldap_url, ldap_searchdn, ldap_search_pwd, ldap_filter, ldap_basedn, ldap_uid,
|
||||
ldap_scope, ldap_timeout):
|
||||
self.vc_host = vc_host
|
||||
self.vc_user = vc_user
|
||||
self.vc_password = vc_password
|
||||
self.ds = ds
|
||||
self.cluster = cluster
|
||||
self.ova_path = ova_path
|
||||
self.ova_name = ova_name
|
||||
self.ova_root_password = ova_root_password
|
||||
self.dry_run = dry_run
|
||||
self.count = count
|
||||
self.auth_mode=auth_mode
|
||||
|
||||
if auth_mode == 'ldap_auth':
|
||||
self.ldap_url = ldap_url
|
||||
self.ldap_searchdn = ldap_searchdn
|
||||
self.ldap_search_pwd = ldap_search_pwd
|
||||
self.ldap_filter = ldap_filter
|
||||
self.ldap_basedn = ldap_basedn
|
||||
self.ldap_uid = ldap_uid
|
||||
self.ldap_scope = ldap_scope
|
||||
self.ldap_timeout = ldap_timeout
|
||||
|
||||
self.harbor_password='Harbor12345'
|
||||
self.log_path=None
|
||||
self.ip=None
|
||||
self.netmask=None
|
||||
self.gateway=None
|
||||
self.dns=None
|
||||
self.ovf_tool_path=None
|
||||
self.DEFAULT_LOCAL_OVF_TOOL_PATH = '/home/harbor-ci/ovftool/ovftool'
|
||||
self.ova_endpoints = []
|
||||
self.ova_names = []
|
||||
|
||||
def __generate_ova_names(self):
|
||||
for i in range(0, self.count):
|
||||
ova_name_temp = ''
|
||||
ova_name_temp = self.ova_name +"-"+ datetime.now().isoformat().replace(":", "-").replace(".", "-")
|
||||
time.sleep(1)
|
||||
self.ova_names.append(ova_name_temp)
|
||||
|
||||
def __set_ovf_tool(self):
|
||||
if not self.ova_endpoints:
|
||||
self.ovf_tool_path = self.DEFAULT_LOCAL_OVF_TOOL_PATH
|
||||
if not os.path.isfile(self.ovf_tool_path):
|
||||
logger.error("ovftool not found.")
|
||||
return
|
||||
|
||||
def __compose_cmd(self, ova_name):
|
||||
cmd = ''
|
||||
|
||||
if self.auth_mode == "db_auth":
|
||||
cmd = (
|
||||
'"%s" --X:"logFile"="./deploy_oms.log" --overwrite --powerOn --datastore=\'%s\' --noSSLVerify --acceptAllEulas --name=%s \
|
||||
--X:injectOvfEnv --X:enableHiddenProperties --prop:root_pwd=\'%s\' --prop:permit_root_login=true --prop:auth_mode=\'%s\' \
|
||||
--prop:harbor_admin_password=\'%s\' --prop:max_job_workers=5 %s \
|
||||
vi://%s:\'%s\'@%s/Datacenter/host/%s'
|
||||
% (self.ovf_tool_path, self.ds, ova_name,
|
||||
self.ova_root_password, self.auth_mode,
|
||||
self.harbor_password, self.ova_path,
|
||||
self.vc_user, self.vc_password, self.vc_host, self.cluster
|
||||
)
|
||||
)
|
||||
|
||||
if self.auth_mode == "ldap_auth":
|
||||
cmd = (
|
||||
'"%s" --X:"logFile"="./deploy_oms.log" --overwrite --powerOn --datastore=\'%s\' --noSSLVerify --acceptAllEulas --name=%s \
|
||||
--X:injectOvfEnv --X:enableHiddenProperties --prop:root_pwd=\'%s\' --prop:permit_root_login=true --prop:auth_mode=\'%s\' \
|
||||
--prop:harbor_admin_password=\'%s\' --prop:max_job_workers=5 \
|
||||
--prop:ldap_url=\'%s\' --prop:ldap_searchdn=\'%s\' --prop:ldap_search_pwd=\'%s\' \
|
||||
--prop:ldap_filter=\'%s\' \
|
||||
--prop:ldap_basedn=\'%s\' \
|
||||
--prop:ldap_uid=\'%s\' --prop:ldap_scope=\'%s\' --prop:ldap_timeout=\'%s\' %s \
|
||||
vi://%s:\'%s\'@%s/Datacenter/host/%s'
|
||||
% (self.ovf_tool_path, self.ds, ova_name,
|
||||
self.ova_root_password, self.auth_mode,
|
||||
self.harbor_password,
|
||||
self.ldap_url, self.ldap_searchdn,
|
||||
self.ldap_search_pwd, self.ldap_filter,
|
||||
self.ldap_basedn, self.ldap_uid,
|
||||
self.ldap_scope, self.ldap_timeout,
|
||||
self.ova_path,
|
||||
self.vc_user, self.vc_password, self.vc_host, self.cluster
|
||||
)
|
||||
)
|
||||
return cmd
|
||||
|
||||
def deploy(self):
|
||||
self.__generate_ova_names()
|
||||
self.__set_ovf_tool()
|
||||
|
||||
for i in range(0, self.count):
|
||||
cmd = self.__compose_cmd(self.ova_names[i])
|
||||
logger.info(cmd)
|
||||
if self.dry_run == "true" :
|
||||
logger.info("Dry run ...")
|
||||
else:
|
||||
try:
|
||||
subprocess.check_output(cmd, shell=True)
|
||||
except Exception, e:
|
||||
logger.info(e)
|
||||
time.sleep(5)
|
||||
# try onre more time if any failure.
|
||||
subprocess.check_output(cmd, shell=True)
|
||||
logger.info("Successfully deployed harbor OVA.")
|
||||
|
||||
ova_endpoint = ''
|
||||
ova_endpoint = govc_utils.getvmip(self.vc_host, self.vc_user, self.vc_password, self.ova_names[i])
|
||||
if ova_endpoint is not '':
|
||||
self.ova_endpoints.append(ova_endpoint)
|
||||
|
||||
return self.ova_endpoints, self.ova_names
|
||||
|
||||
def destory(self):
|
||||
for item in self.ova_names:
|
||||
govc_utils.destoryvm(self.vc_host, self.vc_user, self.vc_password, item)
|
||||
|
||||
|
||||
class OfflineDeployer(Deployer):
|
||||
|
||||
def __init__(self):
|
||||
self.vm_host = ''
|
||||
self.vm_user = ''
|
||||
self.vm_password = ''
|
||||
|
||||
def deploy(self):
|
||||
pass
|
||||
|
||||
def destory(self):
|
||||
pass
|
109
tests/nightly-test/launch.py
Normal file
@ -0,0 +1,109 @@
|
||||
#!/usr/bin/python2
|
||||
|
||||
import sys
|
||||
import os
|
||||
import ConfigParser
|
||||
from subprocess import call
|
||||
from datetime import datetime
|
||||
import time
|
||||
dir_path = os.path.dirname(os.path.realpath(__file__))
|
||||
sys.path.append(dir_path + '/utils')
|
||||
sys.path.append(dir_path + '/deployment')
|
||||
import harbor_util
|
||||
import buildweb_utils
|
||||
import govc_utils
|
||||
import nlogging
|
||||
logger = nlogging.create_logger(__name__)
|
||||
import test_executor
|
||||
from deployer import *
|
||||
|
||||
if len(sys.argv)!=9 :
|
||||
logger.info("python launch.py <build_type> <image_url> <test suitename> <config_file> <dry_run> <auth_mode> <destory>")
|
||||
logger.info("Wrong parameters, quit test")
|
||||
quit()
|
||||
|
||||
build_type = sys.argv[1]
|
||||
image_url = sys.argv[2]
|
||||
test_suite = sys.argv[3]
|
||||
config_file = sys.argv[4]
|
||||
deploy_count = int(sys.argv[5])
|
||||
dry_run = sys.argv[6]
|
||||
auth_mode = sys.argv[7]
|
||||
destory = sys.argv[8]
|
||||
config_file = os.getcwd() + "/harbor_nightly_test/testenv.ini"
|
||||
config = ConfigParser.ConfigParser()
|
||||
config.read(config_file)
|
||||
harbor_endpoints = []
|
||||
vm_names = []
|
||||
|
||||
# ----- deploy harbor build -----
|
||||
if build_type == "ova" :
|
||||
vc_host = config.get("vcenter", "vc_host")
|
||||
vc_user = config.get("vcenter", "vc_user")
|
||||
vc_password = config.get("vcenter", "vc_password")
|
||||
datastore = config.get("vcenter", "datastore")
|
||||
cluster = config.get("vcenter", "cluster")
|
||||
ova_password = config.get("vcenter", "ova_password")
|
||||
ova_name = config.get("vcenter", "ova_name")
|
||||
|
||||
ldap_url = config.get("ldap", "ldap_url")
|
||||
ldap_searchdn = config.get("ldap", "ldap_searchdn")
|
||||
ldap_search_pwd = config.get("ldap", "ldap_search_pwd")
|
||||
ldap_filter = config.get("ldap", "ldap_filter")
|
||||
ldap_basedn = config.get("ldap", "ldap_basedn")
|
||||
ldap_uid = config.get("ldap", "ldap_uid")
|
||||
ldap_scope = config.get("ldap", "ldap_scope")
|
||||
ldap_timeout = config.get("ldap", "ldap_timeout")
|
||||
|
||||
if image_url == "latest" :
|
||||
image_url = buildweb_utils.get_latest_build_url('master','beta')
|
||||
logger.info("Get latest image url:" + image_url)
|
||||
|
||||
ova_deployer = OVADeployer(vc_host,
|
||||
vc_user,
|
||||
vc_password,
|
||||
datastore,
|
||||
cluster,
|
||||
image_url,
|
||||
ova_name,
|
||||
ova_password,
|
||||
deploy_count,
|
||||
dry_run,
|
||||
auth_mode,
|
||||
ldap_url,
|
||||
ldap_searchdn,
|
||||
ldap_search_pwd,
|
||||
ldap_filter,
|
||||
ldap_basedn,
|
||||
ldap_uid,
|
||||
ldap_scope,
|
||||
ldap_timeout)
|
||||
|
||||
logger.info("Going to deploy harbor ova..")
|
||||
harbor_endpoints, vm_names = ova_deployer.deploy()
|
||||
|
||||
# ----- wait for harbor ready -----
|
||||
for item in harbor_endpoints:
|
||||
is_harbor_ready = harbor_util.wait_for_harbor_ready("https://"+item)
|
||||
if not is_harbor_ready:
|
||||
logger.info("Harbor is not ready after 10 minutes.")
|
||||
sys.exit(-1)
|
||||
logger.info("%s is ready for test now..." % item)
|
||||
|
||||
# ----- execute test cases -----
|
||||
try:
|
||||
execute_results = test_executor.execute(harbor_endpoints, vm_names, ova_password, test_suite, auth_mode, vc_host, vc_user, vc_password)
|
||||
if not execute_results:
|
||||
logger.info("execute test failure.")
|
||||
sys.exit(-1)
|
||||
except Exception, e:
|
||||
logger.info(e)
|
||||
sys.exit(-1)
|
||||
finally:
|
||||
if destory == "true":
|
||||
ova_deployer.destory()
|
||||
|
||||
elif build_type == "installer" :
|
||||
logger.info("Going to download installer image to install")
|
||||
elif build_type == "all" :
|
||||
logger.info("launch ova and installer")
|
7
tests/nightly-test/shellscript/destoryvm.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
export GOVC_USERNAME=$2
|
||||
export GOVC_PASSWORD=$3
|
||||
export GOVC_INSECURE=1
|
||||
export GOVC_URL=$1
|
||||
govc vm.destroy $4
|
7
tests/nightly-test/shellscript/getvmip.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
export GOVC_USERNAME=$2
|
||||
export GOVC_PASSWORD=$3
|
||||
export GOVC_INSECURE=1
|
||||
export GOVC_URL=$1
|
||||
govc vm.info -json $4 | jq -r .VirtualMachines[].Guest.HostName
|
64
tests/nightly-test/utils/buildweb_utils.py
Normal file
@ -0,0 +1,64 @@
|
||||
import os
|
||||
import logging
|
||||
|
||||
from buildwebapi import api as buildapi
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_build_type(build_id):
|
||||
build = get_build(build_id)
|
||||
LOG.debug('%s is %s build', build_id, build.buildtype)
|
||||
return build.buildtype
|
||||
|
||||
|
||||
def get_build_id_and_system(build_id):
|
||||
build_system = 'ob'
|
||||
if '-' in str(build_id):
|
||||
temp = build_id.split('-')
|
||||
build_id = temp[1]
|
||||
build_system = temp[0]
|
||||
return build_id, build_system
|
||||
|
||||
|
||||
def get_ova_url(build_id):
|
||||
return get_url(build_id, '_OVF10.ova')
|
||||
|
||||
|
||||
def get_url(build_id, deliverable_name):
|
||||
build = get_build(build_id)
|
||||
deliverables = buildapi.ListResource.by_url(build._deliverables_url)
|
||||
deliverable = [d for d in deliverables
|
||||
if d.matches(path=deliverable_name)][0]
|
||||
LOG.debug('Download URL of %s is %s', build_id, deliverable._download_url)
|
||||
return deliverable._download_url
|
||||
|
||||
|
||||
def get_product(build_id):
|
||||
build = get_build(build_id)
|
||||
LOG.debug('Product of %s is %s.', build_id, build.product)
|
||||
return build.product
|
||||
|
||||
|
||||
def get_latest_build_url(branch, build_type, product='harbor_build'):
|
||||
build_id = get_latest_build_id(branch, build_type, product)
|
||||
print build_id
|
||||
return get_ova_url(build_id)
|
||||
|
||||
|
||||
def get_latest_build_id(branch, build_type, product='harbor_build'):
|
||||
return buildapi.MetricResource.by_name('build',
|
||||
product=product,
|
||||
buildstate='succeeded',
|
||||
buildtype=build_type,
|
||||
branch=branch).get_max_id()
|
||||
|
||||
|
||||
def get_build(build_id):
|
||||
build_id, build_system = get_build_id_and_system(build_id)
|
||||
return buildapi.ItemResource.by_id('build', int(build_id), build_system)
|
||||
|
||||
|
||||
def get_build_version(build_id):
|
||||
build = get_build(build_id)
|
||||
LOG.debug('Version of %s is %s.', build_id, build.version)
|
||||
return build.version
|
37
tests/nightly-test/utils/cmd_utils.py
Normal file
@ -0,0 +1,37 @@
|
||||
import datetime
|
||||
import logging
|
||||
import time
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def wait_for(func, timeout, delay, *args, **kargs):
|
||||
"""Decorator for waiting for until a function finished running."""
|
||||
|
||||
poll_timeout = timeout
|
||||
poll_sleep_retry = delay
|
||||
|
||||
begin_poll = datetime.datetime.now()
|
||||
while True:
|
||||
try:
|
||||
return func(*args, **kargs)
|
||||
break
|
||||
except Exception as e:
|
||||
if (datetime.datetime.now() - begin_poll).seconds > poll_timeout:
|
||||
LOG.exception('Time out after %s seconds.' % poll_timeout)
|
||||
raise TimeoutError('Timed out after %s seconds. Reason: '
|
||||
'%s' % (poll_timeout, e))
|
||||
else:
|
||||
LOG.debug('Sleeping %s seconds before retrying'
|
||||
'' % poll_sleep_retry)
|
||||
time.sleep(poll_sleep_retry)
|
||||
|
||||
|
||||
def safe_run(cmd, msg, sleep_time=180):
|
||||
exit_code = shell.local(cmd)[0]
|
||||
if exit_code:
|
||||
LOG.warning('Failed to %s. Retry it after %s seconds' %
|
||||
(msg, sleep_time))
|
||||
time.sleep(sleep_time)
|
||||
shell.local(cmd, raise_error=True)
|
32
tests/nightly-test/utils/govc_utils.py
Normal file
@ -0,0 +1,32 @@
|
||||
#!/usr/bin/python2
|
||||
|
||||
import os, subprocess
|
||||
import time
|
||||
|
||||
SHELL_SCRIPT_DIR = os.getcwd() + '/tests/nightly-test/shellscript/'
|
||||
|
||||
def getvmip(vc_url, vc_user, vc_password, vm_name, timeout=600) :
|
||||
cmd = (SHELL_SCRIPT_DIR+'getvmip.sh %s %s %s %s ' % (vc_url, vc_user, getPasswordInShell(vc_password), vm_name))
|
||||
interval = 10
|
||||
while True:
|
||||
try:
|
||||
if timeout <= 0:
|
||||
return ''
|
||||
result = subprocess.check_output(cmd,shell=True).strip()
|
||||
if result is not '':
|
||||
if result != 'photon-machine':
|
||||
return result
|
||||
except Exception, e:
|
||||
timeout -= interval
|
||||
time.sleep(interval)
|
||||
continue
|
||||
timeout -= interval
|
||||
time.sleep(interval)
|
||||
|
||||
def destoryvm(vc_url, vc_user, vc_password, vm_name) :
|
||||
cmd = (SHELL_SCRIPT_DIR+'destoryvm.sh %s %s %s %s ' % (vc_url, vc_user, getPasswordInShell(vc_password), vm_name))
|
||||
result = subprocess.check_output(cmd, shell=True)
|
||||
return result
|
||||
|
||||
def getPasswordInShell(password) :
|
||||
return password.replace("!", "\!")
|
23
tests/nightly-test/utils/harbor_util.py
Normal file
@ -0,0 +1,23 @@
|
||||
from urllib2 import urlopen
|
||||
import ssl
|
||||
import time
|
||||
|
||||
# wait for 10 minutes as OVA needs about 7 minutes to startup harbor.
|
||||
def wait_for_harbor_ready(harbor_endpoint, timeout=600):
|
||||
ctx = ssl.create_default_context()
|
||||
ctx.check_hostname = False
|
||||
ctx.verify_mode = ssl.CERT_NONE
|
||||
interval = 10
|
||||
while True:
|
||||
try:
|
||||
if timeout <= 0:
|
||||
return False
|
||||
code = urlopen(harbor_endpoint, context=ctx).code
|
||||
if code == 200:
|
||||
return True
|
||||
except Exception, e:
|
||||
timeout -= interval
|
||||
time.sleep(interval)
|
||||
continue
|
||||
timeout -= interval
|
||||
time.sleep(interval)
|
14
tests/nightly-test/utils/nlogging.py
Normal file
@ -0,0 +1,14 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import logging
|
||||
import sys
|
||||
|
||||
def create_logger(name):
|
||||
default_handler = logging.StreamHandler(sys.stderr)
|
||||
default_handler.setFormatter(logging.Formatter(
|
||||
'[%(asctime)s] %(levelname)s in %(module)s: %(message)s'
|
||||
))
|
||||
logger = logging.getLogger(name)
|
||||
logger.setLevel(logging.DEBUG)
|
||||
logger.addHandler(default_handler)
|
||||
return logger
|
53
tests/nightly-test/utils/test_executor.py
Normal file
@ -0,0 +1,53 @@
|
||||
#!/usr/bin/python2
|
||||
|
||||
import os, subprocess
|
||||
import time
|
||||
import sys
|
||||
|
||||
from subprocess import call
|
||||
import json
|
||||
|
||||
import nlogging
|
||||
logger = nlogging.create_logger(__name__)
|
||||
|
||||
# Needs have docker installed.
|
||||
def execute(harbor_endpoints, vm_names, harbor_root_pwd, test_suite, auth_mode ,vc_host, vc_user, vc_password, harbor_pwd='Harbor12345') :
|
||||
cmd = ''
|
||||
exe_result = -1
|
||||
cmd_base = "docker run -i --privileged -v %s:/drone -w /drone vmware/harbor-e2e-engine:1.38 " % os.getcwd()
|
||||
|
||||
if len(harbor_endpoints) == 1:
|
||||
cmd_pybot = "pybot -v ip:%s -v vm_name:%s -v HARBOR_PASSWORD:%s -v SSH_PWD:%s -v vc_host:%s -v vc_user:%s -v vc_password:%s " % (harbor_endpoints[0], vm_names[0], harbor_pwd, harbor_root_pwd, vc_host, vc_user, vc_password)
|
||||
|
||||
if len(harbor_endpoints) == 2:
|
||||
cmd_pybot = "pybot -v ip:%s -v vm_name:%s -v ip1:%s -v vm_name1:%s -v HARBOR_PASSWORD:%s -v SSH_PWD:%s -v vc_host:%s -v vc_user:%s -v vc_password:%s " % (harbor_endpoints[0], vm_names[0], harbor_endpoints[1], vm_names[1], harbor_pwd, harbor_root_pwd, vc_host, vc_user, vc_password)
|
||||
|
||||
cmd = cmd_base + cmd_pybot
|
||||
if test_suite == 'Nightly':
|
||||
if auth_mode == 'ldap_auth':
|
||||
cmd = cmd + "/drone/tests/robot-cases/Group11-Nightly/LDAP.robot"
|
||||
else:
|
||||
cmd = cmd + "/drone/tests/robot-cases/Group11-Nightly/Nightly.robot"
|
||||
|
||||
logger.info(cmd)
|
||||
p = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE)
|
||||
while True:
|
||||
out = p.stderr.read(1)
|
||||
if out == '' and p.poll() != None:
|
||||
break
|
||||
if out != '':
|
||||
sys.stdout.write(out)
|
||||
sys.stdout.flush()
|
||||
exe_result = p.returncode
|
||||
|
||||
if test_suite == 'Longevity':
|
||||
cmd = cmd + "/drone/tests/robot-cases/Group12-Longevity/Longevity.robot > /dev/null 2>&1"
|
||||
logger.info(cmd)
|
||||
exe_result = subprocess.call(cmd, shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
|
||||
|
||||
collect_log()
|
||||
return exe_result == 0
|
||||
|
||||
# Needs to move log.html to another path it will be overwrite by any pybot run.
|
||||
def collect_log():
|
||||
pass
|
@ -126,6 +126,13 @@ Start Docker Daemon Locally
|
||||
Sleep 2s
|
||||
[Return] ${handle}
|
||||
|
||||
Prepare Docker Cert
|
||||
[Arguments] ${ip}
|
||||
${rc} ${out}= Run And Return Rc And Output mkdir -p /etc/docker/certs.d/${ip}
|
||||
Should Be Equal As Integers ${rc} 0
|
||||
${rc} ${out}= Run And Return Rc And Output cp harbor_ca.crt /etc/docker/certs.d/${ip}
|
||||
Should Be Equal As Integers ${rc} 0
|
||||
|
||||
Kill Local Docker Daemon
|
||||
[Arguments] ${handle} ${dockerd-pid}
|
||||
Terminate Process ${handle}
|
||||
|
@ -76,6 +76,10 @@ Test Ldap Connection
|
||||
Capture Page Screenshot
|
||||
Wait Until Page Contains Connection to LDAP server is verified timeout=15
|
||||
|
||||
Test LDAP Server Success
|
||||
Click Element xpath=${test_ldap_xpath}
|
||||
Wait Until Page Contains Connection to LDAP server is verified timeout=15
|
||||
|
||||
Disable Ldap Verify Cert Checkbox
|
||||
Mouse Down xpath=//*[@id="clr-checkbox-ldapVerifyCert"]
|
||||
Mouse Up xpath=//*[@id="clr-checkbox-ldapVerifyCert"]
|
||||
|
36
tests/resources/Harbor-Pages/Project-Repository.robot
Normal file
@ -0,0 +1,36 @@
|
||||
# Copyright 2016-2017 VMware, Inc. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License
|
||||
|
||||
*** Settings ***
|
||||
Documentation This resource provides any keywords related to the Harbor private registry appliance
|
||||
Resource ../../resources/Util.robot
|
||||
|
||||
*** Keywords ***
|
||||
View Repo Scan Details
|
||||
Click Element xpath=${first_repo_xpath}
|
||||
Sleep 2
|
||||
Capture Page Screenshot viewcve1.png
|
||||
Wait Until Page Contains unknown
|
||||
Wait Until Page Contains high
|
||||
Wait Until Page Contains medium
|
||||
Page Should Contain CVE
|
||||
|
||||
View Scan Error Log
|
||||
Page Should Contain View Log
|
||||
Click Element xpath=${view_log_xpath}
|
||||
Sleep 1
|
||||
Capture Page Screenshot viewlog.png
|
||||
Wait Until Page Contains Entered scan initializer
|
||||
Wait Until Page Contains ERROR
|
||||
Wait Until Page Contains View Scanning Job Log
|
@ -0,0 +1,21 @@
|
||||
# Copyright 2016-2017 VMware, Inc. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License
|
||||
|
||||
*** Settings ***
|
||||
Documentation This resource provides any keywords related to the Harbor private registry appliance
|
||||
|
||||
*** Variables ***
|
||||
${first_repo_xpath} //clr-dg-row//clr-dg-cell[2]//a
|
||||
${first_cve_xpath} //clr-dg-row[1]//clr-dg-cell//a
|
||||
${view_log_xpath} //clr-dg-row[1]//clr-dg-cell[5]//a
|
@ -61,7 +61,7 @@ Switch To Replication
|
||||
|
||||
Back To projects
|
||||
Click Element xpath=${projects_xpath}
|
||||
Sleep 1
|
||||
Sleep 2
|
||||
|
||||
Project Should Display
|
||||
[Arguments] ${projectname}
|
||||
|
@ -57,7 +57,7 @@ Package Harbor Offline
|
||||
[Arguments] ${golang_image}=golang:${GOLANG_VERSION} ${clarity_image}=vmware/harbor-clarity-ui-builder:${CLAIR_BUILDER} ${with_notary}=true ${with_clair}=true ${with_migrator}=true
|
||||
Log To Console \nStart Docker Daemon
|
||||
Start Docker Daemon Locally
|
||||
${rc} ${output}= Run And Return Rc And Output make package_offline DEVFLAG=false GOBUILDIMAGE=${golang_image} COMPILETAG=compile_golangimage CLARITYIMAGE=${clarity_image} NOTARYFLAG=${with_notary} CLAIRFLAG=${with_clair} MIGRATORFLAG=${with_migrator} HTTPPROXY=
|
||||
${rc} ${output}= Run And Return Rc And Output make package_offline VERSIONTAG=%{HARBOR_BUILD_NUMBER} GOBUILDIMAGE=${golang_image} COMPILETAG=compile_golangimage CLARITYIMAGE=${clarity_image} NOTARYFLAG=${with_notary} CLAIRFLAG=${with_clair} MIGRATORFLAG=${with_migrator} HTTPPROXY=
|
||||
Log ${rc}
|
||||
Log ${output}
|
||||
Should Be Equal As Integers ${rc} 0
|
||||
@ -66,7 +66,7 @@ Package Harbor Online
|
||||
[Arguments] ${golang_image}=golang:${GOLANG_VERSION} ${clarity_image}=vmware/harbor-clarity-ui-builder:${CLAIR_BUILDER} ${with_notary}=true ${with_clair}=true ${with_migrator}=true
|
||||
Log To Console \nStart Docker Daemon
|
||||
Start Docker Daemon Locally
|
||||
${rc} ${output}= Run And Return Rc And Output make package_online DEVFLAG=false GOBUILDIMAGE=${golang_image} COMPILETAG=compile_golangimage CLARITYIMAGE=${clarity_image} NOTARYFLAG=${with_notary} CLAIRFLAG=${with_clair} MIGRATORFLAG=${with_migrator} HTTPPROXY=
|
||||
${rc} ${output}= Run And Return Rc And Output make package_online VERSIONTAG=%{HARBOR_BUILD_NUMBER} GOBUILDIMAGE=${golang_image} COMPILETAG=compile_golangimage CLARITYIMAGE=${clarity_image} NOTARYFLAG=${with_notary} CLAIRFLAG=${with_clair} MIGRATORFLAG=${with_migrator} HTTPPROXY=
|
||||
Log ${rc}
|
||||
Log ${output}
|
||||
Should Be Equal As Integers ${rc} 0
|
||||
@ -92,7 +92,7 @@ Switch To LDAP
|
||||
Should Be Equal As Integers ${rc} 0
|
||||
Generate Certificate Authority For Chrome
|
||||
|
||||
Enabe Notary Client
|
||||
Enable Notary Client
|
||||
${rc} ${output}= Run And Return Rc And Output rm -rf ~/.docker/
|
||||
Log ${rc}
|
||||
Should Be Equal As Integers ${rc} 0
|
||||
|
53
tests/resources/Nightly-Util.robot
Normal file
@ -0,0 +1,53 @@
|
||||
# Copyright 2016-2017 VMware, Inc. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License
|
||||
|
||||
*** Settings ***
|
||||
Documentation This resource provides any keywords related to the Harbor private registry appliance
|
||||
Resource Util.robot
|
||||
|
||||
*** Variables ***
|
||||
${SSH_USER} root
|
||||
|
||||
*** Keywords ***
|
||||
Nightly Test Setup
|
||||
[Arguments] ${ip} ${SSH_PWD} ${HARBOR_PASSWORD}
|
||||
Run Keyword CA setup ${ip} ${SSH_PWD} ${HARBOR_PASSWORD}
|
||||
Run Keyword Prepare Docker Cert ${ip}
|
||||
Run Keyword Start Docker Daemon Locally
|
||||
|
||||
CA Setup
|
||||
[Arguments] ${ip} ${SSH_PWD} ${HARBOR_PASSWORD}
|
||||
Open Connection ${ip}
|
||||
Login ${SSH_USER} ${SSH_PWD}
|
||||
SSHLibrary.Get File /data/ca_download/ca.crt
|
||||
Close All Connections
|
||||
Run mv ca.crt harbor_ca.crt
|
||||
Generate Certificate Authority For Chrome ${HARBOR_PASSWORD}
|
||||
|
||||
Collect Nightly Logs
|
||||
[Arguments] ${ip} ${SSH_PWD}
|
||||
Open Connection ${ip}
|
||||
Login ${SSH_USER} ${SSH_PWD}
|
||||
SSHLibrary.Get File /var/log/harbor/ui.log
|
||||
SSHLibrary.Get File /var/log/harbor/registry.log
|
||||
SSHLibrary.Get File /var/log/harbor/proxy.log
|
||||
SSHLibrary.Get File /var/log/harbor/adminserver.log
|
||||
SSHLibrary.Get File /var/log/harbor/clair-db.log
|
||||
SSHLibrary.Get File /var/log/harbor/clair.log
|
||||
SSHLibrary.Get File /var/log/harbor/jobservice.log
|
||||
SSHLibrary.Get File /var/log/harbor/mysql.log
|
||||
SSHLibrary.Get File /var/log/harbor/notary-db.log
|
||||
SSHLibrary.Get File /var/log/harbor/notary-server.log
|
||||
SSHLibrary.Get File /var/log/harbor/notary-signer.log
|
||||
Close All Connections
|
@ -32,10 +32,10 @@ ${ova_network_options} --prop:network.ip0=${ova_network_ip0} --prop:network.net
|
||||
|
||||
${ova_harbor_admin_password} harbor-admin-passwd
|
||||
${ova_harbor_db_password} harbor-db-passwd
|
||||
${ova_service_options} --prop:auth_mode="%{AUTH_MODE}" --prop:clair_db_password="%{CLAIR_DB_PASSWORD}" --prop:max_job_workers="%{MAX_JOB_WORKERS}" --prop:harbor_admin_password="%{HARBOR_ADMIN_PASSWORD}" --prop:db_password="%{DB_PASSWORD}"
|
||||
#${ova_service_options} --prop:auth_mode="%{AUTH_MODE}" --prop:clair_db_password="%{CLAIR_DB_PASSWORD}" --prop:max_job_workers="%{MAX_JOB_WORKERS}" --prop:harbor_admin_password="%{HARBOR_ADMIN_PASSWORD}" --prop:db_password="%{DB_PASSWORD}"
|
||||
|
||||
${ova_options} ${ovftool_options} ${ova_appliance_options} ${ova_service_options}
|
||||
${ova_options_with_network} ${ova_options} ${ova_network_options}
|
||||
#${ova_options} ${ovftool_options} ${ova_appliance_options} ${ova_service_options}
|
||||
#${ova_options_with_network} ${ova_options} ${ova_network_options}
|
||||
|
||||
${tls_not_disabled} False
|
||||
|
||||
|
@ -33,6 +33,8 @@ Resource Harbor-Pages/Project.robot
|
||||
Resource Harbor-Pages/Project_Elements.robot
|
||||
Resource Harbor-Pages/Project-Members.robot
|
||||
Resource Harbor-Pages/Project-Members_Elements.robot
|
||||
Resource Harbor-Pages/Project-Repository.robot
|
||||
Resource Harbor-Pages/Project-Repository_Elements.robot
|
||||
Resource Harbor-Pages/Replication.robot
|
||||
Resource Harbor-Pages/Replication_Elements.robot
|
||||
Resource Harbor-Pages/UserProfile.robot
|
||||
@ -47,3 +49,4 @@ Resource OVA-Util.robot
|
||||
Resource Cert-Util.robot
|
||||
Resource SeleniumUtil.robot
|
||||
Resource Harbor-Pages/Project-Config.robot
|
||||
Resource Nightly-Util.robot
|
||||
|
@ -17,19 +17,19 @@ Documentation This resource contains any keywords dealing with operations being
|
||||
|
||||
*** Keywords ***
|
||||
Power On VM OOB
|
||||
[Arguments] ${vm}
|
||||
${rc} ${output}= Run And Return Rc And Output govc vm.power -on "${vm}"
|
||||
[Arguments] ${vm} ${vc_host} ${vc_user} ${vc_password}
|
||||
${rc} ${output}= Run And Return Rc And Output GOVC_URL=${vc_host} GOVC_USERNAME=${vc_user} GOVC_PASSWORD=${vc_password} GOVC_INSECURE=1 govc vm.power -on "${vm}"
|
||||
Should Be Equal As Integers ${rc} 0
|
||||
Log To Console Waiting for VM to power on ...
|
||||
Wait Until VM Powers On ${vm}
|
||||
Wait Until VM Powers On "${vm}" ${vc_host} ${vc_user} ${vc_password}
|
||||
|
||||
Power Off VM OOB
|
||||
[Arguments] ${vm}
|
||||
${rc} ${output}= Run And Return Rc And Output govc vm.power -off "${vm}"
|
||||
[Arguments] ${vm} ${vc_host} ${vc_user} ${vc_password}
|
||||
${rc} ${output}= Run And Return Rc And Output GOVC_URL=${vc_host} GOVC_USERNAME=${vc_user} GOVC_PASSWORD=${vc_password} GOVC_INSECURE=1 govc vm.power -off "${vm}"
|
||||
Log To Console ${output}
|
||||
Should Be Equal As Integers ${rc} 0
|
||||
Log To Console Waiting for VM to power off ...
|
||||
Wait Until VM Powers Off "${vm}"
|
||||
Wait Until VM Powers Off "${vm}" ${vc_host} ${vc_user} ${vc_password}
|
||||
|
||||
Destroy VM OOB
|
||||
[Arguments] ${vm}
|
||||
@ -45,24 +45,24 @@ Remove Host From Maintenance Mode
|
||||
Should Contain ${output} exiting maintenance mode... OK
|
||||
|
||||
Reboot VM
|
||||
[Arguments] ${vm}
|
||||
[Arguments] ${vm} ${vc_host} ${vc_user} ${vc_password}
|
||||
Log To Console Rebooting ${vm} ...
|
||||
Power Off VM OOB ${vm}
|
||||
Power On VM OOB ${vm}
|
||||
Power Off VM OOB ${vm} ${vc_host} ${vc_user} ${vc_password}
|
||||
Power On VM OOB ${vm} ${vc_host} ${vc_user} ${vc_password}
|
||||
Log To Console ${vm} Powered On
|
||||
|
||||
Reset VM
|
||||
[Arguments] ${vm}
|
||||
${rc} ${output}= Run And Return Rc And Output govc vm.power -reset "${vm}"
|
||||
[Arguments] ${vm} ${vc_host} ${vc_user} ${vc_password}
|
||||
${rc} ${output}= Run And Return Rc And Output GOVC_URL=${vc_host} GOVC_USERNAME=${vc_user} GOVC_PASSWORD=${vc_password} GOVC_INSECURE=1 govc vm.power -reset "${vm}"
|
||||
Log To Console ${output}
|
||||
Should Be Equal As Integers ${rc} 0
|
||||
Log To Console Waiting for VM to reset ...
|
||||
Wait Until VM Powers On "${vm}"
|
||||
Wait Until VM Powers On "${vm}" ${vc_host} ${vc_user} ${vc_password}
|
||||
|
||||
Wait Until VM Powers On
|
||||
[Arguments] ${vm}
|
||||
[Arguments] ${vm} ${vc_host} ${vc_user} ${vc_password}
|
||||
:FOR ${idx} IN RANGE 0 30
|
||||
\ ${ret}= Run govc vm.info ${vm}
|
||||
\ ${ret}= Run GOVC_URL=${vc_host} GOVC_USERNAME=${vc_user} GOVC_PASSWORD=${vc_password} GOVC_INSECURE=1 govc vm.info ${vm}
|
||||
\ Set Test Variable ${out} ${ret}
|
||||
\ ${status}= Run Keyword And Return Status Should Contain ${out} poweredOn
|
||||
\ Return From Keyword If ${status}
|
||||
@ -70,9 +70,9 @@ Wait Until VM Powers On
|
||||
Fail VM did not power on within 30 seconds
|
||||
|
||||
Wait Until VM Powers Off
|
||||
[Arguments] ${vm}
|
||||
[Arguments] ${vm} ${vc_host} ${vc_user} ${vc_password}
|
||||
:FOR ${idx} IN RANGE 0 30
|
||||
\ ${ret}= Run govc vm.info ${vm}
|
||||
\ ${ret}= Run GOVC_URL=${vc_host} GOVC_USERNAME=${vc_user} GOVC_PASSWORD=${vc_password} GOVC_INSECURE=1 govc vm.info ${vm}
|
||||
\ Set Test Variable ${out} ${ret}
|
||||
\ ${status}= Run Keyword And Return Status Should Contain ${out} poweredOff
|
||||
\ Return From Keyword If ${status}
|
||||
|
@ -392,13 +392,13 @@ Test Case - Assign Sys Admin
|
||||
Close Browser
|
||||
|
||||
Test Case - Admin Push Signed Image
|
||||
Enabe Notary Client
|
||||
Enable Notary Client
|
||||
|
||||
${rc} ${output}= Run And Return Rc And Output docker pull hello-world:latest
|
||||
Log ${output}
|
||||
|
||||
Push image ${ip} %{HARBOR_ADMIN} %{HARBOR_PASSWORD} library hello-world:latest
|
||||
${rc} ${output}= Run And Return Rc And Output ./tests/robot-cases/Group9-Content-trust/notary-push-image.sh
|
||||
${rc} ${output}= Run And Return Rc And Output ./tests/robot-cases/Group9-Content-trust/notary-push-image.sh ${ip}
|
||||
Log ${output}
|
||||
Should Be Equal As Integers ${rc} 0
|
||||
|
||||
|
61
tests/robot-cases/Group11-Nightly/LDAP.robot
Normal file
@ -0,0 +1,61 @@
|
||||
// Copyright (c) 2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
*** Settings ***
|
||||
Documentation Harbor BATs
|
||||
Resource ../../resources/Util.robot
|
||||
Suite Setup Nightly Test Setup ${ip} ${SSH_PWD} ${HARBOR_PASSWORD}
|
||||
Suite Teardown Collect Nightly Logs ${ip} ${SSH_PWD}
|
||||
Default Tags Nightly
|
||||
|
||||
*** Variables ***
|
||||
${HARBOR_URL} https://${ip}
|
||||
${SSH_USER} root
|
||||
${HARBOR_ADMIN} admin
|
||||
|
||||
*** Test Cases ***
|
||||
Test Case - Ldap Verify Cert
|
||||
Init Chrome Driver
|
||||
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
|
||||
Switch To Configure
|
||||
Test LDAP Server Success
|
||||
Close Browser
|
||||
|
||||
Test Case - Ldap Sign in and out
|
||||
Init Chrome Driver
|
||||
Sign In Harbor ${HARBOR_URL} mike zhu88jie
|
||||
Close Browser
|
||||
|
||||
Test Case - Ldap User Create Project
|
||||
Init Chrome Driver
|
||||
${d}= Get Current Date result_format=%m%s
|
||||
Sign In Harbor ${HARBOR_URL} mike zhu88jie
|
||||
Create An New Project project${d}
|
||||
Logout Harbor
|
||||
Manage Project Member ${HARBOR_ADMIN} ${HARBOR_PASSWORD} project${d} mike02 Add
|
||||
Close Browser
|
||||
|
||||
Test Case - Ldap User Push An Image
|
||||
Init Chrome Driver
|
||||
${d}= Get Current Date result_format=%m%s
|
||||
Sign In Harbor ${HARBOR_URL} mike zhu88jie
|
||||
Create An New Project project${d}
|
||||
|
||||
Push Image ${ip} mike zhu88jie project${d} hello-world:latest
|
||||
Go Into Project project${d}
|
||||
Wait Until Page Contains project${d}/hello-world
|
||||
Close Browser
|
||||
|
||||
Test Case - Ldap User Can Not login
|
||||
Docker Login Fail ${ip} test 123456
|
443
tests/robot-cases/Group11-Nightly/Nightly.robot
Normal file
@ -0,0 +1,443 @@
|
||||
// Copyright (c) 2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
*** Settings ***
|
||||
Documentation Harbor BATs
|
||||
Resource ../../resources/Util.robot
|
||||
Suite Setup Nightly Test Setup ${ip} ${SSH_PWD} ${HARBOR_PASSWORD}
|
||||
Suite Teardown Collect Nightly Logs ${ip} ${SSH_PWD}
|
||||
Default Tags Nightly
|
||||
|
||||
*** Variables ***
|
||||
${HARBOR_URL} https://${ip}
|
||||
${SSH_USER} root
|
||||
${HARBOR_ADMIN} admin
|
||||
|
||||
*** Test Cases ***
|
||||
Test Case - Create An New User
|
||||
Init Chrome Driver
|
||||
${d}= Get Current Date result_format=%m%s
|
||||
Create An New User url=${HARBOR_URL} username=tester${d} email=tester${d}@vmware.com realname=harbortest newPassword=Test1@34 comment=harbortest
|
||||
Close Browser
|
||||
|
||||
Test Case - Sign With Admin
|
||||
Init Chrome Driver
|
||||
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
|
||||
Close Browser
|
||||
|
||||
Test Case - Update User Comment
|
||||
Init Chrome Driver
|
||||
${d}= Get Current Date result_format=%m%s
|
||||
Create An New User url=${HARBOR_URL} username=tester${d} email=tester${d}@vmware.com realname=harbortest newPassword=Test1@34 comment=harbortest
|
||||
Update User Comment Test12#4
|
||||
Logout Harbor
|
||||
|
||||
Test Case - Update Password
|
||||
Init Chrome Driver
|
||||
${d}= Get Current Date result_format=%m%s
|
||||
Create An New User url=${HARBOR_URL} username=tester${d} email=tester${d}@vmware.com realname=harbortest newPassword=Test1@34 comment=harbortest
|
||||
Change Password Test1@34 Test12#4
|
||||
Logout Harbor
|
||||
Sign In Harbor ${HARBOR_URL} tester${d} Test12#4
|
||||
Close Browser
|
||||
|
||||
Test Case - Create An New Project
|
||||
Init Chrome Driver
|
||||
${d}= Get Current Date result_format=%m%s
|
||||
Create An New User url=${HARBOR_URL} username=tester${d} email=tester${d}@vmware.com realname=harbortest newPassword=Test1@34 comment=harbortest
|
||||
Create An New Project test${d}
|
||||
Close Browser
|
||||
|
||||
Test Case - User View Projects
|
||||
Init Chrome Driver
|
||||
${d}= Get Current Date result_format=%m%s
|
||||
Create An New User url=${HARBOR_URL} username=tester${d} email=tester${d}@vmware.com realname=harbortest newPassword=Test1@34 comment=harbortest
|
||||
Create An New Project test${d}1
|
||||
Create An New Project test${d}2
|
||||
Create An New Project test${d}3
|
||||
Switch To Log
|
||||
Capture Page Screenshot UserViewProjects.png
|
||||
Wait Until Page Contains test${d}1
|
||||
Wait Until Page Contains test${d}2
|
||||
Wait Until Page Contains test${d}3
|
||||
Close Browser
|
||||
|
||||
Test Case - Push Image
|
||||
Init Chrome Driver
|
||||
${d}= Get Current Date result_format=%m%s
|
||||
Create An New User url=${HARBOR_URL} username=tester${d} email=tester${d}@vmware.com realname=harbortest newPassword=Test1@34 comment=harbortest
|
||||
Create An New Project test${d}
|
||||
|
||||
Push image ${ip} tester${d} Test1@34 test${d} hello-world:latest
|
||||
Go Into Project test${d}
|
||||
Wait Until Page Contains test${d}/hello-world
|
||||
|
||||
Test Case - User View Logs
|
||||
Init Chrome Driver
|
||||
${d}= Get Current Date result_format=%m%s
|
||||
|
||||
Create An New Project With New User url=${HARBOR_URL} username=tester${d} email=tester${d}@vmware.com realname=tester${d} newPassword=Test1@34 comment=harbor projectname=project${d} public=true
|
||||
|
||||
Push image ${ip} tester${d} Test1@34 project${d} busybox:latest
|
||||
Pull image ${ip} tester${d} Test1@34 project${d} busybox:latest
|
||||
|
||||
Go Into Project project${d}
|
||||
Delete Repo project${d}
|
||||
|
||||
Go To Project Log
|
||||
Advanced Search Should Display
|
||||
|
||||
Do Log Advanced Search
|
||||
Close Browser
|
||||
|
||||
Test Case - Manage project publicity
|
||||
Init Chrome Driver
|
||||
${d}= Get Current Date result_format=%m%s
|
||||
|
||||
Create An New User url=${HARBOR_URL} username=usera${d} email=usera${d}@vmware.com realname=usera${d} newPassword=Test1@34 comment=harbor
|
||||
Logout Harbor
|
||||
Create An New User url=${HARBOR_URL} username=userb${d} email=userb${d}@vmware.com realname=userb${d} newPassword=Test1@34 comment=harbor
|
||||
Logout Harbor
|
||||
|
||||
Sign In Harbor ${HARBOR_URL} usera${d} Test1@34
|
||||
Create An New Project project${d} public=true
|
||||
|
||||
Push image ${ip} usera${d} Test1@34 project${d} hello-world:latest
|
||||
Pull image ${ip} userb${d} Test1@34 project${d} hello-world:latest
|
||||
|
||||
Logout Harbor
|
||||
Sign In Harbor ${HARBOR_URL} userb${d} Test1@34
|
||||
Project Should Display project${d}
|
||||
Search Private Projects
|
||||
Project Should Not Display project${d}
|
||||
|
||||
Logout Harbor
|
||||
Sign In Harbor ${HARBOR_URL} usera${d} Test1@34
|
||||
Make Project Private project${d}
|
||||
|
||||
Logout Harbor
|
||||
Sign In Harbor ${HARBOR_URL} userb${d} Test1@34
|
||||
Project Should Not Display project${d}
|
||||
Cannot Pull image ${ip} userb${d} Test1@34 project${d} hello-world:latest
|
||||
|
||||
Logout Harbor
|
||||
Sign In Harbor ${HARBOR_URL} usera${d} Test1@34
|
||||
Make Project Public project${d}
|
||||
|
||||
Logout Harbor
|
||||
Sign In Harbor ${HARBOR_URL} userb${d} Test1@34
|
||||
Project Should Display project${d}
|
||||
Close Browser
|
||||
|
||||
Test Case - Project Level Policy Public
|
||||
Init Chrome Driver
|
||||
${d}= Get Current Date result_format=%m%s
|
||||
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
|
||||
Create An New Project project${d}
|
||||
Go Into Project project${d}
|
||||
Goto Project Config
|
||||
Click Project Public
|
||||
Save Project Config
|
||||
#verify
|
||||
Public Should Be Selected
|
||||
Back To Projects
|
||||
#project${d} default should be private
|
||||
Project Should Be Public project${d}
|
||||
Close Browser
|
||||
|
||||
Test Case - Project Level Policy Content Trust
|
||||
Init Chrome Driver
|
||||
${d}= Get Current Date result_format=%m%s
|
||||
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
|
||||
Create An New Project project${d}
|
||||
Push Image ${ip} ${HARBOR_ADMIN} ${HARBOR_PASSWORD} project${d} hello-world:latest
|
||||
Go Into Project project${d}
|
||||
Goto Project Config
|
||||
Click Content Trust
|
||||
Save Project Config
|
||||
#verify
|
||||
Content Trust Should Be Selected
|
||||
Cannot Pull Unsigned Image ${ip} ${HARBOR_ADMIN} ${HARBOR_PASSWORD} project${d} hello-world:latest
|
||||
Close Browser
|
||||
|
||||
Test Case - Edit Project Creation
|
||||
# create normal user and login
|
||||
Init Chrome Driver
|
||||
${d}= Get Current Date result_format=%m%s
|
||||
Create An New User url=${HARBOR_URL} username=tester${d} email=tester${d}@vmware.com realname=harbortest newPassword=Test1@34 comment=harbortest
|
||||
|
||||
Project Creation Should Display
|
||||
Logout Harbor
|
||||
|
||||
Sleep 3
|
||||
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
|
||||
Set Pro Create Admin Only
|
||||
Logout Harbor
|
||||
|
||||
Sign In Harbor ${HARBOR_URL} tester${d} Test1@34
|
||||
Project Creation Should Not Display
|
||||
Logout Harbor
|
||||
|
||||
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
|
||||
Set Pro Create Every One
|
||||
Close browser
|
||||
|
||||
Test Case - Edit Self-Registration
|
||||
Init Chrome Driver
|
||||
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
|
||||
Disable Self Reg
|
||||
Logout Harbor
|
||||
|
||||
Sign Up Should Not Display
|
||||
|
||||
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
|
||||
Switch To Configure
|
||||
Self Reg Should Be Disabled
|
||||
Sleep 1
|
||||
|
||||
#restore setting
|
||||
Enable Self Reg
|
||||
Close Browser
|
||||
|
||||
Test Case - Edit Email Settings
|
||||
Init Chrome Driver
|
||||
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
|
||||
|
||||
Switch To Email
|
||||
Config Email
|
||||
|
||||
Logout Harbor
|
||||
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
|
||||
|
||||
Switch To Email
|
||||
Verify Email
|
||||
|
||||
Close Browser
|
||||
|
||||
Test Case - Edit Token Expire
|
||||
Init Chrome Driver
|
||||
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
|
||||
Switch To System Settings
|
||||
Modify Token Expiration 20
|
||||
Logout Harbor
|
||||
|
||||
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
|
||||
Switch To System Settings
|
||||
Token Must Be Match 20
|
||||
|
||||
#reset to default
|
||||
Modify Token Expiration 30
|
||||
Close Browser
|
||||
|
||||
#Test Case - Create An Replication Rule New Endpoint
|
||||
# Init Chrome Driver
|
||||
# ${d}= Get current date result_format=%m%s
|
||||
# Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
|
||||
# Create An New Project project${d}
|
||||
# Go Into Project project${d}
|
||||
# Switch To Replication
|
||||
# Create An New Rule With New Endpoint policy_name=test_policy_${d} policy_description=test_description destination_name=test_destination_name_${d} destination_url=test_destination_url_${d} destination_username=test_destination_username destination_password=test_destination_password
|
||||
# Close Browser
|
||||
|
||||
Test Case - Scan A Tag In The Repo
|
||||
Init Chrome Driver
|
||||
${d}= get current date result_format=%m%s
|
||||
Create An New Project With New User url=${HARBOR_URL} username=tester${d} email=tester${d}@vmware.com realname=tester${d} newPassword=Test1@34 comment=harbor projectname=project${d} public=false
|
||||
Push Image ${ip} tester${d} Test1@34 project${d} hello-world
|
||||
Go Into Project project${d}
|
||||
Go Into Repo project${d}/hello-world
|
||||
Scan Repo latest
|
||||
Summary Chart Should Display latest
|
||||
#Edit Repo Info
|
||||
Close Browser
|
||||
|
||||
Test Case - Manage Project Member
|
||||
Init Chrome Driver
|
||||
${d}= Get current Date result_format=%m%s
|
||||
|
||||
Create An New Project With New User url=${HARBOR_URL} username=alice${d} email=alice${d}@vmware.com realname=alice${d} newPassword=Test1@34 comment=harbor projectname=project${d} public=false
|
||||
Push image ip=${ip} user=alice${d} pwd=Test1@34 project=project${d} image=hello-world
|
||||
Logout Harbor
|
||||
Create An New User url=${HARBOR_URL} username=bob${d} email=bob${d}@vmware.com realname=bob${d} newPassword=Test1@34 comment=habor
|
||||
Logout Harbor
|
||||
Create An New User url=${HARBOR_URL} username=carol${d} email=carol${d}@vmware.com realname=carol${d} newPassword=Test1@34 comment=harbor
|
||||
Logout Harbor
|
||||
|
||||
User Should Not Be A Member Of Project bob${d} Test1@34 project${d}
|
||||
Manage Project Member alice${d} Test1@34 project${d} bob${d} Add
|
||||
User Should Be Guest bob${d} Test1@34 project${d}
|
||||
Change User Role In Project alice${d} Test1@34 project${d} bob${d} Developer
|
||||
User Should Be Developer bob${d} Test1@34 project${d}
|
||||
Change User Role In Project alice${d} Test1@34 project${d} bob${d} Admin
|
||||
User Should Be Admin bob${d} Test1@34 project${d} carol${d}
|
||||
Manage Project Member alice${d} Test1@34 project${d} bob${d} Remove
|
||||
User Should Not Be A Member Of Project bob${d} Test1@34 project${d}
|
||||
User Should Be Guest carol${d} Test1@34 project${d}
|
||||
|
||||
Close Browser
|
||||
|
||||
Test Case - Delete A Project
|
||||
Init Chrome Driver
|
||||
${d}= Get Current Date result_format=%m%s
|
||||
Create An New Project With New User ${HARBOR_URL} tester${d} tester${d}@vmware.com tester${d} Test1@34 harobr project${d} false
|
||||
Push Image ${ip} tester${d} Test1@34 project${d} hello-world
|
||||
Project Should Not Be Deleted project${d}
|
||||
Go Into Project project${d}
|
||||
Delete Repo project${d}
|
||||
Back To projects
|
||||
Project Should Be Deleted project${d}
|
||||
Close Browser
|
||||
|
||||
Test Case - Delete Multi Project
|
||||
Init Chrome Driver
|
||||
${d}= Get Current Date result_format=%m%s
|
||||
Create An New User ${HARBOR_URL} test${d} test${d}@vmware.com test${d} Test1@34 harbor
|
||||
Create An New Project projecta${d}
|
||||
Create An New Project projectb${d}
|
||||
Push Image ${ip} test${d} Test1@34 projecta${d} hello-world
|
||||
Filter Object project
|
||||
Multi-delete Object projecta projectb
|
||||
#verify delete project with image should not be deleted directly
|
||||
Partly Success
|
||||
Page Should Contain projecta${d}
|
||||
Page Should Not Contain projectb${d}
|
||||
Close Browser
|
||||
|
||||
Test Case - Delete Multi User
|
||||
Init Chrome Driver
|
||||
${d}= Get Current Date result_format=%m%s
|
||||
Create An New User ${HARBOR_URL} deletea${d} testa${d}@vmware.com test${d} Test1@34 harbor
|
||||
Logout Harbor
|
||||
Create An New User ${HARBOR_URL} deleteb${d} testb${d}@vmware.com test${d} Test1@34 harbor
|
||||
Logout Harbor
|
||||
Create An New User ${HARBOR_URL} deletec${d} testc${d}@vmware.com test${d} Test1@34 harbor
|
||||
Logout Harbor
|
||||
Sign In Harbor ${HARBOR_URL} admin Harbor12345
|
||||
Switch To User Tag
|
||||
Filter Object delete
|
||||
Multi-delete Object deletea deleteb deletec
|
||||
#assert delete
|
||||
#Delete Success comment temp wait for fixing
|
||||
Click Element //clr-modal//button[contains(.,'CLOSE')]
|
||||
Sleep 1
|
||||
#filter object delete
|
||||
Page Should Not Contain deletea
|
||||
Close Browser
|
||||
|
||||
Test Case - Delete Multi Repo
|
||||
Init Chrome Driver
|
||||
${d}= Get Current Date result_format=%m%s
|
||||
Create An New User ${HARBOR_URL} test${d} test${d}@vmware.com test${d} Test1@34 harbor
|
||||
Create An New Project project${d}
|
||||
Push Image ${ip} test${d} Test1@34 project${d} hello-world
|
||||
Push Image ${ip} test${d} Test1@34 project${d} busybox
|
||||
Sleep 2
|
||||
Go Into Project project${d}
|
||||
Multi-delete Object hello-world busybox
|
||||
#verify
|
||||
Delete Success
|
||||
Close Browser
|
||||
|
||||
Test Case - Delete Multi Tag
|
||||
Init Chrome Driver
|
||||
${d}= Get Current Date result_format=%m%s
|
||||
Create An New User ${HARBOR_URL} test${d} test${d}@vmware.com test${d} Test1@34 harbor
|
||||
Create An New Project project${d}
|
||||
Push Image With Tag ${ip} test${d} Test1@34 project${d} hello-world latest
|
||||
Push Image With Tag ${ip} test${d} Test1@34 project${d} hello-world v1
|
||||
Sleep 2
|
||||
Go Into Project project${d}
|
||||
Go Into Repo hello-world
|
||||
Multi-delete object latest v1
|
||||
#verify
|
||||
Delete Success
|
||||
Close Browser
|
||||
|
||||
Test Case - Delete Multi Member
|
||||
Init Chrome Driver
|
||||
${d}= Get Current Date result_format=%m%s
|
||||
Create An New User ${HARBOR_URL} testa${d} testa${d}@vmware.com test${d} Test1@34 harbor
|
||||
Logout Harbor
|
||||
Create An New User ${HARBOR_URL} testb${d} testb${d}@vmware.com test${d} Test1@34 harbor
|
||||
Logout Harbor
|
||||
Create An New User ${HARBOR_URL} test${d} test${d}@vmware.com test${d} Test1@34 harbor
|
||||
Create An New Project project${d}
|
||||
Go Into Project project${d}
|
||||
Switch To Member
|
||||
Add Guest Member to project testa${d}
|
||||
Add Guest Member to project testb${d}
|
||||
Multi-delete Object testa${d} testb${d}
|
||||
Delete Success
|
||||
Page Should Not Contain testa${d}
|
||||
Close Browser
|
||||
|
||||
Test Case - Assign Sys Admin
|
||||
Init Chrome Driver
|
||||
${d}= Get Current Date result_format=%m%s
|
||||
Create An New User url=${HARBOR_URL} username=tester${d} email=tester${d}@vmware.com realname=harbortest newPassword=Test1@34 comment=harbortest
|
||||
Logout Harbor
|
||||
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
|
||||
Switch to User Tag
|
||||
Assign User Admin tester${d}
|
||||
Logout Harbor
|
||||
Sign In Harbor ${HARBOR_URL} tester${d} Test1@34
|
||||
Administration Tag Should Display
|
||||
Close Browser
|
||||
|
||||
Test Case - Admin Push Signed Image
|
||||
Enable Notary Client
|
||||
|
||||
${rc} ${output}= Run And Return Rc And Output docker pull hello-world:latest
|
||||
Log ${output}
|
||||
|
||||
Push image ${ip} ${HARBOR_ADMIN} ${HARBOR_PASSWORD} library hello-world:latest
|
||||
${rc} ${output}= Run And Return Rc And Output ./tests/robot-cases/Group9-Content-trust/notary-push-image.sh ${ip}
|
||||
Log ${output}
|
||||
Should Be Equal As Integers ${rc} 0
|
||||
|
||||
${rc} ${output}= Run And Return Rc And Output curl -u admin:Harbor12345 -s --insecure -H "Content-Type: application/json" -X GET "https://${ip}/api/repositories/library/tomcat/signatures"
|
||||
Log To Console ${output}
|
||||
Should Be Equal As Integers ${rc} 0
|
||||
Should Contain ${output} sha256
|
||||
|
||||
Test Case - View Scan Results
|
||||
Init Chrome Driver
|
||||
${d}= get current date result_format=%m%s
|
||||
Create An New Project With New User url=${HARBOR_URL} username=tester${d} email=tester${d}@vmware.com realname=tester${d} newPassword=Test1@34 comment=harbor projectname=project${d} public=false
|
||||
Push Image ${ip} tester${d} Test1@34 project${d} tomcat
|
||||
Go Into Project project${d}
|
||||
Go Into Repo project${d}/tomcat
|
||||
Scan Repo latest
|
||||
Summary Chart Should Display latest
|
||||
View Repo Scan Details
|
||||
Close Browser
|
||||
|
||||
Test Case - View Scan Error
|
||||
Init Chrome Driver
|
||||
${d}= get current date result_format=%m%s
|
||||
Create An New Project With New User url=${HARBOR_URL} username=tester${d} email=tester${d}@vmware.com realname=tester${d} newPassword=Test1@34 comment=harbor projectname=project${d} public=false
|
||||
Push Image ${ip} tester${d} Test1@34 project${d} vmware/photon:1.0
|
||||
Go Into Project project${d}
|
||||
Go Into Repo project${d}/vmware/photon
|
||||
Scan Repo 1.0
|
||||
View Scan Error Log
|
||||
Close Browser
|
||||
|
||||
#Test Case - OVA reboot
|
||||
# Reboot VM ${vm_name} ${vc_host} ${vc_user} ${vc_password}
|
||||
# Wait for Harbor Ready https ${ip}
|
||||
|
||||
#Test Case - OVA reset
|
||||
# Reset VM ${vm_name} ${vc_host} ${vc_user} ${vc_password}
|
||||
# Wait for Harbor Ready https ${ip}
|
2
tests/robot-cases/Group12-Longevity/Dockerfile.longevity
Normal file
@ -0,0 +1,2 @@
|
||||
FROM busybox:1.26
|
||||
RUN /bin/dd if=/dev/urandom of=file10mb bs=10485760 count=1
|
90
tests/robot-cases/Group12-Longevity/Longevity.robot
Normal file
@ -0,0 +1,90 @@
|
||||
# Copyright 2016-2017 VMware, Inc. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License
|
||||
|
||||
*** Settings ***
|
||||
Documentation Longevity
|
||||
Resource ../../resources/Util.robot
|
||||
Suite Teardown Collect Nightly Logs ${ip} ${SSH_PWD}
|
||||
|
||||
*** Variables ***
|
||||
${HARBOR_URL} https://${ip}
|
||||
${SSH_USER} root
|
||||
|
||||
${image0} consul
|
||||
${image1} node
|
||||
${image2} tomcat
|
||||
${image3} redis
|
||||
${image4} httpd
|
||||
${image5} busybox
|
||||
${image6} mysql
|
||||
${image7} registry
|
||||
${image8} mongo
|
||||
${image9} memcached
|
||||
|
||||
*** Keywords ***
|
||||
Longevity setup
|
||||
Run Keyword CA setup
|
||||
Run Keyword Prepare Docker Cert ${ip}
|
||||
Run Keyword Start Docker Daemon Locally
|
||||
|
||||
CA setup
|
||||
Open Connection ${ip}
|
||||
Login ${SSH_USER} ${SSH_PWD}
|
||||
SSHLibrary.Get File /data/ca_download/ca.crt
|
||||
Close All Connections
|
||||
Run mv ca.crt harbor_ca.crt
|
||||
Generate Certificate Authority For Chrome ${HARBOR_PASSWORD}
|
||||
|
||||
Regression Test With DB
|
||||
[Arguments] ${HARBOR_URL}
|
||||
Run Keyword And Continue On Failure Exe Regression Test Cases ${HARBOR_URL}
|
||||
|
||||
Exe Regression Test Cases
|
||||
[Arguments] ${HARBOR_URL}
|
||||
|
||||
# New user, new project, push image, pull image
|
||||
Init Chrome Driver
|
||||
${d}= Get Current Date result_format=%m%s
|
||||
Create An New Project With New User url=${HARBOR_URL} username=tester${d} email=tester${d}@vmware.com realname=tester${d} newPassword=Test1@34 comment=harbor projectname=project${d} public=false
|
||||
|
||||
${rand}= Evaluate random.randint(0, 1) modules=random
|
||||
Run Keyword If '${rand}' == '0' Generate Prepared Image ${ip} tester${d} project${d}
|
||||
Run Keyword If '${rand}' == '1' Generate Random 10MB Image ${ip} tester${d} project${d}
|
||||
|
||||
Close Browser
|
||||
|
||||
Generate Prepared Image
|
||||
[Arguments] ${ip} ${user} ${project}
|
||||
${rand}= Evaluate random.randint(0, 9) modules=random
|
||||
Push image ${ip} ${user} Test1@34 ${project} ${image${rand}}:latest
|
||||
Pull image ${ip} ${user} Test1@34 ${project} ${image${rand}}:latest
|
||||
Pull image ${ip} ${user} Test1@34 ${project} ${image${rand}}:latest
|
||||
|
||||
Generate Random 10MB Image
|
||||
[Arguments] ${ip} ${user} ${project}
|
||||
${rand}= Evaluate random.randint(0, 10000) modules=random
|
||||
${rc}= Run And Return Rc docker build -f ./tests/robot-cases/Group12-Longevity/Dockerfile.longevity -t longevity${rand}:latest .
|
||||
Should Be Equal As Integers ${rc} 0
|
||||
Push image ${ip} ${user} Test1@34 ${project} longevity${rand}:latest
|
||||
Pull image ${ip} ${user} Test1@34 ${project} longevity${rand}:latest
|
||||
Pull image ${ip} ${user} Test1@34 ${project} longevity${rand}:latest
|
||||
|
||||
*** Test Cases ***
|
||||
Longevity
|
||||
Run Keyword Longevity setup
|
||||
# Each loop should take between 1 and 2 hours
|
||||
:FOR ${idx} IN RANGE 0 48
|
||||
\ ${rand}= Evaluate random.randint(10, 50) modules=random
|
||||
\ Log To Console \nLoop: ${idx}
|
||||
\ Repeat Keyword ${rand} times Regression Test With DB ${HARBOR_URL}
|
@ -1,27 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import pexpect
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import socket
|
||||
|
||||
ip = socket.gethostbyname(socket.gethostname())
|
||||
cmd = "docker push "+ip+"/library/tomcat:latest"
|
||||
passw = "Harbor12345"
|
||||
child = pexpect.spawn(cmd)
|
||||
time.sleep(5)
|
||||
|
||||
child.expect(':')
|
||||
child.sendline(passw)
|
||||
time.sleep(1)
|
||||
child.expect(':')
|
||||
child.sendline(passw)
|
||||
time.sleep(1)
|
||||
child.expect(':')
|
||||
child.sendline(passw)
|
||||
time.sleep(1)
|
||||
child.expect(':')
|
||||
child.sendline(passw)
|
||||
time.sleep(1)
|
||||
child.expect(pexpect.EOF)
|
@ -2,7 +2,7 @@
|
||||
|
||||
docker pull tomcat:latest
|
||||
|
||||
IP=`ip addr s eth0 |grep "inet "|awk '{print $2}' |awk -F "/" '{print $1}'`
|
||||
IP=$1
|
||||
PASSHRASE='Harbor12345'
|
||||
|
||||
echo $IP
|
||||
|