Phase 2: Implement Execution Environment Abstraction (v0.3.0)
This commit implements Phase 2 of the CHORUS Task Execution Engine development plan, providing a comprehensive execution environment abstraction layer with Docker container sandboxing support. ## New Features ### Core Sandbox Interface - Comprehensive ExecutionSandbox interface with isolated task execution - Support for command execution, file I/O, environment management - Resource usage monitoring and sandbox lifecycle management - Standardized error handling with SandboxError types and categories ### Docker Container Sandbox Implementation - Full Docker API integration with secure container creation - Transparent repository mounting with configurable read/write access - Advanced security policies with capability dropping and privilege controls - Comprehensive resource limits (CPU, memory, disk, processes, file handles) - Support for tmpfs mounts, masked paths, and read-only bind mounts - Container lifecycle management with proper cleanup and health monitoring ### Security & Resource Management - Configurable security policies with SELinux, AppArmor, and Seccomp support - Fine-grained capability management with secure defaults - Network isolation options with configurable DNS and proxy settings - Resource monitoring with real-time CPU, memory, and network usage tracking - Comprehensive ulimits configuration for process and file handle limits ### Repository Integration - Seamless repository mounting from local paths to container workspaces - Git configuration support with user credentials and global settings - File inclusion/exclusion patterns for selective repository access - Configurable permissions and ownership for mounted repositories ### Testing Infrastructure - Comprehensive test suite with 60+ test cases covering all functionality - Docker integration tests with Alpine Linux containers (skipped in short mode) - Mock sandbox implementation for unit testing without Docker dependencies - Security policy validation tests with read-only filesystem enforcement - Resource usage monitoring and cleanup verification tests ## Technical Details ### Dependencies Added - github.com/docker/docker v28.4.0+incompatible - Docker API client - github.com/docker/go-connections v0.6.0 - Docker connection utilities - github.com/docker/go-units v0.5.0 - Docker units and formatting - Associated Docker API dependencies for complete container management ### Architecture - Interface-driven design enabling multiple sandbox implementations - Comprehensive configuration structures for all sandbox aspects - Resource usage tracking with detailed metrics collection - Error handling with retryable error classification - Proper cleanup and resource management throughout sandbox lifecycle ### Compatibility - Maintains backward compatibility with existing CHORUS architecture - Designed for future integration with Phase 3 Core Task Execution Engine - Extensible design supporting additional sandbox implementations (VM, process) This Phase 2 implementation provides the foundation for secure, isolated task execution that will be integrated with the AI model providers from Phase 1 in the upcoming Phase 3 development. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
22
vendor/github.com/stretchr/testify/assert/assertion_compare.go
generated
vendored
22
vendor/github.com/stretchr/testify/assert/assertion_compare.go
generated
vendored
@@ -390,7 +390,8 @@ func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return compareTwoValues(t, e1, e2, []compareResult{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs...)
|
||||
failMessage := fmt.Sprintf("\"%v\" is not greater than \"%v\"", e1, e2)
|
||||
return compareTwoValues(t, e1, e2, []compareResult{compareGreater}, failMessage, msgAndArgs...)
|
||||
}
|
||||
|
||||
// GreaterOrEqual asserts that the first element is greater than or equal to the second
|
||||
@@ -403,7 +404,8 @@ func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...in
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return compareTwoValues(t, e1, e2, []compareResult{compareGreater, compareEqual}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs...)
|
||||
failMessage := fmt.Sprintf("\"%v\" is not greater than or equal to \"%v\"", e1, e2)
|
||||
return compareTwoValues(t, e1, e2, []compareResult{compareGreater, compareEqual}, failMessage, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Less asserts that the first element is less than the second
|
||||
@@ -415,7 +417,8 @@ func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{})
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return compareTwoValues(t, e1, e2, []compareResult{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs...)
|
||||
failMessage := fmt.Sprintf("\"%v\" is not less than \"%v\"", e1, e2)
|
||||
return compareTwoValues(t, e1, e2, []compareResult{compareLess}, failMessage, msgAndArgs...)
|
||||
}
|
||||
|
||||
// LessOrEqual asserts that the first element is less than or equal to the second
|
||||
@@ -428,7 +431,8 @@ func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...inter
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return compareTwoValues(t, e1, e2, []compareResult{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs...)
|
||||
failMessage := fmt.Sprintf("\"%v\" is not less than or equal to \"%v\"", e1, e2)
|
||||
return compareTwoValues(t, e1, e2, []compareResult{compareLess, compareEqual}, failMessage, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Positive asserts that the specified element is positive
|
||||
@@ -440,7 +444,8 @@ func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) bool {
|
||||
h.Helper()
|
||||
}
|
||||
zero := reflect.Zero(reflect.TypeOf(e))
|
||||
return compareTwoValues(t, e, zero.Interface(), []compareResult{compareGreater}, "\"%v\" is not positive", msgAndArgs...)
|
||||
failMessage := fmt.Sprintf("\"%v\" is not positive", e)
|
||||
return compareTwoValues(t, e, zero.Interface(), []compareResult{compareGreater}, failMessage, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Negative asserts that the specified element is negative
|
||||
@@ -452,7 +457,8 @@ func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) bool {
|
||||
h.Helper()
|
||||
}
|
||||
zero := reflect.Zero(reflect.TypeOf(e))
|
||||
return compareTwoValues(t, e, zero.Interface(), []compareResult{compareLess}, "\"%v\" is not negative", msgAndArgs...)
|
||||
failMessage := fmt.Sprintf("\"%v\" is not negative", e)
|
||||
return compareTwoValues(t, e, zero.Interface(), []compareResult{compareLess}, failMessage, msgAndArgs...)
|
||||
}
|
||||
|
||||
func compareTwoValues(t TestingT, e1 interface{}, e2 interface{}, allowedComparesResults []compareResult, failMessage string, msgAndArgs ...interface{}) bool {
|
||||
@@ -468,11 +474,11 @@ func compareTwoValues(t TestingT, e1 interface{}, e2 interface{}, allowedCompare
|
||||
|
||||
compareResult, isComparable := compare(e1, e2, e1Kind)
|
||||
if !isComparable {
|
||||
return Fail(t, fmt.Sprintf("Can not compare type \"%s\"", reflect.TypeOf(e1)), msgAndArgs...)
|
||||
return Fail(t, fmt.Sprintf(`Can not compare type "%T"`, e1), msgAndArgs...)
|
||||
}
|
||||
|
||||
if !containsValue(allowedComparesResults, compareResult) {
|
||||
return Fail(t, fmt.Sprintf(failMessage, e1, e2), msgAndArgs...)
|
||||
return Fail(t, failMessage, msgAndArgs...)
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
51
vendor/github.com/stretchr/testify/assert/assertion_format.go
generated
vendored
51
vendor/github.com/stretchr/testify/assert/assertion_format.go
generated
vendored
@@ -50,10 +50,19 @@ func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string
|
||||
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.
|
||||
// Emptyf asserts that the given value is "empty".
|
||||
//
|
||||
// [Zero values] are "empty".
|
||||
//
|
||||
// Arrays are "empty" if every element is the zero value of the type (stricter than "empty").
|
||||
//
|
||||
// Slices, maps and channels with zero length are "empty".
|
||||
//
|
||||
// Pointer values are "empty" if the pointer is nil or if the pointed value is "empty".
|
||||
//
|
||||
// assert.Emptyf(t, obj, "error message %s", "formatted")
|
||||
//
|
||||
// [Zero values]: https://go.dev/ref/spec#The_zero_value
|
||||
func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -117,10 +126,8 @@ func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg stri
|
||||
|
||||
// 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)
|
||||
// }
|
||||
// actualObj, err := SomeFunction()
|
||||
// assert.Errorf(t, err, "error message %s", "formatted")
|
||||
func Errorf(t TestingT, err error, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -438,7 +445,19 @@ func IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interf
|
||||
return IsNonIncreasing(t, object, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// IsNotTypef asserts that the specified objects are not of the same type.
|
||||
//
|
||||
// assert.IsNotTypef(t, &NotMyStruct{}, &MyStruct{}, "error message %s", "formatted")
|
||||
func IsNotTypef(t TestingT, theType interface{}, object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return IsNotType(t, theType, object, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// IsTypef asserts that the specified objects are of the same type.
|
||||
//
|
||||
// assert.IsTypef(t, &MyStruct{}, &MyStruct{}, "error message %s", "formatted")
|
||||
func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -585,8 +604,7 @@ func NotElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg str
|
||||
return NotElementsMatch(t, listA, listB, 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.
|
||||
// NotEmptyf asserts that the specified object is NOT [Empty].
|
||||
//
|
||||
// if assert.NotEmptyf(t, obj, "error message %s", "formatted") {
|
||||
// assert.Equal(t, "two", obj[1])
|
||||
@@ -693,12 +711,15 @@ func NotSamef(t TestingT, expected interface{}, actual interface{}, msg string,
|
||||
return NotSame(t, expected, actual, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// NotSubsetf asserts that the specified list(array, slice...) or map does NOT
|
||||
// contain all elements given in the specified subset list(array, slice...) or
|
||||
// map.
|
||||
// NotSubsetf asserts that the list (array, slice, or map) does NOT contain all
|
||||
// elements given in the subset (array, slice, or map).
|
||||
// Map elements are key-value pairs unless compared with an array or slice where
|
||||
// only the map key is evaluated.
|
||||
//
|
||||
// assert.NotSubsetf(t, [1, 3, 4], [1, 2], "error message %s", "formatted")
|
||||
// assert.NotSubsetf(t, {"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted")
|
||||
// assert.NotSubsetf(t, [1, 3, 4], {1: "one", 2: "two"}, "error message %s", "formatted")
|
||||
// assert.NotSubsetf(t, {"x": 1, "y": 2}, ["z"], "error message %s", "formatted")
|
||||
func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -782,11 +803,15 @@ func Samef(t TestingT, expected interface{}, actual interface{}, msg string, arg
|
||||
return Same(t, expected, actual, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// Subsetf asserts that the specified list(array, slice...) or map contains all
|
||||
// elements given in the specified subset list(array, slice...) or map.
|
||||
// Subsetf asserts that the list (array, slice, or map) contains all elements
|
||||
// given in the subset (array, slice, or map).
|
||||
// Map elements are key-value pairs unless compared with an array or slice where
|
||||
// only the map key is evaluated.
|
||||
//
|
||||
// assert.Subsetf(t, [1, 2, 3], [1, 2], "error message %s", "formatted")
|
||||
// assert.Subsetf(t, {"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted")
|
||||
// assert.Subsetf(t, [1, 2, 3], {1: "one", 2: "two"}, "error message %s", "formatted")
|
||||
// assert.Subsetf(t, {"x": 1, "y": 2}, ["x"], "error message %s", "formatted")
|
||||
func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
|
||||
102
vendor/github.com/stretchr/testify/assert/assertion_forward.go
generated
vendored
102
vendor/github.com/stretchr/testify/assert/assertion_forward.go
generated
vendored
@@ -92,10 +92,19 @@ func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg st
|
||||
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.
|
||||
// Empty asserts that the given value is "empty".
|
||||
//
|
||||
// [Zero values] are "empty".
|
||||
//
|
||||
// Arrays are "empty" if every element is the zero value of the type (stricter than "empty").
|
||||
//
|
||||
// Slices, maps and channels with zero length are "empty".
|
||||
//
|
||||
// Pointer values are "empty" if the pointer is nil or if the pointed value is "empty".
|
||||
//
|
||||
// a.Empty(obj)
|
||||
//
|
||||
// [Zero values]: https://go.dev/ref/spec#The_zero_value
|
||||
func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -103,10 +112,19 @@ 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.
|
||||
// Emptyf asserts that the given value is "empty".
|
||||
//
|
||||
// [Zero values] are "empty".
|
||||
//
|
||||
// Arrays are "empty" if every element is the zero value of the type (stricter than "empty").
|
||||
//
|
||||
// Slices, maps and channels with zero length are "empty".
|
||||
//
|
||||
// Pointer values are "empty" if the pointer is nil or if the pointed value is "empty".
|
||||
//
|
||||
// a.Emptyf(obj, "error message %s", "formatted")
|
||||
//
|
||||
// [Zero values]: https://go.dev/ref/spec#The_zero_value
|
||||
func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -224,10 +242,8 @@ func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string
|
||||
|
||||
// Error asserts that a function returned an error (i.e. not `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// if a.Error(err) {
|
||||
// assert.Equal(t, expectedError, err)
|
||||
// }
|
||||
// actualObj, err := SomeFunction()
|
||||
// a.Error(err)
|
||||
func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -297,10 +313,8 @@ func (a *Assertions) ErrorIsf(err error, target error, msg string, args ...inter
|
||||
|
||||
// Errorf asserts that a function returned an error (i.e. not `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// if a.Errorf(err, "error message %s", "formatted") {
|
||||
// assert.Equal(t, expectedErrorf, err)
|
||||
// }
|
||||
// actualObj, err := SomeFunction()
|
||||
// a.Errorf(err, "error message %s", "formatted")
|
||||
func (a *Assertions) Errorf(err error, msg string, args ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -868,7 +882,29 @@ func (a *Assertions) IsNonIncreasingf(object interface{}, msg string, args ...in
|
||||
return IsNonIncreasingf(a.t, object, msg, args...)
|
||||
}
|
||||
|
||||
// IsNotType asserts that the specified objects are not of the same type.
|
||||
//
|
||||
// a.IsNotType(&NotMyStruct{}, &MyStruct{})
|
||||
func (a *Assertions) IsNotType(theType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return IsNotType(a.t, theType, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// IsNotTypef asserts that the specified objects are not of the same type.
|
||||
//
|
||||
// a.IsNotTypef(&NotMyStruct{}, &MyStruct{}, "error message %s", "formatted")
|
||||
func (a *Assertions) IsNotTypef(theType interface{}, object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return IsNotTypef(a.t, theType, object, msg, args...)
|
||||
}
|
||||
|
||||
// IsType asserts that the specified objects are of the same type.
|
||||
//
|
||||
// a.IsType(&MyStruct{}, &MyStruct{})
|
||||
func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -877,6 +913,8 @@ func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAnd
|
||||
}
|
||||
|
||||
// IsTypef asserts that the specified objects are of the same type.
|
||||
//
|
||||
// a.IsTypef(&MyStruct{}, &MyStruct{}, "error message %s", "formatted")
|
||||
func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -1162,8 +1200,7 @@ func (a *Assertions) NotElementsMatchf(listA interface{}, listB interface{}, msg
|
||||
return NotElementsMatchf(a.t, listA, listB, 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.
|
||||
// NotEmpty asserts that the specified object is NOT [Empty].
|
||||
//
|
||||
// if a.NotEmpty(obj) {
|
||||
// assert.Equal(t, "two", obj[1])
|
||||
@@ -1175,8 +1212,7 @@ 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.
|
||||
// NotEmptyf asserts that the specified object is NOT [Empty].
|
||||
//
|
||||
// if a.NotEmptyf(obj, "error message %s", "formatted") {
|
||||
// assert.Equal(t, "two", obj[1])
|
||||
@@ -1378,12 +1414,15 @@ func (a *Assertions) NotSamef(expected interface{}, actual interface{}, msg stri
|
||||
return NotSamef(a.t, expected, actual, msg, args...)
|
||||
}
|
||||
|
||||
// NotSubset asserts that the specified list(array, slice...) or map does NOT
|
||||
// contain all elements given in the specified subset list(array, slice...) or
|
||||
// map.
|
||||
// NotSubset asserts that the list (array, slice, or map) does NOT contain all
|
||||
// elements given in the subset (array, slice, or map).
|
||||
// Map elements are key-value pairs unless compared with an array or slice where
|
||||
// only the map key is evaluated.
|
||||
//
|
||||
// a.NotSubset([1, 3, 4], [1, 2])
|
||||
// a.NotSubset({"x": 1, "y": 2}, {"z": 3})
|
||||
// a.NotSubset([1, 3, 4], {1: "one", 2: "two"})
|
||||
// a.NotSubset({"x": 1, "y": 2}, ["z"])
|
||||
func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -1391,12 +1430,15 @@ func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs
|
||||
return NotSubset(a.t, list, subset, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotSubsetf asserts that the specified list(array, slice...) or map does NOT
|
||||
// contain all elements given in the specified subset list(array, slice...) or
|
||||
// map.
|
||||
// NotSubsetf asserts that the list (array, slice, or map) does NOT contain all
|
||||
// elements given in the subset (array, slice, or map).
|
||||
// Map elements are key-value pairs unless compared with an array or slice where
|
||||
// only the map key is evaluated.
|
||||
//
|
||||
// a.NotSubsetf([1, 3, 4], [1, 2], "error message %s", "formatted")
|
||||
// a.NotSubsetf({"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted")
|
||||
// a.NotSubsetf([1, 3, 4], {1: "one", 2: "two"}, "error message %s", "formatted")
|
||||
// a.NotSubsetf({"x": 1, "y": 2}, ["z"], "error message %s", "formatted")
|
||||
func (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -1556,11 +1598,15 @@ func (a *Assertions) Samef(expected interface{}, actual interface{}, msg string,
|
||||
return Samef(a.t, expected, actual, msg, args...)
|
||||
}
|
||||
|
||||
// Subset asserts that the specified list(array, slice...) or map contains all
|
||||
// elements given in the specified subset list(array, slice...) or map.
|
||||
// Subset asserts that the list (array, slice, or map) contains all elements
|
||||
// given in the subset (array, slice, or map).
|
||||
// Map elements are key-value pairs unless compared with an array or slice where
|
||||
// only the map key is evaluated.
|
||||
//
|
||||
// a.Subset([1, 2, 3], [1, 2])
|
||||
// a.Subset({"x": 1, "y": 2}, {"x": 1})
|
||||
// a.Subset([1, 2, 3], {1: "one", 2: "two"})
|
||||
// a.Subset({"x": 1, "y": 2}, ["x"])
|
||||
func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -1568,11 +1614,15 @@ func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...
|
||||
return Subset(a.t, list, subset, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Subsetf asserts that the specified list(array, slice...) or map contains all
|
||||
// elements given in the specified subset list(array, slice...) or map.
|
||||
// Subsetf asserts that the list (array, slice, or map) contains all elements
|
||||
// given in the subset (array, slice, or map).
|
||||
// Map elements are key-value pairs unless compared with an array or slice where
|
||||
// only the map key is evaluated.
|
||||
//
|
||||
// a.Subsetf([1, 2, 3], [1, 2], "error message %s", "formatted")
|
||||
// a.Subsetf({"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted")
|
||||
// a.Subsetf([1, 2, 3], {1: "one", 2: "two"}, "error message %s", "formatted")
|
||||
// a.Subsetf({"x": 1, "y": 2}, ["x"], "error message %s", "formatted")
|
||||
func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
|
||||
2
vendor/github.com/stretchr/testify/assert/assertion_order.go
generated
vendored
2
vendor/github.com/stretchr/testify/assert/assertion_order.go
generated
vendored
@@ -33,7 +33,7 @@ func isOrdered(t TestingT, object interface{}, allowedComparesResults []compareR
|
||||
compareResult, isComparable := compare(prevValueInterface, valueInterface, firstValueKind)
|
||||
|
||||
if !isComparable {
|
||||
return Fail(t, fmt.Sprintf("Can not compare type \"%s\" and \"%s\"", reflect.TypeOf(value), reflect.TypeOf(prevValue)), msgAndArgs...)
|
||||
return Fail(t, fmt.Sprintf(`Can not compare type "%T" and "%T"`, value, prevValue), msgAndArgs...)
|
||||
}
|
||||
|
||||
if !containsValue(allowedComparesResults, compareResult) {
|
||||
|
||||
379
vendor/github.com/stretchr/testify/assert/assertions.go
generated
vendored
379
vendor/github.com/stretchr/testify/assert/assertions.go
generated
vendored
@@ -210,59 +210,77 @@ the problem actually occurred in calling code.*/
|
||||
// of each stack frame leading from the current test to the assert call that
|
||||
// failed.
|
||||
func CallerInfo() []string {
|
||||
|
||||
var pc uintptr
|
||||
var ok bool
|
||||
var file string
|
||||
var line int
|
||||
var name string
|
||||
|
||||
const stackFrameBufferSize = 10
|
||||
pcs := make([]uintptr, stackFrameBufferSize)
|
||||
|
||||
callers := []string{}
|
||||
for i := 0; ; i++ {
|
||||
pc, file, line, ok = runtime.Caller(i)
|
||||
if !ok {
|
||||
// The breaks below failed to terminate the loop, and we ran off the
|
||||
// end of the call stack.
|
||||
offset := 1
|
||||
|
||||
for {
|
||||
n := runtime.Callers(offset, pcs)
|
||||
|
||||
if n == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
// This is a huge edge case, but it will panic if this is the case, see #180
|
||||
if file == "<autogenerated>" {
|
||||
break
|
||||
}
|
||||
frames := runtime.CallersFrames(pcs[:n])
|
||||
|
||||
f := runtime.FuncForPC(pc)
|
||||
if f == nil {
|
||||
break
|
||||
}
|
||||
name = f.Name()
|
||||
for {
|
||||
frame, more := frames.Next()
|
||||
pc = frame.PC
|
||||
file = frame.File
|
||||
line = frame.Line
|
||||
|
||||
// testing.tRunner is the standard library function that calls
|
||||
// tests. Subtests are called directly by tRunner, without going through
|
||||
// the Test/Benchmark/Example function that contains the t.Run calls, so
|
||||
// with subtests we should break when we hit tRunner, without adding it
|
||||
// to the list of callers.
|
||||
if name == "testing.tRunner" {
|
||||
break
|
||||
}
|
||||
// This is a huge edge case, but it will panic if this is the case, see #180
|
||||
if file == "<autogenerated>" {
|
||||
break
|
||||
}
|
||||
|
||||
parts := strings.Split(file, "/")
|
||||
if len(parts) > 1 {
|
||||
filename := parts[len(parts)-1]
|
||||
dir := parts[len(parts)-2]
|
||||
if (dir != "assert" && dir != "mock" && dir != "require") || filename == "mock_test.go" {
|
||||
callers = append(callers, fmt.Sprintf("%s:%d", file, line))
|
||||
f := runtime.FuncForPC(pc)
|
||||
if f == nil {
|
||||
break
|
||||
}
|
||||
name = f.Name()
|
||||
|
||||
// testing.tRunner is the standard library function that calls
|
||||
// tests. Subtests are called directly by tRunner, without going through
|
||||
// the Test/Benchmark/Example function that contains the t.Run calls, so
|
||||
// with subtests we should break when we hit tRunner, without adding it
|
||||
// to the list of callers.
|
||||
if name == "testing.tRunner" {
|
||||
break
|
||||
}
|
||||
|
||||
parts := strings.Split(file, "/")
|
||||
if len(parts) > 1 {
|
||||
filename := parts[len(parts)-1]
|
||||
dir := parts[len(parts)-2]
|
||||
if (dir != "assert" && dir != "mock" && dir != "require") || filename == "mock_test.go" {
|
||||
callers = append(callers, fmt.Sprintf("%s:%d", file, line))
|
||||
}
|
||||
}
|
||||
|
||||
// Drop the package
|
||||
dotPos := strings.LastIndexByte(name, '.')
|
||||
name = name[dotPos+1:]
|
||||
if isTest(name, "Test") ||
|
||||
isTest(name, "Benchmark") ||
|
||||
isTest(name, "Example") {
|
||||
break
|
||||
}
|
||||
|
||||
if !more {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Drop the package
|
||||
segments := strings.Split(name, ".")
|
||||
name = segments[len(segments)-1]
|
||||
if isTest(name, "Test") ||
|
||||
isTest(name, "Benchmark") ||
|
||||
isTest(name, "Example") {
|
||||
break
|
||||
}
|
||||
// Next batch
|
||||
offset += cap(pcs)
|
||||
}
|
||||
|
||||
return callers
|
||||
@@ -437,17 +455,34 @@ func NotImplements(t TestingT, interfaceObject interface{}, object interface{},
|
||||
return true
|
||||
}
|
||||
|
||||
func isType(expectedType, object interface{}) bool {
|
||||
return ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType))
|
||||
}
|
||||
|
||||
// IsType asserts that the specified objects are of the same type.
|
||||
func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
//
|
||||
// assert.IsType(t, &MyStruct{}, &MyStruct{})
|
||||
func IsType(t TestingT, expectedType, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
if isType(expectedType, object) {
|
||||
return true
|
||||
}
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return Fail(t, fmt.Sprintf("Object expected to be of type %T, but was %T", expectedType, object), msgAndArgs...)
|
||||
}
|
||||
|
||||
if !ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType)) {
|
||||
return Fail(t, fmt.Sprintf("Object expected to be of type %v, but was %v", reflect.TypeOf(expectedType), reflect.TypeOf(object)), msgAndArgs...)
|
||||
// IsNotType asserts that the specified objects are not of the same type.
|
||||
//
|
||||
// assert.IsNotType(t, &NotMyStruct{}, &MyStruct{})
|
||||
func IsNotType(t TestingT, theType, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
if !isType(theType, object) {
|
||||
return true
|
||||
}
|
||||
|
||||
return true
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return Fail(t, fmt.Sprintf("Object type expected to be different than %T", theType), msgAndArgs...)
|
||||
}
|
||||
|
||||
// Equal asserts that two objects are equal.
|
||||
@@ -475,7 +510,6 @@ func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{})
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
// validateEqualArgs checks whether provided arguments can be safely used in the
|
||||
@@ -510,8 +544,9 @@ func Same(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) b
|
||||
if !same {
|
||||
// both are pointers but not the same type & pointing to the same address
|
||||
return Fail(t, fmt.Sprintf("Not same: \n"+
|
||||
"expected: %p %#v\n"+
|
||||
"actual : %p %#v", expected, expected, actual, actual), msgAndArgs...)
|
||||
"expected: %p %#[1]v\n"+
|
||||
"actual : %p %#[2]v",
|
||||
expected, actual), msgAndArgs...)
|
||||
}
|
||||
|
||||
return true
|
||||
@@ -530,14 +565,14 @@ func NotSame(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}
|
||||
|
||||
same, ok := samePointers(expected, actual)
|
||||
if !ok {
|
||||
//fails when the arguments are not pointers
|
||||
// fails when the arguments are not pointers
|
||||
return !(Fail(t, "Both arguments must be pointers", msgAndArgs...))
|
||||
}
|
||||
|
||||
if same {
|
||||
return Fail(t, fmt.Sprintf(
|
||||
"Expected and actual point to the same object: %p %#v",
|
||||
expected, expected), msgAndArgs...)
|
||||
"Expected and actual point to the same object: %p %#[1]v",
|
||||
expected), msgAndArgs...)
|
||||
}
|
||||
return true
|
||||
}
|
||||
@@ -549,7 +584,7 @@ func NotSame(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}
|
||||
func samePointers(first, second interface{}) (same bool, ok bool) {
|
||||
firstPtr, secondPtr := reflect.ValueOf(first), reflect.ValueOf(second)
|
||||
if firstPtr.Kind() != reflect.Ptr || secondPtr.Kind() != reflect.Ptr {
|
||||
return false, false //not both are pointers
|
||||
return false, false // not both are pointers
|
||||
}
|
||||
|
||||
firstType, secondType := reflect.TypeOf(first), reflect.TypeOf(second)
|
||||
@@ -610,7 +645,6 @@ func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interfa
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
// EqualExportedValues asserts that the types of two objects are equal and their public
|
||||
@@ -665,7 +699,6 @@ func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}
|
||||
}
|
||||
|
||||
return Equal(t, expected, actual, msgAndArgs...)
|
||||
|
||||
}
|
||||
|
||||
// NotNil asserts that the specified object is not nil.
|
||||
@@ -715,37 +748,45 @@ func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
objValue := reflect.ValueOf(object)
|
||||
|
||||
switch objValue.Kind() {
|
||||
// collection types are empty when they have no element
|
||||
case 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
|
||||
}
|
||||
deref := objValue.Elem().Interface()
|
||||
return isEmpty(deref)
|
||||
// for all other types, compare against the zero value
|
||||
// array types are empty when they match their zero-initialized state
|
||||
default:
|
||||
zero := reflect.Zero(objValue.Type())
|
||||
return reflect.DeepEqual(object, zero.Interface())
|
||||
}
|
||||
return isEmptyValue(reflect.ValueOf(object))
|
||||
}
|
||||
|
||||
// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
// isEmptyValue gets whether the specified reflect.Value is considered empty or not.
|
||||
func isEmptyValue(objValue reflect.Value) bool {
|
||||
if objValue.IsZero() {
|
||||
return true
|
||||
}
|
||||
// Special cases of non-zero values that we consider empty
|
||||
switch objValue.Kind() {
|
||||
// collection types are empty when they have no element
|
||||
// Note: array types are empty when they match their zero-initialized state.
|
||||
case reflect.Chan, reflect.Map, reflect.Slice:
|
||||
return objValue.Len() == 0
|
||||
// non-nil pointers are empty if the value they point to is empty
|
||||
case reflect.Ptr:
|
||||
return isEmptyValue(objValue.Elem())
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Empty asserts that the given value is "empty".
|
||||
//
|
||||
// [Zero values] are "empty".
|
||||
//
|
||||
// Arrays are "empty" if every element is the zero value of the type (stricter than "empty").
|
||||
//
|
||||
// Slices, maps and channels with zero length are "empty".
|
||||
//
|
||||
// Pointer values are "empty" if the pointer is nil or if the pointed value is "empty".
|
||||
//
|
||||
// assert.Empty(t, obj)
|
||||
//
|
||||
// [Zero values]: https://go.dev/ref/spec#The_zero_value
|
||||
func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
pass := isEmpty(object)
|
||||
if !pass {
|
||||
@@ -756,11 +797,9 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
}
|
||||
|
||||
return pass
|
||||
|
||||
}
|
||||
|
||||
// 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.
|
||||
// NotEmpty asserts that the specified object is NOT [Empty].
|
||||
//
|
||||
// if assert.NotEmpty(t, obj) {
|
||||
// assert.Equal(t, "two", obj[1])
|
||||
@@ -775,7 +814,6 @@ func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
}
|
||||
|
||||
return pass
|
||||
|
||||
}
|
||||
|
||||
// getLen tries to get the length of an object.
|
||||
@@ -819,7 +857,6 @@ func True(t TestingT, value bool, msgAndArgs ...interface{}) bool {
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
// False asserts that the specified value is false.
|
||||
@@ -834,7 +871,6 @@ func False(t TestingT, value bool, msgAndArgs ...interface{}) bool {
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
// NotEqual asserts that the specified values are NOT equal.
|
||||
@@ -857,7 +893,6 @@ func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
// NotEqualValues asserts that two objects are not equal even when converted to the same type
|
||||
@@ -880,7 +915,6 @@ func NotEqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...inte
|
||||
// return (true, false) if element was not found.
|
||||
// return (true, true) if element was found.
|
||||
func containsElement(list interface{}, element interface{}) (ok, found bool) {
|
||||
|
||||
listValue := reflect.ValueOf(list)
|
||||
listType := reflect.TypeOf(list)
|
||||
if listType == nil {
|
||||
@@ -915,7 +949,6 @@ func containsElement(list interface{}, element interface{}) (ok, found bool) {
|
||||
}
|
||||
}
|
||||
return true, false
|
||||
|
||||
}
|
||||
|
||||
// Contains asserts that the specified string, list(array, slice...) or map contains the
|
||||
@@ -938,7 +971,6 @@ func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bo
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the
|
||||
@@ -961,14 +993,17 @@ func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{})
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
// Subset asserts that the specified list(array, slice...) or map contains all
|
||||
// elements given in the specified subset list(array, slice...) or map.
|
||||
// Subset asserts that the list (array, slice, or map) contains all elements
|
||||
// given in the subset (array, slice, or map).
|
||||
// Map elements are key-value pairs unless compared with an array or slice where
|
||||
// only the map key is evaluated.
|
||||
//
|
||||
// assert.Subset(t, [1, 2, 3], [1, 2])
|
||||
// assert.Subset(t, {"x": 1, "y": 2}, {"x": 1})
|
||||
// assert.Subset(t, [1, 2, 3], {1: "one", 2: "two"})
|
||||
// assert.Subset(t, {"x": 1, "y": 2}, ["x"])
|
||||
func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -983,7 +1018,7 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok
|
||||
}
|
||||
|
||||
subsetKind := reflect.TypeOf(subset).Kind()
|
||||
if subsetKind != reflect.Array && subsetKind != reflect.Slice && listKind != reflect.Map {
|
||||
if subsetKind != reflect.Array && subsetKind != reflect.Slice && subsetKind != reflect.Map {
|
||||
return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...)
|
||||
}
|
||||
|
||||
@@ -1007,6 +1042,13 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok
|
||||
}
|
||||
|
||||
subsetList := reflect.ValueOf(subset)
|
||||
if subsetKind == reflect.Map {
|
||||
keys := make([]interface{}, subsetList.Len())
|
||||
for idx, key := range subsetList.MapKeys() {
|
||||
keys[idx] = key.Interface()
|
||||
}
|
||||
subsetList = reflect.ValueOf(keys)
|
||||
}
|
||||
for i := 0; i < subsetList.Len(); i++ {
|
||||
element := subsetList.Index(i).Interface()
|
||||
ok, found := containsElement(list, element)
|
||||
@@ -1021,12 +1063,15 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok
|
||||
return true
|
||||
}
|
||||
|
||||
// NotSubset asserts that the specified list(array, slice...) or map does NOT
|
||||
// contain all elements given in the specified subset list(array, slice...) or
|
||||
// map.
|
||||
// NotSubset asserts that the list (array, slice, or map) does NOT contain all
|
||||
// elements given in the subset (array, slice, or map).
|
||||
// Map elements are key-value pairs unless compared with an array or slice where
|
||||
// only the map key is evaluated.
|
||||
//
|
||||
// assert.NotSubset(t, [1, 3, 4], [1, 2])
|
||||
// assert.NotSubset(t, {"x": 1, "y": 2}, {"z": 3})
|
||||
// assert.NotSubset(t, [1, 3, 4], {1: "one", 2: "two"})
|
||||
// assert.NotSubset(t, {"x": 1, "y": 2}, ["z"])
|
||||
func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -1041,7 +1086,7 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{})
|
||||
}
|
||||
|
||||
subsetKind := reflect.TypeOf(subset).Kind()
|
||||
if subsetKind != reflect.Array && subsetKind != reflect.Slice && listKind != reflect.Map {
|
||||
if subsetKind != reflect.Array && subsetKind != reflect.Slice && subsetKind != reflect.Map {
|
||||
return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...)
|
||||
}
|
||||
|
||||
@@ -1065,11 +1110,18 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{})
|
||||
}
|
||||
|
||||
subsetList := reflect.ValueOf(subset)
|
||||
if subsetKind == reflect.Map {
|
||||
keys := make([]interface{}, subsetList.Len())
|
||||
for idx, key := range subsetList.MapKeys() {
|
||||
keys[idx] = key.Interface()
|
||||
}
|
||||
subsetList = reflect.ValueOf(keys)
|
||||
}
|
||||
for i := 0; i < subsetList.Len(); i++ {
|
||||
element := subsetList.Index(i).Interface()
|
||||
ok, found := containsElement(list, element)
|
||||
if !ok {
|
||||
return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", list), msgAndArgs...)
|
||||
return Fail(t, fmt.Sprintf("%q could not be applied builtin len()", list), msgAndArgs...)
|
||||
}
|
||||
if !found {
|
||||
return true
|
||||
@@ -1591,10 +1643,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) {
|
||||
// assert.Equal(t, expectedError, err)
|
||||
// }
|
||||
// actualObj, err := SomeFunction()
|
||||
// assert.Error(t, err)
|
||||
func Error(t TestingT, err error, msgAndArgs ...interface{}) bool {
|
||||
if err == nil {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
@@ -1667,7 +1717,6 @@ func matchRegexp(rx interface{}, str interface{}) bool {
|
||||
default:
|
||||
return r.MatchString(fmt.Sprint(v))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Regexp asserts that a specified regexp matches a string.
|
||||
@@ -1703,7 +1752,6 @@ func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interf
|
||||
}
|
||||
|
||||
return !match
|
||||
|
||||
}
|
||||
|
||||
// Zero asserts that i is the zero value for its type.
|
||||
@@ -1814,6 +1862,11 @@ func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{
|
||||
return Fail(t, fmt.Sprintf("Expected value ('%s') is not valid json.\nJSON parsing error: '%s'", expected, err.Error()), msgAndArgs...)
|
||||
}
|
||||
|
||||
// Shortcut if same bytes
|
||||
if actual == expected {
|
||||
return true
|
||||
}
|
||||
|
||||
if err := json.Unmarshal([]byte(actual), &actualJSONAsInterface); err != nil {
|
||||
return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid json.\nJSON parsing error: '%s'", actual, err.Error()), msgAndArgs...)
|
||||
}
|
||||
@@ -1832,6 +1885,11 @@ func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{
|
||||
return Fail(t, fmt.Sprintf("Expected value ('%s') is not valid yaml.\nYAML parsing error: '%s'", expected, err.Error()), msgAndArgs...)
|
||||
}
|
||||
|
||||
// Shortcut if same bytes
|
||||
if actual == expected {
|
||||
return true
|
||||
}
|
||||
|
||||
if err := yaml.Unmarshal([]byte(actual), &actualYAMLAsInterface); err != nil {
|
||||
return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid yaml.\nYAML error: '%s'", actual, err.Error()), msgAndArgs...)
|
||||
}
|
||||
@@ -1933,6 +1991,7 @@ func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick t
|
||||
}
|
||||
|
||||
ch := make(chan bool, 1)
|
||||
checkCond := func() { ch <- condition() }
|
||||
|
||||
timer := time.NewTimer(waitFor)
|
||||
defer timer.Stop()
|
||||
@@ -1940,18 +1999,23 @@ func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick t
|
||||
ticker := time.NewTicker(tick)
|
||||
defer ticker.Stop()
|
||||
|
||||
for tick := ticker.C; ; {
|
||||
var tickC <-chan time.Time
|
||||
|
||||
// Check the condition once first on the initial call.
|
||||
go checkCond()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-timer.C:
|
||||
return Fail(t, "Condition never satisfied", msgAndArgs...)
|
||||
case <-tick:
|
||||
tick = nil
|
||||
go func() { ch <- condition() }()
|
||||
case <-tickC:
|
||||
tickC = nil
|
||||
go checkCond()
|
||||
case v := <-ch:
|
||||
if v {
|
||||
return true
|
||||
}
|
||||
tick = ticker.C
|
||||
tickC = ticker.C
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1964,6 +2028,9 @@ type CollectT struct {
|
||||
errors []error
|
||||
}
|
||||
|
||||
// Helper is like [testing.T.Helper] but does nothing.
|
||||
func (CollectT) Helper() {}
|
||||
|
||||
// Errorf collects the error.
|
||||
func (c *CollectT) Errorf(format string, args ...interface{}) {
|
||||
c.errors = append(c.errors, fmt.Errorf(format, args...))
|
||||
@@ -2021,35 +2088,42 @@ func EventuallyWithT(t TestingT, condition func(collect *CollectT), waitFor time
|
||||
var lastFinishedTickErrs []error
|
||||
ch := make(chan *CollectT, 1)
|
||||
|
||||
checkCond := func() {
|
||||
collect := new(CollectT)
|
||||
defer func() {
|
||||
ch <- collect
|
||||
}()
|
||||
condition(collect)
|
||||
}
|
||||
|
||||
timer := time.NewTimer(waitFor)
|
||||
defer timer.Stop()
|
||||
|
||||
ticker := time.NewTicker(tick)
|
||||
defer ticker.Stop()
|
||||
|
||||
for tick := ticker.C; ; {
|
||||
var tickC <-chan time.Time
|
||||
|
||||
// Check the condition once first on the initial call.
|
||||
go checkCond()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-timer.C:
|
||||
for _, err := range lastFinishedTickErrs {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
return Fail(t, "Condition never satisfied", msgAndArgs...)
|
||||
case <-tick:
|
||||
tick = nil
|
||||
go func() {
|
||||
collect := new(CollectT)
|
||||
defer func() {
|
||||
ch <- collect
|
||||
}()
|
||||
condition(collect)
|
||||
}()
|
||||
case <-tickC:
|
||||
tickC = nil
|
||||
go checkCond()
|
||||
case collect := <-ch:
|
||||
if !collect.failed() {
|
||||
return true
|
||||
}
|
||||
// Keep the errors from the last ended condition, so that they can be copied to t if timeout is reached.
|
||||
lastFinishedTickErrs = collect.errors
|
||||
tick = ticker.C
|
||||
tickC = ticker.C
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2064,6 +2138,7 @@ func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.D
|
||||
}
|
||||
|
||||
ch := make(chan bool, 1)
|
||||
checkCond := func() { ch <- condition() }
|
||||
|
||||
timer := time.NewTimer(waitFor)
|
||||
defer timer.Stop()
|
||||
@@ -2071,18 +2146,23 @@ func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.D
|
||||
ticker := time.NewTicker(tick)
|
||||
defer ticker.Stop()
|
||||
|
||||
for tick := ticker.C; ; {
|
||||
var tickC <-chan time.Time
|
||||
|
||||
// Check the condition once first on the initial call.
|
||||
go checkCond()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-timer.C:
|
||||
return true
|
||||
case <-tick:
|
||||
tick = nil
|
||||
go func() { ch <- condition() }()
|
||||
case <-tickC:
|
||||
tickC = nil
|
||||
go checkCond()
|
||||
case v := <-ch:
|
||||
if v {
|
||||
return Fail(t, "Condition satisfied", msgAndArgs...)
|
||||
}
|
||||
tick = ticker.C
|
||||
tickC = ticker.C
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2100,9 +2180,12 @@ func ErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool {
|
||||
var expectedText string
|
||||
if target != nil {
|
||||
expectedText = target.Error()
|
||||
if err == nil {
|
||||
return Fail(t, fmt.Sprintf("Expected error with %q in chain but got nil.", expectedText), msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
chain := buildErrorChainString(err)
|
||||
chain := buildErrorChainString(err, false)
|
||||
|
||||
return Fail(t, fmt.Sprintf("Target error should be in err chain:\n"+
|
||||
"expected: %q\n"+
|
||||
@@ -2125,7 +2208,7 @@ func NotErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool {
|
||||
expectedText = target.Error()
|
||||
}
|
||||
|
||||
chain := buildErrorChainString(err)
|
||||
chain := buildErrorChainString(err, false)
|
||||
|
||||
return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+
|
||||
"found: %q\n"+
|
||||
@@ -2143,11 +2226,17 @@ func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{
|
||||
return true
|
||||
}
|
||||
|
||||
chain := buildErrorChainString(err)
|
||||
expectedType := reflect.TypeOf(target).Elem().String()
|
||||
if err == nil {
|
||||
return Fail(t, fmt.Sprintf("An error is expected but got nil.\n"+
|
||||
"expected: %s", expectedType), msgAndArgs...)
|
||||
}
|
||||
|
||||
chain := buildErrorChainString(err, true)
|
||||
|
||||
return Fail(t, fmt.Sprintf("Should be in error chain:\n"+
|
||||
"expected: %q\n"+
|
||||
"in chain: %s", target, chain,
|
||||
"expected: %s\n"+
|
||||
"in chain: %s", expectedType, chain,
|
||||
), msgAndArgs...)
|
||||
}
|
||||
|
||||
@@ -2161,24 +2250,46 @@ func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interfa
|
||||
return true
|
||||
}
|
||||
|
||||
chain := buildErrorChainString(err)
|
||||
chain := buildErrorChainString(err, true)
|
||||
|
||||
return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+
|
||||
"found: %q\n"+
|
||||
"in chain: %s", target, chain,
|
||||
"found: %s\n"+
|
||||
"in chain: %s", reflect.TypeOf(target).Elem().String(), chain,
|
||||
), msgAndArgs...)
|
||||
}
|
||||
|
||||
func buildErrorChainString(err error) string {
|
||||
func unwrapAll(err error) (errs []error) {
|
||||
errs = append(errs, err)
|
||||
switch x := err.(type) {
|
||||
case interface{ Unwrap() error }:
|
||||
err = x.Unwrap()
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
errs = append(errs, unwrapAll(err)...)
|
||||
case interface{ Unwrap() []error }:
|
||||
for _, err := range x.Unwrap() {
|
||||
errs = append(errs, unwrapAll(err)...)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func buildErrorChainString(err error, withType bool) string {
|
||||
if err == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
e := errors.Unwrap(err)
|
||||
chain := fmt.Sprintf("%q", err.Error())
|
||||
for e != nil {
|
||||
chain += fmt.Sprintf("\n\t%q", e.Error())
|
||||
e = errors.Unwrap(e)
|
||||
var chain string
|
||||
errs := unwrapAll(err)
|
||||
for i := range errs {
|
||||
if i != 0 {
|
||||
chain += "\n\t"
|
||||
}
|
||||
chain += fmt.Sprintf("%q", errs[i].Error())
|
||||
if withType {
|
||||
chain += fmt.Sprintf(" (%T)", errs[i])
|
||||
}
|
||||
}
|
||||
return chain
|
||||
}
|
||||
|
||||
4
vendor/github.com/stretchr/testify/assert/doc.go
generated
vendored
4
vendor/github.com/stretchr/testify/assert/doc.go
generated
vendored
@@ -1,5 +1,9 @@
|
||||
// Package assert provides a set of comprehensive testing tools for use with the normal Go testing system.
|
||||
//
|
||||
// # Note
|
||||
//
|
||||
// All functions in this package return a bool value indicating whether the assertion has passed.
|
||||
//
|
||||
// # Example Usage
|
||||
//
|
||||
// The following is a complete example using assert in a standard test function:
|
||||
|
||||
4
vendor/github.com/stretchr/testify/assert/http_assertions.go
generated
vendored
4
vendor/github.com/stretchr/testify/assert/http_assertions.go
generated
vendored
@@ -138,7 +138,7 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string,
|
||||
|
||||
contains := strings.Contains(body, fmt.Sprint(str))
|
||||
if !contains {
|
||||
Fail(t, fmt.Sprintf("Expected response body for \"%s\" to contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body), msgAndArgs...)
|
||||
Fail(t, fmt.Sprintf("Expected response body for %q to contain %q but found %q", url+"?"+values.Encode(), str, body), msgAndArgs...)
|
||||
}
|
||||
|
||||
return contains
|
||||
@@ -158,7 +158,7 @@ func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url strin
|
||||
|
||||
contains := strings.Contains(body, fmt.Sprint(str))
|
||||
if contains {
|
||||
Fail(t, fmt.Sprintf("Expected response body for \"%s\" to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body), msgAndArgs...)
|
||||
Fail(t, fmt.Sprintf("Expected response body for %q to NOT contain %q but found %q", url+"?"+values.Encode(), str, body), msgAndArgs...)
|
||||
}
|
||||
|
||||
return !contains
|
||||
|
||||
1
vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go
generated
vendored
1
vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go
generated
vendored
@@ -1,5 +1,4 @@
|
||||
//go:build testify_yaml_custom && !testify_yaml_fail && !testify_yaml_default
|
||||
// +build testify_yaml_custom,!testify_yaml_fail,!testify_yaml_default
|
||||
|
||||
// Package yaml is an implementation of YAML functions that calls a pluggable implementation.
|
||||
//
|
||||
|
||||
1
vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go
generated
vendored
1
vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go
generated
vendored
@@ -1,5 +1,4 @@
|
||||
//go:build !testify_yaml_fail && !testify_yaml_custom
|
||||
// +build !testify_yaml_fail,!testify_yaml_custom
|
||||
|
||||
// Package yaml is just an indirection to handle YAML deserialization.
|
||||
//
|
||||
|
||||
1
vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go
generated
vendored
1
vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go
generated
vendored
@@ -1,5 +1,4 @@
|
||||
//go:build testify_yaml_fail && !testify_yaml_custom && !testify_yaml_default
|
||||
// +build testify_yaml_fail,!testify_yaml_custom,!testify_yaml_default
|
||||
|
||||
// Package yaml is an implementation of YAML functions that always fail.
|
||||
//
|
||||
|
||||
2
vendor/github.com/stretchr/testify/require/doc.go
generated
vendored
2
vendor/github.com/stretchr/testify/require/doc.go
generated
vendored
@@ -23,6 +23,8 @@
|
||||
//
|
||||
// The `require` package have same global functions as in the `assert` package,
|
||||
// but instead of returning a boolean result they call `t.FailNow()`.
|
||||
// A consequence of this is that it must be called from the goroutine running
|
||||
// the test function, not from other goroutines created during the test.
|
||||
//
|
||||
// Every assertion function also takes an optional string message as the final argument,
|
||||
// allowing custom error messages to be appended to the message the assertion method outputs.
|
||||
|
||||
108
vendor/github.com/stretchr/testify/require/require.go
generated
vendored
108
vendor/github.com/stretchr/testify/require/require.go
generated
vendored
@@ -117,10 +117,19 @@ func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string
|
||||
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.
|
||||
// Empty asserts that the given value is "empty".
|
||||
//
|
||||
// [Zero values] are "empty".
|
||||
//
|
||||
// Arrays are "empty" if every element is the zero value of the type (stricter than "empty").
|
||||
//
|
||||
// Slices, maps and channels with zero length are "empty".
|
||||
//
|
||||
// Pointer values are "empty" if the pointer is nil or if the pointed value is "empty".
|
||||
//
|
||||
// require.Empty(t, obj)
|
||||
//
|
||||
// [Zero values]: https://go.dev/ref/spec#The_zero_value
|
||||
func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -131,10 +140,19 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) {
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
// Emptyf asserts that the given value is "empty".
|
||||
//
|
||||
// [Zero values] are "empty".
|
||||
//
|
||||
// Arrays are "empty" if every element is the zero value of the type (stricter than "empty").
|
||||
//
|
||||
// Slices, maps and channels with zero length are "empty".
|
||||
//
|
||||
// Pointer values are "empty" if the pointer is nil or if the pointed value is "empty".
|
||||
//
|
||||
// require.Emptyf(t, obj, "error message %s", "formatted")
|
||||
//
|
||||
// [Zero values]: https://go.dev/ref/spec#The_zero_value
|
||||
func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -279,10 +297,8 @@ func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, ar
|
||||
|
||||
// Error asserts that a function returned an error (i.e. not `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// if require.Error(t, err) {
|
||||
// require.Equal(t, expectedError, err)
|
||||
// }
|
||||
// actualObj, err := SomeFunction()
|
||||
// require.Error(t, err)
|
||||
func Error(t TestingT, err error, msgAndArgs ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -373,10 +389,8 @@ func ErrorIsf(t TestingT, err error, target error, msg string, args ...interface
|
||||
|
||||
// Errorf asserts that a function returned an error (i.e. not `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// if require.Errorf(t, err, "error message %s", "formatted") {
|
||||
// require.Equal(t, expectedErrorf, err)
|
||||
// }
|
||||
// actualObj, err := SomeFunction()
|
||||
// require.Errorf(t, err, "error message %s", "formatted")
|
||||
func Errorf(t TestingT, err error, msg string, args ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -1097,7 +1111,35 @@ func IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interf
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// IsNotType asserts that the specified objects are not of the same type.
|
||||
//
|
||||
// require.IsNotType(t, &NotMyStruct{}, &MyStruct{})
|
||||
func IsNotType(t TestingT, theType interface{}, object interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
if assert.IsNotType(t, theType, object, msgAndArgs...) {
|
||||
return
|
||||
}
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// IsNotTypef asserts that the specified objects are not of the same type.
|
||||
//
|
||||
// require.IsNotTypef(t, &NotMyStruct{}, &MyStruct{}, "error message %s", "formatted")
|
||||
func IsNotTypef(t TestingT, theType interface{}, object interface{}, msg string, args ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
if assert.IsNotTypef(t, theType, object, msg, args...) {
|
||||
return
|
||||
}
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// IsType asserts that the specified objects are of the same type.
|
||||
//
|
||||
// require.IsType(t, &MyStruct{}, &MyStruct{})
|
||||
func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -1109,6 +1151,8 @@ func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs
|
||||
}
|
||||
|
||||
// IsTypef asserts that the specified objects are of the same type.
|
||||
//
|
||||
// require.IsTypef(t, &MyStruct{}, &MyStruct{}, "error message %s", "formatted")
|
||||
func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -1469,8 +1513,7 @@ func NotElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg str
|
||||
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.
|
||||
// NotEmpty asserts that the specified object is NOT [Empty].
|
||||
//
|
||||
// if require.NotEmpty(t, obj) {
|
||||
// require.Equal(t, "two", obj[1])
|
||||
@@ -1485,8 +1528,7 @@ func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) {
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// 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.
|
||||
// NotEmptyf asserts that the specified object is NOT [Empty].
|
||||
//
|
||||
// if require.NotEmptyf(t, obj, "error message %s", "formatted") {
|
||||
// require.Equal(t, "two", obj[1])
|
||||
@@ -1745,12 +1787,15 @@ func NotSamef(t TestingT, expected interface{}, actual interface{}, msg string,
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// NotSubset asserts that the specified list(array, slice...) or map does NOT
|
||||
// contain all elements given in the specified subset list(array, slice...) or
|
||||
// map.
|
||||
// NotSubset asserts that the list (array, slice, or map) does NOT contain all
|
||||
// elements given in the subset (array, slice, or map).
|
||||
// Map elements are key-value pairs unless compared with an array or slice where
|
||||
// only the map key is evaluated.
|
||||
//
|
||||
// require.NotSubset(t, [1, 3, 4], [1, 2])
|
||||
// require.NotSubset(t, {"x": 1, "y": 2}, {"z": 3})
|
||||
// require.NotSubset(t, [1, 3, 4], {1: "one", 2: "two"})
|
||||
// require.NotSubset(t, {"x": 1, "y": 2}, ["z"])
|
||||
func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -1761,12 +1806,15 @@ func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...i
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// NotSubsetf asserts that the specified list(array, slice...) or map does NOT
|
||||
// contain all elements given in the specified subset list(array, slice...) or
|
||||
// map.
|
||||
// NotSubsetf asserts that the list (array, slice, or map) does NOT contain all
|
||||
// elements given in the subset (array, slice, or map).
|
||||
// Map elements are key-value pairs unless compared with an array or slice where
|
||||
// only the map key is evaluated.
|
||||
//
|
||||
// require.NotSubsetf(t, [1, 3, 4], [1, 2], "error message %s", "formatted")
|
||||
// require.NotSubsetf(t, {"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted")
|
||||
// require.NotSubsetf(t, [1, 3, 4], {1: "one", 2: "two"}, "error message %s", "formatted")
|
||||
// require.NotSubsetf(t, {"x": 1, "y": 2}, ["z"], "error message %s", "formatted")
|
||||
func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -1971,11 +2019,15 @@ func Samef(t TestingT, expected interface{}, actual interface{}, msg string, arg
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// Subset asserts that the specified list(array, slice...) or map contains all
|
||||
// elements given in the specified subset list(array, slice...) or map.
|
||||
// Subset asserts that the list (array, slice, or map) contains all elements
|
||||
// given in the subset (array, slice, or map).
|
||||
// Map elements are key-value pairs unless compared with an array or slice where
|
||||
// only the map key is evaluated.
|
||||
//
|
||||
// require.Subset(t, [1, 2, 3], [1, 2])
|
||||
// require.Subset(t, {"x": 1, "y": 2}, {"x": 1})
|
||||
// require.Subset(t, [1, 2, 3], {1: "one", 2: "two"})
|
||||
// require.Subset(t, {"x": 1, "y": 2}, ["x"])
|
||||
func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -1986,11 +2038,15 @@ func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...inte
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// Subsetf asserts that the specified list(array, slice...) or map contains all
|
||||
// elements given in the specified subset list(array, slice...) or map.
|
||||
// Subsetf asserts that the list (array, slice, or map) contains all elements
|
||||
// given in the subset (array, slice, or map).
|
||||
// Map elements are key-value pairs unless compared with an array or slice where
|
||||
// only the map key is evaluated.
|
||||
//
|
||||
// require.Subsetf(t, [1, 2, 3], [1, 2], "error message %s", "formatted")
|
||||
// require.Subsetf(t, {"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted")
|
||||
// require.Subsetf(t, [1, 2, 3], {1: "one", 2: "two"}, "error message %s", "formatted")
|
||||
// require.Subsetf(t, {"x": 1, "y": 2}, ["x"], "error message %s", "formatted")
|
||||
func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
|
||||
102
vendor/github.com/stretchr/testify/require/require_forward.go
generated
vendored
102
vendor/github.com/stretchr/testify/require/require_forward.go
generated
vendored
@@ -93,10 +93,19 @@ func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg st
|
||||
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.
|
||||
// Empty asserts that the given value is "empty".
|
||||
//
|
||||
// [Zero values] are "empty".
|
||||
//
|
||||
// Arrays are "empty" if every element is the zero value of the type (stricter than "empty").
|
||||
//
|
||||
// Slices, maps and channels with zero length are "empty".
|
||||
//
|
||||
// Pointer values are "empty" if the pointer is nil or if the pointed value is "empty".
|
||||
//
|
||||
// a.Empty(obj)
|
||||
//
|
||||
// [Zero values]: https://go.dev/ref/spec#The_zero_value
|
||||
func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -104,10 +113,19 @@ 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.
|
||||
// Emptyf asserts that the given value is "empty".
|
||||
//
|
||||
// [Zero values] are "empty".
|
||||
//
|
||||
// Arrays are "empty" if every element is the zero value of the type (stricter than "empty").
|
||||
//
|
||||
// Slices, maps and channels with zero length are "empty".
|
||||
//
|
||||
// Pointer values are "empty" if the pointer is nil or if the pointed value is "empty".
|
||||
//
|
||||
// a.Emptyf(obj, "error message %s", "formatted")
|
||||
//
|
||||
// [Zero values]: https://go.dev/ref/spec#The_zero_value
|
||||
func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -225,10 +243,8 @@ func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string
|
||||
|
||||
// Error asserts that a function returned an error (i.e. not `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// if a.Error(err) {
|
||||
// assert.Equal(t, expectedError, err)
|
||||
// }
|
||||
// actualObj, err := SomeFunction()
|
||||
// a.Error(err)
|
||||
func (a *Assertions) Error(err error, msgAndArgs ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -298,10 +314,8 @@ func (a *Assertions) ErrorIsf(err error, target error, msg string, args ...inter
|
||||
|
||||
// Errorf asserts that a function returned an error (i.e. not `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// if a.Errorf(err, "error message %s", "formatted") {
|
||||
// assert.Equal(t, expectedErrorf, err)
|
||||
// }
|
||||
// actualObj, err := SomeFunction()
|
||||
// a.Errorf(err, "error message %s", "formatted")
|
||||
func (a *Assertions) Errorf(err error, msg string, args ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -869,7 +883,29 @@ func (a *Assertions) IsNonIncreasingf(object interface{}, msg string, args ...in
|
||||
IsNonIncreasingf(a.t, object, msg, args...)
|
||||
}
|
||||
|
||||
// IsNotType asserts that the specified objects are not of the same type.
|
||||
//
|
||||
// a.IsNotType(&NotMyStruct{}, &MyStruct{})
|
||||
func (a *Assertions) IsNotType(theType interface{}, object interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
IsNotType(a.t, theType, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// IsNotTypef asserts that the specified objects are not of the same type.
|
||||
//
|
||||
// a.IsNotTypef(&NotMyStruct{}, &MyStruct{}, "error message %s", "formatted")
|
||||
func (a *Assertions) IsNotTypef(theType interface{}, object interface{}, msg string, args ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
IsNotTypef(a.t, theType, object, msg, args...)
|
||||
}
|
||||
|
||||
// IsType asserts that the specified objects are of the same type.
|
||||
//
|
||||
// a.IsType(&MyStruct{}, &MyStruct{})
|
||||
func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -878,6 +914,8 @@ func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAnd
|
||||
}
|
||||
|
||||
// IsTypef asserts that the specified objects are of the same type.
|
||||
//
|
||||
// a.IsTypef(&MyStruct{}, &MyStruct{}, "error message %s", "formatted")
|
||||
func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg string, args ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -1163,8 +1201,7 @@ func (a *Assertions) NotElementsMatchf(listA interface{}, listB interface{}, msg
|
||||
NotElementsMatchf(a.t, listA, listB, 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.
|
||||
// NotEmpty asserts that the specified object is NOT [Empty].
|
||||
//
|
||||
// if a.NotEmpty(obj) {
|
||||
// assert.Equal(t, "two", obj[1])
|
||||
@@ -1176,8 +1213,7 @@ 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.
|
||||
// NotEmptyf asserts that the specified object is NOT [Empty].
|
||||
//
|
||||
// if a.NotEmptyf(obj, "error message %s", "formatted") {
|
||||
// assert.Equal(t, "two", obj[1])
|
||||
@@ -1379,12 +1415,15 @@ func (a *Assertions) NotSamef(expected interface{}, actual interface{}, msg stri
|
||||
NotSamef(a.t, expected, actual, msg, args...)
|
||||
}
|
||||
|
||||
// NotSubset asserts that the specified list(array, slice...) or map does NOT
|
||||
// contain all elements given in the specified subset list(array, slice...) or
|
||||
// map.
|
||||
// NotSubset asserts that the list (array, slice, or map) does NOT contain all
|
||||
// elements given in the subset (array, slice, or map).
|
||||
// Map elements are key-value pairs unless compared with an array or slice where
|
||||
// only the map key is evaluated.
|
||||
//
|
||||
// a.NotSubset([1, 3, 4], [1, 2])
|
||||
// a.NotSubset({"x": 1, "y": 2}, {"z": 3})
|
||||
// a.NotSubset([1, 3, 4], {1: "one", 2: "two"})
|
||||
// a.NotSubset({"x": 1, "y": 2}, ["z"])
|
||||
func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -1392,12 +1431,15 @@ func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs
|
||||
NotSubset(a.t, list, subset, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotSubsetf asserts that the specified list(array, slice...) or map does NOT
|
||||
// contain all elements given in the specified subset list(array, slice...) or
|
||||
// map.
|
||||
// NotSubsetf asserts that the list (array, slice, or map) does NOT contain all
|
||||
// elements given in the subset (array, slice, or map).
|
||||
// Map elements are key-value pairs unless compared with an array or slice where
|
||||
// only the map key is evaluated.
|
||||
//
|
||||
// a.NotSubsetf([1, 3, 4], [1, 2], "error message %s", "formatted")
|
||||
// a.NotSubsetf({"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted")
|
||||
// a.NotSubsetf([1, 3, 4], {1: "one", 2: "two"}, "error message %s", "formatted")
|
||||
// a.NotSubsetf({"x": 1, "y": 2}, ["z"], "error message %s", "formatted")
|
||||
func (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -1557,11 +1599,15 @@ func (a *Assertions) Samef(expected interface{}, actual interface{}, msg string,
|
||||
Samef(a.t, expected, actual, msg, args...)
|
||||
}
|
||||
|
||||
// Subset asserts that the specified list(array, slice...) or map contains all
|
||||
// elements given in the specified subset list(array, slice...) or map.
|
||||
// Subset asserts that the list (array, slice, or map) contains all elements
|
||||
// given in the subset (array, slice, or map).
|
||||
// Map elements are key-value pairs unless compared with an array or slice where
|
||||
// only the map key is evaluated.
|
||||
//
|
||||
// a.Subset([1, 2, 3], [1, 2])
|
||||
// a.Subset({"x": 1, "y": 2}, {"x": 1})
|
||||
// a.Subset([1, 2, 3], {1: "one", 2: "two"})
|
||||
// a.Subset({"x": 1, "y": 2}, ["x"])
|
||||
func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@@ -1569,11 +1615,15 @@ func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...
|
||||
Subset(a.t, list, subset, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Subsetf asserts that the specified list(array, slice...) or map contains all
|
||||
// elements given in the specified subset list(array, slice...) or map.
|
||||
// Subsetf asserts that the list (array, slice, or map) contains all elements
|
||||
// given in the subset (array, slice, or map).
|
||||
// Map elements are key-value pairs unless compared with an array or slice where
|
||||
// only the map key is evaluated.
|
||||
//
|
||||
// a.Subsetf([1, 2, 3], [1, 2], "error message %s", "formatted")
|
||||
// a.Subsetf({"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted")
|
||||
// a.Subsetf([1, 2, 3], {1: "one", 2: "two"}, "error message %s", "formatted")
|
||||
// a.Subsetf({"x": 1, "y": 2}, ["x"], "error message %s", "formatted")
|
||||
func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
|
||||
16
vendor/github.com/stretchr/testify/suite/stats.go
generated
vendored
16
vendor/github.com/stretchr/testify/suite/stats.go
generated
vendored
@@ -16,26 +16,30 @@ type TestInformation struct {
|
||||
}
|
||||
|
||||
func newSuiteInformation() *SuiteInformation {
|
||||
testStats := make(map[string]*TestInformation)
|
||||
|
||||
return &SuiteInformation{
|
||||
TestStats: testStats,
|
||||
TestStats: make(map[string]*TestInformation),
|
||||
}
|
||||
}
|
||||
|
||||
func (s SuiteInformation) start(testName string) {
|
||||
func (s *SuiteInformation) start(testName string) {
|
||||
if s == nil {
|
||||
return
|
||||
}
|
||||
s.TestStats[testName] = &TestInformation{
|
||||
TestName: testName,
|
||||
Start: time.Now(),
|
||||
}
|
||||
}
|
||||
|
||||
func (s SuiteInformation) end(testName string, passed bool) {
|
||||
func (s *SuiteInformation) end(testName string, passed bool) {
|
||||
if s == nil {
|
||||
return
|
||||
}
|
||||
s.TestStats[testName].End = time.Now()
|
||||
s.TestStats[testName].Passed = passed
|
||||
}
|
||||
|
||||
func (s SuiteInformation) Passed() bool {
|
||||
func (s *SuiteInformation) Passed() bool {
|
||||
for _, stats := range s.TestStats {
|
||||
if !stats.Passed {
|
||||
return false
|
||||
|
||||
112
vendor/github.com/stretchr/testify/suite/suite.go
generated
vendored
112
vendor/github.com/stretchr/testify/suite/suite.go
generated
vendored
@@ -7,6 +7,7 @@ import (
|
||||
"reflect"
|
||||
"regexp"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -15,7 +16,6 @@ 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
|
||||
@@ -116,6 +116,11 @@ func (suite *Suite) Run(name string, subtest func()) bool {
|
||||
})
|
||||
}
|
||||
|
||||
type test = struct {
|
||||
name string
|
||||
run func(t *testing.T)
|
||||
}
|
||||
|
||||
// Run takes a testing suite and runs all of the tests attached
|
||||
// to it.
|
||||
func Run(t *testing.T, suite TestingSuite) {
|
||||
@@ -124,45 +129,39 @@ func Run(t *testing.T, suite TestingSuite) {
|
||||
suite.SetT(t)
|
||||
suite.SetS(suite)
|
||||
|
||||
var suiteSetupDone bool
|
||||
|
||||
var stats *SuiteInformation
|
||||
if _, ok := suite.(WithStats); ok {
|
||||
stats = newSuiteInformation()
|
||||
}
|
||||
|
||||
tests := []testing.InternalTest{}
|
||||
var tests []test
|
||||
methodFinder := reflect.TypeOf(suite)
|
||||
suiteName := methodFinder.Elem().Name()
|
||||
|
||||
for i := 0; i < methodFinder.NumMethod(); i++ {
|
||||
method := methodFinder.Method(i)
|
||||
|
||||
ok, err := methodFilter(method.Name)
|
||||
var matchMethodRE *regexp.Regexp
|
||||
if *matchMethod != "" {
|
||||
var err error
|
||||
matchMethodRE, err = regexp.Compile(*matchMethod)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "testify: invalid regexp for -m: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
if !ok {
|
||||
for i := 0; i < methodFinder.NumMethod(); i++ {
|
||||
method := methodFinder.Method(i)
|
||||
|
||||
if !strings.HasPrefix(method.Name, "Test") {
|
||||
continue
|
||||
}
|
||||
// Apply -testify.m filter
|
||||
if matchMethodRE != nil && !matchMethodRE.MatchString(method.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
if !suiteSetupDone {
|
||||
if stats != nil {
|
||||
stats.Start = time.Now()
|
||||
}
|
||||
|
||||
if setupAllSuite, ok := suite.(SetupAllSuite); ok {
|
||||
setupAllSuite.SetupSuite()
|
||||
}
|
||||
|
||||
suiteSetupDone = true
|
||||
}
|
||||
|
||||
test := testing.InternalTest{
|
||||
Name: method.Name,
|
||||
F: func(t *testing.T) {
|
||||
test := test{
|
||||
name: method.Name,
|
||||
run: func(t *testing.T) {
|
||||
parentT := suite.T()
|
||||
suite.SetT(t)
|
||||
defer recoverAndFailOnPanic(t)
|
||||
@@ -171,10 +170,7 @@ func Run(t *testing.T, suite TestingSuite) {
|
||||
|
||||
r := recover()
|
||||
|
||||
if stats != nil {
|
||||
passed := !t.Failed() && r == nil
|
||||
stats.end(method.Name, passed)
|
||||
}
|
||||
stats.end(method.Name, !t.Failed() && r == nil)
|
||||
|
||||
if afterTestSuite, ok := suite.(AfterTest); ok {
|
||||
afterTestSuite.AfterTest(suiteName, method.Name)
|
||||
@@ -195,59 +191,47 @@ func Run(t *testing.T, suite TestingSuite) {
|
||||
beforeTestSuite.BeforeTest(methodFinder.Elem().Name(), method.Name)
|
||||
}
|
||||
|
||||
if stats != nil {
|
||||
stats.start(method.Name)
|
||||
}
|
||||
stats.start(method.Name)
|
||||
|
||||
method.Func.Call([]reflect.Value{reflect.ValueOf(suite)})
|
||||
},
|
||||
}
|
||||
tests = append(tests, test)
|
||||
}
|
||||
if suiteSetupDone {
|
||||
defer func() {
|
||||
if tearDownAllSuite, ok := suite.(TearDownAllSuite); ok {
|
||||
tearDownAllSuite.TearDownSuite()
|
||||
}
|
||||
|
||||
if suiteWithStats, measureStats := suite.(WithStats); measureStats {
|
||||
stats.End = time.Now()
|
||||
suiteWithStats.HandleStats(suiteName, stats)
|
||||
}
|
||||
}()
|
||||
if len(tests) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if stats != nil {
|
||||
stats.Start = time.Now()
|
||||
}
|
||||
|
||||
if setupAllSuite, ok := suite.(SetupAllSuite); ok {
|
||||
setupAllSuite.SetupSuite()
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if tearDownAllSuite, ok := suite.(TearDownAllSuite); ok {
|
||||
tearDownAllSuite.TearDownSuite()
|
||||
}
|
||||
|
||||
if suiteWithStats, measureStats := suite.(WithStats); measureStats {
|
||||
stats.End = time.Now()
|
||||
suiteWithStats.HandleStats(suiteName, stats)
|
||||
}
|
||||
}()
|
||||
|
||||
runTests(t, tests)
|
||||
}
|
||||
|
||||
// Filtering method according to set regular expression
|
||||
// specified command-line argument -m
|
||||
func methodFilter(name string) (bool, error) {
|
||||
if ok, _ := regexp.MatchString("^Test", name); !ok {
|
||||
return false, nil
|
||||
}
|
||||
return regexp.MatchString(*matchMethod, name)
|
||||
}
|
||||
|
||||
func runTests(t testing.TB, tests []testing.InternalTest) {
|
||||
func runTests(t *testing.T, tests []test) {
|
||||
if len(tests) == 0 {
|
||||
t.Log("warning: no tests to run")
|
||||
return
|
||||
}
|
||||
|
||||
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)
|
||||
t.Run(test.name, test.run)
|
||||
}
|
||||
}
|
||||
|
||||
type runner interface {
|
||||
Run(name string, f func(t *testing.T)) bool
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user