Update code.gitea.io/git (#3137)
parent
682ac11958
commit
58a7de2aea
@ -0,0 +1,307 @@
|
||||
// Copyright 2017 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package git
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"path"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
// parameters for searching for commit infos. If the untargeted search has
|
||||
// not found any entries in the past 5 commits, and 12 or fewer entries
|
||||
// remain, then we'll just let the targeted-searching threads finish off,
|
||||
// and stop the untargeted search to not interfere.
|
||||
deferToTargetedSearchColdStreak = 5
|
||||
deferToTargetedSearchNumRemainingEntries = 12
|
||||
)
|
||||
|
||||
// getCommitsInfoState shared state while getting commit info for entries
|
||||
type getCommitsInfoState struct {
|
||||
lock sync.Mutex
|
||||
/* read-only fields, can be read without the mutex */
|
||||
// entries and entryPaths are read-only after initialization, so they can
|
||||
// safely be read without the mutex
|
||||
entries []*TreeEntry
|
||||
// set of filepaths to get info for
|
||||
entryPaths map[string]struct{}
|
||||
treePath string
|
||||
headCommit *Commit
|
||||
|
||||
/* mutable fields, must hold mutex to read or write */
|
||||
// map from filepath to commit
|
||||
commits map[string]*Commit
|
||||
// set of filepaths that have been or are being searched for in a target search
|
||||
targetedPaths map[string]struct{}
|
||||
}
|
||||
|
||||
func (state *getCommitsInfoState) numRemainingEntries() int {
|
||||
state.lock.Lock()
|
||||
defer state.lock.Unlock()
|
||||
return len(state.entries) - len(state.commits)
|
||||
}
|
||||
|
||||
// getTargetEntryPath Returns the next path for a targeted-searching thread to
|
||||
// search for, or returns the empty string if nothing left to search for
|
||||
func (state *getCommitsInfoState) getTargetedEntryPath() string {
|
||||
var targetedEntryPath string
|
||||
state.lock.Lock()
|
||||
defer state.lock.Unlock()
|
||||
for _, entry := range state.entries {
|
||||
entryPath := path.Join(state.treePath, entry.Name())
|
||||
if _, ok := state.commits[entryPath]; ok {
|
||||
continue
|
||||
} else if _, ok = state.targetedPaths[entryPath]; ok {
|
||||
continue
|
||||
}
|
||||
targetedEntryPath = entryPath
|
||||
state.targetedPaths[entryPath] = struct{}{}
|
||||
break
|
||||
}
|
||||
return targetedEntryPath
|
||||
}
|
||||
|
||||
// repeatedly perform targeted searches for unpopulated entries
|
||||
func targetedSearch(state *getCommitsInfoState, done chan error) {
|
||||
for {
|
||||
entryPath := state.getTargetedEntryPath()
|
||||
if len(entryPath) == 0 {
|
||||
done <- nil
|
||||
return
|
||||
}
|
||||
command := NewCommand("rev-list", "-1", "HEAD", "--", entryPath)
|
||||
output, err := command.RunInDir(state.headCommit.repo.Path)
|
||||
if err != nil {
|
||||
done <- err
|
||||
return
|
||||
}
|
||||
id, err := NewIDFromString(strings.TrimSpace(output))
|
||||
if err != nil {
|
||||
done <- err
|
||||
return
|
||||
}
|
||||
commit, err := state.headCommit.repo.getCommit(id)
|
||||
if err != nil {
|
||||
done <- err
|
||||
return
|
||||
}
|
||||
state.update(entryPath, commit)
|
||||
}
|
||||
}
|
||||
|
||||
func initGetCommitInfoState(entries Entries, headCommit *Commit, treePath string) *getCommitsInfoState {
|
||||
entryPaths := make(map[string]struct{}, len(entries))
|
||||
for _, entry := range entries {
|
||||
entryPaths[path.Join(treePath, entry.Name())] = struct{}{}
|
||||
}
|
||||
if treePath = path.Clean(treePath); treePath == "." {
|
||||
treePath = ""
|
||||
}
|
||||
return &getCommitsInfoState{
|
||||
entries: entries,
|
||||
entryPaths: entryPaths,
|
||||
commits: make(map[string]*Commit, len(entries)),
|
||||
targetedPaths: make(map[string]struct{}, len(entries)),
|
||||
treePath: treePath,
|
||||
headCommit: headCommit,
|
||||
}
|
||||
}
|
||||
|
||||
// GetCommitsInfo gets information of all commits that are corresponding to these entries
|
||||
func (tes Entries) GetCommitsInfo(commit *Commit, treePath string) ([][]interface{}, error) {
|
||||
state := initGetCommitInfoState(tes, commit, treePath)
|
||||
if err := getCommitsInfo(state); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(state.commits) < len(state.entryPaths) {
|
||||
return nil, fmt.Errorf("could not find commits for all entries")
|
||||
}
|
||||
|
||||
commitsInfo := make([][]interface{}, len(tes))
|
||||
for i, entry := range tes {
|
||||
commit, ok := state.commits[path.Join(treePath, entry.Name())]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("could not find commit for %s", entry.Name())
|
||||
}
|
||||
switch entry.Type {
|
||||
case ObjectCommit:
|
||||
subModuleURL := ""
|
||||
if subModule, err := state.headCommit.GetSubModule(entry.Name()); err != nil {
|
||||
return nil, err
|
||||
} else if subModule != nil {
|
||||
subModuleURL = subModule.URL
|
||||
}
|
||||
subModuleFile := NewSubModuleFile(commit, subModuleURL, entry.ID.String())
|
||||
commitsInfo[i] = []interface{}{entry, subModuleFile}
|
||||
default:
|
||||
commitsInfo[i] = []interface{}{entry, commit}
|
||||
}
|
||||
}
|
||||
return commitsInfo, nil
|
||||
}
|
||||
|
||||
func (state *getCommitsInfoState) cleanEntryPath(rawEntryPath string) (string, error) {
|
||||
if rawEntryPath[0] == '"' {
|
||||
var err error
|
||||
rawEntryPath, err = strconv.Unquote(rawEntryPath)
|
||||
if err != nil {
|
||||
return rawEntryPath, err
|
||||
}
|
||||
}
|
||||
var entryNameStartIndex int
|
||||
if len(state.treePath) > 0 {
|
||||
entryNameStartIndex = len(state.treePath) + 1
|
||||
}
|
||||
|
||||
if index := strings.IndexByte(rawEntryPath[entryNameStartIndex:], '/'); index >= 0 {
|
||||
return rawEntryPath[:entryNameStartIndex+index], nil
|
||||
}
|
||||
return rawEntryPath, nil
|
||||
}
|
||||
|
||||
// update report that the given path was last modified by the given commit.
|
||||
// Returns whether state.commits was updated
|
||||
func (state *getCommitsInfoState) update(entryPath string, commit *Commit) bool {
|
||||
if _, ok := state.entryPaths[entryPath]; !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
var updated bool
|
||||
state.lock.Lock()
|
||||
defer state.lock.Unlock()
|
||||
if _, ok := state.commits[entryPath]; !ok {
|
||||
state.commits[entryPath] = commit
|
||||
updated = true
|
||||
}
|
||||
return updated
|
||||
}
|
||||
|
||||
const getCommitsInfoPretty = "--pretty=format:%H %ct %s"
|
||||
|
||||
func getCommitsInfo(state *getCommitsInfoState) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
args := []string{"log", getCommitsInfoPretty, "--name-status", "-c"}
|
||||
if len(state.treePath) > 0 {
|
||||
args = append(args, "--", state.treePath)
|
||||
}
|
||||
cmd := exec.CommandContext(ctx, "git", args...)
|
||||
cmd.Dir = state.headCommit.repo.Path
|
||||
|
||||
readCloser, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := cmd.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
numThreads := runtime.NumCPU()
|
||||
done := make(chan error, numThreads)
|
||||
for i := 0; i < numThreads; i++ {
|
||||
go targetedSearch(state, done)
|
||||
}
|
||||
|
||||
scanner := bufio.NewScanner(readCloser)
|
||||
err = state.processGitLogOutput(scanner)
|
||||
for i := 0; i < numThreads; i++ {
|
||||
doneErr := <-done
|
||||
if doneErr != nil && err == nil {
|
||||
err = doneErr
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (state *getCommitsInfoState) processGitLogOutput(scanner *bufio.Scanner) error {
|
||||
// keep a local cache of seen paths to avoid acquiring a lock for paths
|
||||
// we've already seen
|
||||
seenPaths := make(map[string]struct{}, len(state.entryPaths))
|
||||
// number of consecutive commits without any finds
|
||||
coldStreak := 0
|
||||
var commit *Commit
|
||||
var err error
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if len(line) == 0 { // in-between commits
|
||||
numRemainingEntries := state.numRemainingEntries()
|
||||
if numRemainingEntries == 0 {
|
||||
break
|
||||
}
|
||||
if coldStreak >= deferToTargetedSearchColdStreak &&
|
||||
numRemainingEntries <= deferToTargetedSearchNumRemainingEntries {
|
||||
// stop this untargeted search, and let the targeted-search threads
|
||||
// finish the work
|
||||
break
|
||||
}
|
||||
continue
|
||||
}
|
||||
if line[0] >= 'A' && line[0] <= 'X' { // a file was changed by the current commit
|
||||
// look for the last tab, since for copies (C) and renames (R) two
|
||||
// filenames are printed: src, then dest
|
||||
tabIndex := strings.LastIndexByte(line, '\t')
|
||||
if tabIndex < 1 {
|
||||
return fmt.Errorf("misformatted line: %s", line)
|
||||
}
|
||||
entryPath, err := state.cleanEntryPath(line[tabIndex+1:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, ok := seenPaths[entryPath]; !ok {
|
||||
if state.update(entryPath, commit) {
|
||||
coldStreak = 0
|
||||
}
|
||||
seenPaths[entryPath] = struct{}{}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// a new commit
|
||||
commit, err = parseCommitInfo(line)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
coldStreak++
|
||||
}
|
||||
return scanner.Err()
|
||||
}
|
||||
|
||||
// parseCommitInfo parse a commit from a line of `git log` output. Expects the
|
||||
// line to be formatted according to getCommitsInfoPretty.
|
||||
func parseCommitInfo(line string) (*Commit, error) {
|
||||
if len(line) < 43 {
|
||||
return nil, fmt.Errorf("invalid git output: %s", line)
|
||||
}
|
||||
ref, err := NewIDFromString(line[:40])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
spaceIndex := strings.IndexByte(line[41:], ' ')
|
||||
if spaceIndex < 0 {
|
||||
return nil, fmt.Errorf("invalid git output: %s", line)
|
||||
}
|
||||
unixSeconds, err := strconv.Atoi(line[41 : 41+spaceIndex])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
message := line[spaceIndex+42:]
|
||||
return &Commit{
|
||||
ID: ref,
|
||||
CommitMessage: message,
|
||||
Committer: &Signature{
|
||||
When: time.Unix(int64(unixSeconds), 0),
|
||||
},
|
||||
}, nil
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
// Copyright (c) 2015 Dave Collins <dave@davec.name>
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
// NOTE: Due to the following build constraints, this file will only be compiled
|
||||
// when the code is running on Google App Engine, compiled by GopherJS, or
|
||||
// "-tags safe" is added to the go build command line. The "disableunsafe"
|
||||
// tag is deprecated and thus should not be used.
|
||||
// +build js appengine safe disableunsafe
|
||||
|
||||
package spew
|
||||
|
||||
import "reflect"
|
||||
|
||||
const (
|
||||
// UnsafeDisabled is a build-time constant which specifies whether or
|
||||
// not access to the unsafe package is available.
|
||||
UnsafeDisabled = true
|
||||
)
|
||||
|
||||
// unsafeReflectValue typically converts the passed reflect.Value into a one
|
||||
// that bypasses the typical safety restrictions preventing access to
|
||||
// unaddressable and unexported data. However, doing this relies on access to
|
||||
// the unsafe package. This is a stub version which simply returns the passed
|
||||
// reflect.Value when the unsafe package is not available.
|
||||
func unsafeReflectValue(v reflect.Value) reflect.Value {
|
||||
return v
|
||||
}
|
@ -0,0 +1,379 @@
|
||||
/*
|
||||
* 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...)...)
|
||||
}
|
||||
|
||||
// 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 is 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...)...)
|
||||
}
|
||||
|
||||
// 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{}) bool {
|
||||
return HTTPBodyContains(t, handler, method, url, values, str)
|
||||
}
|
||||
|
||||
// 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{}) bool {
|
||||
return HTTPBodyNotContains(t, handler, method, url, values, str)
|
||||
}
|
||||
|
||||
// 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) bool {
|
||||
return HTTPError(t, handler, method, url, values)
|
||||
}
|
||||
|
||||
// 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) bool {
|
||||
return HTTPRedirect(t, handler, method, url, values)
|
||||
}
|
||||
|
||||
// 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) bool {
|
||||
return HTTPSuccess(t, handler, method, url, values)
|
||||
}
|
||||
|
||||
// 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...)...)
|
||||
}
|
||||
|
||||
// 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")
|
||||