From 8623a884c8f063facf56d26bcdbd16649c7b02bc Mon Sep 17 00:00:00 2001 From: Patrick Mezard Date: Sun, 20 Oct 2013 18:51:51 +0200 Subject: [PATCH 001/178] Initial port with SequenceMatcher and unified_diff() Ported from python default branch (29764a7bd6ba). --- LICENSE | 27 +++ README.md | 12 + difflib.go | 628 ++++++++++++++++++++++++++++++++++++++++++++++++ difflib_test.go | 208 ++++++++++++++++ 4 files changed, 875 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 difflib.go create mode 100644 difflib_test.go diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..c67dad612 --- /dev/null +++ b/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2013, Patrick Mezard +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + The names of its contributors may not be used to endorse or promote +products derived from this software without specific prior written +permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 000000000..fe7b1e3e4 --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +Here is a partial port of python 3 difflib package. Its main goal was to +make available a unified diff implementation, mostly for testing purposes. + +The following class and functions have be ported: + +* `SequenceMatcher` +* `unified_diff()` + +Related doctests have been ported as well. + +I have barely used to code yet so do not consider it being production-ready. +The API is likely to evolve too. diff --git a/difflib.go b/difflib.go new file mode 100644 index 000000000..396bcc2ac --- /dev/null +++ b/difflib.go @@ -0,0 +1,628 @@ +// Package difflib is a partial port of Python difflib module. It provides tools +// to compare sequences of strings and generate textual diffs. +// +// The following class and functions have been ported: +// +// - SequenceMatcher +// +// - unified_diff +// +// Getting unified diffs was the main goal of the port. Keep in mind this code +// is mostly suitable to output text differences in a human friendly way, there +// are no guarantees generated diffs are consumable by patch(1). +package difflib + +import ( + "bufio" + "bytes" + "fmt" + "io" +) + +func min(a, b int) int { + if a < b { + return a + } + return b +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} + +func calculateRatio(matches, length int) float64 { + if length > 0 { + return 2.0 * float64(matches) / float64(length) + } + return 1.0 +} + +type Match struct { + A int + B int + Size int +} + +type OpCode struct { + Tag byte + I1 int + I2 int + J1 int + J2 int +} + +// SequenceMatcher compares sequence of strings. The basic +// algorithm predates, and is a little fancier than, an algorithm +// published in the late 1980's by Ratcliff and Obershelp under the +// hyperbolic name "gestalt pattern matching". The basic idea is to find +// the longest contiguous matching subsequence that contains no "junk" +// elements (R-O doesn't address junk). The same idea is then applied +// recursively to the pieces of the sequences to the left and to the right +// of the matching subsequence. This does not yield minimal edit +// sequences, but does tend to yield matches that "look right" to people. +// +// SequenceMatcher tries to compute a "human-friendly diff" between two +// sequences. Unlike e.g. UNIX(tm) diff, the fundamental notion is the +// longest *contiguous* & junk-free matching subsequence. That's what +// catches peoples' eyes. The Windows(tm) windiff has another interesting +// notion, pairing up elements that appear uniquely in each sequence. +// That, and the method here, appear to yield more intuitive difference +// reports than does diff. This method appears to be the least vulnerable +// to synching up on blocks of "junk lines", though (like blank lines in +// ordinary text files, or maybe "

" lines in HTML files). That may be +// because this is the only method of the 3 that has a *concept* of +// "junk" . +// +// Timing: Basic R-O is cubic time worst case and quadratic time expected +// case. SequenceMatcher is quadratic time for the worst case and has +// expected-case behavior dependent in a complicated way on how many +// elements the sequences have in common; best case time is linear. +type SequenceMatcher struct { + a []string + b []string + b2j map[string][]int + IsJunk func(string) bool + autoJunk bool + bJunk map[string]struct{} + matchingBlocks []Match + fullBCount map[string]int + bPopular map[string]struct{} + opCodes []OpCode +} + +func NewMatcher(a, b []string) *SequenceMatcher { + m := SequenceMatcher{autoJunk: true} + m.SetSeqs(a, b) + return &m +} + +func NewMatcherWithJunk(a, b []string, autoJunk bool, + isJunk func(string) bool) *SequenceMatcher { + + m := SequenceMatcher{IsJunk: isJunk, autoJunk: autoJunk} + m.SetSeqs(a, b) + return &m +} + +// Set two sequences to be compared. +func (m *SequenceMatcher) SetSeqs(a, b []string) { + m.SetSeq1(a) + m.SetSeq2(b) +} + +// Set the first sequence to be compared. The second sequence to be compared is +// not changed. +// +// SequenceMatcher computes and caches detailed information about the second +// sequence, so if you want to compare one sequence S against many sequences, +// use .SetSeq2(s) once and call .SetSeq1(x) repeatedly for each of the other +// sequences. +// +// See also SetSeqs() and SetSeq2(). +func (m *SequenceMatcher) SetSeq1(a []string) { + if &a == &m.a { + return + } + m.a = a + m.matchingBlocks = nil + m.opCodes = nil +} + +// Set the second sequence to be compared. The first sequence to be compared is +// not changed. +func (m *SequenceMatcher) SetSeq2(b []string) { + if &b == &m.b { + return + } + m.b = b + m.matchingBlocks = nil + m.opCodes = nil + m.fullBCount = nil + m.chainB() +} + +func (m *SequenceMatcher) chainB() { + // Populate line -> index mapping + b2j := map[string][]int{} + for i, s := range m.b { + indices := b2j[s] + indices = append(indices, i) + b2j[s] = indices + } + + // Purge junk elements + m.bJunk = map[string]struct{}{} + if m.IsJunk != nil { + junk := m.bJunk + for s, _ := range b2j { + if m.IsJunk(s) { + junk[s] = struct{}{} + } + } + for s, _ := range junk { + delete(b2j, s) + } + } + + // Purge remaining popular elements + popular := map[string]struct{}{} + n := len(m.b) + if m.autoJunk && n >= 200 { + ntest := n/100 + 1 + for s, indices := range b2j { + if len(indices) > ntest { + popular[s] = struct{}{} + } + } + for s, _ := range popular { + delete(b2j, s) + } + } + m.bPopular = popular + m.b2j = b2j +} + +func (m *SequenceMatcher) isBJunk(s string) bool { + _, ok := m.bJunk[s] + return ok +} + +// Find longest matching block in a[alo:ahi] and b[blo:bhi]. +// +// If IsJunk is not defined: +// +// Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where +// alo <= i <= i+k <= ahi +// blo <= j <= j+k <= bhi +// and for all (i',j',k') meeting those conditions, +// k >= k' +// i <= i' +// and if i == i', j <= j' +// +// In other words, of all maximal matching blocks, return one that +// starts earliest in a, and of all those maximal matching blocks that +// start earliest in a, return the one that starts earliest in b. +// +// If IsJunk is defined, first the longest matching block is +// determined as above, but with the additional restriction that no +// junk element appears in the block. Then that block is extended as +// far as possible by matching (only) junk elements on both sides. So +// the resulting block never matches on junk except as identical junk +// happens to be adjacent to an "interesting" match. +// +// If no blocks match, return (alo, blo, 0). +func (m *SequenceMatcher) findLongestMatch(alo, ahi, blo, bhi int) Match { + // CAUTION: stripping common prefix or suffix would be incorrect. + // E.g., + // ab + // acab + // Longest matching block is "ab", but if common prefix is + // stripped, it's "a" (tied with "b"). UNIX(tm) diff does so + // strip, so ends up claiming that ab is changed to acab by + // inserting "ca" in the middle. That's minimal but unintuitive: + // "it's obvious" that someone inserted "ac" at the front. + // Windiff ends up at the same place as diff, but by pairing up + // the unique 'b's and then matching the first two 'a's. + besti, bestj, bestsize := alo, blo, 0 + + // find longest junk-free match + // during an iteration of the loop, j2len[j] = length of longest + // junk-free match ending with a[i-1] and b[j] + j2len := map[int]int{} + for i := alo; i != ahi; i++ { + // look at all instances of a[i] in b; note that because + // b2j has no junk keys, the loop is skipped if a[i] is junk + newj2len := map[int]int{} + for _, j := range m.b2j[m.a[i]] { + // a[i] matches b[j] + if j < blo { + continue + } + if j >= bhi { + break + } + k := j2len[j-1] + 1 + newj2len[j] = k + if k > bestsize { + besti, bestj, bestsize = i-k+1, j-k+1, k + } + } + j2len = newj2len + } + + // Extend the best by non-junk elements on each end. In particular, + // "popular" non-junk elements aren't in b2j, which greatly speeds + // the inner loop above, but also means "the best" match so far + // doesn't contain any junk *or* popular non-junk elements. + for besti > alo && bestj > blo && !m.isBJunk(m.b[bestj-1]) && + m.a[besti-1] == m.b[bestj-1] { + besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 + } + for besti+bestsize < ahi && bestj+bestsize < bhi && + !m.isBJunk(m.b[bestj+bestsize]) && + m.a[besti+bestsize] == m.b[bestj+bestsize] { + bestsize += 1 + } + + // Now that we have a wholly interesting match (albeit possibly + // empty!), we may as well suck up the matching junk on each + // side of it too. Can't think of a good reason not to, and it + // saves post-processing the (possibly considerable) expense of + // figuring out what to do with it. In the case of an empty + // interesting match, this is clearly the right thing to do, + // because no other kind of match is possible in the regions. + for besti > alo && bestj > blo && m.isBJunk(m.b[bestj-1]) && + m.a[besti-1] == m.b[bestj-1] { + besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 + } + for besti+bestsize < ahi && bestj+bestsize < bhi && + m.isBJunk(m.b[bestj+bestsize]) && + m.a[besti+bestsize] == m.b[bestj+bestsize] { + bestsize += 1 + } + + return Match{A: besti, B: bestj, Size: bestsize} +} + +// Return list of triples describing matching subsequences. +// +// Each triple is of the form (i, j, n), and means that +// a[i:i+n] == b[j:j+n]. The triples are monotonically increasing in +// i and in j. It's also guaranteed that if (i, j, n) and (i', j', n') are +// adjacent triples in the list, and the second is not the last triple in the +// list, then i+n != i' or j+n != j'. IOW, adjacent triples never describe +// adjacent equal blocks. +// +// The last triple is a dummy, (len(a), len(b), 0), and is the only +// triple with n==0. +func (m *SequenceMatcher) GetMatchingBlocks() []Match { + if m.matchingBlocks != nil { + return m.matchingBlocks + } + + var matchBlocks func(alo, ahi, blo, bhi int, matched []Match) []Match + matchBlocks = func(alo, ahi, blo, bhi int, matched []Match) []Match { + match := m.findLongestMatch(alo, ahi, blo, bhi) + i, j, k := match.A, match.B, match.Size + if match.Size > 0 { + if alo < i && blo < j { + matched = matchBlocks(alo, i, blo, j, matched) + } + matched = append(matched, match) + if i+k < ahi && j+k < bhi { + matched = matchBlocks(i+k, ahi, j+k, bhi, matched) + } + } + return matched + } + matched := matchBlocks(0, len(m.a), 0, len(m.b), nil) + + // It's possible that we have adjacent equal blocks in the + // matching_blocks list now. + nonAdjacent := []Match{} + i1, j1, k1 := 0, 0, 0 + for _, b := range matched { + // Is this block adjacent to i1, j1, k1? + i2, j2, k2 := b.A, b.B, b.Size + if i1+k1 == i2 && j1+k1 == j2 { + // Yes, so collapse them -- this just increases the length of + // the first block by the length of the second, and the first + // block so lengthened remains the block to compare against. + k1 += k2 + } else { + // Not adjacent. Remember the first block (k1==0 means it's + // the dummy we started with), and make the second block the + // new block to compare against. + if k1 > 0 { + nonAdjacent = append(nonAdjacent, Match{i1, j1, k1}) + } + i1, j1, k1 = i2, j2, k2 + } + } + if k1 > 0 { + nonAdjacent = append(nonAdjacent, Match{i1, j1, k1}) + } + + nonAdjacent = append(nonAdjacent, Match{len(m.a), len(m.b), 0}) + m.matchingBlocks = nonAdjacent + return m.matchingBlocks +} + +// Return list of 5-tuples describing how to turn a into b. +// +// Each tuple is of the form (tag, i1, i2, j1, j2). The first tuple +// has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the +// tuple preceding it, and likewise for j1 == the previous j2. +// +// The tags are characters, with these meanings: +// +// 'r' (replace): a[i1:i2] should be replaced by b[j1:j2] +// 'd' (delete): a[i1:i2] should be deleted. +// Note that j1==j2 in this case. +// 'i' (insert): b[j1:j2] should be inserted at a[i1:i1]. +// Note that i1==i2 in this case. +// 'e' (equal): a[i1:i2] == b[j1:j2] +func (m *SequenceMatcher) GetOpCodes() []OpCode { + if m.opCodes != nil { + return m.opCodes + } + i, j := 0, 0 + matching := m.GetMatchingBlocks() + opCodes := make([]OpCode, 0, len(matching)) + for _, m := range matching { + // invariant: we've pumped out correct diffs to change + // a[:i] into b[:j], and the next matching block is + // a[ai:ai+size] == b[bj:bj+size]. So we need to pump + // out a diff to change a[i:ai] into b[j:bj], pump out + // the matching block, and move (i,j) beyond the match + ai, bj, size := m.A, m.B, m.Size + tag := byte(0) + if i < ai && j < bj { + tag = 'r' + } else if i < ai { + tag = 'd' + } else if j < bj { + tag = 'i' + } + if tag > 0 { + opCodes = append(opCodes, OpCode{tag, i, ai, j, bj}) + } + i, j = ai+size, bj+size + // the list of matching blocks is terminated by a + // sentinel with size 0 + if size > 0 { + opCodes = append(opCodes, OpCode{'e', ai, i, bj, j}) + } + } + m.opCodes = opCodes + return m.opCodes +} + +// Isolate change clusters by eliminating ranges with no changes. +// +// Return a generator of groups with up to n lines of context. +// Each group is in the same format as returned by GetOpCodes(). +func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode { + if n < 0 { + n = 3 + } + codes := m.GetOpCodes() + if len(codes) == 0 { + codes = []OpCode{OpCode{'e', 0, 1, 0, 1}} + } + // Fixup leading and trailing groups if they show no changes. + if codes[0].Tag == 'e' { + c := codes[0] + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + codes[0] = OpCode{c.Tag, max(i1, i2-n), i2, max(j1, j2-n), j2} + } + if codes[len(codes)-1].Tag == 'e' { + c := codes[len(codes)-1] + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + codes[len(codes)-1] = OpCode{c.Tag, i1, min(i2, i1+n), j1, min(j2, j1+n)} + } + nn := n + n + groups := [][]OpCode{} + group := []OpCode{} + for _, c := range codes { + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + // End the current group and start a new one whenever + // there is a large range with no changes. + if c.Tag == 'e' && i2-i1 > nn { + group = append(group, OpCode{c.Tag, i1, min(i2, i1+n), + j1, min(j2, j1+n)}) + groups = append(groups, group) + group = []OpCode{} + i1, j1 = max(i1, i2-n), max(j1, j2-n) + } + group = append(group, OpCode{c.Tag, i1, i2, j1, j2}) + } + if len(group) > 0 && !(len(group) == 1 && group[0].Tag == 'e') { + groups = append(groups, group) + } + return groups +} + +// Return a measure of the sequences' similarity (float in [0,1]). +// +// Where T is the total number of elements in both sequences, and +// M is the number of matches, this is 2.0*M / T. +// Note that this is 1 if the sequences are identical, and 0 if +// they have nothing in common. +// +// .Ratio() is expensive to compute if you haven't already computed +// .GetMatchingBlocks() or .GetOpCodes(), in which case you may +// want to try .QuickRatio() or .RealQuickRation() first to get an +// upper bound. +func (m *SequenceMatcher) Ratio() float64 { + matches := 0 + for _, m := range m.GetMatchingBlocks() { + matches += m.Size + } + return calculateRatio(matches, len(m.a)+len(m.b)) +} + +// Return an upper bound on ratio() relatively quickly. +// +// This isn't defined beyond that it is an upper bound on .Ratio(), and +// is faster to compute. +func (m *SequenceMatcher) QuickRatio() float64 { + // viewing a and b as multisets, set matches to the cardinality + // of their intersection; this counts the number of matches + // without regard to order, so is clearly an upper bound + if m.fullBCount == nil { + m.fullBCount = map[string]int{} + for _, s := range m.b { + m.fullBCount[s] = m.fullBCount[s] + 1 + } + } + + // avail[x] is the number of times x appears in 'b' less the + // number of times we've seen it in 'a' so far ... kinda + avail := map[string]int{} + matches := 0 + for _, s := range m.a { + n, ok := avail[s] + if !ok { + n = m.fullBCount[s] + } + avail[s] = n - 1 + if n > 0 { + matches += 1 + } + } + return calculateRatio(matches, len(m.a)+len(m.b)) +} + +// Return an upper bound on ratio() very quickly. +// +// This isn't defined beyond that it is an upper bound on .Ratio(), and +// is faster to compute than either .Ratio() or .QuickRatio(). +func (m *SequenceMatcher) RealQuickRatio() float64 { + la, lb := len(m.a), len(m.b) + return calculateRatio(min(la, lb), la+lb) +} + +// Convert range to the "ed" format +func formatRangeUnified(start, stop int) string { + // Per the diff spec at http://www.unix.org/single_unix_specification/ + beginning := start + 1 // lines start numbering with one + length := stop - start + if length == 1 { + return fmt.Sprintf("%d", beginning) + } + if length == 0 { + beginning -= 1 // empty ranges begin at line just before the range + } + return fmt.Sprintf("%d,%d", beginning, length) +} + +// Unified diff parameters +type UnifiedDiff struct { + A []string // First sequence lines + FromFile string // First file name + FromDate string // First file time + B []string // Second sequence lines + ToFile string // Second file name + ToDate string // Second file time + Eol string // Headers end of line, defaults to LF + Context int // Number of context lines +} + +// Compare two sequences of lines; generate the delta as a unified diff. +// +// Unified diffs are a compact way of showing line changes and a few +// lines of context. The number of context lines is set by 'n' which +// defaults to three. +// +// By default, the diff control lines (those with ---, +++, or @@) are +// created with a trailing newline. This is helpful so that inputs +// created from file.readlines() result in diffs that are suitable for +// file.writelines() since both the inputs and outputs have trailing +// newlines. +// +// For inputs that do not have trailing newlines, set the lineterm +// argument to "" so that the output will be uniformly newline free. +// +// The unidiff format normally has a header for filenames and modification +// times. Any or all of these may be specified using strings for +// 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'. +// The modification times are normally expressed in the ISO 8601 format. +func WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error { + buf := bufio.NewWriter(writer) + defer buf.Flush() + w := func(format string, args ...interface{}) error { + _, err := buf.WriteString(fmt.Sprintf(format, args...)) + return err + } + + if len(diff.Eol) == 0 { + diff.Eol = "\n" + } + + started := false + m := NewMatcher(diff.A, diff.B) + for _, g := range m.GetGroupedOpCodes(diff.Context) { + if !started { + started = true + fromDate := "" + if len(diff.FromDate) > 0 { + fromDate = "\t" + diff.FromDate + } + toDate := "" + if len(diff.ToDate) > 0 { + toDate = "\t" + diff.ToDate + } + err := w("--- %s%s%s", diff.FromFile, fromDate, diff.Eol) + if err != nil { + return err + } + err = w("+++ %s%s%s", diff.ToFile, toDate, diff.Eol) + if err != nil { + return err + } + } + first, last := g[0], g[len(g)-1] + range1 := formatRangeUnified(first.I1, last.I2) + range2 := formatRangeUnified(first.J1, last.J2) + if err := w("@@ -%s +%s @@%s", range1, range2, diff.Eol); err != nil { + return err + } + for _, c := range g { + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + if c.Tag == 'e' { + for _, line := range diff.A[i1:i2] { + if err := w(" " + line); err != nil { + return err + } + } + continue + } + if c.Tag == 'r' || c.Tag == 'd' { + for _, line := range diff.A[i1:i2] { + if err := w("-" + line); err != nil { + return err + } + } + } + if c.Tag == 'r' || c.Tag == 'i' { + for _, line := range diff.B[j1:j2] { + if err := w("+" + line); err != nil { + return err + } + } + } + } + } + return nil +} + +// Like WriteUnifiedDiff but returns the diff a string. +func GetUnifiedDiffString(diff UnifiedDiff) (string, error) { + w := &bytes.Buffer{} + err := WriteUnifiedDiff(w, diff) + return string(w.Bytes()), err +} diff --git a/difflib_test.go b/difflib_test.go new file mode 100644 index 000000000..440f6efa9 --- /dev/null +++ b/difflib_test.go @@ -0,0 +1,208 @@ +package difflib + +import ( + "bytes" + "fmt" + "math" + "reflect" + "strings" + "testing" +) + +func splitChars(s string) []string { + chars := make([]string, 0, len(s)) + // Assume ASCII inputs + for i := 0; i != len(s); i++ { + chars = append(chars, string(s[i])) + } + return chars +} + +func TestSequenceMatcherRatio(t *testing.T) { + s := NewMatcher(splitChars("abcd"), splitChars("bcde")) + ratio := s.Ratio() + if ratio != 0.75 { + t.Errorf("unexpected ratio: %v", ratio) + } + + ratio = s.QuickRatio() + if ratio != 0.75 { + t.Errorf("unexpected quick ratio: %v", ratio) + } + + ratio = s.RealQuickRatio() + if ratio != 1.0 { + t.Errorf("unexpected real quick ratio: %v", ratio) + } +} + +func TestGetOptCodes(t *testing.T) { + a := "qabxcd" + b := "abycdf" + s := NewMatcher(splitChars(a), splitChars(b)) + w := &bytes.Buffer{} + for _, op := range s.GetOpCodes() { + fmt.Fprintf(w, "%s a[%d:%d], (%s) b[%d:%d] (%s)\n", string(op.Tag), + op.I1, op.I2, a[op.I1:op.I2], op.J1, op.J2, b[op.J1:op.J2]) + } + result := string(w.Bytes()) + expected := `d a[0:1], (q) b[0:0] () +e a[1:3], (ab) b[0:2] (ab) +r a[3:4], (x) b[2:3] (y) +e a[4:6], (cd) b[3:5] (cd) +i a[6:6], () b[5:6] (f) +` + if expected != result { + t.Errorf("unexpected op codes: \n%s", result) + } +} + +func TestGroupedOpCodes(t *testing.T) { + a := []string{} + for i := 0; i != 39; i++ { + a = append(a, fmt.Sprintf("%02d", i)) + } + b := []string{} + b = append(b, a[:8]...) + b = append(b, " i") + b = append(b, a[8:19]...) + b = append(b, " x") + b = append(b, a[20:22]...) + b = append(b, a[27:34]...) + b = append(b, " y") + b = append(b, a[35:]...) + s := NewMatcher(a, b) + w := &bytes.Buffer{} + for _, g := range s.GetGroupedOpCodes(-1) { + fmt.Fprintf(w, "group\n") + for _, op := range g { + fmt.Fprintf(w, " %s, %d, %d, %d, %d\n", string(op.Tag), + op.I1, op.I2, op.J1, op.J2) + } + } + result := string(w.Bytes()) + expected := `group + e, 5, 8, 5, 8 + i, 8, 8, 8, 9 + e, 8, 11, 9, 12 +group + e, 16, 19, 17, 20 + r, 19, 20, 20, 21 + e, 20, 22, 21, 23 + d, 22, 27, 23, 23 + e, 27, 30, 23, 26 +group + e, 31, 34, 27, 30 + r, 34, 35, 30, 31 + e, 35, 38, 31, 34 +` + if expected != result { + t.Errorf("unexpected op codes: \n%s", result) + } +} + +func splitLines(s string) []string { + lines := []string{} + for _, line := range strings.Split(s, "\n") { + lines = append(lines, line+"\n") + } + return lines +} + +func TestUnifiedDiff(t *testing.T) { + a := `one +two +three +four` + b := `zero +one +three +four` + diff := UnifiedDiff{ + A: splitLines(a), + B: splitLines(b), + FromFile: "Original", + FromDate: "2005-01-26 23:30:50", + ToFile: "Current", + ToDate: "2010-04-02 10:20:52", + Context: 3, + } + result, err := GetUnifiedDiffString(diff) + if err != nil { + t.Errorf("unified diff failed: %s", err) + } + expected := `--- Original\t2005-01-26 23:30:50 ++++ Current\t2010-04-02 10:20:52 +@@ -1,4 +1,4 @@ ++zero + one +-two + three + four +` + // TABs are a pain to preserve through editors + expected = strings.Replace(expected, "\\t", "\t", -1) + if expected != result { + t.Errorf("unexpected diff result:\n%s", result) + } +} + +func assertAlmostEqual(t *testing.T, a, b float64, places int) { + if math.Abs(a-b) > math.Pow10(-places) { + t.Errorf("%.7f != %.7f", a, b) + } +} + +func assertEqual(t *testing.T, a, b interface{}) { + if !reflect.DeepEqual(a, b) { + t.Errorf("%v != %v", a, b) + } +} + +func rep(s string, count int) string { + return strings.Repeat(s, count) +} + +func TestWithAsciiOneInsert(t *testing.T) { + sm := NewMatcher(splitChars(rep("b", 100)), + splitChars("a"+rep("b", 100))) + assertAlmostEqual(t, sm.Ratio(), 0.995, 3) + assertEqual(t, sm.GetOpCodes(), + []OpCode{{'i', 0, 0, 0, 1}, {'e', 0, 100, 1, 101}}) + assertEqual(t, len(sm.bPopular), 0) + + sm = NewMatcher(splitChars(rep("b", 100)), + splitChars(rep("b", 50)+"a"+rep("b", 50))) + assertAlmostEqual(t, sm.Ratio(), 0.995, 3) + assertEqual(t, sm.GetOpCodes(), + []OpCode{{'e', 0, 50, 0, 50}, {'i', 50, 50, 50, 51}, {'e', 50, 100, 51, 101}}) + assertEqual(t, len(sm.bPopular), 0) +} + +func TestWithAsciiOnDelete(t *testing.T) { + sm := NewMatcher(splitChars(rep("a", 40)+"c"+rep("b", 40)), + splitChars(rep("a", 40)+rep("b", 40))) + assertAlmostEqual(t, sm.Ratio(), 0.994, 3) + assertEqual(t, sm.GetOpCodes(), + []OpCode{{'e', 0, 40, 0, 40}, {'d', 40, 41, 40, 40}, {'e', 41, 81, 40, 80}}) +} + +func TestWithAsciiBJunk(t *testing.T) { + isJunk := func(s string) bool { + return s == " " + } + sm := NewMatcherWithJunk(splitChars(rep("a", 40)+rep("b", 40)), + splitChars(rep("a", 44)+rep("b", 40)), true, isJunk) + assertEqual(t, sm.bJunk, map[string]struct{}{}) + + sm = NewMatcherWithJunk(splitChars(rep("a", 40)+rep("b", 40)), + splitChars(rep("a", 44)+rep("b", 40)+rep(" ", 20)), false, isJunk) + assertEqual(t, sm.bJunk, map[string]struct{}{" ": struct{}{}}) + + isJunk = func(s string) bool { + return s == " " || s == "b" + } + sm = NewMatcherWithJunk(splitChars(rep("a", 40)+rep("b", 40)), + splitChars(rep("a", 44)+rep("b", 40)+rep(" ", 20)), false, isJunk) + assertEqual(t, sm.bJunk, map[string]struct{}{" ": struct{}{}, "b": struct{}{}}) +} From 3859285434d126964aae0ac456624fdc5f6bde64 Mon Sep 17 00:00:00 2001 From: Patrick Mezard Date: Sun, 27 Oct 2013 14:39:48 +0100 Subject: [PATCH 002/178] Reorganize repository --- difflib.go => difflib/difflib.go | 0 difflib_test.go => difflib/difflib_test.go | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename difflib.go => difflib/difflib.go (100%) rename difflib_test.go => difflib/difflib_test.go (100%) diff --git a/difflib.go b/difflib/difflib.go similarity index 100% rename from difflib.go rename to difflib/difflib.go diff --git a/difflib_test.go b/difflib/difflib_test.go similarity index 100% rename from difflib_test.go rename to difflib/difflib_test.go From 35c8dc471bbf909461e79e6033701b985fb713b7 Mon Sep 17 00:00:00 2001 From: Patrick Mezard Date: Sat, 23 Nov 2013 18:06:15 +0100 Subject: [PATCH 003/178] difflib_test: add more tests --- difflib/difflib_test.go | 78 +++++++++++++++++++++++++++-------------- 1 file changed, 52 insertions(+), 26 deletions(-) diff --git a/difflib/difflib_test.go b/difflib/difflib_test.go index 440f6efa9..62ce78f3c 100644 --- a/difflib/difflib_test.go +++ b/difflib/difflib_test.go @@ -9,6 +9,18 @@ import ( "testing" ) +func assertAlmostEqual(t *testing.T, a, b float64, places int) { + if math.Abs(a-b) > math.Pow10(-places) { + t.Errorf("%.7f != %.7f", a, b) + } +} + +func assertEqual(t *testing.T, a, b interface{}) { + if !reflect.DeepEqual(a, b) { + t.Errorf("%v != %v", a, b) + } +} + func splitChars(s string) []string { chars := make([]string, 0, len(s)) // Assume ASCII inputs @@ -20,20 +32,9 @@ func splitChars(s string) []string { func TestSequenceMatcherRatio(t *testing.T) { s := NewMatcher(splitChars("abcd"), splitChars("bcde")) - ratio := s.Ratio() - if ratio != 0.75 { - t.Errorf("unexpected ratio: %v", ratio) - } - - ratio = s.QuickRatio() - if ratio != 0.75 { - t.Errorf("unexpected quick ratio: %v", ratio) - } - - ratio = s.RealQuickRatio() - if ratio != 1.0 { - t.Errorf("unexpected real quick ratio: %v", ratio) - } + assertEqual(t, s.Ratio(), 0.75) + assertEqual(t, s.QuickRatio(), 0.75) + assertEqual(t, s.RealQuickRatio(), 1.0) } func TestGetOptCodes(t *testing.T) { @@ -147,18 +148,6 @@ four` } } -func assertAlmostEqual(t *testing.T, a, b float64, places int) { - if math.Abs(a-b) > math.Pow10(-places) { - t.Errorf("%.7f != %.7f", a, b) - } -} - -func assertEqual(t *testing.T, a, b interface{}) { - if !reflect.DeepEqual(a, b) { - t.Errorf("%v != %v", a, b) - } -} - func rep(s string, count int) string { return strings.Repeat(s, count) } @@ -206,3 +195,40 @@ func TestWithAsciiBJunk(t *testing.T) { splitChars(rep("a", 44)+rep("b", 40)+rep(" ", 20)), false, isJunk) assertEqual(t, sm.bJunk, map[string]struct{}{" ": struct{}{}, "b": struct{}{}}) } + +func TestSFBugsRatioForNullSeqn(t *testing.T) { + sm := NewMatcher(nil, nil) + assertEqual(t, sm.Ratio(), 1.0) + assertEqual(t, sm.QuickRatio(), 1.0) + assertEqual(t, sm.RealQuickRatio(), 1.0) +} + +func TestSFBugsComparingEmptyLists(t *testing.T) { + groups := NewMatcher(nil, nil).GetGroupedOpCodes(-1) + assertEqual(t, len(groups), 0) + diff := UnifiedDiff{ + FromFile: "Original", + ToFile: "Current", + Context: 3, + } + result, err := GetUnifiedDiffString(diff) + assertEqual(t, err, nil) + assertEqual(t, result, "") +} + +func TestOutputFormatRangeFormatUnified(t *testing.T) { + // Per the diff spec at http://www.unix.org/single_unix_specification/ + // + // Each field shall be of the form: + // %1d", if the range contains exactly one line, + // and: + // "%1d,%1d", , otherwise. + // If a range is empty, its beginning line number shall be the number of + // the line just before the range, or 0 if the empty range starts the file. + fm := formatRangeUnified + assertEqual(t, fm(3, 3), "3,0") + assertEqual(t, fm(3, 4), "4") + assertEqual(t, fm(3, 5), "4,2") + assertEqual(t, fm(3, 6), "4,3") + assertEqual(t, fm(0, 0), "0,0") +} From 6f90939c9ae34a98073ea8c790bb128f08d7935d Mon Sep 17 00:00:00 2001 From: Patrick Mezard Date: Sat, 23 Nov 2013 19:56:54 +0100 Subject: [PATCH 004/178] difflib: implement context diffs --- README.md | 3 +- difflib/difflib.go | 117 ++++++++++++++++++++++++++++++++++++++++ difflib/difflib_test.go | 105 ++++++++++++++++++++++++++++++++++++ 3 files changed, 224 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fe7b1e3e4..aa7dba9df 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,9 @@ The following class and functions have be ported: * `SequenceMatcher` * `unified_diff()` +* `context_diff()` -Related doctests have been ported as well. +Related doctests and unittests have been ported as well. I have barely used to code yet so do not consider it being production-ready. The API is likely to evolve too. diff --git a/difflib/difflib.go b/difflib/difflib.go index 396bcc2ac..ec0b826ae 100644 --- a/difflib/difflib.go +++ b/difflib/difflib.go @@ -626,3 +626,120 @@ func GetUnifiedDiffString(diff UnifiedDiff) (string, error) { err := WriteUnifiedDiff(w, diff) return string(w.Bytes()), err } + +// Convert range to the "ed" format. +func formatRangeContext(start, stop int) string { + // Per the diff spec at http://www.unix.org/single_unix_specification/ + beginning := start + 1 // lines start numbering with one + length := stop - start + if length == 0 { + beginning -= 1 // empty ranges begin at line just before the range + } + if length <= 1 { + return fmt.Sprintf("%d", beginning) + } + return fmt.Sprintf("%d,%d", beginning, beginning+length-1) +} + +type ContextDiff UnifiedDiff + +// Compare two sequences of lines; generate the delta as a context diff. +// +// Context diffs are a compact way of showing line changes and a few +// lines of context. The number of context lines is set by diff.Context +// which defaults to three. +// +// By default, the diff control lines (those with *** or ---) are +// created with a trailing newline. +// +// For inputs that do not have trailing newlines, set the diff.Eol +// argument to "" so that the output will be uniformly newline free. +// +// The context diff format normally has a header for filenames and +// modification times. Any or all of these may be specified using +// strings for diff.FromFile, diff.ToFile, diff.FromDate, diff.ToDate. +// The modification times are normally expressed in the ISO 8601 format. +// If not specified, the strings default to blanks. +func WriteContextDiff(writer io.Writer, diff ContextDiff) error { + buf := bufio.NewWriter(writer) + defer buf.Flush() + var diffErr error + w := func(format string, args ...interface{}) { + _, err := buf.WriteString(fmt.Sprintf(format, args...)) + if diffErr == nil && err != nil { + diffErr = err + } + } + + if len(diff.Eol) == 0 { + diff.Eol = "\n" + } + + prefix := map[byte]string{ + 'i': "+ ", + 'd': "- ", + 'r': "! ", + 'e': " ", + } + + started := false + m := NewMatcher(diff.A, diff.B) + for _, g := range m.GetGroupedOpCodes(diff.Context) { + if !started { + started = true + fromDate := "" + if len(diff.FromDate) > 0 { + fromDate = "\t" + diff.FromDate + } + toDate := "" + if len(diff.ToDate) > 0 { + toDate = "\t" + diff.ToDate + } + w("*** %s%s%s", diff.FromFile, fromDate, diff.Eol) + w("--- %s%s%s", diff.ToFile, toDate, diff.Eol) + } + + first, last := g[0], g[len(g)-1] + w("***************" + diff.Eol) + + range1 := formatRangeContext(first.I1, last.I2) + w("*** %s ****%s", range1, diff.Eol) + for _, c := range g { + if c.Tag == 'r' || c.Tag == 'd' { + for _, cc := range g { + if cc.Tag == 'i' { + continue + } + for _, line := range diff.A[cc.I1:cc.I2] { + w(prefix[cc.Tag] + line) + } + } + break + } + } + + range2 := formatRangeContext(first.J1, last.J2) + w("--- %s ----%s", range2, diff.Eol) + for _, c := range g { + if c.Tag == 'r' || c.Tag == 'i' { + for _, cc := range g { + if cc.Tag == 'd' { + continue + } + for _, line := range diff.B[cc.J1:cc.J2] { + w(prefix[cc.Tag] + line) + } + } + break + } + } + } + return diffErr +} + +// Like WriteContextDiff but returns the diff a string. +func GetContextDiffString(diff ContextDiff) (string, error) { + w := &bytes.Buffer{} + err := WriteContextDiff(w, diff) + return string(w.Bytes()), err +} diff --git a/difflib/difflib_test.go b/difflib/difflib_test.go index 62ce78f3c..d36c257c3 100644 --- a/difflib/difflib_test.go +++ b/difflib/difflib_test.go @@ -148,6 +148,46 @@ four` } } +func TestContextDiff(t *testing.T) { + a := `one +two +three +four` + b := `zero +one +tree +four` + diff := ContextDiff{ + A: splitLines(a), + B: splitLines(b), + FromFile: "Original", + ToFile: "Current", + Context: 3, + Eol: "\n", + } + result, err := GetContextDiffString(diff) + assertEqual(t, err, nil) + expected := `*** Original +--- Current +*************** +*** 1,4 **** + one +! two +! three + four +--- 1,4 ---- ++ zero + one +! tree + four +` + // TABs are a pain to preserve through editors + expected = strings.Replace(expected, "\\t", "\t", -1) + if expected != result { + t.Errorf("unexpected diff result:\n%s", result) + } +} + func rep(s string, count int) string { return strings.Repeat(s, count) } @@ -232,3 +272,68 @@ func TestOutputFormatRangeFormatUnified(t *testing.T) { assertEqual(t, fm(3, 6), "4,3") assertEqual(t, fm(0, 0), "0,0") } + +func TestOutputFormatRangeFormatContext(t *testing.T) { + // Per the diff spec at http://www.unix.org/single_unix_specification/ + // + // The range of lines in file1 shall be written in the following format + // if the range contains two or more lines: + // "*** %d,%d ****\n", , + // and the following format otherwise: + // "*** %d ****\n", + // The ending line number of an empty range shall be the number of the preceding line, + // or 0 if the range is at the start of the file. + // + // Next, the range of lines in file2 shall be written in the following format + // if the range contains two or more lines: + // "--- %d,%d ----\n", , + // and the following format otherwise: + // "--- %d ----\n", + fm := formatRangeContext + assertEqual(t, fm(3, 3), "3") + assertEqual(t, fm(3, 4), "4") + assertEqual(t, fm(3, 5), "4,5") + assertEqual(t, fm(3, 6), "4,6") + assertEqual(t, fm(0, 0), "0") +} + +func TestOutputFormatTabDelimiter(t *testing.T) { + diff := UnifiedDiff{ + A: splitChars("one"), + B: splitChars("two"), + FromFile: "Original", + FromDate: "2005-01-26 23:30:50", + ToFile: "Current", + ToDate: "2010-04-12 10:20:52", + Eol: "\n", + } + ud, err := GetUnifiedDiffString(diff) + assertEqual(t, err, nil) + assertEqual(t, splitLines(ud)[:2], []string{ + "--- Original\t2005-01-26 23:30:50\n", + "+++ Current\t2010-04-12 10:20:52\n", + }) + cd, err := GetContextDiffString(ContextDiff(diff)) + assertEqual(t, err, nil) + assertEqual(t, splitLines(cd)[:2], []string{ + "*** Original\t2005-01-26 23:30:50\n", + "--- Current\t2010-04-12 10:20:52\n", + }) +} + +func TestOutputFormatNoTrailingTabOnEmptyFiledate(t *testing.T) { + diff := UnifiedDiff{ + A: splitChars("one"), + B: splitChars("two"), + FromFile: "Original", + ToFile: "Current", + Eol: "\n", + } + ud, err := GetUnifiedDiffString(diff) + assertEqual(t, err, nil) + assertEqual(t, splitLines(ud)[:2], []string{"--- Original\n", "+++ Current\n"}) + + cd, err := GetContextDiffString(ContextDiff(diff)) + assertEqual(t, err, nil) + assertEqual(t, splitLines(cd)[:2], []string{"*** Original\n", "--- Current\n"}) +} From 06eeb1d9485ad108480a3539cb2ee3d5e203f878 Mon Sep 17 00:00:00 2001 From: Patrick Mezard Date: Sat, 23 Nov 2013 20:53:20 +0100 Subject: [PATCH 005/178] difflib: move and publish splitLines in difflib --- difflib/difflib.go | 11 +++++++++++ difflib/difflib_test.go | 24 ++++++++---------------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/difflib/difflib.go b/difflib/difflib.go index ec0b826ae..e5221e450 100644 --- a/difflib/difflib.go +++ b/difflib/difflib.go @@ -17,6 +17,7 @@ import ( "bytes" "fmt" "io" + "strings" ) func min(a, b int) int { @@ -743,3 +744,13 @@ func GetContextDiffString(diff ContextDiff) (string, error) { err := WriteContextDiff(w, diff) return string(w.Bytes()), err } + +// Split a string on "\n" while preserving them. The output can be used +// as input for UnifiedDiff and ContextDiff structures. +func SplitLines(s string) []string { + lines := []string{} + for _, line := range strings.Split(s, "\n") { + lines = append(lines, line+"\n") + } + return lines +} diff --git a/difflib/difflib_test.go b/difflib/difflib_test.go index d36c257c3..b7ea0a82d 100644 --- a/difflib/difflib_test.go +++ b/difflib/difflib_test.go @@ -102,14 +102,6 @@ group } } -func splitLines(s string) []string { - lines := []string{} - for _, line := range strings.Split(s, "\n") { - lines = append(lines, line+"\n") - } - return lines -} - func TestUnifiedDiff(t *testing.T) { a := `one two @@ -120,8 +112,8 @@ one three four` diff := UnifiedDiff{ - A: splitLines(a), - B: splitLines(b), + A: SplitLines(a), + B: SplitLines(b), FromFile: "Original", FromDate: "2005-01-26 23:30:50", ToFile: "Current", @@ -158,8 +150,8 @@ one tree four` diff := ContextDiff{ - A: splitLines(a), - B: splitLines(b), + A: SplitLines(a), + B: SplitLines(b), FromFile: "Original", ToFile: "Current", Context: 3, @@ -309,13 +301,13 @@ func TestOutputFormatTabDelimiter(t *testing.T) { } ud, err := GetUnifiedDiffString(diff) assertEqual(t, err, nil) - assertEqual(t, splitLines(ud)[:2], []string{ + assertEqual(t, SplitLines(ud)[:2], []string{ "--- Original\t2005-01-26 23:30:50\n", "+++ Current\t2010-04-12 10:20:52\n", }) cd, err := GetContextDiffString(ContextDiff(diff)) assertEqual(t, err, nil) - assertEqual(t, splitLines(cd)[:2], []string{ + assertEqual(t, SplitLines(cd)[:2], []string{ "*** Original\t2005-01-26 23:30:50\n", "--- Current\t2010-04-12 10:20:52\n", }) @@ -331,9 +323,9 @@ func TestOutputFormatNoTrailingTabOnEmptyFiledate(t *testing.T) { } ud, err := GetUnifiedDiffString(diff) assertEqual(t, err, nil) - assertEqual(t, splitLines(ud)[:2], []string{"--- Original\n", "+++ Current\n"}) + assertEqual(t, SplitLines(ud)[:2], []string{"--- Original\n", "+++ Current\n"}) cd, err := GetContextDiffString(ContextDiff(diff)) assertEqual(t, err, nil) - assertEqual(t, splitLines(cd)[:2], []string{"*** Original\n", "--- Current\n"}) + assertEqual(t, SplitLines(cd)[:2], []string{"*** Original\n", "--- Current\n"}) } From 4d91f93589497b4a43be12f5039d5f2983ae56ad Mon Sep 17 00:00:00 2001 From: Patrick Mezard Date: Sat, 23 Nov 2013 20:53:50 +0100 Subject: [PATCH 006/178] README: make it less experimental, add examples --- README.md | 46 ++++++++++++++++++++++++++++++++++++++++------ difflib/difflib.go | 2 ++ 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index aa7dba9df..937005e65 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,47 @@ -Here is a partial port of python 3 difflib package. Its main goal was to -make available a unified diff implementation, mostly for testing purposes. +go-difflib +========== -The following class and functions have be ported: +Go-difflib is a partial port of python 3 difflib package. Its main goal +was to make unified and context diff available in pure Go, mostly for +testing purposes. + +The following class and functions (and related tests) have be ported: * `SequenceMatcher` * `unified_diff()` * `context_diff()` -Related doctests and unittests have been ported as well. +## Installation + +```bash +$ go get github.com/pmezard/go-difflib/difflib +``` + +### Quick Start + +Diffs are configured with Unified (or ContextDiff) structures, and can +be output to an io.Writer or returned as a string. + +```Go +diff := UnifiedDiff{ + A: difflib.SplitLines("foo\nbar\n"), + B: difflib.SplitLines("foo\nbaz\n"), + FromFile: "Original", + ToFile: "Current", + Context: 3, +} +text, _ := GetUnifiedDiffString(diff) +fmt.Printf(text) +``` + +would output: + +``` +--- Original ++++ Current +@@ -1,3 +1,3 @@ + foo +-bar ++baz +``` -I have barely used to code yet so do not consider it being production-ready. -The API is likely to evolve too. diff --git a/difflib/difflib.go b/difflib/difflib.go index e5221e450..5d3d44451 100644 --- a/difflib/difflib.go +++ b/difflib/difflib.go @@ -7,6 +7,8 @@ // // - unified_diff // +// - context_diff +// // Getting unified diffs was the main goal of the port. Keep in mind this code // is mostly suitable to output text differences in a human friendly way, there // are no guarantees generated diffs are consumable by patch(1). From 6fb7d10580f6b3b7b131ff4bb8edfb866e1335e6 Mon Sep 17 00:00:00 2001 From: Patrick Mezard Date: Sat, 23 Nov 2013 21:08:37 +0100 Subject: [PATCH 007/178] difflib: turn some tests into examples, fix documentation --- difflib/difflib.go | 9 +++--- difflib/difflib_test.go | 70 +++++++++++++++++------------------------ 2 files changed, 34 insertions(+), 45 deletions(-) diff --git a/difflib/difflib.go b/difflib/difflib.go index 5d3d44451..20925c64c 100644 --- a/difflib/difflib.go +++ b/difflib/difflib.go @@ -363,10 +363,11 @@ func (m *SequenceMatcher) GetMatchingBlocks() []Match { // The tags are characters, with these meanings: // // 'r' (replace): a[i1:i2] should be replaced by b[j1:j2] -// 'd' (delete): a[i1:i2] should be deleted. -// Note that j1==j2 in this case. -// 'i' (insert): b[j1:j2] should be inserted at a[i1:i1]. -// Note that i1==i2 in this case. +// +// 'd' (delete): a[i1:i2] should be deleted, j1==j2 in this case. +// +// 'i' (insert): b[j1:j2] should be inserted at a[i1:i1], i1==i2 in this case. +// // 'e' (equal): a[i1:i2] == b[j1:j2] func (m *SequenceMatcher) GetOpCodes() []OpCode { if m.opCodes != nil { diff --git a/difflib/difflib_test.go b/difflib/difflib_test.go index b7ea0a82d..3924e801d 100644 --- a/difflib/difflib_test.go +++ b/difflib/difflib_test.go @@ -102,7 +102,7 @@ group } } -func TestUnifiedDiff(t *testing.T) { +func ExampleGetUnifiedDiffString() { a := `one two three @@ -120,27 +120,20 @@ four` ToDate: "2010-04-02 10:20:52", Context: 3, } - result, err := GetUnifiedDiffString(diff) - if err != nil { - t.Errorf("unified diff failed: %s", err) - } - expected := `--- Original\t2005-01-26 23:30:50 -+++ Current\t2010-04-02 10:20:52 -@@ -1,4 +1,4 @@ -+zero - one --two - three - four -` - // TABs are a pain to preserve through editors - expected = strings.Replace(expected, "\\t", "\t", -1) - if expected != result { - t.Errorf("unexpected diff result:\n%s", result) - } + result, _ := GetUnifiedDiffString(diff) + fmt.Printf(strings.Replace(result, "\t", " ", -1)) + // Output: + // --- Original 2005-01-26 23:30:50 + // +++ Current 2010-04-02 10:20:52 + // @@ -1,4 +1,4 @@ + // +zero + // one + // -two + // three + // four } -func TestContextDiff(t *testing.T) { +func ExampleGetContextDiffString() { a := `one two three @@ -157,27 +150,22 @@ four` Context: 3, Eol: "\n", } - result, err := GetContextDiffString(diff) - assertEqual(t, err, nil) - expected := `*** Original ---- Current -*************** -*** 1,4 **** - one -! two -! three - four ---- 1,4 ---- -+ zero - one -! tree - four -` - // TABs are a pain to preserve through editors - expected = strings.Replace(expected, "\\t", "\t", -1) - if expected != result { - t.Errorf("unexpected diff result:\n%s", result) - } + result, _ := GetContextDiffString(diff) + fmt.Printf(strings.Replace(result, "\t", " ", -1)) + // Output: + // *** Original + // --- Current + // *************** + // *** 1,4 **** + // one + // ! two + // ! three + // four + // --- 1,4 ---- + // + zero + // one + // ! tree + // four } func rep(s string, count int) string { From a77cab6ef25e3a78c14c1b799cf2da92815d7664 Mon Sep 17 00:00:00 2001 From: Patrick Mezard Date: Sat, 23 Nov 2013 21:16:25 +0100 Subject: [PATCH 008/178] difflib: extract summary line from package documentation --- difflib/difflib.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/difflib/difflib.go b/difflib/difflib.go index 20925c64c..60ad7ff50 100644 --- a/difflib/difflib.go +++ b/difflib/difflib.go @@ -1,5 +1,6 @@ -// Package difflib is a partial port of Python difflib module. It provides tools -// to compare sequences of strings and generate textual diffs. +// Package difflib is a partial port of Python difflib module. +// +// It provides tools to compare sequences of strings and generate textual diffs. // // The following class and functions have been ported: // From 8fee7c092072bf96cc63e29dff195c0d721d4162 Mon Sep 17 00:00:00 2001 From: Patrick Mezard Date: Sun, 19 Apr 2015 18:35:27 +0200 Subject: [PATCH 009/178] Add travis configuration file --- .travis.yml | 5 +++++ README.md | 2 ++ 2 files changed, 7 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..4e76534c1 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,5 @@ +language: go +go: + - 1.4 + - tip + diff --git a/README.md b/README.md index 937005e65..65887a659 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ go-difflib ========== +[![Build Status](https://travis-ci.org/pmezard/go-difflib.png?branch=master)](https://travis-ci.org/pmezard/go-difflib) + Go-difflib is a partial port of python 3 difflib package. Its main goal was to make unified and context diff available in pure Go, mostly for testing purposes. From b65e32b7e1770d0bf8ab0491dc8712baa40b4b16 Mon Sep 17 00:00:00 2001 From: Robert Williamson Date: Sat, 9 May 2015 17:21:22 -0500 Subject: [PATCH 010/178] difflib: optimize SplitLines --- difflib/difflib.go | 6 ++---- difflib/difflib_test.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/difflib/difflib.go b/difflib/difflib.go index 60ad7ff50..64cc40fe1 100644 --- a/difflib/difflib.go +++ b/difflib/difflib.go @@ -752,9 +752,7 @@ func GetContextDiffString(diff ContextDiff) (string, error) { // Split a string on "\n" while preserving them. The output can be used // as input for UnifiedDiff and ContextDiff structures. func SplitLines(s string) []string { - lines := []string{} - for _, line := range strings.Split(s, "\n") { - lines = append(lines, line+"\n") - } + lines := strings.SplitAfter(s, "\n") + lines[len(lines)-1] += "\n" return lines } diff --git a/difflib/difflib_test.go b/difflib/difflib_test.go index 3924e801d..94670bea3 100644 --- a/difflib/difflib_test.go +++ b/difflib/difflib_test.go @@ -317,3 +317,36 @@ func TestOutputFormatNoTrailingTabOnEmptyFiledate(t *testing.T) { assertEqual(t, err, nil) assertEqual(t, SplitLines(cd)[:2], []string{"*** Original\n", "--- Current\n"}) } + +func TestSplitLines(t *testing.T) { + allTests := []struct { + input string + want []string + }{ + {"foo", []string{"foo\n"}}, + {"foo\nbar", []string{"foo\n", "bar\n"}}, + {"foo\nbar\n", []string{"foo\n", "bar\n", "\n"}}, + } + for _, test := range allTests { + assertEqual(t, SplitLines(test.input), test.want) + } +} + +func benchmarkSplitLines(b *testing.B, count int) { + str := strings.Repeat("foo\n", count) + + b.ResetTimer() + + n := 0 + for i := 0; i < b.N; i++ { + n += len(SplitLines(str)) + } +} + +func BenchmarkSplitLines100(b *testing.B) { + benchmarkSplitLines(b, 100) +} + +func BenchmarkSplitLines10000(b *testing.B) { + benchmarkSplitLines(b, 10000) +} From ac475e89e25c7c9553d111ef5b89aa1a33deb363 Mon Sep 17 00:00:00 2001 From: Patrick Mezard Date: Tue, 27 Oct 2015 13:37:14 +0100 Subject: [PATCH 011/178] .travis.yml: update stable go version to 1.5 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4e76534c1..90c9c6f91 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: go go: - - 1.4 + - 1.5 - tip From dedecaa78879aa0f9a8ee9544957fe46523081bb Mon Sep 17 00:00:00 2001 From: Patrick Mezard Date: Wed, 28 Oct 2015 10:34:38 +0100 Subject: [PATCH 012/178] README: add link to godoc.org --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 65887a659..e87f307ed 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ go-difflib ========== [![Build Status](https://travis-ci.org/pmezard/go-difflib.png?branch=master)](https://travis-ci.org/pmezard/go-difflib) +[![GoDoc](https://godoc.org/github.com/pmezard/go-difflib/difflib?status.svg)](https://godoc.org/github.com/pmezard/go-difflib/difflib) Go-difflib is a partial port of python 3 difflib package. Its main goal was to make unified and context diff available in pure Go, mostly for From 901e4f8c4647fc73b0789417f91c73d5da736370 Mon Sep 17 00:00:00 2001 From: visualfc Date: Mon, 7 Dec 2015 21:12:49 +0800 Subject: [PATCH 013/178] fix WriteUnifiedDiff fmt.Sprintf format error --- difflib/difflib.go | 18 ++++++---- difflib/difflib_test.go | 80 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 88 insertions(+), 10 deletions(-) diff --git a/difflib/difflib.go b/difflib/difflib.go index 64cc40fe1..a534525a2 100644 --- a/difflib/difflib.go +++ b/difflib/difflib.go @@ -559,10 +559,14 @@ type UnifiedDiff struct { func WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error { buf := bufio.NewWriter(writer) defer buf.Flush() - w := func(format string, args ...interface{}) error { + wf := func(format string, args ...interface{}) error { _, err := buf.WriteString(fmt.Sprintf(format, args...)) return err } + ws := func(s string) error { + _, err := buf.WriteString(s) + return err + } if len(diff.Eol) == 0 { diff.Eol = "\n" @@ -581,11 +585,11 @@ func WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error { if len(diff.ToDate) > 0 { toDate = "\t" + diff.ToDate } - err := w("--- %s%s%s", diff.FromFile, fromDate, diff.Eol) + err := wf("--- %s%s%s", diff.FromFile, fromDate, diff.Eol) if err != nil { return err } - err = w("+++ %s%s%s", diff.ToFile, toDate, diff.Eol) + err = wf("+++ %s%s%s", diff.ToFile, toDate, diff.Eol) if err != nil { return err } @@ -593,14 +597,14 @@ func WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error { first, last := g[0], g[len(g)-1] range1 := formatRangeUnified(first.I1, last.I2) range2 := formatRangeUnified(first.J1, last.J2) - if err := w("@@ -%s +%s @@%s", range1, range2, diff.Eol); err != nil { + if err := wf("@@ -%s +%s @@%s", range1, range2, diff.Eol); err != nil { return err } for _, c := range g { i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 if c.Tag == 'e' { for _, line := range diff.A[i1:i2] { - if err := w(" " + line); err != nil { + if err := ws(" " + line); err != nil { return err } } @@ -608,14 +612,14 @@ func WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error { } if c.Tag == 'r' || c.Tag == 'd' { for _, line := range diff.A[i1:i2] { - if err := w("-" + line); err != nil { + if err := ws("-" + line); err != nil { return err } } } if c.Tag == 'r' || c.Tag == 'i' { for _, line := range diff.B[j1:j2] { - if err := w("+" + line); err != nil { + if err := ws("+" + line); err != nil { return err } } diff --git a/difflib/difflib_test.go b/difflib/difflib_test.go index 94670bea3..eb1cccc33 100644 --- a/difflib/difflib_test.go +++ b/difflib/difflib_test.go @@ -102,11 +102,48 @@ group } } -func ExampleGetUnifiedDiffString() { +func ExampleGetUnifiedDiffCode() { a := `one two three +four +fmt.Printf("%s,%T",a,b) +` + b := `zero +one +three four` + diff := UnifiedDiff{ + A: SplitLines(a), + B: SplitLines(b), + FromFile: "Original", + FromDate: "2005-01-26 23:30:50", + ToFile: "Current", + ToDate: "2010-04-02 10:20:52", + Context: 3, + } + result, _ := GetUnifiedDiffString(diff) + fmt.Println(strings.Replace(result, "\t", " ", -1)) + // Output: + // --- Original 2005-01-26 23:30:50 + // +++ Current 2010-04-02 10:20:52 + // @@ -1,6 +1,4 @@ + // +zero + // one + // -two + // three + // four + // -fmt.Printf("%s,%T",a,b) + // - +} + +func ExampleGetUnifiedDiffString() { + a := `one +two +three +four +fmt.Printf("%s,%T",a,b) +` b := `zero one three @@ -121,16 +158,53 @@ four` Context: 3, } result, _ := GetUnifiedDiffString(diff) - fmt.Printf(strings.Replace(result, "\t", " ", -1)) + fmt.Println(strings.Replace(result, "\t", " ", -1)) // Output: // --- Original 2005-01-26 23:30:50 // +++ Current 2010-04-02 10:20:52 - // @@ -1,4 +1,4 @@ + // @@ -1,6 +1,4 @@ // +zero // one // -two // three // four + // -fmt.Printf("%s,%T",a,b) + // - +} + +func ExampleGetContextDiffCode() { + a := `one +two +three +four` + b := `zero +one +tree +four` + diff := ContextDiff{ + A: SplitLines(a), + B: SplitLines(b), + FromFile: "Original", + ToFile: "Current", + Context: 3, + Eol: "\n", + } + result, _ := GetContextDiffString(diff) + fmt.Printf(strings.Replace(result, "\t", " ", -1)) + // Output: + // *** Original + // --- Current + // *************** + // *** 1,4 **** + // one + // ! two + // ! three + // four + // --- 1,4 ---- + // + zero + // one + // ! tree + // four } func ExampleGetContextDiffString() { From 017ffa654c626b327474628673a99f0adb51e8c5 Mon Sep 17 00:00:00 2001 From: visualfc Date: Mon, 7 Dec 2015 21:28:13 +0800 Subject: [PATCH 014/178] fix WriteContextDiff fmt.Sprintf format error --- difflib/difflib.go | 22 ++++++++++-------- difflib/difflib_test.go | 49 ++++++----------------------------------- 2 files changed, 20 insertions(+), 51 deletions(-) diff --git a/difflib/difflib.go b/difflib/difflib.go index a534525a2..5dd76b809 100644 --- a/difflib/difflib.go +++ b/difflib/difflib.go @@ -673,13 +673,17 @@ func WriteContextDiff(writer io.Writer, diff ContextDiff) error { buf := bufio.NewWriter(writer) defer buf.Flush() var diffErr error - w := func(format string, args ...interface{}) { + wf := func(format string, args ...interface{}) { _, err := buf.WriteString(fmt.Sprintf(format, args...)) if diffErr == nil && err != nil { diffErr = err } } - + ws := func(s string) error { + _, err := buf.WriteString(s) + return err + } + if len(diff.Eol) == 0 { diff.Eol = "\n" } @@ -704,15 +708,15 @@ func WriteContextDiff(writer io.Writer, diff ContextDiff) error { if len(diff.ToDate) > 0 { toDate = "\t" + diff.ToDate } - w("*** %s%s%s", diff.FromFile, fromDate, diff.Eol) - w("--- %s%s%s", diff.ToFile, toDate, diff.Eol) + wf("*** %s%s%s", diff.FromFile, fromDate, diff.Eol) + wf("--- %s%s%s", diff.ToFile, toDate, diff.Eol) } first, last := g[0], g[len(g)-1] - w("***************" + diff.Eol) + wf("***************" + diff.Eol) range1 := formatRangeContext(first.I1, last.I2) - w("*** %s ****%s", range1, diff.Eol) + wf("*** %s ****%s", range1, diff.Eol) for _, c := range g { if c.Tag == 'r' || c.Tag == 'd' { for _, cc := range g { @@ -720,7 +724,7 @@ func WriteContextDiff(writer io.Writer, diff ContextDiff) error { continue } for _, line := range diff.A[cc.I1:cc.I2] { - w(prefix[cc.Tag] + line) + ws(prefix[cc.Tag] + line) } } break @@ -728,7 +732,7 @@ func WriteContextDiff(writer io.Writer, diff ContextDiff) error { } range2 := formatRangeContext(first.J1, last.J2) - w("--- %s ----%s", range2, diff.Eol) + wf("--- %s ----%s", range2, diff.Eol) for _, c := range g { if c.Tag == 'r' || c.Tag == 'i' { for _, cc := range g { @@ -736,7 +740,7 @@ func WriteContextDiff(writer io.Writer, diff ContextDiff) error { continue } for _, line := range diff.B[cc.J1:cc.J2] { - w(prefix[cc.Tag] + line) + ws(prefix[cc.Tag] + line) } } break diff --git a/difflib/difflib_test.go b/difflib/difflib_test.go index eb1cccc33..4d462ec20 100644 --- a/difflib/difflib_test.go +++ b/difflib/difflib_test.go @@ -107,43 +107,7 @@ func ExampleGetUnifiedDiffCode() { two three four -fmt.Printf("%s,%T",a,b) -` - b := `zero -one -three -four` - diff := UnifiedDiff{ - A: SplitLines(a), - B: SplitLines(b), - FromFile: "Original", - FromDate: "2005-01-26 23:30:50", - ToFile: "Current", - ToDate: "2010-04-02 10:20:52", - Context: 3, - } - result, _ := GetUnifiedDiffString(diff) - fmt.Println(strings.Replace(result, "\t", " ", -1)) - // Output: - // --- Original 2005-01-26 23:30:50 - // +++ Current 2010-04-02 10:20:52 - // @@ -1,6 +1,4 @@ - // +zero - // one - // -two - // three - // four - // -fmt.Printf("%s,%T",a,b) - // - -} - -func ExampleGetUnifiedDiffString() { - a := `one -two -three -four -fmt.Printf("%s,%T",a,b) -` +fmt.Printf("%s,%T",a,b)` b := `zero one three @@ -162,21 +126,21 @@ four` // Output: // --- Original 2005-01-26 23:30:50 // +++ Current 2010-04-02 10:20:52 - // @@ -1,6 +1,4 @@ + // @@ -1,5 +1,4 @@ // +zero // one // -two // three // four // -fmt.Printf("%s,%T",a,b) - // - } func ExampleGetContextDiffCode() { a := `one two three -four` +four +fmt.Printf("%s,%T",a,b)` b := `zero one tree @@ -190,16 +154,17 @@ four` Eol: "\n", } result, _ := GetContextDiffString(diff) - fmt.Printf(strings.Replace(result, "\t", " ", -1)) + fmt.Print(strings.Replace(result, "\t", " ", -1)) // Output: // *** Original // --- Current // *************** - // *** 1,4 **** + // *** 1,5 **** // one // ! two // ! three // four + // - fmt.Printf("%s,%T",a,b) // --- 1,4 ---- // + zero // one From 7b7f521a6ee157ed1d5ae612990b9766f495262d Mon Sep 17 00:00:00 2001 From: Patrick Mezard Date: Mon, 7 Dec 2015 19:24:13 +0100 Subject: [PATCH 015/178] difflib: fix error handling in WriteContextDiff --- difflib/difflib.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/difflib/difflib.go b/difflib/difflib.go index 5dd76b809..e5005daaa 100644 --- a/difflib/difflib.go +++ b/difflib/difflib.go @@ -679,11 +679,13 @@ func WriteContextDiff(writer io.Writer, diff ContextDiff) error { diffErr = err } } - ws := func(s string) error { + ws := func(s string) { _, err := buf.WriteString(s) - return err + if diffErr == nil && err != nil { + diffErr = err + } } - + if len(diff.Eol) == 0 { diff.Eol = "\n" } @@ -713,7 +715,7 @@ func WriteContextDiff(writer io.Writer, diff ContextDiff) error { } first, last := g[0], g[len(g)-1] - wf("***************" + diff.Eol) + ws("***************" + diff.Eol) range1 := formatRangeContext(first.I1, last.I2) wf("*** %s ****%s", range1, diff.Eol) From 509b2ff0f087b5cc442896c1246b9fc2bebe2c81 Mon Sep 17 00:00:00 2001 From: Andrey Petrov Date: Tue, 8 Dec 2015 16:27:26 -0500 Subject: [PATCH 016/178] Skip file headers if FromFile/ToFile are empty --- difflib/difflib.go | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/difflib/difflib.go b/difflib/difflib.go index e5005daaa..003e99fad 100644 --- a/difflib/difflib.go +++ b/difflib/difflib.go @@ -585,13 +585,15 @@ func WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error { if len(diff.ToDate) > 0 { toDate = "\t" + diff.ToDate } - err := wf("--- %s%s%s", diff.FromFile, fromDate, diff.Eol) - if err != nil { - return err - } - err = wf("+++ %s%s%s", diff.ToFile, toDate, diff.Eol) - if err != nil { - return err + if diff.FromFile != "" || diff.ToFile != "" { + err := wf("--- %s%s%s", diff.FromFile, fromDate, diff.Eol) + if err != nil { + return err + } + err = wf("+++ %s%s%s", diff.ToFile, toDate, diff.Eol) + if err != nil { + return err + } } } first, last := g[0], g[len(g)-1] @@ -710,8 +712,10 @@ func WriteContextDiff(writer io.Writer, diff ContextDiff) error { if len(diff.ToDate) > 0 { toDate = "\t" + diff.ToDate } - wf("*** %s%s%s", diff.FromFile, fromDate, diff.Eol) - wf("--- %s%s%s", diff.ToFile, toDate, diff.Eol) + if diff.FromFile != "" || diff.ToFile != "" { + wf("*** %s%s%s", diff.FromFile, fromDate, diff.Eol) + wf("--- %s%s%s", diff.ToFile, toDate, diff.Eol) + } } first, last := g[0], g[len(g)-1] From 4d60064e8c5ac716dd73fad04e5e72cb5ce0d2c5 Mon Sep 17 00:00:00 2001 From: Patrick Mezard Date: Sun, 10 Jan 2016 11:52:04 +0100 Subject: [PATCH 017/178] tests: test header is omitted if file names are empty --- difflib/difflib_test.go | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/difflib/difflib_test.go b/difflib/difflib_test.go index 4d462ec20..d72511962 100644 --- a/difflib/difflib_test.go +++ b/difflib/difflib_test.go @@ -357,6 +357,41 @@ func TestOutputFormatNoTrailingTabOnEmptyFiledate(t *testing.T) { assertEqual(t, SplitLines(cd)[:2], []string{"*** Original\n", "--- Current\n"}) } +func TestOmitFilenames(t *testing.T) { + diff := UnifiedDiff{ + A: SplitLines("o\nn\ne\n"), + B: SplitLines("t\nw\no\n"), + Eol: "\n", + } + ud, err := GetUnifiedDiffString(diff) + assertEqual(t, err, nil) + assertEqual(t, SplitLines(ud), []string{ + "@@ -0,0 +1,2 @@\n", + "+t\n", + "+w\n", + "@@ -2,2 +3,0 @@\n", + "-n\n", + "-e\n", + "\n", + }) + + cd, err := GetContextDiffString(ContextDiff(diff)) + assertEqual(t, err, nil) + assertEqual(t, SplitLines(cd), []string{ + "***************\n", + "*** 0 ****\n", + "--- 1,2 ----\n", + "+ t\n", + "+ w\n", + "***************\n", + "*** 2,3 ****\n", + "- n\n", + "- e\n", + "--- 3 ----\n", + "\n", + }) +} + func TestSplitLines(t *testing.T) { allTests := []struct { input string From 4d7e5c1199c6c6f41571643a498177aa237b284a Mon Sep 17 00:00:00 2001 From: Justin Buchanan Date: Tue, 2 Jan 2018 03:16:43 -0800 Subject: [PATCH 018/178] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e87f307ed..2d0f9849f 100644 --- a/README.md +++ b/README.md @@ -26,14 +26,14 @@ Diffs are configured with Unified (or ContextDiff) structures, and can be output to an io.Writer or returned as a string. ```Go -diff := UnifiedDiff{ +diff := difflib.UnifiedDiff{ A: difflib.SplitLines("foo\nbar\n"), B: difflib.SplitLines("foo\nbaz\n"), FromFile: "Original", ToFile: "Current", Context: 3, } -text, _ := GetUnifiedDiffString(diff) +text, _ := difflib.GetUnifiedDiffString(diff) fmt.Printf(text) ``` From 1ef1646f464bff6853dfa4c32750886762dc023a Mon Sep 17 00:00:00 2001 From: Patrick Mezard Date: Wed, 26 Dec 2018 11:52:15 +0100 Subject: [PATCH 019/178] README: end of maintenance notice. --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e87f307ed..120d776c3 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,10 @@ go-difflib ========== -[![Build Status](https://travis-ci.org/pmezard/go-difflib.png?branch=master)](https://travis-ci.org/pmezard/go-difflib) +THIS PACKAGE IS NO LONGER MAINTAINED. + +At this point, I have no longer the time nor the interest to work on go-difflib. I apologize for the inconvenience. + [![GoDoc](https://godoc.org/github.com/pmezard/go-difflib/difflib?status.svg)](https://godoc.org/github.com/pmezard/go-difflib/difflib) Go-difflib is a partial port of python 3 difflib package. Its main goal From fca3d27b089d3a454fd37b7170c3c4a36ee2babd Mon Sep 17 00:00:00 2001 From: Patrick Mezard Date: Wed, 26 Dec 2018 11:53:00 +0100 Subject: [PATCH 020/178] travis: remove travis integration --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 90c9c6f91..000000000 --- a/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: go -go: - - 1.5 - - tip - From 0e5b59666aca1b397b46d5ba14b1ae00cb5e93ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ania=20Kapu=C5=9Bci=C5=84ska?= Date: Tue, 16 Mar 2021 01:40:28 +0000 Subject: [PATCH 021/178] Fix failure message formatting for Positive and Negative asserts --- assert/assertion_compare.go | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/assert/assertion_compare.go b/assert/assertion_compare.go index 7e19eba09..07a74926f 100644 --- a/assert/assertion_compare.go +++ b/assert/assertion_compare.go @@ -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 { @@ -472,7 +478,7 @@ func compareTwoValues(t TestingT, e1 interface{}, e2 interface{}, allowedCompare } if !containsValue(allowedComparesResults, compareResult) { - return Fail(t, fmt.Sprintf(failMessage, e1, e2), msgAndArgs...) + return Fail(t, failMessage, msgAndArgs...) } return true From 42d887f28b4602ac3570597162aed14af8f1d909 Mon Sep 17 00:00:00 2001 From: Reda Chlieh Date: Thu, 11 Apr 2024 22:54:14 +0200 Subject: [PATCH 022/178] Remove type validation in EqualExportedValues --- assert/assertions.go | 15 ------------ assert/assertions_test.go | 50 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 15 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index 8109ef2a8..5a2b29c4a 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -619,21 +619,6 @@ func EqualExportedValues(t TestingT, expected, actual interface{}, msgAndArgs .. return Fail(t, fmt.Sprintf("Types expected to match exactly\n\t%v != %v", aType, bType), msgAndArgs...) } - if aType.Kind() == reflect.Ptr { - aType = aType.Elem() - } - if bType.Kind() == reflect.Ptr { - bType = bType.Elem() - } - - if aType.Kind() != reflect.Struct { - return Fail(t, fmt.Sprintf("Types expected to both be struct or pointer to struct \n\t%v != %v", aType.Kind(), reflect.Struct), msgAndArgs...) - } - - if bType.Kind() != reflect.Struct { - return Fail(t, fmt.Sprintf("Types expected to both be struct or pointer to struct \n\t%v != %v", bType.Kind(), reflect.Struct), msgAndArgs...) - } - expected = copyExportedFields(expected) actual = copyExportedFields(actual) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 0ae36cd92..1bcf53cf9 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -449,6 +449,56 @@ func TestEqualExportedValues(t *testing.T) { + Exported: (int) 1, notExported: (interface {}) `, }, + { + value1: []int{1, 2}, + value2: []int{1, 2}, + expectedEqual: true, + }, + { + value1: []int{1, 2}, + value2: []int{1, 3}, + expectedEqual: false, + expectedFail: ` + Diff: + --- Expected + +++ Actual + @@ -2,3 +2,3 @@ + (int) 1, + - (int) 2 + + (int) 3 + }`, + }, + { + value1: []*Nested{ + {1, 2}, + {3, 4}, + }, + value2: []*Nested{ + {1, "a"}, + {3, "b"}, + }, + expectedEqual: true, + }, + { + value1: []*Nested{ + {1, 2}, + {3, 4}, + }, + value2: []*Nested{ + {1, "a"}, + {2, "b"}, + }, + expectedEqual: false, + expectedFail: ` + Diff: + --- Expected + +++ Actual + @@ -6,3 +6,3 @@ + (*assert.Nested)({ + - Exported: (int) 3, + + Exported: (int) 2, + notExported: (interface {}) `, + }, } for _, c := range cases { From d4a63f5b89ec8c392fe4066e3a91b48dc10fe92f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Thu, 7 Mar 2024 00:23:10 +0100 Subject: [PATCH 023/178] mock: simplify implementation of FunctionalOptions Remove unnecessary use of reflect in the implementation of mock.FunctionalOptions(). --- mock/mock.go | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/mock/mock.go b/mock/mock.go index 876371d94..9062f0153 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -803,21 +803,20 @@ func IsType(t interface{}) *IsTypeArgument { return &IsTypeArgument{t: reflect.TypeOf(t)} } -// FunctionalOptionsArgument is a struct that contains the type and value of an functional option argument -// for use when type checking. +// FunctionalOptionsArgument contains a list of functional options arguments +// expected for use when matching a list of arguments. type FunctionalOptionsArgument struct { - value interface{} + values []interface{} } // String returns the string representation of FunctionalOptionsArgument func (f *FunctionalOptionsArgument) String() string { var name string - tValue := reflect.ValueOf(f.value) - if tValue.Len() > 0 { - name = "[]" + reflect.TypeOf(tValue.Index(0).Interface()).String() + if len(f.values) > 0 { + name = "[]" + reflect.TypeOf(f.values[0]).String() } - return strings.Replace(fmt.Sprintf("%#v", f.value), "[]interface {}", name, 1) + return strings.Replace(fmt.Sprintf("%#v", f.values), "[]interface {}", name, 1) } // FunctionalOptions returns an [FunctionalOptionsArgument] object containing @@ -825,10 +824,10 @@ func (f *FunctionalOptionsArgument) String() string { // // For example: // -// Assert(t, FunctionalOptions(foo.Opt1("strValue"), foo.Opt2(613))) -func FunctionalOptions(value ...interface{}) *FunctionalOptionsArgument { +// args.Assert(t, FunctionalOptions(foo.Opt1("strValue"), foo.Opt2(613))) +func FunctionalOptions(values ...interface{}) *FunctionalOptionsArgument { return &FunctionalOptionsArgument{ - value: value, + values: values, } } @@ -982,20 +981,17 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, expected.t.Name(), actualT.Name(), actualFmt) } case *FunctionalOptionsArgument: - t := expected.value - var name string - tValue := reflect.ValueOf(t) - if tValue.Len() > 0 { - name = "[]" + reflect.TypeOf(tValue.Index(0).Interface()).String() + if len(expected.values) > 0 { + name = "[]" + reflect.TypeOf(expected.values[0]).String() } - tName := reflect.TypeOf(t).Name() - if name != reflect.TypeOf(actual).String() && tValue.Len() != 0 { + const tName = "[]interface{}" + if name != reflect.TypeOf(actual).String() && len(expected.values) != 0 { differences++ output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, tName, reflect.TypeOf(actual).Name(), actualFmt) } else { - if ef, af := assertOpts(t, actual); ef == "" && af == "" { + if ef, af := assertOpts(expected.values, actual); ef == "" && af == "" { // match output = fmt.Sprintf("%s\t%d: PASS: %s == %s\n", output, i, tName, tName) } else { From 9326036bf5a035bb295949d779b8bd9996797801 Mon Sep 17 00:00:00 2001 From: Simon Schulte Date: Thu, 13 Jun 2024 06:52:14 +0200 Subject: [PATCH 024/178] Generate better comments for require package The comments for the require package were just copied over from the assert package when generating the functions. This could lead to confusion because 1. The code-examples were showing examples using the assert package instead of the require package 2. The function-documentation was not mentioning that the functions were calling `t.FailNow()` which is some critical information when using this package. --- _codegen/main.go | 4 +- require/require.go | 600 ++++++++++++++++++++++++++++------------ require/require.go.tmpl | 3 +- 3 files changed, 423 insertions(+), 184 deletions(-) diff --git a/_codegen/main.go b/_codegen/main.go index 11cdbfbc6..7158afc9f 100644 --- a/_codegen/main.go +++ b/_codegen/main.go @@ -107,7 +107,9 @@ func parseTemplates() (*template.Template, *template.Template, error) { } funcTemplate = string(f) } - tmpl, err := template.New("function").Parse(funcTemplate) + tmpl, err := template.New("function").Funcs(template.FuncMap{ + "replace": strings.ReplaceAll, + }).Parse(funcTemplate) if err != nil { return nil, nil, err } diff --git a/require/require.go b/require/require.go index 59b87c8e3..ed6bad911 100644 --- a/require/require.go +++ b/require/require.go @@ -10,6 +10,7 @@ import ( ) // Condition uses a Comparison to assert a complex condition. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Condition(t TestingT, comp assert.Comparison, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -21,6 +22,7 @@ func Condition(t TestingT, comp assert.Comparison, msgAndArgs ...interface{}) { } // Conditionf uses a Comparison to assert a complex condition. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Conditionf(t TestingT, comp assert.Comparison, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -34,9 +36,11 @@ func Conditionf(t TestingT, comp assert.Comparison, msg string, args ...interfac // Contains asserts that the specified string, list(array, slice...) or map contains the // specified substring or element. // -// assert.Contains(t, "Hello World", "World") -// assert.Contains(t, ["Hello", "World"], "World") -// assert.Contains(t, {"Hello": "World"}, "Hello") +// require.Contains(t, "Hello World", "World") +// require.Contains(t, ["Hello", "World"], "World") +// require.Contains(t, {"Hello": "World"}, "Hello") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -50,9 +54,11 @@ func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...int // Containsf asserts that the specified string, list(array, slice...) or map contains the // specified substring or element. // -// assert.Containsf(t, "Hello World", "World", "error message %s", "formatted") -// assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted") -// assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted") +// require.Containsf(t, "Hello World", "World", "error message %s", "formatted") +// require.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted") +// require.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -65,6 +71,7 @@ func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args // DirExists checks whether a directory exists in the given path. It also fails // if the path is a file rather a directory or there is an error checking whether it exists. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func DirExists(t TestingT, path string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -77,6 +84,7 @@ func DirExists(t TestingT, path string, msgAndArgs ...interface{}) { // DirExistsf checks whether a directory exists in the given path. It also fails // if the path is a file rather a directory or there is an error checking whether it exists. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func DirExistsf(t TestingT, path string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -91,7 +99,8 @@ func DirExistsf(t TestingT, path string, msg string, args ...interface{}) { // listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, // the number of appearances of each of them in both lists should match. // -// assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2]) +// require.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2]) +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func ElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -106,7 +115,8 @@ func ElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs // listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, // the number of appearances of each of them in both lists should match. // -// assert.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted") +// require.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted") +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -120,7 +130,9 @@ func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string // Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either // a slice or a channel with len == 0. // -// assert.Empty(t, obj) +// require.Empty(t, obj) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -134,7 +146,9 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) { // Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either // a slice or a channel with len == 0. // -// assert.Emptyf(t, obj, "error message %s", "formatted") +// require.Emptyf(t, obj, "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -147,11 +161,12 @@ func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) { // Equal asserts that two objects are equal. // -// assert.Equal(t, 123, 123) +// require.Equal(t, 123, 123) // // 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. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -166,7 +181,9 @@ func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...i // and that it is equal to the provided error. // // actualObj, err := SomeFunction() -// assert.EqualError(t, err, expectedErrorString) +// require.EqualError(t, err, expectedErrorString) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -181,7 +198,9 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte // and that it is equal to the provided error. // // actualObj, err := SomeFunction() -// assert.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted") +// require.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -200,8 +219,10 @@ func EqualErrorf(t TestingT, theError error, errString string, msg string, args // Exported int // notExported int // } -// assert.EqualExportedValues(t, S{1, 2}, S{1, 3}) => true -// assert.EqualExportedValues(t, S{1, 2}, S{2, 3}) => false +// require.EqualExportedValues(t, S{1, 2}, S{1, 3}) => true +// require.EqualExportedValues(t, S{1, 2}, S{2, 3}) => false +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func EqualExportedValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -220,8 +241,10 @@ func EqualExportedValues(t TestingT, expected interface{}, actual interface{}, m // Exported int // notExported int // } -// assert.EqualExportedValuesf(t, S{1, 2}, S{1, 3}, "error message %s", "formatted") => true -// assert.EqualExportedValuesf(t, S{1, 2}, S{2, 3}, "error message %s", "formatted") => false +// require.EqualExportedValuesf(t, S{1, 2}, S{1, 3}, "error message %s", "formatted") => true +// require.EqualExportedValuesf(t, S{1, 2}, S{2, 3}, "error message %s", "formatted") => false +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func EqualExportedValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -235,7 +258,9 @@ func EqualExportedValuesf(t TestingT, expected interface{}, actual interface{}, // EqualValues asserts that two objects are equal or convertible to the larger // type and equal. // -// assert.EqualValues(t, uint32(123), int32(123)) +// require.EqualValues(t, uint32(123), int32(123)) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -249,7 +274,9 @@ func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArg // EqualValuesf asserts that two objects are equal or convertible to the larger // type and equal. // -// assert.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted") +// require.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -262,11 +289,12 @@ func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg stri // Equalf asserts that two objects are equal. // -// assert.Equalf(t, 123, 123, "error message %s", "formatted") +// require.Equalf(t, 123, 123, "error message %s", "formatted") // // 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. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -280,9 +308,11 @@ 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 assert.Error(t, err) { -// assert.Equal(t, expectedError, err) +// if require.Error(t, err) { +// require.Equal(t, expectedError, err) // } +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Error(t TestingT, err error, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -295,6 +325,7 @@ func Error(t TestingT, err error, msgAndArgs ...interface{}) { // ErrorAs asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value. // This is a wrapper for errors.As. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -307,6 +338,7 @@ func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{ // ErrorAsf asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value. // This is a wrapper for errors.As. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -321,7 +353,9 @@ func ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...int // and that the error contains the specified substring. // // actualObj, err := SomeFunction() -// assert.ErrorContains(t, err, expectedErrorSubString) +// require.ErrorContains(t, err, expectedErrorSubString) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -336,7 +370,9 @@ func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...in // and that the error contains the specified substring. // // actualObj, err := SomeFunction() -// assert.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") +// require.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func ErrorContainsf(t TestingT, theError error, contains string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -349,6 +385,7 @@ func ErrorContainsf(t TestingT, theError error, contains string, msg string, arg // ErrorIs asserts that at least one of the errors in err's chain matches target. // This is a wrapper for errors.Is. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func ErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -361,6 +398,7 @@ func ErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) { // ErrorIsf asserts that at least one of the errors in err's chain matches target. // This is a wrapper for errors.Is. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func ErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -374,9 +412,11 @@ 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 assert.Errorf(t, err, "error message %s", "formatted") { -// assert.Equal(t, expectedErrorf, err) +// if require.Errorf(t, err, "error message %s", "formatted") { +// require.Equal(t, expectedErrorf, err) // } +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Errorf(t TestingT, err error, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -390,7 +430,9 @@ func Errorf(t TestingT, err error, msg string, args ...interface{}) { // Eventually asserts that given condition will be met in waitFor time, // periodically checking target function each tick. // -// assert.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond) +// require.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -415,10 +457,12 @@ func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick t // time.Sleep(8*time.Second) // externalValue = true // }() -// assert.EventuallyWithT(t, func(c *assert.CollectT) { +// require.EventuallyWithT(t, func(c *require.CollectT) { // // add assertions as needed; any assertion failure will fail the current tick -// assert.True(c, externalValue, "expected 'externalValue' to be true") +// require.True(c, externalValue, "expected 'externalValue' to be true") // }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func EventuallyWithT(t TestingT, condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -443,10 +487,12 @@ func EventuallyWithT(t TestingT, condition func(collect *assert.CollectT), waitF // time.Sleep(8*time.Second) // externalValue = true // }() -// assert.EventuallyWithTf(t, func(c *assert.CollectT, "error message %s", "formatted") { +// require.EventuallyWithTf(t, func(c *require.CollectT, "error message %s", "formatted") { // // add assertions as needed; any assertion failure will fail the current tick -// assert.True(c, externalValue, "expected 'externalValue' to be true") +// require.True(c, externalValue, "expected 'externalValue' to be true") // }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func EventuallyWithTf(t TestingT, condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -460,7 +506,9 @@ func EventuallyWithTf(t TestingT, condition func(collect *assert.CollectT), wait // Eventuallyf asserts that given condition will be met in waitFor time, // periodically checking target function each tick. // -// assert.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") +// require.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -473,7 +521,9 @@ func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick // Exactly asserts that two objects are equal in value and type. // -// assert.Exactly(t, int32(123), int64(123)) +// require.Exactly(t, int32(123), int64(123)) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -486,7 +536,9 @@ func Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs .. // Exactlyf asserts that two objects are equal in value and type. // -// assert.Exactlyf(t, int32(123), int64(123), "error message %s", "formatted") +// require.Exactlyf(t, int32(123), int64(123), "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -498,6 +550,7 @@ func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, } // Fail reports a failure through +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -509,6 +562,7 @@ func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) { } // FailNow fails test +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -520,6 +574,7 @@ func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) { } // FailNowf fails test +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -531,6 +586,7 @@ func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{} } // Failf reports a failure through +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -543,7 +599,9 @@ func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) { // False asserts that the specified value is false. // -// assert.False(t, myBool) +// require.False(t, myBool) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func False(t TestingT, value bool, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -556,7 +614,9 @@ func False(t TestingT, value bool, msgAndArgs ...interface{}) { // Falsef asserts that the specified value is false. // -// assert.Falsef(t, myBool, "error message %s", "formatted") +// require.Falsef(t, myBool, "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Falsef(t TestingT, value bool, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -569,6 +629,7 @@ func Falsef(t TestingT, value bool, msg string, args ...interface{}) { // FileExists checks whether a file exists in the given path. It also fails if // the path points to a directory or there is an error when trying to check the file. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func FileExists(t TestingT, path string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -581,6 +642,7 @@ func FileExists(t TestingT, path string, msgAndArgs ...interface{}) { // FileExistsf checks whether a file exists in the given path. It also fails if // the path points to a directory or there is an error when trying to check the file. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func FileExistsf(t TestingT, path string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -593,9 +655,11 @@ func FileExistsf(t TestingT, path string, msg string, args ...interface{}) { // Greater asserts that the first element is greater than the second // -// assert.Greater(t, 2, 1) -// assert.Greater(t, float64(2), float64(1)) -// assert.Greater(t, "b", "a") +// require.Greater(t, 2, 1) +// require.Greater(t, float64(2), float64(1)) +// require.Greater(t, "b", "a") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -608,10 +672,12 @@ func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface // GreaterOrEqual asserts that the first element is greater than or equal to the second // -// assert.GreaterOrEqual(t, 2, 1) -// assert.GreaterOrEqual(t, 2, 2) -// assert.GreaterOrEqual(t, "b", "a") -// assert.GreaterOrEqual(t, "b", "b") +// require.GreaterOrEqual(t, 2, 1) +// require.GreaterOrEqual(t, 2, 2) +// require.GreaterOrEqual(t, "b", "a") +// require.GreaterOrEqual(t, "b", "b") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -624,10 +690,12 @@ func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...in // GreaterOrEqualf asserts that the first element is greater than or equal to the second // -// assert.GreaterOrEqualf(t, 2, 1, "error message %s", "formatted") -// assert.GreaterOrEqualf(t, 2, 2, "error message %s", "formatted") -// assert.GreaterOrEqualf(t, "b", "a", "error message %s", "formatted") -// assert.GreaterOrEqualf(t, "b", "b", "error message %s", "formatted") +// require.GreaterOrEqualf(t, 2, 1, "error message %s", "formatted") +// require.GreaterOrEqualf(t, 2, 2, "error message %s", "formatted") +// require.GreaterOrEqualf(t, "b", "a", "error message %s", "formatted") +// require.GreaterOrEqualf(t, "b", "b", "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -640,9 +708,11 @@ func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, arg // Greaterf asserts that the first element is greater than the second // -// assert.Greaterf(t, 2, 1, "error message %s", "formatted") -// assert.Greaterf(t, float64(2), float64(1), "error message %s", "formatted") -// assert.Greaterf(t, "b", "a", "error message %s", "formatted") +// require.Greaterf(t, 2, 1, "error message %s", "formatted") +// require.Greaterf(t, float64(2), float64(1), "error message %s", "formatted") +// require.Greaterf(t, "b", "a", "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -656,9 +726,10 @@ func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...in // HTTPBodyContains asserts that a specified handler returns a // body that contains a string. // -// assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// require.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") // // Returns whether the assertion was successful (true) or not (false). +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -672,9 +743,10 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url s // HTTPBodyContainsf asserts that a specified handler returns a // body that contains a string. // -// assert.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// require.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -688,9 +760,10 @@ func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url // HTTPBodyNotContains asserts that a specified handler returns a // body that does not contain a string. // -// assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// require.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") // // Returns whether the assertion was successful (true) or not (false). +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -704,9 +777,10 @@ func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, ur // HTTPBodyNotContainsf asserts that a specified handler returns a // body that does not contain a string. // -// assert.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// require.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -719,9 +793,10 @@ func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, u // HTTPError asserts that a specified handler returns an error status code. // -// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// require.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -734,9 +809,10 @@ func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, // 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"}} +// require.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -749,9 +825,10 @@ func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, // HTTPRedirect asserts that a specified handler returns a redirect status code. // -// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// require.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -764,9 +841,10 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url strin // 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"}} +// require.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -779,9 +857,10 @@ func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url stri // HTTPStatusCode asserts that a specified handler returns a specified status code. // -// assert.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501) +// require.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501) // // Returns whether the assertion was successful (true) or not (false). +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -794,9 +873,10 @@ func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method string, url str // HTTPStatusCodef asserts that a specified handler returns a specified status code. // -// assert.HTTPStatusCodef(t, myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") +// require.HTTPStatusCodef(t, myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -809,9 +889,10 @@ func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url st // HTTPSuccess asserts that a specified handler returns a success status code. // -// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) +// require.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) // // Returns whether the assertion was successful (true) or not (false). +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -824,9 +905,10 @@ func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string // 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") +// require.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -839,7 +921,9 @@ func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url strin // Implements asserts that an object is implemented by the specified interface. // -// assert.Implements(t, (*MyInterface)(nil), new(MyObject)) +// require.Implements(t, (*MyInterface)(nil), new(MyObject)) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -852,7 +936,9 @@ func Implements(t TestingT, interfaceObject interface{}, object interface{}, msg // Implementsf asserts that an object is implemented by the specified interface. // -// assert.Implementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") +// require.Implementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -865,7 +951,9 @@ func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, ms // InDelta asserts that the two numerals are within delta of each other. // -// assert.InDelta(t, math.Pi, 22/7.0, 0.01) +// require.InDelta(t, math.Pi, 22/7.0, 0.01) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func InDelta(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -877,6 +965,7 @@ func InDelta(t TestingT, expected interface{}, actual interface{}, delta float64 } // InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func InDeltaMapValues(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -888,6 +977,7 @@ func InDeltaMapValues(t TestingT, expected interface{}, actual interface{}, delt } // InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -899,6 +989,7 @@ func InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, del } // InDeltaSlice is the same as InDelta, except it compares two slices. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func InDeltaSlice(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -910,6 +1001,7 @@ func InDeltaSlice(t TestingT, expected interface{}, actual interface{}, delta fl } // InDeltaSlicef is the same as InDelta, except it compares two slices. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -922,7 +1014,9 @@ func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta f // InDeltaf asserts that the two numerals are within delta of each other. // -// assert.InDeltaf(t, math.Pi, 22/7.0, 0.01, "error message %s", "formatted") +// require.InDeltaf(t, math.Pi, 22/7.0, 0.01, "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -934,6 +1028,7 @@ func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float6 } // InEpsilon asserts that expected and actual have a relative error less than epsilon +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func InEpsilon(t TestingT, expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -945,6 +1040,7 @@ func InEpsilon(t TestingT, expected interface{}, actual interface{}, epsilon flo } // InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func InEpsilonSlice(t TestingT, expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -956,6 +1052,7 @@ func InEpsilonSlice(t TestingT, expected interface{}, actual interface{}, epsilo } // InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -967,6 +1064,7 @@ func InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsil } // InEpsilonf asserts that expected and actual have a relative error less than epsilon +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -979,9 +1077,11 @@ func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon fl // IsDecreasing asserts that the collection is decreasing // -// assert.IsDecreasing(t, []int{2, 1, 0}) -// assert.IsDecreasing(t, []float{2, 1}) -// assert.IsDecreasing(t, []string{"b", "a"}) +// require.IsDecreasing(t, []int{2, 1, 0}) +// require.IsDecreasing(t, []float{2, 1}) +// require.IsDecreasing(t, []string{"b", "a"}) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -994,9 +1094,11 @@ func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { // IsDecreasingf asserts that the collection is decreasing // -// assert.IsDecreasingf(t, []int{2, 1, 0}, "error message %s", "formatted") -// assert.IsDecreasingf(t, []float{2, 1}, "error message %s", "formatted") -// assert.IsDecreasingf(t, []string{"b", "a"}, "error message %s", "formatted") +// require.IsDecreasingf(t, []int{2, 1, 0}, "error message %s", "formatted") +// require.IsDecreasingf(t, []float{2, 1}, "error message %s", "formatted") +// require.IsDecreasingf(t, []string{"b", "a"}, "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1009,9 +1111,11 @@ func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface // IsIncreasing asserts that the collection is increasing // -// assert.IsIncreasing(t, []int{1, 2, 3}) -// assert.IsIncreasing(t, []float{1, 2}) -// assert.IsIncreasing(t, []string{"a", "b"}) +// require.IsIncreasing(t, []int{1, 2, 3}) +// require.IsIncreasing(t, []float{1, 2}) +// require.IsIncreasing(t, []string{"a", "b"}) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1024,9 +1128,11 @@ func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { // IsIncreasingf asserts that the collection is increasing // -// assert.IsIncreasingf(t, []int{1, 2, 3}, "error message %s", "formatted") -// assert.IsIncreasingf(t, []float{1, 2}, "error message %s", "formatted") -// assert.IsIncreasingf(t, []string{"a", "b"}, "error message %s", "formatted") +// require.IsIncreasingf(t, []int{1, 2, 3}, "error message %s", "formatted") +// require.IsIncreasingf(t, []float{1, 2}, "error message %s", "formatted") +// require.IsIncreasingf(t, []string{"a", "b"}, "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1039,9 +1145,11 @@ func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface // IsNonDecreasing asserts that the collection is not decreasing // -// assert.IsNonDecreasing(t, []int{1, 1, 2}) -// assert.IsNonDecreasing(t, []float{1, 2}) -// assert.IsNonDecreasing(t, []string{"a", "b"}) +// require.IsNonDecreasing(t, []int{1, 1, 2}) +// require.IsNonDecreasing(t, []float{1, 2}) +// require.IsNonDecreasing(t, []string{"a", "b"}) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1054,9 +1162,11 @@ func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) // IsNonDecreasingf asserts that the collection is not decreasing // -// assert.IsNonDecreasingf(t, []int{1, 1, 2}, "error message %s", "formatted") -// assert.IsNonDecreasingf(t, []float{1, 2}, "error message %s", "formatted") -// assert.IsNonDecreasingf(t, []string{"a", "b"}, "error message %s", "formatted") +// require.IsNonDecreasingf(t, []int{1, 1, 2}, "error message %s", "formatted") +// require.IsNonDecreasingf(t, []float{1, 2}, "error message %s", "formatted") +// require.IsNonDecreasingf(t, []string{"a", "b"}, "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1069,9 +1179,11 @@ func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interf // IsNonIncreasing asserts that the collection is not increasing // -// assert.IsNonIncreasing(t, []int{2, 1, 1}) -// assert.IsNonIncreasing(t, []float{2, 1}) -// assert.IsNonIncreasing(t, []string{"b", "a"}) +// require.IsNonIncreasing(t, []int{2, 1, 1}) +// require.IsNonIncreasing(t, []float{2, 1}) +// require.IsNonIncreasing(t, []string{"b", "a"}) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1084,9 +1196,11 @@ func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) // IsNonIncreasingf asserts that the collection is not increasing // -// assert.IsNonIncreasingf(t, []int{2, 1, 1}, "error message %s", "formatted") -// assert.IsNonIncreasingf(t, []float{2, 1}, "error message %s", "formatted") -// assert.IsNonIncreasingf(t, []string{"b", "a"}, "error message %s", "formatted") +// require.IsNonIncreasingf(t, []int{2, 1, 1}, "error message %s", "formatted") +// require.IsNonIncreasingf(t, []float{2, 1}, "error message %s", "formatted") +// require.IsNonIncreasingf(t, []string{"b", "a"}, "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1098,6 +1212,7 @@ func IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interf } // IsType asserts that the specified objects are of the same type. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1109,6 +1224,7 @@ func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs } // IsTypef asserts that the specified objects are of the same type. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1121,7 +1237,9 @@ func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg strin // JSONEq asserts that two JSON strings are equivalent. // -// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) +// require.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1134,7 +1252,9 @@ func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{ // JSONEqf asserts that two JSON strings are equivalent. // -// assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") +// require.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1148,7 +1268,9 @@ func JSONEqf(t TestingT, expected string, actual string, msg string, args ...int // Len asserts that the specified object has specific length. // Len also fails if the object has a type that len() not accept. // -// assert.Len(t, mySlice, 3) +// require.Len(t, mySlice, 3) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1162,7 +1284,9 @@ func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) // Lenf asserts that the specified object has specific length. // Lenf also fails if the object has a type that len() not accept. // -// assert.Lenf(t, mySlice, 3, "error message %s", "formatted") +// require.Lenf(t, mySlice, 3, "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1175,9 +1299,11 @@ func Lenf(t TestingT, object interface{}, length int, msg string, args ...interf // Less asserts that the first element is less than the second // -// assert.Less(t, 1, 2) -// assert.Less(t, float64(1), float64(2)) -// assert.Less(t, "a", "b") +// require.Less(t, 1, 2) +// require.Less(t, float64(1), float64(2)) +// require.Less(t, "a", "b") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1190,10 +1316,12 @@ func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) // LessOrEqual asserts that the first element is less than or equal to the second // -// assert.LessOrEqual(t, 1, 2) -// assert.LessOrEqual(t, 2, 2) -// assert.LessOrEqual(t, "a", "b") -// assert.LessOrEqual(t, "b", "b") +// require.LessOrEqual(t, 1, 2) +// require.LessOrEqual(t, 2, 2) +// require.LessOrEqual(t, "a", "b") +// require.LessOrEqual(t, "b", "b") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1206,10 +1334,12 @@ func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...inter // LessOrEqualf asserts that the first element is less than or equal to the second // -// assert.LessOrEqualf(t, 1, 2, "error message %s", "formatted") -// assert.LessOrEqualf(t, 2, 2, "error message %s", "formatted") -// assert.LessOrEqualf(t, "a", "b", "error message %s", "formatted") -// assert.LessOrEqualf(t, "b", "b", "error message %s", "formatted") +// require.LessOrEqualf(t, 1, 2, "error message %s", "formatted") +// require.LessOrEqualf(t, 2, 2, "error message %s", "formatted") +// require.LessOrEqualf(t, "a", "b", "error message %s", "formatted") +// require.LessOrEqualf(t, "b", "b", "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1222,9 +1352,11 @@ func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args . // Lessf asserts that the first element is less than the second // -// assert.Lessf(t, 1, 2, "error message %s", "formatted") -// assert.Lessf(t, float64(1), float64(2), "error message %s", "formatted") -// assert.Lessf(t, "a", "b", "error message %s", "formatted") +// require.Lessf(t, 1, 2, "error message %s", "formatted") +// require.Lessf(t, float64(1), float64(2), "error message %s", "formatted") +// require.Lessf(t, "a", "b", "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1237,8 +1369,10 @@ func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...inter // Negative asserts that the specified element is negative // -// assert.Negative(t, -1) -// assert.Negative(t, -1.23) +// require.Negative(t, -1) +// require.Negative(t, -1.23) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1251,8 +1385,10 @@ func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) { // Negativef asserts that the specified element is negative // -// assert.Negativef(t, -1, "error message %s", "formatted") -// assert.Negativef(t, -1.23, "error message %s", "formatted") +// require.Negativef(t, -1, "error message %s", "formatted") +// require.Negativef(t, -1.23, "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1266,7 +1402,9 @@ func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) { // Never asserts that the given condition doesn't satisfy in waitFor time, // periodically checking the target function each tick. // -// assert.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond) +// require.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1280,7 +1418,9 @@ func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.D // Neverf asserts that the given condition doesn't satisfy in waitFor time, // periodically checking the target function each tick. // -// assert.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") +// require.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1293,7 +1433,9 @@ func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time. // Nil asserts that the specified object is nil. // -// assert.Nil(t, err) +// require.Nil(t, err) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1306,7 +1448,9 @@ func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) { // Nilf asserts that the specified object is nil. // -// assert.Nilf(t, err, "error message %s", "formatted") +// require.Nilf(t, err, "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1319,6 +1463,7 @@ func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) { // NoDirExists checks whether a directory does not exist in the given path. // It fails if the path points to an existing _directory_ only. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NoDirExists(t TestingT, path string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1331,6 +1476,7 @@ func NoDirExists(t TestingT, path string, msgAndArgs ...interface{}) { // NoDirExistsf checks whether a directory does not exist in the given path. // It fails if the path points to an existing _directory_ only. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1344,9 +1490,11 @@ func NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) { // NoError asserts that a function returned no error (i.e. `nil`). // // actualObj, err := SomeFunction() -// if assert.NoError(t, err) { -// assert.Equal(t, expectedObj, actualObj) +// if require.NoError(t, err) { +// require.Equal(t, expectedObj, actualObj) // } +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NoError(t TestingT, err error, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1360,9 +1508,11 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) { // NoErrorf asserts that a function returned no error (i.e. `nil`). // // actualObj, err := SomeFunction() -// if assert.NoErrorf(t, err, "error message %s", "formatted") { -// assert.Equal(t, expectedObj, actualObj) +// if require.NoErrorf(t, err, "error message %s", "formatted") { +// require.Equal(t, expectedObj, actualObj) // } +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NoErrorf(t TestingT, err error, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1375,6 +1525,7 @@ func NoErrorf(t TestingT, err error, msg string, args ...interface{}) { // NoFileExists checks whether a file does not exist in a given path. It fails // if the path points to an existing _file_ only. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NoFileExists(t TestingT, path string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1387,6 +1538,7 @@ func NoFileExists(t TestingT, path string, msgAndArgs ...interface{}) { // NoFileExistsf checks whether a file does not exist in a given path. It fails // if the path points to an existing _file_ only. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NoFileExistsf(t TestingT, path string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1400,9 +1552,11 @@ func NoFileExistsf(t TestingT, path string, msg string, args ...interface{}) { // NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the // specified substring or element. // -// assert.NotContains(t, "Hello World", "Earth") -// assert.NotContains(t, ["Hello", "World"], "Earth") -// assert.NotContains(t, {"Hello": "World"}, "Earth") +// require.NotContains(t, "Hello World", "Earth") +// require.NotContains(t, ["Hello", "World"], "Earth") +// require.NotContains(t, {"Hello": "World"}, "Earth") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1416,9 +1570,11 @@ func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ... // NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the // specified substring or element. // -// assert.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted") -// assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted") -// assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted") +// require.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted") +// require.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted") +// require.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1434,11 +1590,12 @@ func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, a // the number of appearances of each of them in both lists should not match. // This is an inverse of ElementsMatch. // -// assert.NotElementsMatch(t, [1, 1, 2, 3], [1, 1, 2, 3]) -> false +// require.NotElementsMatch(t, [1, 1, 2, 3], [1, 1, 2, 3]) -> false // -// assert.NotElementsMatch(t, [1, 1, 2, 3], [1, 2, 3]) -> true +// require.NotElementsMatch(t, [1, 1, 2, 3], [1, 2, 3]) -> true // -// assert.NotElementsMatch(t, [1, 2, 3], [1, 2, 4]) -> true +// require.NotElementsMatch(t, [1, 2, 3], [1, 2, 4]) -> true +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NotElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1454,11 +1611,12 @@ func NotElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndAr // the number of appearances of each of them in both lists should not match. // This is an inverse of ElementsMatch. // -// assert.NotElementsMatchf(t, [1, 1, 2, 3], [1, 1, 2, 3], "error message %s", "formatted") -> false +// require.NotElementsMatchf(t, [1, 1, 2, 3], [1, 1, 2, 3], "error message %s", "formatted") -> false // -// assert.NotElementsMatchf(t, [1, 1, 2, 3], [1, 2, 3], "error message %s", "formatted") -> true +// require.NotElementsMatchf(t, [1, 1, 2, 3], [1, 2, 3], "error message %s", "formatted") -> true // -// assert.NotElementsMatchf(t, [1, 2, 3], [1, 2, 4], "error message %s", "formatted") -> true +// require.NotElementsMatchf(t, [1, 2, 3], [1, 2, 4], "error message %s", "formatted") -> true +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NotElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1472,9 +1630,11 @@ func NotElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg str // 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. // -// if assert.NotEmpty(t, obj) { -// assert.Equal(t, "two", obj[1]) +// if require.NotEmpty(t, obj) { +// require.Equal(t, "two", obj[1]) // } +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1488,9 +1648,11 @@ func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) { // NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either // a slice or a channel with len == 0. // -// if assert.NotEmptyf(t, obj, "error message %s", "formatted") { -// assert.Equal(t, "two", obj[1]) +// if require.NotEmptyf(t, obj, "error message %s", "formatted") { +// require.Equal(t, "two", obj[1]) // } +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1503,10 +1665,11 @@ func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) // NotEqual asserts that the specified values are NOT equal. // -// assert.NotEqual(t, obj1, obj2) +// require.NotEqual(t, obj1, obj2) // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NotEqual(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1519,7 +1682,9 @@ func NotEqual(t TestingT, expected interface{}, actual interface{}, msgAndArgs . // NotEqualValues asserts that two objects are not equal even when converted to the same type // -// assert.NotEqualValues(t, obj1, obj2) +// require.NotEqualValues(t, obj1, obj2) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NotEqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1532,7 +1697,9 @@ func NotEqualValues(t TestingT, expected interface{}, actual interface{}, msgAnd // NotEqualValuesf asserts that two objects are not equal even when converted to the same type // -// assert.NotEqualValuesf(t, obj1, obj2, "error message %s", "formatted") +// require.NotEqualValuesf(t, obj1, obj2, "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1545,10 +1712,11 @@ func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg s // NotEqualf asserts that the specified values are NOT equal. // -// assert.NotEqualf(t, obj1, obj2, "error message %s", "formatted") +// require.NotEqualf(t, obj1, obj2, "error message %s", "formatted") // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1561,6 +1729,7 @@ func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, // NotErrorIs asserts that at none of the errors in err's chain matches target. // This is a wrapper for errors.Is. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NotErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1573,6 +1742,7 @@ func NotErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) // NotErrorIsf asserts that at none of the errors in err's chain matches target. // This is a wrapper for errors.Is. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1585,7 +1755,9 @@ func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interf // NotImplements asserts that an object does not implement the specified interface. // -// assert.NotImplements(t, (*MyInterface)(nil), new(MyObject)) +// require.NotImplements(t, (*MyInterface)(nil), new(MyObject)) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NotImplements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1598,7 +1770,9 @@ func NotImplements(t TestingT, interfaceObject interface{}, object interface{}, // NotImplementsf asserts that an object does not implement the specified interface. // -// assert.NotImplementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") +// require.NotImplementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NotImplementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1611,7 +1785,9 @@ func NotImplementsf(t TestingT, interfaceObject interface{}, object interface{}, // NotNil asserts that the specified object is not nil. // -// assert.NotNil(t, err) +// require.NotNil(t, err) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1624,7 +1800,9 @@ func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) { // NotNilf asserts that the specified object is not nil. // -// assert.NotNilf(t, err, "error message %s", "formatted") +// require.NotNilf(t, err, "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1637,7 +1815,9 @@ func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) { // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. // -// assert.NotPanics(t, func(){ RemainCalm() }) +// require.NotPanics(t, func(){ RemainCalm() }) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1650,7 +1830,9 @@ func NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { // NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic. // -// assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted") +// require.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NotPanicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1663,8 +1845,10 @@ func NotPanicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interfac // NotRegexp asserts that a specified regexp does not match a string. // -// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") -// assert.NotRegexp(t, "^start", "it's not starting") +// require.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") +// require.NotRegexp(t, "^start", "it's not starting") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1677,8 +1861,10 @@ func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interf // NotRegexpf asserts that a specified regexp does not match a string. // -// assert.NotRegexpf(t, regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") -// assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted") +// require.NotRegexpf(t, regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") +// require.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1691,10 +1877,11 @@ func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args .. // NotSame asserts that two pointers do not reference the same object. // -// assert.NotSame(t, ptr1, ptr2) +// require.NotSame(t, ptr1, ptr2) // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NotSame(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1707,10 +1894,11 @@ func NotSame(t TestingT, expected interface{}, actual interface{}, msgAndArgs .. // NotSamef asserts that two pointers do not reference the same object. // -// assert.NotSamef(t, ptr1, ptr2, "error message %s", "formatted") +// require.NotSamef(t, ptr1, ptr2, "error message %s", "formatted") // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NotSamef(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1725,8 +1913,10 @@ func NotSamef(t TestingT, expected interface{}, actual interface{}, msg string, // contain all elements given in the specified subset list(array, slice...) or // map. // -// assert.NotSubset(t, [1, 3, 4], [1, 2]) -// assert.NotSubset(t, {"x": 1, "y": 2}, {"z": 3}) +// require.NotSubset(t, [1, 3, 4], [1, 2]) +// require.NotSubset(t, {"x": 1, "y": 2}, {"z": 3}) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1741,8 +1931,10 @@ func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...i // contain all elements given in the specified subset list(array, slice...) or // map. // -// 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") +// 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") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1754,6 +1946,7 @@ func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, ar } // NotZero asserts that i is not the zero value for its type. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1765,6 +1958,7 @@ func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) { } // NotZerof asserts that i is not the zero value for its type. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1777,7 +1971,9 @@ func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) { // Panics asserts that the code inside the specified PanicTestFunc panics. // -// assert.Panics(t, func(){ GoCrazy() }) +// require.Panics(t, func(){ GoCrazy() }) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1792,7 +1988,9 @@ func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { // panics, and that the recovered panic value is an error that satisfies the // EqualError comparison. // -// assert.PanicsWithError(t, "crazy error", func(){ GoCrazy() }) +// require.PanicsWithError(t, "crazy error", func(){ GoCrazy() }) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func PanicsWithError(t TestingT, errString string, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1807,7 +2005,9 @@ func PanicsWithError(t TestingT, errString string, f assert.PanicTestFunc, msgAn // panics, and that the recovered panic value is an error that satisfies the // EqualError comparison. // -// assert.PanicsWithErrorf(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +// require.PanicsWithErrorf(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func PanicsWithErrorf(t TestingT, errString string, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1821,7 +2021,9 @@ func PanicsWithErrorf(t TestingT, errString string, f assert.PanicTestFunc, msg // PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that // the recovered panic value equals the expected panic value. // -// assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) +// require.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func PanicsWithValue(t TestingT, expected interface{}, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1835,7 +2037,9 @@ func PanicsWithValue(t TestingT, expected interface{}, f assert.PanicTestFunc, m // 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") +// require.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func PanicsWithValuef(t TestingT, expected interface{}, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1848,7 +2052,9 @@ func PanicsWithValuef(t TestingT, expected interface{}, f assert.PanicTestFunc, // Panicsf asserts that the code inside the specified PanicTestFunc panics. // -// assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted") +// require.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Panicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1861,8 +2067,10 @@ func Panicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{} // Positive asserts that the specified element is positive // -// assert.Positive(t, 1) -// assert.Positive(t, 1.23) +// require.Positive(t, 1) +// require.Positive(t, 1.23) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1875,8 +2083,10 @@ func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) { // Positivef asserts that the specified element is positive // -// assert.Positivef(t, 1, "error message %s", "formatted") -// assert.Positivef(t, 1.23, "error message %s", "formatted") +// require.Positivef(t, 1, "error message %s", "formatted") +// require.Positivef(t, 1.23, "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1889,8 +2099,10 @@ func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) { // Regexp asserts that a specified regexp matches a string. // -// assert.Regexp(t, regexp.MustCompile("start"), "it's starting") -// assert.Regexp(t, "start...$", "it's not starting") +// require.Regexp(t, regexp.MustCompile("start"), "it's starting") +// require.Regexp(t, "start...$", "it's not starting") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1903,8 +2115,10 @@ func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface // Regexpf asserts that a specified regexp matches a string. // -// assert.Regexpf(t, regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") -// assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted") +// require.Regexpf(t, regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") +// require.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1917,10 +2131,11 @@ func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...in // Same asserts that two pointers reference the same object. // -// assert.Same(t, ptr1, ptr2) +// require.Same(t, ptr1, ptr2) // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Same(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1933,10 +2148,11 @@ func Same(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...in // Samef asserts that two pointers reference the same object. // -// assert.Samef(t, ptr1, ptr2, "error message %s", "formatted") +// require.Samef(t, ptr1, ptr2, "error message %s", "formatted") // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Samef(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1950,8 +2166,10 @@ func Samef(t TestingT, expected interface{}, actual interface{}, msg string, arg // Subset asserts that the specified list(array, slice...) or map contains all // elements given in the specified subset list(array, slice...) or map. // -// assert.Subset(t, [1, 2, 3], [1, 2]) -// assert.Subset(t, {"x": 1, "y": 2}, {"x": 1}) +// require.Subset(t, [1, 2, 3], [1, 2]) +// require.Subset(t, {"x": 1, "y": 2}, {"x": 1}) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1965,8 +2183,10 @@ func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...inte // Subsetf asserts that the specified list(array, slice...) or map contains all // elements given in the specified subset list(array, slice...) or map. // -// 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") +// 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") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1979,7 +2199,9 @@ func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args // True asserts that the specified value is true. // -// assert.True(t, myBool) +// require.True(t, myBool) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func True(t TestingT, value bool, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1992,7 +2214,9 @@ func True(t TestingT, value bool, msgAndArgs ...interface{}) { // Truef asserts that the specified value is true. // -// assert.Truef(t, myBool, "error message %s", "formatted") +// require.Truef(t, myBool, "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Truef(t TestingT, value bool, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2005,7 +2229,9 @@ func Truef(t TestingT, value bool, msg string, args ...interface{}) { // WithinDuration asserts that the two times are within duration delta of each other. // -// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) +// require.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2018,7 +2244,9 @@ func WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time // WithinDurationf asserts that the two times are within duration delta of each other. // -// assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") +// require.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2031,7 +2259,9 @@ func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta tim // WithinRange asserts that a time is within a time range (inclusive). // -// assert.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) +// require.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func WithinRange(t TestingT, actual time.Time, start time.Time, end time.Time, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2044,7 +2274,9 @@ func WithinRange(t TestingT, actual time.Time, start time.Time, end time.Time, m // WithinRangef asserts that a time is within a time range (inclusive). // -// assert.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") +// require.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") +// +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2056,6 +2288,7 @@ func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, } // YAMLEq asserts that two YAML strings are equivalent. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2067,6 +2300,7 @@ func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{ } // YAMLEqf asserts that two YAML strings are equivalent. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2078,6 +2312,7 @@ func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...int } // Zero asserts that i is the zero value for its type. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2089,6 +2324,7 @@ func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) { } // Zerof asserts that i is the zero value for its type. +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func Zerof(t TestingT, i interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/require/require.go.tmpl b/require/require.go.tmpl index 55e42ddeb..ded85afa4 100644 --- a/require/require.go.tmpl +++ b/require/require.go.tmpl @@ -1,4 +1,5 @@ -{{.Comment}} +{{ replace .Comment "assert." "require."}} +// Instead of returning a boolean result this function calls `t.FailNow()` on failure. func {{.DocInfo.Name}}(t TestingT, {{.Params}}) { if h, ok := t.(tHelper); ok { h.Helper() } if assert.{{.DocInfo.Name}}(t, {{.ForwardedParams}}) { return } From 044c46a89fc0d0f106a7293ae9622a7b6cf14150 Mon Sep 17 00:00:00 2001 From: Simon Schulte Date: Thu, 13 Jun 2024 15:40:29 +0200 Subject: [PATCH 025/178] Update require.go.tmpl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Olivier Mengué --- require/require.go.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/require/require.go.tmpl b/require/require.go.tmpl index ded85afa4..11cca94cd 100644 --- a/require/require.go.tmpl +++ b/require/require.go.tmpl @@ -1,5 +1,5 @@ {{ replace .Comment "assert." "require."}} -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func {{.DocInfo.Name}}(t TestingT, {{.Params}}) { if h, ok := t.(tHelper); ok { h.Helper() } if assert.{{.DocInfo.Name}}(t, {{.ForwardedParams}}) { return } From f71de4a756dd594795b9a68167d53e000f2ead45 Mon Sep 17 00:00:00 2001 From: Simon Schulte Date: Thu, 13 Jun 2024 18:02:19 +0200 Subject: [PATCH 026/178] updated message --- require/require.go | 296 ++++++++++++++++++++++----------------------- 1 file changed, 148 insertions(+), 148 deletions(-) diff --git a/require/require.go b/require/require.go index 102dd7f16..b94398f3a 100644 --- a/require/require.go +++ b/require/require.go @@ -10,7 +10,7 @@ import ( ) // Condition uses a Comparison to assert a complex condition. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Condition(t TestingT, comp assert.Comparison, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -22,7 +22,7 @@ func Condition(t TestingT, comp assert.Comparison, msgAndArgs ...interface{}) { } // Conditionf uses a Comparison to assert a complex condition. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Conditionf(t TestingT, comp assert.Comparison, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -40,7 +40,7 @@ func Conditionf(t TestingT, comp assert.Comparison, msg string, args ...interfac // require.Contains(t, ["Hello", "World"], "World") // require.Contains(t, {"Hello": "World"}, "Hello") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -58,7 +58,7 @@ func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...int // require.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted") // require.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -71,7 +71,7 @@ func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args // DirExists checks whether a directory exists in the given path. It also fails // if the path is a file rather a directory or there is an error checking whether it exists. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func DirExists(t TestingT, path string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -84,7 +84,7 @@ func DirExists(t TestingT, path string, msgAndArgs ...interface{}) { // DirExistsf checks whether a directory exists in the given path. It also fails // if the path is a file rather a directory or there is an error checking whether it exists. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func DirExistsf(t TestingT, path string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -100,7 +100,7 @@ func DirExistsf(t TestingT, path string, msg string, args ...interface{}) { // the number of appearances of each of them in both lists should match. // // require.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2]) -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func ElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -116,7 +116,7 @@ func ElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs // the number of appearances of each of them in both lists should match. // // require.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted") -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -132,7 +132,7 @@ func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string // // require.Empty(t, obj) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -148,7 +148,7 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) { // // require.Emptyf(t, obj, "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -166,7 +166,7 @@ func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) { // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). Function equality // cannot be determined and will always fail. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -183,7 +183,7 @@ func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...i // actualObj, err := SomeFunction() // require.EqualError(t, err, expectedErrorString) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -200,7 +200,7 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte // actualObj, err := SomeFunction() // require.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -222,7 +222,7 @@ func EqualErrorf(t TestingT, theError error, errString string, msg string, args // require.EqualExportedValues(t, S{1, 2}, S{1, 3}) => true // require.EqualExportedValues(t, S{1, 2}, S{2, 3}) => false // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func EqualExportedValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -244,7 +244,7 @@ func EqualExportedValues(t TestingT, expected interface{}, actual interface{}, m // require.EqualExportedValuesf(t, S{1, 2}, S{1, 3}, "error message %s", "formatted") => true // require.EqualExportedValuesf(t, S{1, 2}, S{2, 3}, "error message %s", "formatted") => false // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func EqualExportedValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -260,7 +260,7 @@ func EqualExportedValuesf(t TestingT, expected interface{}, actual interface{}, // // require.EqualValues(t, uint32(123), int32(123)) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -276,7 +276,7 @@ func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArg // // require.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -294,7 +294,7 @@ func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg stri // 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. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -312,7 +312,7 @@ func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, ar // require.Equal(t, expectedError, err) // } // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Error(t TestingT, err error, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -325,7 +325,7 @@ func Error(t TestingT, err error, msgAndArgs ...interface{}) { // ErrorAs asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value. // This is a wrapper for errors.As. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -338,7 +338,7 @@ func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{ // ErrorAsf asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value. // This is a wrapper for errors.As. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -355,7 +355,7 @@ func ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...int // actualObj, err := SomeFunction() // require.ErrorContains(t, err, expectedErrorSubString) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -372,7 +372,7 @@ func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...in // actualObj, err := SomeFunction() // require.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func ErrorContainsf(t TestingT, theError error, contains string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -385,7 +385,7 @@ func ErrorContainsf(t TestingT, theError error, contains string, msg string, arg // ErrorIs asserts that at least one of the errors in err's chain matches target. // This is a wrapper for errors.Is. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func ErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -398,7 +398,7 @@ func ErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) { // ErrorIsf asserts that at least one of the errors in err's chain matches target. // This is a wrapper for errors.Is. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func ErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -416,7 +416,7 @@ func ErrorIsf(t TestingT, err error, target error, msg string, args ...interface // require.Equal(t, expectedErrorf, err) // } // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Errorf(t TestingT, err error, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -432,7 +432,7 @@ func Errorf(t TestingT, err error, msg string, args ...interface{}) { // // require.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -462,7 +462,7 @@ func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick t // require.True(c, externalValue, "expected 'externalValue' to be true") // }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func EventuallyWithT(t TestingT, condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -492,7 +492,7 @@ func EventuallyWithT(t TestingT, condition func(collect *assert.CollectT), waitF // require.True(c, externalValue, "expected 'externalValue' to be true") // }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func EventuallyWithTf(t TestingT, condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -508,7 +508,7 @@ func EventuallyWithTf(t TestingT, condition func(collect *assert.CollectT), wait // // require.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -523,7 +523,7 @@ func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick // // require.Exactly(t, int32(123), int64(123)) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -538,7 +538,7 @@ func Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs .. // // require.Exactlyf(t, int32(123), int64(123), "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -550,7 +550,7 @@ func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, } // Fail reports a failure through -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -562,7 +562,7 @@ func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) { } // FailNow fails test -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -574,7 +574,7 @@ func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) { } // FailNowf fails test -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -586,7 +586,7 @@ func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{} } // Failf reports a failure through -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -601,7 +601,7 @@ func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) { // // require.False(t, myBool) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func False(t TestingT, value bool, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -616,7 +616,7 @@ func False(t TestingT, value bool, msgAndArgs ...interface{}) { // // require.Falsef(t, myBool, "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Falsef(t TestingT, value bool, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -629,7 +629,7 @@ func Falsef(t TestingT, value bool, msg string, args ...interface{}) { // FileExists checks whether a file exists in the given path. It also fails if // the path points to a directory or there is an error when trying to check the file. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func FileExists(t TestingT, path string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -642,7 +642,7 @@ func FileExists(t TestingT, path string, msgAndArgs ...interface{}) { // FileExistsf checks whether a file exists in the given path. It also fails if // the path points to a directory or there is an error when trying to check the file. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func FileExistsf(t TestingT, path string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -659,7 +659,7 @@ func FileExistsf(t TestingT, path string, msg string, args ...interface{}) { // require.Greater(t, float64(2), float64(1)) // require.Greater(t, "b", "a") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -677,7 +677,7 @@ func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface // require.GreaterOrEqual(t, "b", "a") // require.GreaterOrEqual(t, "b", "b") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -695,7 +695,7 @@ func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...in // require.GreaterOrEqualf(t, "b", "a", "error message %s", "formatted") // require.GreaterOrEqualf(t, "b", "b", "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -712,7 +712,7 @@ func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, arg // require.Greaterf(t, float64(2), float64(1), "error message %s", "formatted") // require.Greaterf(t, "b", "a", "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -729,7 +729,7 @@ func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...in // require.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") // // Returns whether the assertion was successful (true) or not (false). -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -746,7 +746,7 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url s // require.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -763,7 +763,7 @@ func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url // require.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") // // Returns whether the assertion was successful (true) or not (false). -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -780,7 +780,7 @@ func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, ur // require.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -796,7 +796,7 @@ func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, u // require.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -812,7 +812,7 @@ func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, // require.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -828,7 +828,7 @@ func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, // require.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -844,7 +844,7 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url strin // require.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -860,7 +860,7 @@ func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url stri // require.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501) // // Returns whether the assertion was successful (true) or not (false). -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -876,7 +876,7 @@ func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method string, url str // require.HTTPStatusCodef(t, myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -892,7 +892,7 @@ func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url st // require.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) // // Returns whether the assertion was successful (true) or not (false). -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -908,7 +908,7 @@ func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string // require.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -923,7 +923,7 @@ func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url strin // // require.Implements(t, (*MyInterface)(nil), new(MyObject)) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -938,7 +938,7 @@ func Implements(t TestingT, interfaceObject interface{}, object interface{}, msg // // require.Implementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -953,7 +953,7 @@ func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, ms // // require.InDelta(t, math.Pi, 22/7.0, 0.01) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func InDelta(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -965,7 +965,7 @@ func InDelta(t TestingT, expected interface{}, actual interface{}, delta float64 } // InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func InDeltaMapValues(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -977,7 +977,7 @@ func InDeltaMapValues(t TestingT, expected interface{}, actual interface{}, delt } // InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -989,7 +989,7 @@ func InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, del } // InDeltaSlice is the same as InDelta, except it compares two slices. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func InDeltaSlice(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1001,7 +1001,7 @@ func InDeltaSlice(t TestingT, expected interface{}, actual interface{}, delta fl } // InDeltaSlicef is the same as InDelta, except it compares two slices. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1016,7 +1016,7 @@ func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta f // // require.InDeltaf(t, math.Pi, 22/7.0, 0.01, "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1028,7 +1028,7 @@ func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float6 } // InEpsilon asserts that expected and actual have a relative error less than epsilon -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func InEpsilon(t TestingT, expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1040,7 +1040,7 @@ func InEpsilon(t TestingT, expected interface{}, actual interface{}, epsilon flo } // InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func InEpsilonSlice(t TestingT, expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1052,7 +1052,7 @@ func InEpsilonSlice(t TestingT, expected interface{}, actual interface{}, epsilo } // InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1064,7 +1064,7 @@ func InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsil } // InEpsilonf asserts that expected and actual have a relative error less than epsilon -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1081,7 +1081,7 @@ func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon fl // require.IsDecreasing(t, []float{2, 1}) // require.IsDecreasing(t, []string{"b", "a"}) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1098,7 +1098,7 @@ func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { // require.IsDecreasingf(t, []float{2, 1}, "error message %s", "formatted") // require.IsDecreasingf(t, []string{"b", "a"}, "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1115,7 +1115,7 @@ func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface // require.IsIncreasing(t, []float{1, 2}) // require.IsIncreasing(t, []string{"a", "b"}) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1132,7 +1132,7 @@ func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { // require.IsIncreasingf(t, []float{1, 2}, "error message %s", "formatted") // require.IsIncreasingf(t, []string{"a", "b"}, "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1149,7 +1149,7 @@ func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface // require.IsNonDecreasing(t, []float{1, 2}) // require.IsNonDecreasing(t, []string{"a", "b"}) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1166,7 +1166,7 @@ func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) // require.IsNonDecreasingf(t, []float{1, 2}, "error message %s", "formatted") // require.IsNonDecreasingf(t, []string{"a", "b"}, "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1183,7 +1183,7 @@ func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interf // require.IsNonIncreasing(t, []float{2, 1}) // require.IsNonIncreasing(t, []string{"b", "a"}) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1200,7 +1200,7 @@ func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) // require.IsNonIncreasingf(t, []float{2, 1}, "error message %s", "formatted") // require.IsNonIncreasingf(t, []string{"b", "a"}, "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1212,7 +1212,7 @@ func IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interf } // IsType asserts that the specified objects are of the same type. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1224,7 +1224,7 @@ func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs } // IsTypef asserts that the specified objects are of the same type. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1239,7 +1239,7 @@ func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg strin // // require.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1254,7 +1254,7 @@ func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{ // // require.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1270,7 +1270,7 @@ func JSONEqf(t TestingT, expected string, actual string, msg string, args ...int // // require.Len(t, mySlice, 3) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1286,7 +1286,7 @@ func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) // // require.Lenf(t, mySlice, 3, "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1303,7 +1303,7 @@ func Lenf(t TestingT, object interface{}, length int, msg string, args ...interf // require.Less(t, float64(1), float64(2)) // require.Less(t, "a", "b") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1321,7 +1321,7 @@ func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) // require.LessOrEqual(t, "a", "b") // require.LessOrEqual(t, "b", "b") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1339,7 +1339,7 @@ func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...inter // require.LessOrEqualf(t, "a", "b", "error message %s", "formatted") // require.LessOrEqualf(t, "b", "b", "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1356,7 +1356,7 @@ func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args . // require.Lessf(t, float64(1), float64(2), "error message %s", "formatted") // require.Lessf(t, "a", "b", "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1372,7 +1372,7 @@ func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...inter // require.Negative(t, -1) // require.Negative(t, -1.23) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1388,7 +1388,7 @@ func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) { // require.Negativef(t, -1, "error message %s", "formatted") // require.Negativef(t, -1.23, "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1404,7 +1404,7 @@ func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) { // // require.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1420,7 +1420,7 @@ func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.D // // require.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1435,7 +1435,7 @@ func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time. // // require.Nil(t, err) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1450,7 +1450,7 @@ func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) { // // require.Nilf(t, err, "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1463,7 +1463,7 @@ func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) { // NoDirExists checks whether a directory does not exist in the given path. // It fails if the path points to an existing _directory_ only. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NoDirExists(t TestingT, path string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1476,7 +1476,7 @@ func NoDirExists(t TestingT, path string, msgAndArgs ...interface{}) { // NoDirExistsf checks whether a directory does not exist in the given path. // It fails if the path points to an existing _directory_ only. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1494,7 +1494,7 @@ func NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) { // require.Equal(t, expectedObj, actualObj) // } // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NoError(t TestingT, err error, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1512,7 +1512,7 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) { // require.Equal(t, expectedObj, actualObj) // } // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NoErrorf(t TestingT, err error, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1525,7 +1525,7 @@ func NoErrorf(t TestingT, err error, msg string, args ...interface{}) { // NoFileExists checks whether a file does not exist in a given path. It fails // if the path points to an existing _file_ only. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NoFileExists(t TestingT, path string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1538,7 +1538,7 @@ func NoFileExists(t TestingT, path string, msgAndArgs ...interface{}) { // NoFileExistsf checks whether a file does not exist in a given path. It fails // if the path points to an existing _file_ only. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NoFileExistsf(t TestingT, path string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1556,7 +1556,7 @@ func NoFileExistsf(t TestingT, path string, msg string, args ...interface{}) { // require.NotContains(t, ["Hello", "World"], "Earth") // require.NotContains(t, {"Hello": "World"}, "Earth") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1574,7 +1574,7 @@ func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ... // require.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted") // require.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1595,7 +1595,7 @@ func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, a // require.NotElementsMatch(t, [1, 1, 2, 3], [1, 2, 3]) -> true // // require.NotElementsMatch(t, [1, 2, 3], [1, 2, 4]) -> true -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1616,7 +1616,7 @@ func NotElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndAr // require.NotElementsMatchf(t, [1, 1, 2, 3], [1, 2, 3], "error message %s", "formatted") -> true // // require.NotElementsMatchf(t, [1, 2, 3], [1, 2, 4], "error message %s", "formatted") -> true -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1634,7 +1634,7 @@ func NotElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg str // require.Equal(t, "two", obj[1]) // } // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1652,7 +1652,7 @@ func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) { // require.Equal(t, "two", obj[1]) // } // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1669,7 +1669,7 @@ func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotEqual(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1684,7 +1684,7 @@ func NotEqual(t TestingT, expected interface{}, actual interface{}, msgAndArgs . // // require.NotEqualValues(t, obj1, obj2) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotEqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1699,7 +1699,7 @@ func NotEqualValues(t TestingT, expected interface{}, actual interface{}, msgAnd // // require.NotEqualValuesf(t, obj1, obj2, "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1716,7 +1716,7 @@ func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg s // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1729,7 +1729,7 @@ func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, // NotErrorIs asserts that none of the errors in err's chain matches target. // This is a wrapper for errors.Is. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1742,7 +1742,7 @@ func NotErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) // NotErrorIsf asserts that none of the errors in err's chain matches target. // This is a wrapper for errors.Is. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1757,7 +1757,7 @@ func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interf // // require.NotImplements(t, (*MyInterface)(nil), new(MyObject)) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotImplements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1772,7 +1772,7 @@ func NotImplements(t TestingT, interfaceObject interface{}, object interface{}, // // require.NotImplementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotImplementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1787,7 +1787,7 @@ func NotImplementsf(t TestingT, interfaceObject interface{}, object interface{}, // // require.NotNil(t, err) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1802,7 +1802,7 @@ func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) { // // require.NotNilf(t, err, "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1817,7 +1817,7 @@ func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) { // // require.NotPanics(t, func(){ RemainCalm() }) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1832,7 +1832,7 @@ func NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { // // require.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotPanicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1848,7 +1848,7 @@ func NotPanicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interfac // require.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") // require.NotRegexp(t, "^start", "it's not starting") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1864,7 +1864,7 @@ func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interf // require.NotRegexpf(t, regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") // require.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1881,7 +1881,7 @@ func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args .. // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotSame(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1898,7 +1898,7 @@ func NotSame(t TestingT, expected interface{}, actual interface{}, msgAndArgs .. // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotSamef(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1916,7 +1916,7 @@ func NotSamef(t TestingT, expected interface{}, actual interface{}, msg string, // require.NotSubset(t, [1, 3, 4], [1, 2]) // require.NotSubset(t, {"x": 1, "y": 2}, {"z": 3}) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1934,7 +1934,7 @@ func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...i // 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") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1946,7 +1946,7 @@ func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, ar } // NotZero asserts that i is not the zero value for its type. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1958,7 +1958,7 @@ func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) { } // NotZerof asserts that i is not the zero value for its type. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1973,7 +1973,7 @@ func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) { // // require.Panics(t, func(){ GoCrazy() }) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1990,7 +1990,7 @@ func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { // // require.PanicsWithError(t, "crazy error", func(){ GoCrazy() }) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func PanicsWithError(t TestingT, errString string, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2007,7 +2007,7 @@ func PanicsWithError(t TestingT, errString string, f assert.PanicTestFunc, msgAn // // require.PanicsWithErrorf(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func PanicsWithErrorf(t TestingT, errString string, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2023,7 +2023,7 @@ func PanicsWithErrorf(t TestingT, errString string, f assert.PanicTestFunc, msg // // require.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func PanicsWithValue(t TestingT, expected interface{}, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2039,7 +2039,7 @@ func PanicsWithValue(t TestingT, expected interface{}, f assert.PanicTestFunc, m // // require.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func PanicsWithValuef(t TestingT, expected interface{}, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2054,7 +2054,7 @@ func PanicsWithValuef(t TestingT, expected interface{}, f assert.PanicTestFunc, // // require.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Panicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2070,7 +2070,7 @@ func Panicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{} // require.Positive(t, 1) // require.Positive(t, 1.23) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2086,7 +2086,7 @@ func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) { // require.Positivef(t, 1, "error message %s", "formatted") // require.Positivef(t, 1.23, "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2102,7 +2102,7 @@ func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) { // require.Regexp(t, regexp.MustCompile("start"), "it's starting") // require.Regexp(t, "start...$", "it's not starting") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2118,7 +2118,7 @@ func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface // require.Regexpf(t, regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") // require.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2135,7 +2135,7 @@ func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...in // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Same(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2152,7 +2152,7 @@ func Same(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...in // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Samef(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2169,7 +2169,7 @@ func Samef(t TestingT, expected interface{}, actual interface{}, msg string, arg // require.Subset(t, [1, 2, 3], [1, 2]) // require.Subset(t, {"x": 1, "y": 2}, {"x": 1}) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2186,7 +2186,7 @@ func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...inte // 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") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2201,7 +2201,7 @@ func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args // // require.True(t, myBool) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func True(t TestingT, value bool, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2216,7 +2216,7 @@ func True(t TestingT, value bool, msgAndArgs ...interface{}) { // // require.Truef(t, myBool, "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Truef(t TestingT, value bool, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2231,7 +2231,7 @@ func Truef(t TestingT, value bool, msg string, args ...interface{}) { // // require.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2246,7 +2246,7 @@ func WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time // // require.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2261,7 +2261,7 @@ func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta tim // // require.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func WithinRange(t TestingT, actual time.Time, start time.Time, end time.Time, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2276,7 +2276,7 @@ func WithinRange(t TestingT, actual time.Time, start time.Time, end time.Time, m // // require.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") // -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2288,7 +2288,7 @@ func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, } // YAMLEq asserts that two YAML strings are equivalent. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2300,7 +2300,7 @@ func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{ } // YAMLEqf asserts that two YAML strings are equivalent. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2312,7 +2312,7 @@ func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...int } // Zero asserts that i is the zero value for its type. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2324,7 +2324,7 @@ func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) { } // Zerof asserts that i is the zero value for its type. -// Instead of returning a boolean result this function calls `t.FailNow()` on failure. +// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Zerof(t TestingT, i interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() From 3ca01f4bc352e36e9d80f87d80b7de57d967fb7a Mon Sep 17 00:00:00 2001 From: Mike Auclair Date: Mon, 24 Jun 2024 16:39:18 +0000 Subject: [PATCH 027/178] Stop querying for stack frames multiple times on CallerInfo() --- assert/assertions.go | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index 104a0c936..cf4d80fe0 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -212,19 +212,23 @@ the problem actually occurred in calling code.*/ func CallerInfo() []string { var pc uintptr - var ok bool var file string var line int var name string 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. - break - } + pcs := []uintptr{} + n := runtime.Callers(0, pcs) + if n == 0 { + return []string{} + } + frames := runtime.CallersFrames(pcs[:n]) + + for { + frame, more := frames.Next() + pc = frame.PC + file = frame.File + line = frame.Line // This is a huge edge case, but it will panic if this is the case, see #180 if file == "" { @@ -263,6 +267,10 @@ func CallerInfo() []string { isTest(name, "Example") { break } + + if !more { + break + } } return callers From 4a90eff4ae12f3ed4bc9331e2f8ba368317fe86e Mon Sep 17 00:00:00 2001 From: Mike Auclair Date: Mon, 24 Jun 2024 16:50:27 +0000 Subject: [PATCH 028/178] fix --- assert/assertions.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index cf4d80fe0..02dc37487 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -217,8 +217,8 @@ func CallerInfo() []string { var name string callers := []string{} - pcs := []uintptr{} - n := runtime.Callers(0, pcs) + pcs := make([]uintptr, 50) + n := runtime.Callers(1, pcs) if n == 0 { return []string{} } From 28e0be50927fb120f1275d34c648d0abbd166810 Mon Sep 17 00:00:00 2001 From: Mike Auclair Date: Mon, 24 Jun 2024 18:11:07 +0000 Subject: [PATCH 029/178] refill stack frame buffer after it's exhausted --- assert/assertions.go | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index 02dc37487..1013f601b 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -24,6 +24,8 @@ import ( "github.com/stretchr/testify/assert/yaml" ) +const stackFrameBufferSize = 10 + //go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=assert -template=assertion_format.go.tmpl" // TestingT is an interface wrapper around *testing.T @@ -217,8 +219,14 @@ func CallerInfo() []string { var name string callers := []string{} - pcs := make([]uintptr, 50) - n := runtime.Callers(1, pcs) + pcs := make([]uintptr, stackFrameBufferSize) + offset := 1 + n := runtime.Callers(offset, pcs) + maybeMore := true + if n < stackFrameBufferSize { + maybeMore = false + } + if n == 0 { return []string{} } @@ -269,8 +277,22 @@ func CallerInfo() []string { } if !more { - break + // We know we already have less than a buffer's worth of frames + if !maybeMore { + break + } + offset += stackFrameBufferSize + n = runtime.Callers(offset, pcs) + if n < stackFrameBufferSize { + maybeMore = false + } + + if n == 0 { + break + } + frames = runtime.CallersFrames(pcs[:n]) } + } return callers From dd725333f3de28fceb3b209630c580fb03144d54 Mon Sep 17 00:00:00 2001 From: Mike Auclair Date: Mon, 24 Jun 2024 20:29:26 +0000 Subject: [PATCH 030/178] wip --- mock/mock.go | 49 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/mock/mock.go b/mock/mock.go index d5eb1ef55..a28f686c4 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -923,6 +923,8 @@ func (args Arguments) Is(objects ...interface{}) bool { return true } +type outputRenderer interface{} + // Diff gets a string describing the differences between the arguments // and the specified objects. // @@ -930,7 +932,7 @@ func (args Arguments) Is(objects ...interface{}) bool { func (args Arguments) Diff(objects []interface{}) (string, int) { // TODO: could return string as error and nil for No difference - output := "\n" + var outputBuilder strings.Builder var differences int maxArgCount := len(args) @@ -938,7 +940,10 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { maxArgCount = len(objects) } - for i := 0; i < maxArgCount; i++ { + outputRenderers := []outputRenderer{} + + for j := 0; j < maxArgCount; j++ { + i := j var actual, expected interface{} var actualFmt, expectedFmt string @@ -969,10 +974,12 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { matches = matcher.Matches(actual) }() if matches { - output = fmt.Sprintf("%s\t%d: PASS: %s matched by %s\n", output, i, actualFmt, matcher) + outputRenderers = append(outputRenderers, func() string { + return fmt.Sprintf("\t%d: PASS: %s matched by %s\n", i, actualFmt, matcher) + }) } else { differences++ - output = fmt.Sprintf("%s\t%d: FAIL: %s not matched by %s\n", output, i, actualFmt, matcher) + outputRenderers = append(outputRenderers, fmt.Sprintf("\t%d: FAIL: %s not matched by %s\n", i, actualFmt, matcher)) } } else { switch expected := expected.(type) { @@ -981,13 +988,13 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { if reflect.TypeOf(actual).Name() != string(expected) && reflect.TypeOf(actual).String() != string(expected) { // not match differences++ - output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, expected, reflect.TypeOf(actual).Name(), actualFmt) + outputRenderers = append(outputRenderers, fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, expected, reflect.TypeOf(actual).Name(), actualFmt)) } case *IsTypeArgument: actualT := reflect.TypeOf(actual) if actualT != expected.t { differences++ - output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, expected.t.Name(), actualT.Name(), actualFmt) + outputRenderers = append(outputRenderers, fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, expected.t.Name(), actualT.Name(), actualFmt)) } case *FunctionalOptionsArgument: t := expected.value @@ -1001,26 +1008,30 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { tName := reflect.TypeOf(t).Name() if name != reflect.TypeOf(actual).String() && tValue.Len() != 0 { differences++ - output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, tName, reflect.TypeOf(actual).Name(), actualFmt) + outputRenderers = append(outputRenderers, fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, tName, reflect.TypeOf(actual).Name(), actualFmt)) } else { if ef, af := assertOpts(t, actual); ef == "" && af == "" { // match - output = fmt.Sprintf("%s\t%d: PASS: %s == %s\n", output, i, tName, tName) + outputRenderers = append(outputRenderers, func() string { + return fmt.Sprintf("\t%d: PASS: %s == %s\n", i, tName, tName) + }) } else { // not match differences++ - output = fmt.Sprintf("%s\t%d: FAIL: %s != %s\n", output, i, af, ef) + outputRenderers = append(outputRenderers, fmt.Sprintf("\t%d: FAIL: %s != %s\n", i, af, ef)) } } default: - if assert.ObjectsAreEqual(expected, Anything) || assert.ObjectsAreEqual(actual, Anything) || assert.ObjectsAreEqual(actual, expected) { + if expected == Anything || assert.ObjectsAreEqual(expected, Anything) || assert.ObjectsAreEqual(actual, Anything) || assert.ObjectsAreEqual(actual, expected) { // match - output = fmt.Sprintf("%s\t%d: PASS: %s == %s\n", output, i, actualFmt, expectedFmt) + outputRenderers = append(outputRenderers, func() string { + return fmt.Sprintf("\t%d: PASS: %s == %s\n", i, actualFmt, expectedFmt) + }) } else { // not match differences++ - output = fmt.Sprintf("%s\t%d: FAIL: %s != %s\n", output, i, actualFmt, expectedFmt) + outputRenderers = append(outputRenderers, fmt.Sprintf("\t%d: FAIL: %s != %s\n", i, actualFmt, expectedFmt)) } } } @@ -1031,7 +1042,19 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { return "No differences.", differences } - return output, differences + outputBuilder.WriteString("\n") + for _, renderer := range outputRenderers { + switch r := renderer.(type) { + case string: + outputBuilder.WriteString(r) + case func() string: + outputBuilder.WriteString(r()) + default: + panic("Invalid Output Renderer") + } + } + + return outputBuilder.String(), differences } // Assert compares the arguments with the specified objects and fails if From 176474a4c9bcd6b4d1daf36d902dd773171fb7c6 Mon Sep 17 00:00:00 2001 From: Mike Auclair Date: Mon, 24 Jun 2024 20:42:26 +0000 Subject: [PATCH 031/178] cleanup --- assert/assertions.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index 1013f601b..461182210 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -222,10 +222,7 @@ func CallerInfo() []string { pcs := make([]uintptr, stackFrameBufferSize) offset := 1 n := runtime.Callers(offset, pcs) - maybeMore := true - if n < stackFrameBufferSize { - maybeMore = false - } + maybeMore := n == stackFrameBufferSize if n == 0 { return []string{} @@ -283,13 +280,12 @@ func CallerInfo() []string { } offset += stackFrameBufferSize n = runtime.Callers(offset, pcs) - if n < stackFrameBufferSize { - maybeMore = false - } - if n == 0 { break } + + maybeMore = n == stackFrameBufferSize + frames = runtime.CallersFrames(pcs[:n]) } From 7f10816c9395d22ff32f384f79d07d8ef6feb698 Mon Sep 17 00:00:00 2001 From: Mike Auclair Date: Tue, 25 Jun 2024 11:50:49 +0000 Subject: [PATCH 032/178] review feedback --- assert/assertions.go | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index 461182210..9edddc784 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -222,11 +222,12 @@ func CallerInfo() []string { pcs := make([]uintptr, stackFrameBufferSize) offset := 1 n := runtime.Callers(offset, pcs) - maybeMore := n == stackFrameBufferSize if n == 0 { return []string{} } + + maybeMore := n == stackFrameBufferSize frames := runtime.CallersFrames(pcs[:n]) for { @@ -273,21 +274,22 @@ func CallerInfo() []string { break } - if !more { - // We know we already have less than a buffer's worth of frames - if !maybeMore { - break - } - offset += stackFrameBufferSize - n = runtime.Callers(offset, pcs) - if n == 0 { - break - } + if more { + continue + } + // We know we already have less than a buffer's worth of frames + if !maybeMore { + break + } + offset += stackFrameBufferSize + n = runtime.Callers(offset, pcs) + if n == 0 { + break + } - maybeMore = n == stackFrameBufferSize + maybeMore = n == stackFrameBufferSize - frames = runtime.CallersFrames(pcs[:n]) - } + frames = runtime.CallersFrames(pcs[:n]) } From 2b53603313959458632f3becbb6ad50c0a2061c3 Mon Sep 17 00:00:00 2001 From: Mike Auclair Date: Tue, 25 Jun 2024 14:59:20 +0000 Subject: [PATCH 033/178] wip --- mock/mock.go | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/mock/mock.go b/mock/mock.go index a28f686c4..c8ed892bd 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -945,22 +945,30 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { for j := 0; j < maxArgCount; j++ { i := j var actual, expected interface{} - var actualFmt, expectedFmt string + var actualFmt, expectedFmt func() string if len(objects) <= i { actual = "(Missing)" - actualFmt = "(Missing)" + actualFmt = func() string { + return "(Missing)" + } } else { actual = objects[i] - actualFmt = fmt.Sprintf("(%[1]T=%[1]v)", actual) + actualFmt = func() string { + return fmt.Sprintf("(%[1]T=%[1]v)", actual) + } } if len(args) <= i { expected = "(Missing)" - expectedFmt = "(Missing)" + expectedFmt = func() string { + return "(Missing)" + } } else { expected = args[i] - expectedFmt = fmt.Sprintf("(%[1]T=%[1]v)", expected) + expectedFmt = func() string { + return fmt.Sprintf("(%[1]T=%[1]v)", expected) + } } if matcher, ok := expected.(argumentMatcher); ok { @@ -968,18 +976,20 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { func() { defer func() { if r := recover(); r != nil { - actualFmt = fmt.Sprintf("panic in argument matcher: %v", r) + actualFmt = func() string { + return fmt.Sprintf("panic in argument matcher: %v", r) + } } }() matches = matcher.Matches(actual) }() if matches { outputRenderers = append(outputRenderers, func() string { - return fmt.Sprintf("\t%d: PASS: %s matched by %s\n", i, actualFmt, matcher) + return fmt.Sprintf("\t%d: PASS: %s matched by %s\n", i, actualFmt(), matcher) }) } else { differences++ - outputRenderers = append(outputRenderers, fmt.Sprintf("\t%d: FAIL: %s not matched by %s\n", i, actualFmt, matcher)) + outputRenderers = append(outputRenderers, fmt.Sprintf("\t%d: FAIL: %s not matched by %s\n", i, actualFmt(), matcher)) } } else { switch expected := expected.(type) { @@ -988,13 +998,13 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { if reflect.TypeOf(actual).Name() != string(expected) && reflect.TypeOf(actual).String() != string(expected) { // not match differences++ - outputRenderers = append(outputRenderers, fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, expected, reflect.TypeOf(actual).Name(), actualFmt)) + outputRenderers = append(outputRenderers, fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, expected, reflect.TypeOf(actual).Name(), actualFmt())) } case *IsTypeArgument: actualT := reflect.TypeOf(actual) if actualT != expected.t { differences++ - outputRenderers = append(outputRenderers, fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, expected.t.Name(), actualT.Name(), actualFmt)) + outputRenderers = append(outputRenderers, fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, expected.t.Name(), actualT.Name(), actualFmt())) } case *FunctionalOptionsArgument: t := expected.value @@ -1008,7 +1018,7 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { tName := reflect.TypeOf(t).Name() if name != reflect.TypeOf(actual).String() && tValue.Len() != 0 { differences++ - outputRenderers = append(outputRenderers, fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, tName, reflect.TypeOf(actual).Name(), actualFmt)) + outputRenderers = append(outputRenderers, fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, tName, reflect.TypeOf(actual).Name(), actualFmt())) } else { if ef, af := assertOpts(t, actual); ef == "" && af == "" { // match @@ -1026,12 +1036,12 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { if expected == Anything || assert.ObjectsAreEqual(expected, Anything) || assert.ObjectsAreEqual(actual, Anything) || assert.ObjectsAreEqual(actual, expected) { // match outputRenderers = append(outputRenderers, func() string { - return fmt.Sprintf("\t%d: PASS: %s == %s\n", i, actualFmt, expectedFmt) + return fmt.Sprintf("\t%d: PASS: %s == %s\n", i, actualFmt(), expectedFmt()) }) } else { // not match differences++ - outputRenderers = append(outputRenderers, fmt.Sprintf("\t%d: FAIL: %s != %s\n", i, actualFmt, expectedFmt)) + outputRenderers = append(outputRenderers, fmt.Sprintf("\t%d: FAIL: %s != %s\n", i, actualFmt(), expectedFmt())) } } } From 68f35d264053856231a655a904361e83ec95a845 Mon Sep 17 00:00:00 2001 From: cszczepaniak Date: Sat, 15 Jul 2023 13:34:22 -0500 Subject: [PATCH 034/178] return early in Eventually and EventuallyWithT --- assert/assertions.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/assert/assertions.go b/assert/assertions.go index 104a0c936..cce5fe5c5 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -1930,6 +1930,10 @@ func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick t h.Helper() } + if condition() { + return true + } + ch := make(chan bool, 1) timer := time.NewTimer(waitFor) From cd4dc2864cb197f712c73a81e3517d3080aa07c1 Mon Sep 17 00:00:00 2001 From: cszczepaniak Date: Sat, 22 Jul 2023 11:39:00 -0500 Subject: [PATCH 035/178] respect the timeout on the initial condition check --- assert/assertions.go | 49 ++++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index cce5fe5c5..e294b329c 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -1930,11 +1930,8 @@ func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick t h.Helper() } - if condition() { - return true - } - ch := make(chan bool, 1) + checkCond := func() { ch <- condition() } timer := time.NewTimer(waitFor) defer timer.Stop() @@ -1942,18 +1939,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 } } } @@ -2023,35 +2025,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 } } } From f96316432bbdb775725e3a2fe9b8ff47917cf621 Mon Sep 17 00:00:00 2001 From: cszczepaniak Date: Sat, 22 Jul 2023 11:55:14 -0500 Subject: [PATCH 036/178] test that we succeed quickly --- assert/assertions_test.go | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 064b92f4a..3ada50f65 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -3030,6 +3030,42 @@ func TestEventuallyTimeout(t *testing.T) { }) } +func TestEventuallySucceedQuickly(t *testing.T) { + mockT := new(testing.T) + + condition := func() bool { <-time.After(time.Millisecond); return true } + + done := make(chan struct{}) + go func() { + defer close(done) + True(t, Eventually(mockT, condition, 1000*time.Millisecond, 100*time.Millisecond)) + }() + + select { + case <-done: + case <-time.After(10 * time.Millisecond): + Fail(t, `condition not satisfied quickly enough`) + } +} + +func TestEventuallyWithTSucceedQuickly(t *testing.T) { + mockT := new(testing.T) + + condition := func(t *CollectT) { <-time.After(time.Millisecond) } + + done := make(chan struct{}) + go func() { + defer close(done) + True(t, EventuallyWithT(mockT, condition, 1000*time.Millisecond, 100*time.Millisecond)) + }() + + select { + case <-done: + case <-time.After(10 * time.Millisecond): + Fail(t, `condition not satisfied quickly enough`) + } +} + func Test_validateEqualArgs(t *testing.T) { if validateEqualArgs(func() {}, func() {}) == nil { t.Error("non-nil functions should error") From e4e93dd77cc7f860f3dbdc11ee2501b1cfad0c6f Mon Sep 17 00:00:00 2001 From: Connor Szczepaniak Date: Sat, 8 Jun 2024 19:00:08 -0500 Subject: [PATCH 037/178] update Never to also check the condition initially --- assert/assertions.go | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index e294b329c..538f2e26d 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -2075,6 +2075,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() @@ -2082,18 +2083,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 } } } From ab114f88b1f16d804f2f00fb301bfde80da920d5 Mon Sep 17 00:00:00 2001 From: Connor Szczepaniak Date: Sat, 8 Jun 2024 19:01:54 -0500 Subject: [PATCH 038/178] test never when it fails quickly --- assert/assertions_test.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 3ada50f65..4c20a6612 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -3007,6 +3007,24 @@ func TestNeverTrue(t *testing.T) { False(t, Never(mockT, condition, 100*time.Millisecond, 20*time.Millisecond)) } +func TestNeverFailQuickly(t *testing.T) { + mockT := new(testing.T) + + condition := func() bool { <-time.After(time.Millisecond); return true } + + done := make(chan struct{}) + go func() { + defer close(done) + False(t, Never(mockT, condition, 1000*time.Millisecond, 100*time.Millisecond)) + }() + + select { + case <-done: + case <-time.After(10 * time.Millisecond): + Fail(t, `condition not satisfied quickly enough`) + } +} + // Check that a long running condition doesn't block Eventually. // See issue 805 (and its long tail of following issues) func TestEventuallyTimeout(t *testing.T) { From bf2c747ccaa7018462210d77f5a8fd1a3a558217 Mon Sep 17 00:00:00 2001 From: Connor Szczepaniak Date: Sat, 8 Jun 2024 19:06:31 -0500 Subject: [PATCH 039/178] simplify tests --- assert/assertions_test.go | 49 ++++++++++----------------------------- 1 file changed, 12 insertions(+), 37 deletions(-) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 4c20a6612..0e02274e0 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -3010,19 +3010,10 @@ func TestNeverTrue(t *testing.T) { func TestNeverFailQuickly(t *testing.T) { mockT := new(testing.T) - condition := func() bool { <-time.After(time.Millisecond); return true } - - done := make(chan struct{}) - go func() { - defer close(done) - False(t, Never(mockT, condition, 1000*time.Millisecond, 100*time.Millisecond)) - }() - - select { - case <-done: - case <-time.After(10 * time.Millisecond): - Fail(t, `condition not satisfied quickly enough`) - } + // By making the tick longer than the total duration, we expect that this test would fail if + // we didn't check the condition before the first tick elapses. + condition := func() bool { return true } + False(t, Never(mockT, condition, 100*time.Millisecond, time.Second)) } // Check that a long running condition doesn't block Eventually. @@ -3051,37 +3042,21 @@ func TestEventuallyTimeout(t *testing.T) { func TestEventuallySucceedQuickly(t *testing.T) { mockT := new(testing.T) - condition := func() bool { <-time.After(time.Millisecond); return true } - - done := make(chan struct{}) - go func() { - defer close(done) - True(t, Eventually(mockT, condition, 1000*time.Millisecond, 100*time.Millisecond)) - }() + condition := func() bool { return true } - select { - case <-done: - case <-time.After(10 * time.Millisecond): - Fail(t, `condition not satisfied quickly enough`) - } + // By making the tick longer than the total duration, we expect that this test would fail if + // we didn't check the condition before the first tick elapses. + True(t, Eventually(mockT, condition, 100*time.Millisecond, time.Second)) } func TestEventuallyWithTSucceedQuickly(t *testing.T) { mockT := new(testing.T) - condition := func(t *CollectT) { <-time.After(time.Millisecond) } + condition := func(t *CollectT) {} - done := make(chan struct{}) - go func() { - defer close(done) - True(t, EventuallyWithT(mockT, condition, 1000*time.Millisecond, 100*time.Millisecond)) - }() - - select { - case <-done: - case <-time.After(10 * time.Millisecond): - Fail(t, `condition not satisfied quickly enough`) - } + // By making the tick longer than the total duration, we expect that this test would fail if + // we didn't check the condition before the first tick elapses. + True(t, EventuallyWithT(mockT, condition, 100*time.Millisecond, time.Second)) } func Test_validateEqualArgs(t *testing.T) { From bae586f140e3578be864304c3a0cb037303cdfb4 Mon Sep 17 00:00:00 2001 From: Connor Szczepaniak Date: Sat, 8 Jun 2024 19:08:49 -0500 Subject: [PATCH 040/178] colocate never/eventually tests --- assert/assertions_test.go | 72 +++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 0e02274e0..dc7c5bde3 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -2980,42 +2980,6 @@ func TestEventuallyWithTFailNow(t *testing.T) { Len(t, mockT.errors, 1) } -func TestNeverFalse(t *testing.T) { - condition := func() bool { - return false - } - - True(t, Never(t, condition, 100*time.Millisecond, 20*time.Millisecond)) -} - -// TestNeverTrue checks Never with a condition that returns true on second call. -func TestNeverTrue(t *testing.T) { - mockT := new(testing.T) - - // A list of values returned by condition. - // Channel protects against concurrent access. - returns := make(chan bool, 2) - returns <- false - returns <- true - defer close(returns) - - // Will return true on second call. - condition := func() bool { - return <-returns - } - - False(t, Never(mockT, condition, 100*time.Millisecond, 20*time.Millisecond)) -} - -func TestNeverFailQuickly(t *testing.T) { - mockT := new(testing.T) - - // By making the tick longer than the total duration, we expect that this test would fail if - // we didn't check the condition before the first tick elapses. - condition := func() bool { return true } - False(t, Never(mockT, condition, 100*time.Millisecond, time.Second)) -} - // Check that a long running condition doesn't block Eventually. // See issue 805 (and its long tail of following issues) func TestEventuallyTimeout(t *testing.T) { @@ -3059,6 +3023,42 @@ func TestEventuallyWithTSucceedQuickly(t *testing.T) { True(t, EventuallyWithT(mockT, condition, 100*time.Millisecond, time.Second)) } +func TestNeverFalse(t *testing.T) { + condition := func() bool { + return false + } + + True(t, Never(t, condition, 100*time.Millisecond, 20*time.Millisecond)) +} + +// TestNeverTrue checks Never with a condition that returns true on second call. +func TestNeverTrue(t *testing.T) { + mockT := new(testing.T) + + // A list of values returned by condition. + // Channel protects against concurrent access. + returns := make(chan bool, 2) + returns <- false + returns <- true + defer close(returns) + + // Will return true on second call. + condition := func() bool { + return <-returns + } + + False(t, Never(mockT, condition, 100*time.Millisecond, 20*time.Millisecond)) +} + +func TestNeverFailQuickly(t *testing.T) { + mockT := new(testing.T) + + // By making the tick longer than the total duration, we expect that this test would fail if + // we didn't check the condition before the first tick elapses. + condition := func() bool { return true } + False(t, Never(mockT, condition, 100*time.Millisecond, time.Second)) +} + func Test_validateEqualArgs(t *testing.T) { if validateEqualArgs(func() {}, func() {}) == nil { t.Error("non-nil functions should error") From 52df55490e922b9229bf066cd8f28664cf84de33 Mon Sep 17 00:00:00 2001 From: Harald Nordgren Date: Wed, 24 Jul 2024 13:39:26 +0200 Subject: [PATCH 041/178] .github/workflows: Run tests for Go 1.22 --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9458c398e..1dd4e650f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -29,6 +29,7 @@ jobs: - "1.19" - "1.20" - "1.21" + - "1.22" steps: - uses: actions/checkout@v4 - name: Setup Go From da63673a11ab3babfaffb7501ef4108c505af6bb Mon Sep 17 00:00:00 2001 From: Joseph Dallago Date: Thu, 29 Aug 2024 22:05:04 +0300 Subject: [PATCH 042/178] Now properly record the ReturnArguments as part of the call. --- mock/mock.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mock/mock.go b/mock/mock.go index d5eb1ef55..372c8e5ba 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -80,12 +80,12 @@ type Call struct { requires []*Call } -func newCall(parent *Mock, methodName string, callerInfo []string, methodArguments ...interface{}) *Call { +func newCall(parent *Mock, methodName string, callerInfo []string, methodArguments Arguments, returnArguments Arguments) *Call { return &Call{ Parent: parent, Method: methodName, Arguments: methodArguments, - ReturnArguments: make([]interface{}, 0), + ReturnArguments: returnArguments, callerInfo: callerInfo, Repeatability: 0, WaitFor: nil, @@ -351,7 +351,8 @@ func (m *Mock) On(methodName string, arguments ...interface{}) *Call { m.mutex.Lock() defer m.mutex.Unlock() - c := newCall(m, methodName, assert.CallerInfo(), arguments...) + + c := newCall(m, methodName, assert.CallerInfo(), arguments, make([]interface{}, 0)) m.ExpectedCalls = append(m.ExpectedCalls, c) return c } @@ -529,7 +530,7 @@ func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Argumen call.totalCalls++ // add the call - m.Calls = append(m.Calls, *newCall(m, methodName, assert.CallerInfo(), arguments...)) + m.Calls = append(m.Calls, *newCall(m, methodName, assert.CallerInfo(), arguments, call.ReturnArguments)) m.mutex.Unlock() // block if specified From 7268a5bc0bb240a58a3f85d04076ad9ae13e2cb2 Mon Sep 17 00:00:00 2001 From: Reynier Ortiz Date: Fri, 6 Sep 2024 09:18:07 -0400 Subject: [PATCH 043/178] mock: in order mock calls --- mock/mock.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mock/mock.go b/mock/mock.go index d5eb1ef55..64464450b 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -273,6 +273,13 @@ func (c *Call) NotBefore(calls ...*Call) *Call { return c } +// InOrder defines the order in which the calls should be made +func InOrder(calls ...*Call) { + for i := 1; i < len(calls); i++ { + calls[i].NotBefore(calls[i-1]) + } +} + // Mock is the workhorse used to track activity on another object. // For an example of its usage, refer to the "Example Usage" section at the top // of this document. From e943930404ddd99e7481c92aabebbc589385b6b9 Mon Sep 17 00:00:00 2001 From: Steven Hartland Date: Sun, 13 Nov 2022 21:32:28 +0000 Subject: [PATCH 044/178] fix(suite): test failures Fix TestFailfastSuite when run with go test flag -count=X where X greater than 1. --- suite/suite_test.go | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/suite/suite_test.go b/suite/suite_test.go index db57a5fd2..b97eb4311 100644 --- a/suite/suite_test.go +++ b/suite/suite_test.go @@ -604,14 +604,44 @@ func TestFailfastSuite(t *testing.T) { }}, ) assert.False(t, ok) + var expect []string if failFast { // Test A Fails and because we are running with failfast Test B never runs and we proceed straight to TearDownSuite - assert.Equal(t, "SetupSuite;SetupTest;Test A Fails;TearDownTest;TearDownSuite", strings.Join(s.callOrder, ";")) + expect = []string{"SetupSuite", "SetupTest", "Test A Fails", "TearDownTest", "TearDownSuite"} } else { // Test A Fails and because we are running without failfast we continue and run Test B and then proceed to TearDownSuite - assert.Equal(t, "SetupSuite;SetupTest;Test A Fails;TearDownTest;SetupTest;Test B Passes;TearDownTest;TearDownSuite", strings.Join(s.callOrder, ";")) + expect = []string{"SetupSuite", "SetupTest", "Test A Fails", "TearDownTest", "SetupTest", "Test B Passes", "TearDownTest", "TearDownSuite"} } + callOrderAssert(t, expect, s.callOrder) } + +type tHelper interface { + Helper() +} + +// callOrderAssert is a help with confirms that asserts that expect +// matches one or more times in callOrder. This makes it compatible +// with go test flag -count=X where X > 1. +func callOrderAssert(t *testing.T, expect, callOrder []string) { + var ti interface{} = t + if h, ok := ti.(tHelper); ok { + h.Helper() + } + + callCount := len(callOrder) + expectCount := len(expect) + if callCount > expectCount && callCount%expectCount == 0 { + // Command line flag -count=X where X > 1. + for len(callOrder) >= expectCount { + assert.Equal(t, expect, callOrder[:expectCount]) + callOrder = callOrder[expectCount:] + } + return + } + + assert.Equal(t, expect, callOrder) +} + func TestFailfastSuiteFailFastOn(t *testing.T) { // To test this with failfast on (and isolated from other intended test failures in our test suite) we launch it in its own process cmd := exec.Command("go", "test", "-v", "-race", "-run", "TestFailfastSuite", "-failfast") From bdb1271ed89c8de6881bc02cfe700bb91bc9a990 Mon Sep 17 00:00:00 2001 From: Reynier Ortiz Date: Fri, 6 Sep 2024 09:18:07 -0400 Subject: [PATCH 045/178] mock: in order mock calls --- mock/mock_test.go | 59 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/mock/mock_test.go b/mock/mock_test.go index b80a8a75b..bc3c5ad2f 100644 --- a/mock/mock_test.go +++ b/mock/mock_test.go @@ -937,6 +937,30 @@ func Test_Mock_Return_NotBefore_In_Order(t *testing.T) { }) } +func Test_Mock_Return_InOrder_Uses_NotBefore(t *testing.T) { + var mockedService = new(TestExampleImplementation) + + b := mockedService. + On("TheExampleMethod", 1, 2, 3). + Return(4, nil) + c := mockedService. + On("TheExampleMethod2", true). + Return() + + InOrder( + b, + c, + ) + + require.Equal(t, []*Call{b, c}, mockedService.ExpectedCalls) + require.NotPanics(t, func() { + mockedService.TheExampleMethod(1, 2, 3) + }) + require.NotPanics(t, func() { + mockedService.TheExampleMethod2(true) + }) +} + func Test_Mock_Return_NotBefore_Out_Of_Order(t *testing.T) { var mockedService = new(TestExampleImplementation) @@ -967,6 +991,40 @@ TheExampleMethod(int,int,int) }) } +func Test_Mock_Return_InOrder_Uses_NotBefore_Out_Of_Order(t *testing.T) { + var mockedService = new(TestExampleImplementation) + + b := mockedService. + On("TheExampleMethod", 1, 2, 3). + Return(4, nil).Twice() + c := mockedService. + On("TheExampleMethod2", true). + Return() + + InOrder( + b, + c, + ) + + require.Equal(t, []*Call{b, c}, mockedService.ExpectedCalls) + + expectedPanicString := `mock: Unexpected Method Call +----------------------------- + +TheExampleMethod2(bool) + 0: true + +Must not be called before: + +TheExampleMethod(int,int,int) + 0: 1 + 1: 2 + 2: 3` + require.PanicsWithValue(t, expectedPanicString, func() { + mockedService.TheExampleMethod2(true) + }) +} + func Test_Mock_Return_NotBefore_Not_Enough_Times(t *testing.T) { var mockedService = new(TestExampleImplementation) @@ -1022,6 +1080,7 @@ func Test_Mock_Return_NotBefore_Different_Mock_In_Order(t *testing.T) { mockedService2.TheExampleMethod2(true) }) } + func Test_Mock_Return_NotBefore_Different_Mock_Out_Of_Order(t *testing.T) { var ( mockedService1 = new(TestExampleImplementation) From f17409f81f93ebd964caa7a36793134d68e23fdb Mon Sep 17 00:00:00 2001 From: Reynier Ortiz Date: Fri, 6 Sep 2024 09:18:07 -0400 Subject: [PATCH 046/178] mock: in order mock calls (requested changes applied) --- mock/mock.go | 7 +++++++ mock/mock_test.go | 33 ++++++++++++--------------------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/mock/mock.go b/mock/mock.go index 64464450b..920a87adc 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -274,6 +274,13 @@ func (c *Call) NotBefore(calls ...*Call) *Call { } // InOrder defines the order in which the calls should be made +// +// For example: +// +// InOrder( +// Mock.On("init").Return(nil), +// Mock.On("Do").Return(nil), +// ) func InOrder(calls ...*Call) { for i := 1; i < len(calls); i++ { calls[i].NotBefore(calls[i-1]) diff --git a/mock/mock_test.go b/mock/mock_test.go index bc3c5ad2f..4878b677e 100644 --- a/mock/mock_test.go +++ b/mock/mock_test.go @@ -940,19 +940,15 @@ func Test_Mock_Return_NotBefore_In_Order(t *testing.T) { func Test_Mock_Return_InOrder_Uses_NotBefore(t *testing.T) { var mockedService = new(TestExampleImplementation) - b := mockedService. - On("TheExampleMethod", 1, 2, 3). - Return(4, nil) - c := mockedService. - On("TheExampleMethod2", true). - Return() - InOrder( - b, - c, + mockedService. + On("TheExampleMethod", 1, 2, 3). + Return(4, nil), + mockedService. + On("TheExampleMethod2", true). + Return(), ) - require.Equal(t, []*Call{b, c}, mockedService.ExpectedCalls) require.NotPanics(t, func() { mockedService.TheExampleMethod(1, 2, 3) }) @@ -994,20 +990,15 @@ TheExampleMethod(int,int,int) func Test_Mock_Return_InOrder_Uses_NotBefore_Out_Of_Order(t *testing.T) { var mockedService = new(TestExampleImplementation) - b := mockedService. - On("TheExampleMethod", 1, 2, 3). - Return(4, nil).Twice() - c := mockedService. - On("TheExampleMethod2", true). - Return() - InOrder( - b, - c, + mockedService. + On("TheExampleMethod", 1, 2, 3). + Return(4, nil).Twice(), + mockedService. + On("TheExampleMethod2", true). + Return(), ) - require.Equal(t, []*Call{b, c}, mockedService.ExpectedCalls) - expectedPanicString := `mock: Unexpected Method Call ----------------------------- From ea6964c2e96c2c682acc94781c71d861e21c94fc Mon Sep 17 00:00:00 2001 From: spirin Date: Mon, 30 Sep 2024 21:33:46 +0300 Subject: [PATCH 047/178] mock: caller information for unexpected method call --- mock/mock.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mock/mock.go b/mock/mock.go index d5eb1ef55..a4b7b0864 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -491,11 +491,12 @@ func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Argumen m.mutex.Unlock() if closestCall != nil { - m.fail("\n\nmock: Unexpected Method Call\n-----------------------------\n\n%s\n\nThe closest call I have is: \n\n%s\n\n%s\nDiff: %s", + m.fail("\n\nmock: Unexpected Method Call\n-----------------------------\n\n%s\n\nThe closest call I have is: \n\n%s\n\n%s\nDiff: %s\nat: %s\n", callString(methodName, arguments, true), callString(methodName, closestCall.Arguments, true), diffArguments(closestCall.Arguments, arguments), strings.TrimSpace(mismatch), + assert.CallerInfo(), ) } else { m.fail("\nassert: mock: I don't know what to return because the method call was unexpected.\n\tEither do Mock.On(\"%s\").Return(...) first, or remove the %s() call.\n\tThis method was unexpected:\n\t\t%s\n\tat: %s", methodName, methodName, callString(methodName, arguments, true), assert.CallerInfo()) From d62ca68bf5d930468044ce3b7286c12a63079c22 Mon Sep 17 00:00:00 2001 From: spirin Date: Tue, 1 Oct 2024 02:21:38 +0300 Subject: [PATCH 048/178] tests --- mock/mock_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mock/mock_test.go b/mock/mock_test.go index b80a8a75b..95159d852 100644 --- a/mock/mock_test.go +++ b/mock/mock_test.go @@ -1980,7 +1980,7 @@ func TestArgumentMatcherToPrintMismatch(t *testing.T) { defer func() { if r := recover(); r != nil { matchingExp := regexp.MustCompile( - `\s+mock: Unexpected Method Call\s+-*\s+GetTime\(int\)\s+0: 1\s+The closest call I have is:\s+GetTime\(mock.argumentMatcher\)\s+0: mock.argumentMatcher\{.*?\}\s+Diff:.*\(int=1\) not matched by func\(int\) bool`) + `\s+mock: Unexpected Method Call\s+-*\s+GetTime\(int\)\s+0: 1\s+The closest call I have is:\s+GetTime\(mock.argumentMatcher\)\s+0: mock.argumentMatcher\{.*?\}\s+Diff:.*\(int=1\) not matched by func\(int\) bool\nat: \[[^\]]+mock\/mock_test.go`) assert.Regexp(t, matchingExp, r) } }() @@ -1997,7 +1997,7 @@ func TestArgumentMatcherToPrintMismatchWithReferenceType(t *testing.T) { defer func() { if r := recover(); r != nil { matchingExp := regexp.MustCompile( - `\s+mock: Unexpected Method Call\s+-*\s+GetTimes\(\[\]int\)\s+0: \[\]int\{1\}\s+The closest call I have is:\s+GetTimes\(mock.argumentMatcher\)\s+0: mock.argumentMatcher\{.*?\}\s+Diff:.*\(\[\]int=\[1\]\) not matched by func\(\[\]int\) bool`) + `\s+mock: Unexpected Method Call\s+-*\s+GetTimes\(\[\]int\)\s+0: \[\]int\{1\}\s+The closest call I have is:\s+GetTimes\(mock.argumentMatcher\)\s+0: mock.argumentMatcher\{.*?\}\s+Diff:.*\(\[\]int=\[1\]\) not matched by func\(\[\]int\) bool\nat: \[[^\]]+mock\/mock_test.go`) assert.Regexp(t, matchingExp, r) } }() @@ -2028,7 +2028,7 @@ func TestClosestCallMismatchedArgumentInformationShowsTheClosest(t *testing.T) { func TestClosestCallFavorsFirstMock(t *testing.T) { defer func() { if r := recover(); r != nil { - diffRegExp := `Difference found in argument 0:\s+--- Expected\s+\+\+\+ Actual\s+@@ -2,4 \+2,4 @@\s+\(bool\) true,\s+- \(bool\) true,\s+- \(bool\) true\s+\+ \(bool\) false,\s+\+ \(bool\) false\s+}\s+` + diffRegExp := `Difference found in argument 0:\s+--- Expected\s+\+\+\+ Actual\s+@@ -2,4 \+2,4 @@\s+\(bool\) true,\s+- \(bool\) true,\s+- \(bool\) true\s+\+ \(bool\) false,\s+\+ \(bool\) false\s+}\s+Diff: 0: FAIL: \(\[\]bool=\[(true\s?|false\s?){3}]\) != \(\[\]bool=\[(true\s?|false\s?){3}\]\)` matchingExp := regexp.MustCompile(unexpectedCallRegex(`TheExampleMethod7([]bool)`, `0: \[\]bool{true, false, false}`, `0: \[\]bool{true, true, true}`, diffRegExp)) assert.Regexp(t, matchingExp, r) } @@ -2044,7 +2044,7 @@ func TestClosestCallFavorsFirstMock(t *testing.T) { func TestClosestCallUsesRepeatabilityToFindClosest(t *testing.T) { defer func() { if r := recover(); r != nil { - diffRegExp := `Difference found in argument 0:\s+--- Expected\s+\+\+\+ Actual\s+@@ -1,4 \+1,4 @@\s+\(\[\]bool\) \(len=3\) {\s+- \(bool\) false,\s+- \(bool\) false,\s+\+ \(bool\) true,\s+\+ \(bool\) true,\s+\(bool\) false\s+` + diffRegExp := `Difference found in argument 0:\s+--- Expected\s+\+\+\+ Actual\s+@@ -1,4 \+1,4 @@\s+\(\[\]bool\) \(len=3\) {\s+- \(bool\) false,\s+- \(bool\) false,\s+\+ \(bool\) true,\s+\+ \(bool\) true,\s+\(bool\) false\s+Diff: 0: FAIL: \(\[\]bool=\[(true\s?|false\s?){3}]\) != \(\[\]bool=\[(true\s?|false\s?){3}\]\)` matchingExp := regexp.MustCompile(unexpectedCallRegex(`TheExampleMethod7([]bool)`, `0: \[\]bool{true, true, false}`, `0: \[\]bool{false, false, false}`, diffRegExp)) assert.Regexp(t, matchingExp, r) } @@ -2101,7 +2101,7 @@ func Test_isBetterMatchThanReturnsFalseIfRepeatabilityIsLessThanOrEqualToOther(t func unexpectedCallRegex(method, calledArg, expectedArg, diff string) string { rMethod := regexp.QuoteMeta(method) - return fmt.Sprintf(`\s+mock: Unexpected Method Call\s+-*\s+%s\s+%s\s+The closest call I have is:\s+%s\s+%s\s+%s`, + return fmt.Sprintf(`\s+mock: Unexpected Method Call\s+-*\s+%s\s+%s\s+The closest call I have is:\s+%s\s+%s\s+%s\nat: \[[^\]]+mock\/mock_test.go`, rMethod, calledArg, rMethod, expectedArg, diff) } From fed9ee68dc942c41c77a9b2c2431f3c2967c00ae Mon Sep 17 00:00:00 2001 From: Bracken Dawson Date: Tue, 1 Oct 2024 23:55:16 +0100 Subject: [PATCH 049/178] Document suite's lack of support for t.Parallel --- README.md | 2 ++ suite/doc.go | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/README.md b/README.md index 0250c3e6d..ccaa7586b 100644 --- a/README.md +++ b/README.md @@ -223,6 +223,8 @@ You can use the [mockery tool](https://vektra.github.io/mockery/latest/) to auto [`suite`](https://pkg.go.dev/github.com/stretchr/testify/suite "API documentation") package ----------------------------------------------------------------------------------------- +> [!WARNING] +> The suite package does not support parallel tests. See [#934](https://github.com/stretchr/testify/issues/934). The `suite` package provides functionality that you might be used to from more common object-oriented languages. With it, you can build a testing suite as a struct, build setup/teardown methods and testing methods on your struct, and run them with 'go test' as per normal. diff --git a/suite/doc.go b/suite/doc.go index 8d55a3aa8..05a562f72 100644 --- a/suite/doc.go +++ b/suite/doc.go @@ -5,6 +5,8 @@ // or individual tests (depending on which interface(s) you // implement). // +// The suite package does not support parallel tests. See [issue 934]. +// // A testing suite is usually built by first extending the built-in // suite functionality from suite.Suite in testify. Alternatively, // you could reproduce that logic on your own if you wanted (you @@ -63,4 +65,6 @@ // func TestExampleTestSuite(t *testing.T) { // suite.Run(t, new(ExampleTestSuite)) // } +// +// [issue 934]: https://github.com/stretchr/testify/issues/934 package suite From 3380867632684d2023eeeb0d5d1d45a7b89e6972 Mon Sep 17 00:00:00 2001 From: Pal Sivertsen Date: Tue, 30 Nov 2021 14:26:04 +0100 Subject: [PATCH 050/178] Add NotErrorAs assertion The library already had assertions for `ErrorIs`, `NotErrorIs` and `ErrorAs`. This commit adds the `NotErrorAs` assertion which is the inverse of `ErrorAs`. --- assert/assertion_format.go | 9 +++++++++ assert/assertion_forward.go | 18 ++++++++++++++++++ assert/assertions.go | 18 ++++++++++++++++++ assert/assertions_test.go | 27 ++++++++++++++++++++++++++- require/require.go | 24 ++++++++++++++++++++++++ require/require_forward.go | 18 ++++++++++++++++++ 6 files changed, 113 insertions(+), 1 deletion(-) diff --git a/assert/assertion_format.go b/assert/assertion_format.go index 546fe1fb2..1db39550d 100644 --- a/assert/assertion_format.go +++ b/assert/assertion_format.go @@ -621,6 +621,15 @@ func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg s return NotEqualValues(t, expected, actual, append([]interface{}{msg}, args...)...) } +// NotErrorAsf asserts that at none of the errors in err's chain matches target. +// This is the inverse of the ErrorAs function. +func NotErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return NotErrorAs(t, err, target, append([]interface{}{msg}, args...)...) +} + // NotErrorIsf asserts that none of the errors in err's chain matches target. // This is a wrapper for errors.Is. func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) bool { diff --git a/assert/assertion_forward.go b/assert/assertion_forward.go index 8504dca9f..a658b4db8 100644 --- a/assert/assertion_forward.go +++ b/assert/assertion_forward.go @@ -1234,6 +1234,24 @@ func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg str return NotEqualf(a.t, expected, actual, msg, args...) } +// NotErrorAs asserts that at none of the errors in err's chain matches target. +// This is the inverse of the ErrorAs function. +func (a *Assertions) NotErrorAs(err error, target interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotErrorAs(a.t, err, target, msgAndArgs...) +} + +// NotErrorAsf asserts that at none of the errors in err's chain matches target. +// This is the inverse of the ErrorAs function. +func (a *Assertions) NotErrorAsf(err error, target interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotErrorAsf(a.t, err, target, msg, args...) +} + // NotErrorIs asserts that none of the errors in err's chain matches target. // This is a wrapper for errors.Is. func (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface{}) bool { diff --git a/assert/assertions.go b/assert/assertions.go index 104a0c936..5ace3d495 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -2149,6 +2149,24 @@ func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{ ), msgAndArgs...) } +// NotErrorAs asserts that at none of the errors in err's chain matches target. +// This is the inverse of the ErrorAs function. +func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if !errors.As(err, target) { + return true + } + + chain := buildErrorChainString(err) + + return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+ + "found: %q\n"+ + "in chain: %s", target, chain, + ), msgAndArgs...) +} + func buildErrorChainString(err error) string { if err == nil { return "" diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 064b92f4a..228f20ac4 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -3284,7 +3284,32 @@ func TestErrorAs(t *testing.T) { t.Run(fmt.Sprintf("ErrorAs(%#v,%#v)", tt.err, target), func(t *testing.T) { res := ErrorAs(mockT, tt.err, &target) if res != tt.result { - t.Errorf("ErrorAs(%#v,%#v) should return %t)", tt.err, target, tt.result) + t.Errorf("ErrorAs(%#v,%#v) should return %t", tt.err, target, tt.result) + } + }) + } +} + +func TestNotErrorAs(t *testing.T) { + tests := []struct { + err error + result bool + }{ + {fmt.Errorf("wrap: %w", &customError{}), false}, + {io.EOF, true}, + {nil, true}, + } + for _, tt := range tests { + tt := tt + var target *customError + t.Run(fmt.Sprintf("NotErrorAs(%#v,%#v)", tt.err, target), func(t *testing.T) { + mockT := new(testing.T) + res := NotErrorAs(mockT, tt.err, &target) + if res != tt.result { + t.Errorf("NotErrorAs(%#v,%#v) should not return %t", tt.err, target, tt.result) + } + if res == mockT.Failed() { + t.Errorf("The test result (%t) should be reflected in the testing.T type (%t)", res, !mockT.Failed()) } }) } diff --git a/require/require.go b/require/require.go index d0c73ff13..bf9877cfa 100644 --- a/require/require.go +++ b/require/require.go @@ -1559,6 +1559,30 @@ func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, t.FailNow() } +// NotErrorAs asserts that at none of the errors in err's chain matches target. +// This is the inverse of the ErrorAs function. +func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if assert.NotErrorAs(t, err, target, msgAndArgs...) { + return + } + t.FailNow() +} + +// NotErrorAsf asserts that at none of the errors in err's chain matches target. +// This is the inverse of the ErrorAs function. +func NotErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if assert.NotErrorAsf(t, err, target, msg, args...) { + return + } + t.FailNow() +} + // NotErrorIs asserts that none of the errors in err's chain matches target. // This is a wrapper for errors.Is. func NotErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) { diff --git a/require/require_forward.go b/require/require_forward.go index 3c15ca36b..521daaf1a 100644 --- a/require/require_forward.go +++ b/require/require_forward.go @@ -1235,6 +1235,24 @@ func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg str NotEqualf(a.t, expected, actual, msg, args...) } +// NotErrorAs asserts that at none of the errors in err's chain matches target. +// This is the inverse of the ErrorAs function. +func (a *Assertions) NotErrorAs(err error, target interface{}, msgAndArgs ...interface{}) { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + NotErrorAs(a.t, err, target, msgAndArgs...) +} + +// NotErrorAsf asserts that at none of the errors in err's chain matches target. +// This is the inverse of the ErrorAs function. +func (a *Assertions) NotErrorAsf(err error, target interface{}, msg string, args ...interface{}) { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + NotErrorAsf(a.t, err, target, msg, args...) +} + // NotErrorIs asserts that none of the errors in err's chain matches target. // This is a wrapper for errors.Is. func (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface{}) { From aade8450b3812d4f2e5d4cb65769b264c4604328 Mon Sep 17 00:00:00 2001 From: Pal Sivertsen Date: Tue, 30 Nov 2021 14:29:39 +0100 Subject: [PATCH 051/178] Improve tests for ErrorIs/ErrorAs Checks that the assertion result matches what's set in `testing.T`. --- assert/assertions_test.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 228f20ac4..20d63b108 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -3269,7 +3269,6 @@ func TestNotErrorIs(t *testing.T) { } func TestErrorAs(t *testing.T) { - mockT := new(testing.T) tests := []struct { err error result bool @@ -3282,10 +3281,14 @@ func TestErrorAs(t *testing.T) { tt := tt var target *customError t.Run(fmt.Sprintf("ErrorAs(%#v,%#v)", tt.err, target), func(t *testing.T) { + mockT := new(testing.T) res := ErrorAs(mockT, tt.err, &target) if res != tt.result { t.Errorf("ErrorAs(%#v,%#v) should return %t", tt.err, target, tt.result) } + if res == mockT.Failed() { + t.Errorf("The test result (%t) should be reflected in the testing.T type (%t)", res, !mockT.Failed()) + } }) } } From dc100b1be3ac644d59bccf1f4b9b00261eb10f6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A5l=20Sivertsen?= Date: Fri, 4 Oct 2024 09:52:45 +0200 Subject: [PATCH 052/178] Review: Drop doc line and fix typo Review feedback: https://github.com/stretchr/testify/pull/1129#discussion_r1786495803 --- assert/assertion_format.go | 3 +-- assert/assertion_forward.go | 6 ++---- assert/assertions.go | 3 +-- require/require.go | 6 ++---- require/require_forward.go | 6 ++---- 5 files changed, 8 insertions(+), 16 deletions(-) diff --git a/assert/assertion_format.go b/assert/assertion_format.go index 1db39550d..2dff9e457 100644 --- a/assert/assertion_format.go +++ b/assert/assertion_format.go @@ -621,8 +621,7 @@ func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg s return NotEqualValues(t, expected, actual, append([]interface{}{msg}, args...)...) } -// NotErrorAsf asserts that at none of the errors in err's chain matches target. -// This is the inverse of the ErrorAs function. +// NotErrorAsf asserts that none of the errors in err's chain matches target. func NotErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/assert/assertion_forward.go b/assert/assertion_forward.go index a658b4db8..7bcc9f07a 100644 --- a/assert/assertion_forward.go +++ b/assert/assertion_forward.go @@ -1234,8 +1234,7 @@ func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg str return NotEqualf(a.t, expected, actual, msg, args...) } -// NotErrorAs asserts that at none of the errors in err's chain matches target. -// This is the inverse of the ErrorAs function. +// NotErrorAs asserts that none of the errors in err's chain matches target. func (a *Assertions) NotErrorAs(err error, target interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1243,8 +1242,7 @@ func (a *Assertions) NotErrorAs(err error, target interface{}, msgAndArgs ...int return NotErrorAs(a.t, err, target, msgAndArgs...) } -// NotErrorAsf asserts that at none of the errors in err's chain matches target. -// This is the inverse of the ErrorAs function. +// NotErrorAsf asserts that none of the errors in err's chain matches target. func (a *Assertions) NotErrorAsf(err error, target interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() diff --git a/assert/assertions.go b/assert/assertions.go index 5ace3d495..4ebe30279 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -2149,8 +2149,7 @@ func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{ ), msgAndArgs...) } -// NotErrorAs asserts that at none of the errors in err's chain matches target. -// This is the inverse of the ErrorAs function. +// NotErrorAs asserts that none of the errors in err's chain matches target. func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/require/require.go b/require/require.go index bf9877cfa..9871d0855 100644 --- a/require/require.go +++ b/require/require.go @@ -1559,8 +1559,7 @@ func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, t.FailNow() } -// NotErrorAs asserts that at none of the errors in err's chain matches target. -// This is the inverse of the ErrorAs function. +// NotErrorAs asserts that none of the errors in err's chain matches target. func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1571,8 +1570,7 @@ func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interfa t.FailNow() } -// NotErrorAsf asserts that at none of the errors in err's chain matches target. -// This is the inverse of the ErrorAs function. +// NotErrorAsf asserts that none of the errors in err's chain matches target. func NotErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/require/require_forward.go b/require/require_forward.go index 521daaf1a..34ac53318 100644 --- a/require/require_forward.go +++ b/require/require_forward.go @@ -1235,8 +1235,7 @@ func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg str NotEqualf(a.t, expected, actual, msg, args...) } -// NotErrorAs asserts that at none of the errors in err's chain matches target. -// This is the inverse of the ErrorAs function. +// NotErrorAs asserts that none of the errors in err's chain matches target. func (a *Assertions) NotErrorAs(err error, target interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1244,8 +1243,7 @@ func (a *Assertions) NotErrorAs(err error, target interface{}, msgAndArgs ...int NotErrorAs(a.t, err, target, msgAndArgs...) } -// NotErrorAsf asserts that at none of the errors in err's chain matches target. -// This is the inverse of the ErrorAs function. +// NotErrorAsf asserts that none of the errors in err's chain matches target. func (a *Assertions) NotErrorAsf(err error, target interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() From f844b269dfdaed00db57ff08e2ff601daa349e00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A5l=20Sivertsen?= Date: Fri, 4 Oct 2024 12:37:24 +0200 Subject: [PATCH 053/178] Review: Expand NotErrorAs func docs https://github.com/stretchr/testify/pull/1129#discussion_r1787490770 --- assert/assertion_format.go | 3 ++- assert/assertion_forward.go | 6 ++++-- assert/assertions.go | 3 ++- require/require.go | 6 ++++-- require/require_forward.go | 6 ++++-- 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/assert/assertion_format.go b/assert/assertion_format.go index 2dff9e457..190634165 100644 --- a/assert/assertion_format.go +++ b/assert/assertion_format.go @@ -621,7 +621,8 @@ func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg s return NotEqualValues(t, expected, actual, append([]interface{}{msg}, args...)...) } -// NotErrorAsf asserts that none of the errors in err's chain matches target. +// NotErrorAsf asserts that none of the errors in err's chain matches target, +// but if so, sets target to that error value. func NotErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/assert/assertion_forward.go b/assert/assertion_forward.go index 7bcc9f07a..21629087b 100644 --- a/assert/assertion_forward.go +++ b/assert/assertion_forward.go @@ -1234,7 +1234,8 @@ func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg str return NotEqualf(a.t, expected, actual, msg, args...) } -// NotErrorAs asserts that none of the errors in err's chain matches target. +// NotErrorAs asserts that none of the errors in err's chain matches target, +// but if so, sets target to that error value. func (a *Assertions) NotErrorAs(err error, target interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1242,7 +1243,8 @@ func (a *Assertions) NotErrorAs(err error, target interface{}, msgAndArgs ...int return NotErrorAs(a.t, err, target, msgAndArgs...) } -// NotErrorAsf asserts that none of the errors in err's chain matches target. +// NotErrorAsf asserts that none of the errors in err's chain matches target, +// but if so, sets target to that error value. func (a *Assertions) NotErrorAsf(err error, target interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() diff --git a/assert/assertions.go b/assert/assertions.go index 4ebe30279..44b854da6 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -2149,7 +2149,8 @@ func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{ ), msgAndArgs...) } -// NotErrorAs asserts that none of the errors in err's chain matches target. +// NotErrorAs asserts that none of the errors in err's chain matches target, +// but if so, sets target to that error value. func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/require/require.go b/require/require.go index 9871d0855..50ec19e13 100644 --- a/require/require.go +++ b/require/require.go @@ -1559,7 +1559,8 @@ func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, t.FailNow() } -// NotErrorAs asserts that none of the errors in err's chain matches target. +// NotErrorAs asserts that none of the errors in err's chain matches target, +// but if so, sets target to that error value. func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1570,7 +1571,8 @@ func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interfa t.FailNow() } -// NotErrorAsf asserts that none of the errors in err's chain matches target. +// NotErrorAsf asserts that none of the errors in err's chain matches target, +// but if so, sets target to that error value. func NotErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/require/require_forward.go b/require/require_forward.go index 34ac53318..1bd87304f 100644 --- a/require/require_forward.go +++ b/require/require_forward.go @@ -1235,7 +1235,8 @@ func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg str NotEqualf(a.t, expected, actual, msg, args...) } -// NotErrorAs asserts that none of the errors in err's chain matches target. +// NotErrorAs asserts that none of the errors in err's chain matches target, +// but if so, sets target to that error value. func (a *Assertions) NotErrorAs(err error, target interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1243,7 +1244,8 @@ func (a *Assertions) NotErrorAs(err error, target interface{}, msgAndArgs ...int NotErrorAs(a.t, err, target, msgAndArgs...) } -// NotErrorAsf asserts that none of the errors in err's chain matches target. +// NotErrorAsf asserts that none of the errors in err's chain matches target, +// but if so, sets target to that error value. func (a *Assertions) NotErrorAsf(err error, target interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() From 2063e816961eecfd3a9f80e13fa69f7ef66a4c54 Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Fri, 4 Oct 2024 18:02:45 +0300 Subject: [PATCH 054/178] assert: fix typos in comments --- assert/assertions_test.go | 2 +- assert/yaml/yaml_custom.go | 2 +- assert/yaml/yaml_default.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 20d63b108..e158688f2 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -1327,7 +1327,7 @@ func TestNotElementsMatch(t *testing.T) { actual interface{} result bool }{ - // not mathing + // not matching {[]int{1}, []int{}, true}, {[]int{}, []int{2}, true}, {[]int{1}, []int{2}, true}, diff --git a/assert/yaml/yaml_custom.go b/assert/yaml/yaml_custom.go index bc32dc96c..baa0cc7d7 100644 --- a/assert/yaml/yaml_custom.go +++ b/assert/yaml/yaml_custom.go @@ -15,7 +15,7 @@ // import assertYaml "github.com/stretchr/testify/assert/yaml" // // func init() { -// assertYaml.Unmarshall = func (in []byte, out interface{}) error { +// assertYaml.Unmarshal = func (in []byte, out interface{}) error { // // ... // return nil // } diff --git a/assert/yaml/yaml_default.go b/assert/yaml/yaml_default.go index 9a92eed67..b83c6cf64 100644 --- a/assert/yaml/yaml_default.go +++ b/assert/yaml/yaml_default.go @@ -5,7 +5,7 @@ // // This package is just an indirection that allows the builder to override the // indirection with an alternative implementation of this package that uses -// another implemantation of YAML deserialization. This allows to not either not +// another implementation of YAML deserialization. This allows to not either not // use YAML deserialization at all, or to use another implementation than // [gopkg.in/yaml.v3] (for example for license compatibility reasons, see [PR #1120]). // From ba3e7c34d5ee33bd1dd7d6835daafeaa093525ca Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Fri, 4 Oct 2024 18:06:40 +0300 Subject: [PATCH 055/178] mock: fix doc comment for NotBefore --- mock/mock.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mock/mock.go b/mock/mock.go index 41257fbeb..0c309418b 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -256,7 +256,7 @@ func (c *Call) Unset() *Call { // calls have been called as expected. The referenced calls may be from the // same mock instance and/or other mock instances. // -// Mock.On("Do").Return(nil).Notbefore( +// Mock.On("Do").Return(nil).NotBefore( // Mock.On("Init").Return(nil) // ) func (c *Call) NotBefore(calls ...*Call) *Call { From 3b2754b72fe06f9f41e8998132daaece39d01d7a Mon Sep 17 00:00:00 2001 From: Simon Schulte Date: Tue, 15 Oct 2024 13:54:51 +0200 Subject: [PATCH 056/178] remove failure note on require-comments --- require/require.go | 236 ---------------------------------------- require/require.go.tmpl | 1 - 2 files changed, 237 deletions(-) diff --git a/require/require.go b/require/require.go index b94398f3a..6e52b04df 100644 --- a/require/require.go +++ b/require/require.go @@ -10,7 +10,6 @@ import ( ) // Condition uses a Comparison to assert a complex condition. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Condition(t TestingT, comp assert.Comparison, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -22,7 +21,6 @@ func Condition(t TestingT, comp assert.Comparison, msgAndArgs ...interface{}) { } // Conditionf uses a Comparison to assert a complex condition. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Conditionf(t TestingT, comp assert.Comparison, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -39,8 +37,6 @@ func Conditionf(t TestingT, comp assert.Comparison, msg string, args ...interfac // require.Contains(t, "Hello World", "World") // require.Contains(t, ["Hello", "World"], "World") // require.Contains(t, {"Hello": "World"}, "Hello") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -57,8 +53,6 @@ func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...int // require.Containsf(t, "Hello World", "World", "error message %s", "formatted") // require.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted") // require.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -71,7 +65,6 @@ func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args // DirExists checks whether a directory exists in the given path. It also fails // if the path is a file rather a directory or there is an error checking whether it exists. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func DirExists(t TestingT, path string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -84,7 +77,6 @@ func DirExists(t TestingT, path string, msgAndArgs ...interface{}) { // DirExistsf checks whether a directory exists in the given path. It also fails // if the path is a file rather a directory or there is an error checking whether it exists. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func DirExistsf(t TestingT, path string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -100,7 +92,6 @@ func DirExistsf(t TestingT, path string, msg string, args ...interface{}) { // the number of appearances of each of them in both lists should match. // // require.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2]) -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func ElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -116,7 +107,6 @@ func ElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs // the number of appearances of each of them in both lists should match. // // require.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted") -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -131,8 +121,6 @@ func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string // a slice or a channel with len == 0. // // require.Empty(t, obj) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -147,8 +135,6 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) { // a slice or a channel with len == 0. // // require.Emptyf(t, obj, "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -166,7 +152,6 @@ func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) { // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). Function equality // cannot be determined and will always fail. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -182,8 +167,6 @@ func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...i // // actualObj, err := SomeFunction() // require.EqualError(t, err, expectedErrorString) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -199,8 +182,6 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte // // actualObj, err := SomeFunction() // require.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -221,8 +202,6 @@ func EqualErrorf(t TestingT, theError error, errString string, msg string, args // } // require.EqualExportedValues(t, S{1, 2}, S{1, 3}) => true // require.EqualExportedValues(t, S{1, 2}, S{2, 3}) => false -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func EqualExportedValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -243,8 +222,6 @@ func EqualExportedValues(t TestingT, expected interface{}, actual interface{}, m // } // require.EqualExportedValuesf(t, S{1, 2}, S{1, 3}, "error message %s", "formatted") => true // require.EqualExportedValuesf(t, S{1, 2}, S{2, 3}, "error message %s", "formatted") => false -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func EqualExportedValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -259,8 +236,6 @@ func EqualExportedValuesf(t TestingT, expected interface{}, actual interface{}, // type and equal. // // require.EqualValues(t, uint32(123), int32(123)) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -275,8 +250,6 @@ func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArg // type and equal. // // require.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -294,7 +267,6 @@ func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg stri // 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. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -311,8 +283,6 @@ func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, ar // if require.Error(t, err) { // require.Equal(t, expectedError, err) // } -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Error(t TestingT, err error, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -325,7 +295,6 @@ func Error(t TestingT, err error, msgAndArgs ...interface{}) { // ErrorAs asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value. // This is a wrapper for errors.As. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -338,7 +307,6 @@ func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{ // ErrorAsf asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value. // This is a wrapper for errors.As. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -354,8 +322,6 @@ func ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...int // // actualObj, err := SomeFunction() // require.ErrorContains(t, err, expectedErrorSubString) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -371,8 +337,6 @@ func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...in // // actualObj, err := SomeFunction() // require.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func ErrorContainsf(t TestingT, theError error, contains string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -385,7 +349,6 @@ func ErrorContainsf(t TestingT, theError error, contains string, msg string, arg // ErrorIs asserts that at least one of the errors in err's chain matches target. // This is a wrapper for errors.Is. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func ErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -398,7 +361,6 @@ func ErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) { // ErrorIsf asserts that at least one of the errors in err's chain matches target. // This is a wrapper for errors.Is. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func ErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -415,8 +377,6 @@ func ErrorIsf(t TestingT, err error, target error, msg string, args ...interface // if require.Errorf(t, err, "error message %s", "formatted") { // require.Equal(t, expectedErrorf, err) // } -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Errorf(t TestingT, err error, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -431,8 +391,6 @@ func Errorf(t TestingT, err error, msg string, args ...interface{}) { // periodically checking target function each tick. // // require.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -461,8 +419,6 @@ func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick t // // add assertions as needed; any assertion failure will fail the current tick // require.True(c, externalValue, "expected 'externalValue' to be true") // }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func EventuallyWithT(t TestingT, condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -491,8 +447,6 @@ func EventuallyWithT(t TestingT, condition func(collect *assert.CollectT), waitF // // add assertions as needed; any assertion failure will fail the current tick // require.True(c, externalValue, "expected 'externalValue' to be true") // }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func EventuallyWithTf(t TestingT, condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -507,8 +461,6 @@ func EventuallyWithTf(t TestingT, condition func(collect *assert.CollectT), wait // periodically checking target function each tick. // // require.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -522,8 +474,6 @@ func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick // Exactly asserts that two objects are equal in value and type. // // require.Exactly(t, int32(123), int64(123)) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -537,8 +487,6 @@ func Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs .. // Exactlyf asserts that two objects are equal in value and type. // // require.Exactlyf(t, int32(123), int64(123), "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -550,7 +498,6 @@ func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, } // Fail reports a failure through -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -562,7 +509,6 @@ func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) { } // FailNow fails test -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -574,7 +520,6 @@ func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) { } // FailNowf fails test -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -586,7 +531,6 @@ func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{} } // Failf reports a failure through -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -600,8 +544,6 @@ func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) { // False asserts that the specified value is false. // // require.False(t, myBool) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func False(t TestingT, value bool, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -615,8 +557,6 @@ func False(t TestingT, value bool, msgAndArgs ...interface{}) { // Falsef asserts that the specified value is false. // // require.Falsef(t, myBool, "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Falsef(t TestingT, value bool, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -629,7 +569,6 @@ func Falsef(t TestingT, value bool, msg string, args ...interface{}) { // FileExists checks whether a file exists in the given path. It also fails if // the path points to a directory or there is an error when trying to check the file. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func FileExists(t TestingT, path string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -642,7 +581,6 @@ func FileExists(t TestingT, path string, msgAndArgs ...interface{}) { // FileExistsf checks whether a file exists in the given path. It also fails if // the path points to a directory or there is an error when trying to check the file. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func FileExistsf(t TestingT, path string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -658,8 +596,6 @@ func FileExistsf(t TestingT, path string, msg string, args ...interface{}) { // require.Greater(t, 2, 1) // require.Greater(t, float64(2), float64(1)) // require.Greater(t, "b", "a") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -676,8 +612,6 @@ func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface // require.GreaterOrEqual(t, 2, 2) // require.GreaterOrEqual(t, "b", "a") // require.GreaterOrEqual(t, "b", "b") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -694,8 +628,6 @@ func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...in // require.GreaterOrEqualf(t, 2, 2, "error message %s", "formatted") // require.GreaterOrEqualf(t, "b", "a", "error message %s", "formatted") // require.GreaterOrEqualf(t, "b", "b", "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -711,8 +643,6 @@ func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, arg // require.Greaterf(t, 2, 1, "error message %s", "formatted") // require.Greaterf(t, float64(2), float64(1), "error message %s", "formatted") // require.Greaterf(t, "b", "a", "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -729,7 +659,6 @@ func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...in // require.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") // // Returns whether the assertion was successful (true) or not (false). -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -746,7 +675,6 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url s // require.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -763,7 +691,6 @@ func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url // require.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") // // Returns whether the assertion was successful (true) or not (false). -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -780,7 +707,6 @@ func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, ur // require.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -796,7 +722,6 @@ func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, u // require.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -812,7 +737,6 @@ func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, // require.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -828,7 +752,6 @@ func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, // require.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -844,7 +767,6 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url strin // require.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -860,7 +782,6 @@ func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url stri // require.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501) // // Returns whether the assertion was successful (true) or not (false). -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -876,7 +797,6 @@ func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method string, url str // require.HTTPStatusCodef(t, myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -892,7 +812,6 @@ func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url st // require.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) // // Returns whether the assertion was successful (true) or not (false). -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -908,7 +827,6 @@ func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string // require.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -922,8 +840,6 @@ func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url strin // Implements asserts that an object is implemented by the specified interface. // // require.Implements(t, (*MyInterface)(nil), new(MyObject)) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -937,8 +853,6 @@ func Implements(t TestingT, interfaceObject interface{}, object interface{}, msg // Implementsf asserts that an object is implemented by the specified interface. // // require.Implementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -952,8 +866,6 @@ func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, ms // InDelta asserts that the two numerals are within delta of each other. // // require.InDelta(t, math.Pi, 22/7.0, 0.01) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func InDelta(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -965,7 +877,6 @@ func InDelta(t TestingT, expected interface{}, actual interface{}, delta float64 } // InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func InDeltaMapValues(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -977,7 +888,6 @@ func InDeltaMapValues(t TestingT, expected interface{}, actual interface{}, delt } // InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -989,7 +899,6 @@ func InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, del } // InDeltaSlice is the same as InDelta, except it compares two slices. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func InDeltaSlice(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1001,7 +910,6 @@ func InDeltaSlice(t TestingT, expected interface{}, actual interface{}, delta fl } // InDeltaSlicef is the same as InDelta, except it compares two slices. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1015,8 +923,6 @@ func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta f // InDeltaf asserts that the two numerals are within delta of each other. // // require.InDeltaf(t, math.Pi, 22/7.0, 0.01, "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1028,7 +934,6 @@ func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float6 } // InEpsilon asserts that expected and actual have a relative error less than epsilon -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func InEpsilon(t TestingT, expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1040,7 +945,6 @@ func InEpsilon(t TestingT, expected interface{}, actual interface{}, epsilon flo } // InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func InEpsilonSlice(t TestingT, expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1052,7 +956,6 @@ func InEpsilonSlice(t TestingT, expected interface{}, actual interface{}, epsilo } // InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1064,7 +967,6 @@ func InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsil } // InEpsilonf asserts that expected and actual have a relative error less than epsilon -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1080,8 +982,6 @@ func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon fl // require.IsDecreasing(t, []int{2, 1, 0}) // require.IsDecreasing(t, []float{2, 1}) // require.IsDecreasing(t, []string{"b", "a"}) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1097,8 +997,6 @@ func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { // require.IsDecreasingf(t, []int{2, 1, 0}, "error message %s", "formatted") // require.IsDecreasingf(t, []float{2, 1}, "error message %s", "formatted") // require.IsDecreasingf(t, []string{"b", "a"}, "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1114,8 +1012,6 @@ func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface // require.IsIncreasing(t, []int{1, 2, 3}) // require.IsIncreasing(t, []float{1, 2}) // require.IsIncreasing(t, []string{"a", "b"}) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1131,8 +1027,6 @@ func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { // require.IsIncreasingf(t, []int{1, 2, 3}, "error message %s", "formatted") // require.IsIncreasingf(t, []float{1, 2}, "error message %s", "formatted") // require.IsIncreasingf(t, []string{"a", "b"}, "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1148,8 +1042,6 @@ func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface // require.IsNonDecreasing(t, []int{1, 1, 2}) // require.IsNonDecreasing(t, []float{1, 2}) // require.IsNonDecreasing(t, []string{"a", "b"}) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1165,8 +1057,6 @@ func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) // require.IsNonDecreasingf(t, []int{1, 1, 2}, "error message %s", "formatted") // require.IsNonDecreasingf(t, []float{1, 2}, "error message %s", "formatted") // require.IsNonDecreasingf(t, []string{"a", "b"}, "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1182,8 +1072,6 @@ func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interf // require.IsNonIncreasing(t, []int{2, 1, 1}) // require.IsNonIncreasing(t, []float{2, 1}) // require.IsNonIncreasing(t, []string{"b", "a"}) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1199,8 +1087,6 @@ func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) // require.IsNonIncreasingf(t, []int{2, 1, 1}, "error message %s", "formatted") // require.IsNonIncreasingf(t, []float{2, 1}, "error message %s", "formatted") // require.IsNonIncreasingf(t, []string{"b", "a"}, "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1212,7 +1098,6 @@ func IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interf } // IsType asserts that the specified objects are of the same type. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1224,7 +1109,6 @@ func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs } // IsTypef asserts that the specified objects are of the same type. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1238,8 +1122,6 @@ func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg strin // JSONEq asserts that two JSON strings are equivalent. // // require.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1253,8 +1135,6 @@ func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{ // JSONEqf asserts that two JSON strings are equivalent. // // require.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1269,8 +1149,6 @@ func JSONEqf(t TestingT, expected string, actual string, msg string, args ...int // Len also fails if the object has a type that len() not accept. // // require.Len(t, mySlice, 3) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1285,8 +1163,6 @@ func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) // Lenf also fails if the object has a type that len() not accept. // // require.Lenf(t, mySlice, 3, "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1302,8 +1178,6 @@ func Lenf(t TestingT, object interface{}, length int, msg string, args ...interf // require.Less(t, 1, 2) // require.Less(t, float64(1), float64(2)) // require.Less(t, "a", "b") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1320,8 +1194,6 @@ func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) // require.LessOrEqual(t, 2, 2) // require.LessOrEqual(t, "a", "b") // require.LessOrEqual(t, "b", "b") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1338,8 +1210,6 @@ func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...inter // require.LessOrEqualf(t, 2, 2, "error message %s", "formatted") // require.LessOrEqualf(t, "a", "b", "error message %s", "formatted") // require.LessOrEqualf(t, "b", "b", "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1355,8 +1225,6 @@ func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args . // require.Lessf(t, 1, 2, "error message %s", "formatted") // require.Lessf(t, float64(1), float64(2), "error message %s", "formatted") // require.Lessf(t, "a", "b", "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1371,8 +1239,6 @@ func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...inter // // require.Negative(t, -1) // require.Negative(t, -1.23) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1387,8 +1253,6 @@ func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) { // // require.Negativef(t, -1, "error message %s", "formatted") // require.Negativef(t, -1.23, "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1403,8 +1267,6 @@ func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) { // periodically checking the target function each tick. // // require.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1419,8 +1281,6 @@ func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.D // periodically checking the target function each tick. // // require.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1434,8 +1294,6 @@ func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time. // Nil asserts that the specified object is nil. // // require.Nil(t, err) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1449,8 +1307,6 @@ func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) { // Nilf asserts that the specified object is nil. // // require.Nilf(t, err, "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1463,7 +1319,6 @@ func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) { // NoDirExists checks whether a directory does not exist in the given path. // It fails if the path points to an existing _directory_ only. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NoDirExists(t TestingT, path string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1476,7 +1331,6 @@ func NoDirExists(t TestingT, path string, msgAndArgs ...interface{}) { // NoDirExistsf checks whether a directory does not exist in the given path. // It fails if the path points to an existing _directory_ only. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1493,8 +1347,6 @@ func NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) { // if require.NoError(t, err) { // require.Equal(t, expectedObj, actualObj) // } -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NoError(t TestingT, err error, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1511,8 +1363,6 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) { // if require.NoErrorf(t, err, "error message %s", "formatted") { // require.Equal(t, expectedObj, actualObj) // } -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NoErrorf(t TestingT, err error, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1525,7 +1375,6 @@ func NoErrorf(t TestingT, err error, msg string, args ...interface{}) { // NoFileExists checks whether a file does not exist in a given path. It fails // if the path points to an existing _file_ only. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NoFileExists(t TestingT, path string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1538,7 +1387,6 @@ func NoFileExists(t TestingT, path string, msgAndArgs ...interface{}) { // NoFileExistsf checks whether a file does not exist in a given path. It fails // if the path points to an existing _file_ only. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NoFileExistsf(t TestingT, path string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1555,8 +1403,6 @@ func NoFileExistsf(t TestingT, path string, msg string, args ...interface{}) { // require.NotContains(t, "Hello World", "Earth") // require.NotContains(t, ["Hello", "World"], "Earth") // require.NotContains(t, {"Hello": "World"}, "Earth") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1573,8 +1419,6 @@ func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ... // require.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted") // require.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted") // require.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1595,7 +1439,6 @@ func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, a // require.NotElementsMatch(t, [1, 1, 2, 3], [1, 2, 3]) -> true // // require.NotElementsMatch(t, [1, 2, 3], [1, 2, 4]) -> true -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1616,7 +1459,6 @@ func NotElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndAr // require.NotElementsMatchf(t, [1, 1, 2, 3], [1, 2, 3], "error message %s", "formatted") -> true // // require.NotElementsMatchf(t, [1, 2, 3], [1, 2, 4], "error message %s", "formatted") -> true -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1633,8 +1475,6 @@ func NotElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg str // if require.NotEmpty(t, obj) { // require.Equal(t, "two", obj[1]) // } -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1651,8 +1491,6 @@ func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) { // if require.NotEmptyf(t, obj, "error message %s", "formatted") { // require.Equal(t, "two", obj[1]) // } -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1669,7 +1507,6 @@ func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotEqual(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1683,8 +1520,6 @@ func NotEqual(t TestingT, expected interface{}, actual interface{}, msgAndArgs . // NotEqualValues asserts that two objects are not equal even when converted to the same type // // require.NotEqualValues(t, obj1, obj2) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotEqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1698,8 +1533,6 @@ func NotEqualValues(t TestingT, expected interface{}, actual interface{}, msgAnd // NotEqualValuesf asserts that two objects are not equal even when converted to the same type // // require.NotEqualValuesf(t, obj1, obj2, "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1716,7 +1549,6 @@ func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg s // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1729,7 +1561,6 @@ func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, // NotErrorIs asserts that none of the errors in err's chain matches target. // This is a wrapper for errors.Is. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1742,7 +1573,6 @@ func NotErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) // NotErrorIsf asserts that none of the errors in err's chain matches target. // This is a wrapper for errors.Is. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1756,8 +1586,6 @@ func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interf // NotImplements asserts that an object does not implement the specified interface. // // require.NotImplements(t, (*MyInterface)(nil), new(MyObject)) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotImplements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1771,8 +1599,6 @@ func NotImplements(t TestingT, interfaceObject interface{}, object interface{}, // NotImplementsf asserts that an object does not implement the specified interface. // // require.NotImplementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotImplementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1786,8 +1612,6 @@ func NotImplementsf(t TestingT, interfaceObject interface{}, object interface{}, // NotNil asserts that the specified object is not nil. // // require.NotNil(t, err) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1801,8 +1625,6 @@ func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) { // NotNilf asserts that the specified object is not nil. // // require.NotNilf(t, err, "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1816,8 +1638,6 @@ func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) { // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. // // require.NotPanics(t, func(){ RemainCalm() }) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1831,8 +1651,6 @@ func NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { // NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic. // // require.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotPanicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1847,8 +1665,6 @@ func NotPanicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interfac // // require.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") // require.NotRegexp(t, "^start", "it's not starting") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1863,8 +1679,6 @@ func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interf // // require.NotRegexpf(t, regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") // require.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1881,7 +1695,6 @@ func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args .. // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotSame(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1898,7 +1711,6 @@ func NotSame(t TestingT, expected interface{}, actual interface{}, msgAndArgs .. // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotSamef(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1915,8 +1727,6 @@ func NotSamef(t TestingT, expected interface{}, actual interface{}, msg string, // // require.NotSubset(t, [1, 3, 4], [1, 2]) // require.NotSubset(t, {"x": 1, "y": 2}, {"z": 3}) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1933,8 +1743,6 @@ func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...i // // 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") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1946,7 +1754,6 @@ func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, ar } // NotZero asserts that i is not the zero value for its type. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1958,7 +1765,6 @@ func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) { } // NotZerof asserts that i is not the zero value for its type. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1972,8 +1778,6 @@ func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) { // Panics asserts that the code inside the specified PanicTestFunc panics. // // require.Panics(t, func(){ GoCrazy() }) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1989,8 +1793,6 @@ func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { // EqualError comparison. // // require.PanicsWithError(t, "crazy error", func(){ GoCrazy() }) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func PanicsWithError(t TestingT, errString string, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2006,8 +1808,6 @@ func PanicsWithError(t TestingT, errString string, f assert.PanicTestFunc, msgAn // EqualError comparison. // // require.PanicsWithErrorf(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func PanicsWithErrorf(t TestingT, errString string, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2022,8 +1822,6 @@ func PanicsWithErrorf(t TestingT, errString string, f assert.PanicTestFunc, msg // the recovered panic value equals the expected panic value. // // require.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func PanicsWithValue(t TestingT, expected interface{}, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2038,8 +1836,6 @@ func PanicsWithValue(t TestingT, expected interface{}, f assert.PanicTestFunc, m // the recovered panic value equals the expected panic value. // // require.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func PanicsWithValuef(t TestingT, expected interface{}, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2053,8 +1849,6 @@ func PanicsWithValuef(t TestingT, expected interface{}, f assert.PanicTestFunc, // Panicsf asserts that the code inside the specified PanicTestFunc panics. // // require.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Panicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2069,8 +1863,6 @@ func Panicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{} // // require.Positive(t, 1) // require.Positive(t, 1.23) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2085,8 +1877,6 @@ func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) { // // require.Positivef(t, 1, "error message %s", "formatted") // require.Positivef(t, 1.23, "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2101,8 +1891,6 @@ func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) { // // require.Regexp(t, regexp.MustCompile("start"), "it's starting") // require.Regexp(t, "start...$", "it's not starting") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2117,8 +1905,6 @@ func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface // // require.Regexpf(t, regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") // require.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2135,7 +1921,6 @@ func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...in // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Same(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2152,7 +1937,6 @@ func Same(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...in // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Samef(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2168,8 +1952,6 @@ func Samef(t TestingT, expected interface{}, actual interface{}, msg string, arg // // require.Subset(t, [1, 2, 3], [1, 2]) // require.Subset(t, {"x": 1, "y": 2}, {"x": 1}) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2185,8 +1967,6 @@ func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...inte // // 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") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2200,8 +1980,6 @@ func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args // True asserts that the specified value is true. // // require.True(t, myBool) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func True(t TestingT, value bool, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2215,8 +1993,6 @@ func True(t TestingT, value bool, msgAndArgs ...interface{}) { // Truef asserts that the specified value is true. // // require.Truef(t, myBool, "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Truef(t TestingT, value bool, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2230,8 +2006,6 @@ func Truef(t TestingT, value bool, msg string, args ...interface{}) { // WithinDuration asserts that the two times are within duration delta of each other. // // require.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2245,8 +2019,6 @@ func WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time // WithinDurationf asserts that the two times are within duration delta of each other. // // require.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2260,8 +2032,6 @@ func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta tim // WithinRange asserts that a time is within a time range (inclusive). // // require.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func WithinRange(t TestingT, actual time.Time, start time.Time, end time.Time, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2275,8 +2045,6 @@ func WithinRange(t TestingT, actual time.Time, start time.Time, end time.Time, m // WithinRangef asserts that a time is within a time range (inclusive). // // require.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") -// -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2288,7 +2056,6 @@ func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, } // YAMLEq asserts that two YAML strings are equivalent. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2300,7 +2067,6 @@ func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{ } // YAMLEqf asserts that two YAML strings are equivalent. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2312,7 +2078,6 @@ func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...int } // Zero asserts that i is the zero value for its type. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2324,7 +2089,6 @@ func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) { } // Zerof asserts that i is the zero value for its type. -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func Zerof(t TestingT, i interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/require/require.go.tmpl b/require/require.go.tmpl index 11cca94cd..8b3283685 100644 --- a/require/require.go.tmpl +++ b/require/require.go.tmpl @@ -1,5 +1,4 @@ {{ replace .Comment "assert." "require."}} -// Failure of this check is fatal ([testing.T.FailNow] is called on failure). func {{.DocInfo.Name}}(t TestingT, {{.Params}}) { if h, ok := t.(tHelper); ok { h.Helper() } if assert.{{.DocInfo.Name}}(t, {{.ForwardedParams}}) { return } From 6555fd4da6911f1a3a0e751fbe4fd61c22e809d5 Mon Sep 17 00:00:00 2001 From: Yaroslav Brustinov Date: Wed, 16 Oct 2024 17:25:23 +0300 Subject: [PATCH 057/178] Fix issue #1662 (comparing infs should fail) --- assert/assertions.go | 3 +++ assert/assertions_test.go | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/assert/assertions.go b/assert/assertions.go index 44b854da6..d4b4befcb 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -1527,6 +1527,9 @@ func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAnd if err != nil { return Fail(t, err.Error(), msgAndArgs...) } + if math.IsNaN(actualEpsilon) { + return Fail(t, "relative error is NaN", msgAndArgs...) + } if actualEpsilon > epsilon { return Fail(t, fmt.Sprintf("Relative error is too high: %#v (expected)\n"+ " < %#v (actual)", epsilon, actualEpsilon), msgAndArgs...) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index e158688f2..848a5d8a5 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -1986,6 +1986,14 @@ func TestInEpsilon(t *testing.T) { {math.NaN(), 0, 1}, {0, math.NaN(), 1}, {0, 0, math.NaN()}, + {math.Inf(1), 1, 1}, + {math.Inf(-1), 1, 1}, + {1, math.Inf(1), 1}, + {1, math.Inf(-1), 1}, + {math.Inf(1), math.Inf(1), 1}, + {math.Inf(1), math.Inf(-1), 1}, + {math.Inf(-1), math.Inf(1), 1}, + {math.Inf(-1), math.Inf(-1), 1}, } for _, tc := range cases { From 9c174eb41c6bd1d44d9aec62f68b8f1c514f3f5f Mon Sep 17 00:00:00 2001 From: Arjun Dhawan Date: Tue, 23 Jul 2024 16:18:22 +0200 Subject: [PATCH 058/178] fix: compare functional option names for indirect calls Closes Functional Options testing broken for indirect calls #1380 --- mock/mock.go | 9 ++++++++- mock/mock_test.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/mock/mock.go b/mock/mock.go index 49328337b..009767554 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -1260,5 +1260,12 @@ func assertOpts(expected, actual interface{}) (expectedFmt, actualFmt string) { func funcName(opt interface{}) string { n := runtime.FuncForPC(reflect.ValueOf(opt).Pointer()).Name() - return strings.TrimSuffix(path.Base(n), path.Ext(n)) + trimmed := strings.TrimSuffix(path.Base(n), path.Ext(n)) + splitted := strings.Split(trimmed, ".") + + if len(splitted) == 0 { + return trimmed + } + + return splitted[len(splitted)-1] } diff --git a/mock/mock_test.go b/mock/mock_test.go index d28686700..12fb45e74 100644 --- a/mock/mock_test.go +++ b/mock/mock_test.go @@ -55,6 +55,10 @@ func (i *TestExampleImplementation) TheExampleMethodFunctionalOptions(x string, return args.Error(0) } +func TheExampleMethodFunctionalOptionsIndirect(i *TestExampleImplementation) { + i.TheExampleMethodFunctionalOptions("test", OpNum(1), OpStr("foo")) +} + //go:noinline func (i *TestExampleImplementation) TheExampleMethod2(yesorno bool) { i.Called(yesorno) @@ -1505,6 +1509,23 @@ func Test_Mock_AssertExpectationsFunctionalOptionsType(t *testing.T) { } +func Test_Mock_AssertExpectationsFunctionalOptionsTypeIndirectly(t *testing.T) { + + var mockedService = new(TestExampleImplementation) + + mockedService.On("TheExampleMethodFunctionalOptions", "test", FunctionalOptions(OpNum(1), OpStr("foo"))).Return(nil).Once() + + tt := new(testing.T) + assert.False(t, mockedService.AssertExpectations(tt)) + + // make the call now + TheExampleMethodFunctionalOptionsIndirect(mockedService) + + // now assert expectations + assert.True(t, mockedService.AssertExpectations(tt)) + +} + func Test_Mock_AssertExpectationsFunctionalOptionsType_Empty(t *testing.T) { var mockedService = new(TestExampleImplementation) @@ -1522,6 +1543,20 @@ func Test_Mock_AssertExpectationsFunctionalOptionsType_Empty(t *testing.T) { } +func Test_Mock_AssertExpectationsFunctionalOptionsType_Diff(t *testing.T) { + + var mockedService = new(TestExampleImplementation) + + mockedService.On("TheExampleMethodFunctionalOptions", "test", FunctionalOptions(OpNum(1))).Return(nil).Once() + + tt := new(testing.T) + assert.False(t, mockedService.AssertExpectations(tt)) + + assert.Panics(t, func() { + mockedService.TheExampleMethodFunctionalOptions("test", OpStr("1")) + }) +} + func Test_Mock_AssertExpectations_With_Repeatability(t *testing.T) { var mockedService = new(TestExampleImplementation) From 22d3bd5defb6f5dfe50062c22651669393ecdbc5 Mon Sep 17 00:00:00 2001 From: Arjun Dhawan Date: Tue, 23 Jul 2024 16:53:06 +0200 Subject: [PATCH 059/178] in order to remain compatible with go1..19, don't compare function names (but do include them in the diff output) --- mock/mock.go | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/mock/mock.go b/mock/mock.go index 009767554..19ec01d87 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -1204,17 +1204,10 @@ type tHelper interface { func assertOpts(expected, actual interface{}) (expectedFmt, actualFmt string) { expectedOpts := reflect.ValueOf(expected) actualOpts := reflect.ValueOf(actual) - var expectedNames []string - for i := 0; i < expectedOpts.Len(); i++ { - expectedNames = append(expectedNames, funcName(expectedOpts.Index(i).Interface())) - } - var actualNames []string - for i := 0; i < actualOpts.Len(); i++ { - actualNames = append(actualNames, funcName(actualOpts.Index(i).Interface())) - } - if !assert.ObjectsAreEqual(expectedNames, actualNames) { - expectedFmt = fmt.Sprintf("%v", expectedNames) - actualFmt = fmt.Sprintf("%v", actualNames) + + if expectedOpts.Len() != actualOpts.Len() { + expectedFmt = fmt.Sprintf("%v", expectedOpts) + actualFmt = fmt.Sprintf("%v", actualOpts) return } @@ -1222,14 +1215,6 @@ func assertOpts(expected, actual interface{}) (expectedFmt, actualFmt string) { expectedOpt := expectedOpts.Index(i).Interface() actualOpt := actualOpts.Index(i).Interface() - expectedFunc := expectedNames[i] - actualFunc := actualNames[i] - if expectedFunc != actualFunc { - expectedFmt = expectedFunc - actualFmt = actualFunc - return - } - ot := reflect.TypeOf(expectedOpt) var expectedValues []reflect.Value var actualValues []reflect.Value @@ -1248,8 +1233,8 @@ func assertOpts(expected, actual interface{}) (expectedFmt, actualFmt string) { for i := 0; i < ot.NumIn(); i++ { if !assert.ObjectsAreEqual(expectedValues[i].Interface(), actualValues[i].Interface()) { - expectedFmt = fmt.Sprintf("%s %+v", expectedNames[i], expectedValues[i].Interface()) - actualFmt = fmt.Sprintf("%s %+v", expectedNames[i], actualValues[i].Interface()) + expectedFmt = fmt.Sprintf("%s %+v", funcName(expectedOpts.Index(i).Interface()), expectedValues[i].Interface()) + actualFmt = fmt.Sprintf("%s %+v", funcName(actualOpts.Index(i).Interface()), actualValues[i].Interface()) return } } From 822223ec3418f3f55230d59b2701b9d6dafff758 Mon Sep 17 00:00:00 2001 From: Arjun Dhawan Date: Tue, 22 Oct 2024 16:04:49 +0200 Subject: [PATCH 060/178] fix name regression --- mock/mock.go | 20 +++++++++++++++++--- mock/mock_test.go | 29 +++++++++++++++++++++++++---- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/mock/mock.go b/mock/mock.go index 19ec01d87..487dca2b3 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -1211,6 +1211,20 @@ func assertOpts(expected, actual interface{}) (expectedFmt, actualFmt string) { return } + var expectedNames []string + for i := 0; i < expectedOpts.Len(); i++ { + expectedNames = append(expectedNames, funcName(expectedOpts.Index(i).Interface())) + } + var actualNames []string + for i := 0; i < actualOpts.Len(); i++ { + actualNames = append(actualNames, funcName(actualOpts.Index(i).Interface())) + } + if !assert.ObjectsAreEqual(expectedNames, actualNames) { + expectedFmt = fmt.Sprintf("%v", expectedNames) + actualFmt = fmt.Sprintf("%v", actualNames) + return + } + for i := 0; i < expectedOpts.Len(); i++ { expectedOpt := expectedOpts.Index(i).Interface() actualOpt := actualOpts.Index(i).Interface() @@ -1232,9 +1246,9 @@ func assertOpts(expected, actual interface{}) (expectedFmt, actualFmt string) { reflect.ValueOf(actualOpt).Call(actualValues) for i := 0; i < ot.NumIn(); i++ { - if !assert.ObjectsAreEqual(expectedValues[i].Interface(), actualValues[i].Interface()) { - expectedFmt = fmt.Sprintf("%s %+v", funcName(expectedOpts.Index(i).Interface()), expectedValues[i].Interface()) - actualFmt = fmt.Sprintf("%s %+v", funcName(actualOpts.Index(i).Interface()), actualValues[i].Interface()) + if expectedArg, actualArg := expectedValues[i].Interface(), actualValues[i].Interface(); !assert.ObjectsAreEqual(expectedArg, actualArg) { + expectedFmt = fmt.Sprintf("%s(%T) -> %#v", expectedNames[i], expectedArg, expectedArg) + actualFmt = fmt.Sprintf("%s(%T) -> %#v", expectedNames[i], actualArg, actualArg) return } } diff --git a/mock/mock_test.go b/mock/mock_test.go index 12fb45e74..e5bdaef9d 100644 --- a/mock/mock_test.go +++ b/mock/mock_test.go @@ -50,6 +50,13 @@ func OpStr(s string) OptionFn { o.str = s } } + +func OpBytes(b []byte) OptionFn { + return func(m *options) { + m.str = string(b) + } +} + func (i *TestExampleImplementation) TheExampleMethodFunctionalOptions(x string, opts ...OptionFn) error { args := i.Called(x, opts) return args.Error(0) @@ -1509,7 +1516,7 @@ func Test_Mock_AssertExpectationsFunctionalOptionsType(t *testing.T) { } -func Test_Mock_AssertExpectationsFunctionalOptionsTypeIndirectly(t *testing.T) { +func Test_Mock_AssertExpectationsFunctionalOptionsType_Indirectly(t *testing.T) { var mockedService = new(TestExampleImplementation) @@ -1543,17 +1550,31 @@ func Test_Mock_AssertExpectationsFunctionalOptionsType_Empty(t *testing.T) { } -func Test_Mock_AssertExpectationsFunctionalOptionsType_Diff(t *testing.T) { +func Test_Mock_AssertExpectationsFunctionalOptionsType_Diff_Name(t *testing.T) { + + var mockedService = new(TestExampleImplementation) + + mockedService.On("TheExampleMethodFunctionalOptions", "test", FunctionalOptions(OpStr("this"))).Return(nil).Once() + + tt := new(testing.T) + assert.False(t, mockedService.AssertExpectations(tt)) + + assert.Panics(t, func() { + mockedService.TheExampleMethodFunctionalOptions("test", OpBytes([]byte("this"))) + }) +} + +func Test_Mock_AssertExpectationsFunctionalOptionsType_Diff_Arg(t *testing.T) { var mockedService = new(TestExampleImplementation) - mockedService.On("TheExampleMethodFunctionalOptions", "test", FunctionalOptions(OpNum(1))).Return(nil).Once() + mockedService.On("TheExampleMethodFunctionalOptions", "test", FunctionalOptions(OpStr("this"))).Return(nil).Once() tt := new(testing.T) assert.False(t, mockedService.AssertExpectations(tt)) assert.Panics(t, func() { - mockedService.TheExampleMethodFunctionalOptions("test", OpStr("1")) + mockedService.TheExampleMethodFunctionalOptions("test", OpStr("that")) }) } From 55bac843547859145b0a174024ce495256cff5f8 Mon Sep 17 00:00:00 2001 From: Arjun Dhawan Date: Thu, 24 Oct 2024 11:28:15 +0200 Subject: [PATCH 061/178] reword tests --- mock/mock_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mock/mock_test.go b/mock/mock_test.go index e5bdaef9d..71249239b 100644 --- a/mock/mock_test.go +++ b/mock/mock_test.go @@ -1516,34 +1516,34 @@ func Test_Mock_AssertExpectationsFunctionalOptionsType(t *testing.T) { } -func Test_Mock_AssertExpectationsFunctionalOptionsType_Indirectly(t *testing.T) { +func Test_Mock_AssertExpectationsFunctionalOptionsType_Empty(t *testing.T) { var mockedService = new(TestExampleImplementation) - mockedService.On("TheExampleMethodFunctionalOptions", "test", FunctionalOptions(OpNum(1), OpStr("foo"))).Return(nil).Once() + mockedService.On("TheExampleMethodFunctionalOptions", "test", FunctionalOptions()).Return(nil).Once() tt := new(testing.T) assert.False(t, mockedService.AssertExpectations(tt)) // make the call now - TheExampleMethodFunctionalOptionsIndirect(mockedService) + mockedService.TheExampleMethodFunctionalOptions("test") // now assert expectations assert.True(t, mockedService.AssertExpectations(tt)) } -func Test_Mock_AssertExpectationsFunctionalOptionsType_Empty(t *testing.T) { +func Test_Mock_AssertExpectationsFunctionalOptionsType_Indirectly(t *testing.T) { var mockedService = new(TestExampleImplementation) - mockedService.On("TheExampleMethodFunctionalOptions", "test", FunctionalOptions()).Return(nil).Once() + mockedService.On("TheExampleMethodFunctionalOptions", "test", FunctionalOptions(OpNum(1), OpStr("foo"))).Return(nil).Once() tt := new(testing.T) assert.False(t, mockedService.AssertExpectations(tt)) // make the call now - mockedService.TheExampleMethodFunctionalOptions("test") + TheExampleMethodFunctionalOptionsIndirect(mockedService) // now assert expectations assert.True(t, mockedService.AssertExpectations(tt)) From fb67df63928ed75bbececffbd748155d2620f290 Mon Sep 17 00:00:00 2001 From: Arjun Dhawan Date: Thu, 24 Oct 2024 11:40:45 +0200 Subject: [PATCH 062/178] no regression --- mock/mock.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/mock/mock.go b/mock/mock.go index 487dca2b3..7ba05b754 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -1205,12 +1205,6 @@ func assertOpts(expected, actual interface{}) (expectedFmt, actualFmt string) { expectedOpts := reflect.ValueOf(expected) actualOpts := reflect.ValueOf(actual) - if expectedOpts.Len() != actualOpts.Len() { - expectedFmt = fmt.Sprintf("%v", expectedOpts) - actualFmt = fmt.Sprintf("%v", actualOpts) - return - } - var expectedNames []string for i := 0; i < expectedOpts.Len(); i++ { expectedNames = append(expectedNames, funcName(expectedOpts.Index(i).Interface())) @@ -1229,6 +1223,14 @@ func assertOpts(expected, actual interface{}) (expectedFmt, actualFmt string) { expectedOpt := expectedOpts.Index(i).Interface() actualOpt := actualOpts.Index(i).Interface() + expectedFunc := expectedNames[i] + actualFunc := actualNames[i] + if expectedFunc != actualFunc { + expectedFmt = expectedFunc + actualFmt = actualFunc + return + } + ot := reflect.TypeOf(expectedOpt) var expectedValues []reflect.Value var actualValues []reflect.Value From be992afabf0732046a842caf78868376945ad245 Mon Sep 17 00:00:00 2001 From: Arjun Dhawan Date: Thu, 24 Oct 2024 13:28:30 +0200 Subject: [PATCH 063/178] trial --- mock/mock.go | 54 +++++++++++++++++++++++++++-------------------- mock/mock_test.go | 2 +- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/mock/mock.go b/mock/mock.go index 7ba05b754..fe3510860 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -1205,31 +1205,28 @@ func assertOpts(expected, actual interface{}) (expectedFmt, actualFmt string) { expectedOpts := reflect.ValueOf(expected) actualOpts := reflect.ValueOf(actual) - var expectedNames []string - for i := 0; i < expectedOpts.Len(); i++ { - expectedNames = append(expectedNames, funcName(expectedOpts.Index(i).Interface())) - } - var actualNames []string - for i := 0; i < actualOpts.Len(); i++ { - actualNames = append(actualNames, funcName(actualOpts.Index(i).Interface())) - } - if !assert.ObjectsAreEqual(expectedNames, actualNames) { - expectedFmt = fmt.Sprintf("%v", expectedNames) - actualFmt = fmt.Sprintf("%v", actualNames) + if expectedOpts.Len() != actualOpts.Len() { + expectedFmt = fmt.Sprintf("%v", expected) + actualFmt = fmt.Sprintf("%v", actual) return } + var funcNames []string + for i := 0; i < expectedOpts.Len(); i++ { - expectedOpt := expectedOpts.Index(i).Interface() - actualOpt := actualOpts.Index(i).Interface() + expectedFunc := getRuntimeFunc(expectedOpts.Index(i).Interface()) + funcNames = append(funcNames, funcName(getRuntimeFunc(expectedFunc))) - expectedFunc := expectedNames[i] - actualFunc := actualNames[i] - if expectedFunc != actualFunc { - expectedFmt = expectedFunc - actualFmt = actualFunc + if actualFunc := getRuntimeFunc(actualOpts.Index(i).Interface()); !isFuncSame(expectedFunc, actualFunc) { + expectedFmt = funcName(expectedFunc) + actualFmt = funcName(actualFunc) return } + } + + for i := 0; i < expectedOpts.Len(); i++ { + expectedOpt := expectedOpts.Index(i).Interface() + actualOpt := actualOpts.Index(i).Interface() ot := reflect.TypeOf(expectedOpt) var expectedValues []reflect.Value @@ -1249,8 +1246,8 @@ func assertOpts(expected, actual interface{}) (expectedFmt, actualFmt string) { for i := 0; i < ot.NumIn(); i++ { if expectedArg, actualArg := expectedValues[i].Interface(), actualValues[i].Interface(); !assert.ObjectsAreEqual(expectedArg, actualArg) { - expectedFmt = fmt.Sprintf("%s(%T) -> %#v", expectedNames[i], expectedArg, expectedArg) - actualFmt = fmt.Sprintf("%s(%T) -> %#v", expectedNames[i], actualArg, actualArg) + expectedFmt = fmt.Sprintf("%s(%T) -> %#v", funcNames[i], expectedArg, expectedArg) + actualFmt = fmt.Sprintf("%s(%T) -> %#v", funcNames[i], actualArg, actualArg) return } } @@ -1259,9 +1256,13 @@ func assertOpts(expected, actual interface{}) (expectedFmt, actualFmt string) { return "", "" } -func funcName(opt interface{}) string { - n := runtime.FuncForPC(reflect.ValueOf(opt).Pointer()).Name() - trimmed := strings.TrimSuffix(path.Base(n), path.Ext(n)) +func getRuntimeFunc(opt interface{}) *runtime.Func { + return runtime.FuncForPC(reflect.ValueOf(opt).Pointer()) +} + +func funcName(f *runtime.Func) string { + name := f.Name() + trimmed := strings.TrimSuffix(path.Base(name), path.Ext(name)) splitted := strings.Split(trimmed, ".") if len(splitted) == 0 { @@ -1270,3 +1271,10 @@ func funcName(opt interface{}) string { return splitted[len(splitted)-1] } + +func isFuncSame(f1, f2 *runtime.Func) bool { + f1File, f1Loc := f1.FileLine(f1.Entry()) + f2File, f2Loc := f2.FileLine(f2.Entry()) + + return f1File == f2File && f1Loc == f2Loc +} diff --git a/mock/mock_test.go b/mock/mock_test.go index 71249239b..2de277371 100644 --- a/mock/mock_test.go +++ b/mock/mock_test.go @@ -1550,7 +1550,7 @@ func Test_Mock_AssertExpectationsFunctionalOptionsType_Indirectly(t *testing.T) } -func Test_Mock_AssertExpectationsFunctionalOptionsType_Diff_Name(t *testing.T) { +func Test_Mock_AssertExpectationsFunctionalOptionsType_Diff_Func(t *testing.T) { var mockedService = new(TestExampleImplementation) From 8f049b01221b20d4fba5b8ebfd03b66d576d8cc1 Mon Sep 17 00:00:00 2001 From: "hendry.wiranto" Date: Sun, 10 Dec 2023 14:36:49 +0700 Subject: [PATCH 064/178] link maintainer manifesto on readme instead of v2 notice --- README.md | 3 ++- doc.go | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ccaa7586b..629a319e2 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ Testify - Thou Shalt Write Tests ================================ -ℹ️ We are working on testify v2 and would love to hear what you'd like to see in it, have your say here: https://cutt.ly/testify +Notice about Testify V2: +It won't happen due to various reasons. You can read more about it on the maintainer's manifesto [here](https://github.com/stretchr/testify/issues/1089#issuecomment-1812734472). [![Build Status](https://github.com/stretchr/testify/actions/workflows/main.yml/badge.svg?branch=master)](https://github.com/stretchr/testify/actions/workflows/main.yml) [![Go Report Card](https://goreportcard.com/badge/github.com/stretchr/testify)](https://goreportcard.com/report/github.com/stretchr/testify) [![PkgGoDev](https://pkg.go.dev/badge/github.com/stretchr/testify)](https://pkg.go.dev/github.com/stretchr/testify) diff --git a/doc.go b/doc.go index 96407f3be..babc122f2 100644 --- a/doc.go +++ b/doc.go @@ -1,4 +1,3 @@ -// ** We are working on testify v2 and would love to hear what you'd like to see in it, have your say here: https://cutt.ly/testify ** // Package testify is a set of packages that provide many tools for testifying that your code will behave as you intend. // // testify contains the following packages: From 2780579e15e5bbf58886f170d380caa1ac61f056 Mon Sep 17 00:00:00 2001 From: "hendry.wiranto" Date: Sat, 26 Oct 2024 23:14:23 +0700 Subject: [PATCH 065/178] review: use proper github md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 629a319e2..b2dbd16ea 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ Testify - Thou Shalt Write Tests ================================ -Notice about Testify V2: -It won't happen due to various reasons. You can read more about it on the maintainer's manifesto [here](https://github.com/stretchr/testify/issues/1089#issuecomment-1812734472). +> [!NOTE] +> Testify is being maintained at v1, no breaking changes will be accepted in this repo. +> [See discussion about v2](https://github.com/stretchr/testify/discussions/1560). [![Build Status](https://github.com/stretchr/testify/actions/workflows/main.yml/badge.svg?branch=master)](https://github.com/stretchr/testify/actions/workflows/main.yml) [![Go Report Card](https://goreportcard.com/badge/github.com/stretchr/testify)](https://goreportcard.com/report/github.com/stretchr/testify) [![PkgGoDev](https://pkg.go.dev/badge/github.com/stretchr/testify)](https://pkg.go.dev/github.com/stretchr/testify) From ea7129e00694592e20cb34c58a6b8a251418b9da Mon Sep 17 00:00:00 2001 From: Arjun Dhawan Date: Sun, 27 Oct 2024 08:02:53 +0100 Subject: [PATCH 066/178] better fmt --- mock/mock.go | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/mock/mock.go b/mock/mock.go index fe3510860..50eeaba03 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -1205,21 +1205,31 @@ func assertOpts(expected, actual interface{}) (expectedFmt, actualFmt string) { expectedOpts := reflect.ValueOf(expected) actualOpts := reflect.ValueOf(actual) + var expectedFuncs []*runtime.Func + var expectedNames []string + for i := 0; i < expectedOpts.Len(); i++ { + f := runtimeFunc(expectedOpts.Index(i).Interface()) + expectedFuncs = append(expectedFuncs, f) + expectedNames = append(expectedNames, funcName(f)) + } + var actualFuncs []*runtime.Func + var actualNames []string + for i := 0; i < actualOpts.Len(); i++ { + f := runtimeFunc(actualOpts.Index(i).Interface()) + actualFuncs = append(actualFuncs, f) + actualNames = append(actualNames, funcName(f)) + } + if expectedOpts.Len() != actualOpts.Len() { - expectedFmt = fmt.Sprintf("%v", expected) - actualFmt = fmt.Sprintf("%v", actual) + expectedFmt = fmt.Sprintf("%v", expectedNames) + actualFmt = fmt.Sprintf("%v", actualNames) return } - var funcNames []string - for i := 0; i < expectedOpts.Len(); i++ { - expectedFunc := getRuntimeFunc(expectedOpts.Index(i).Interface()) - funcNames = append(funcNames, funcName(getRuntimeFunc(expectedFunc))) - - if actualFunc := getRuntimeFunc(actualOpts.Index(i).Interface()); !isFuncSame(expectedFunc, actualFunc) { - expectedFmt = funcName(expectedFunc) - actualFmt = funcName(actualFunc) + if !isFuncSame(expectedFuncs[i], actualFuncs[i]) { + expectedFmt = expectedNames[i] + actualFmt = actualNames[i] return } } @@ -1246,8 +1256,8 @@ func assertOpts(expected, actual interface{}) (expectedFmt, actualFmt string) { for i := 0; i < ot.NumIn(); i++ { if expectedArg, actualArg := expectedValues[i].Interface(), actualValues[i].Interface(); !assert.ObjectsAreEqual(expectedArg, actualArg) { - expectedFmt = fmt.Sprintf("%s(%T) -> %#v", funcNames[i], expectedArg, expectedArg) - actualFmt = fmt.Sprintf("%s(%T) -> %#v", funcNames[i], actualArg, actualArg) + expectedFmt = fmt.Sprintf("%s(%T) -> %#v", expectedNames[i], expectedArg, expectedArg) + actualFmt = fmt.Sprintf("%s(%T) -> %#v", expectedNames[i], actualArg, actualArg) return } } @@ -1256,7 +1266,7 @@ func assertOpts(expected, actual interface{}) (expectedFmt, actualFmt string) { return "", "" } -func getRuntimeFunc(opt interface{}) *runtime.Func { +func runtimeFunc(opt interface{}) *runtime.Func { return runtime.FuncForPC(reflect.ValueOf(opt).Pointer()) } From 05f87c016035811e6d8371f1887ec360c318f53f Mon Sep 17 00:00:00 2001 From: Arjun Dhawan Date: Sun, 27 Oct 2024 08:05:00 +0100 Subject: [PATCH 067/178] more similar --- mock/mock.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/mock/mock.go b/mock/mock.go index 50eeaba03..9f24479cd 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -1227,16 +1227,14 @@ func assertOpts(expected, actual interface{}) (expectedFmt, actualFmt string) { } for i := 0; i < expectedOpts.Len(); i++ { + expectedOpt := expectedOpts.Index(i).Interface() + actualOpt := actualOpts.Index(i).Interface() + if !isFuncSame(expectedFuncs[i], actualFuncs[i]) { expectedFmt = expectedNames[i] actualFmt = actualNames[i] return } - } - - for i := 0; i < expectedOpts.Len(); i++ { - expectedOpt := expectedOpts.Index(i).Interface() - actualOpt := actualOpts.Index(i).Interface() ot := reflect.TypeOf(expectedOpt) var expectedValues []reflect.Value From 7d99b2b43d8f60a8982a78cde6e8bd287dea5da0 Mon Sep 17 00:00:00 2001 From: Arjun Dhawan Date: Sun, 27 Oct 2024 08:07:57 +0100 Subject: [PATCH 068/178] attempt 2 --- mock/mock.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mock/mock.go b/mock/mock.go index 9f24479cd..eb5682df9 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -1227,15 +1227,15 @@ func assertOpts(expected, actual interface{}) (expectedFmt, actualFmt string) { } for i := 0; i < expectedOpts.Len(); i++ { - expectedOpt := expectedOpts.Index(i).Interface() - actualOpt := actualOpts.Index(i).Interface() - if !isFuncSame(expectedFuncs[i], actualFuncs[i]) { expectedFmt = expectedNames[i] actualFmt = actualNames[i] return } + expectedOpt := expectedOpts.Index(i).Interface() + actualOpt := actualOpts.Index(i).Interface() + ot := reflect.TypeOf(expectedOpt) var expectedValues []reflect.Value var actualValues []reflect.Value From 118fb8346630c192421c8914848381af9d4412a7 Mon Sep 17 00:00:00 2001 From: Hisham Akmal Date: Mon, 28 Oct 2024 16:38:04 +0530 Subject: [PATCH 069/178] NotSame should fail if args are not pointers #1661 (#1664) ## Summary Reduces the confusion assosciated with NotSame that previously would check nothing if any of the values is not a pointer. The changes made were tested using TestSame, TestNotSame, and Test_samePointers tests, and the changes did clear the tests. ## Changes 1. Modified samePointers to return another bool value(ok) that would determine if the 2 values are of pointer type or not, while the returned "same" bool value would determine if the 2 pointers are same. 2. Modified assert.NotSame to call Fail() if the 2 values are either i)pointers pointing to the same address or ii)either/both of the values are not pointers. 3. Modified assert.Same to call Fail() if the 2 values are either i)pointers not pointing to the same address or ii)either/both of the values are not pointers. 4. Modified Test_samePointers to handle the new behavior of samePointers by checking both if the inputs are pointers (ok) and if they point to the same object (same). ## Motivation Ensure NotSame accurately verifies pointer sameness by handling non-pointer inputs explicitly, improving clarity and reducing potential misuse. ## Related issues Closes #1661 --------- Co-authored-by: Bracken --- assert/assertions.go | 30 ++++++++++++++------ assert/assertions_test.go | 58 ++++++++++++++++++++++++++------------- 2 files changed, 61 insertions(+), 27 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index bfb640abc..4e91332bb 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -502,7 +502,13 @@ func Same(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) b h.Helper() } - if !samePointers(expected, actual) { + same, ok := samePointers(expected, actual) + if !ok { + return Fail(t, "Both arguments must be pointers", msgAndArgs...) + } + + 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...) @@ -522,7 +528,13 @@ func NotSame(t TestingT, expected, actual interface{}, msgAndArgs ...interface{} h.Helper() } - if samePointers(expected, actual) { + same, ok := samePointers(expected, actual) + if !ok { + //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...) @@ -530,21 +542,23 @@ func NotSame(t TestingT, expected, actual interface{}, msgAndArgs ...interface{} return true } -// samePointers compares two generic interface objects and returns whether -// they point to the same object -func samePointers(first, second interface{}) bool { +// samePointers checks if two generic interface objects are pointers of the same +// type pointing to the same object. It returns two values: same indicating if +// they are the same type and point to the same object, and ok indicating that +// both inputs are pointers. +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 + return false, false //not both are pointers } firstType, secondType := reflect.TypeOf(first), reflect.TypeOf(second) if firstType != secondType { - return false + return false, true // both are pointers, but of different types } // compare pointer addresses - return first == second + return first == second, true } // formatUnequalValues takes two values of arbitrary types and returns string diff --git a/assert/assertions_test.go b/assert/assertions_test.go index ca125998c..9f859fa8d 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -655,39 +655,59 @@ func Test_samePointers(t *testing.T) { second interface{} } tests := []struct { - name string - args args - assertion BoolAssertionFunc + name string + args args + same BoolAssertionFunc + ok BoolAssertionFunc }{ { - name: "1 != 2", - args: args{first: 1, second: 2}, - assertion: False, + name: "1 != 2", + args: args{first: 1, second: 2}, + same: False, + ok: False, + }, + { + name: "1 != 1 (not same ptr)", + args: args{first: 1, second: 1}, + same: False, + ok: False, + }, + { + name: "ptr(1) == ptr(1)", + args: args{first: p, second: p}, + same: True, + ok: True, }, { - name: "1 != 1 (not same ptr)", - args: args{first: 1, second: 1}, - assertion: False, + name: "int(1) != float32(1)", + args: args{first: int(1), second: float32(1)}, + same: False, + ok: False, }, { - name: "ptr(1) == ptr(1)", - args: args{first: p, second: p}, - assertion: True, + name: "array != slice", + args: args{first: [2]int{1, 2}, second: []int{1, 2}}, + same: False, + ok: False, }, { - name: "int(1) != float32(1)", - args: args{first: int(1), second: float32(1)}, - assertion: False, + name: "non-pointer vs pointer (1 != ptr(2))", + args: args{first: 1, second: p}, + same: False, + ok: False, }, { - name: "array != slice", - args: args{first: [2]int{1, 2}, second: []int{1, 2}}, - assertion: False, + name: "pointer vs non-pointer (ptr(2) != 1)", + args: args{first: p, second: 1}, + same: False, + ok: False, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - tt.assertion(t, samePointers(tt.args.first, tt.args.second)) + same, ok := samePointers(tt.args.first, tt.args.second) + tt.same(t, same) + tt.ok(t, ok) }) } } From 716de8dff46ed7ae3c6ebb7a6124db741ba7c018 Mon Sep 17 00:00:00 2001 From: sikehish Date: Mon, 28 Oct 2024 23:50:00 +0530 Subject: [PATCH 070/178] Increase timeouts in Test_Mock_Called_blocks to reduce flakiness in CI --- mock/mock_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mock/mock_test.go b/mock/mock_test.go index d28686700..5aab204b9 100644 --- a/mock/mock_test.go +++ b/mock/mock_test.go @@ -1256,7 +1256,7 @@ func Test_Mock_Called_blocks(t *testing.T) { var mockedService = new(TestExampleImplementation) - mockedService.Mock.On("asyncCall", 1, 2, 3).Return(5, "6", true).After(2 * time.Millisecond) + mockedService.Mock.On("asyncCall", 1, 2, 3).Return(5, "6", true).After(20 * time.Millisecond) ch := make(chan Arguments) @@ -1265,7 +1265,7 @@ func Test_Mock_Called_blocks(t *testing.T) { select { case <-ch: t.Fatal("should have waited") - case <-time.After(1 * time.Millisecond): + case <-time.After(10 * time.Millisecond): } returnArguments := <-ch From 2eca2b1976672aef09e63f0ab56329bc33a2fb5c Mon Sep 17 00:00:00 2001 From: Archit Agarwal Date: Sun, 3 Nov 2024 02:19:05 +0530 Subject: [PATCH 071/178] update documentation for the Error function in assert or require package #1609 --- assert/assertions.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index 4e91332bb..295144d14 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -1591,10 +1591,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 { From d27af4e3f5556bca53d8f401be6324776e64db22 Mon Sep 17 00:00:00 2001 From: Archit Agarwal Date: Sun, 3 Nov 2024 02:51:16 +0530 Subject: [PATCH 072/178] update documentation for auto require package --- assert/assertion_format.go | 6 ++---- assert/assertion_forward.go | 12 ++++-------- require/require.go | 12 ++++-------- require/require_forward.go | 12 ++++-------- 4 files changed, 14 insertions(+), 28 deletions(-) diff --git a/assert/assertion_format.go b/assert/assertion_format.go index 190634165..ebcbae58a 100644 --- a/assert/assertion_format.go +++ b/assert/assertion_format.go @@ -117,10 +117,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() diff --git a/assert/assertion_forward.go b/assert/assertion_forward.go index 21629087b..6222d1269 100644 --- a/assert/assertion_forward.go +++ b/assert/assertion_forward.go @@ -224,10 +224,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 +295,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() diff --git a/require/require.go b/require/require.go index d8921950d..5cc14fa07 100644 --- a/require/require.go +++ b/require/require.go @@ -279,10 +279,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 +371,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() diff --git a/require/require_forward.go b/require/require_forward.go index 1bd87304f..096904ba3 100644 --- a/require/require_forward.go +++ b/require/require_forward.go @@ -225,10 +225,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 +296,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() From 7434b149f3f14df72a6aa0d6d2c30a31931459c7 Mon Sep 17 00:00:00 2001 From: tsioftas Date: Mon, 18 Nov 2024 11:48:33 +0000 Subject: [PATCH 073/178] Improve ErrorIs message when error is nil but an error was expected --- assert/assertions.go | 3 +++ assert/assertions_test.go | 5 +---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index 4e91332bb..7aaa850a6 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -2100,6 +2100,9 @@ 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 %q but got nil.", expectedText), msgAndArgs...) + } } chain := buildErrorChainString(err) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 9f859fa8d..671b8ccfc 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -3240,10 +3240,7 @@ func TestErrorIs(t *testing.T) { err: nil, target: io.EOF, result: false, - resultErrMsg: "" + - "Target error should be in err chain:\n" + - "expected: \"EOF\"\n" + - "in chain: \n", + resultErrMsg: "Expected error \"EOF\" but got nil.\n", }, { err: io.EOF, From 19ddcbb61a59f0886dc7f51d08e9275372b85fe6 Mon Sep 17 00:00:00 2001 From: tsioftas Date: Mon, 18 Nov 2024 12:20:16 +0000 Subject: [PATCH 074/178] go fmt --- assert/assertions_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 671b8ccfc..8f0a0a958 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -3237,9 +3237,9 @@ func TestErrorIs(t *testing.T) { "in chain: \"EOF\"\n", }, { - err: nil, - target: io.EOF, - result: false, + err: nil, + target: io.EOF, + result: false, resultErrMsg: "Expected error \"EOF\" but got nil.\n", }, { From d57bac872105f5e62f6d3dd1f612d9c8a7d77d2b Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Wed, 30 Oct 2024 21:56:55 +0200 Subject: [PATCH 075/178] refactor: use %q to simplify fmt.Sprintf --- assert/assertion_compare.go | 2 +- assert/assertion_order.go | 2 +- assert/assertions.go | 2 +- assert/assertions_test.go | 2 +- assert/forward_assertions_test.go | 2 +- assert/http_assertions.go | 4 ++-- mock/mock.go | 4 ++-- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/assert/assertion_compare.go b/assert/assertion_compare.go index 7e19eba09..3bab482fd 100644 --- a/assert/assertion_compare.go +++ b/assert/assertion_compare.go @@ -468,7 +468,7 @@ 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 %q", reflect.TypeOf(e1)), msgAndArgs...) } if !containsValue(allowedComparesResults, compareResult) { diff --git a/assert/assertion_order.go b/assert/assertion_order.go index 1d2f71824..528645216 100644 --- a/assert/assertion_order.go +++ b/assert/assertion_order.go @@ -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 %q and %q", reflect.TypeOf(value), reflect.TypeOf(prevValue)), msgAndArgs...) } if !containsValue(allowedComparesResults, compareResult) { diff --git a/assert/assertions.go b/assert/assertions.go index 4e91332bb..e3d88539d 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -1069,7 +1069,7 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) 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 diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 9f859fa8d..bcbbc1273 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -2118,7 +2118,7 @@ func TestRegexp(t *testing.T) { } for _, tc := range cases { - False(t, Regexp(mockT, tc.rx, tc.str), "Expected \"%s\" to not match \"%s\"", tc.rx, tc.str) + False(t, Regexp(mockT, tc.rx, tc.str), "Expected %q to not match %q", tc.rx, tc.str) False(t, Regexp(mockT, regexp.MustCompile(tc.rx), tc.str)) False(t, Regexp(mockT, regexp.MustCompile(tc.rx), []byte(tc.str))) True(t, NotRegexp(mockT, tc.rx, tc.str)) diff --git a/assert/forward_assertions_test.go b/assert/forward_assertions_test.go index 496d3c0db..5752d449d 100644 --- a/assert/forward_assertions_test.go +++ b/assert/forward_assertions_test.go @@ -546,7 +546,7 @@ func TestRegexpWrapper(t *testing.T) { } for _, tc := range cases { - False(t, assert.Regexp(tc.rx, tc.str), "Expected \"%s\" to not match \"%s\"", tc.rx, tc.str) + False(t, assert.Regexp(tc.rx, tc.str), "Expected %q to not match %q", tc.rx, tc.str) False(t, assert.Regexp(regexp.MustCompile(tc.rx), tc.str)) True(t, assert.NotRegexp(tc.rx, tc.str)) True(t, assert.NotRegexp(regexp.MustCompile(tc.rx), tc.str)) diff --git a/assert/http_assertions.go b/assert/http_assertions.go index 861ed4b7c..5a6bb75f2 100644 --- a/assert/http_assertions.go +++ b/assert/http_assertions.go @@ -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 diff --git a/mock/mock.go b/mock/mock.go index eb5682df9..489015d10 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -494,7 +494,7 @@ func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Argumen // expected call found, but it has already been called with repeatable times if call != nil { m.mutex.Unlock() - m.fail("\nassert: mock: The method has been called over %d times.\n\tEither do one more Mock.On(\"%s\").Return(...), or remove extra call.\n\tThis call was unexpected:\n\t\t%s\n\tat: %s", call.totalCalls, methodName, callString(methodName, arguments, true), assert.CallerInfo()) + m.fail("\nassert: mock: The method has been called over %d times.\n\tEither do one more Mock.On(%q).Return(...), or remove extra call.\n\tThis call was unexpected:\n\t\t%s\n\tat: %s", call.totalCalls, methodName, callString(methodName, arguments, true), assert.CallerInfo()) } // we have to fail here - because we don't know what to do // as the return arguments. This is because: @@ -514,7 +514,7 @@ func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Argumen assert.CallerInfo(), ) } else { - m.fail("\nassert: mock: I don't know what to return because the method call was unexpected.\n\tEither do Mock.On(\"%s\").Return(...) first, or remove the %s() call.\n\tThis method was unexpected:\n\t\t%s\n\tat: %s", methodName, methodName, callString(methodName, arguments, true), assert.CallerInfo()) + m.fail("\nassert: mock: I don't know what to return because the method call was unexpected.\n\tEither do Mock.On(%q).Return(...) first, or remove the %s() call.\n\tThis method was unexpected:\n\t\t%s\n\tat: %s", methodName, methodName, callString(methodName, arguments, true), assert.CallerInfo()) } } From 30f3cef5ad49e3d1888120a76da2fa821d838e7e Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Tue, 10 Dec 2024 13:55:30 +0200 Subject: [PATCH 076/178] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Olivier Mengué --- assert/assertion_compare.go | 2 +- assert/assertion_order.go | 2 +- assert/assertions.go | 2 +- assert/assertions_test.go | 8 ++++---- mock/mock.go | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/assert/assertion_compare.go b/assert/assertion_compare.go index 3bab482fd..dfecd04ae 100644 --- a/assert/assertion_compare.go +++ b/assert/assertion_compare.go @@ -468,7 +468,7 @@ 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 %q", reflect.TypeOf(e1)), msgAndArgs...) + return Fail(t, fmt.Sprintf(`Can not compare type "%T"`, e1), msgAndArgs...) } if !containsValue(allowedComparesResults, compareResult) { diff --git a/assert/assertion_order.go b/assert/assertion_order.go index 528645216..2fdf80fdd 100644 --- a/assert/assertion_order.go +++ b/assert/assertion_order.go @@ -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 %q and %q", 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) { diff --git a/assert/assertions.go b/assert/assertions.go index e3d88539d..d3fd28fa2 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -444,7 +444,7 @@ func IsType(t TestingT, expectedType interface{}, object interface{}, 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...) + return Fail(t, fmt.Sprintf("Object expected to be of type %T, but was %T", expectedType, object), msgAndArgs...) } return true diff --git a/assert/assertions_test.go b/assert/assertions_test.go index bcbbc1273..009a839bc 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -2151,11 +2151,11 @@ func TestZero(t *testing.T) { mockT := new(testing.T) for _, test := range zeros { - True(t, Zero(mockT, test, "%#v is not the %v zero value", test, reflect.TypeOf(test))) + True(t, Zero(mockT, test, "%#v is not the %T zero value", test, test)) } for _, test := range nonZeros { - False(t, Zero(mockT, test, "%#v is not the %v zero value", test, reflect.TypeOf(test))) + False(t, Zero(mockT, test, "%#v is not the %T zero value", test, test)) } } @@ -2163,11 +2163,11 @@ func TestNotZero(t *testing.T) { mockT := new(testing.T) for _, test := range zeros { - False(t, NotZero(mockT, test, "%#v is not the %v zero value", test, reflect.TypeOf(test))) + False(t, NotZero(mockT, test, "%#v is not the %T zero value", test, test)) } for _, test := range nonZeros { - True(t, NotZero(mockT, test, "%#v is not the %v zero value", test, reflect.TypeOf(test))) + True(t, NotZero(mockT, test, "%#v is not the %T zero value", test, test)) } } diff --git a/mock/mock.go b/mock/mock.go index 489015d10..1a7c03853 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -494,7 +494,7 @@ func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Argumen // expected call found, but it has already been called with repeatable times if call != nil { m.mutex.Unlock() - m.fail("\nassert: mock: The method has been called over %d times.\n\tEither do one more Mock.On(%q).Return(...), or remove extra call.\n\tThis call was unexpected:\n\t\t%s\n\tat: %s", call.totalCalls, methodName, callString(methodName, arguments, true), assert.CallerInfo()) + m.fail("\nassert: mock: The method has been called over %d times.\n\tEither do one more Mock.On(%#v).Return(...), or remove extra call.\n\tThis call was unexpected:\n\t\t%s\n\tat: %s", call.totalCalls, methodName, callString(methodName, arguments, true), assert.CallerInfo()) } // we have to fail here - because we don't know what to do // as the return arguments. This is because: @@ -514,7 +514,7 @@ func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Argumen assert.CallerInfo(), ) } else { - m.fail("\nassert: mock: I don't know what to return because the method call was unexpected.\n\tEither do Mock.On(%q).Return(...) first, or remove the %s() call.\n\tThis method was unexpected:\n\t\t%s\n\tat: %s", methodName, methodName, callString(methodName, arguments, true), assert.CallerInfo()) + m.fail("\nassert: mock: I don't know what to return because the method call was unexpected.\n\tEither do Mock.On(%#v).Return(...) first, or remove the %s() call.\n\tThis method was unexpected:\n\t\t%s\n\tat: %s", methodName, methodName, callString(methodName, arguments, true), assert.CallerInfo()) } } From 014ae9a7a4ccff999ad5da28bb21b29715ab427a Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Tue, 10 Dec 2024 14:21:03 +0200 Subject: [PATCH 077/178] Replace deprecated io/ioutil with io and os --- _codegen/main.go | 5 ++--- suite/suite_test.go | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/_codegen/main.go b/_codegen/main.go index 7158afc9f..e193a74a5 100644 --- a/_codegen/main.go +++ b/_codegen/main.go @@ -16,7 +16,6 @@ import ( "go/token" "go/types" "io" - "io/ioutil" "log" "os" "path" @@ -101,7 +100,7 @@ func parseTemplates() (*template.Template, *template.Template, error) { return nil, nil, err } if *tmplFile != "" { - f, err := ioutil.ReadFile(*tmplFile) + f, err := os.ReadFile(*tmplFile) if err != nil { return nil, nil, err } @@ -183,7 +182,7 @@ func parsePackageSource(pkg string) (*types.Scope, *doc.Package, error) { files := make(map[string]*ast.File) fileList := make([]*ast.File, len(pd.GoFiles)) for i, fname := range pd.GoFiles { - src, err := ioutil.ReadFile(path.Join(pd.Dir, fname)) + src, err := os.ReadFile(path.Join(pd.Dir, fname)) if err != nil { return nil, nil, err } diff --git a/suite/suite_test.go b/suite/suite_test.go index b97eb4311..eceecb622 100644 --- a/suite/suite_test.go +++ b/suite/suite_test.go @@ -4,7 +4,7 @@ import ( "bytes" "errors" "flag" - "io/ioutil" + "io" "math/rand" "os" "os/exec" @@ -440,7 +440,7 @@ func (sc *StdoutCapture) StopCapture() (string, error) { } os.Stdout.Close() os.Stdout = sc.oldStdout - bytes, err := ioutil.ReadAll(sc.readPipe) + bytes, err := io.ReadAll(sc.readPipe) if err != nil { return "", err } From f8c628e5a14e7cf6bc5d4407e2fdc54b772ee85b Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Mon, 16 Dec 2024 23:14:16 +0200 Subject: [PATCH 078/178] docs: Fix typo in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b2dbd16ea..d4857d38f 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Get started: * Install testify with [one line of code](#installation), or [update it with another](#staying-up-to-date) * For an introduction to writing test code in Go, see https://go.dev/doc/code#Testing * Check out the API Documentation https://pkg.go.dev/github.com/stretchr/testify - * Use [testifylint](https://github.com/Antonboom/testifylint) (via [golanci-lint](https://golangci-lint.run/)) to avoid common mistakes + * Use [testifylint](https://github.com/Antonboom/testifylint) (via [golangci-lint](https://golangci-lint.run/)) to avoid common mistakes * A little about [Test-Driven Development (TDD)](https://en.wikipedia.org/wiki/Test-driven_development) [`assert`](https://pkg.go.dev/github.com/stretchr/testify/assert "API documentation") package From cfee2346d77ee99757847d055944f73c22cd5c4e Mon Sep 17 00:00:00 2001 From: Mike Auclair Date: Tue, 17 Dec 2024 18:18:56 +0000 Subject: [PATCH 079/178] review feedback --- assert/assertions.go | 102 +++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 56 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index 9edddc784..9024239a4 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -221,75 +221,65 @@ func CallerInfo() []string { callers := []string{} pcs := make([]uintptr, stackFrameBufferSize) offset := 1 - n := runtime.Callers(offset, pcs) - - if n == 0 { - return []string{} - } - - maybeMore := n == stackFrameBufferSize - frames := runtime.CallersFrames(pcs[:n]) for { - frame, more := frames.Next() - pc = frame.PC - file = frame.File - line = frame.Line + n := runtime.Callers(offset, pcs) - // This is a huge edge case, but it will panic if this is the case, see #180 - if file == "" { + if n == 0 { break } - 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 - } + frames := runtime.CallersFrames(pcs[:n]) - 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)) + for { + frame, more := frames.Next() + pc = frame.PC + file = frame.File + line = frame.Line + + // This is a huge edge case, but it will panic if this is the case, see #180 + if file == "" { + break } - } - // Drop the package - segments := strings.Split(name, ".") - name = segments[len(segments)-1] - if isTest(name, "Test") || - isTest(name, "Benchmark") || - isTest(name, "Example") { - break - } + 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 + } - if more { - continue + 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 + segments := strings.Split(name, ".") + name = segments[len(segments)-1] + if isTest(name, "Test") || + isTest(name, "Benchmark") || + isTest(name, "Example") { + break + } + if !more { + break + } } // We know we already have less than a buffer's worth of frames - if !maybeMore { - break - } offset += stackFrameBufferSize - n = runtime.Callers(offset, pcs) - if n == 0 { - break - } - - maybeMore = n == stackFrameBufferSize - - frames = runtime.CallersFrames(pcs[:n]) } From 3d98e693c74692c3a66c6cb55cb6f4cac9b52516 Mon Sep 17 00:00:00 2001 From: Mike Auclair Date: Tue, 25 Jun 2024 16:12:07 +0000 Subject: [PATCH 080/178] cleanup --- mock/mock.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mock/mock.go b/mock/mock.go index c8ed892bd..ba66ad5e6 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -1033,7 +1033,7 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { } default: - if expected == Anything || assert.ObjectsAreEqual(expected, Anything) || assert.ObjectsAreEqual(actual, Anything) || assert.ObjectsAreEqual(actual, expected) { + if assert.ObjectsAreEqual(expected, Anything) || assert.ObjectsAreEqual(actual, Anything) || assert.ObjectsAreEqual(actual, expected) { // match outputRenderers = append(outputRenderers, func() string { return fmt.Sprintf("\t%d: PASS: %s == %s\n", i, actualFmt(), expectedFmt()) From cbf6e73c7e22a394e39dd30ca0d1368813ceb1e7 Mon Sep 17 00:00:00 2001 From: Mike Auclair Date: Tue, 17 Dec 2024 18:30:48 +0000 Subject: [PATCH 081/178] simplified renderers --- mock/mock.go | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/mock/mock.go b/mock/mock.go index ba66ad5e6..0feb48218 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -923,7 +923,7 @@ func (args Arguments) Is(objects ...interface{}) bool { return true } -type outputRenderer interface{} +type outputRenderer func() string // Diff gets a string describing the differences between the arguments // and the specified objects. @@ -989,7 +989,9 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { }) } else { differences++ - outputRenderers = append(outputRenderers, fmt.Sprintf("\t%d: FAIL: %s not matched by %s\n", i, actualFmt(), matcher)) + outputRenderers = append(outputRenderers, func() string { + return fmt.Sprintf("\t%d: FAIL: %s not matched by %s\n", i, actualFmt(), matcher) + }) } } else { switch expected := expected.(type) { @@ -998,13 +1000,17 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { if reflect.TypeOf(actual).Name() != string(expected) && reflect.TypeOf(actual).String() != string(expected) { // not match differences++ - outputRenderers = append(outputRenderers, fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, expected, reflect.TypeOf(actual).Name(), actualFmt())) + outputRenderers = append(outputRenderers, func() string { + return fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, expected, reflect.TypeOf(actual).Name(), actualFmt()) + }) } case *IsTypeArgument: actualT := reflect.TypeOf(actual) if actualT != expected.t { differences++ - outputRenderers = append(outputRenderers, fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, expected.t.Name(), actualT.Name(), actualFmt())) + outputRenderers = append(outputRenderers, func() string { + return fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, expected.t.Name(), actualT.Name(), actualFmt()) + }) } case *FunctionalOptionsArgument: t := expected.value @@ -1018,7 +1024,9 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { tName := reflect.TypeOf(t).Name() if name != reflect.TypeOf(actual).String() && tValue.Len() != 0 { differences++ - outputRenderers = append(outputRenderers, fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, tName, reflect.TypeOf(actual).Name(), actualFmt())) + outputRenderers = append(outputRenderers, func() string { + return fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, tName, reflect.TypeOf(actual).Name(), actualFmt()) + }) } else { if ef, af := assertOpts(t, actual); ef == "" && af == "" { // match @@ -1028,7 +1036,9 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { } else { // not match differences++ - outputRenderers = append(outputRenderers, fmt.Sprintf("\t%d: FAIL: %s != %s\n", i, af, ef)) + outputRenderers = append(outputRenderers, func() string { + return fmt.Sprintf("\t%d: FAIL: %s != %s\n", i, af, ef) + }) } } @@ -1041,7 +1051,9 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { } else { // not match differences++ - outputRenderers = append(outputRenderers, fmt.Sprintf("\t%d: FAIL: %s != %s\n", i, actualFmt(), expectedFmt())) + outputRenderers = append(outputRenderers, func() string { + return fmt.Sprintf("\t%d: FAIL: %s != %s\n", i, actualFmt(), expectedFmt()) + }) } } } @@ -1053,15 +1065,8 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { } outputBuilder.WriteString("\n") - for _, renderer := range outputRenderers { - switch r := renderer.(type) { - case string: - outputBuilder.WriteString(r) - case func() string: - outputBuilder.WriteString(r()) - default: - panic("Invalid Output Renderer") - } + for _, r := range outputRenderers { + outputBuilder.WriteString(r()) } return outputBuilder.String(), differences From ca6698b8a1c4617c5ca4333ce0c878e91c506702 Mon Sep 17 00:00:00 2001 From: Craig Davison Date: Tue, 31 Dec 2024 15:09:40 -0700 Subject: [PATCH 082/178] assert.ErrorAs: log target type --- assert/assertions.go | 49 ++++++++++++++++------ assert/assertions_test.go | 87 ++++++++++++++++++++++++++++----------- 2 files changed, 99 insertions(+), 37 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index 4e91332bb..466554e5a 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -2102,7 +2102,7 @@ func ErrorIs(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 be in err chain:\n"+ "expected: %q\n"+ @@ -2125,7 +2125,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,10 +2143,10 @@ func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{ return true } - chain := buildErrorChainString(err) + chain := buildErrorChainString(err, true) return Fail(t, fmt.Sprintf("Should be in error chain:\n"+ - "expected: %q\n"+ + "expected: %T\n"+ "in chain: %s", target, chain, ), msgAndArgs...) } @@ -2161,24 +2161,49 @@ 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"+ + "found: %T\n"+ "in chain: %s", target, 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 + default: + return + } + 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 } diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 9f859fa8d..18911ba83 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -3175,11 +3175,13 @@ func parseLabeledOutput(output string) []labeledContent { } type captureTestingT struct { - msg string + failed bool + msg string } func (ctt *captureTestingT) Errorf(format string, args ...interface{}) { ctt.msg = fmt.Sprintf(format, args...) + ctt.failed = true } func (ctt *captureTestingT) checkResultAndErrMsg(t *testing.T, expectedRes, res bool, expectedErrMsg string) { @@ -3188,6 +3190,9 @@ func (ctt *captureTestingT) checkResultAndErrMsg(t *testing.T, expectedRes, res t.Errorf("Should return %t", expectedRes) return } + if res == ctt.failed { + t.Errorf("The test result (%t) should be reflected in the testing.T type (%t)", res, !ctt.failed) + } contents := parseLabeledOutput(ctt.msg) if res == true { if contents != nil { @@ -3348,50 +3353,82 @@ func TestNotErrorIs(t *testing.T) { func TestErrorAs(t *testing.T) { tests := []struct { - err error - result bool + err error + result bool + resultErrMsg string }{ - {fmt.Errorf("wrap: %w", &customError{}), true}, - {io.EOF, false}, - {nil, false}, + { + err: fmt.Errorf("wrap: %w", &customError{}), + result: true, + }, + { + err: io.EOF, + result: false, + resultErrMsg: "" + + "Should be in error chain:\n" + + "expected: **assert.customError\n" + + "in chain: \"EOF\" (*errors.errorString)\n", + }, + { + err: nil, + result: false, + resultErrMsg: "" + + "Should be in error chain:\n" + + "expected: **assert.customError\n" + + "in chain: \n", + }, + { + err: fmt.Errorf("abc: %w", errors.New("def")), + result: false, + resultErrMsg: "" + + "Should be in error chain:\n" + + "expected: **assert.customError\n" + + "in chain: \"abc: def\" (*fmt.wrapError)\n" + + "\t\"def\" (*errors.errorString)\n", + }, } for _, tt := range tests { tt := tt var target *customError t.Run(fmt.Sprintf("ErrorAs(%#v,%#v)", tt.err, target), func(t *testing.T) { - mockT := new(testing.T) + mockT := new(captureTestingT) res := ErrorAs(mockT, tt.err, &target) - if res != tt.result { - t.Errorf("ErrorAs(%#v,%#v) should return %t", tt.err, target, tt.result) - } - if res == mockT.Failed() { - t.Errorf("The test result (%t) should be reflected in the testing.T type (%t)", res, !mockT.Failed()) - } + mockT.checkResultAndErrMsg(t, tt.result, res, tt.resultErrMsg) }) } } func TestNotErrorAs(t *testing.T) { tests := []struct { - err error - result bool + err error + result bool + resultErrMsg string }{ - {fmt.Errorf("wrap: %w", &customError{}), false}, - {io.EOF, true}, - {nil, true}, + { + err: fmt.Errorf("wrap: %w", &customError{}), + result: false, + resultErrMsg: "" + + "Target error should not be in err chain:\n" + + "found: **assert.customError\n" + + "in chain: \"wrap: fail\" (*fmt.wrapError)\n" + + "\t\"fail\" (*assert.customError)\n", + }, + { + err: io.EOF, + result: true, + }, + { + err: nil, + result: true, + }, } for _, tt := range tests { tt := tt var target *customError t.Run(fmt.Sprintf("NotErrorAs(%#v,%#v)", tt.err, target), func(t *testing.T) { - mockT := new(testing.T) + mockT := new(captureTestingT) res := NotErrorAs(mockT, tt.err, &target) - if res != tt.result { - t.Errorf("NotErrorAs(%#v,%#v) should not return %t", tt.err, target, tt.result) - } - if res == mockT.Failed() { - t.Errorf("The test result (%t) should be reflected in the testing.T type (%t)", res, !mockT.Failed()) - } + mockT.checkResultAndErrMsg(t, tt.result, res, tt.resultErrMsg) }) } } From ccb5e7f656ccfbd55ab31f98b4a7aa8d5255d30a Mon Sep 17 00:00:00 2001 From: Craig Davison Date: Tue, 31 Dec 2024 15:26:24 -0700 Subject: [PATCH 083/178] Remove redundant returns --- assert/assertions.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index 466554e5a..4efe1de47 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -2182,9 +2182,6 @@ func unwrapAll(err error) (errs []error) { for _, err := range x.Unwrap() { errs = append(errs, unwrapAll(err)...) } - return - default: - return } return } From 1c717c00c126f37ce24492e0e34ca7921bf01b5d Mon Sep 17 00:00:00 2001 From: Craig Davison Date: Tue, 31 Dec 2024 15:35:31 -0700 Subject: [PATCH 084/178] Add return --- assert/assertions_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 18911ba83..bb6af1b6f 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -3192,6 +3192,7 @@ func (ctt *captureTestingT) checkResultAndErrMsg(t *testing.T, expectedRes, res } if res == ctt.failed { t.Errorf("The test result (%t) should be reflected in the testing.T type (%t)", res, !ctt.failed) + return } contents := parseLabeledOutput(ctt.msg) if res == true { From c60c3bd7fb8aa1f50fe1e91c9136060a4cbd9657 Mon Sep 17 00:00:00 2001 From: Craig Davison Date: Fri, 3 Jan 2025 14:34:16 -0700 Subject: [PATCH 085/178] dereference target --- assert/assertions.go | 8 ++++---- assert/assertions_test.go | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index 4efe1de47..be821614b 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -2146,8 +2146,8 @@ func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{ chain := buildErrorChainString(err, true) return Fail(t, fmt.Sprintf("Should be in error chain:\n"+ - "expected: %T\n"+ - "in chain: %s", target, chain, + "expected: %s\n"+ + "in chain: %s", reflect.ValueOf(target).Elem().Type(), chain, ), msgAndArgs...) } @@ -2164,8 +2164,8 @@ func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interfa chain := buildErrorChainString(err, true) return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+ - "found: %T\n"+ - "in chain: %s", target, chain, + "found: %s\n"+ + "in chain: %s", reflect.ValueOf(target).Elem().Type(), chain, ), msgAndArgs...) } diff --git a/assert/assertions_test.go b/assert/assertions_test.go index bb6af1b6f..503eadb3a 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -3367,7 +3367,7 @@ func TestErrorAs(t *testing.T) { result: false, resultErrMsg: "" + "Should be in error chain:\n" + - "expected: **assert.customError\n" + + "expected: *assert.customError\n" + "in chain: \"EOF\" (*errors.errorString)\n", }, { @@ -3375,7 +3375,7 @@ func TestErrorAs(t *testing.T) { result: false, resultErrMsg: "" + "Should be in error chain:\n" + - "expected: **assert.customError\n" + + "expected: *assert.customError\n" + "in chain: \n", }, { @@ -3383,7 +3383,7 @@ func TestErrorAs(t *testing.T) { result: false, resultErrMsg: "" + "Should be in error chain:\n" + - "expected: **assert.customError\n" + + "expected: *assert.customError\n" + "in chain: \"abc: def\" (*fmt.wrapError)\n" + "\t\"def\" (*errors.errorString)\n", }, @@ -3410,7 +3410,7 @@ func TestNotErrorAs(t *testing.T) { result: false, resultErrMsg: "" + "Target error should not be in err chain:\n" + - "found: **assert.customError\n" + + "found: *assert.customError\n" + "in chain: \"wrap: fail\" (*fmt.wrapError)\n" + "\t\"fail\" (*assert.customError)\n", }, From 3cf0926564e4b2e9646e212ed6b5e935970e2f8f Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Mon, 16 Dec 2024 22:27:38 +0200 Subject: [PATCH 086/178] docs: Format examples in README --- README.md | 185 ++++++++++++++++++++++++++---------------------------- 1 file changed, 88 insertions(+), 97 deletions(-) diff --git a/README.md b/README.md index d4857d38f..44d40e6c4 100644 --- a/README.md +++ b/README.md @@ -38,30 +38,27 @@ See it in action: package yours import ( - "testing" - "github.com/stretchr/testify/assert" + "testing" + + "github.com/stretchr/testify/assert" ) func TestSomething(t *testing.T) { + // assert equality + assert.Equal(t, 123, 123, "they should be equal") - // assert equality - assert.Equal(t, 123, 123, "they should be equal") - - // assert inequality - assert.NotEqual(t, 123, 456, "they should not be equal") - - // assert for nil (good for errors) - assert.Nil(t, object) + // assert inequality + assert.NotEqual(t, 123, 456, "they should not be equal") - // assert for not nil (good when you expect something) - if assert.NotNil(t, object) { - - // now we know that object isn't nil, we are safe to make - // further assertions without causing any errors - assert.Equal(t, "Something", object.Value) - - } + // assert for nil (good for errors) + assert.Nil(t, object) + // assert for not nil (good when you expect something) + if assert.NotNil(t, object) { + // now we know that object isn't nil, we are safe to make + // further assertions without causing any errors + assert.Equal(t, "Something", object.Value) + } } ``` @@ -74,29 +71,29 @@ if you assert many times, use the below: package yours import ( - "testing" - "github.com/stretchr/testify/assert" + "testing" + + "github.com/stretchr/testify/assert" ) func TestSomething(t *testing.T) { - assert := assert.New(t) + assert := assert.New(t) - // assert equality - assert.Equal(123, 123, "they should be equal") + // assert equality + assert.Equal(123, 123, "they should be equal") - // assert inequality - assert.NotEqual(123, 456, "they should not be equal") + // assert inequality + assert.NotEqual(123, 456, "they should not be equal") - // assert for nil (good for errors) - assert.Nil(object) + // assert for nil (good for errors) + assert.Nil(object) - // assert for not nil (good when you expect something) - if assert.NotNil(object) { - - // now we know that object isn't nil, we are safe to make - // further assertions without causing any errors - assert.Equal("Something", object.Value) - } + // assert for not nil (good when you expect something) + if assert.NotNil(object) { + // now we know that object isn't nil, we are safe to make + // further assertions without causing any errors + assert.Equal("Something", object.Value) + } } ``` @@ -120,8 +117,9 @@ An example test function that tests a piece of code that relies on an external o package yours import ( - "testing" - "github.com/stretchr/testify/mock" + "testing" + + "github.com/stretchr/testify/mock" ) /* @@ -130,8 +128,8 @@ import ( // MyMockedObject is a mocked object that implements an interface // that describes an object that the code I am testing relies on. -type MyMockedObject struct{ - mock.Mock +type MyMockedObject struct { + mock.Mock } // DoSomething is a method on MyMockedObject that implements some interface @@ -142,10 +140,8 @@ type MyMockedObject struct{ // // NOTE: This method is not being tested here, code that uses this object is. func (m *MyMockedObject) DoSomething(number int) (bool, error) { - - args := m.Called(number) - return args.Bool(0), args.Error(1) - + args := m.Called(number) + return args.Bool(0), args.Error(1) } /* @@ -155,20 +151,17 @@ func (m *MyMockedObject) DoSomething(number int) (bool, error) { // TestSomething is an example of how to use our test object to // make assertions about some target code we are testing. func TestSomething(t *testing.T) { + // create an instance of our test object + testObj := new(MyMockedObject) - // create an instance of our test object - testObj := new(MyMockedObject) - - // set up expectations - testObj.On("DoSomething", 123).Return(true, nil) - - // call the code we are testing - targetFuncThatDoesSomethingWithObj(testObj) - - // assert that the expectations were met - testObj.AssertExpectations(t) + // set up expectations + testObj.On("DoSomething", 123).Return(true, nil) + // call the code we are testing + targetFuncThatDoesSomethingWithObj(testObj) + // assert that the expectations were met + testObj.AssertExpectations(t) } // TestSomethingWithPlaceholder is a second example of how to use our test object to @@ -177,45 +170,42 @@ func TestSomething(t *testing.T) { // data being passed in is normally dynamically generated and cannot be // predicted beforehand (eg. containing hashes that are time sensitive) func TestSomethingWithPlaceholder(t *testing.T) { + // create an instance of our test object + testObj := new(MyMockedObject) - // create an instance of our test object - testObj := new(MyMockedObject) - - // set up expectations with a placeholder in the argument list - testObj.On("DoSomething", mock.Anything).Return(true, nil) + // set up expectations with a placeholder in the argument list + testObj.On("DoSomething", mock.Anything).Return(true, nil) - // call the code we are testing - targetFuncThatDoesSomethingWithObj(testObj) - - // assert that the expectations were met - testObj.AssertExpectations(t) + // call the code we are testing + targetFuncThatDoesSomethingWithObj(testObj) + // assert that the expectations were met + testObj.AssertExpectations(t) } // TestSomethingElse2 is a third example that shows how you can use // the Unset method to cleanup handlers and then add new ones. func TestSomethingElse2(t *testing.T) { + // create an instance of our test object + testObj := new(MyMockedObject) - // create an instance of our test object - testObj := new(MyMockedObject) - - // set up expectations with a placeholder in the argument list - mockCall := testObj.On("DoSomething", mock.Anything).Return(true, nil) + // set up expectations with a placeholder in the argument list + mockCall := testObj.On("DoSomething", mock.Anything).Return(true, nil) - // call the code we are testing - targetFuncThatDoesSomethingWithObj(testObj) + // call the code we are testing + targetFuncThatDoesSomethingWithObj(testObj) - // assert that the expectations were met - testObj.AssertExpectations(t) + // assert that the expectations were met + testObj.AssertExpectations(t) - // remove the handler now so we can add another one that takes precedence - mockCall.Unset() + // remove the handler now so we can add another one that takes precedence + mockCall.Unset() - // return false now instead of true - testObj.On("DoSomething", mock.Anything).Return(false, nil) + // return false now instead of true + testObj.On("DoSomething", mock.Anything).Return(false, nil) - testObj.AssertExpectations(t) + testObj.AssertExpectations(t) } ``` @@ -235,35 +225,36 @@ An example suite is shown below: ```go // Basic imports import ( - "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/suite" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" ) // Define the suite, and absorb the built-in basic suite // functionality from testify - including a T() method which // returns the current testing context type ExampleTestSuite struct { - suite.Suite - VariableThatShouldStartAtFive int + suite.Suite + VariableThatShouldStartAtFive int } // Make sure that VariableThatShouldStartAtFive is set to five // before each test func (suite *ExampleTestSuite) SetupTest() { - suite.VariableThatShouldStartAtFive = 5 + suite.VariableThatShouldStartAtFive = 5 } // All methods that begin with "Test" are run as tests within a // suite. func (suite *ExampleTestSuite) TestExample() { - assert.Equal(suite.T(), 5, suite.VariableThatShouldStartAtFive) + assert.Equal(suite.T(), 5, suite.VariableThatShouldStartAtFive) } // In order for 'go test' to run this suite, we need to create // a normal test function and pass our suite to suite.Run func TestExampleTestSuite(t *testing.T) { - suite.Run(t, new(ExampleTestSuite)) + suite.Run(t, new(ExampleTestSuite)) } ``` @@ -276,33 +267,34 @@ For more information on writing suites, check out the [API documentation for the ```go // Basic imports import ( - "testing" - "github.com/stretchr/testify/suite" + "testing" + + "github.com/stretchr/testify/suite" ) // Define the suite, and absorb the built-in basic suite // functionality from testify - including assertion methods. type ExampleTestSuite struct { - suite.Suite - VariableThatShouldStartAtFive int + suite.Suite + VariableThatShouldStartAtFive int } // Make sure that VariableThatShouldStartAtFive is set to five // before each test func (suite *ExampleTestSuite) SetupTest() { - suite.VariableThatShouldStartAtFive = 5 + suite.VariableThatShouldStartAtFive = 5 } // All methods that begin with "Test" are run as tests within a // suite. func (suite *ExampleTestSuite) TestExample() { - suite.Equal(suite.VariableThatShouldStartAtFive, 5) + suite.Equal(suite.VariableThatShouldStartAtFive, 5) } // In order for 'go test' to run this suite, we need to create // a normal test function and pass our suite to suite.Run func TestExampleTestSuite(t *testing.T) { - suite.Run(t, new(ExampleTestSuite)) + suite.Run(t, new(ExampleTestSuite)) } ``` @@ -329,14 +321,13 @@ Import the `testify/assert` package into your code using this template: package yours import ( - "testing" - "github.com/stretchr/testify/assert" + "testing" + + "github.com/stretchr/testify/assert" ) func TestSomething(t *testing.T) { - - assert.True(t, true, "True is true!") - + assert.True(t, true, "True is true!") } ``` From dfda68b86fdac7fe5dc07ecc18eb65d7ca32923f Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Mon, 20 Jan 2025 19:41:28 +0200 Subject: [PATCH 087/178] Verify formatting of code snippets in CI --- .ci.readme.fmt.sh | 10 ++++++++++ .github/workflows/main.yml | 12 ++++++++++++ .mdsf.json | 12 ++++++++++++ 3 files changed, 34 insertions(+) create mode 100755 .ci.readme.fmt.sh create mode 100644 .mdsf.json diff --git a/.ci.readme.fmt.sh b/.ci.readme.fmt.sh new file mode 100755 index 000000000..6f1f3a269 --- /dev/null +++ b/.ci.readme.fmt.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# Verify that the code snippets in README.md are formatted. +# The tool https://github.com/hougesen/mdsf is used. + +if [ -n "$(mdsf verify --config .mdsf.json README.md 2>&1)" ]; then + echo "Go code in the README.md is not formatted." + echo "Did you forget to run 'mdsf format --config .mdsf.json README.md'?" + exit 1 +fi diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1dd4e650f..ded4f06b5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -37,3 +37,15 @@ jobs: with: go-version: ${{ matrix.go_version }} - run: go test -v -race ./... + format: + name: Check formatting of code snippets in markdown files + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: stable + - run: npm install -g mdsf-cli + - run: ./.ci.gofmt.sh + - run: ./.ci.readme.fmt.sh diff --git a/.mdsf.json b/.mdsf.json new file mode 100644 index 000000000..7617589ce --- /dev/null +++ b/.mdsf.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://raw.githubusercontent.com/hougesen/mdsf/main/schemas/v0.4.1/mdsf.schema.json", + "format_finished_document": false, + "languages": { + "go": [ + [ + "gofmt", + "goimports" + ] + ] + } +} From 098128fd102520c289cc5aef04afa388f10998a9 Mon Sep 17 00:00:00 2001 From: techfg Date: Tue, 18 Mar 2025 12:48:09 -0700 Subject: [PATCH 088/178] chore: update docs for Unset #1621 --- mock/mock.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/mock/mock.go b/mock/mock.go index eb5682df9..6f734feef 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -208,9 +208,16 @@ func (c *Call) On(methodName string, arguments ...interface{}) *Call { return c.Parent.On(methodName, arguments...) } -// Unset removes a mock handler from being called. +// Unset removes all mock handlers that satisfy the call instance arguments from being +// called. Only supported on call instances with static input arguments. // -// test.On("func", mock.Anything).Unset() +// For example, the only handler remaining after the following would be `2, 2`: +// +// test. +// On("func", 2, 2).Return(0). +// On("func", 3, 3).Return(0). +// On("func", Anything, Anything).Return(0) +// test.On("func", 3, 3).Unset() func (c *Call) Unset() *Call { var unlockOnce sync.Once From 89086b0757c069a4ab49a42f36f8a2e54c831e4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Wed, 19 Mar 2025 20:48:34 +0100 Subject: [PATCH 089/178] Document consequences of calling t.FailNow() These comments are adapted from t.FailNow()'s own documentation. Closes #1701 --- mock/mock.go | 2 ++ require/doc.go | 2 ++ 2 files changed, 4 insertions(+) diff --git a/mock/mock.go b/mock/mock.go index eb5682df9..3f53d22c5 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -332,6 +332,8 @@ func (m *Mock) TestData() objx.Map { */ // Test sets the test struct variable of the mock object +// Test should not be called on an object that is going to be used in a +// goroutine other than the one running the test function. func (m *Mock) Test(t TestingT) { m.mutex.Lock() defer m.mutex.Unlock() diff --git a/require/doc.go b/require/doc.go index 968434724..c8e3f94a8 100644 --- a/require/doc.go +++ b/require/doc.go @@ -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. From b1c9368f814ec4c2d286b557f12c255f33ea76e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Fri, 21 Mar 2025 13:21:25 +0100 Subject: [PATCH 090/178] Improve existing docs --- mock/mock.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mock/mock.go b/mock/mock.go index 3f53d22c5..a6be813c7 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -331,7 +331,8 @@ func (m *Mock) TestData() objx.Map { Setting expectations */ -// Test sets the test struct variable of the mock object +// Test sets the [TestingT] on which errors will be reported, otherwise errors +// will cause a panic. // Test should not be called on an object that is going to be used in a // goroutine other than the one running the test function. func (m *Mock) Test(t TestingT) { From c6ac9bb91dd4966b95a61971926b69a5d8ac1506 Mon Sep 17 00:00:00 2001 From: techfg Date: Fri, 21 Mar 2025 06:25:01 -0700 Subject: [PATCH 091/178] chore: update per PR feedback --- mock/mock.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mock/mock.go b/mock/mock.go index 6f734feef..da9f57365 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -211,13 +211,13 @@ func (c *Call) On(methodName string, arguments ...interface{}) *Call { // Unset removes all mock handlers that satisfy the call instance arguments from being // called. Only supported on call instances with static input arguments. // -// For example, the only handler remaining after the following would be `2, 2`: +// For example, the only handler remaining after the following would be "MyMethod(2, 2)": // -// test. -// On("func", 2, 2).Return(0). -// On("func", 3, 3).Return(0). -// On("func", Anything, Anything).Return(0) -// test.On("func", 3, 3).Unset() +// Mock. +// On("MyMethod", 2, 2).Return(0). +// On("MyMethod", 3, 3).Return(0). +// On("MyMethod", Anything, Anything).Return(0) +// Mock.On("MyMethod", 3, 3).Unset() func (c *Call) Unset() *Call { var unlockOnce sync.Once From a9e8aed1556e5c10230ce73deb847cbc4ba186d6 Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Sun, 23 Mar 2025 12:18:52 +0200 Subject: [PATCH 092/178] Remove mistakenly added .ci.gofmt.sh --- .github/workflows/main.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ded4f06b5..d21d98b55 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -47,5 +47,4 @@ jobs: with: go-version: stable - run: npm install -g mdsf-cli - - run: ./.ci.gofmt.sh - run: ./.ci.readme.fmt.sh From 33be8f984a1c39c021b03270d110629f3cda7853 Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Sun, 23 Mar 2025 12:20:44 +0200 Subject: [PATCH 093/178] Move to jobs.build --- .github/workflows/main.yml | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d21d98b55..2aed14548 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -15,8 +15,10 @@ jobs: uses: actions/setup-go@v5 with: go-version: ${{ matrix.go_version }} + - run: npm install -g mdsf-cli - run: ./.ci.gogenerate.sh - run: ./.ci.gofmt.sh + - run: ./.ci.readme.fmt.sh - run: ./.ci.govet.sh - run: go test -v -race ./... test: @@ -37,14 +39,3 @@ jobs: with: go-version: ${{ matrix.go_version }} - run: go test -v -race ./... - format: - name: Check formatting of code snippets in markdown files - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Setup Go - uses: actions/setup-go@v5 - with: - go-version: stable - - run: npm install -g mdsf-cli - - run: ./.ci.readme.fmt.sh From 75df9d50d4345d38921f361cdeed1478a2dcd12e Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Sun, 23 Mar 2025 12:40:01 +0200 Subject: [PATCH 094/178] Update mdsf --- .ci.readme.fmt.sh | 4 +++- .mdsf.json | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.ci.readme.fmt.sh b/.ci.readme.fmt.sh index 6f1f3a269..045cb5fb0 100755 --- a/.ci.readme.fmt.sh +++ b/.ci.readme.fmt.sh @@ -3,8 +3,10 @@ # Verify that the code snippets in README.md are formatted. # The tool https://github.com/hougesen/mdsf is used. -if [ -n "$(mdsf verify --config .mdsf.json README.md 2>&1)" ]; then +if [ -n "$(mdsf verify --config .mdsf.json --log-level error README.md 2>&1)" ]; then echo "Go code in the README.md is not formatted." echo "Did you forget to run 'mdsf format --config .mdsf.json README.md'?" + mdsf format --config .mdsf.json README.md + git diff exit 1 fi diff --git a/.mdsf.json b/.mdsf.json index 7617589ce..884bbbebf 100644 --- a/.mdsf.json +++ b/.mdsf.json @@ -1,5 +1,5 @@ { - "$schema": "https://raw.githubusercontent.com/hougesen/mdsf/main/schemas/v0.4.1/mdsf.schema.json", + "$schema": "https://raw.githubusercontent.com/hougesen/mdsf/main/schemas/v0.8.2/mdsf.schema.json", "format_finished_document": false, "languages": { "go": [ From b561f16e870ca4274851951ec25856a5109fd32e Mon Sep 17 00:00:00 2001 From: Bracken Dawson Date: Sun, 23 Mar 2025 18:33:47 +0100 Subject: [PATCH 095/178] Correct maintainers list arjunmahishi is actually only an approver, at the moment. --- MAINTAINERS.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS.md b/MAINTAINERS.md index cb9a39aba..362b14fa9 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -6,5 +6,11 @@ pull requests. * @boyan-soubachov * @dolmen * @MovieStoreGuy - * @arjunmahishi * @brackendawson + +## Approvers + +The individuals listed below are active in the project and have the ability to approve pull +requests. + + * @arjunmahishi From d0e0f4961bc2d74829b5a4a90ba6af14f3d201b2 Mon Sep 17 00:00:00 2001 From: Bracken Dawson Date: Sun, 23 Mar 2025 18:36:20 +0100 Subject: [PATCH 096/178] Propose Christophe Colombier (ccoVeille) as approver --- MAINTAINERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.md b/MAINTAINERS.md index 362b14fa9..120c46398 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -14,3 +14,4 @@ The individuals listed below are active in the project and have the ability to a requests. * @arjunmahishi + * @ccoVeille From e6575e05edbeeeea4a2fc0d73ba4cd091cd8276b Mon Sep 17 00:00:00 2001 From: Mike Auclair Date: Mon, 24 Mar 2025 14:24:41 -0400 Subject: [PATCH 097/178] Update mock.go --- mock/mock.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mock/mock.go b/mock/mock.go index 0feb48218..7712577af 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -942,8 +942,8 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { outputRenderers := []outputRenderer{} - for j := 0; j < maxArgCount; j++ { - i := j + for i := 0; i < maxArgCount; i++ { + i := i var actual, expected interface{} var actualFmt, expectedFmt func() string From 0b6039ed540bcb55b8599166c740622d0531c201 Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Wed, 30 Oct 2024 14:10:59 +0200 Subject: [PATCH 098/178] assert: remove deprecated build constraints --- assert/yaml/yaml_custom.go | 1 - assert/yaml/yaml_default.go | 1 - assert/yaml/yaml_fail.go | 1 - 3 files changed, 3 deletions(-) diff --git a/assert/yaml/yaml_custom.go b/assert/yaml/yaml_custom.go index baa0cc7d7..5a74c4f4d 100644 --- a/assert/yaml/yaml_custom.go +++ b/assert/yaml/yaml_custom.go @@ -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. // diff --git a/assert/yaml/yaml_default.go b/assert/yaml/yaml_default.go index b83c6cf64..0bae80e34 100644 --- a/assert/yaml/yaml_default.go +++ b/assert/yaml/yaml_default.go @@ -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. // diff --git a/assert/yaml/yaml_fail.go b/assert/yaml/yaml_fail.go index e78f7dfe6..8041803fd 100644 --- a/assert/yaml/yaml_fail.go +++ b/assert/yaml/yaml_fail.go @@ -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. // From 5ed1b903671b8e8243d234dd824391868d81f825 Mon Sep 17 00:00:00 2001 From: tsioftas Date: Thu, 3 Apr 2025 14:17:58 +0300 Subject: [PATCH 099/178] Update assert/assertions_test.go Co-authored-by: Bracken --- assert/assertions_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 8f0a0a958..a5e54b1e0 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -3240,7 +3240,7 @@ func TestErrorIs(t *testing.T) { err: nil, target: io.EOF, result: false, - resultErrMsg: "Expected error \"EOF\" but got nil.\n", + resultErrMsg: "Expected error with \"EOF\" in chain but got nil.\n", }, { err: io.EOF, From e7b18803494f0f174b66b59e473d097fa464bb11 Mon Sep 17 00:00:00 2001 From: tsioftas Date: Thu, 3 Apr 2025 14:20:14 +0300 Subject: [PATCH 100/178] update error message based on suggestion --- assert/assertions.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assert/assertions.go b/assert/assertions.go index 7aaa850a6..c0f1f68fd 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -2101,7 +2101,7 @@ func ErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool { if target != nil { expectedText = target.Error() if err == nil { - return Fail(t, fmt.Sprintf("Expected error %q but got nil.", expectedText), msgAndArgs...) + return Fail(t, fmt.Sprintf("Expected error with %q in chain but got nil.", expectedText), msgAndArgs...) } } From d5cd75acec87ebc41af613a3cc2a438d26a9f519 Mon Sep 17 00:00:00 2001 From: Archit Agarwal Date: Tue, 22 Apr 2025 23:33:01 +0530 Subject: [PATCH 101/178] update documentation of assert package to mention that all function return a bool value --- assert/doc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assert/doc.go b/assert/doc.go index 4953981d3..925cc69d1 100644 --- a/assert/doc.go +++ b/assert/doc.go @@ -1,5 +1,5 @@ // Package assert provides a set of comprehensive testing tools for use with the normal Go testing system. -// +// All functions in this package return a bool value indicating whether the test has passed. // # Example Usage // // The following is a complete example using assert in a standard test function: From 2a9c44b1d87607c362de484a7a2f7a14098530bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dud=C3=A1s=20=C3=81d=C3=A1m?= Date: Wed, 23 Apr 2025 14:31:40 +0000 Subject: [PATCH 102/178] fix Subset/NotSubset when calling with mixed input types (array/slice list with map subset) --- assert/assertions.go | 18 ++++++++++++++++-- assert/assertions_test.go | 2 ++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index 09feff854..0088d2748 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -1001,7 +1001,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...) } @@ -1025,6 +1025,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) @@ -1059,7 +1066,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...) } @@ -1083,6 +1090,13 @@ 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) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 9d27d1bfa..ec807ca2b 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -1142,6 +1142,7 @@ func TestSubsetNotSubset(t *testing.T) { "a": "x", "b": "y", }, true, `map["a":"x" "b":"y"] is a subset of map["a":"x" "b":"y" "c":"z"]`}, + {[]string{"a", "b", "c"}, map[string]int{"a": 1, "c": 3}, true, `map["a":'\x01' "c":'\x03'] is a subset of ["a" "b" "c"]`}, // cases that are expected not to contain {[]string{"hello", "world"}, []string{"hello", "testify"}, false, `[]string{"hello", "world"} does not contain "testify"`}, @@ -1163,6 +1164,7 @@ func TestSubsetNotSubset(t *testing.T) { "b": "y", "c": "z", }, false, `map[string]string{"a":"x", "b":"y"} does not contain map[string]string{"a":"x", "b":"y", "c":"z"}`}, + {[]string{"a", "b", "c"}, map[string]int{"c": 3, "d": 4}, false, `[]string{"a", "b", "c"} does not contain "d"`}, } for _, c := range cases { From e32ceae4ea31a90929ef3585f102451cb26661e3 Mon Sep 17 00:00:00 2001 From: Archit Agarwal Date: Tue, 29 Apr 2025 17:08:34 +0530 Subject: [PATCH 103/178] Update assert/doc.go Co-authored-by: ccoVeille <3875889+ccoVeille@users.noreply.github.com> --- assert/doc.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/assert/doc.go b/assert/doc.go index 925cc69d1..b39ebdbfd 100644 --- a/assert/doc.go +++ b/assert/doc.go @@ -1,6 +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 test has passed. -// # Example Usage + // + // # Example Usage // // The following is a complete example using assert in a standard test function: // From 992db2b883ecca754085f89e543c66e38edbf97c Mon Sep 17 00:00:00 2001 From: Archit Agarwal Date: Tue, 29 Apr 2025 17:10:00 +0530 Subject: [PATCH 104/178] upadte doc --- assert/doc.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assert/doc.go b/assert/doc.go index b39ebdbfd..f0f186a65 100644 --- a/assert/doc.go +++ b/assert/doc.go @@ -2,8 +2,8 @@ // // # Note // All functions in this package return a bool value indicating whether the test has passed. - // - // # Example Usage +// +// # Example Usage // // The following is a complete example using assert in a standard test function: // From 0c9a9e02f82c4835d66d16781b23ba6e93d94bd7 Mon Sep 17 00:00:00 2001 From: Archit Agarwal Date: Fri, 2 May 2025 13:01:29 +0530 Subject: [PATCH 105/178] Update assert/doc.go Co-authored-by: ccoVeille <3875889+ccoVeille@users.noreply.github.com> --- assert/doc.go | 1 + 1 file changed, 1 insertion(+) diff --git a/assert/doc.go b/assert/doc.go index f0f186a65..6abab4a49 100644 --- a/assert/doc.go +++ b/assert/doc.go @@ -1,6 +1,7 @@ // 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 test has passed. // // # Example Usage From d0c350a872fb8dfa57792280e64d3bc27be90043 Mon Sep 17 00:00:00 2001 From: Archit Agarwal Date: Wed, 7 May 2025 17:25:57 +0530 Subject: [PATCH 106/178] Update assert/doc.go Co-authored-by: Bracken --- assert/doc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assert/doc.go b/assert/doc.go index 6abab4a49..a0b953aa5 100644 --- a/assert/doc.go +++ b/assert/doc.go @@ -2,7 +2,7 @@ // // # Note // -// All functions in this package return a bool value indicating whether the test has passed. +// All functions in this package return a bool value indicating whether the assertion has passed. // // # Example Usage // From 121ddb9b0e12e75072fd14456ed6fe0a19c1477b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dud=C3=A1s=20=C3=81d=C3=A1m?= Date: Wed, 7 May 2025 00:26:09 +0000 Subject: [PATCH 107/178] clarify behavior of Subset/NotSubset when passing maps --- assert/assertion_format.go | 17 ++++++++++++----- assert/assertion_forward.go | 34 ++++++++++++++++++++++++---------- assert/assertions.go | 17 ++++++++++++----- require/require.go | 34 ++++++++++++++++++++++++---------- require/require_forward.go | 34 ++++++++++++++++++++++++---------- 5 files changed, 96 insertions(+), 40 deletions(-) diff --git a/assert/assertion_format.go b/assert/assertion_format.go index 190634165..53c184c87 100644 --- a/assert/assertion_format.go +++ b/assert/assertion_format.go @@ -693,12 +693,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 +785,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() diff --git a/assert/assertion_forward.go b/assert/assertion_forward.go index 21629087b..938bd2496 100644 --- a/assert/assertion_forward.go +++ b/assert/assertion_forward.go @@ -1378,12 +1378,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 +1394,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 +1562,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 +1578,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() diff --git a/assert/assertions.go b/assert/assertions.go index 0088d2748..30252060c 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -982,11 +982,15 @@ func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) } -// 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() @@ -1046,12 +1050,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() diff --git a/require/require.go b/require/require.go index d8921950d..b78c5cf81 100644 --- a/require/require.go +++ b/require/require.go @@ -1745,12 +1745,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 +1764,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 +1977,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 +1996,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() diff --git a/require/require_forward.go b/require/require_forward.go index 1bd87304f..b74150f2c 100644 --- a/require/require_forward.go +++ b/require/require_forward.go @@ -1379,12 +1379,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 +1395,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 +1563,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 +1579,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() From c2116b41944a93870cbf8d8b207523ec2e98efc8 Mon Sep 17 00:00:00 2001 From: ccoVeille <3875889+ccoVeille@users.noreply.github.com> Date: Thu, 8 May 2025 15:44:35 +0200 Subject: [PATCH 108/178] Improve ErrorAs failure message when error is nil Before: Should be in error chain: expected: *assert.customError in chain: After: An error is expected but got nil. expected: *assert.customError The message `An error is expected but got nil.` is the one already reported by `assert.Error` --- assert/assertions.go | 8 +++++++- assert/assertions_test.go | 5 ++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index 0ed1eed09..3353b33a2 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -2202,11 +2202,17 @@ func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{ return true } + expectedText := reflect.ValueOf(target).Elem().Type().String() + if err == nil { + return Fail(t, fmt.Sprintf("An error is expected but got nil.\n"+ + "expected: %s", expectedText), msgAndArgs...) + } + chain := buildErrorChainString(err, true) return Fail(t, fmt.Sprintf("Should be in error chain:\n"+ "expected: %s\n"+ - "in chain: %s", reflect.ValueOf(target).Elem().Type(), chain, + "in chain: %s", expectedText, chain, ), msgAndArgs...) } diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 16dc2587d..77a151856 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -3402,9 +3402,8 @@ func TestErrorAs(t *testing.T) { err: nil, result: false, resultErrMsg: "" + - "Should be in error chain:\n" + - "expected: *assert.customError\n" + - "in chain: \n", + "An error is expected but got nil.\n" + + `expected: *assert.customError` + "\n", }, { err: fmt.Errorf("abc: %w", errors.New("def")), From 9bcca2f9508cb4df8f3f2bf8186c4c56add14179 Mon Sep 17 00:00:00 2001 From: ccoVeille <3875889+ccoVeille@users.noreply.github.com> Date: Thu, 8 May 2025 20:56:01 +0200 Subject: [PATCH 109/178] Format assertions files with gofumpt --- assert/assertions.go | 20 ++---------- assert/assertions_test.go | 66 +++++++-------------------------------- 2 files changed, 14 insertions(+), 72 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index 3353b33a2..c1bb0fb08 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -212,7 +212,6 @@ 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 file string var line int @@ -493,7 +492,6 @@ func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) } return true - } // validateEqualArgs checks whether provided arguments can be safely used in the @@ -548,7 +546,7 @@ 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...)) } @@ -567,7 +565,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) @@ -628,7 +626,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 @@ -683,7 +680,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. @@ -733,7 +729,6 @@ 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 @@ -774,7 +769,6 @@ 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 @@ -793,7 +787,6 @@ func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { } return pass - } // getLen tries to get the length of an object. @@ -837,7 +830,6 @@ func True(t TestingT, value bool, msgAndArgs ...interface{}) bool { } return true - } // False asserts that the specified value is false. @@ -852,7 +844,6 @@ func False(t TestingT, value bool, msgAndArgs ...interface{}) bool { } return true - } // NotEqual asserts that the specified values are NOT equal. @@ -875,7 +866,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 @@ -898,7 +888,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 { @@ -933,7 +922,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 @@ -956,7 +944,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 @@ -979,7 +966,6 @@ func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) } return true - } // Subset asserts that the list (array, slice, or map) contains all elements @@ -1704,7 +1690,6 @@ func matchRegexp(rx interface{}, str interface{}) bool { default: return r.MatchString(fmt.Sprint(v)) } - } // Regexp asserts that a specified regexp matches a string. @@ -1740,7 +1725,6 @@ func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interf } return !match - } // Zero asserts that i is the zero value for its type. diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 77a151856..ee0e0512e 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -91,15 +91,13 @@ type AssertionTesterInterface interface { } // AssertionTesterConformingObject is an object that conforms to the AssertionTesterInterface interface -type AssertionTesterConformingObject struct { -} +type AssertionTesterConformingObject struct{} func (a *AssertionTesterConformingObject) TestMethod() { } // AssertionTesterNonConformingObject is an object that does not conform to the AssertionTesterInterface interface -type AssertionTesterNonConformingObject struct { -} +type AssertionTesterNonConformingObject struct{} func TestObjectsAreEqual(t *testing.T) { cases := []struct { @@ -132,7 +130,6 @@ func TestObjectsAreEqual(t *testing.T) { if res != c.result { t.Errorf("ObjectsAreEqual(%#v, %#v) should return %#v", c.expected, c.actual, c.result) } - }) } } @@ -208,7 +205,6 @@ type S6 struct { } func TestObjectsExportedFieldsAreEqual(t *testing.T) { - intValue := 1 cases := []struct { @@ -277,7 +273,6 @@ func TestObjectsExportedFieldsAreEqual(t *testing.T) { if res != c.result { t.Errorf("ObjectsExportedFieldsAreEqual(%#v, %#v) should return %#v", c.expected, c.actual, c.result) } - }) } } @@ -328,11 +323,15 @@ func TestCopyExportedFields(t *testing.T) { }}, }, { - input: S4{[]*Nested{ - {1, 2}}, + input: S4{ + []*Nested{ + {1, 2}, + }, }, - expected: S4{[]*Nested{ - {1, nil}}, + expected: S4{ + []*Nested{ + {1, nil}, + }, }, }, { @@ -516,11 +515,9 @@ func TestEqualExportedValues(t *testing.T) { } }) } - } func TestImplements(t *testing.T) { - mockT := new(testing.T) if !Implements(mockT, (*AssertionTesterInterface)(nil), new(AssertionTesterConformingObject)) { @@ -532,11 +529,9 @@ func TestImplements(t *testing.T) { if Implements(mockT, (*AssertionTesterInterface)(nil), nil) { t.Error("Implements method should return false: nil does not implement AssertionTesterInterface") } - } func TestNotImplements(t *testing.T) { - mockT := new(testing.T) if !NotImplements(mockT, (*AssertionTesterInterface)(nil), new(AssertionTesterNonConformingObject)) { @@ -548,11 +543,9 @@ func TestNotImplements(t *testing.T) { if NotImplements(mockT, (*AssertionTesterInterface)(nil), nil) { t.Error("NotImplements method should return false: nil can't be checked to be implementing AssertionTesterInterface or not") } - } func TestIsType(t *testing.T) { - mockT := new(testing.T) if !IsType(mockT, new(AssertionTesterConformingObject), new(AssertionTesterConformingObject)) { @@ -561,7 +554,6 @@ func TestIsType(t *testing.T) { if IsType(mockT, new(AssertionTesterConformingObject), new(AssertionTesterNonConformingObject)) { t.Error("IsType should return false: AssertionTesterConformingObject is not the same type as AssertionTesterNonConformingObject") } - } func TestEqual(t *testing.T) { @@ -610,7 +602,6 @@ func ptr(i int) *int { } func TestSame(t *testing.T) { - mockT := new(testing.T) if Same(mockT, ptr(1), ptr(1)) { @@ -629,7 +620,6 @@ func TestSame(t *testing.T) { } func TestNotSame(t *testing.T) { - mockT := new(testing.T) if !NotSame(mockT, ptr(1), ptr(1)) { @@ -814,7 +804,6 @@ func TestFormatUnequalValues(t *testing.T) { } func TestNotNil(t *testing.T) { - mockT := new(testing.T) if !NotNil(mockT, new(AssertionTesterConformingObject)) { @@ -826,11 +815,9 @@ func TestNotNil(t *testing.T) { if NotNil(mockT, (*struct{})(nil)) { t.Error("NotNil should return false: object is (*struct{})(nil)") } - } func TestNil(t *testing.T) { - mockT := new(testing.T) if !Nil(mockT, nil) { @@ -842,11 +829,9 @@ func TestNil(t *testing.T) { if Nil(mockT, new(AssertionTesterConformingObject)) { t.Error("Nil should return false: object is not nil") } - } func TestTrue(t *testing.T) { - mockT := new(testing.T) if !True(mockT, true) { @@ -855,11 +840,9 @@ func TestTrue(t *testing.T) { if True(mockT, false) { t.Error("True should return false") } - } func TestFalse(t *testing.T) { - mockT := new(testing.T) if !False(mockT, false) { @@ -868,11 +851,9 @@ func TestFalse(t *testing.T) { if False(mockT, true) { t.Error("False should return false") } - } func TestExactly(t *testing.T) { - mockT := new(testing.T) a := float32(1) @@ -903,7 +884,6 @@ func TestExactly(t *testing.T) { } func TestNotEqual(t *testing.T) { - mockT := new(testing.T) cases := []struct { @@ -986,7 +966,6 @@ func TestNotEqualValues(t *testing.T) { } func TestContainsNotContains(t *testing.T) { - type A struct { Name, Value string } @@ -1169,7 +1148,6 @@ func TestSubsetNotSubset(t *testing.T) { for _, c := range cases { t.Run("SubSet: "+c.message, func(t *testing.T) { - mockT := new(mockTestingT) res := Subset(mockT, c.list, c.subset) @@ -1216,7 +1194,6 @@ func TestNotSubsetNil(t *testing.T) { } func Test_containsElement(t *testing.T) { - list1 := []string{"Foo", "Bar"} list2 := []int{1, 2} simpleMap := map[interface{}]interface{}{"Foo": "Bar"} @@ -1447,11 +1424,9 @@ func TestCondition(t *testing.T) { if Condition(mockT, func() bool { return false }, "Lie") { t.Error("Condition should return false") } - } func TestDidPanic(t *testing.T) { - const panicMsg = "Panic!" if funcDidPanic, msg, _ := didPanic(func() { @@ -1470,11 +1445,9 @@ func TestDidPanic(t *testing.T) { }); funcDidPanic { t.Error("didPanic should return false") } - } func TestPanics(t *testing.T) { - mockT := new(testing.T) if !Panics(mockT, func() { @@ -1487,11 +1460,9 @@ func TestPanics(t *testing.T) { }) { t.Error("Panics should return false") } - } func TestPanicsWithValue(t *testing.T) { - mockT := new(testing.T) if !PanicsWithValue(mockT, "Panic!", func() { @@ -1519,7 +1490,6 @@ func TestPanicsWithValue(t *testing.T) { } func TestPanicsWithError(t *testing.T) { - mockT := new(testing.T) if !PanicsWithError(mockT, "panic", func() { @@ -1547,7 +1517,6 @@ func TestPanicsWithError(t *testing.T) { } func TestNotPanics(t *testing.T) { - mockT := new(testing.T) if !NotPanics(mockT, func() { @@ -1560,11 +1529,9 @@ func TestNotPanics(t *testing.T) { }) { t.Error("NotPanics should return false") } - } func TestNoError(t *testing.T) { - mockT := new(testing.T) // start with a nil error @@ -1595,7 +1562,6 @@ type customError struct{} func (*customError) Error() string { return "fail" } func TestError(t *testing.T) { - mockT := new(testing.T) // start with a nil error @@ -1659,7 +1625,6 @@ func TestErrorContains(t *testing.T) { } func Test_isEmpty(t *testing.T) { - chWithValue := make(chan struct{}, 1) chWithValue <- struct{}{} @@ -1686,7 +1651,6 @@ func Test_isEmpty(t *testing.T) { } func TestEmpty(t *testing.T) { - mockT := new(testing.T) chWithValue := make(chan struct{}, 1) chWithValue <- struct{}{} @@ -1731,7 +1695,6 @@ func TestEmpty(t *testing.T) { } func TestNotEmpty(t *testing.T) { - mockT := new(testing.T) chWithValue := make(chan struct{}, 1) chWithValue <- struct{}{} @@ -1845,7 +1808,6 @@ func TestLen(t *testing.T) { } func TestWithinDuration(t *testing.T) { - mockT := new(testing.T) a := time.Now() b := a.Add(10 * time.Second) @@ -1864,7 +1826,6 @@ func TestWithinDuration(t *testing.T) { } func TestWithinRange(t *testing.T) { - mockT := new(testing.T) n := time.Now() s := n.Add(-time.Second) @@ -2071,7 +2032,6 @@ func TestInEpsilon(t *testing.T) { for _, tc := range cases { False(t, InEpsilon(mockT, tc.a, tc.b, tc.epsilon, "Expected %V and %V to have a relative difference of %v", tc.a, tc.b, tc.epsilon)) } - } func TestInEpsilonSlice(t *testing.T) { @@ -2673,8 +2633,7 @@ func TestFailNowWithPlainTestingT(t *testing.T) { }, "should panic since mockT is missing FailNow()") } -type mockFailNowTestingT struct { -} +type mockFailNowTestingT struct{} func (m *mockFailNowTestingT) Errorf(format string, args ...interface{}) {} @@ -2689,7 +2648,7 @@ func TestFailNowWithFullTestingT(t *testing.T) { } func TestBytesEqual(t *testing.T) { - var cases = []struct { + cases := []struct { a, b []byte }{ {make([]byte, 2), make([]byte, 2)}, @@ -3154,7 +3113,6 @@ func Test_validateEqualArgs(t *testing.T) { } func Test_truncatingFormat(t *testing.T) { - original := strings.Repeat("a", bufio.MaxScanTokenSize-102) result := truncatingFormat(original) Equal(t, fmt.Sprintf("%#v", original), result, "string should not be truncated") From 9fc264e324c587f876d486ce8339f45784a6c3a1 Mon Sep 17 00:00:00 2001 From: Bart Venter <72999113+bartventer@users.noreply.github.com> Date: Thu, 22 May 2025 11:45:11 +0200 Subject: [PATCH 110/178] assert: add IsNotType (#1730) Add the `IsNotType` assertion, which is the inverse of the existing `IsType` assertion. It allows users to assert that an object is not of a specific type. Additionally, minor documentation improvements were made. ## Summary This PR adds a new assertion function, `IsNotType`, to the `testify/assert` package. It complements the existing `IsType` function by providing a way to assert that an object is not of a specific type. ## Changes * Added the `IsNotType` function to the `assert` package. * Wrote unit tests for `IsNotType` to ensure correctness. * Updated documentation to include examples and usage for `IsNotType`. ## Motivation The `testify/assert` package already provides an `IsType` function to check if an object is of a specific type. However, there was no built-in way to assert that an object is **not** of a specific type. This PR addresses that gap by introducing the `IsNotType` function, improving the library's completeness and usability. ## Example usage ```go assert.IsNotType(t, &MyStruct{}, actualObject) ``` ## Related issues _N/A_ --- assert/assertion_format.go | 12 +++++++++++ assert/assertion_forward.go | 24 ++++++++++++++++++++++ assert/assertions.go | 27 ++++++++++++++++++++----- assert/assertions_test.go | 12 +++++++++++ require/forward_requirements_test.go | 12 +++++++++++ require/require.go | 30 ++++++++++++++++++++++++++++ require/require_forward.go | 24 ++++++++++++++++++++++ 7 files changed, 136 insertions(+), 5 deletions(-) diff --git a/assert/assertion_format.go b/assert/assertion_format.go index a62ac200a..714404125 100644 --- a/assert/assertion_format.go +++ b/assert/assertion_format.go @@ -436,7 +436,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() diff --git a/assert/assertion_forward.go b/assert/assertion_forward.go index 675e5f627..38e253ebb 100644 --- a/assert/assertion_forward.go +++ b/assert/assertion_forward.go @@ -864,7 +864,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() @@ -873,6 +895,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() diff --git a/assert/assertions.go b/assert/assertions.go index c1bb0fb08..bdead180f 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -454,17 +454,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 %T, but was %T", expectedType, 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. diff --git a/assert/assertions_test.go b/assert/assertions_test.go index ee0e0512e..f3d41a5ac 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -556,6 +556,18 @@ func TestIsType(t *testing.T) { } } +func TestNotIsType(t *testing.T) { + + mockT := new(testing.T) + + if !IsNotType(mockT, new(AssertionTesterConformingObject), new(AssertionTesterNonConformingObject)) { + t.Error("NotIsType should return true: AssertionTesterConformingObject is not the same type as AssertionTesterNonConformingObject") + } + if IsNotType(mockT, new(AssertionTesterConformingObject), new(AssertionTesterConformingObject)) { + t.Error("NotIsType should return false: AssertionTesterConformingObject is the same type as AssertionTesterConformingObject") + } +} + func TestEqual(t *testing.T) { type myType string diff --git a/require/forward_requirements_test.go b/require/forward_requirements_test.go index 8fbcc1530..99515daa3 100644 --- a/require/forward_requirements_test.go +++ b/require/forward_requirements_test.go @@ -19,6 +19,18 @@ func TestImplementsWrapper(t *testing.T) { } } +func TestIsNotTypeWrapper(t *testing.T) { + require := New(t) + require.IsNotType(new(AssertionTesterNonConformingObject), new(AssertionTesterConformingObject)) + + mockT := new(MockT) + mockRequire := New(mockT) + mockRequire.IsNotType(new(AssertionTesterConformingObject), new(AssertionTesterConformingObject)) + if !mockT.Failed { + t.Error("Check should fail") + } +} + func TestIsTypeWrapper(t *testing.T) { require := New(t) require.IsType(new(AssertionTesterConformingObject), new(AssertionTesterConformingObject)) diff --git a/require/require.go b/require/require.go index 1f597c8a5..6cd133417 100644 --- a/require/require.go +++ b/require/require.go @@ -1093,7 +1093,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() @@ -1105,6 +1133,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() diff --git a/require/require_forward.go b/require/require_forward.go index 0df63920e..f6192dfea 100644 --- a/require/require_forward.go +++ b/require/require_forward.go @@ -865,7 +865,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() @@ -874,6 +896,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() From af716f8bffb6c42f4d996f0776b43ffcf33b4bba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Thu, 22 May 2025 11:38:24 +0200 Subject: [PATCH 111/178] CI: fix shebang in .ci.*.sh scripts Fix shebang in .ci.*.sh scripts to ease running on platforms where bash is not in /bin/bash (ex: MacOS). --- .ci.gofmt.sh | 2 +- .ci.gogenerate.sh | 2 +- .ci.govet.sh | 2 +- .ci.readme.fmt.sh | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.ci.gofmt.sh b/.ci.gofmt.sh index 3f2e5d329..1ac21ef10 100755 --- a/.ci.gofmt.sh +++ b/.ci.gofmt.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash if [ -n "$(gofmt -l .)" ]; then echo "Go code is not formatted:" diff --git a/.ci.gogenerate.sh b/.ci.gogenerate.sh index 3fc73fea7..5b5642094 100755 --- a/.ci.gogenerate.sh +++ b/.ci.gogenerate.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # If GOMOD is defined we are running with Go Modules enabled, either # automatically or via the GO111MODULE=on environment variable. Codegen only diff --git a/.ci.govet.sh b/.ci.govet.sh index 77aeb5c47..9bdf4519b 100755 --- a/.ci.govet.sh +++ b/.ci.govet.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/.ci.readme.fmt.sh b/.ci.readme.fmt.sh index 045cb5fb0..b3d6a1d06 100755 --- a/.ci.readme.fmt.sh +++ b/.ci.readme.fmt.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Verify that the code snippets in README.md are formatted. # The tool https://github.com/hougesen/mdsf is used. From 559d23ae666dd2dad6bc00ca82e986caff003f5b Mon Sep 17 00:00:00 2001 From: ccoVeille <3875889+ccoVeille@users.noreply.github.com> Date: Sat, 17 May 2025 16:28:06 +0200 Subject: [PATCH 112/178] check test failure message for Empty and NotEmpty Only the tests are updated, code is unchanged. Previously, the tests were checking only the result of the asserter. Using captureTestingT helper allows to check the error message --- assert/assertions_test.go | 198 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index f3d41a5ac..05c81b9e1 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -1704,6 +1704,142 @@ func TestEmpty(t *testing.T) { False(t, Empty(mockT, TString("abc")), "non-empty aliased string is empty") False(t, Empty(mockT, xP), "ptr to non-nil value is not empty") False(t, Empty(mockT, [1]int{42}), "array is not state") + + // error messages validation + tests := []struct { + name string + value interface{} + expectedResult bool + expectedErrMsg string + }{ + { + name: "Non Empty string is not empty", + value: "something", + expectedResult: false, + expectedErrMsg: "Should be empty, but was something\n", + }, + { + name: "Non nil object is not empty", + value: errors.New("something"), + expectedResult: false, + expectedErrMsg: "Should be empty, but was something\n", + }, + { + name: "Non empty string array is not empty", + value: []string{"something"}, + expectedResult: false, + expectedErrMsg: "Should be empty, but was [something]\n", + }, + { + name: "Non-zero int value is not empty", + value: 1, + expectedResult: false, + expectedErrMsg: "Should be empty, but was 1\n", + }, + { + name: "True value is not empty", + value: true, + expectedResult: false, + expectedErrMsg: "Should be empty, but was true\n", + }, + { + name: "Channel with values is not empty", + value: chWithValue, + expectedResult: false, + expectedErrMsg: fmt.Sprintf("Should be empty, but was %v\n", chWithValue), + }, + { + name: "struct with initialized values is empty", + value: TStruct{x: 1}, + expectedResult: false, + expectedErrMsg: "Should be empty, but was {1}\n", + }, + { + name: "non-empty aliased string is empty", + value: TString("abc"), + expectedResult: false, + expectedErrMsg: "Should be empty, but was abc\n", + }, + { + name: "ptr to non-nil value is not empty", + value: xP, + expectedResult: false, + expectedErrMsg: fmt.Sprintf("Should be empty, but was %p\n", xP), + }, + { + name: "array is not state", + value: [1]int{42}, + expectedResult: false, + expectedErrMsg: "Should be empty, but was [42]\n", + }, + + // Here are some edge cases + { + name: "string with only spaces is not empty", + value: " ", + expectedResult: false, + expectedErrMsg: "Should be empty, but was \n", // TODO FIX THIS strange error message + }, + { + name: "string with a line feed is not empty", + value: "\n", + expectedResult: false, + // TODO This is the exact same error message as for an empty string + expectedErrMsg: "Should be empty, but was \n", // TODO FIX THIS strange error message + }, + { + name: "string with only tabulation and lines feed is not empty", + value: "\n\t\n", + expectedResult: false, + // TODO The line feeds and tab are not helping to spot what is expected + expectedErrMsg: "" + // this syntax is used to show how errors are reported. + "Should be empty, but was \n" + + "\t\n", + }, + { + name: "string with trailing lines feed is not empty", + value: "foo\n\n", + expectedResult: false, + // TODO it's not clear if one or two lines feed are expected + expectedErrMsg: "Should be empty, but was foo\n\n", + }, + { + name: "string with leading and trailing tabulation and lines feed is not empty", + value: "\n\nfoo\t\n\t\n", + expectedResult: false, + // TODO The line feeds and tab are not helping to figure what is expected + expectedErrMsg: "" + + "Should be empty, but was \n" + + "\n" + + "foo\t\n" + + "\t\n", + }, + + { + name: "non-printable character is not empty", + value: "\u00a0", // NO-BREAK SPACE UNICODE CHARACTER + expectedResult: false, + // TODO here you cannot figure out what is expected + expectedErrMsg: "Should be empty, but was \u00a0\n", + }, + + // Here we are testing there is no error message on success + { + name: "Empty string is empty", + value: "", + expectedResult: true, + expectedErrMsg: "", + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + mockCT := new(captureTestingT) + res := Empty(mockCT, tt.value) + mockCT.checkResultAndErrMsg(t, res, tt.expectedResult, tt.expectedErrMsg) + }) + } } func TestNotEmpty(t *testing.T) { @@ -1726,6 +1862,68 @@ func TestNotEmpty(t *testing.T) { True(t, NotEmpty(mockT, true), "True value is not empty") True(t, NotEmpty(mockT, chWithValue), "Channel with values is not empty") True(t, NotEmpty(mockT, [1]int{42}), "array is not state") + + // error messages validation + tests := []struct { + name string + value interface{} + expectedResult bool + expectedErrMsg string + }{ + { + name: "Empty string is empty", + value: "", + expectedResult: false, + expectedErrMsg: `Should NOT be empty, but was ` + "\n", // TODO FIX THIS strange error message + }, + { + name: "Nil is empty", + value: nil, + expectedResult: false, + expectedErrMsg: "Should NOT be empty, but was \n", + }, + { + name: "Empty string array is empty", + value: []string{}, + expectedResult: false, + expectedErrMsg: "Should NOT be empty, but was []\n", + }, + { + name: "Zero int value is empty", + value: 0, + expectedResult: false, + expectedErrMsg: "Should NOT be empty, but was 0\n", + }, + { + name: "False value is empty", + value: false, + expectedResult: false, + expectedErrMsg: "Should NOT be empty, but was false\n", + }, + { + name: "array is state", + value: [1]int{}, + expectedResult: false, + expectedErrMsg: "Should NOT be empty, but was [0]\n", + }, + + // Here we are testing there is no error message on success + { + name: "Non Empty string is not empty", + value: "something", + expectedResult: true, + expectedErrMsg: "", + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + mockCT := new(captureTestingT) + res := NotEmpty(mockCT, tt.value) + mockCT.checkResultAndErrMsg(t, tt.expectedResult, res, tt.expectedErrMsg) + }) + } } func Test_getLen(t *testing.T) { From 603c2a0348bdd2ed3b86a1b9cdf12984b6c48c55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Fri, 23 May 2025 16:05:02 +0200 Subject: [PATCH 113/178] assert,require: enable parallel testing on (almost) all top tests Enable parallel testing for almost all tests in packages 'assert' and 'require' by calling t.Parallel() as the first line of the test. A few tests are incompatible and will be fixed separately. They are marked with a FIXME. Incompatible tests: TestFileExists, TestNoFileExists, TestDirExists, TestNoDirExists. Before: $ go test -count=10 ./assert ./require ok github.com/stretchr/testify/assert 7.575s ok github.com/stretchr/testify/require 1.501s After: $ go test -count=10 ./assert ./require ok github.com/stretchr/testify/assert 1.703s ok github.com/stretchr/testify/require 1.245s --- assert/assertion_compare_test.go | 22 +++ assert/assertion_order_test.go | 10 ++ assert/assertions_test.go | 221 +++++++++++++++++++++++++++ assert/forward_assertions_test.go | 91 +++++++++++ assert/http_assertions_test.go | 18 +++ require/forward_requirements_test.go | 88 +++++++++++ require/requirements_test.go | 75 +++++++++ 7 files changed, 525 insertions(+) diff --git a/assert/assertion_compare_test.go b/assert/assertion_compare_test.go index bf6b8160b..d68407a02 100644 --- a/assert/assertion_compare_test.go +++ b/assert/assertion_compare_test.go @@ -10,6 +10,8 @@ import ( ) func TestCompare(t *testing.T) { + t.Parallel() + type customString string type customInt int type customInt8 int8 @@ -127,6 +129,8 @@ func callerName(skip int) string { } func TestGreater(t *testing.T) { + t.Parallel() + mockT := new(testing.T) if !Greater(mockT, 2, 1) { @@ -171,6 +175,8 @@ func TestGreater(t *testing.T) { } func TestGreaterOrEqual(t *testing.T) { + t.Parallel() + mockT := new(testing.T) if !GreaterOrEqual(mockT, 2, 1) { @@ -215,6 +221,8 @@ func TestGreaterOrEqual(t *testing.T) { } func TestLess(t *testing.T) { + t.Parallel() + mockT := new(testing.T) if !Less(mockT, 1, 2) { @@ -259,6 +267,8 @@ func TestLess(t *testing.T) { } func TestLessOrEqual(t *testing.T) { + t.Parallel() + mockT := new(testing.T) if !LessOrEqual(mockT, 1, 2) { @@ -303,6 +313,8 @@ func TestLessOrEqual(t *testing.T) { } func TestPositive(t *testing.T) { + t.Parallel() + mockT := new(testing.T) if !Positive(mockT, 1) { @@ -342,6 +354,8 @@ func TestPositive(t *testing.T) { } func TestNegative(t *testing.T) { + t.Parallel() + mockT := new(testing.T) if !Negative(mockT, -1) { @@ -381,6 +395,8 @@ func TestNegative(t *testing.T) { } func Test_compareTwoValuesDifferentValuesTypes(t *testing.T) { + t.Parallel() + mockT := new(testing.T) for _, currCase := range []struct { @@ -399,6 +415,8 @@ func Test_compareTwoValuesDifferentValuesTypes(t *testing.T) { } func Test_compareTwoValuesNotComparableValues(t *testing.T) { + t.Parallel() + mockT := new(testing.T) type CompareStruct struct { @@ -418,6 +436,8 @@ func Test_compareTwoValuesNotComparableValues(t *testing.T) { } func Test_compareTwoValuesCorrectCompareResult(t *testing.T) { + t.Parallel() + mockT := new(testing.T) for _, currCase := range []struct { @@ -438,6 +458,8 @@ func Test_compareTwoValuesCorrectCompareResult(t *testing.T) { } func Test_containsValue(t *testing.T) { + t.Parallel() + for _, currCase := range []struct { values []compareResult value compareResult diff --git a/assert/assertion_order_test.go b/assert/assertion_order_test.go index eefe06127..273333065 100644 --- a/assert/assertion_order_test.go +++ b/assert/assertion_order_test.go @@ -6,6 +6,8 @@ import ( ) func TestIsIncreasing(t *testing.T) { + t.Parallel() + mockT := new(testing.T) if !IsIncreasing(mockT, []int{1, 2}) { @@ -51,6 +53,8 @@ func TestIsIncreasing(t *testing.T) { } func TestIsNonIncreasing(t *testing.T) { + t.Parallel() + mockT := new(testing.T) if !IsNonIncreasing(mockT, []int{2, 1}) { @@ -96,6 +100,8 @@ func TestIsNonIncreasing(t *testing.T) { } func TestIsDecreasing(t *testing.T) { + t.Parallel() + mockT := new(testing.T) if !IsDecreasing(mockT, []int{2, 1}) { @@ -141,6 +147,8 @@ func TestIsDecreasing(t *testing.T) { } func TestIsNonDecreasing(t *testing.T) { + t.Parallel() + mockT := new(testing.T) if !IsNonDecreasing(mockT, []int{1, 2}) { @@ -186,6 +194,8 @@ func TestIsNonDecreasing(t *testing.T) { } func TestOrderingMsgAndArgsForwarding(t *testing.T) { + t.Parallel() + msgAndArgs := []interface{}{"format %s %x", "this", 0xc001} expectedOutput := "format this c001\n" collection := []int{1, 2, 1} diff --git a/assert/assertions_test.go b/assert/assertions_test.go index f3d41a5ac..f3b8ddae0 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -100,6 +100,8 @@ func (a *AssertionTesterConformingObject) TestMethod() { type AssertionTesterNonConformingObject struct{} func TestObjectsAreEqual(t *testing.T) { + t.Parallel() + cases := []struct { expected interface{} actual interface{} @@ -135,6 +137,8 @@ func TestObjectsAreEqual(t *testing.T) { } func TestObjectsAreEqualValues(t *testing.T) { + t.Parallel() + now := time.Now() cases := []struct { @@ -205,6 +209,8 @@ type S6 struct { } func TestObjectsExportedFieldsAreEqual(t *testing.T) { + t.Parallel() + intValue := 1 cases := []struct { @@ -278,6 +284,8 @@ func TestObjectsExportedFieldsAreEqual(t *testing.T) { } func TestCopyExportedFields(t *testing.T) { + t.Parallel() + intValue := 1 cases := []struct { @@ -365,6 +373,8 @@ func TestCopyExportedFields(t *testing.T) { } func TestEqualExportedValues(t *testing.T) { + t.Parallel() + cases := []struct { value1 interface{} value2 interface{} @@ -518,6 +528,8 @@ func TestEqualExportedValues(t *testing.T) { } func TestImplements(t *testing.T) { + t.Parallel() + mockT := new(testing.T) if !Implements(mockT, (*AssertionTesterInterface)(nil), new(AssertionTesterConformingObject)) { @@ -532,6 +544,8 @@ func TestImplements(t *testing.T) { } func TestNotImplements(t *testing.T) { + t.Parallel() + mockT := new(testing.T) if !NotImplements(mockT, (*AssertionTesterInterface)(nil), new(AssertionTesterNonConformingObject)) { @@ -546,6 +560,8 @@ func TestNotImplements(t *testing.T) { } func TestIsType(t *testing.T) { + t.Parallel() + mockT := new(testing.T) if !IsType(mockT, new(AssertionTesterConformingObject), new(AssertionTesterConformingObject)) { @@ -557,6 +573,7 @@ func TestIsType(t *testing.T) { } func TestNotIsType(t *testing.T) { + t.Parallel() mockT := new(testing.T) @@ -569,6 +586,8 @@ func TestNotIsType(t *testing.T) { } func TestEqual(t *testing.T) { + t.Parallel() + type myType string mockT := new(testing.T) @@ -614,6 +633,8 @@ func ptr(i int) *int { } func TestSame(t *testing.T) { + t.Parallel() + mockT := new(testing.T) if Same(mockT, ptr(1), ptr(1)) { @@ -632,6 +653,8 @@ func TestSame(t *testing.T) { } func TestNotSame(t *testing.T) { + t.Parallel() + mockT := new(testing.T) if !NotSame(mockT, ptr(1), ptr(1)) { @@ -650,6 +673,8 @@ func TestNotSame(t *testing.T) { } func Test_samePointers(t *testing.T) { + t.Parallel() + p := ptr(2) type args struct { @@ -757,6 +782,8 @@ func (t *bufferT) Errorf(format string, args ...interface{}) { } func TestStringEqual(t *testing.T) { + t.Parallel() + for i, currCase := range []struct { equalWant string equalGot string @@ -772,6 +799,8 @@ func TestStringEqual(t *testing.T) { } func TestEqualFormatting(t *testing.T) { + t.Parallel() + for i, currCase := range []struct { equalWant string equalGot string @@ -790,6 +819,8 @@ func TestEqualFormatting(t *testing.T) { } func TestFormatUnequalValues(t *testing.T) { + t.Parallel() + expected, actual := formatUnequalValues("foo", "bar") Equal(t, `"foo"`, expected, "value should not include type") Equal(t, `"bar"`, actual, "value should not include type") @@ -816,6 +847,8 @@ func TestFormatUnequalValues(t *testing.T) { } func TestNotNil(t *testing.T) { + t.Parallel() + mockT := new(testing.T) if !NotNil(mockT, new(AssertionTesterConformingObject)) { @@ -830,6 +863,8 @@ func TestNotNil(t *testing.T) { } func TestNil(t *testing.T) { + t.Parallel() + mockT := new(testing.T) if !Nil(mockT, nil) { @@ -844,6 +879,8 @@ func TestNil(t *testing.T) { } func TestTrue(t *testing.T) { + t.Parallel() + mockT := new(testing.T) if !True(mockT, true) { @@ -855,6 +892,8 @@ func TestTrue(t *testing.T) { } func TestFalse(t *testing.T) { + t.Parallel() + mockT := new(testing.T) if !False(mockT, false) { @@ -866,6 +905,7 @@ func TestFalse(t *testing.T) { } func TestExactly(t *testing.T) { + t.Parallel() mockT := new(testing.T) a := float32(1) @@ -896,6 +936,7 @@ func TestExactly(t *testing.T) { } func TestNotEqual(t *testing.T) { + t.Parallel() mockT := new(testing.T) cases := []struct { @@ -935,6 +976,8 @@ func TestNotEqual(t *testing.T) { } func TestNotEqualValues(t *testing.T) { + t.Parallel() + mockT := new(testing.T) cases := []struct { @@ -978,6 +1021,8 @@ func TestNotEqualValues(t *testing.T) { } func TestContainsNotContains(t *testing.T) { + t.Parallel() + type A struct { Name, Value string } @@ -1041,6 +1086,8 @@ func TestContainsNotContains(t *testing.T) { } func TestContainsNotContainsFailMessage(t *testing.T) { + t.Parallel() + mockT := new(mockTestingT) type nonContainer struct { @@ -1097,6 +1144,8 @@ func TestContainsNotContainsFailMessage(t *testing.T) { } func TestContainsNotContainsOnNilValue(t *testing.T) { + t.Parallel() + mockT := new(mockTestingT) Contains(mockT, nil, "key") @@ -1113,6 +1162,8 @@ func TestContainsNotContainsOnNilValue(t *testing.T) { } func TestSubsetNotSubset(t *testing.T) { + t.Parallel() + cases := []struct { list interface{} subset interface{} @@ -1198,6 +1249,8 @@ func TestSubsetNotSubset(t *testing.T) { } func TestNotSubsetNil(t *testing.T) { + t.Parallel() + mockT := new(testing.T) NotSubset(mockT, []string{"foo"}, nil) if !mockT.Failed() { @@ -1206,6 +1259,8 @@ func TestNotSubsetNil(t *testing.T) { } func Test_containsElement(t *testing.T) { + t.Parallel() + list1 := []string{"Foo", "Bar"} list2 := []int{1, 2} simpleMap := map[interface{}]interface{}{"Foo": "Bar"} @@ -1256,6 +1311,8 @@ func Test_containsElement(t *testing.T) { } func TestElementsMatch(t *testing.T) { + t.Parallel() + mockT := new(testing.T) cases := []struct { @@ -1297,6 +1354,8 @@ func TestElementsMatch(t *testing.T) { } func TestDiffLists(t *testing.T) { + t.Parallel() + tests := []struct { name string listA interface{} @@ -1381,6 +1440,8 @@ func TestDiffLists(t *testing.T) { } func TestNotElementsMatch(t *testing.T) { + t.Parallel() + mockT := new(testing.T) cases := []struct { @@ -1427,6 +1488,8 @@ func TestNotElementsMatch(t *testing.T) { } func TestCondition(t *testing.T) { + t.Parallel() + mockT := new(testing.T) if !Condition(mockT, func() bool { return true }, "Truth") { @@ -1439,6 +1502,8 @@ func TestCondition(t *testing.T) { } func TestDidPanic(t *testing.T) { + t.Parallel() + const panicMsg = "Panic!" if funcDidPanic, msg, _ := didPanic(func() { @@ -1460,6 +1525,8 @@ func TestDidPanic(t *testing.T) { } func TestPanics(t *testing.T) { + t.Parallel() + mockT := new(testing.T) if !Panics(mockT, func() { @@ -1475,6 +1542,8 @@ func TestPanics(t *testing.T) { } func TestPanicsWithValue(t *testing.T) { + t.Parallel() + mockT := new(testing.T) if !PanicsWithValue(mockT, "Panic!", func() { @@ -1502,6 +1571,8 @@ func TestPanicsWithValue(t *testing.T) { } func TestPanicsWithError(t *testing.T) { + t.Parallel() + mockT := new(testing.T) if !PanicsWithError(mockT, "panic", func() { @@ -1529,6 +1600,8 @@ func TestPanicsWithError(t *testing.T) { } func TestNotPanics(t *testing.T) { + t.Parallel() + mockT := new(testing.T) if !NotPanics(mockT, func() { @@ -1544,6 +1617,8 @@ func TestNotPanics(t *testing.T) { } func TestNoError(t *testing.T) { + t.Parallel() + mockT := new(testing.T) // start with a nil error @@ -1574,6 +1649,8 @@ type customError struct{} func (*customError) Error() string { return "fail" } func TestError(t *testing.T) { + t.Parallel() + mockT := new(testing.T) // start with a nil error @@ -1603,6 +1680,8 @@ func TestError(t *testing.T) { } func TestEqualError(t *testing.T) { + t.Parallel() + mockT := new(testing.T) // start with a nil error @@ -1619,6 +1698,8 @@ func TestEqualError(t *testing.T) { } func TestErrorContains(t *testing.T) { + t.Parallel() + mockT := new(testing.T) // start with a nil error @@ -1637,6 +1718,8 @@ func TestErrorContains(t *testing.T) { } func Test_isEmpty(t *testing.T) { + t.Parallel() + chWithValue := make(chan struct{}, 1) chWithValue <- struct{}{} @@ -1663,6 +1746,8 @@ func Test_isEmpty(t *testing.T) { } func TestEmpty(t *testing.T) { + t.Parallel() + mockT := new(testing.T) chWithValue := make(chan struct{}, 1) chWithValue <- struct{}{} @@ -1707,6 +1792,8 @@ func TestEmpty(t *testing.T) { } func TestNotEmpty(t *testing.T) { + t.Parallel() + mockT := new(testing.T) chWithValue := make(chan struct{}, 1) chWithValue <- struct{}{} @@ -1729,6 +1816,8 @@ func TestNotEmpty(t *testing.T) { } func Test_getLen(t *testing.T) { + t.Parallel() + falseCases := []interface{}{ nil, 0, @@ -1774,6 +1863,8 @@ func Test_getLen(t *testing.T) { } func TestLen(t *testing.T) { + t.Parallel() + mockT := new(testing.T) False(t, Len(mockT, nil, 0), "nil does not have length") @@ -1820,6 +1911,8 @@ func TestLen(t *testing.T) { } func TestWithinDuration(t *testing.T) { + t.Parallel() + mockT := new(testing.T) a := time.Now() b := a.Add(10 * time.Second) @@ -1838,6 +1931,8 @@ func TestWithinDuration(t *testing.T) { } func TestWithinRange(t *testing.T) { + t.Parallel() + mockT := new(testing.T) n := time.Now() s := n.Add(-time.Second) @@ -1856,6 +1951,8 @@ func TestWithinRange(t *testing.T) { } func TestInDelta(t *testing.T) { + t.Parallel() + mockT := new(testing.T) True(t, InDelta(mockT, 1.001, 1, 0.01), "|1.001 - 1| <= 0.01") @@ -1894,6 +1991,8 @@ func TestInDelta(t *testing.T) { } func TestInDeltaSlice(t *testing.T) { + t.Parallel() + mockT := new(testing.T) True(t, InDeltaSlice(mockT, @@ -1915,6 +2014,8 @@ func TestInDeltaSlice(t *testing.T) { } func TestInDeltaMapValues(t *testing.T) { + t.Parallel() + mockT := new(testing.T) for _, tc := range []struct { @@ -1993,6 +2094,8 @@ func TestInDeltaMapValues(t *testing.T) { } func TestInEpsilon(t *testing.T) { + t.Parallel() + mockT := new(testing.T) cases := []struct { @@ -2047,6 +2150,8 @@ func TestInEpsilon(t *testing.T) { } func TestInEpsilonSlice(t *testing.T) { + t.Parallel() + mockT := new(testing.T) True(t, InEpsilonSlice(mockT, @@ -2063,6 +2168,8 @@ func TestInEpsilonSlice(t *testing.T) { } func TestRegexp(t *testing.T) { + t.Parallel() + mockT := new(testing.T) cases := []struct { @@ -2116,12 +2223,16 @@ func testAutogeneratedFunction() { } func TestCallerInfoWithAutogeneratedFunctions(t *testing.T) { + t.Parallel() + NotPanics(t, func() { testAutogeneratedFunction() }) } func TestZero(t *testing.T) { + t.Parallel() + mockT := new(testing.T) for _, test := range zeros { @@ -2134,6 +2245,8 @@ func TestZero(t *testing.T) { } func TestNotZero(t *testing.T) { + t.Parallel() + mockT := new(testing.T) for _, test := range zeros { @@ -2146,6 +2259,8 @@ func TestNotZero(t *testing.T) { } func TestFileExists(t *testing.T) { + // FIXME t.Parallel() + mockT := new(testing.T) True(t, FileExists(mockT, "assertions.go")) @@ -2180,6 +2295,8 @@ func TestFileExists(t *testing.T) { } func TestNoFileExists(t *testing.T) { + // FIXME t.Parallel() + mockT := new(testing.T) False(t, NoFileExists(mockT, "assertions.go")) @@ -2231,6 +2348,8 @@ func cleanUpTempFiles(paths []string) []error { } func TestDirExists(t *testing.T) { + // FIXME t.Parallel() + mockT := new(testing.T) False(t, DirExists(mockT, "assertions.go")) @@ -2265,6 +2384,8 @@ func TestDirExists(t *testing.T) { } func TestNoDirExists(t *testing.T) { + // FIXME t.Parallel() + mockT := new(testing.T) True(t, NoDirExists(mockT, "assertions.go")) @@ -2299,67 +2420,93 @@ func TestNoDirExists(t *testing.T) { } func TestJSONEq_EqualSONString(t *testing.T) { + t.Parallel() + mockT := new(testing.T) True(t, JSONEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`)) } func TestJSONEq_EquivalentButNotEqual(t *testing.T) { + t.Parallel() + mockT := new(testing.T) True(t, JSONEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)) } func TestJSONEq_HashOfArraysAndHashes(t *testing.T) { + t.Parallel() + mockT := new(testing.T) True(t, JSONEq(mockT, "{\r\n\t\"numeric\": 1.5,\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]],\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\"\r\n}", "{\r\n\t\"numeric\": 1.5,\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\",\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]]\r\n}")) } func TestJSONEq_Array(t *testing.T) { + t.Parallel() + mockT := new(testing.T) True(t, JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`)) } func TestJSONEq_HashAndArrayNotEquivalent(t *testing.T) { + t.Parallel() + mockT := new(testing.T) False(t, JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`)) } func TestJSONEq_HashesNotEquivalent(t *testing.T) { + t.Parallel() + mockT := new(testing.T) False(t, JSONEq(mockT, `{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)) } func TestJSONEq_ActualIsNotJSON(t *testing.T) { + t.Parallel() + mockT := new(testing.T) False(t, JSONEq(mockT, `{"foo": "bar"}`, "Not JSON")) } func TestJSONEq_ExpectedIsNotJSON(t *testing.T) { + t.Parallel() + mockT := new(testing.T) False(t, JSONEq(mockT, "Not JSON", `{"foo": "bar", "hello": "world"}`)) } func TestJSONEq_ExpectedAndActualNotJSON(t *testing.T) { + t.Parallel() + mockT := new(testing.T) False(t, JSONEq(mockT, "Not JSON", "Not JSON")) } func TestJSONEq_ArraysOfDifferentOrder(t *testing.T) { + t.Parallel() + mockT := new(testing.T) False(t, JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`)) } func TestYAMLEq_EqualYAMLString(t *testing.T) { + t.Parallel() + mockT := new(testing.T) True(t, YAMLEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`)) } func TestYAMLEq_EquivalentButNotEqual(t *testing.T) { + t.Parallel() + mockT := new(testing.T) True(t, YAMLEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)) } func TestYAMLEq_HashOfArraysAndHashes(t *testing.T) { + t.Parallel() + mockT := new(testing.T) expected := ` numeric: 1.5 @@ -2390,36 +2537,50 @@ array: } func TestYAMLEq_Array(t *testing.T) { + t.Parallel() + mockT := new(testing.T) True(t, YAMLEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`)) } func TestYAMLEq_HashAndArrayNotEquivalent(t *testing.T) { + t.Parallel() + mockT := new(testing.T) False(t, YAMLEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`)) } func TestYAMLEq_HashesNotEquivalent(t *testing.T) { + t.Parallel() + mockT := new(testing.T) False(t, YAMLEq(mockT, `{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)) } func TestYAMLEq_ActualIsSimpleString(t *testing.T) { + t.Parallel() + mockT := new(testing.T) False(t, YAMLEq(mockT, `{"foo": "bar"}`, "Simple String")) } func TestYAMLEq_ExpectedIsSimpleString(t *testing.T) { + t.Parallel() + mockT := new(testing.T) False(t, YAMLEq(mockT, "Simple String", `{"foo": "bar", "hello": "world"}`)) } func TestYAMLEq_ExpectedAndActualSimpleString(t *testing.T) { + t.Parallel() + mockT := new(testing.T) True(t, YAMLEq(mockT, "Simple String", "Simple String")) } func TestYAMLEq_ArraysOfDifferentOrder(t *testing.T) { + t.Parallel() + mockT := new(testing.T) False(t, YAMLEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`)) } @@ -2434,6 +2595,8 @@ func (d *diffTestingStruct) String() string { } func TestDiff(t *testing.T) { + t.Parallel() + expected := ` Diff: @@ -2568,6 +2731,8 @@ Diff: } func TestTimeEqualityErrorFormatting(t *testing.T) { + t.Parallel() + mockT := new(mockTestingT) Equal(mockT, time.Second*2, time.Millisecond) @@ -2577,6 +2742,8 @@ func TestTimeEqualityErrorFormatting(t *testing.T) { } func TestDiffEmptyCases(t *testing.T) { + t.Parallel() + Equal(t, "", diff(nil, nil)) Equal(t, "", diff(struct{ foo string }{}, nil)) Equal(t, "", diff(nil, struct{ foo string }{})) @@ -2638,6 +2805,8 @@ func (m *mockTestingT) Failed() bool { } func TestFailNowWithPlainTestingT(t *testing.T) { + t.Parallel() + mockT := &mockTestingT{} Panics(t, func() { @@ -2652,6 +2821,8 @@ func (m *mockFailNowTestingT) Errorf(format string, args ...interface{}) {} func (m *mockFailNowTestingT) FailNow() {} func TestFailNowWithFullTestingT(t *testing.T) { + t.Parallel() + mockT := &mockFailNowTestingT{} NotPanics(t, func() { @@ -2660,6 +2831,8 @@ func TestFailNowWithFullTestingT(t *testing.T) { } func TestBytesEqual(t *testing.T) { + t.Parallel() + cases := []struct { a, b []byte }{ @@ -2725,6 +2898,8 @@ func ExampleComparisonAssertionFunc() { } func TestComparisonAssertionFunc(t *testing.T) { + t.Parallel() + type iface interface { Name() string } @@ -2786,6 +2961,8 @@ func ExampleValueAssertionFunc() { } func TestValueAssertionFunc(t *testing.T) { + t.Parallel() + tests := []struct { name string value interface{} @@ -2832,6 +3009,8 @@ func ExampleBoolAssertionFunc() { } func TestBoolAssertionFunc(t *testing.T) { + t.Parallel() + tests := []struct { name string value bool @@ -2875,6 +3054,8 @@ func ExampleErrorAssertionFunc() { } func TestErrorAssertionFunc(t *testing.T) { + t.Parallel() + tests := []struct { name string err error @@ -2911,6 +3092,8 @@ func ExamplePanicAssertionFunc() { } func TestPanicAssertionFunc(t *testing.T) { + t.Parallel() + tests := []struct { name string panicFn PanicTestFunc @@ -2928,6 +3111,8 @@ func TestPanicAssertionFunc(t *testing.T) { } func TestEventuallyFalse(t *testing.T) { + t.Parallel() + mockT := new(testing.T) condition := func() bool { @@ -2938,6 +3123,8 @@ func TestEventuallyFalse(t *testing.T) { } func TestEventuallyTrue(t *testing.T) { + t.Parallel() + state := 0 condition := func() bool { defer func() { @@ -2961,6 +3148,8 @@ func (t *errorsCapturingT) Errorf(format string, args ...interface{}) { func (t *errorsCapturingT) Helper() {} func TestEventuallyWithTFalse(t *testing.T) { + t.Parallel() + mockT := new(errorsCapturingT) condition := func(collect *CollectT) { @@ -2972,6 +3161,8 @@ func TestEventuallyWithTFalse(t *testing.T) { } func TestEventuallyWithTTrue(t *testing.T) { + t.Parallel() + mockT := new(errorsCapturingT) counter := 0 @@ -2986,6 +3177,8 @@ func TestEventuallyWithTTrue(t *testing.T) { } func TestEventuallyWithT_ConcurrencySafe(t *testing.T) { + t.Parallel() + mockT := new(errorsCapturingT) condition := func(collect *CollectT) { @@ -2998,6 +3191,8 @@ func TestEventuallyWithT_ConcurrencySafe(t *testing.T) { } func TestEventuallyWithT_ReturnsTheLatestFinishedConditionErrors(t *testing.T) { + t.Parallel() + // We'll use a channel to control whether a condition should sleep or not. mustSleep := make(chan bool, 2) mustSleep <- false @@ -3021,6 +3216,8 @@ func TestEventuallyWithT_ReturnsTheLatestFinishedConditionErrors(t *testing.T) { } func TestEventuallyWithTFailNow(t *testing.T) { + t.Parallel() + mockT := new(CollectT) condition := func(collect *CollectT) { @@ -3034,6 +3231,8 @@ func TestEventuallyWithTFailNow(t *testing.T) { // Check that a long running condition doesn't block Eventually. // See issue 805 (and its long tail of following issues) func TestEventuallyTimeout(t *testing.T) { + t.Parallel() + mockT := new(testing.T) NotPanics(t, func() { @@ -3055,6 +3254,8 @@ func TestEventuallyTimeout(t *testing.T) { } func TestEventuallySucceedQuickly(t *testing.T) { + t.Parallel() + mockT := new(testing.T) condition := func() bool { return true } @@ -3065,6 +3266,8 @@ func TestEventuallySucceedQuickly(t *testing.T) { } func TestEventuallyWithTSucceedQuickly(t *testing.T) { + t.Parallel() + mockT := new(testing.T) condition := func(t *CollectT) {} @@ -3075,6 +3278,8 @@ func TestEventuallyWithTSucceedQuickly(t *testing.T) { } func TestNeverFalse(t *testing.T) { + t.Parallel() + condition := func() bool { return false } @@ -3084,6 +3289,8 @@ func TestNeverFalse(t *testing.T) { // TestNeverTrue checks Never with a condition that returns true on second call. func TestNeverTrue(t *testing.T) { + t.Parallel() + mockT := new(testing.T) // A list of values returned by condition. @@ -3102,6 +3309,8 @@ func TestNeverTrue(t *testing.T) { } func TestNeverFailQuickly(t *testing.T) { + t.Parallel() + mockT := new(testing.T) // By making the tick longer than the total duration, we expect that this test would fail if @@ -3111,6 +3320,8 @@ func TestNeverFailQuickly(t *testing.T) { } func Test_validateEqualArgs(t *testing.T) { + t.Parallel() + if validateEqualArgs(func() {}, func() {}) == nil { t.Error("non-nil functions should error") } @@ -3125,6 +3336,8 @@ func Test_validateEqualArgs(t *testing.T) { } func Test_truncatingFormat(t *testing.T) { + t.Parallel() + original := strings.Repeat("a", bufio.MaxScanTokenSize-102) result := truncatingFormat(original) Equal(t, fmt.Sprintf("%#v", original), result, "string should not be truncated") @@ -3218,6 +3431,8 @@ func (ctt *captureTestingT) checkResultAndErrMsg(t *testing.T, expectedRes, res } func TestErrorIs(t *testing.T) { + t.Parallel() + tests := []struct { err error target error @@ -3285,6 +3500,8 @@ func TestErrorIs(t *testing.T) { } func TestNotErrorIs(t *testing.T) { + t.Parallel() + tests := []struct { err error target error @@ -3351,6 +3568,8 @@ func TestNotErrorIs(t *testing.T) { } func TestErrorAs(t *testing.T) { + t.Parallel() + tests := []struct { err error result bool @@ -3397,6 +3616,8 @@ func TestErrorAs(t *testing.T) { } func TestNotErrorAs(t *testing.T) { + t.Parallel() + tests := []struct { err error result bool diff --git a/assert/forward_assertions_test.go b/assert/forward_assertions_test.go index 5752d449d..5523422fe 100644 --- a/assert/forward_assertions_test.go +++ b/assert/forward_assertions_test.go @@ -8,6 +8,8 @@ import ( ) func TestImplementsWrapper(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if !assert.Implements((*AssertionTesterInterface)(nil), new(AssertionTesterConformingObject)) { @@ -19,6 +21,8 @@ func TestImplementsWrapper(t *testing.T) { } func TestIsTypeWrapper(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if !assert.IsType(new(AssertionTesterConformingObject), new(AssertionTesterConformingObject)) { @@ -31,6 +35,8 @@ func TestIsTypeWrapper(t *testing.T) { } func TestEqualWrapper(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if !assert.Equal("Hello World", "Hello World") { @@ -51,6 +57,8 @@ func TestEqualWrapper(t *testing.T) { } func TestEqualValuesWrapper(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if !assert.EqualValues(uint32(10), int32(10)) { @@ -59,6 +67,8 @@ func TestEqualValuesWrapper(t *testing.T) { } func TestNotNilWrapper(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if !assert.NotNil(new(AssertionTesterConformingObject)) { @@ -71,6 +81,8 @@ func TestNotNilWrapper(t *testing.T) { } func TestNilWrapper(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if !assert.Nil(nil) { @@ -83,6 +95,8 @@ func TestNilWrapper(t *testing.T) { } func TestTrueWrapper(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if !assert.True(true) { @@ -95,6 +109,8 @@ func TestTrueWrapper(t *testing.T) { } func TestFalseWrapper(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if !assert.False(false) { @@ -107,6 +123,8 @@ func TestFalseWrapper(t *testing.T) { } func TestExactlyWrapper(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) a := float32(1) @@ -134,6 +152,7 @@ func TestExactlyWrapper(t *testing.T) { } func TestNotEqualWrapper(t *testing.T) { + t.Parallel() assert := New(new(testing.T)) @@ -155,6 +174,7 @@ func TestNotEqualWrapper(t *testing.T) { } func TestNotEqualValuesWrapper(t *testing.T) { + t.Parallel() assert := New(new(testing.T)) @@ -179,6 +199,7 @@ func TestNotEqualValuesWrapper(t *testing.T) { } func TestContainsWrapper(t *testing.T) { + t.Parallel() assert := New(new(testing.T)) list := []string{"Foo", "Bar"} @@ -200,6 +221,7 @@ func TestContainsWrapper(t *testing.T) { } func TestNotContainsWrapper(t *testing.T) { + t.Parallel() assert := New(new(testing.T)) list := []string{"Foo", "Bar"} @@ -221,6 +243,7 @@ func TestNotContainsWrapper(t *testing.T) { } func TestConditionWrapper(t *testing.T) { + t.Parallel() assert := New(new(testing.T)) @@ -235,6 +258,7 @@ func TestConditionWrapper(t *testing.T) { } func TestDidPanicWrapper(t *testing.T) { + t.Parallel() if funcDidPanic, _, _ := didPanic(func() { panic("Panic!") @@ -250,6 +274,7 @@ func TestDidPanicWrapper(t *testing.T) { } func TestPanicsWrapper(t *testing.T) { + t.Parallel() assert := New(new(testing.T)) @@ -267,6 +292,7 @@ func TestPanicsWrapper(t *testing.T) { } func TestNotPanicsWrapper(t *testing.T) { + t.Parallel() assert := New(new(testing.T)) @@ -284,6 +310,8 @@ func TestNotPanicsWrapper(t *testing.T) { } func TestNoErrorWrapper(t *testing.T) { + t.Parallel() + assert := New(t) mockAssert := New(new(testing.T)) @@ -300,6 +328,8 @@ func TestNoErrorWrapper(t *testing.T) { } func TestErrorWrapper(t *testing.T) { + t.Parallel() + assert := New(t) mockAssert := New(new(testing.T)) @@ -316,6 +346,8 @@ func TestErrorWrapper(t *testing.T) { } func TestErrorContainsWrapper(t *testing.T) { + t.Parallel() + assert := New(t) mockAssert := New(new(testing.T)) @@ -335,6 +367,8 @@ func TestErrorContainsWrapper(t *testing.T) { } func TestEqualErrorWrapper(t *testing.T) { + t.Parallel() + assert := New(t) mockAssert := New(new(testing.T)) @@ -352,6 +386,8 @@ func TestEqualErrorWrapper(t *testing.T) { } func TestEmptyWrapper(t *testing.T) { + t.Parallel() + assert := New(t) mockAssert := New(new(testing.T)) @@ -370,6 +406,8 @@ func TestEmptyWrapper(t *testing.T) { } func TestNotEmptyWrapper(t *testing.T) { + t.Parallel() + assert := New(t) mockAssert := New(new(testing.T)) @@ -388,6 +426,8 @@ func TestNotEmptyWrapper(t *testing.T) { } func TestLenWrapper(t *testing.T) { + t.Parallel() + assert := New(t) mockAssert := New(new(testing.T)) @@ -428,6 +468,8 @@ func TestLenWrapper(t *testing.T) { } func TestWithinDurationWrapper(t *testing.T) { + t.Parallel() + assert := New(t) mockAssert := New(new(testing.T)) a := time.Now() @@ -447,6 +489,8 @@ func TestWithinDurationWrapper(t *testing.T) { } func TestInDeltaWrapper(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) True(t, assert.InDelta(1.001, 1, 0.01), "|1.001 - 1| <= 0.01") @@ -481,6 +525,8 @@ func TestInDeltaWrapper(t *testing.T) { } func TestInEpsilonWrapper(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) cases := []struct { @@ -519,6 +565,7 @@ func TestInEpsilonWrapper(t *testing.T) { } func TestRegexpWrapper(t *testing.T) { + t.Parallel() assert := New(new(testing.T)) @@ -554,6 +601,8 @@ func TestRegexpWrapper(t *testing.T) { } func TestZeroWrapper(t *testing.T) { + t.Parallel() + assert := New(t) mockAssert := New(new(testing.T)) @@ -567,6 +616,8 @@ func TestZeroWrapper(t *testing.T) { } func TestNotZeroWrapper(t *testing.T) { + t.Parallel() + assert := New(t) mockAssert := New(new(testing.T)) @@ -580,6 +631,8 @@ func TestNotZeroWrapper(t *testing.T) { } func TestJSONEqWrapper_EqualSONString(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if !assert.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`) { t.Error("JSONEq should return true") @@ -588,6 +641,8 @@ func TestJSONEqWrapper_EqualSONString(t *testing.T) { } func TestJSONEqWrapper_EquivalentButNotEqual(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if !assert.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) { t.Error("JSONEq should return true") @@ -596,6 +651,8 @@ func TestJSONEqWrapper_EquivalentButNotEqual(t *testing.T) { } func TestJSONEqWrapper_HashOfArraysAndHashes(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if !assert.JSONEq("{\r\n\t\"numeric\": 1.5,\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]],\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\"\r\n}", "{\r\n\t\"numeric\": 1.5,\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\",\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]]\r\n}") { @@ -604,6 +661,8 @@ func TestJSONEqWrapper_HashOfArraysAndHashes(t *testing.T) { } func TestJSONEqWrapper_Array(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if !assert.JSONEq(`["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`) { t.Error("JSONEq should return true") @@ -612,6 +671,8 @@ func TestJSONEqWrapper_Array(t *testing.T) { } func TestJSONEqWrapper_HashAndArrayNotEquivalent(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if assert.JSONEq(`["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`) { t.Error("JSONEq should return false") @@ -619,6 +680,8 @@ func TestJSONEqWrapper_HashAndArrayNotEquivalent(t *testing.T) { } func TestJSONEqWrapper_HashesNotEquivalent(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if assert.JSONEq(`{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) { t.Error("JSONEq should return false") @@ -626,6 +689,8 @@ func TestJSONEqWrapper_HashesNotEquivalent(t *testing.T) { } func TestJSONEqWrapper_ActualIsNotJSON(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if assert.JSONEq(`{"foo": "bar"}`, "Not JSON") { t.Error("JSONEq should return false") @@ -633,6 +698,8 @@ func TestJSONEqWrapper_ActualIsNotJSON(t *testing.T) { } func TestJSONEqWrapper_ExpectedIsNotJSON(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if assert.JSONEq("Not JSON", `{"foo": "bar", "hello": "world"}`) { t.Error("JSONEq should return false") @@ -640,6 +707,8 @@ func TestJSONEqWrapper_ExpectedIsNotJSON(t *testing.T) { } func TestJSONEqWrapper_ExpectedAndActualNotJSON(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if assert.JSONEq("Not JSON", "Not JSON") { t.Error("JSONEq should return false") @@ -647,6 +716,8 @@ func TestJSONEqWrapper_ExpectedAndActualNotJSON(t *testing.T) { } func TestJSONEqWrapper_ArraysOfDifferentOrder(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if assert.JSONEq(`["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`) { t.Error("JSONEq should return false") @@ -654,6 +725,8 @@ func TestJSONEqWrapper_ArraysOfDifferentOrder(t *testing.T) { } func TestYAMLEqWrapper_EqualYAMLString(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if !assert.YAMLEq(`{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`) { t.Error("YAMLEq should return true") @@ -662,6 +735,8 @@ func TestYAMLEqWrapper_EqualYAMLString(t *testing.T) { } func TestYAMLEqWrapper_EquivalentButNotEqual(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if !assert.YAMLEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) { t.Error("YAMLEq should return true") @@ -670,6 +745,8 @@ func TestYAMLEqWrapper_EquivalentButNotEqual(t *testing.T) { } func TestYAMLEqWrapper_HashOfArraysAndHashes(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) expected := ` numeric: 1.5 @@ -702,6 +779,8 @@ array: } func TestYAMLEqWrapper_Array(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if !assert.YAMLEq(`["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`) { t.Error("YAMLEq should return true") @@ -710,6 +789,8 @@ func TestYAMLEqWrapper_Array(t *testing.T) { } func TestYAMLEqWrapper_HashAndArrayNotEquivalent(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if assert.YAMLEq(`["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`) { t.Error("YAMLEq should return false") @@ -717,6 +798,8 @@ func TestYAMLEqWrapper_HashAndArrayNotEquivalent(t *testing.T) { } func TestYAMLEqWrapper_HashesNotEquivalent(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if assert.YAMLEq(`{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) { t.Error("YAMLEq should return false") @@ -724,6 +807,8 @@ func TestYAMLEqWrapper_HashesNotEquivalent(t *testing.T) { } func TestYAMLEqWrapper_ActualIsSimpleString(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if assert.YAMLEq(`{"foo": "bar"}`, "Simple String") { t.Error("YAMLEq should return false") @@ -731,6 +816,8 @@ func TestYAMLEqWrapper_ActualIsSimpleString(t *testing.T) { } func TestYAMLEqWrapper_ExpectedIsSimpleString(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if assert.YAMLEq("Simple String", `{"foo": "bar", "hello": "world"}`) { t.Error("YAMLEq should return false") @@ -738,6 +825,8 @@ func TestYAMLEqWrapper_ExpectedIsSimpleString(t *testing.T) { } func TestYAMLEqWrapper_ExpectedAndActualSimpleString(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if !assert.YAMLEq("Simple String", "Simple String") { t.Error("YAMLEq should return true") @@ -745,6 +834,8 @@ func TestYAMLEqWrapper_ExpectedAndActualSimpleString(t *testing.T) { } func TestYAMLEqWrapper_ArraysOfDifferentOrder(t *testing.T) { + t.Parallel() + assert := New(new(testing.T)) if assert.YAMLEq(`["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`) { t.Error("YAMLEq should return false") diff --git a/assert/http_assertions_test.go b/assert/http_assertions_test.go index dd84f02f1..a1dd4540d 100644 --- a/assert/http_assertions_test.go +++ b/assert/http_assertions_test.go @@ -31,6 +31,8 @@ func httpStatusCode(w http.ResponseWriter, r *http.Request) { } func TestHTTPSuccess(t *testing.T) { + t.Parallel() + assert := New(t) mockT1 := new(testing.T) @@ -59,6 +61,8 @@ func TestHTTPSuccess(t *testing.T) { } func TestHTTPRedirect(t *testing.T) { + t.Parallel() + assert := New(t) mockT1 := new(mockTestingT) @@ -83,6 +87,8 @@ func TestHTTPRedirect(t *testing.T) { } func TestHTTPError(t *testing.T) { + t.Parallel() + assert := New(t) mockT1 := new(testing.T) @@ -107,6 +113,8 @@ func TestHTTPError(t *testing.T) { } func TestHTTPStatusCode(t *testing.T) { + t.Parallel() + assert := New(t) mockT1 := new(testing.T) @@ -131,6 +139,8 @@ func TestHTTPStatusCode(t *testing.T) { } func TestHTTPStatusesWrapper(t *testing.T) { + t.Parallel() + assert := New(t) mockAssert := New(new(testing.T)) @@ -153,6 +163,8 @@ func httpHelloName(w http.ResponseWriter, r *http.Request) { } func TestHTTPRequestWithNoParams(t *testing.T) { + t.Parallel() + var got *http.Request handler := func(w http.ResponseWriter, r *http.Request) { got = r @@ -166,6 +178,8 @@ func TestHTTPRequestWithNoParams(t *testing.T) { } func TestHTTPRequestWithParams(t *testing.T) { + t.Parallel() + var got *http.Request handler := func(w http.ResponseWriter, r *http.Request) { got = r @@ -182,6 +196,8 @@ func TestHTTPRequestWithParams(t *testing.T) { } func TestHttpBody(t *testing.T) { + t.Parallel() + assert := New(t) mockT := new(mockTestingT) @@ -201,6 +217,8 @@ func TestHttpBody(t *testing.T) { } func TestHttpBodyWrappers(t *testing.T) { + t.Parallel() + assert := New(t) mockAssert := New(new(testing.T)) diff --git a/require/forward_requirements_test.go b/require/forward_requirements_test.go index 99515daa3..617bfb2c3 100644 --- a/require/forward_requirements_test.go +++ b/require/forward_requirements_test.go @@ -7,6 +7,8 @@ import ( ) func TestImplementsWrapper(t *testing.T) { + t.Parallel() + require := New(t) require.Implements((*AssertionTesterInterface)(nil), new(AssertionTesterConformingObject)) @@ -20,6 +22,8 @@ func TestImplementsWrapper(t *testing.T) { } func TestIsNotTypeWrapper(t *testing.T) { + t.Parallel() + require := New(t) require.IsNotType(new(AssertionTesterNonConformingObject), new(AssertionTesterConformingObject)) @@ -32,6 +36,8 @@ func TestIsNotTypeWrapper(t *testing.T) { } func TestIsTypeWrapper(t *testing.T) { + t.Parallel() + require := New(t) require.IsType(new(AssertionTesterConformingObject), new(AssertionTesterConformingObject)) @@ -44,6 +50,8 @@ func TestIsTypeWrapper(t *testing.T) { } func TestEqualWrapper(t *testing.T) { + t.Parallel() + require := New(t) require.Equal(1, 1) @@ -56,6 +64,8 @@ func TestEqualWrapper(t *testing.T) { } func TestNotEqualWrapper(t *testing.T) { + t.Parallel() + require := New(t) require.NotEqual(1, 2) @@ -68,6 +78,8 @@ func TestNotEqualWrapper(t *testing.T) { } func TestExactlyWrapper(t *testing.T) { + t.Parallel() + require := New(t) a := float32(1) @@ -85,6 +97,8 @@ func TestExactlyWrapper(t *testing.T) { } func TestNotNilWrapper(t *testing.T) { + t.Parallel() + require := New(t) require.NotNil(t, new(AssertionTesterConformingObject)) @@ -97,6 +111,8 @@ func TestNotNilWrapper(t *testing.T) { } func TestNilWrapper(t *testing.T) { + t.Parallel() + require := New(t) require.Nil(nil) @@ -109,6 +125,8 @@ func TestNilWrapper(t *testing.T) { } func TestTrueWrapper(t *testing.T) { + t.Parallel() + require := New(t) require.True(true) @@ -121,6 +139,8 @@ func TestTrueWrapper(t *testing.T) { } func TestFalseWrapper(t *testing.T) { + t.Parallel() + require := New(t) require.False(false) @@ -133,6 +153,8 @@ func TestFalseWrapper(t *testing.T) { } func TestContainsWrapper(t *testing.T) { + t.Parallel() + require := New(t) require.Contains("Hello World", "Hello") @@ -145,6 +167,8 @@ func TestContainsWrapper(t *testing.T) { } func TestNotContainsWrapper(t *testing.T) { + t.Parallel() + require := New(t) require.NotContains("Hello World", "Hello!") @@ -157,6 +181,8 @@ func TestNotContainsWrapper(t *testing.T) { } func TestPanicsWrapper(t *testing.T) { + t.Parallel() + require := New(t) require.Panics(func() { panic("Panic!") @@ -171,6 +197,8 @@ func TestPanicsWrapper(t *testing.T) { } func TestNotPanicsWrapper(t *testing.T) { + t.Parallel() + require := New(t) require.NotPanics(func() {}) @@ -185,6 +213,8 @@ func TestNotPanicsWrapper(t *testing.T) { } func TestNoErrorWrapper(t *testing.T) { + t.Parallel() + require := New(t) require.NoError(nil) @@ -197,6 +227,8 @@ func TestNoErrorWrapper(t *testing.T) { } func TestErrorWrapper(t *testing.T) { + t.Parallel() + require := New(t) require.Error(errors.New("some error")) @@ -209,6 +241,8 @@ func TestErrorWrapper(t *testing.T) { } func TestErrorContainsWrapper(t *testing.T) { + t.Parallel() + require := New(t) require.ErrorContains(errors.New("some error: another error"), "some error") @@ -221,6 +255,8 @@ func TestErrorContainsWrapper(t *testing.T) { } func TestEqualErrorWrapper(t *testing.T) { + t.Parallel() + require := New(t) require.EqualError(errors.New("some error"), "some error") @@ -233,6 +269,8 @@ func TestEqualErrorWrapper(t *testing.T) { } func TestEmptyWrapper(t *testing.T) { + t.Parallel() + require := New(t) require.Empty("") @@ -245,6 +283,8 @@ func TestEmptyWrapper(t *testing.T) { } func TestNotEmptyWrapper(t *testing.T) { + t.Parallel() + require := New(t) require.NotEmpty("x") @@ -257,6 +297,8 @@ func TestNotEmptyWrapper(t *testing.T) { } func TestWithinDurationWrapper(t *testing.T) { + t.Parallel() + require := New(t) a := time.Now() b := a.Add(10 * time.Second) @@ -272,6 +314,8 @@ func TestWithinDurationWrapper(t *testing.T) { } func TestInDeltaWrapper(t *testing.T) { + t.Parallel() + require := New(t) require.InDelta(1.001, 1, 0.01) @@ -284,6 +328,8 @@ func TestInDeltaWrapper(t *testing.T) { } func TestZeroWrapper(t *testing.T) { + t.Parallel() + require := New(t) require.Zero(0) @@ -296,6 +342,8 @@ func TestZeroWrapper(t *testing.T) { } func TestNotZeroWrapper(t *testing.T) { + t.Parallel() + require := New(t) require.NotZero(1) @@ -308,6 +356,8 @@ func TestNotZeroWrapper(t *testing.T) { } func TestJSONEqWrapper_EqualSONString(t *testing.T) { + t.Parallel() + mockT := new(MockT) mockRequire := New(mockT) @@ -318,6 +368,8 @@ func TestJSONEqWrapper_EqualSONString(t *testing.T) { } func TestJSONEqWrapper_EquivalentButNotEqual(t *testing.T) { + t.Parallel() + mockT := new(MockT) mockRequire := New(mockT) @@ -328,6 +380,8 @@ func TestJSONEqWrapper_EquivalentButNotEqual(t *testing.T) { } func TestJSONEqWrapper_HashOfArraysAndHashes(t *testing.T) { + t.Parallel() + mockT := new(MockT) mockRequire := New(mockT) @@ -339,6 +393,8 @@ func TestJSONEqWrapper_HashOfArraysAndHashes(t *testing.T) { } func TestJSONEqWrapper_Array(t *testing.T) { + t.Parallel() + mockT := new(MockT) mockRequire := New(mockT) @@ -349,6 +405,8 @@ func TestJSONEqWrapper_Array(t *testing.T) { } func TestJSONEqWrapper_HashAndArrayNotEquivalent(t *testing.T) { + t.Parallel() + mockT := new(MockT) mockRequire := New(mockT) @@ -359,6 +417,8 @@ func TestJSONEqWrapper_HashAndArrayNotEquivalent(t *testing.T) { } func TestJSONEqWrapper_HashesNotEquivalent(t *testing.T) { + t.Parallel() + mockT := new(MockT) mockRequire := New(mockT) @@ -369,6 +429,8 @@ func TestJSONEqWrapper_HashesNotEquivalent(t *testing.T) { } func TestJSONEqWrapper_ActualIsNotJSON(t *testing.T) { + t.Parallel() + mockT := new(MockT) mockRequire := New(mockT) @@ -379,6 +441,8 @@ func TestJSONEqWrapper_ActualIsNotJSON(t *testing.T) { } func TestJSONEqWrapper_ExpectedIsNotJSON(t *testing.T) { + t.Parallel() + mockT := new(MockT) mockRequire := New(mockT) @@ -389,6 +453,8 @@ func TestJSONEqWrapper_ExpectedIsNotJSON(t *testing.T) { } func TestJSONEqWrapper_ExpectedAndActualNotJSON(t *testing.T) { + t.Parallel() + mockT := new(MockT) mockRequire := New(mockT) @@ -399,6 +465,8 @@ func TestJSONEqWrapper_ExpectedAndActualNotJSON(t *testing.T) { } func TestJSONEqWrapper_ArraysOfDifferentOrder(t *testing.T) { + t.Parallel() + mockT := new(MockT) mockRequire := New(mockT) @@ -409,6 +477,8 @@ func TestJSONEqWrapper_ArraysOfDifferentOrder(t *testing.T) { } func TestYAMLEqWrapper_EqualYAMLString(t *testing.T) { + t.Parallel() + mockT := new(MockT) mockRequire := New(mockT) @@ -419,6 +489,8 @@ func TestYAMLEqWrapper_EqualYAMLString(t *testing.T) { } func TestYAMLEqWrapper_EquivalentButNotEqual(t *testing.T) { + t.Parallel() + mockT := new(MockT) mockRequire := New(mockT) @@ -429,6 +501,8 @@ func TestYAMLEqWrapper_EquivalentButNotEqual(t *testing.T) { } func TestYAMLEqWrapper_HashOfArraysAndHashes(t *testing.T) { + t.Parallel() + mockT := new(MockT) mockRequire := New(mockT) @@ -465,6 +539,8 @@ array: } func TestYAMLEqWrapper_Array(t *testing.T) { + t.Parallel() + mockT := new(MockT) mockRequire := New(mockT) @@ -475,6 +551,8 @@ func TestYAMLEqWrapper_Array(t *testing.T) { } func TestYAMLEqWrapper_HashAndArrayNotEquivalent(t *testing.T) { + t.Parallel() + mockT := new(MockT) mockRequire := New(mockT) @@ -485,6 +563,8 @@ func TestYAMLEqWrapper_HashAndArrayNotEquivalent(t *testing.T) { } func TestYAMLEqWrapper_HashesNotEquivalent(t *testing.T) { + t.Parallel() + mockT := new(MockT) mockRequire := New(mockT) @@ -495,6 +575,8 @@ func TestYAMLEqWrapper_HashesNotEquivalent(t *testing.T) { } func TestYAMLEqWrapper_ActualIsSimpleString(t *testing.T) { + t.Parallel() + mockT := new(MockT) mockRequire := New(mockT) @@ -505,6 +587,8 @@ func TestYAMLEqWrapper_ActualIsSimpleString(t *testing.T) { } func TestYAMLEqWrapper_ExpectedIsSimpleString(t *testing.T) { + t.Parallel() + mockT := new(MockT) mockRequire := New(mockT) @@ -515,6 +599,8 @@ func TestYAMLEqWrapper_ExpectedIsSimpleString(t *testing.T) { } func TestYAMLEqWrapper_ExpectedAndActualSimpleString(t *testing.T) { + t.Parallel() + mockT := new(MockT) mockRequire := New(mockT) @@ -525,6 +611,8 @@ func TestYAMLEqWrapper_ExpectedAndActualSimpleString(t *testing.T) { } func TestYAMLEqWrapper_ArraysOfDifferentOrder(t *testing.T) { + t.Parallel() + mockT := new(MockT) mockRequire := New(mockT) diff --git a/require/requirements_test.go b/require/requirements_test.go index 824b159fa..b62a5ba2c 100644 --- a/require/requirements_test.go +++ b/require/requirements_test.go @@ -38,6 +38,7 @@ func (t *MockT) Errorf(format string, args ...interface{}) { } func TestImplements(t *testing.T) { + t.Parallel() Implements(t, (*AssertionTesterInterface)(nil), new(AssertionTesterConformingObject)) @@ -49,6 +50,7 @@ func TestImplements(t *testing.T) { } func TestIsType(t *testing.T) { + t.Parallel() IsType(t, new(AssertionTesterConformingObject), new(AssertionTesterConformingObject)) @@ -60,6 +62,7 @@ func TestIsType(t *testing.T) { } func TestEqual(t *testing.T) { + t.Parallel() Equal(t, 1, 1) @@ -72,6 +75,7 @@ func TestEqual(t *testing.T) { } func TestNotEqual(t *testing.T) { + t.Parallel() NotEqual(t, 1, 2) mockT := new(MockT) @@ -82,6 +86,7 @@ func TestNotEqual(t *testing.T) { } func TestExactly(t *testing.T) { + t.Parallel() a := float32(1) b := float32(1) @@ -97,6 +102,7 @@ func TestExactly(t *testing.T) { } func TestNotNil(t *testing.T) { + t.Parallel() NotNil(t, new(AssertionTesterConformingObject)) @@ -108,6 +114,7 @@ func TestNotNil(t *testing.T) { } func TestNil(t *testing.T) { + t.Parallel() Nil(t, nil) @@ -119,6 +126,7 @@ func TestNil(t *testing.T) { } func TestTrue(t *testing.T) { + t.Parallel() True(t, true) @@ -130,6 +138,7 @@ func TestTrue(t *testing.T) { } func TestFalse(t *testing.T) { + t.Parallel() False(t, false) @@ -141,6 +150,7 @@ func TestFalse(t *testing.T) { } func TestContains(t *testing.T) { + t.Parallel() Contains(t, "Hello World", "Hello") @@ -152,6 +162,7 @@ func TestContains(t *testing.T) { } func TestNotContains(t *testing.T) { + t.Parallel() NotContains(t, "Hello World", "Hello!") @@ -163,6 +174,7 @@ func TestNotContains(t *testing.T) { } func TestPanics(t *testing.T) { + t.Parallel() Panics(t, func() { panic("Panic!") @@ -176,6 +188,7 @@ func TestPanics(t *testing.T) { } func TestNotPanics(t *testing.T) { + t.Parallel() NotPanics(t, func() {}) @@ -189,6 +202,7 @@ func TestNotPanics(t *testing.T) { } func TestNoError(t *testing.T) { + t.Parallel() NoError(t, nil) @@ -200,6 +214,7 @@ func TestNoError(t *testing.T) { } func TestError(t *testing.T) { + t.Parallel() Error(t, errors.New("some error")) @@ -211,6 +226,7 @@ func TestError(t *testing.T) { } func TestErrorContains(t *testing.T) { + t.Parallel() ErrorContains(t, errors.New("some error: another error"), "some error") @@ -222,6 +238,7 @@ func TestErrorContains(t *testing.T) { } func TestEqualError(t *testing.T) { + t.Parallel() EqualError(t, errors.New("some error"), "some error") @@ -233,6 +250,7 @@ func TestEqualError(t *testing.T) { } func TestEmpty(t *testing.T) { + t.Parallel() Empty(t, "") @@ -244,6 +262,7 @@ func TestEmpty(t *testing.T) { } func TestNotEmpty(t *testing.T) { + t.Parallel() NotEmpty(t, "x") @@ -255,6 +274,7 @@ func TestNotEmpty(t *testing.T) { } func TestWithinDuration(t *testing.T) { + t.Parallel() a := time.Now() b := a.Add(10 * time.Second) @@ -269,6 +289,7 @@ func TestWithinDuration(t *testing.T) { } func TestInDelta(t *testing.T) { + t.Parallel() InDelta(t, 1.001, 1, 0.01) @@ -280,6 +301,7 @@ func TestInDelta(t *testing.T) { } func TestZero(t *testing.T) { + t.Parallel() Zero(t, "") @@ -291,6 +313,7 @@ func TestZero(t *testing.T) { } func TestNotZero(t *testing.T) { + t.Parallel() NotZero(t, "x") @@ -302,6 +325,8 @@ func TestNotZero(t *testing.T) { } func TestJSONEq_EqualSONString(t *testing.T) { + t.Parallel() + mockT := new(MockT) JSONEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`) if mockT.Failed { @@ -310,6 +335,8 @@ func TestJSONEq_EqualSONString(t *testing.T) { } func TestJSONEq_EquivalentButNotEqual(t *testing.T) { + t.Parallel() + mockT := new(MockT) JSONEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) if mockT.Failed { @@ -318,6 +345,8 @@ func TestJSONEq_EquivalentButNotEqual(t *testing.T) { } func TestJSONEq_HashOfArraysAndHashes(t *testing.T) { + t.Parallel() + mockT := new(MockT) JSONEq(mockT, "{\r\n\t\"numeric\": 1.5,\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]],\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\"\r\n}", "{\r\n\t\"numeric\": 1.5,\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\",\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]]\r\n}") @@ -327,6 +356,8 @@ func TestJSONEq_HashOfArraysAndHashes(t *testing.T) { } func TestJSONEq_Array(t *testing.T) { + t.Parallel() + mockT := new(MockT) JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`) if mockT.Failed { @@ -335,6 +366,8 @@ func TestJSONEq_Array(t *testing.T) { } func TestJSONEq_HashAndArrayNotEquivalent(t *testing.T) { + t.Parallel() + mockT := new(MockT) JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`) if !mockT.Failed { @@ -343,6 +376,8 @@ func TestJSONEq_HashAndArrayNotEquivalent(t *testing.T) { } func TestJSONEq_HashesNotEquivalent(t *testing.T) { + t.Parallel() + mockT := new(MockT) JSONEq(mockT, `{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) if !mockT.Failed { @@ -351,6 +386,8 @@ func TestJSONEq_HashesNotEquivalent(t *testing.T) { } func TestJSONEq_ActualIsNotJSON(t *testing.T) { + t.Parallel() + mockT := new(MockT) JSONEq(mockT, `{"foo": "bar"}`, "Not JSON") if !mockT.Failed { @@ -359,6 +396,8 @@ func TestJSONEq_ActualIsNotJSON(t *testing.T) { } func TestJSONEq_ExpectedIsNotJSON(t *testing.T) { + t.Parallel() + mockT := new(MockT) JSONEq(mockT, "Not JSON", `{"foo": "bar", "hello": "world"}`) if !mockT.Failed { @@ -367,6 +406,8 @@ func TestJSONEq_ExpectedIsNotJSON(t *testing.T) { } func TestJSONEq_ExpectedAndActualNotJSON(t *testing.T) { + t.Parallel() + mockT := new(MockT) JSONEq(mockT, "Not JSON", "Not JSON") if !mockT.Failed { @@ -375,6 +416,8 @@ func TestJSONEq_ExpectedAndActualNotJSON(t *testing.T) { } func TestJSONEq_ArraysOfDifferentOrder(t *testing.T) { + t.Parallel() + mockT := new(MockT) JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`) if !mockT.Failed { @@ -383,6 +426,8 @@ func TestJSONEq_ArraysOfDifferentOrder(t *testing.T) { } func TestYAMLEq_EqualYAMLString(t *testing.T) { + t.Parallel() + mockT := new(MockT) YAMLEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`) if mockT.Failed { @@ -391,6 +436,8 @@ func TestYAMLEq_EqualYAMLString(t *testing.T) { } func TestYAMLEq_EquivalentButNotEqual(t *testing.T) { + t.Parallel() + mockT := new(MockT) YAMLEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) if mockT.Failed { @@ -399,6 +446,8 @@ func TestYAMLEq_EquivalentButNotEqual(t *testing.T) { } func TestYAMLEq_HashOfArraysAndHashes(t *testing.T) { + t.Parallel() + mockT := new(MockT) expected := ` numeric: 1.5 @@ -432,6 +481,8 @@ array: } func TestYAMLEq_Array(t *testing.T) { + t.Parallel() + mockT := new(MockT) YAMLEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`) if mockT.Failed { @@ -440,6 +491,8 @@ func TestYAMLEq_Array(t *testing.T) { } func TestYAMLEq_HashAndArrayNotEquivalent(t *testing.T) { + t.Parallel() + mockT := new(MockT) YAMLEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`) if !mockT.Failed { @@ -448,6 +501,8 @@ func TestYAMLEq_HashAndArrayNotEquivalent(t *testing.T) { } func TestYAMLEq_HashesNotEquivalent(t *testing.T) { + t.Parallel() + mockT := new(MockT) YAMLEq(mockT, `{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) if !mockT.Failed { @@ -456,6 +511,8 @@ func TestYAMLEq_HashesNotEquivalent(t *testing.T) { } func TestYAMLEq_ActualIsSimpleString(t *testing.T) { + t.Parallel() + mockT := new(MockT) YAMLEq(mockT, `{"foo": "bar"}`, "Simple String") if !mockT.Failed { @@ -464,6 +521,8 @@ func TestYAMLEq_ActualIsSimpleString(t *testing.T) { } func TestYAMLEq_ExpectedIsSimpleString(t *testing.T) { + t.Parallel() + mockT := new(MockT) YAMLEq(mockT, "Simple String", `{"foo": "bar", "hello": "world"}`) if !mockT.Failed { @@ -472,6 +531,8 @@ func TestYAMLEq_ExpectedIsSimpleString(t *testing.T) { } func TestYAMLEq_ExpectedAndActualSimpleString(t *testing.T) { + t.Parallel() + mockT := new(MockT) YAMLEq(mockT, "Simple String", "Simple String") if mockT.Failed { @@ -480,6 +541,8 @@ func TestYAMLEq_ExpectedAndActualSimpleString(t *testing.T) { } func TestYAMLEq_ArraysOfDifferentOrder(t *testing.T) { + t.Parallel() + mockT := new(MockT) YAMLEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`) if !mockT.Failed { @@ -518,6 +581,8 @@ func ExampleComparisonAssertionFunc() { } func TestComparisonAssertionFunc(t *testing.T) { + t.Parallel() + type iface interface { Name() string } @@ -579,6 +644,8 @@ func ExampleValueAssertionFunc() { } func TestValueAssertionFunc(t *testing.T) { + t.Parallel() + tests := []struct { name string value interface{} @@ -625,6 +692,8 @@ func ExampleBoolAssertionFunc() { } func TestBoolAssertionFunc(t *testing.T) { + t.Parallel() + tests := []struct { name string value bool @@ -668,6 +737,8 @@ func ExampleErrorAssertionFunc() { } func TestErrorAssertionFunc(t *testing.T) { + t.Parallel() + tests := []struct { name string err error @@ -685,6 +756,8 @@ func TestErrorAssertionFunc(t *testing.T) { } func TestEventuallyWithTFalse(t *testing.T) { + t.Parallel() + mockT := new(MockT) condition := func(collect *assert.CollectT) { @@ -696,6 +769,8 @@ func TestEventuallyWithTFalse(t *testing.T) { } func TestEventuallyWithTTrue(t *testing.T) { + t.Parallel() + mockT := new(MockT) counter := 0 From d2ddb5da5d3a5bfb855d6e9396cbe131cbb9c813 Mon Sep 17 00:00:00 2001 From: Ararsa <116437655+Ararsa-Derese@users.noreply.github.com> Date: Sun, 25 May 2025 11:10:11 +0300 Subject: [PATCH 114/178] suite.Passed: add one more status test report (#1706) ## Summary This test case verifies that the Passed method returns false when all tests in the suite fail ## Changes Added a test case to check the scenario where all tests fail. ## Motivation This test is important to ensure that the Passed method correctly identifies the overall failure state of a test suite when none of the individual tests pass. ## Example usage This test can be used as a part of the test suite to validate the behavior of the Passed method under failure conditions. ## Related issues None --- suite/stats_test.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/suite/stats_test.go b/suite/stats_test.go index 4446a6d64..d68db4e56 100644 --- a/suite/stats_test.go +++ b/suite/stats_test.go @@ -27,3 +27,14 @@ func TestPassedReturnsFalseWhenSomeTestFails(t *testing.T) { assert.False(t, sinfo.Passed()) } + +func TestPassedReturnsFalseWhenAllTestsFail(t *testing.T) { + sinfo := newSuiteInformation() + sinfo.TestStats = map[string]*TestInformation{ + "Test1": {TestName: "Test1", Passed: false}, + "Test2": {TestName: "Test2", Passed: false}, + "Test3": {TestName: "Test3", Passed: false}, + } + + assert.False(t, sinfo.Passed()) +} From bf47cc8868e89083fee4f5c6ae452c3c6f1d7d21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Tue, 11 Jul 2023 21:54:19 +0200 Subject: [PATCH 115/178] assert/tests: add Helper() in all testing.T mocks Add an Helper() method to all mocks in tests of package 'assert'. --- assert/assertions_test.go | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index f3b8ddae0..c8d59d640 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -745,6 +745,9 @@ type bufferT struct { buf bytes.Buffer } +// Helper is like [testing.T.Helper] but does nothing. +func (bufferT) Helper() {} + func (t *bufferT) Errorf(format string, args ...interface{}) { // implementation of decorate is copied from testing.T decorate := func(s string) string { @@ -2791,6 +2794,9 @@ type mockTestingT struct { args []interface{} } +// Helper is like [testing.T.Helper] but does nothing. +func (mockTestingT) Helper() {} + func (m *mockTestingT) errorString() string { return fmt.Sprintf(m.errorFmt, m.args...) } @@ -2816,6 +2822,9 @@ func TestFailNowWithPlainTestingT(t *testing.T) { type mockFailNowTestingT struct{} +// Helper is like [testing.T.Helper] but does nothing. +func (mockFailNowTestingT) Helper() {} + func (m *mockFailNowTestingT) Errorf(format string, args ...interface{}) {} func (m *mockFailNowTestingT) FailNow() {} @@ -3141,12 +3150,13 @@ type errorsCapturingT struct { errors []error } +// Helper is like [testing.T.Helper] but does nothing. +func (errorsCapturingT) Helper() {} + func (t *errorsCapturingT) Errorf(format string, args ...interface{}) { t.errors = append(t.errors, fmt.Errorf(format, args...)) } -func (t *errorsCapturingT) Helper() {} - func TestEventuallyWithTFalse(t *testing.T) { t.Parallel() @@ -3393,6 +3403,9 @@ type captureTestingT struct { msg string } +// Helper is like [testing.T.Helper] but does nothing. +func (captureTestingT) Helper() {} + func (ctt *captureTestingT) Errorf(format string, args ...interface{}) { ctt.msg = fmt.Sprintf(format, args...) ctt.failed = true From b534400d1759dcd4ccef5b1ba11ec127eb6e0632 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Tue, 11 Jul 2023 21:54:58 +0200 Subject: [PATCH 116/178] require/tests: add Helper() method to all mocks of *testing.T --- require/requirements_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/require/requirements_test.go b/require/requirements_test.go index b62a5ba2c..7cb63a554 100644 --- a/require/requirements_test.go +++ b/require/requirements_test.go @@ -29,6 +29,9 @@ type MockT struct { Failed bool } +// Helper is like [testing.T.Helper] but does nothing. +func (MockT) Helper() {} + func (t *MockT) FailNow() { t.Failed = true } From e2ad95950ec6d51233ace09f87ae47ee96de93c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Tue, 11 Jul 2023 21:55:54 +0200 Subject: [PATCH 117/178] mock/tests: add method Helper() to all mock of *testing.T --- mock/mock_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mock/mock_test.go b/mock/mock_test.go index 04664d44b..2dea0873b 100644 --- a/mock/mock_test.go +++ b/mock/mock_test.go @@ -132,6 +132,9 @@ type MockTestingT struct { logfCount, errorfCount, failNowCount int } +// Helper is like [testing.T.Helper] but does nothing. +func (MockTestingT) Helper() {} + const mockTestingTFailNowCalled = "FailNow was called" func (m *MockTestingT) Logf(string, ...interface{}) { From 8f73f15d6939f4720ea8442714fdce556873b785 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Tue, 11 Jul 2023 22:17:10 +0200 Subject: [PATCH 118/178] assert.CollectT: add Helper() method Add Helper() method to CollectT like testing.T as we intend to add Helper() to the assert.TestingT interface. --- assert/assertions.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/assert/assertions.go b/assert/assertions.go index bdead180f..adac3ed4e 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -2008,6 +2008,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...)) From 3c1541a3b402701ac9e9e6d5d75e5933e5f0014d Mon Sep 17 00:00:00 2001 From: ccoVeille <3875889+ccoVeille@users.noreply.github.com> Date: Tue, 13 May 2025 15:10:26 +0200 Subject: [PATCH 119/178] Improve usage of Sprintf with Same/NotSame MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Olivier Mengué --- assert/assertions.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index adac3ed4e..effd026d5 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -543,8 +543,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 @@ -569,8 +570,8 @@ func NotSame(t TestingT, expected, actual interface{}, msgAndArgs ...interface{} 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 } From 4eb688ba0c181ce495062311336ff9f419ab7385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Wed, 28 May 2025 18:51:47 +0200 Subject: [PATCH 120/178] assert.JSONEq: shortcut if same strings Shortcut in assert.JSONEq once we have validated that 'expected' is valid JSON, and 'actual' is the exact same string. --- assert/assertions.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/assert/assertions.go b/assert/assertions.go index effd026d5..6fc02a340 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -1853,6 +1853,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...) } From 4f71159ca8c6fffb34384e7e2eff2b3c4efdf988 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Wed, 28 May 2025 19:11:19 +0200 Subject: [PATCH 121/178] assert.YAMLEq: shortcut if same strings Shortcut in assert.YAMLEq once we have validated that 'expected' is valid YAML, and 'actual' is the exact same string. --- assert/assertions.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/assert/assertions.go b/assert/assertions.go index 6fc02a340..9913ac2f0 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -1876,6 +1876,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...) } From 8b3dc18b37cc18e399999823e3b4bf327ac41f39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Wed, 28 May 2025 21:49:17 +0200 Subject: [PATCH 122/178] mock: enable parallel testing on internal testsuite Add t.Parallel() to all package-level tests of the 'mock' package. Result: faster tests results. Before: $ go test -count=10 ./mock ok github.com/stretchr/testify/mock 0.631s After: $ go test -count=10 ./mock ok github.com/stretchr/testify/mock 0.426s --- mock/mock_test.go | 166 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) diff --git a/mock/mock_test.go b/mock/mock_test.go index 2dea0873b..813ec5e56 100644 --- a/mock/mock_test.go +++ b/mock/mock_test.go @@ -163,6 +163,7 @@ func (m *MockTestingT) FailNow() { */ func Test_Mock_TestData(t *testing.T) { + t.Parallel() var mockedService = new(TestExampleImplementation) @@ -174,6 +175,7 @@ func Test_Mock_TestData(t *testing.T) { } func Test_Mock_On(t *testing.T) { + t.Parallel() // make a test impl object var mockedService = new(TestExampleImplementation) @@ -184,6 +186,8 @@ func Test_Mock_On(t *testing.T) { } func Test_Mock_Chained_On(t *testing.T) { + t.Parallel() + // make a test impl object var mockedService = new(TestExampleImplementation) @@ -215,6 +219,7 @@ func Test_Mock_Chained_On(t *testing.T) { } func Test_Mock_On_WithArgs(t *testing.T) { + t.Parallel() // make a test impl object var mockedService = new(TestExampleImplementation) @@ -227,6 +232,7 @@ func Test_Mock_On_WithArgs(t *testing.T) { } func Test_Mock_On_WithFuncArg(t *testing.T) { + t.Parallel() // make a test impl object var mockedService = new(TestExampleImplementation) @@ -248,6 +254,8 @@ func Test_Mock_On_WithFuncArg(t *testing.T) { } func Test_Mock_On_WithIntArgMatcher(t *testing.T) { + t.Parallel() + var mockedService TestExampleImplementation mockedService.On("TheExampleMethod", @@ -271,6 +279,8 @@ func Test_Mock_On_WithIntArgMatcher(t *testing.T) { } func Test_Mock_On_WithArgMatcherThatPanics(t *testing.T) { + t.Parallel() + var mockedService TestExampleImplementation mockedService.On("TheExampleMethod2", MatchedBy(func(_ interface{}) bool { @@ -297,6 +307,8 @@ func Test_Mock_On_WithArgMatcherThatPanics(t *testing.T) { } func TestMock_WithTest(t *testing.T) { + t.Parallel() + var ( mockedService TestExampleImplementation mockedTest MockTestingT @@ -325,6 +337,8 @@ func TestMock_WithTest(t *testing.T) { } func Test_Mock_On_WithPtrArgMatcher(t *testing.T) { + t.Parallel() + var mockedService TestExampleImplementation mockedService.On("TheExampleMethod3", @@ -345,6 +359,8 @@ func Test_Mock_On_WithPtrArgMatcher(t *testing.T) { } func Test_Mock_On_WithFuncArgMatcher(t *testing.T) { + t.Parallel() + var mockedService TestExampleImplementation fixture1, fixture2 := errors.New("fixture1"), errors.New("fixture2") @@ -369,6 +385,8 @@ func Test_Mock_On_WithFuncArgMatcher(t *testing.T) { } func Test_Mock_On_WithInterfaceArgMatcher(t *testing.T) { + t.Parallel() + var mockedService TestExampleImplementation mockedService.On("TheExampleMethod4", @@ -379,6 +397,8 @@ func Test_Mock_On_WithInterfaceArgMatcher(t *testing.T) { } func Test_Mock_On_WithChannelArgMatcher(t *testing.T) { + t.Parallel() + var mockedService TestExampleImplementation mockedService.On("TheExampleMethod5", @@ -389,6 +409,8 @@ func Test_Mock_On_WithChannelArgMatcher(t *testing.T) { } func Test_Mock_On_WithMapArgMatcher(t *testing.T) { + t.Parallel() + var mockedService TestExampleImplementation mockedService.On("TheExampleMethod6", @@ -399,6 +421,8 @@ func Test_Mock_On_WithMapArgMatcher(t *testing.T) { } func Test_Mock_On_WithSliceArgMatcher(t *testing.T) { + t.Parallel() + var mockedService TestExampleImplementation mockedService.On("TheExampleMethod7", @@ -409,6 +433,7 @@ func Test_Mock_On_WithSliceArgMatcher(t *testing.T) { } func Test_Mock_On_WithVariadicFunc(t *testing.T) { + t.Parallel() // make a test impl object var mockedService = new(TestExampleImplementation) @@ -431,6 +456,7 @@ func Test_Mock_On_WithVariadicFunc(t *testing.T) { } func Test_Mock_On_WithMixedVariadicFunc(t *testing.T) { + t.Parallel() // make a test impl object var mockedService = new(TestExampleImplementation) @@ -454,6 +480,7 @@ func Test_Mock_On_WithMixedVariadicFunc(t *testing.T) { } func Test_Mock_On_WithVariadicFuncWithInterface(t *testing.T) { + t.Parallel() // make a test impl object var mockedService = new(TestExampleImplementation) @@ -475,6 +502,7 @@ func Test_Mock_On_WithVariadicFuncWithInterface(t *testing.T) { } func Test_Mock_On_WithVariadicFuncWithEmptyInterfaceArray(t *testing.T) { + t.Parallel() // make a test impl object var mockedService = new(TestExampleImplementation) @@ -498,6 +526,8 @@ func Test_Mock_On_WithVariadicFuncWithEmptyInterfaceArray(t *testing.T) { } func Test_Mock_On_WithFuncPanics(t *testing.T) { + t.Parallel() + // make a test impl object var mockedService = new(TestExampleImplementation) @@ -507,6 +537,7 @@ func Test_Mock_On_WithFuncPanics(t *testing.T) { } func Test_Mock_On_WithFuncTypeArg(t *testing.T) { + t.Parallel() // make a test impl object var mockedService = new(TestExampleImplementation) @@ -526,6 +557,8 @@ func Test_Mock_On_WithFuncTypeArg(t *testing.T) { } func Test_Mock_Unset(t *testing.T) { + t.Parallel() + // make a test impl object var mockedService = new(TestExampleImplementation) @@ -554,6 +587,8 @@ func Test_Mock_Unset(t *testing.T) { // Since every time you call On it creates a new object // the last time you call Unset it will only unset the last call func Test_Mock_Chained_UnsetOnlyUnsetsLastCall(t *testing.T) { + t.Parallel() + // make a test impl object var mockedService = new(TestExampleImplementation) @@ -588,6 +623,8 @@ func Test_Mock_Chained_UnsetOnlyUnsetsLastCall(t *testing.T) { } func Test_Mock_UnsetIfAlreadyUnsetFails(t *testing.T) { + t.Parallel() + // make a test impl object var mockedService = new(TestExampleImplementation) @@ -607,6 +644,8 @@ func Test_Mock_UnsetIfAlreadyUnsetFails(t *testing.T) { } func Test_Mock_UnsetByOnMethodSpec(t *testing.T) { + t.Parallel() + // make a test impl object var mockedService = new(TestExampleImplementation) @@ -628,6 +667,8 @@ func Test_Mock_UnsetByOnMethodSpec(t *testing.T) { } func Test_Mock_UnsetByOnMethodSpecAmongOthers(t *testing.T) { + t.Parallel() + // make a test impl object var mockedService = new(TestExampleImplementation) @@ -670,6 +711,8 @@ func Test_Mock_UnsetByOnMethodSpecAmongOthers(t *testing.T) { } func Test_Mock_Unset_WithFuncPanics(t *testing.T) { + t.Parallel() + // make a test impl object var mockedService = new(TestExampleImplementation) mock1 := mockedService.On("TheExampleMethod", 1) @@ -681,6 +724,7 @@ func Test_Mock_Unset_WithFuncPanics(t *testing.T) { } func Test_Mock_Return(t *testing.T) { + t.Parallel() // make a test impl object var mockedService = new(TestExampleImplementation) @@ -705,6 +749,7 @@ func Test_Mock_Return(t *testing.T) { } func Test_Mock_Panic(t *testing.T) { + t.Parallel() // make a test impl object var mockedService = new(TestExampleImplementation) @@ -728,6 +773,7 @@ func Test_Mock_Panic(t *testing.T) { } func Test_Mock_Return_WaitUntil(t *testing.T) { + t.Parallel() // make a test impl object var mockedService = new(TestExampleImplementation) @@ -755,6 +801,7 @@ func Test_Mock_Return_WaitUntil(t *testing.T) { } func Test_Mock_Return_After(t *testing.T) { + t.Parallel() // make a test impl object var mockedService = new(TestExampleImplementation) @@ -781,6 +828,7 @@ func Test_Mock_Return_After(t *testing.T) { } func Test_Mock_Return_Run(t *testing.T) { + t.Parallel() // make a test impl object var mockedService = new(TestExampleImplementation) @@ -813,6 +861,8 @@ func Test_Mock_Return_Run(t *testing.T) { } func Test_Mock_Return_Run_Out_Of_Order(t *testing.T) { + t.Parallel() + // make a test impl object var mockedService = new(TestExampleImplementation) f := func(args Arguments) { @@ -838,6 +888,7 @@ func Test_Mock_Return_Run_Out_Of_Order(t *testing.T) { } func Test_Mock_Return_Once(t *testing.T) { + t.Parallel() // make a test impl object var mockedService = new(TestExampleImplementation) @@ -862,6 +913,7 @@ func Test_Mock_Return_Once(t *testing.T) { } func Test_Mock_Return_Twice(t *testing.T) { + t.Parallel() // make a test impl object var mockedService = new(TestExampleImplementation) @@ -887,6 +939,7 @@ func Test_Mock_Return_Twice(t *testing.T) { } func Test_Mock_Return_Times(t *testing.T) { + t.Parallel() // make a test impl object var mockedService = new(TestExampleImplementation) @@ -912,6 +965,7 @@ func Test_Mock_Return_Times(t *testing.T) { } func Test_Mock_Return_Nothing(t *testing.T) { + t.Parallel() // make a test impl object var mockedService = new(TestExampleImplementation) @@ -932,6 +986,8 @@ func Test_Mock_Return_Nothing(t *testing.T) { } func Test_Mock_Return_NotBefore_In_Order(t *testing.T) { + t.Parallel() + var mockedService = new(TestExampleImplementation) b := mockedService. @@ -952,6 +1008,8 @@ func Test_Mock_Return_NotBefore_In_Order(t *testing.T) { } func Test_Mock_Return_InOrder_Uses_NotBefore(t *testing.T) { + t.Parallel() + var mockedService = new(TestExampleImplementation) InOrder( @@ -972,6 +1030,8 @@ func Test_Mock_Return_InOrder_Uses_NotBefore(t *testing.T) { } func Test_Mock_Return_NotBefore_Out_Of_Order(t *testing.T) { + t.Parallel() + var mockedService = new(TestExampleImplementation) b := mockedService. @@ -1002,6 +1062,8 @@ TheExampleMethod(int,int,int) } func Test_Mock_Return_InOrder_Uses_NotBefore_Out_Of_Order(t *testing.T) { + t.Parallel() + var mockedService = new(TestExampleImplementation) InOrder( @@ -1031,6 +1093,8 @@ TheExampleMethod(int,int,int) } func Test_Mock_Return_NotBefore_Not_Enough_Times(t *testing.T) { + t.Parallel() + var mockedService = new(TestExampleImplementation) b := mockedService. @@ -1064,6 +1128,8 @@ TheExampleMethod(int,int,int) } func Test_Mock_Return_NotBefore_Different_Mock_In_Order(t *testing.T) { + t.Parallel() + var ( mockedService1 = new(TestExampleImplementation) mockedService2 = new(TestExampleImplementation) @@ -1087,6 +1153,8 @@ func Test_Mock_Return_NotBefore_Different_Mock_In_Order(t *testing.T) { } func Test_Mock_Return_NotBefore_Different_Mock_Out_Of_Order(t *testing.T) { + t.Parallel() + var ( mockedService1 = new(TestExampleImplementation) mockedService2 = new(TestExampleImplementation) @@ -1120,6 +1188,8 @@ TheExampleMethod(int,int,int) } func Test_Mock_Return_NotBefore_In_Order_With_Non_Dependant(t *testing.T) { + t.Parallel() + var mockedService = new(TestExampleImplementation) a := mockedService. @@ -1160,6 +1230,8 @@ func Test_Mock_Return_NotBefore_In_Order_With_Non_Dependant(t *testing.T) { } func Test_Mock_Return_NotBefore_Orphan_Call(t *testing.T) { + t.Parallel() + var mockedService = new(TestExampleImplementation) require.PanicsWithValue(t, "not before calls must be created with Mock.On()", func() { @@ -1171,6 +1243,7 @@ func Test_Mock_Return_NotBefore_Orphan_Call(t *testing.T) { } func Test_Mock_findExpectedCall(t *testing.T) { + t.Parallel() m := new(Mock) m.On("One", 1).Return("one") @@ -1190,6 +1263,7 @@ func Test_Mock_findExpectedCall(t *testing.T) { } func Test_Mock_findExpectedCall_For_Unknown_Method(t *testing.T) { + t.Parallel() m := new(Mock) m.On("One", 1).Return("one") @@ -1203,6 +1277,7 @@ func Test_Mock_findExpectedCall_For_Unknown_Method(t *testing.T) { } func Test_Mock_findExpectedCall_Respects_Repeatability(t *testing.T) { + t.Parallel() m := new(Mock) m.On("One", 1).Return("one") @@ -1233,6 +1308,7 @@ func Test_Mock_findExpectedCall_Respects_Repeatability(t *testing.T) { } func Test_callString(t *testing.T) { + t.Parallel() assert.Equal(t, `Method(int,bool,string)`, callString("Method", []interface{}{1, true, "something"}, false)) assert.Equal(t, `Method()`, callString("Method", []interface{}{nil}, false)) @@ -1240,6 +1316,7 @@ func Test_callString(t *testing.T) { } func Test_Mock_Called(t *testing.T) { + t.Parallel() var mockedService = new(TestExampleImplementation) @@ -1267,6 +1344,7 @@ func asyncCall(m *Mock, ch chan Arguments) { } func Test_Mock_Called_blocks(t *testing.T) { + t.Parallel() var mockedService = new(TestExampleImplementation) @@ -1300,6 +1378,7 @@ func Test_Mock_Called_blocks(t *testing.T) { } func Test_Mock_Called_For_Bounded_Repeatability(t *testing.T) { + t.Parallel() var mockedService = new(TestExampleImplementation) @@ -1341,6 +1420,7 @@ func Test_Mock_Called_For_Bounded_Repeatability(t *testing.T) { } func Test_Mock_Called_For_SetTime_Expectation(t *testing.T) { + t.Parallel() var mockedService = new(TestExampleImplementation) @@ -1357,6 +1437,7 @@ func Test_Mock_Called_For_SetTime_Expectation(t *testing.T) { } func Test_Mock_Called_Unexpected(t *testing.T) { + t.Parallel() var mockedService = new(TestExampleImplementation) @@ -1368,6 +1449,7 @@ func Test_Mock_Called_Unexpected(t *testing.T) { } func Test_AssertExpectationsForObjects_Helper(t *testing.T) { + t.Parallel() var mockedService1 = new(TestExampleImplementation) var mockedService2 = new(TestExampleImplementation) @@ -1388,6 +1470,7 @@ func Test_AssertExpectationsForObjects_Helper(t *testing.T) { } func Test_AssertExpectationsForObjects_Helper_Failed(t *testing.T) { + t.Parallel() var mockedService1 = new(TestExampleImplementation) var mockedService2 = new(TestExampleImplementation) @@ -1407,6 +1490,7 @@ func Test_AssertExpectationsForObjects_Helper_Failed(t *testing.T) { } func Test_Mock_AssertExpectations(t *testing.T) { + t.Parallel() var mockedService = new(TestExampleImplementation) @@ -1424,6 +1508,7 @@ func Test_Mock_AssertExpectations(t *testing.T) { } func Test_Mock_AssertExpectations_Placeholder_NoArgs(t *testing.T) { + t.Parallel() var mockedService = new(TestExampleImplementation) @@ -1442,6 +1527,7 @@ func Test_Mock_AssertExpectations_Placeholder_NoArgs(t *testing.T) { } func Test_Mock_AssertExpectations_Placeholder(t *testing.T) { + t.Parallel() var mockedService = new(TestExampleImplementation) @@ -1465,6 +1551,7 @@ func Test_Mock_AssertExpectations_Placeholder(t *testing.T) { } func Test_Mock_AssertExpectations_With_Pointers(t *testing.T) { + t.Parallel() var mockedService = new(TestExampleImplementation) @@ -1486,6 +1573,7 @@ func Test_Mock_AssertExpectations_With_Pointers(t *testing.T) { } func Test_Mock_AssertExpectationsCustomType(t *testing.T) { + t.Parallel() var mockedService = new(TestExampleImplementation) @@ -1503,6 +1591,7 @@ func Test_Mock_AssertExpectationsCustomType(t *testing.T) { } func Test_Mock_AssertExpectationsFunctionalOptionsType(t *testing.T) { + t.Parallel() var mockedService = new(TestExampleImplementation) @@ -1520,6 +1609,7 @@ func Test_Mock_AssertExpectationsFunctionalOptionsType(t *testing.T) { } func Test_Mock_AssertExpectationsFunctionalOptionsType_Empty(t *testing.T) { + t.Parallel() var mockedService = new(TestExampleImplementation) @@ -1537,6 +1627,7 @@ func Test_Mock_AssertExpectationsFunctionalOptionsType_Empty(t *testing.T) { } func Test_Mock_AssertExpectationsFunctionalOptionsType_Indirectly(t *testing.T) { + t.Parallel() var mockedService = new(TestExampleImplementation) @@ -1554,6 +1645,7 @@ func Test_Mock_AssertExpectationsFunctionalOptionsType_Indirectly(t *testing.T) } func Test_Mock_AssertExpectationsFunctionalOptionsType_Diff_Func(t *testing.T) { + t.Parallel() var mockedService = new(TestExampleImplementation) @@ -1568,6 +1660,7 @@ func Test_Mock_AssertExpectationsFunctionalOptionsType_Diff_Func(t *testing.T) { } func Test_Mock_AssertExpectationsFunctionalOptionsType_Diff_Arg(t *testing.T) { + t.Parallel() var mockedService = new(TestExampleImplementation) @@ -1582,6 +1675,7 @@ func Test_Mock_AssertExpectationsFunctionalOptionsType_Diff_Arg(t *testing.T) { } func Test_Mock_AssertExpectations_With_Repeatability(t *testing.T) { + t.Parallel() var mockedService = new(TestExampleImplementation) @@ -1603,6 +1697,7 @@ func Test_Mock_AssertExpectations_With_Repeatability(t *testing.T) { } func Test_Mock_AssertExpectations_Skipped_Test(t *testing.T) { + t.Parallel() var mockedService = new(TestExampleImplementation) @@ -1613,6 +1708,7 @@ func Test_Mock_AssertExpectations_Skipped_Test(t *testing.T) { } func Test_Mock_TwoCallsWithDifferentArguments(t *testing.T) { + t.Parallel() var mockedService = new(TestExampleImplementation) @@ -1632,6 +1728,7 @@ func Test_Mock_TwoCallsWithDifferentArguments(t *testing.T) { } func Test_Mock_AssertNumberOfCalls(t *testing.T) { + t.Parallel() var mockedService = new(TestExampleImplementation) @@ -1646,6 +1743,7 @@ func Test_Mock_AssertNumberOfCalls(t *testing.T) { } func Test_Mock_AssertCalled(t *testing.T) { + t.Parallel() var mockedService = new(TestExampleImplementation) @@ -1658,6 +1756,7 @@ func Test_Mock_AssertCalled(t *testing.T) { } func Test_Mock_AssertCalled_WithAnythingOfTypeArgument(t *testing.T) { + t.Parallel() var mockedService = new(TestExampleImplementation) @@ -1672,6 +1771,7 @@ func Test_Mock_AssertCalled_WithAnythingOfTypeArgument(t *testing.T) { } func Test_Mock_AssertCalled_WithArguments(t *testing.T) { + t.Parallel() var mockedService = new(TestExampleImplementation) @@ -1686,6 +1786,7 @@ func Test_Mock_AssertCalled_WithArguments(t *testing.T) { } func Test_Mock_AssertCalled_WithArguments_With_Repeatability(t *testing.T) { + t.Parallel() var mockedService = new(TestExampleImplementation) @@ -1703,6 +1804,7 @@ func Test_Mock_AssertCalled_WithArguments_With_Repeatability(t *testing.T) { } func Test_Mock_AssertNotCalled(t *testing.T) { + t.Parallel() var mockedService = new(TestExampleImplementation) @@ -1715,6 +1817,8 @@ func Test_Mock_AssertNotCalled(t *testing.T) { } func Test_Mock_IsMethodCallable(t *testing.T) { + t.Parallel() + var mockedService = new(TestExampleImplementation) arg := []Call{{Repeatability: 1}, {Repeatability: 2}} @@ -1734,6 +1838,8 @@ func Test_Mock_IsMethodCallable(t *testing.T) { } func TestIsArgsEqual(t *testing.T) { + t.Parallel() + var expected = Arguments{5, 3, 4, 6, 7, 2} // Copy elements 1 to 5 @@ -1747,6 +1853,8 @@ func TestIsArgsEqual(t *testing.T) { } func Test_Mock_AssertOptional(t *testing.T) { + t.Parallel() + // Optional called var ms1 = new(TestExampleImplementation) ms1.On("TheExampleMethod", 1, 2, 3).Maybe().Return(4, nil) @@ -1775,6 +1883,7 @@ func Test_Mock_AssertOptional(t *testing.T) { Arguments helper methods */ func Test_Arguments_Get(t *testing.T) { + t.Parallel() var args = Arguments([]interface{}{"string", 123, true}) @@ -1785,6 +1894,7 @@ func Test_Arguments_Get(t *testing.T) { } func Test_Arguments_Is(t *testing.T) { + t.Parallel() var args = Arguments([]interface{}{"string", 123, true}) @@ -1794,6 +1904,7 @@ func Test_Arguments_Is(t *testing.T) { } func Test_Arguments_Diff(t *testing.T) { + t.Parallel() var args = Arguments([]interface{}{"Hello World", 123, true}) var diff string @@ -1807,6 +1918,7 @@ func Test_Arguments_Diff(t *testing.T) { } func Test_Arguments_Diff_DifferentNumberOfArgs(t *testing.T) { + t.Parallel() var args = Arguments([]interface{}{"string", 123, true}) var diff string @@ -1819,6 +1931,7 @@ func Test_Arguments_Diff_DifferentNumberOfArgs(t *testing.T) { } func Test_Arguments_Diff_WithAnythingArgument(t *testing.T) { + t.Parallel() var args = Arguments([]interface{}{"string", 123, true}) var count int @@ -1829,6 +1942,7 @@ func Test_Arguments_Diff_WithAnythingArgument(t *testing.T) { } func Test_Arguments_Diff_WithAnythingArgument_InActualToo(t *testing.T) { + t.Parallel() var args = Arguments([]interface{}{"string", Anything, true}) var count int @@ -1839,6 +1953,7 @@ func Test_Arguments_Diff_WithAnythingArgument_InActualToo(t *testing.T) { } func Test_Arguments_Diff_WithAnythingOfTypeArgument(t *testing.T) { + t.Parallel() var args = Arguments([]interface{}{"string", AnythingOfType("int"), true}) var count int @@ -1849,6 +1964,7 @@ func Test_Arguments_Diff_WithAnythingOfTypeArgument(t *testing.T) { } func Test_Arguments_Diff_WithAnythingOfTypeArgument_Failing(t *testing.T) { + t.Parallel() var args = Arguments([]interface{}{"string", AnythingOfType("string"), true}) var count int @@ -1861,6 +1977,8 @@ func Test_Arguments_Diff_WithAnythingOfTypeArgument_Failing(t *testing.T) { } func Test_Arguments_Diff_WithIsTypeArgument(t *testing.T) { + t.Parallel() + var args = Arguments([]interface{}{"string", IsType(0), true}) var count int _, count = args.Diff([]interface{}{"string", 123, true}) @@ -1869,6 +1987,8 @@ func Test_Arguments_Diff_WithIsTypeArgument(t *testing.T) { } func Test_Arguments_Diff_WithIsTypeArgument_Failing(t *testing.T) { + t.Parallel() + var args = Arguments([]interface{}{"string", IsType(""), true}) var count int var diff string @@ -1879,6 +1999,8 @@ func Test_Arguments_Diff_WithIsTypeArgument_Failing(t *testing.T) { } func Test_Arguments_Diff_WithArgMatcher(t *testing.T) { + t.Parallel() + matchFn := func(a int) bool { return a == 123 } @@ -1902,6 +2024,7 @@ func Test_Arguments_Diff_WithArgMatcher(t *testing.T) { } func Test_Arguments_Assert(t *testing.T) { + t.Parallel() var args = Arguments([]interface{}{"string", 123, true}) @@ -1910,6 +2033,7 @@ func Test_Arguments_Assert(t *testing.T) { } func Test_Arguments_String_Representation(t *testing.T) { + t.Parallel() var args = Arguments([]interface{}{"string", 123, true}) assert.Equal(t, `string,int,bool`, args.String()) @@ -1917,6 +2041,7 @@ func Test_Arguments_String_Representation(t *testing.T) { } func Test_Arguments_String(t *testing.T) { + t.Parallel() var args = Arguments([]interface{}{"string", 123, true}) assert.Equal(t, "string", args.String(0)) @@ -1924,6 +2049,7 @@ func Test_Arguments_String(t *testing.T) { } func Test_Arguments_Error(t *testing.T) { + t.Parallel() var err = errors.New("An Error") var args = Arguments([]interface{}{"string", 123, true, err}) @@ -1932,6 +2058,7 @@ func Test_Arguments_Error(t *testing.T) { } func Test_Arguments_Error_Nil(t *testing.T) { + t.Parallel() var args = Arguments([]interface{}{"string", 123, true, nil}) assert.Equal(t, nil, args.Error(3)) @@ -1939,6 +2066,7 @@ func Test_Arguments_Error_Nil(t *testing.T) { } func Test_Arguments_Int(t *testing.T) { + t.Parallel() var args = Arguments([]interface{}{"string", 123, true}) assert.Equal(t, 123, args.Int(1)) @@ -1946,6 +2074,7 @@ func Test_Arguments_Int(t *testing.T) { } func Test_Arguments_Bool(t *testing.T) { + t.Parallel() var args = Arguments([]interface{}{"string", 123, true}) assert.Equal(t, true, args.Bool(2)) @@ -1953,6 +2082,7 @@ func Test_Arguments_Bool(t *testing.T) { } func Test_WaitUntil_Parallel(t *testing.T) { + t.Parallel() // make a test impl object var mockedService = new(TestExampleImplementation) @@ -1979,6 +2109,8 @@ func Test_WaitUntil_Parallel(t *testing.T) { } func Test_MockMethodCalled(t *testing.T) { + t.Parallel() + m := new(Mock) m.On("foo", "hello").Return("world") @@ -1989,6 +2121,8 @@ func Test_MockMethodCalled(t *testing.T) { } func Test_MockMethodCalled_Panic(t *testing.T) { + t.Parallel() + m := new(Mock) m.On("foo", "hello").Panic("world panics") @@ -1998,6 +2132,8 @@ func Test_MockMethodCalled_Panic(t *testing.T) { // Test to validate fix for racy concurrent call access in MethodCalled() func Test_MockReturnAndCalledConcurrent(t *testing.T) { + t.Parallel() + iterations := 1000 m := &Mock{} call := m.On("ConcurrencyTestMethod") @@ -2048,6 +2184,8 @@ func (tc *tCustomLogger) Errorf(format string, args ...interface{}) { func (tc *tCustomLogger) FailNow() {} func TestLoggingAssertExpectations(t *testing.T) { + t.Parallel() + m := new(timer) m.On("GetTime", 0).Return("") tcl := &tCustomLogger{t, []string{}, []string{}} @@ -2062,6 +2200,8 @@ func TestLoggingAssertExpectations(t *testing.T) { } func TestAfterTotalWaitTimeWhileExecution(t *testing.T) { + t.Parallel() + waitDuration := 1 total, waitMs := 5, time.Millisecond*time.Duration(waitDuration) aTimer := new(timer) @@ -2086,6 +2226,8 @@ func TestAfterTotalWaitTimeWhileExecution(t *testing.T) { } func TestArgumentMatcherToPrintMismatch(t *testing.T) { + t.Parallel() + defer func() { if r := recover(); r != nil { matchingExp := regexp.MustCompile( @@ -2103,6 +2245,8 @@ func TestArgumentMatcherToPrintMismatch(t *testing.T) { } func TestArgumentMatcherToPrintMismatchWithReferenceType(t *testing.T) { + t.Parallel() + defer func() { if r := recover(); r != nil { matchingExp := regexp.MustCompile( @@ -2120,6 +2264,8 @@ func TestArgumentMatcherToPrintMismatchWithReferenceType(t *testing.T) { } func TestClosestCallMismatchedArgumentInformationShowsTheClosest(t *testing.T) { + t.Parallel() + defer func() { if r := recover(); r != nil { matchingExp := regexp.MustCompile(unexpectedCallRegex(`TheExampleMethod(int,int,int)`, `0: 1\s+1: 1\s+2: 2`, `0: 1\s+1: 1\s+2: 1`, `Diff: 0: PASS: \(int=1\) == \(int=1\)\s+1: PASS: \(int=1\) == \(int=1\)\s+2: FAIL: \(int=2\) != \(int=1\)`)) @@ -2135,6 +2281,8 @@ func TestClosestCallMismatchedArgumentInformationShowsTheClosest(t *testing.T) { } func TestClosestCallFavorsFirstMock(t *testing.T) { + t.Parallel() + defer func() { if r := recover(); r != nil { diffRegExp := `Difference found in argument 0:\s+--- Expected\s+\+\+\+ Actual\s+@@ -2,4 \+2,4 @@\s+\(bool\) true,\s+- \(bool\) true,\s+- \(bool\) true\s+\+ \(bool\) false,\s+\+ \(bool\) false\s+}\s+Diff: 0: FAIL: \(\[\]bool=\[(true\s?|false\s?){3}]\) != \(\[\]bool=\[(true\s?|false\s?){3}\]\)` @@ -2151,6 +2299,8 @@ func TestClosestCallFavorsFirstMock(t *testing.T) { } func TestClosestCallUsesRepeatabilityToFindClosest(t *testing.T) { + t.Parallel() + defer func() { if r := recover(); r != nil { diffRegExp := `Difference found in argument 0:\s+--- Expected\s+\+\+\+ Actual\s+@@ -1,4 \+1,4 @@\s+\(\[\]bool\) \(len=3\) {\s+- \(bool\) false,\s+- \(bool\) false,\s+\+ \(bool\) true,\s+\+ \(bool\) true,\s+\(bool\) false\s+Diff: 0: FAIL: \(\[\]bool=\[(true\s?|false\s?){3}]\) != \(\[\]bool=\[(true\s?|false\s?){3}\]\)` @@ -2171,6 +2321,8 @@ func TestClosestCallUsesRepeatabilityToFindClosest(t *testing.T) { } func TestClosestCallMismatchedArgumentValueInformation(t *testing.T) { + t.Parallel() + defer func() { if r := recover(); r != nil { matchingExp := regexp.MustCompile(unexpectedCallRegex(`GetTime(int)`, "0: 1", "0: 999", `Diff: 0: FAIL: \(int=1\) != \(int=999\)`)) @@ -2185,26 +2337,38 @@ func TestClosestCallMismatchedArgumentValueInformation(t *testing.T) { } func Test_isBetterMatchThanReturnsFalseIfCandidateCallIsNil(t *testing.T) { + t.Parallel() + assert.False(t, matchCandidate{}.isBetterMatchThan(matchCandidate{})) } func Test_isBetterMatchThanReturnsTrueIfOtherCandidateCallIsNil(t *testing.T) { + t.Parallel() + assert.True(t, matchCandidate{call: &Call{}}.isBetterMatchThan(matchCandidate{})) } func Test_isBetterMatchThanReturnsFalseIfDiffCountIsGreaterThanOther(t *testing.T) { + t.Parallel() + assert.False(t, matchCandidate{call: &Call{}, diffCount: 2}.isBetterMatchThan(matchCandidate{call: &Call{}, diffCount: 1})) } func Test_isBetterMatchThanReturnsTrueIfDiffCountIsLessThanOther(t *testing.T) { + t.Parallel() + assert.True(t, matchCandidate{call: &Call{}, diffCount: 1}.isBetterMatchThan(matchCandidate{call: &Call{}, diffCount: 2})) } func Test_isBetterMatchThanReturnsTrueIfRepeatabilityIsGreaterThanOther(t *testing.T) { + t.Parallel() + assert.True(t, matchCandidate{call: &Call{Repeatability: 1}, diffCount: 1}.isBetterMatchThan(matchCandidate{call: &Call{Repeatability: -1}, diffCount: 1})) } func Test_isBetterMatchThanReturnsFalseIfRepeatabilityIsLessThanOrEqualToOther(t *testing.T) { + t.Parallel() + assert.False(t, matchCandidate{call: &Call{Repeatability: 1}, diffCount: 1}.isBetterMatchThan(matchCandidate{call: &Call{Repeatability: 1}, diffCount: 1})) } @@ -2220,6 +2384,8 @@ func ConcurrencyTestMethod(m *Mock) { } func TestConcurrentArgumentRead(t *testing.T) { + t.Parallel() + methodUnderTest := func(c caller, u user) { go u.Use(c) c.Call() From 82767aed18541a8271db7757a5140894b469e0ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Tue, 27 May 2025 17:54:26 +0200 Subject: [PATCH 123/178] suite: cleanup use of 'testing' internals at runtime Cleanup runtime use of stdlib's testing internals which was required for older Go versions. Note: we are still using testing.RunTests in the suite's test suite for now. --- suite/suite.go | 30 +++++++++++------------------- suite/suite_test.go | 5 +++++ 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/suite/suite.go b/suite/suite.go index 18443a91c..7c79250bb 100644 --- a/suite/suite.go +++ b/suite/suite.go @@ -15,7 +15,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 +115,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) { @@ -131,7 +135,7 @@ func Run(t *testing.T, suite TestingSuite) { stats = newSuiteInformation() } - tests := []testing.InternalTest{} + var tests []test methodFinder := reflect.TypeOf(suite) suiteName := methodFinder.Elem().Name() @@ -160,9 +164,9 @@ func Run(t *testing.T, suite TestingSuite) { 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) @@ -229,25 +233,13 @@ func methodFilter(name string) (bool, error) { 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 -} diff --git a/suite/suite_test.go b/suite/suite_test.go index eceecb622..6cf23459f 100644 --- a/suite/suite_test.go +++ b/suite/suite_test.go @@ -16,6 +16,11 @@ import ( "github.com/stretchr/testify/require" ) +// allTestsFilter is a yes filter for testing.RunTests +func allTestsFilter(pat, str string) (bool, error) { + return true, nil +} + // SuiteRequireTwice is intended to test the usage of suite.Require in two // different tests type SuiteRequireTwice struct{ Suite } From 250eaa5e06e4976625f91ca3ac9c4262ab7f8a3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Mon, 4 Mar 2024 23:58:37 +0100 Subject: [PATCH 124/178] deps: fix dependency cycle with objx $ go mod edit -dropexclude=github.com/stretchr/testify@v1.8.0 -exclude=github.com/stretchr/testify@v1.8.4 $ go mod tidy See https://github.com/stretchr/objx/pull/140 --- go.mod | 2 +- go.sum | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 943798ea7..16a61cc3c 100644 --- a/go.mod +++ b/go.mod @@ -13,4 +13,4 @@ require ( // Break dependency cycle with objx. // See https://github.com/stretchr/objx/pull/140 -exclude github.com/stretchr/testify v1.8.2 +exclude github.com/stretchr/testify v1.8.4 diff --git a/go.sum b/go.sum index d42acda31..3ba5aea30 100644 --- a/go.sum +++ b/go.sum @@ -1,18 +1,10 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 553e822bab7044a749c7ae15f08b9e266fd56cdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Sun, 25 May 2025 22:09:43 +0200 Subject: [PATCH 125/178] go.mod: add comment about how to fix dep cycle with objx --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 16a61cc3c..f4657c9bf 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ go 1.17 require ( github.com/davecgh/go-spew v1.1.1 github.com/pmezard/go-difflib v1.0.0 - github.com/stretchr/objx v0.5.2 + github.com/stretchr/objx v0.5.2 // To avoid a cycle the version of testify used by objx should be excluded below gopkg.in/yaml.v3 v3.0.1 ) From c519b7942b86df5b70eca5687be814cd2e596417 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Wed, 28 May 2025 16:08:21 +0200 Subject: [PATCH 126/178] assert.Empty: comprehensive doc of "Empty"-ness rules Document the assert.Empty rules more comprehensively. This exposes our quirks to the user to avoid wrong expectations. Add many many many more test cases that document edges cases and will allow to catch breaking changes and avoid regressions. --- assert/assertion_format.go | 16 ++++-- assert/assertion_forward.go | 32 +++++++++--- assert/assertions.go | 16 ++++-- assert/assertions_test.go | 97 ++++++++++++++++++++++++++++++++++++- require/require.go | 32 +++++++++--- require/require_forward.go | 32 +++++++++--- 6 files changed, 192 insertions(+), 33 deletions(-) diff --git a/assert/assertion_format.go b/assert/assertion_format.go index 714404125..c592f6ad5 100644 --- a/assert/assertion_format.go +++ b/assert/assertion_format.go @@ -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() @@ -595,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]) diff --git a/assert/assertion_forward.go b/assert/assertion_forward.go index 38e253ebb..58db92845 100644 --- a/assert/assertion_forward.go +++ b/assert/assertion_forward.go @@ -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() @@ -1182,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]) @@ -1195,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]) diff --git a/assert/assertions.go b/assert/assertions.go index 9913ac2f0..46582060d 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -773,10 +773,19 @@ func isEmpty(object interface{}) bool { } } -// 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". // // 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 { @@ -789,8 +798,7 @@ 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]) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 955188d5a..d30eef60d 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -1728,24 +1728,119 @@ func Test_isEmpty(t *testing.T) { True(t, isEmpty("")) True(t, isEmpty(nil)) + True(t, isEmpty(error(nil))) + True(t, isEmpty((*int)(nil))) + True(t, isEmpty((*string)(nil))) + True(t, isEmpty(new(string))) True(t, isEmpty([]string{})) + True(t, isEmpty([]string(nil))) + True(t, isEmpty([]byte(nil))) + True(t, isEmpty([]byte{})) + True(t, isEmpty([]byte(""))) + True(t, isEmpty([]bool(nil))) + True(t, isEmpty([]bool{})) + True(t, isEmpty([]interface{}(nil))) + True(t, isEmpty([]interface{}{})) + True(t, isEmpty(struct{}{})) + True(t, isEmpty(&struct{}{})) + True(t, isEmpty(struct{ A int }{A: 0})) + True(t, isEmpty(struct{ a int }{a: 0})) + True(t, isEmpty(struct { + a int + B int + }{a: 0, B: 0})) True(t, isEmpty(0)) + True(t, isEmpty(int(0))) + True(t, isEmpty(int8(0))) + True(t, isEmpty(int16(0))) + True(t, isEmpty(uint16(0))) True(t, isEmpty(int32(0))) + True(t, isEmpty(uint32(0))) True(t, isEmpty(int64(0))) + True(t, isEmpty(uint64(0))) + True(t, isEmpty('\u0000')) // rune => int32 + True(t, isEmpty(float32(0))) + True(t, isEmpty(float64(0))) + True(t, isEmpty(0i)) // complex + True(t, isEmpty(0.0i)) // complex True(t, isEmpty(false)) + True(t, isEmpty(new(bool))) True(t, isEmpty(map[string]string{})) + True(t, isEmpty(map[string]string(nil))) True(t, isEmpty(new(time.Time))) True(t, isEmpty(time.Time{})) True(t, isEmpty(make(chan struct{}))) - True(t, isEmpty([1]int{})) + True(t, isEmpty(chan struct{}(nil))) + True(t, isEmpty(chan<- struct{}(nil))) + True(t, isEmpty(make(chan struct{}))) + True(t, isEmpty(make(chan<- struct{}))) + True(t, isEmpty(make(chan struct{}, 1))) + True(t, isEmpty(make(chan<- struct{}, 1))) + True(t, isEmpty([1]int{0})) + True(t, isEmpty([2]int{0, 0})) + True(t, isEmpty([8]int{})) + True(t, isEmpty([...]int{7: 0})) + True(t, isEmpty([...]bool{false, false})) + True(t, isEmpty(errors.New(""))) // BEWARE + True(t, isEmpty([]error{})) + True(t, isEmpty([]error(nil))) + True(t, isEmpty(&[1]int{0})) + True(t, isEmpty(&[2]int{0, 0})) False(t, isEmpty("something")) False(t, isEmpty(errors.New("something"))) False(t, isEmpty([]string{"something"})) False(t, isEmpty(1)) + False(t, isEmpty(int(1))) + False(t, isEmpty(uint(1))) + False(t, isEmpty(byte(1))) + False(t, isEmpty(int8(1))) + False(t, isEmpty(uint8(1))) + False(t, isEmpty(int16(1))) + False(t, isEmpty(uint16(1))) + False(t, isEmpty(int32(1))) + False(t, isEmpty(uint32(1))) + False(t, isEmpty(int64(1))) + False(t, isEmpty(uint64(1))) + False(t, isEmpty('A')) // rune => int32 False(t, isEmpty(true)) + False(t, isEmpty(1.0)) + False(t, isEmpty(1i)) // complex + False(t, isEmpty([]byte{0})) // elements values are ignored for slices + False(t, isEmpty([]byte{0, 0})) // elements values are ignored for slices + False(t, isEmpty([]string{""})) // elements values are ignored for slices + False(t, isEmpty([]string{"a"})) // elements values are ignored for slices + False(t, isEmpty([]bool{false})) // elements values are ignored for slices + False(t, isEmpty([]bool{true})) // elements values are ignored for slices + False(t, isEmpty([]error{errors.New("xxx")})) + False(t, isEmpty([]error{nil})) // BEWARE + False(t, isEmpty([]error{errors.New("")})) // BEWARE False(t, isEmpty(map[string]string{"Hello": "World"})) + False(t, isEmpty(map[string]string{"": ""})) + False(t, isEmpty(map[string]string{"foo": ""})) + False(t, isEmpty(map[string]string{"": "foo"})) False(t, isEmpty(chWithValue)) + False(t, isEmpty([1]bool{true})) + False(t, isEmpty([2]bool{false, true})) + False(t, isEmpty([...]bool{10: true})) + False(t, isEmpty([]int{0})) + False(t, isEmpty([]int{42})) False(t, isEmpty([1]int{42})) + False(t, isEmpty([2]int{0, 42})) + False(t, isEmpty(&[1]int{42})) + False(t, isEmpty(&[2]int{0, 42})) + False(t, isEmpty([1]*int{new(int)})) // array elements must be the zero value, not any Empty value + False(t, isEmpty(struct{ A int }{A: 42})) + False(t, isEmpty(struct{ a int }{a: 42})) + False(t, isEmpty(struct{ a *int }{a: new(int)})) // fields must be the zero value, not any Empty value + False(t, isEmpty(struct{ a []int }{a: []int{}})) // fields must be the zero value, not any Empty value + False(t, isEmpty(struct { + a int + B int + }{a: 0, B: 42})) + False(t, isEmpty(struct { + a int + B int + }{a: 42, B: 0})) } func TestEmpty(t *testing.T) { diff --git a/require/require.go b/require/require.go index 6cd133417..2d02f9bce 100644 --- a/require/require.go +++ b/require/require.go @@ -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() @@ -1495,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]) @@ -1511,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]) diff --git a/require/require_forward.go b/require/require_forward.go index f6192dfea..e6f7e9446 100644 --- a/require/require_forward.go +++ b/require/require_forward.go @@ -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() @@ -1183,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]) @@ -1196,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]) From 7a1b408b7ce1b78ce3df4354561e233a8f6ebb4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Mon, 2 Jun 2025 18:43:02 +0200 Subject: [PATCH 127/178] doc: improve godoc of top level 'testify' package --- doc.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/doc.go b/doc.go index babc122f2..2076714cc 100644 --- a/doc.go +++ b/doc.go @@ -1,15 +1,17 @@ -// Package testify is a set of packages that provide many tools for testifying that your code will behave as you intend. +// Module testify is a set of packages that provide many tools for testifying that your code will behave as you intend. // -// testify contains the following packages: +// Testify contains the following packages: // -// The assert package provides a comprehensive set of assertion functions that tie in to the Go testing system. +// The [github.com/stretchr/testify/assert] package provides a comprehensive set of assertion functions that tie in to [the Go testing system]. +// The [github.com/stretchr/testify/require] package provides the same assertions but as fatal checks. // -// The mock package provides a system by which it is possible to mock your objects and verify calls are happening as expected. +// The [github.com/stretchr/testify/mock] package provides a system by which it is possible to mock your objects and verify calls are happening as expected. // -// The suite package provides a basic structure for using structs as testing suites, and methods on those structs as tests. It includes setup/teardown functionality in the way of interfaces. +// The [github.com/stretchr/testify/suite] package provides a basic structure for using structs as testing suites, and methods on those structs as tests. It includes setup/teardown functionality in the way of interfaces. // // A [golangci-lint] compatible linter for testify is available called [testifylint]. // +// [the Go testing system]: https://go.dev/doc/code#Testing // [golangci-lint]: https://golangci-lint.run/ // [testifylint]: https://github.com/Antonboom/testifylint package testify From 0b5b5e64f9089682f5442f1c7d7826055bcfa95f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Tue, 3 Jun 2025 14:48:27 +0200 Subject: [PATCH 128/178] assert: add Benchmark_isEmpty Add a benchmark that shows that isEmpty does memory allocations. $ go test -bench Benchmark_isEmpty goos: darwin goarch: arm64 pkg: github.com/stretchr/testify/assert cpu: Apple M2 Benchmark_isEmpty-8 15074973 76.73 ns/op 8 B/op 1 allocs/op We can do better! --- assert/assertions_test.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index d30eef60d..fb3a17bc8 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -1843,6 +1843,19 @@ func Test_isEmpty(t *testing.T) { }{a: 42, B: 0})) } +func Benchmark_isEmpty(b *testing.B) { + b.ReportAllocs() + + v := new(int) + b.ResetTimer() + + for i := 0; i < b.N; i++ { + isEmpty("") + isEmpty(42) + isEmpty(v) + } +} + func TestEmpty(t *testing.T) { t.Parallel() From 890082edf27321913428f3e42d9cf4bab4fc6127 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Tue, 3 Jun 2025 14:04:04 +0200 Subject: [PATCH 129/178] assert.Empty: refactor isEmpty (1) Refactor isEmpty to extract func isEmptyValue. This allows to avoid unwrapping/wrapping when checking pointer values. --- assert/assertions.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index 46582060d..ec055a8ed 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -752,8 +752,11 @@ func isEmpty(object interface{}) bool { return true } - objValue := reflect.ValueOf(object) + return isEmptyValue(reflect.ValueOf(object)) +} +// isEmptyValue gets whether the specified reflect.Value is considered empty or not. +func isEmptyValue(objValue reflect.Value) bool { switch objValue.Kind() { // collection types are empty when they have no element case reflect.Chan, reflect.Map, reflect.Slice: @@ -763,13 +766,12 @@ func isEmpty(object interface{}) bool { if objValue.IsNil() { return true } - deref := objValue.Elem().Interface() - return isEmpty(deref) + return isEmptyValue(objValue.Elem()) // 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 reflect.DeepEqual(objValue.Interface(), zero.Interface()) } } From acd15f60531b8cb26b566c9e8aa482dbf7a906df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Tue, 3 Jun 2025 14:18:57 +0200 Subject: [PATCH 130/178] assert.Empty: refactor using reflect.Value.IsZero() Simplify isEmptyValue (used by assert.Empty) by checking early if the value is the zero value of the type using reflect.Value.IsZero (available since Go 1.13, so after the initial assert.Empty implementation). isEmpty is now faster. go test -bench Benchmark_isEmpty goos: darwin goarch: arm64 pkg: github.com/stretchr/testify/assert cpu: Apple M2 Before: Benchmark_isEmpty-8 15841243 77.27 ns/op 8 B/op 1 allocs/op After Benchmark_isEmpty-8 50665512 21.08 ns/op 0 B/op 0 allocs/op --- assert/assertions.go | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index ec055a8ed..effccc0eb 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -757,22 +757,20 @@ func isEmpty(object interface{}) bool { // 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 - // pointers are empty if nil or if the value they point to is empty + // non-nil pointers are empty if the value they point to is empty case reflect.Ptr: - if objValue.IsNil() { - return true - } return isEmptyValue(objValue.Elem()) - // 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(objValue.Interface(), zero.Interface()) } + return false } // Empty asserts that the given value is "empty". From 7127b6099902025b069e842d93bcdd6e8462eb5c Mon Sep 17 00:00:00 2001 From: ccoVeille <3875889+ccoVeille@users.noreply.github.com> Date: Tue, 13 May 2025 14:41:26 +0200 Subject: [PATCH 131/178] assert.ErrorAs: simplify retrieving the type name --- assert/assertions.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index effccc0eb..0514a154e 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -2225,17 +2225,17 @@ func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{ return true } - expectedText := reflect.ValueOf(target).Elem().Type().String() + expectedType := reflect.TypeOf(target).Elem().String() if err == nil { return Fail(t, fmt.Sprintf("An error is expected but got nil.\n"+ - "expected: %s", expectedText), msgAndArgs...) + "expected: %s", expectedType), msgAndArgs...) } chain := buildErrorChainString(err, true) return Fail(t, fmt.Sprintf("Should be in error chain:\n"+ "expected: %s\n"+ - "in chain: %s", expectedText, chain, + "in chain: %s", expectedType, chain, ), msgAndArgs...) } @@ -2253,7 +2253,7 @@ func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interfa return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+ "found: %s\n"+ - "in chain: %s", reflect.ValueOf(target).Elem().Type(), chain, + "in chain: %s", reflect.TypeOf(target).Elem().String(), chain, ), msgAndArgs...) } From 5488b2163b7c0ae12489472f5644661a56aa2bd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Wed, 4 Jun 2025 22:35:34 +0000 Subject: [PATCH 132/178] assert: improve EqualValues test coverage to 100% MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extend TestNotEqualValues to also test EqualValues by leveraging the fact that they are inverse functions. The same test cases are used to verify that EqualValues returns the opposite result of NotEqualValues. This change ensures both success and failure paths are tested for EqualValues, covering the error formatting and failure reporting code that was previously untested. Coverage improvement: - EqualValues: 57.1% → 100.0% - Overall package: 68.4% → 68.5% The test function was renamed to TestEqualValuesAndNotEqualValues to reflect its dual purpose while maintaining all existing test logic. Co-Authored-By: sketch Change-ID: s30d4192b08186d88k --- assert/assertions_test.go | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index fb3a17bc8..fc0f215b5 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -978,15 +978,15 @@ func TestNotEqual(t *testing.T) { } } -func TestNotEqualValues(t *testing.T) { +func TestEqualValuesAndNotEqualValues(t *testing.T) { t.Parallel() mockT := new(testing.T) cases := []struct { - expected interface{} - actual interface{} - result bool + expected interface{} + actual interface{} + notEqualResult bool // result for NotEqualValues }{ // cases that are expected not to match {"Hello World", "Hello World!", true}, @@ -1013,11 +1013,22 @@ func TestNotEqualValues(t *testing.T) { } for _, c := range cases { + // Test NotEqualValues t.Run(fmt.Sprintf("NotEqualValues(%#v, %#v)", c.expected, c.actual), func(t *testing.T) { res := NotEqualValues(mockT, c.expected, c.actual) - if res != c.result { - t.Errorf("NotEqualValues(%#v, %#v) should return %#v", c.expected, c.actual, c.result) + if res != c.notEqualResult { + t.Errorf("NotEqualValues(%#v, %#v) should return %#v", c.expected, c.actual, c.notEqualResult) + } + }) + + // Test EqualValues (inverse of NotEqualValues) + t.Run(fmt.Sprintf("EqualValues(%#v, %#v)", c.expected, c.actual), func(t *testing.T) { + expectedEqualResult := !c.notEqualResult // EqualValues should return opposite of NotEqualValues + res := EqualValues(mockT, c.expected, c.actual) + + if res != expectedEqualResult { + t.Errorf("EqualValues(%#v, %#v) should return %#v", c.expected, c.actual, expectedEqualResult) } }) } From b50b016f5259bddde36ba5f07c0a8c9585c6ca99 Mon Sep 17 00:00:00 2001 From: renzoarreaza Date: Thu, 19 Jun 2025 10:18:00 +0200 Subject: [PATCH 133/178] suite.Run: simplify running of Setup/TeardownSuite (#1769) ## Summary Improve readability of suite.Run by moving the running of SetupSuite outside of the loop iterating over the (test) methods. This also allows for other simplifications further down in the code. ## Changes - Move SetupSuite to outside the loop - Don't run Setup/TeardownSuite if no tests are found (not new behaviour, but new check) - Remove variable to keep track of wether SetupSuite was executed or not ## Motivation This is a subset of the changes I made under PR #1749. It was suggested by @dolmen to open a separate PR for this part. ## Related issues N/A --- suite/suite.go | 47 ++++++++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/suite/suite.go b/suite/suite.go index 7c79250bb..a7ceba731 100644 --- a/suite/suite.go +++ b/suite/suite.go @@ -128,8 +128,6 @@ 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() @@ -152,18 +150,6 @@ func Run(t *testing.T, suite TestingSuite) { continue } - if !suiteSetupDone { - if stats != nil { - stats.Start = time.Now() - } - - if setupAllSuite, ok := suite.(SetupAllSuite); ok { - setupAllSuite.SetupSuite() - } - - suiteSetupDone = true - } - test := test{ name: method.Name, run: func(t *testing.T) { @@ -208,19 +194,30 @@ func Run(t *testing.T, suite TestingSuite) { } 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) } From 5c949551ee9608c5eb900229b79cbd5a548f9066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Mon, 16 Jun 2025 16:06:59 +0200 Subject: [PATCH 134/178] assert.CallerInfo: micro optimization by using LastIndexByte Use strings.LastIndexByte instead of strings.Split to extract the function name in CallerInfo. This reduces memory allocations. --- assert/assertions.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index 0514a154e..5e9cb6e5d 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -266,8 +266,8 @@ func CallerInfo() []string { } // Drop the package - segments := strings.Split(name, ".") - name = segments[len(segments)-1] + dotPos := strings.LastIndexByte(name, '.') + name = name[dotPos+1:] if isTest(name, "Test") || isTest(name, "Benchmark") || isTest(name, "Example") { From fac5d473cb5e005ada6ce0bce89e1e76fce8d51c Mon Sep 17 00:00:00 2001 From: vyas-git Date: Tue, 24 Jun 2025 09:01:02 +0530 Subject: [PATCH 135/178] invalid method test signatures fails as subtest, other continues --- suite/suite.go | 14 +++++++++- suite/suite_test.go | 62 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/suite/suite.go b/suite/suite.go index a7ceba731..41bdb8f2a 100644 --- a/suite/suite.go +++ b/suite/suite.go @@ -149,7 +149,19 @@ func Run(t *testing.T, suite TestingSuite) { if !ok { continue } - + // Check method signature + if method.Type.NumIn() > 1 || method.Type.NumOut() > 0 { + tests = append(tests, test{ + name: method.Name, + run: func(t *testing.T) { + t.Errorf( + "testify: suite method %q has invalid signature: expected no inputs or return values (has %d inputs, %d outputs)", + method.Name, method.Type.NumIn()-1, method.Type.NumOut(), + ) + }, + }) + continue + } test := test{ name: method.Name, run: func(t *testing.T) { diff --git a/suite/suite_test.go b/suite/suite_test.go index 6cf23459f..1c193aaf2 100644 --- a/suite/suite_test.go +++ b/suite/suite_test.go @@ -751,3 +751,65 @@ func TestUnInitializedSuites(t *testing.T) { }) }) } + +// SuiteSignatureValidationTester tests valid and invalid method signatures. +type SuiteSignatureValidationTester struct { + Suite + + executedTestCount int + setUp bool + toreDown bool +} + +// SetupSuite runs once before any tests. +func (s *SuiteSignatureValidationTester) SetupSuite() { + s.setUp = true +} + +// TearDownSuite runs once after all tests. +func (s *SuiteSignatureValidationTester) TearDownSuite() { + s.toreDown = true +} + +// Valid test method — should run. +func (s *SuiteSignatureValidationTester) TestValidSignature() { + s.executedTestCount++ +} + +// Invalid: has return value. +func (s *SuiteSignatureValidationTester) TestInvalidSignatureReturnValue() interface{} { + s.executedTestCount++ + return nil +} + +// Invalid: has input arg. +func (s *SuiteSignatureValidationTester) TestInvalidSignatureArg(somearg string) { + s.executedTestCount++ +} + +// Invalid: both input arg and return value. +func (s *SuiteSignatureValidationTester) TestInvalidSignatureBoth(somearg string) interface{} { + s.executedTestCount++ + return nil +} + +// TestSuiteSignatureValidation ensures that invalid signature methods fail and valid method runs. +func TestSuiteSignatureValidation(t *testing.T) { + suiteTester := new(SuiteSignatureValidationTester) + + ok := testing.RunTests(allTestsFilter, []testing.InternalTest{ + { + Name: "signature validation", + F: func(t *testing.T) { + Run(t, suiteTester) + }, + }, + }) + + require.False(t, ok, "Suite should fail due to invalid method signatures") + + assert.Equal(t, 1, suiteTester.executedTestCount, "Only the valid test method should have been executed") + + assert.True(t, suiteTester.setUp, "SetupSuite should have been executed") + assert.True(t, suiteTester.toreDown, "TearDownSuite should have been executed") +} From 6c516f8b1d6ea35f94dd17dbf9b459487569085b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Mon, 16 Jun 2025 16:26:48 +0200 Subject: [PATCH 136/178] assert.CallerInfo: cleanup Move the stackFrameBufferSize const which was in package scope but used only by CallerInfo, into CallerInfo body. --- assert/assertions.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index 5e9cb6e5d..de8de0cb6 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -24,8 +24,6 @@ import ( "github.com/stretchr/testify/assert/yaml" ) -const stackFrameBufferSize = 10 - //go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=assert -template=assertion_format.go.tmpl" // TestingT is an interface wrapper around *testing.T @@ -217,8 +215,10 @@ func CallerInfo() []string { var line int var name string - callers := []string{} + const stackFrameBufferSize = 10 pcs := make([]uintptr, stackFrameBufferSize) + + callers := []string{} offset := 1 for { @@ -273,13 +273,14 @@ func CallerInfo() []string { isTest(name, "Example") { break } + if !more { break } } - // We know we already have less than a buffer's worth of frames - offset += stackFrameBufferSize + // Next batch + offset += cap(pcs) } return callers From d9125497d74d7133321f88bd9c03ca4dcac11754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Mon, 16 Jun 2025 12:06:06 +0200 Subject: [PATCH 137/178] assert/tests: enable parallel testing for Test{,No}{File,Dir}Exists In package assert, fix TestFileExists, TestNoFileExists, TestDirExists, TestNoDirExists to be able to run in parallel: - use t.TempDir() as the storage location for temporary created symlinks. This also allows the cleanup of that storage to be automatically handled by "go test". testing.T.TempDir is available since go1.15. - enable parallel testing on each test --- assert/assertions_test.go | 76 ++++++++------------------------------- 1 file changed, 15 insertions(+), 61 deletions(-) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index fc0f215b5..7e626f512 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -2579,7 +2579,7 @@ func TestNotZero(t *testing.T) { } func TestFileExists(t *testing.T) { - // FIXME t.Parallel() + t.Parallel() mockT := new(testing.T) True(t, FileExists(mockT, "assertions.go")) @@ -2590,32 +2590,23 @@ func TestFileExists(t *testing.T) { mockT = new(testing.T) False(t, FileExists(mockT, "../_codegen")) - var tempFiles []string - - link, err := getTempSymlinkPath("assertions.go") + link, err := getTempSymlinkPath(t, "assertions.go") if err != nil { t.Fatal("could not create temp symlink, err:", err) } - tempFiles = append(tempFiles, link) mockT = new(testing.T) True(t, FileExists(mockT, link)) - link, err = getTempSymlinkPath("non_existent_file") + link, err = getTempSymlinkPath(t, "non_existent_file") if err != nil { t.Fatal("could not create temp symlink, err:", err) } - tempFiles = append(tempFiles, link) mockT = new(testing.T) True(t, FileExists(mockT, link)) - - errs := cleanUpTempFiles(tempFiles) - if len(errs) > 0 { - t.Fatal("could not clean up temporary files") - } } func TestNoFileExists(t *testing.T) { - // FIXME t.Parallel() + t.Parallel() mockT := new(testing.T) False(t, NoFileExists(mockT, "assertions.go")) @@ -2626,49 +2617,30 @@ func TestNoFileExists(t *testing.T) { mockT = new(testing.T) True(t, NoFileExists(mockT, "../_codegen")) - var tempFiles []string - - link, err := getTempSymlinkPath("assertions.go") + link, err := getTempSymlinkPath(t, "assertions.go") if err != nil { t.Fatal("could not create temp symlink, err:", err) } - tempFiles = append(tempFiles, link) mockT = new(testing.T) False(t, NoFileExists(mockT, link)) - link, err = getTempSymlinkPath("non_existent_file") + link, err = getTempSymlinkPath(t, "non_existent_file") if err != nil { t.Fatal("could not create temp symlink, err:", err) } - tempFiles = append(tempFiles, link) mockT = new(testing.T) False(t, NoFileExists(mockT, link)) - - errs := cleanUpTempFiles(tempFiles) - if len(errs) > 0 { - t.Fatal("could not clean up temporary files") - } } -func getTempSymlinkPath(file string) (string, error) { - link := file + "_symlink" +func getTempSymlinkPath(t *testing.T, file string) (string, error) { + tempDir := t.TempDir() + link := filepath.Join(tempDir, file+"_symlink") err := os.Symlink(file, link) return link, err } -func cleanUpTempFiles(paths []string) []error { - var res []error - for _, path := range paths { - err := os.Remove(path) - if err != nil { - res = append(res, err) - } - } - return res -} - func TestDirExists(t *testing.T) { - // FIXME t.Parallel() + t.Parallel() mockT := new(testing.T) False(t, DirExists(mockT, "assertions.go")) @@ -2679,32 +2651,23 @@ func TestDirExists(t *testing.T) { mockT = new(testing.T) True(t, DirExists(mockT, "../_codegen")) - var tempFiles []string - - link, err := getTempSymlinkPath("assertions.go") + link, err := getTempSymlinkPath(t, "assertions.go") if err != nil { t.Fatal("could not create temp symlink, err:", err) } - tempFiles = append(tempFiles, link) mockT = new(testing.T) False(t, DirExists(mockT, link)) - link, err = getTempSymlinkPath("non_existent_dir") + link, err = getTempSymlinkPath(t, "non_existent_dir") if err != nil { t.Fatal("could not create temp symlink, err:", err) } - tempFiles = append(tempFiles, link) mockT = new(testing.T) False(t, DirExists(mockT, link)) - - errs := cleanUpTempFiles(tempFiles) - if len(errs) > 0 { - t.Fatal("could not clean up temporary files") - } } func TestNoDirExists(t *testing.T) { - // FIXME t.Parallel() + t.Parallel() mockT := new(testing.T) True(t, NoDirExists(mockT, "assertions.go")) @@ -2715,28 +2678,19 @@ func TestNoDirExists(t *testing.T) { mockT = new(testing.T) False(t, NoDirExists(mockT, "../_codegen")) - var tempFiles []string - - link, err := getTempSymlinkPath("assertions.go") + link, err := getTempSymlinkPath(t, "assertions.go") if err != nil { t.Fatal("could not create temp symlink, err:", err) } - tempFiles = append(tempFiles, link) mockT = new(testing.T) True(t, NoDirExists(mockT, link)) - link, err = getTempSymlinkPath("non_existent_dir") + link, err = getTempSymlinkPath(t, "non_existent_dir") if err != nil { t.Fatal("could not create temp symlink, err:", err) } - tempFiles = append(tempFiles, link) mockT = new(testing.T) True(t, NoDirExists(mockT, link)) - - errs := cleanUpTempFiles(tempFiles) - if len(errs) > 0 { - t.Fatal("could not clean up temporary files") - } } func TestJSONEq_EqualSONString(t *testing.T) { From 50277a850b12d5f24761afbe0eb5b56e5a035782 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Mon, 16 Jun 2025 12:22:09 +0200 Subject: [PATCH 138/178] assert/tests: simplify Test{No,}{File,Dir}Exists In tests of the assert package, move more logic from each test into the helper getTempSymlinkPath. --- assert/assertions_test.go | 50 ++++++++++++--------------------------- 1 file changed, 15 insertions(+), 35 deletions(-) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 7e626f512..6b5366e83 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -2590,17 +2590,11 @@ func TestFileExists(t *testing.T) { mockT = new(testing.T) False(t, FileExists(mockT, "../_codegen")) - link, err := getTempSymlinkPath(t, "assertions.go") - if err != nil { - t.Fatal("could not create temp symlink, err:", err) - } + link := getTempSymlinkPath(t, "assertions.go") mockT = new(testing.T) True(t, FileExists(mockT, link)) - link, err = getTempSymlinkPath(t, "non_existent_file") - if err != nil { - t.Fatal("could not create temp symlink, err:", err) - } + link = getTempSymlinkPath(t, "non_existent_file") mockT = new(testing.T) True(t, FileExists(mockT, link)) } @@ -2617,26 +2611,24 @@ func TestNoFileExists(t *testing.T) { mockT = new(testing.T) True(t, NoFileExists(mockT, "../_codegen")) - link, err := getTempSymlinkPath(t, "assertions.go") - if err != nil { - t.Fatal("could not create temp symlink, err:", err) - } + link := getTempSymlinkPath(t, "assertions.go") mockT = new(testing.T) False(t, NoFileExists(mockT, link)) - link, err = getTempSymlinkPath(t, "non_existent_file") - if err != nil { - t.Fatal("could not create temp symlink, err:", err) - } + link = getTempSymlinkPath(t, "non_existent_file") mockT = new(testing.T) False(t, NoFileExists(mockT, link)) } -func getTempSymlinkPath(t *testing.T, file string) (string, error) { +func getTempSymlinkPath(t *testing.T, file string) string { + t.Helper() + tempDir := t.TempDir() link := filepath.Join(tempDir, file+"_symlink") - err := os.Symlink(file, link) - return link, err + if err := os.Symlink(file, link); err != nil { + t.Fatal("could not create temp symlink, err:", err) + } + return link } func TestDirExists(t *testing.T) { @@ -2651,17 +2643,11 @@ func TestDirExists(t *testing.T) { mockT = new(testing.T) True(t, DirExists(mockT, "../_codegen")) - link, err := getTempSymlinkPath(t, "assertions.go") - if err != nil { - t.Fatal("could not create temp symlink, err:", err) - } + link := getTempSymlinkPath(t, "assertions.go") mockT = new(testing.T) False(t, DirExists(mockT, link)) - link, err = getTempSymlinkPath(t, "non_existent_dir") - if err != nil { - t.Fatal("could not create temp symlink, err:", err) - } + link = getTempSymlinkPath(t, "non_existent_dir") mockT = new(testing.T) False(t, DirExists(mockT, link)) } @@ -2678,17 +2664,11 @@ func TestNoDirExists(t *testing.T) { mockT = new(testing.T) False(t, NoDirExists(mockT, "../_codegen")) - link, err := getTempSymlinkPath(t, "assertions.go") - if err != nil { - t.Fatal("could not create temp symlink, err:", err) - } + link := getTempSymlinkPath(t, "assertions.go") mockT = new(testing.T) True(t, NoDirExists(mockT, link)) - link, err = getTempSymlinkPath(t, "non_existent_dir") - if err != nil { - t.Fatal("could not create temp symlink, err:", err) - } + link = getTempSymlinkPath(t, "non_existent_dir") mockT = new(testing.T) True(t, NoDirExists(mockT, link)) } From 44c0281fe0e044a759afd2921efb60eacea594b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Mon, 16 Jun 2025 12:25:47 +0200 Subject: [PATCH 139/178] assert/tests: improve failure reporting in Test{No,}{File,Dir}Exists Improve error reporting in getTempSymlinkPath by displaying the file paths. --- assert/assertions_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 6b5366e83..298b685d6 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -2626,7 +2626,7 @@ func getTempSymlinkPath(t *testing.T, file string) string { tempDir := t.TempDir() link := filepath.Join(tempDir, file+"_symlink") if err := os.Symlink(file, link); err != nil { - t.Fatal("could not create temp symlink, err:", err) + t.Fatalf("could not create temp symlink %q pointing to %q: %v", link, file, err) } return link } From 87101a6e4a5859cee372b6ded7821787b3190cb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Thu, 5 Jun 2025 11:47:28 +0200 Subject: [PATCH 140/178] suite.Run: refactor handling of stats Refactor handling of stats in suite.Run with the goal of reducing indented blocks to improve readability. To achieve this, the SuiteInformation methods now handle being called with a nil receiver to work as noop. This allows to call them from suite.Run without nil checks blocks, so with improved readability. --- suite/stats.go | 16 ++++++++++------ suite/suite.go | 9 ++------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/suite/stats.go b/suite/stats.go index 261da37f7..be4ccd679 100644 --- a/suite/stats.go +++ b/suite/stats.go @@ -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 diff --git a/suite/suite.go b/suite/suite.go index a7ceba731..8a5c0534e 100644 --- a/suite/suite.go +++ b/suite/suite.go @@ -161,10 +161,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) @@ -185,9 +182,7 @@ 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)}) }, From 7d37b5c962954410bcd7a71ff3a77c79514056d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Wed, 6 Mar 2024 01:24:45 +0100 Subject: [PATCH 141/178] suite: refactor methodFilter Use strings.HasPrefix instead of a /^Test/ regexp (compiled on every call). --- suite/suite.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/suite/suite.go b/suite/suite.go index 8a5c0534e..f582b3536 100644 --- a/suite/suite.go +++ b/suite/suite.go @@ -7,6 +7,7 @@ import ( "reflect" "regexp" "runtime/debug" + "strings" "sync" "testing" "time" @@ -219,7 +220,7 @@ func Run(t *testing.T, suite TestingSuite) { // 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 { + if !strings.HasPrefix(name, "Test") { return false, nil } return regexp.MatchString(*matchMethod, name) From bc7459ec38128532ff32f23cfab4ea0b725210f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Tue, 27 May 2025 15:36:15 +0200 Subject: [PATCH 142/178] suite: faster filtering of methods (-testify.m) Refactor filtering of methods in suite.Run: the regexp given via -testify.m flag is compiled just once, out of the loop. --- suite/suite.go | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/suite/suite.go b/suite/suite.go index f582b3536..1b19be3bc 100644 --- a/suite/suite.go +++ b/suite/suite.go @@ -138,16 +138,24 @@ func Run(t *testing.T, suite TestingSuite) { 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) } + } + + for i := 0; i < methodFinder.NumMethod(); i++ { + method := methodFinder.Method(i) - if !ok { + if !strings.HasPrefix(method.Name, "Test") { + continue + } + // Apply -testify.m filter + if matchMethodRE != nil && !matchMethodRE.MatchString(method.Name) { continue } @@ -217,15 +225,6 @@ func Run(t *testing.T, suite TestingSuite) { runTests(t, tests) } -// Filtering method according to set regular expression -// specified command-line argument -m -func methodFilter(name string) (bool, error) { - if !strings.HasPrefix(name, "Test") { - return false, nil - } - return regexp.MatchString(*matchMethod, name) -} - func runTests(t *testing.T, tests []test) { if len(tests) == 0 { t.Log("warning: no tests to run") From 7218e0390acd2aea3edb18574110ec2753c0aeef Mon Sep 17 00:00:00 2001 From: user Date: Thu, 15 May 2025 22:50:50 +0200 Subject: [PATCH 143/178] improve error msg --- mock/mock.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mock/mock.go b/mock/mock.go index 73e020f78..175f7a3a8 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -671,7 +671,7 @@ func (m *Mock) AssertNumberOfCalls(t TestingT, methodName string, expectedCalls actualCalls++ } } - return assert.Equal(t, expectedCalls, actualCalls, fmt.Sprintf("Expected number of calls (%d) does not match the actual number of calls (%d).", expectedCalls, actualCalls)) + return assert.Equal(t, expectedCalls, actualCalls, fmt.Sprintf("Expected number of calls (%d) of method (%s) does not match the actual number of calls (%d).", expectedCalls, methodName, actualCalls)) } // AssertCalled asserts that the method was called. From aafb604176db7e1f2c9810bc90d644291d057687 Mon Sep 17 00:00:00 2001 From: 3scalation <43409803+3scalation@users.noreply.github.com> Date: Thu, 22 May 2025 15:26:22 +0200 Subject: [PATCH 144/178] mock: improve formatting of error message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Olivier Mengué --- mock/mock.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mock/mock.go b/mock/mock.go index 175f7a3a8..114fca619 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -671,7 +671,7 @@ func (m *Mock) AssertNumberOfCalls(t TestingT, methodName string, expectedCalls actualCalls++ } } - return assert.Equal(t, expectedCalls, actualCalls, fmt.Sprintf("Expected number of calls (%d) of method (%s) does not match the actual number of calls (%d).", expectedCalls, methodName, actualCalls)) + return assert.Equal(t, expectedCalls, actualCalls, fmt.Sprintf("Expected number of calls (%d) of method %s does not match the actual number of calls (%d).", expectedCalls, methodName, actualCalls)) } // AssertCalled asserts that the method was called. From a53be35c3b0cfcd5189cffcfd75df60ea581104c Mon Sep 17 00:00:00 2001 From: ccoVeille <3875889+ccoVeille@users.noreply.github.com> Date: Thu, 8 May 2025 18:41:57 +0200 Subject: [PATCH 145/178] Improve captureTestingT helper This helper is used to capture the testing.TB interface, and compare the log output with the expected output. This is useful for testing and refactoring purposes. This commit improves the helper by displaying: - the captured and expected outputs on a newline. - the special characters in the captured output, such as newlines and tabs. Both help with readability. Here is an example of the output before and after the change: Before: assertions_test.go:3422: Logged Error: Should be in error chain expected: *assert.customError in chain: "EOF" (*errors.errorString) assertions_test.go:3422: Should log Error: Should be in error chain: expected: *assert.customError in chain: "EOF" (*errors.errorString) After: assertions_test.go:3394: Recorded Error: "Should be in error chain:\nexpected: *assert.customError\nin chain: \"EOF\" (*errors.errorString)\n" assertions_test.go:3394: Expected Error: "Should be in error chain\nexpected: *assert.customError\nin chain: \"EOF\" (*errors.errorString)" The new format helps to identify the differences: - the missing colon after "Should be in error chain" - the extra newline in the captured output Note: I spent 10 minutes on this change, because I lost 10 minutes in finding the differences between the captured and expected output on a refactoring I was doing. --- assert/assertions_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 298b685d6..76ae12f96 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -3675,12 +3675,12 @@ func (ctt *captureTestingT) checkResultAndErrMsg(t *testing.T, expectedRes, res contents := parseLabeledOutput(ctt.msg) if res == true { if contents != nil { - t.Errorf("Should not log an error") + t.Errorf("Should not log an error. Log output: %q", ctt.msg) } return } if contents == nil { - t.Errorf("Should log an error. Log output: %v", ctt.msg) + t.Errorf("Should log an error. Log output: %q", ctt.msg) return } for _, content := range contents { @@ -3688,10 +3688,10 @@ func (ctt *captureTestingT) checkResultAndErrMsg(t *testing.T, expectedRes, res if expectedErrMsg == content.content { return } - t.Errorf("Logged Error: %v", content.content) + t.Errorf("Recorded Error: %q", content.content) } } - t.Errorf("Should log Error: %v", expectedErrMsg) + t.Errorf("Expected Error: %q", expectedErrMsg) } func TestErrorIs(t *testing.T) { From 69831f3b08c40d56a09d0be93e9d5ae034f1590b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Aug 2025 19:06:51 +0000 Subject: [PATCH 146/178] build(deps): bump actions/checkout from 4 to 5 Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/main.yml | 4 ++-- .github/workflows/release.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2aed14548..4c39ac045 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,7 +10,7 @@ jobs: - stable - oldstable steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Setup Go uses: actions/setup-go@v5 with: @@ -33,7 +33,7 @@ jobs: - "1.21" - "1.22" steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Setup Go uses: actions/setup-go@v5 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 08adf73d1..c094648b0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,7 +13,7 @@ jobs: contents: write steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Create GitHub release from tag uses: softprops/action-gh-release@v2 From 7b2204f8a306a98af7acf453e5d57c3647c3fc59 Mon Sep 17 00:00:00 2001 From: mutaiib Date: Sat, 26 Jul 2025 23:38:56 +0530 Subject: [PATCH 147/178] fix(pkg-mock): avoid panic when expected type is nil in Arguments.Diff MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Calling Name() on a nil reflect.Type would panic (and leave the mutex locked), causing hard‑to‑diagnose crashes. Introduce a SafeName helper that returns "" for nil types (or t.Name() otherwise), and switch the Diff method to use SafeName(expected.t) instead of expected.t.Name() when rendering failures. --- mock/mock.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/mock/mock.go b/mock/mock.go index 114fca619..ffe19ce2d 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -1034,7 +1034,7 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { if actualT != expected.t { differences++ outputRenderers = append(outputRenderers, func() string { - return fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, expected.t.Name(), actualT.Name(), actualFmt()) + return fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, args.SafeName(expected.t), actualT, actualFmt()) }) } case *FunctionalOptionsArgument: @@ -1179,6 +1179,17 @@ func (args Arguments) Bool(index int) bool { return s } +// SafeName returns the short name of a reflect.Type without causing a panic. +// If the provided reflect.Type is nil, it returns the placeholder string "". +// This helper is useful when formatting type information in diffs or error messages, +// ensuring that code never attempts to call Name() on a nil reflect.Type +func (args Arguments) SafeName(t reflect.Type) string { + if t == nil { + return "" + } + return t.Name() +} + func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) { t := reflect.TypeOf(v) k := t.Kind() From b9a23f4b6a8889041ff8a3e8c8d93feab038c4f2 Mon Sep 17 00:00:00 2001 From: mutaiib Date: Fri, 1 Aug 2025 16:04:20 +0530 Subject: [PATCH 148/178] refactor: unexport and convert `Arguments.SafeName` method to standalone function - Renamed `Arguments.SafeName` to `safeTypeName` --- mock/mock.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/mock/mock.go b/mock/mock.go index ffe19ce2d..15c00ee2a 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -1034,7 +1034,7 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { if actualT != expected.t { differences++ outputRenderers = append(outputRenderers, func() string { - return fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, args.SafeName(expected.t), actualT, actualFmt()) + return fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, safeTypeName(expected.t), actualT, actualFmt()) }) } case *FunctionalOptionsArgument: @@ -1179,11 +1179,9 @@ func (args Arguments) Bool(index int) bool { return s } -// SafeName returns the short name of a reflect.Type without causing a panic. -// If the provided reflect.Type is nil, it returns the placeholder string "". -// This helper is useful when formatting type information in diffs or error messages, -// ensuring that code never attempts to call Name() on a nil reflect.Type -func (args Arguments) SafeName(t reflect.Type) string { +// safeTypeName returns the reflect.Type's name without causing a panic. +// If the provided reflect.Type is nil, it returns the placeholder string "" +func safeTypeName(t reflect.Type) string { if t == nil { return "" } From 8976267da7c4bae1a01fc582db1c921980f639eb Mon Sep 17 00:00:00 2001 From: mutaiib Date: Sun, 10 Aug 2025 15:49:30 +0530 Subject: [PATCH 149/178] mock: document `IsType` interface limitation and add tests - Updated IsType doc comment to clarify behavior with interface types: - IsType matches the exact concrete type provided. - Passing a nil interface has no type information and will never match. - To match interface values, a non-nil concrete value must be provided. - Added tests for interface type behavior: - Test_Arguments_Diff_WithIsTypeArgument_InterfaceType (non-nil, matches) - Test_Arguments_Diff_WithIsTypeArgument_InterfaceType_Failing (nil, mismatch) --- mock/mock.go | 4 ++++ mock/mock_test.go | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/mock/mock.go b/mock/mock.go index 15c00ee2a..8ebb794f0 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -833,6 +833,10 @@ type IsTypeArgument struct { // For example: // // args.Assert(t, IsType(""), IsType(0)) +// +// Note: IsType checks for the exact type you give it. +// If you pass a nil interface, it has no type and will never match. +// To match an interface value, pass a non-nil value of the concrete type you expect. func IsType(t interface{}) *IsTypeArgument { return &IsTypeArgument{t: reflect.TypeOf(t)} } diff --git a/mock/mock_test.go b/mock/mock_test.go index 813ec5e56..783fc3647 100644 --- a/mock/mock_test.go +++ b/mock/mock_test.go @@ -1,6 +1,7 @@ package mock import ( + "context" "errors" "fmt" "regexp" @@ -1998,6 +1999,25 @@ func Test_Arguments_Diff_WithIsTypeArgument_Failing(t *testing.T) { assert.Contains(t, diff, `string != type int - (int=123)`) } +func Test_Arguments_Diff_WithIsTypeArgument_InterfaceType(t *testing.T) { + t.Parallel() + var ctx = context.Background() + args := Arguments([]interface{}{IsType(ctx)}) + _, count := args.Diff([]interface{}{context.Background()}) + assert.Equal(t, 0, count) +} + +func Test_Arguments_Diff_WithIsTypeArgument_InterfaceType_Failing(t *testing.T) { + t.Parallel() + + var ctx context.Context + var args = Arguments([]interface{}{IsType(ctx)}) + diff, count := args.Diff([]interface{}{context.Background()}) + assert.Equal(t, 1, count) + assert.Contains(t, diff, `type != type context.backgroundCtx`) + +} + func Test_Arguments_Diff_WithArgMatcher(t *testing.T) { t.Parallel() From 354fc33d53efcb63ad1ef2b22203485c827795f1 Mon Sep 17 00:00:00 2001 From: mutaiib Date: Mon, 18 Aug 2025 21:36:41 +0530 Subject: [PATCH 150/178] Update mock/mock.go In short, Mock cannot match interface types with `IsType`, it only matches the values' concrete type. Co-authored-by: Bracken --- mock/mock.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mock/mock.go b/mock/mock.go index 8ebb794f0..e88402b3e 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -834,9 +834,9 @@ type IsTypeArgument struct { // // args.Assert(t, IsType(""), IsType(0)) // -// Note: IsType checks for the exact type you give it. -// If you pass a nil interface, it has no type and will never match. -// To match an interface value, pass a non-nil value of the concrete type you expect. +// Mock cannot match interface types because the contained type will be passed +// to both IsType and Mock.Called, for the zero value of all interfaces this +// will be type. func IsType(t interface{}) *IsTypeArgument { return &IsTypeArgument{t: reflect.TypeOf(t)} } From e3d64ad5afa2099b89cc5922444dc8a0a8878615 Mon Sep 17 00:00:00 2001 From: mutaiib Date: Tue, 19 Aug 2025 00:19:15 +0530 Subject: [PATCH 151/178] Update mock/mock_test.go Depending on the version of go used, context.Background returns either a context.emptyCtx or a context.Backgound since they made it into its own type. This is why the tests will fail for Go 1.18. Co-authored-by: Bracken --- mock/mock_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mock/mock_test.go b/mock/mock_test.go index 783fc3647..c9fea8f6e 100644 --- a/mock/mock_test.go +++ b/mock/mock_test.go @@ -2014,7 +2014,7 @@ func Test_Arguments_Diff_WithIsTypeArgument_InterfaceType_Failing(t *testing.T) var args = Arguments([]interface{}{IsType(ctx)}) diff, count := args.Diff([]interface{}{context.Background()}) assert.Equal(t, 1, count) - assert.Contains(t, diff, `type != type context.backgroundCtx`) + assert.Contains(t, diff, `type != type `) } From af161709418f7b2df18853b39d088a88e963a43c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Mon, 25 Aug 2025 16:05:54 +0200 Subject: [PATCH 152/178] CI: test also with Go 1.23 Now that Go 1.25.0 is released, Go 1.23 must be explicitely mentioned for testing as it was previously "oldstable". --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4c39ac045..e6479811c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -32,6 +32,7 @@ jobs: - "1.20" - "1.21" - "1.22" + - "1.23" steps: - uses: actions/checkout@v5 - name: Setup Go From 5fa380cd3d6bf40461c3d4eadee4b3cd7bf60f89 Mon Sep 17 00:00:00 2001 From: Bracken Dawson Date: Tue, 26 Aug 2025 10:06:09 +0200 Subject: [PATCH 153/178] Promote ccoVeille to maintainer --- MAINTAINERS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS.md b/MAINTAINERS.md index 120c46398..6acd5b1c9 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -7,6 +7,7 @@ pull requests. * @dolmen * @MovieStoreGuy * @brackendawson + * @ccoVeille ## Approvers @@ -14,4 +15,3 @@ The individuals listed below are active in the project and have the ability to a requests. * @arjunmahishi - * @ccoVeille From 5e25bfb162597690d34f205a312a81393c0eb250 Mon Sep 17 00:00:00 2001 From: Bracken Dawson Date: Wed, 27 Aug 2025 11:37:25 +0200 Subject: [PATCH 154/178] mock: Test that arguments with mutating stringers match Covers the use case in issue 1785 where mock can fail to match arguments by inappropriately mutating them by calling their stringer interface. --- mock/mock_test.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/mock/mock_test.go b/mock/mock_test.go index c9fea8f6e..7c97754ae 100644 --- a/mock/mock_test.go +++ b/mock/mock_test.go @@ -6,6 +6,7 @@ import ( "fmt" "regexp" "runtime" + "strconv" "sync" "testing" "time" @@ -2441,3 +2442,22 @@ type user interface { type mockUser struct{ Mock } func (m *mockUser) Use(c caller) { m.Called(c) } + +type mutatingStringer struct { + N int + s string +} + +func (m *mutatingStringer) String() string { + m.s = strconv.Itoa(m.N) + return m.s +} + +func TestIssue1785ArgumentWithMutatingStringer(t *testing.T) { + m := &Mock{} + m.On("Method", &mutatingStringer{N: 2}) + m.On("Method", &mutatingStringer{N: 1}) + m.MethodCalled("Method", &mutatingStringer{N: 1}) + m.MethodCalled("Method", &mutatingStringer{N: 2}) + m.AssertExpectations(t) +} From 0cdb408f5368d8379ae827593781f0aa0d115c78 Mon Sep 17 00:00:00 2001 From: Bracken Dawson Date: Wed, 27 Aug 2025 11:50:26 +0200 Subject: [PATCH 155/178] Revert "Merge pull request #1615 from DevotedHealth/mauclair-mock-match-sprintf" This reverts commit a31a53e5b43e2c8827f61e9a13e885c64b754805, reversing changes made to 5ac6528bffc1ed7557980c3c563caf8308568446. --- mock/mock.go | 72 +++++++++++++--------------------------------------- 1 file changed, 17 insertions(+), 55 deletions(-) diff --git a/mock/mock.go b/mock/mock.go index e88402b3e..3f5c67223 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -952,8 +952,6 @@ func (args Arguments) Is(objects ...interface{}) bool { return true } -type outputRenderer func() string - // Diff gets a string describing the differences between the arguments // and the specified objects. // @@ -961,7 +959,7 @@ type outputRenderer func() string func (args Arguments) Diff(objects []interface{}) (string, int) { // TODO: could return string as error and nil for No difference - var outputBuilder strings.Builder + output := "\n" var differences int maxArgCount := len(args) @@ -969,35 +967,24 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { maxArgCount = len(objects) } - outputRenderers := []outputRenderer{} - for i := 0; i < maxArgCount; i++ { - i := i var actual, expected interface{} - var actualFmt, expectedFmt func() string + var actualFmt, expectedFmt string if len(objects) <= i { actual = "(Missing)" - actualFmt = func() string { - return "(Missing)" - } + actualFmt = "(Missing)" } else { actual = objects[i] - actualFmt = func() string { - return fmt.Sprintf("(%[1]T=%[1]v)", actual) - } + actualFmt = fmt.Sprintf("(%[1]T=%[1]v)", actual) } if len(args) <= i { expected = "(Missing)" - expectedFmt = func() string { - return "(Missing)" - } + expectedFmt = "(Missing)" } else { expected = args[i] - expectedFmt = func() string { - return fmt.Sprintf("(%[1]T=%[1]v)", expected) - } + expectedFmt = fmt.Sprintf("(%[1]T=%[1]v)", expected) } if matcher, ok := expected.(argumentMatcher); ok { @@ -1005,22 +992,16 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { func() { defer func() { if r := recover(); r != nil { - actualFmt = func() string { - return fmt.Sprintf("panic in argument matcher: %v", r) - } + actualFmt = fmt.Sprintf("panic in argument matcher: %v", r) } }() matches = matcher.Matches(actual) }() if matches { - outputRenderers = append(outputRenderers, func() string { - return fmt.Sprintf("\t%d: PASS: %s matched by %s\n", i, actualFmt(), matcher) - }) + output = fmt.Sprintf("%s\t%d: PASS: %s matched by %s\n", output, i, actualFmt, matcher) } else { differences++ - outputRenderers = append(outputRenderers, func() string { - return fmt.Sprintf("\t%d: FAIL: %s not matched by %s\n", i, actualFmt(), matcher) - }) + output = fmt.Sprintf("%s\t%d: FAIL: %s not matched by %s\n", output, i, actualFmt, matcher) } } else { switch expected := expected.(type) { @@ -1029,17 +1010,13 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { if reflect.TypeOf(actual).Name() != string(expected) && reflect.TypeOf(actual).String() != string(expected) { // not match differences++ - outputRenderers = append(outputRenderers, func() string { - return fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, expected, reflect.TypeOf(actual).Name(), actualFmt()) - }) + output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, expected, reflect.TypeOf(actual).Name(), actualFmt) } case *IsTypeArgument: actualT := reflect.TypeOf(actual) if actualT != expected.t { differences++ - outputRenderers = append(outputRenderers, func() string { - return fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, safeTypeName(expected.t), actualT, actualFmt()) - }) + output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, safeTypeName(expected.t), safeTypeName(actualT), actualFmt) } case *FunctionalOptionsArgument: var name string @@ -1050,36 +1027,26 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { const tName = "[]interface{}" if name != reflect.TypeOf(actual).String() && len(expected.values) != 0 { differences++ - outputRenderers = append(outputRenderers, func() string { - return fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, tName, reflect.TypeOf(actual).Name(), actualFmt()) - }) + output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, tName, reflect.TypeOf(actual).Name(), actualFmt) } else { if ef, af := assertOpts(expected.values, actual); ef == "" && af == "" { // match - outputRenderers = append(outputRenderers, func() string { - return fmt.Sprintf("\t%d: PASS: %s == %s\n", i, tName, tName) - }) + output = fmt.Sprintf("%s\t%d: PASS: %s == %s\n", output, i, tName, tName) } else { // not match differences++ - outputRenderers = append(outputRenderers, func() string { - return fmt.Sprintf("\t%d: FAIL: %s != %s\n", i, af, ef) - }) + output = fmt.Sprintf("%s\t%d: FAIL: %s != %s\n", output, i, af, ef) } } default: if assert.ObjectsAreEqual(expected, Anything) || assert.ObjectsAreEqual(actual, Anything) || assert.ObjectsAreEqual(actual, expected) { // match - outputRenderers = append(outputRenderers, func() string { - return fmt.Sprintf("\t%d: PASS: %s == %s\n", i, actualFmt(), expectedFmt()) - }) + output = fmt.Sprintf("%s\t%d: PASS: %s == %s\n", output, i, actualFmt, expectedFmt) } else { // not match differences++ - outputRenderers = append(outputRenderers, func() string { - return fmt.Sprintf("\t%d: FAIL: %s != %s\n", i, actualFmt(), expectedFmt()) - }) + output = fmt.Sprintf("%s\t%d: FAIL: %s != %s\n", output, i, actualFmt, expectedFmt) } } } @@ -1090,12 +1057,7 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { return "No differences.", differences } - outputBuilder.WriteString("\n") - for _, r := range outputRenderers { - outputBuilder.WriteString(r()) - } - - return outputBuilder.String(), differences + return output, differences } // Assert compares the arguments with the specified objects and fails if From 5f941c88ce8a2c0af1a081ad28e2711f4aa07637 Mon Sep 17 00:00:00 2001 From: Vyas Reddy Date: Thu, 28 Aug 2025 23:36:11 +0530 Subject: [PATCH 156/178] Update suite/suite.go Co-authored-by: Bracken --- suite/suite.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/suite/suite.go b/suite/suite.go index 44822000b..92a861098 100644 --- a/suite/suite.go +++ b/suite/suite.go @@ -164,7 +164,7 @@ func Run(t *testing.T, suite TestingSuite) { name: method.Name, run: func(t *testing.T) { t.Errorf( - "testify: suite method %q has invalid signature: expected no inputs or return values (has %d inputs, %d outputs)", + "testify: suite method %q has invalid signature: expected no input or output parameters, method has %d input parameters and %d output parameters", method.Name, method.Type.NumIn()-1, method.Type.NumOut(), ) }, From 4f554a8833afff3cffb491138ba9c796ca4106b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20Gond=C5=BEa?= Date: Thu, 8 Jun 2023 13:28:26 +0200 Subject: [PATCH 157/178] Fix #1399: Always report error message on PanicsWithError mismatch --- assert/assertions.go | 10 +++++++++- assert/assertions_test.go | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index de8de0cb6..12166a78f 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -1345,7 +1345,15 @@ func PanicsWithError(t TestingT, errString string, f PanicTestFunc, msgAndArgs . } panicErr, ok := panicValue.(error) if !ok || panicErr.Error() != errString { - return Fail(t, fmt.Sprintf("func %#v should panic with error message:\t%#v\n\tPanic value:\t%#v\n\tPanic stack:\t%s", f, errString, panicValue, panickedStack), msgAndArgs...) + errorMsg := "" + if ok { + errorMsg = fmt.Sprintf("\tError message:\t%#v\n", panicErr.Error()) + } + msg := fmt.Sprintf( + "func %#v should panic with error message:\t%#v\n\tPanic value:\t%#v\n%s\tPanic stack:\t%s", + f, errString, panicValue, errorMsg, panickedStack, + ) + return Fail(t, msg, msgAndArgs...) } return true diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 76ae12f96..90cdd1938 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -1587,30 +1587,57 @@ func TestPanicsWithValue(t *testing.T) { func TestPanicsWithError(t *testing.T) { t.Parallel() - mockT := new(testing.T) - + mockT := new(CollectT) if !PanicsWithError(mockT, "panic", func() { panic(errors.New("panic")) }) { t.Error("PanicsWithError should return true") } + Len(t, mockT.errors, 0) + mockT = new(CollectT) if PanicsWithError(mockT, "Panic!", func() { }) { t.Error("PanicsWithError should return false") } + if Len(t, mockT.errors, 1) { + actual := mockT.errors[0].Error() + Contains(t, actual, "Panic value: ") + } + mockT = new(CollectT) if PanicsWithError(mockT, "at the disco", func() { - panic(errors.New("panic")) + panic(errors.New("actual err msg")) + }) { + t.Error("PanicsWithError should return false") + } + if Len(t, mockT.errors, 1) { + actual := mockT.errors[0].Error() + Contains(t, actual, `Error message: "actual err msg"`) + } + + mockT = new(CollectT) + if PanicsWithError(mockT, "at the disco", func() { + panic(errors.Join(errors.New("wrapped err msg"), errors.New("other err msg"))) }) { t.Error("PanicsWithError should return false") } + if Len(t, mockT.errors, 1) { + actual := mockT.errors[0].Error() + Contains(t, actual, `Error message: "wrapped err msg\nother err msg"`) + } + mockT = new(CollectT) if PanicsWithError(mockT, "Panic!", func() { panic("panic") }) { t.Error("PanicsWithError should return false") } + if Len(t, mockT.errors, 1) { + actual := mockT.errors[0].Error() + Contains(t, actual, `Panic value: "panic"`) + NotContains(t, actual, "Error message:", "PanicsWithError should not report error message if not due an error") + } } func TestNotPanics(t *testing.T) { From 38d9e83f5afaffee8c0a99d3e051ea5542e9f6c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20Gond=C5=BEa?= Date: Thu, 8 Jun 2023 14:02:27 +0200 Subject: [PATCH 158/178] Fix tests to work with go 1.19 --- assert/assertions_test.go | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 90cdd1938..de196e4b7 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -1587,6 +1587,10 @@ func TestPanicsWithValue(t *testing.T) { func TestPanicsWithError(t *testing.T) { t.Parallel() + type NestedErr struct { + Err error + } + mockT := new(CollectT) if !PanicsWithError(mockT, "panic", func() { panic(errors.New("panic")) @@ -1618,13 +1622,13 @@ func TestPanicsWithError(t *testing.T) { mockT = new(CollectT) if PanicsWithError(mockT, "at the disco", func() { - panic(errors.Join(errors.New("wrapped err msg"), errors.New("other err msg"))) + panic(&PanicsWithErrorWrapper{"wrapped", errors.New("other err msg")}) }) { t.Error("PanicsWithError should return false") } if Len(t, mockT.errors, 1) { actual := mockT.errors[0].Error() - Contains(t, actual, `Error message: "wrapped err msg\nother err msg"`) + Contains(t, actual, `Error message: "wrapped: other err msg"`) } mockT = new(CollectT) @@ -1640,6 +1644,15 @@ func TestPanicsWithError(t *testing.T) { } } +type PanicsWithErrorWrapper struct { + Prefix string + Err error +} + +func (e PanicsWithErrorWrapper) Error() string { + return e.Prefix + ": " + e.Err.Error() +} + func TestNotPanics(t *testing.T) { t.Parallel() From 94ddd7e6d45e47adeb7097f39a67556e65e47dd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20Gond=C5=BEa?= Date: Mon, 2 Jun 2025 14:22:06 +0200 Subject: [PATCH 159/178] refact(test): Make use of captureTestingT over CollectT --- assert/assertions_test.go | 73 ++++++++++++--------------------------- 1 file changed, 23 insertions(+), 50 deletions(-) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index de196e4b7..4db48f38b 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -1587,61 +1587,34 @@ func TestPanicsWithValue(t *testing.T) { func TestPanicsWithError(t *testing.T) { t.Parallel() - type NestedErr struct { - Err error - } - - mockT := new(CollectT) - if !PanicsWithError(mockT, "panic", func() { + mockT := new(captureTestingT) + succeeded := PanicsWithError(mockT, "panic", func() { panic(errors.New("panic")) - }) { - t.Error("PanicsWithError should return true") - } - Len(t, mockT.errors, 0) + }) + mockT.checkResultAndErrMsg(t, true, succeeded, "") - mockT = new(CollectT) - if PanicsWithError(mockT, "Panic!", func() { - }) { - t.Error("PanicsWithError should return false") - } - if Len(t, mockT.errors, 1) { - actual := mockT.errors[0].Error() - Contains(t, actual, "Panic value: ") - } + succeeded = PanicsWithError(mockT, "Panic!", func() {}) + Equal(t, false, succeeded, "PanicsWithError should return false") + Contains(t, mockT.msg, "Panic value:\t") - mockT = new(CollectT) - if PanicsWithError(mockT, "at the disco", func() { - panic(errors.New("actual err msg")) - }) { - t.Error("PanicsWithError should return false") - } - if Len(t, mockT.errors, 1) { - actual := mockT.errors[0].Error() - Contains(t, actual, `Error message: "actual err msg"`) - } + succeeded = PanicsWithError(mockT, "expected panic err msg", func() { + panic(errors.New("actual panic err msg")) + }) + Equal(t, false, succeeded, "PanicsWithError should return false") + Contains(t, mockT.msg, `Error message: "actual panic err msg"`) - mockT = new(CollectT) - if PanicsWithError(mockT, "at the disco", func() { - panic(&PanicsWithErrorWrapper{"wrapped", errors.New("other err msg")}) - }) { - t.Error("PanicsWithError should return false") - } - if Len(t, mockT.errors, 1) { - actual := mockT.errors[0].Error() - Contains(t, actual, `Error message: "wrapped: other err msg"`) - } + succeeded = PanicsWithError(mockT, "expected panic err msg", func() { + panic(&PanicsWithErrorWrapper{"wrapped", errors.New("actual panic err msg")}) + }) + Equal(t, false, succeeded, "PanicsWithError should return false") + Contains(t, mockT.msg, `Error message: "wrapped: actual panic err msg"`) - mockT = new(CollectT) - if PanicsWithError(mockT, "Panic!", func() { - panic("panic") - }) { - t.Error("PanicsWithError should return false") - } - if Len(t, mockT.errors, 1) { - actual := mockT.errors[0].Error() - Contains(t, actual, `Panic value: "panic"`) - NotContains(t, actual, "Error message:", "PanicsWithError should not report error message if not due an error") - } + succeeded = PanicsWithError(mockT, "expected panic msg", func() { + panic("actual panic msg") + }) + Equal(t, false, succeeded, "PanicsWithError should return false") + Contains(t, mockT.msg, `Panic value: "actual panic msg"`) + NotContains(t, mockT.msg, "Error message:", "PanicsWithError should not report error message if not due an error") } type PanicsWithErrorWrapper struct { From a87733af711194db051e6bfd5e285c010243e99d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20Gond=C5=BEa?= Date: Mon, 1 Sep 2025 08:27:47 +0200 Subject: [PATCH 160/178] Refactor PanicsWithError for increased readability --- assert/assertions.go | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index 12166a78f..6fd9ff5b9 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -1343,16 +1343,14 @@ func PanicsWithError(t TestingT, errString string, f PanicTestFunc, msgAndArgs . if !funcDidPanic { return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...) } - panicErr, ok := panicValue.(error) - if !ok || panicErr.Error() != errString { - errorMsg := "" - if ok { - errorMsg = fmt.Sprintf("\tError message:\t%#v\n", panicErr.Error()) + panicErr, isError := panicValue.(error) + if !isError || panicErr.Error() != errString { + msg := fmt.Sprintf("func %#v should panic with error message:\t%#v\n", f, errString) + if isError { + msg += fmt.Sprintf("\tError message:\t%#v\n", panicErr.Error()) } - msg := fmt.Sprintf( - "func %#v should panic with error message:\t%#v\n\tPanic value:\t%#v\n%s\tPanic stack:\t%s", - f, errString, panicValue, errorMsg, panickedStack, - ) + msg += fmt.Sprintf("\tPanic value:\t%#v\n", panicValue) + msg += fmt.Sprintf("\tPanic stack:\t%s\n", panickedStack) return Fail(t, msg, msgAndArgs...) } From dc6592875bb6a9c447833842b32581cf58b33025 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Sep 2025 12:49:19 +0000 Subject: [PATCH 161/178] build(deps): bump actions/setup-go from 5 to 6 Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5 to 6. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/setup-go dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e6479811c..2cd4ad32b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v5 - name: Setup Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: ${{ matrix.go_version }} - run: npm install -g mdsf-cli @@ -36,7 +36,7 @@ jobs: steps: - uses: actions/checkout@v5 - name: Setup Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: ${{ matrix.go_version }} - run: go test -v -race ./... From 59a17f507a1ed1ecb2038b94d51572f851cf0459 Mon Sep 17 00:00:00 2001 From: Bracken Dawson Date: Thu, 11 Sep 2025 09:19:34 +0200 Subject: [PATCH 162/178] Constrain untested behavior of YAMLEq * Identical but invalid YAML is an assertion error. * Subsequent documents are unchecked. --- assert/assertions_test.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 4db48f38b..5e5c71328 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -2852,6 +2852,31 @@ func TestYAMLEq_ArraysOfDifferentOrder(t *testing.T) { False(t, YAMLEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`)) } +func TestYAMLEq_OnlyFirstDocument(t *testing.T) { + t.Parallel() + + mockT := new(testing.T) + True(t, YAMLEq(mockT, + `--- +doc1: same +--- +doc2: different +`, + `--- +doc1: same +--- +doc2: notsame +`, + )) +} + +func TestYAMLEq_InvalidIdenticalYAML(t *testing.T) { + t.Parallel() + + mockT := new(testing.T) + False(t, YAMLEq(mockT, `}`, `}`)) +} + type diffTestingStruct struct { A string B int From a78e37330e674113a8f906c77a2c7cbc37db101f Mon Sep 17 00:00:00 2001 From: Bracken Dawson Date: Thu, 11 Sep 2025 09:22:38 +0200 Subject: [PATCH 163/178] Document that YAMLEq only compared the first document in the YAML strings. --- assert/assertion_format.go | 2 +- assert/assertion_forward.go | 4 ++-- assert/assertions.go | 2 +- require/require.go | 4 ++-- require/require_forward.go | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/assert/assertion_format.go b/assert/assertion_format.go index c592f6ad5..fbd26d5c2 100644 --- a/assert/assertion_format.go +++ b/assert/assertion_format.go @@ -849,7 +849,7 @@ func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, return WithinRange(t, actual, start, end, append([]interface{}{msg}, args...)...) } -// YAMLEqf asserts that two YAML strings are equivalent. +// YAMLEqf asserts that the first document in the two YAML strings is equivalent. func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/assert/assertion_forward.go b/assert/assertion_forward.go index 58db92845..1dc208eb8 100644 --- a/assert/assertion_forward.go +++ b/assert/assertion_forward.go @@ -1690,7 +1690,7 @@ func (a *Assertions) WithinRangef(actual time.Time, start time.Time, end time.Ti return WithinRangef(a.t, actual, start, end, msg, args...) } -// YAMLEq asserts that two YAML strings are equivalent. +// YAMLEq asserts that the first document in the two YAML strings is equivalent. func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1698,7 +1698,7 @@ func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interf return YAMLEq(a.t, expected, actual, msgAndArgs...) } -// YAMLEqf asserts that two YAML strings are equivalent. +// YAMLEqf asserts that the first document in the two YAML strings is equivalent. func (a *Assertions) YAMLEqf(expected string, actual string, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() diff --git a/assert/assertions.go b/assert/assertions.go index 3f75ee0eb..37ad3de41 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -1880,7 +1880,7 @@ func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{ return Equal(t, expectedJSONAsInterface, actualJSONAsInterface, msgAndArgs...) } -// YAMLEq asserts that two YAML strings are equivalent. +// YAMLEq asserts that the first document in the two YAML strings is equivalent. func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/require/require.go b/require/require.go index 2d02f9bce..2e77e2d85 100644 --- a/require/require.go +++ b/require/require.go @@ -2135,7 +2135,7 @@ func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, t.FailNow() } -// YAMLEq asserts that two YAML strings are equivalent. +// YAMLEq asserts that the first document in the two YAML strings is equivalent. func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2146,7 +2146,7 @@ func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{ t.FailNow() } -// YAMLEqf asserts that two YAML strings are equivalent. +// YAMLEqf asserts that the first document in the two YAML strings is equivalent. func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/require/require_forward.go b/require/require_forward.go index e6f7e9446..60e5beed7 100644 --- a/require/require_forward.go +++ b/require/require_forward.go @@ -1691,7 +1691,7 @@ func (a *Assertions) WithinRangef(actual time.Time, start time.Time, end time.Ti WithinRangef(a.t, actual, start, end, msg, args...) } -// YAMLEq asserts that two YAML strings are equivalent. +// YAMLEq asserts that the first document in the two YAML strings is equivalent. func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1699,7 +1699,7 @@ func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interf YAMLEq(a.t, expected, actual, msgAndArgs...) } -// YAMLEqf asserts that two YAML strings are equivalent. +// YAMLEqf asserts that the first document in the two YAML strings is equivalent. func (a *Assertions) YAMLEqf(expected string, actual string, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() From b1007aaefb034b3a0dac3e7d2299876ff108c764 Mon Sep 17 00:00:00 2001 From: Bracken Dawson Date: Fri, 29 Oct 2021 17:38:38 +0100 Subject: [PATCH 164/178] IsIncreasing et al can return false w/out failing If you passed a non-collection to IsIncreasing or any of its compatriots then the assertion would return false without failing the test. --- assert/assertion_order.go | 2 +- assert/assertion_order_test.go | 37 +++++++++++++++++++++++----------- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/assert/assertion_order.go b/assert/assertion_order.go index 2fdf80fdd..161409eb8 100644 --- a/assert/assertion_order.go +++ b/assert/assertion_order.go @@ -9,7 +9,7 @@ import ( func isOrdered(t TestingT, object interface{}, allowedComparesResults []compareResult, failMessage string, msgAndArgs ...interface{}) bool { objKind := reflect.TypeOf(object).Kind() if objKind != reflect.Slice && objKind != reflect.Array { - return false + return Fail(t, fmt.Sprintf("object %T is not a collection", object), msgAndArgs...) } objValue := reflect.ValueOf(object) diff --git a/assert/assertion_order_test.go b/assert/assertion_order_test.go index 273333065..b9e684d64 100644 --- a/assert/assertion_order_test.go +++ b/assert/assertion_order_test.go @@ -2,6 +2,7 @@ package assert import ( "bytes" + "fmt" "testing" ) @@ -45,10 +46,13 @@ func TestIsIncreasing(t *testing.T) { {collection: []uint64{2, 1}, msg: `"2" is not less than "1"`}, {collection: []float32{2.34, 1.23}, msg: `"2.34" is not less than "1.23"`}, {collection: []float64{2.34, 1.23}, msg: `"2.34" is not less than "1.23"`}, + {collection: struct{}{}, msg: `object struct {} is not a collection`}, } { - out := &outputT{buf: bytes.NewBuffer(nil)} - False(t, IsIncreasing(out, currCase.collection)) - Contains(t, out.buf.String(), currCase.msg) + t.Run(fmt.Sprintf("%#v", currCase.collection), func(t *testing.T) { + out := &outputT{buf: bytes.NewBuffer(nil)} + False(t, IsIncreasing(out, currCase.collection)) + Contains(t, out.buf.String(), currCase.msg) + }) } } @@ -92,10 +96,13 @@ func TestIsNonIncreasing(t *testing.T) { {collection: []uint64{1, 2}, msg: `"1" is not greater than or equal to "2"`}, {collection: []float32{1.23, 2.34}, msg: `"1.23" is not greater than or equal to "2.34"`}, {collection: []float64{1.23, 2.34}, msg: `"1.23" is not greater than or equal to "2.34"`}, + {collection: struct{}{}, msg: `object struct {} is not a collection`}, } { - out := &outputT{buf: bytes.NewBuffer(nil)} - False(t, IsNonIncreasing(out, currCase.collection)) - Contains(t, out.buf.String(), currCase.msg) + t.Run(fmt.Sprintf("%#v", currCase.collection), func(t *testing.T) { + out := &outputT{buf: bytes.NewBuffer(nil)} + False(t, IsNonIncreasing(out, currCase.collection)) + Contains(t, out.buf.String(), currCase.msg) + }) } } @@ -139,10 +146,13 @@ func TestIsDecreasing(t *testing.T) { {collection: []uint64{1, 2}, msg: `"1" is not greater than "2"`}, {collection: []float32{1.23, 2.34}, msg: `"1.23" is not greater than "2.34"`}, {collection: []float64{1.23, 2.34}, msg: `"1.23" is not greater than "2.34"`}, + {collection: struct{}{}, msg: `object struct {} is not a collection`}, } { - out := &outputT{buf: bytes.NewBuffer(nil)} - False(t, IsDecreasing(out, currCase.collection)) - Contains(t, out.buf.String(), currCase.msg) + t.Run(fmt.Sprintf("%#v", currCase.collection), func(t *testing.T) { + out := &outputT{buf: bytes.NewBuffer(nil)} + False(t, IsDecreasing(out, currCase.collection)) + Contains(t, out.buf.String(), currCase.msg) + }) } } @@ -186,10 +196,13 @@ func TestIsNonDecreasing(t *testing.T) { {collection: []uint64{2, 1}, msg: `"2" is not less than or equal to "1"`}, {collection: []float32{2.34, 1.23}, msg: `"2.34" is not less than or equal to "1.23"`}, {collection: []float64{2.34, 1.23}, msg: `"2.34" is not less than or equal to "1.23"`}, + {collection: struct{}{}, msg: `object struct {} is not a collection`}, } { - out := &outputT{buf: bytes.NewBuffer(nil)} - False(t, IsNonDecreasing(out, currCase.collection)) - Contains(t, out.buf.String(), currCase.msg) + t.Run(fmt.Sprintf("%#v", currCase.collection), func(t *testing.T) { + out := &outputT{buf: bytes.NewBuffer(nil)} + False(t, IsNonDecreasing(out, currCase.collection)) + Contains(t, out.buf.String(), currCase.msg) + }) } } From ff76a29152096086f0c404cbaaccf34ddf02b0e1 Mon Sep 17 00:00:00 2001 From: Bracken Date: Tue, 8 Aug 2023 13:13:19 +0100 Subject: [PATCH 165/178] Clarify error message for incorrect use of IsIncreasing et al MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Because maps are collections but not ordered. Co-authored-by: Olivier Mengué --- assert/assertion_order.go | 2 +- assert/assertion_order_test.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/assert/assertion_order.go b/assert/assertion_order.go index 161409eb8..93657fea2 100644 --- a/assert/assertion_order.go +++ b/assert/assertion_order.go @@ -9,7 +9,7 @@ import ( func isOrdered(t TestingT, object interface{}, allowedComparesResults []compareResult, failMessage string, msgAndArgs ...interface{}) bool { objKind := reflect.TypeOf(object).Kind() if objKind != reflect.Slice && objKind != reflect.Array { - return Fail(t, fmt.Sprintf("object %T is not a collection", object), msgAndArgs...) + return Fail(t, fmt.Sprintf("object %T is not an ordered collection", object), msgAndArgs...) } objValue := reflect.ValueOf(object) diff --git a/assert/assertion_order_test.go b/assert/assertion_order_test.go index b9e684d64..f6a4763fa 100644 --- a/assert/assertion_order_test.go +++ b/assert/assertion_order_test.go @@ -46,7 +46,7 @@ func TestIsIncreasing(t *testing.T) { {collection: []uint64{2, 1}, msg: `"2" is not less than "1"`}, {collection: []float32{2.34, 1.23}, msg: `"2.34" is not less than "1.23"`}, {collection: []float64{2.34, 1.23}, msg: `"2.34" is not less than "1.23"`}, - {collection: struct{}{}, msg: `object struct {} is not a collection`}, + {collection: struct{}{}, msg: `object struct {} is not an ordered collection`}, } { t.Run(fmt.Sprintf("%#v", currCase.collection), func(t *testing.T) { out := &outputT{buf: bytes.NewBuffer(nil)} @@ -96,7 +96,7 @@ func TestIsNonIncreasing(t *testing.T) { {collection: []uint64{1, 2}, msg: `"1" is not greater than or equal to "2"`}, {collection: []float32{1.23, 2.34}, msg: `"1.23" is not greater than or equal to "2.34"`}, {collection: []float64{1.23, 2.34}, msg: `"1.23" is not greater than or equal to "2.34"`}, - {collection: struct{}{}, msg: `object struct {} is not a collection`}, + {collection: struct{}{}, msg: `object struct {} is not an ordered collection`}, } { t.Run(fmt.Sprintf("%#v", currCase.collection), func(t *testing.T) { out := &outputT{buf: bytes.NewBuffer(nil)} @@ -146,7 +146,7 @@ func TestIsDecreasing(t *testing.T) { {collection: []uint64{1, 2}, msg: `"1" is not greater than "2"`}, {collection: []float32{1.23, 2.34}, msg: `"1.23" is not greater than "2.34"`}, {collection: []float64{1.23, 2.34}, msg: `"1.23" is not greater than "2.34"`}, - {collection: struct{}{}, msg: `object struct {} is not a collection`}, + {collection: struct{}{}, msg: `object struct {} is not an ordered collection`}, } { t.Run(fmt.Sprintf("%#v", currCase.collection), func(t *testing.T) { out := &outputT{buf: bytes.NewBuffer(nil)} @@ -196,7 +196,7 @@ func TestIsNonDecreasing(t *testing.T) { {collection: []uint64{2, 1}, msg: `"2" is not less than or equal to "1"`}, {collection: []float32{2.34, 1.23}, msg: `"2.34" is not less than or equal to "1.23"`}, {collection: []float64{2.34, 1.23}, msg: `"2.34" is not less than or equal to "1.23"`}, - {collection: struct{}{}, msg: `object struct {} is not a collection`}, + {collection: struct{}{}, msg: `object struct {} is not an ordered collection`}, } { t.Run(fmt.Sprintf("%#v", currCase.collection), func(t *testing.T) { out := &outputT{buf: bytes.NewBuffer(nil)} From 65e0b94edeefdb801d16272ba5a85f503581b273 Mon Sep 17 00:00:00 2001 From: Bracken Dawson Date: Sat, 24 Feb 2024 14:56:17 +0000 Subject: [PATCH 166/178] Add missing Helper calls to IsIncreasing et al --- assert/assertion_order.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/assert/assertion_order.go b/assert/assertion_order.go index 93657fea2..a44b40ed3 100644 --- a/assert/assertion_order.go +++ b/assert/assertion_order.go @@ -50,6 +50,9 @@ func isOrdered(t TestingT, object interface{}, allowedComparesResults []compareR // assert.IsIncreasing(t, []float{1, 2}) // assert.IsIncreasing(t, []string{"a", "b"}) func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } return isOrdered(t, object, []compareResult{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs...) } @@ -59,6 +62,9 @@ func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) boo // assert.IsNonIncreasing(t, []float{2, 1}) // assert.IsNonIncreasing(t, []string{"b", "a"}) func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } return isOrdered(t, object, []compareResult{compareEqual, compareGreater}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs...) } @@ -68,6 +74,9 @@ func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) // assert.IsDecreasing(t, []float{2, 1}) // assert.IsDecreasing(t, []string{"b", "a"}) func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } return isOrdered(t, object, []compareResult{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs...) } @@ -77,5 +86,8 @@ func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) boo // assert.IsNonDecreasing(t, []float{1, 2}) // assert.IsNonDecreasing(t, []string{"a", "b"}) func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } return isOrdered(t, object, []compareResult{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs...) } From 392c0bcd569e83015dedee1e6a6fed62ce1c94e0 Mon Sep 17 00:00:00 2001 From: egawata Date: Fri, 12 Sep 2025 14:45:56 +0900 Subject: [PATCH 167/178] add type to error message of assert.Same --- assert/assertions.go | 4 ++-- assert/assertions_test.go | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index 3f75ee0eb..3d53611c3 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -544,8 +544,8 @@ 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 %#[1]v\n"+ - "actual : %p %#[2]v", + "expected: %#[1]v (%[1]T)(%[1]p)\n"+ + "actual : %#[2]v (%[2]T)(%[2]p)", expected, actual), msgAndArgs...) } diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 4db48f38b..0e3536eb1 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -635,7 +635,7 @@ func ptr(i int) *int { func TestSame(t *testing.T) { t.Parallel() - mockT := new(testing.T) + mockT := new(mockTestingT) if Same(mockT, ptr(1), ptr(1)) { t.Error("Same should return false") @@ -650,6 +650,22 @@ func TestSame(t *testing.T) { if !Same(mockT, p, p) { t.Error("Same should return true") } + + t.Run("same object, different type", func(t *testing.T) { + type s struct { + i int + } + type sPtr *s + ps := &s{1} + dps := sPtr(ps) + if Same(mockT, dps, ps) { + t.Error("Same should return false") + } + expPat := + `expected: &assert.s\{i:1\} \(assert.sPtr\)\((0x[a-f0-9]+)\)\s*\n` + + `\s+actual : &assert.s\{i:1\} \(\*assert.s\)\((0x[a-f0-9]+)\)` + Regexp(t, regexp.MustCompile(expPat), mockT.errorString()) + }) } func TestNotSame(t *testing.T) { From e8c7bc92c56e6d6c9b65e0711b3ec725211e9f5d Mon Sep 17 00:00:00 2001 From: Bracken Dawson Date: Fri, 12 Sep 2025 08:35:56 +0200 Subject: [PATCH 168/178] Add example to YAMLEq --- assert/assertion_format.go | 12 ++++++++++++ assert/assertion_forward.go | 24 ++++++++++++++++++++++++ assert/assertions.go | 12 ++++++++++++ require/require.go | 24 ++++++++++++++++++++++++ require/require_forward.go | 24 ++++++++++++++++++++++++ 5 files changed, 96 insertions(+) diff --git a/assert/assertion_format.go b/assert/assertion_format.go index fbd26d5c2..b8f3259ee 100644 --- a/assert/assertion_format.go +++ b/assert/assertion_format.go @@ -850,6 +850,18 @@ func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, } // YAMLEqf asserts that the first document in the two YAML strings is equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// assert.YAMLEqf(t, expected, actual, "error message %s", "formatted") func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/assert/assertion_forward.go b/assert/assertion_forward.go index 1dc208eb8..e24b38e64 100644 --- a/assert/assertion_forward.go +++ b/assert/assertion_forward.go @@ -1691,6 +1691,18 @@ func (a *Assertions) WithinRangef(actual time.Time, start time.Time, end time.Ti } // YAMLEq asserts that the first document in the two YAML strings is equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// a.YAMLEq(expected, actual) func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1699,6 +1711,18 @@ func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interf } // YAMLEqf asserts that the first document in the two YAML strings is equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// a.YAMLEqf(expected, actual, "error message %s", "formatted") func (a *Assertions) YAMLEqf(expected string, actual string, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() diff --git a/assert/assertions.go b/assert/assertions.go index 37ad3de41..8d22f814c 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -1881,6 +1881,18 @@ func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{ } // YAMLEq asserts that the first document in the two YAML strings is equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// assert.YAMLEq(t, expected, actual) func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/require/require.go b/require/require.go index 2e77e2d85..1df1ce93b 100644 --- a/require/require.go +++ b/require/require.go @@ -2136,6 +2136,18 @@ func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, } // YAMLEq asserts that the first document in the two YAML strings is equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// require.YAMLEq(t, expected, actual) func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2147,6 +2159,18 @@ func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{ } // YAMLEqf asserts that the first document in the two YAML strings is equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// require.YAMLEqf(t, expected, actual, "error message %s", "formatted") func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/require/require_forward.go b/require/require_forward.go index 60e5beed7..13053be03 100644 --- a/require/require_forward.go +++ b/require/require_forward.go @@ -1692,6 +1692,18 @@ func (a *Assertions) WithinRangef(actual time.Time, start time.Time, end time.Ti } // YAMLEq asserts that the first document in the two YAML strings is equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// a.YAMLEq(expected, actual) func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1700,6 +1712,18 @@ func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interf } // YAMLEqf asserts that the first document in the two YAML strings is equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// a.YAMLEqf(expected, actual, "error message %s", "formatted") func (a *Assertions) YAMLEqf(expected string, actual string, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() From 2b945c3738bc32d58217d0f8a37ac32f0311643e Mon Sep 17 00:00:00 2001 From: Bracken Date: Fri, 12 Sep 2025 09:14:40 +0200 Subject: [PATCH 169/178] Update assert/assertions.go Co-authored-by: ccoVeille <3875889+ccoVeille@users.noreply.github.com> --- assert/assertion_format.go | 2 +- assert/assertion_forward.go | 4 ++-- assert/assertions.go | 2 +- require/require.go | 4 ++-- require/require_forward.go | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/assert/assertion_format.go b/assert/assertion_format.go index b8f3259ee..66029153a 100644 --- a/assert/assertion_format.go +++ b/assert/assertion_format.go @@ -849,7 +849,7 @@ func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, return WithinRange(t, actual, start, end, append([]interface{}{msg}, args...)...) } -// YAMLEqf asserts that the first document in the two YAML strings is equivalent. +// YAMLEqf asserts that the first documents in the two YAML strings are equivalent. // // expected := `--- // key: value diff --git a/assert/assertion_forward.go b/assert/assertion_forward.go index e24b38e64..b72a4a124 100644 --- a/assert/assertion_forward.go +++ b/assert/assertion_forward.go @@ -1690,7 +1690,7 @@ func (a *Assertions) WithinRangef(actual time.Time, start time.Time, end time.Ti return WithinRangef(a.t, actual, start, end, msg, args...) } -// YAMLEq asserts that the first document in the two YAML strings is equivalent. +// YAMLEq asserts that the first documents in the two YAML strings are equivalent. // // expected := `--- // key: value @@ -1710,7 +1710,7 @@ func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interf return YAMLEq(a.t, expected, actual, msgAndArgs...) } -// YAMLEqf asserts that the first document in the two YAML strings is equivalent. +// YAMLEqf asserts that the first documents in the two YAML strings are equivalent. // // expected := `--- // key: value diff --git a/assert/assertions.go b/assert/assertions.go index 8d22f814c..590bb8922 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -1880,7 +1880,7 @@ func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{ return Equal(t, expectedJSONAsInterface, actualJSONAsInterface, msgAndArgs...) } -// YAMLEq asserts that the first document in the two YAML strings is equivalent. +// YAMLEq asserts that the first documents in the two YAML strings are equivalent. // // expected := `--- // key: value diff --git a/require/require.go b/require/require.go index 1df1ce93b..9cd13df22 100644 --- a/require/require.go +++ b/require/require.go @@ -2135,7 +2135,7 @@ func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, t.FailNow() } -// YAMLEq asserts that the first document in the two YAML strings is equivalent. +// YAMLEq asserts that the first documents in the two YAML strings are equivalent. // // expected := `--- // key: value @@ -2158,7 +2158,7 @@ func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{ t.FailNow() } -// YAMLEqf asserts that the first document in the two YAML strings is equivalent. +// YAMLEqf asserts that the first documents in the two YAML strings are equivalent. // // expected := `--- // key: value diff --git a/require/require_forward.go b/require/require_forward.go index 13053be03..deae0cd13 100644 --- a/require/require_forward.go +++ b/require/require_forward.go @@ -1691,7 +1691,7 @@ func (a *Assertions) WithinRangef(actual time.Time, start time.Time, end time.Ti WithinRangef(a.t, actual, start, end, msg, args...) } -// YAMLEq asserts that the first document in the two YAML strings is equivalent. +// YAMLEq asserts that the first documents in the two YAML strings are equivalent. // // expected := `--- // key: value @@ -1711,7 +1711,7 @@ func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interf YAMLEq(a.t, expected, actual, msgAndArgs...) } -// YAMLEqf asserts that the first document in the two YAML strings is equivalent. +// YAMLEqf asserts that the first documents in the two YAML strings are equivalent. // // expected := `--- // key: value From 0bf6b946d985309f37a4364b0b1f01a92698730e Mon Sep 17 00:00:00 2001 From: Bracken Dawson Date: Mon, 15 Sep 2025 12:07:57 +0200 Subject: [PATCH 170/178] mock.AssertExpectationsForObjects fix panic with wrong testObject type. Previously passing a mock.Mock by value rather than by reference worked (in cases without mutex locking issues) and logged a warning. This was broken by #1212 which introduced a breaking change in an attempt to fix go vet. There is no clean way to fix the breaking change as we now have (and want) go vet in our CI. This PR does not revert the breaking change but changes the panic to a test failure with a useful message. --- mock/mock.go | 9 +++++---- mock/mock_test.go | 6 ++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/mock/mock.go b/mock/mock.go index b9ca645c2..37ce7b396 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -603,11 +603,12 @@ func AssertExpectationsForObjects(t TestingT, testObjects ...interface{}) bool { h.Helper() } for _, obj := range testObjects { - if m, ok := obj.(*Mock); ok { - t.Logf("Deprecated mock.AssertExpectationsForObjects(myMock.Mock) use mock.AssertExpectationsForObjects(myMock)") - obj = m + m, ok := obj.(assertExpectationiser) + if !ok { + t.Errorf("Invalid test object type %T. Expected reference to a mock.Mock, eg: 'AssertExpectationsForObjects(t, myMock)' or 'AssertExpectationsForObjects(t, &myMock.Mock)'", obj) + continue + } - m := obj.(assertExpectationiser) if !m.AssertExpectations(t) { t.Logf("Expectations didn't match for Mock: %+v", reflect.TypeOf(m)) return false diff --git a/mock/mock_test.go b/mock/mock_test.go index 7c97754ae..3dc9e0b1e 100644 --- a/mock/mock_test.go +++ b/mock/mock_test.go @@ -2461,3 +2461,9 @@ func TestIssue1785ArgumentWithMutatingStringer(t *testing.T) { m.MethodCalled("Method", &mutatingStringer{N: 2}) m.AssertExpectations(t) } + +func TestIssue1227AssertExpectationsForObjectsWithMock(t *testing.T) { + mockT := &MockTestingT{} + AssertExpectationsForObjects(mockT, Mock{}) + assert.Equal(t, 1, mockT.errorfCount) +} From 3f2814353abce0092fc4cea1ddb2471c50040a6b Mon Sep 17 00:00:00 2001 From: Bracken Dawson Date: Tue, 16 Sep 2025 10:26:27 +0200 Subject: [PATCH 171/178] Remove ineffective inline code blocks Godoc does not have inline code blocks. Look to the standaed library for conventions for inline references to code. --- assert/assertion_format.go | 10 +++++----- assert/assertion_forward.go | 20 ++++++++++---------- assert/assertions.go | 10 +++++----- assert/doc.go | 4 ++-- mock/mock.go | 4 ++-- require/doc.go | 6 +++--- require/require.go | 20 ++++++++++---------- require/require_forward.go | 20 ++++++++++---------- suite/suite.go | 14 +++++++++----- 9 files changed, 56 insertions(+), 52 deletions(-) diff --git a/assert/assertion_format.go b/assert/assertion_format.go index 66029153a..2d089991a 100644 --- a/assert/assertion_format.go +++ b/assert/assertion_format.go @@ -84,7 +84,7 @@ func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, ar return Equal(t, expected, actual, append([]interface{}{msg}, args...)...) } -// EqualErrorf asserts that a function returned an error (i.e. not `nil`) +// EqualErrorf asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -124,7 +124,7 @@ func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg stri return EqualValues(t, expected, actual, append([]interface{}{msg}, args...)...) } -// Errorf asserts that a function returned an error (i.e. not `nil`). +// Errorf asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // assert.Errorf(t, err, "error message %s", "formatted") @@ -144,8 +144,8 @@ func ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...int return ErrorAs(t, err, target, append([]interface{}{msg}, args...)...) } -// ErrorContainsf asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContainsf asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // assert.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") @@ -552,7 +552,7 @@ func NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) bool return NoDirExists(t, path, append([]interface{}{msg}, args...)...) } -// NoErrorf asserts that a function returned no error (i.e. `nil`). +// NoErrorf asserts that a function returned a nil error (ie. no error). // // actualObj, err := SomeFunction() // if assert.NoErrorf(t, err, "error message %s", "formatted") { diff --git a/assert/assertion_forward.go b/assert/assertion_forward.go index b72a4a124..d8300af73 100644 --- a/assert/assertion_forward.go +++ b/assert/assertion_forward.go @@ -146,7 +146,7 @@ func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs return Equal(a.t, expected, actual, msgAndArgs...) } -// EqualError asserts that a function returned an error (i.e. not `nil`) +// EqualError asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -158,7 +158,7 @@ func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ... return EqualError(a.t, theError, errString, msgAndArgs...) } -// EqualErrorf asserts that a function returned an error (i.e. not `nil`) +// EqualErrorf asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -240,7 +240,7 @@ func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string return Equalf(a.t, expected, actual, msg, args...) } -// Error asserts that a function returned an error (i.e. not `nil`). +// Error asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // a.Error(err) @@ -269,8 +269,8 @@ func (a *Assertions) ErrorAsf(err error, target interface{}, msg string, args .. return ErrorAsf(a.t, err, target, msg, args...) } -// ErrorContains asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContains asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // a.ErrorContains(err, expectedErrorSubString) @@ -281,8 +281,8 @@ func (a *Assertions) ErrorContains(theError error, contains string, msgAndArgs . return ErrorContains(a.t, theError, contains, msgAndArgs...) } -// ErrorContainsf asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContainsf asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // a.ErrorContainsf(err, expectedErrorSubString, "error message %s", "formatted") @@ -311,7 +311,7 @@ func (a *Assertions) ErrorIsf(err error, target error, msg string, args ...inter return ErrorIsf(a.t, err, target, msg, args...) } -// Errorf asserts that a function returned an error (i.e. not `nil`). +// Errorf asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // a.Errorf(err, "error message %s", "formatted") @@ -1096,7 +1096,7 @@ func (a *Assertions) NoDirExistsf(path string, msg string, args ...interface{}) return NoDirExistsf(a.t, path, msg, args...) } -// NoError asserts that a function returned no error (i.e. `nil`). +// NoError asserts that a function returned a nil error (ie. no error). // // actualObj, err := SomeFunction() // if a.NoError(err) { @@ -1109,7 +1109,7 @@ func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool { return NoError(a.t, err, msgAndArgs...) } -// NoErrorf asserts that a function returned no error (i.e. `nil`). +// NoErrorf asserts that a function returned a nil error (ie. no error). // // actualObj, err := SomeFunction() // if a.NoErrorf(err, "error message %s", "formatted") { diff --git a/assert/assertions.go b/assert/assertions.go index f6219d73b..31400a032 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -1630,7 +1630,7 @@ func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, m Errors */ -// NoError asserts that a function returned no error (i.e. `nil`). +// NoError asserts that a function returned a nil error (ie. no error). // // actualObj, err := SomeFunction() // if assert.NoError(t, err) { @@ -1647,7 +1647,7 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { return true } -// Error asserts that a function returned an error (i.e. not `nil`). +// Error asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // assert.Error(t, err) @@ -1662,7 +1662,7 @@ func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { return true } -// EqualError asserts that a function returned an error (i.e. not `nil`) +// EqualError asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -1685,8 +1685,8 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte return true } -// ErrorContains asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContains asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // assert.ErrorContains(t, err, expectedErrorSubString) diff --git a/assert/doc.go b/assert/doc.go index a0b953aa5..0fb5c6137 100644 --- a/assert/doc.go +++ b/assert/doc.go @@ -40,8 +40,8 @@ // // # Assertions // -// Assertions allow you to easily write test code, and are global funcs in the `assert` package. -// All assertion functions take, as the first argument, the `*testing.T` object provided by the +// Assertions allow you to easily write test code, and are global funcs in the assert package. +// All assertion functions take, as the first argument, the *testing.T object provided by the // testing framework. This allows the assertion funcs to write the failings and other details to // the correct place. // diff --git a/mock/mock.go b/mock/mock.go index 37ce7b396..c95eeeca8 100644 --- a/mock/mock.go +++ b/mock/mock.go @@ -712,8 +712,8 @@ func (m *Mock) AssertNotCalled(t TestingT, methodName string, arguments ...inter return true } -// IsMethodCallable checking that the method can be called -// If the method was called more than `Repeatability` return false +// IsMethodCallable returns true if given methodName and arguments have an +// unsatisfied expected call registered in the Mock. func (m *Mock) IsMethodCallable(t TestingT, methodName string, arguments ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/require/doc.go b/require/doc.go index c8e3f94a8..7e88f07cd 100644 --- a/require/doc.go +++ b/require/doc.go @@ -1,4 +1,4 @@ -// Package require implements the same assertions as the `assert` package but +// Package require implements the same assertions as the assert package but // stops test execution when a test fails. // // # Example Usage @@ -21,8 +21,8 @@ // // # Assertions // -// The `require` package have same global functions as in the `assert` package, -// but instead of returning a boolean result they call `t.FailNow()`. +// 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. // diff --git a/require/require.go b/require/require.go index 9cd13df22..23a3be780 100644 --- a/require/require.go +++ b/require/require.go @@ -180,7 +180,7 @@ func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...i t.FailNow() } -// EqualError asserts that a function returned an error (i.e. not `nil`) +// EqualError asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -195,7 +195,7 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte t.FailNow() } -// EqualErrorf asserts that a function returned an error (i.e. not `nil`) +// EqualErrorf asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -295,7 +295,7 @@ func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, ar t.FailNow() } -// Error asserts that a function returned an error (i.e. not `nil`). +// Error asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // require.Error(t, err) @@ -333,8 +333,8 @@ func ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...int t.FailNow() } -// ErrorContains asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContains asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // require.ErrorContains(t, err, expectedErrorSubString) @@ -348,8 +348,8 @@ func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...in t.FailNow() } -// ErrorContainsf asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContainsf asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // require.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") @@ -387,7 +387,7 @@ func ErrorIsf(t TestingT, err error, target error, msg string, args ...interface t.FailNow() } -// Errorf asserts that a function returned an error (i.e. not `nil`). +// Errorf asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // require.Errorf(t, err, "error message %s", "formatted") @@ -1385,7 +1385,7 @@ func NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) { t.FailNow() } -// NoError asserts that a function returned no error (i.e. `nil`). +// NoError asserts that a function returned a nil error (ie. no error). // // actualObj, err := SomeFunction() // if require.NoError(t, err) { @@ -1401,7 +1401,7 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) { t.FailNow() } -// NoErrorf asserts that a function returned no error (i.e. `nil`). +// NoErrorf asserts that a function returned a nil error (ie. no error). // // actualObj, err := SomeFunction() // if require.NoErrorf(t, err, "error message %s", "formatted") { diff --git a/require/require_forward.go b/require/require_forward.go index deae0cd13..38d985a55 100644 --- a/require/require_forward.go +++ b/require/require_forward.go @@ -147,7 +147,7 @@ func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs Equal(a.t, expected, actual, msgAndArgs...) } -// EqualError asserts that a function returned an error (i.e. not `nil`) +// EqualError asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -159,7 +159,7 @@ func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ... EqualError(a.t, theError, errString, msgAndArgs...) } -// EqualErrorf asserts that a function returned an error (i.e. not `nil`) +// EqualErrorf asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -241,7 +241,7 @@ func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string Equalf(a.t, expected, actual, msg, args...) } -// Error asserts that a function returned an error (i.e. not `nil`). +// Error asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // a.Error(err) @@ -270,8 +270,8 @@ func (a *Assertions) ErrorAsf(err error, target interface{}, msg string, args .. ErrorAsf(a.t, err, target, msg, args...) } -// ErrorContains asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContains asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // a.ErrorContains(err, expectedErrorSubString) @@ -282,8 +282,8 @@ func (a *Assertions) ErrorContains(theError error, contains string, msgAndArgs . ErrorContains(a.t, theError, contains, msgAndArgs...) } -// ErrorContainsf asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContainsf asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // a.ErrorContainsf(err, expectedErrorSubString, "error message %s", "formatted") @@ -312,7 +312,7 @@ func (a *Assertions) ErrorIsf(err error, target error, msg string, args ...inter ErrorIsf(a.t, err, target, msg, args...) } -// Errorf asserts that a function returned an error (i.e. not `nil`). +// Errorf asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // a.Errorf(err, "error message %s", "formatted") @@ -1097,7 +1097,7 @@ func (a *Assertions) NoDirExistsf(path string, msg string, args ...interface{}) NoDirExistsf(a.t, path, msg, args...) } -// NoError asserts that a function returned no error (i.e. `nil`). +// NoError asserts that a function returned a nil error (ie. no error). // // actualObj, err := SomeFunction() // if a.NoError(err) { @@ -1110,7 +1110,7 @@ func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) { NoError(a.t, err, msgAndArgs...) } -// NoErrorf asserts that a function returned no error (i.e. `nil`). +// NoErrorf asserts that a function returned a nil error (ie. no error). // // actualObj, err := SomeFunction() // if a.NoErrorf(err, "error message %s", "formatted") { diff --git a/suite/suite.go b/suite/suite.go index 92a861098..32976ac9f 100644 --- a/suite/suite.go +++ b/suite/suite.go @@ -63,11 +63,15 @@ func (suite *Suite) Require() *require.Assertions { return suite.require } -// Assert returns an assert context for suite. Normally, you can call -// `suite.NoError(expected, actual)`, but for situations where the embedded -// methods are overridden (for example, you might want to override -// assert.Assertions with require.Assertions), this method is provided so you -// can call `suite.Assert().NoError()`. +// Assert returns an assert context for suite. Normally, you can call: +// +// suite.NoError(err) +// +// But for situations where the embedded methods are overridden (for example, +// you might want to override assert.Assertions with require.Assertions), this +// method is provided so you can call: +// +// suite.Assert().NoError(err) func (suite *Suite) Assert() *assert.Assertions { suite.mu.Lock() defer suite.mu.Unlock() From c58ac3d0f0edf188e6ad7c8434a90567f661cc2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Mon, 25 Aug 2025 15:09:40 +0200 Subject: [PATCH 172/178] _codegen: copy package github.com/ernesto-jimenez/gogen/imports Copy code from dependency github.com/ernesto-jimenez/gogen/imports (which hasn't evolved since 2018) as package _codegen/internal/imports. This is imported from https://github.com/ernesto-jimenez/gogen at commit d7d4131e6607813977e78297a6060f360f056a97. See https://github.com/ernesto-jimenez/gogen/tree/d7d4131e6607813977e78297a6060f360f056a97/imports The license block is added to match the LICENSE file from the source repository. --- _codegen/internal/imports/imports.go | 108 +++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 _codegen/internal/imports/imports.go diff --git a/_codegen/internal/imports/imports.go b/_codegen/internal/imports/imports.go new file mode 100644 index 000000000..a0c7e2b6a --- /dev/null +++ b/_codegen/internal/imports/imports.go @@ -0,0 +1,108 @@ +/* +The MIT License (MIT) + +Copyright (c) 2015 Ernesto Jiménez + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +package imports + +import ( + "go/types" + "os" + "path/filepath" + "strings" +) + +type Importer interface { + AddImportsFrom(t types.Type) + Imports() map[string]string +} + +// imports contains metadata about all the imports from a given package +type imports struct { + currentpkg string + imp map[string]string +} + +// AddImportsFrom adds imports used in the passed type +func (imp *imports) AddImportsFrom(t types.Type) { + switch el := t.(type) { + case *types.Basic: + case *types.Slice: + imp.AddImportsFrom(el.Elem()) + case *types.Pointer: + imp.AddImportsFrom(el.Elem()) + case *types.Named: + pkg := el.Obj().Pkg() + if pkg == nil { + return + } + if pkg.Name() == imp.currentpkg { + return + } + imp.imp[cleanImportPath(pkg.Path())] = pkg.Name() + case *types.Tuple: + for i := 0; i < el.Len(); i++ { + imp.AddImportsFrom(el.At(i).Type()) + } + default: + } +} + +func cleanImportPath(ipath string) string { + return gopathlessImportPath( + vendorlessImportPath(ipath), + ) +} + +func gopathlessImportPath(ipath string) string { + paths := strings.Split(os.Getenv("GOPATH"), ":") + for _, p := range paths { + ipath = strings.TrimPrefix(ipath, filepath.Join(p, "src")+string(filepath.Separator)) + } + return ipath +} + +// vendorlessImportPath returns the devendorized version of the provided import path. +// e.g. "foo/bar/vendor/a/b" => "a/b" +func vendorlessImportPath(ipath string) string { + // Devendorize for use in import statement. + if i := strings.LastIndex(ipath, "/vendor/"); i >= 0 { + return ipath[i+len("/vendor/"):] + } + if strings.HasPrefix(ipath, "vendor/") { + return ipath[len("vendor/"):] + } + return ipath +} + +// AddImportsFrom adds imports used in the passed type +func (imp *imports) Imports() map[string]string { + return imp.imp +} + +// New initializes a new structure to track packages imported by the currentpkg +func New(currentpkg string) Importer { + return &imports{ + currentpkg: currentpkg, + imp: make(map[string]string), + } +} From 242e746a97a57ce7c85eaa27ecf471eb97311188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= Date: Mon, 25 Aug 2025 15:23:08 +0200 Subject: [PATCH 173/178] _codegen: use our imported copy of github.com/ernesto-jimenez/gogen Use our imported copy of package github.com/ernesto-jimenez/gogen/imports to remove one external dependency. --- _codegen/go.mod | 2 -- _codegen/go.sum | 2 -- _codegen/main.go | 2 +- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/_codegen/go.mod b/_codegen/go.mod index 31a7e991c..c295a36ba 100644 --- a/_codegen/go.mod +++ b/_codegen/go.mod @@ -1,5 +1,3 @@ module github.com/stretchr/testify/_codegen go 1.11 - -require github.com/ernesto-jimenez/gogen v0.0.0-20180125220232-d7d4131e6607 diff --git a/_codegen/go.sum b/_codegen/go.sum index 1c1b88eb5..e69de29bb 100644 --- a/_codegen/go.sum +++ b/_codegen/go.sum @@ -1,2 +0,0 @@ -github.com/ernesto-jimenez/gogen v0.0.0-20180125220232-d7d4131e6607 h1:cTavhURetDkezJCvxFggiyLeP40Mrk/TtVg2+ycw1Es= -github.com/ernesto-jimenez/gogen v0.0.0-20180125220232-d7d4131e6607/go.mod h1:Cg4fM0vhYWOZdgM7RIOSTRNIc8/VT7CXClC3Ni86lu4= diff --git a/_codegen/main.go b/_codegen/main.go index e193a74a5..574985181 100644 --- a/_codegen/main.go +++ b/_codegen/main.go @@ -23,7 +23,7 @@ import ( "strings" "text/template" - "github.com/ernesto-jimenez/gogen/imports" + "github.com/stretchr/testify/_codegen/internal/imports" ) var ( From 1eb5fc0b40b46c0bddf911802faea2dd0831985f Mon Sep 17 00:00:00 2001 From: Bracken Dawson Date: Thu, 3 Oct 2024 16:38:42 +0100 Subject: [PATCH 174/178] Truncate very long objects in test failure messages --- assert/assertions.go | 86 ++++++------- assert/assertions_test.go | 259 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 294 insertions(+), 51 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index f6219d73b..58172881b 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -325,13 +325,15 @@ func messageFromMsgAndArgs(msgAndArgs ...interface{}) string { func indentMessageLines(message string, longestLabelLen int) string { outBuf := new(bytes.Buffer) - for i, scanner := 0, bufio.NewScanner(strings.NewReader(message)); scanner.Scan(); i++ { - // no need to align first line because it starts at the correct location (after the label) - if i != 0 { - // append alignLen+1 spaces to align with "{{longestLabel}}:" before adding tab - outBuf.WriteString("\n\t" + strings.Repeat(" ", longestLabelLen+1) + "\t") + scanner := bufio.NewScanner(strings.NewReader(message)) + for firstLine := true; scanner.Scan(); firstLine = false { + if !firstLine { + fmt.Fprint(outBuf, "\n\t"+strings.Repeat(" ", longestLabelLen+1)+"\t") } - outBuf.WriteString(scanner.Text()) + fmt.Fprint(outBuf, scanner.Text()) + } + if err := scanner.Err(); err != nil { + return fmt.Sprintf("cannot display message: %s", err) } return outBuf.String() @@ -544,9 +546,8 @@ 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: %#[1]v (%[1]T)(%[1]p)\n"+ - "actual : %#[2]v (%[2]T)(%[2]p)", - expected, actual), msgAndArgs...) + "expected: %[2]s (%[1]T)(%[1]p)\n"+ + "actual : %[4]s (%[3]T)(%[3]p)", expected, truncatingFormat("%#v", expected), actual, truncatingFormat("%#v", actual)), msgAndArgs...) } return true @@ -571,8 +572,8 @@ func NotSame(t TestingT, expected, actual interface{}, msgAndArgs ...interface{} if same { return Fail(t, fmt.Sprintf( - "Expected and actual point to the same object: %p %#[1]v", - expected), msgAndArgs...) + "Expected and actual point to the same object: %p %s", + expected, truncatingFormat("%#v", expected)), msgAndArgs...) } return true } @@ -604,23 +605,24 @@ func samePointers(first, second interface{}) (same bool, ok bool) { // to a type conversion in the Go grammar. func formatUnequalValues(expected, actual interface{}) (e string, a string) { if reflect.TypeOf(expected) != reflect.TypeOf(actual) { - return fmt.Sprintf("%T(%s)", expected, truncatingFormat(expected)), - fmt.Sprintf("%T(%s)", actual, truncatingFormat(actual)) + return fmt.Sprintf("%T(%s)", expected, truncatingFormat("%#v", expected)), + fmt.Sprintf("%T(%s)", actual, truncatingFormat("%#v", actual)) } switch expected.(type) { case time.Duration: return fmt.Sprintf("%v", expected), fmt.Sprintf("%v", actual) } - return truncatingFormat(expected), truncatingFormat(actual) + return truncatingFormat("%#v", expected), truncatingFormat("%#v", actual) } // truncatingFormat formats the data and truncates it if it's too long. // // This helps keep formatted error messages lines from exceeding the // bufio.MaxScanTokenSize max line length that the go testing framework imposes. -func truncatingFormat(data interface{}) string { - value := fmt.Sprintf("%#v", data) - max := bufio.MaxScanTokenSize - 100 // Give us some space the type info too if needed. +func truncatingFormat(format string, data interface{}) string { + value := fmt.Sprintf(format, data) + // Give us space for two truncated objects and the surrounding sentence. + max := bufio.MaxScanTokenSize/2 - 100 if len(value) > max { value = value[0:max] + "<... truncated>" } @@ -743,7 +745,7 @@ func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() } - return Fail(t, fmt.Sprintf("Expected nil, but got: %#v", object), msgAndArgs...) + return Fail(t, fmt.Sprintf("Expected nil, but got: %s", truncatingFormat("%#v", object)), msgAndArgs...) } // isEmpty gets whether the specified object is considered empty or not. @@ -793,7 +795,7 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() } - Fail(t, fmt.Sprintf("Should be empty, but was %v", object), msgAndArgs...) + Fail(t, fmt.Sprintf("Should be empty, but was %s", truncatingFormat("%v", object)), msgAndArgs...) } return pass @@ -836,11 +838,11 @@ func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) } l, ok := getLen(object) if !ok { - return Fail(t, fmt.Sprintf("\"%v\" could not be applied builtin len()", object), msgAndArgs...) + return Fail(t, fmt.Sprintf("%q could not be applied builtin len()", truncatingFormat("%v", object)), msgAndArgs...) } if l != length { - return Fail(t, fmt.Sprintf("\"%v\" should have %d item(s), but has %d", object, length, l), msgAndArgs...) + return Fail(t, fmt.Sprintf("%q should have %d item(s), but has %d", truncatingFormat("%v", object), length, l), msgAndArgs...) } return true } @@ -889,7 +891,7 @@ func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{ } if ObjectsAreEqual(expected, actual) { - return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...) + return Fail(t, fmt.Sprintf("Should not be: %s\n", truncatingFormat("%#v", actual)), msgAndArgs...) } return true @@ -904,7 +906,7 @@ func NotEqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...inte } if ObjectsAreEqualValues(expected, actual) { - return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...) + return Fail(t, fmt.Sprintf("Should not be: %s\n", truncatingFormat("%#v", actual)), msgAndArgs...) } return true @@ -964,10 +966,10 @@ func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bo ok, found := containsElement(s, contains) if !ok { - return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", s), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s could not be applied builtin len()", truncatingFormat("%#v", s)), msgAndArgs...) } if !found { - return Fail(t, fmt.Sprintf("%#v does not contain %#v", s, contains), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s does not contain %#v", truncatingFormat("%#v", s), contains), msgAndArgs...) } return true @@ -986,10 +988,10 @@ func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) ok, found := containsElement(s, contains) if !ok { - return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", s), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s could not be applied builtin len()", truncatingFormat("%#v", s)), msgAndArgs...) } if found { - return Fail(t, fmt.Sprintf("%#v should not contain %#v", s, contains), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s should not contain %#v", truncatingFormat("%#v", s), contains), msgAndArgs...) } return true @@ -1031,10 +1033,10 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok av := actualMap.MapIndex(k) if !av.IsValid() { - return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, subset), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s does not contain %s", truncatingFormat("%#v", list), truncatingFormat("%#v", subset)), msgAndArgs...) } if !ObjectsAreEqual(ev.Interface(), av.Interface()) { - return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, subset), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s does not contain %s", truncatingFormat("%#v", list), truncatingFormat("%#v", subset)), msgAndArgs...) } } @@ -1056,7 +1058,7 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", list), msgAndArgs...) } if !found { - return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, element), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s does not contain %#v", truncatingFormat("%#v", list), element), msgAndArgs...) } } @@ -1106,7 +1108,7 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) } } - return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s is a subset of %s", truncatingFormat("%#v", subset), truncatingFormat("%#v", list)), msgAndArgs...) } subsetList := reflect.ValueOf(subset) @@ -1128,7 +1130,7 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) } } - return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s is a subset of %s", truncatingFormat("%#v", subset), truncatingFormat("%#v", list)), msgAndArgs...) } // ElementsMatch asserts that the specified listA(array, slice...) is equal to specified @@ -1641,7 +1643,7 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() } - return Fail(t, fmt.Sprintf("Received unexpected error:\n%+v", err), msgAndArgs...) + return Fail(t, fmt.Sprintf("Received unexpected error:\n%s", truncatingFormat("%+v", err)), msgAndArgs...) } return true @@ -1680,7 +1682,7 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte if expected != actual { return Fail(t, fmt.Sprintf("Error message not equal:\n"+ "expected: %q\n"+ - "actual : %q", expected, actual), msgAndArgs...) + "actual : %s", expected, truncatingFormat("%q", actual)), msgAndArgs...) } return true } @@ -1700,7 +1702,7 @@ func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...in actual := theError.Error() if !strings.Contains(actual, contains) { - return Fail(t, fmt.Sprintf("Error %#v does not contain %#v", actual, contains), msgAndArgs...) + return Fail(t, fmt.Sprintf("Error %s does not contain %#v", truncatingFormat("%#v", actual), contains), msgAndArgs...) } return true @@ -1766,7 +1768,7 @@ func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { h.Helper() } if i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) { - return Fail(t, fmt.Sprintf("Should be zero, but was %v", i), msgAndArgs...) + return Fail(t, fmt.Sprintf("Should be zero, but was %s", truncatingFormat("%v", i)), msgAndArgs...) } return true } @@ -2206,8 +2208,8 @@ func ErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool { chain := buildErrorChainString(err, false) return Fail(t, fmt.Sprintf("Target error should be in err chain:\n"+ - "expected: %q\n"+ - "in chain: %s", expectedText, chain, + "expected: %s\n"+ + "in chain: %s", truncatingFormat("%q", expectedText), truncatingFormat("%s", chain), ), msgAndArgs...) } @@ -2229,8 +2231,8 @@ func NotErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool { chain := buildErrorChainString(err, false) return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+ - "found: %q\n"+ - "in chain: %s", expectedText, chain, + "found: %s\n"+ + "in chain: %s", truncatingFormat("%q", expectedText), truncatingFormat("%s", chain), ), msgAndArgs...) } @@ -2254,7 +2256,7 @@ func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{ return Fail(t, fmt.Sprintf("Should be in error chain:\n"+ "expected: %s\n"+ - "in chain: %s", expectedType, chain, + "in chain: %s", expectedType, truncatingFormat("%s", chain), ), msgAndArgs...) } @@ -2272,7 +2274,7 @@ func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interfa return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+ "found: %s\n"+ - "in chain: %s", reflect.TypeOf(target).Elem().String(), chain, + "in chain: %s", reflect.TypeOf(target).Elem().String(), truncatingFormat("%s", chain), ), msgAndArgs...) } diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 1784d7140..02bef780b 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -1202,10 +1202,10 @@ func TestSubsetNotSubset(t *testing.T) { }{ // cases that are expected to contain {[]int{1, 2, 3}, nil, true, `nil is the empty set which is a subset of every set`}, - {[]int{1, 2, 3}, []int{}, true, `[] is a subset of ['\x01' '\x02' '\x03']`}, - {[]int{1, 2, 3}, []int{1, 2}, true, `['\x01' '\x02'] is a subset of ['\x01' '\x02' '\x03']`}, - {[]int{1, 2, 3}, []int{1, 2, 3}, true, `['\x01' '\x02' '\x03'] is a subset of ['\x01' '\x02' '\x03']`}, - {[]string{"hello", "world"}, []string{"hello"}, true, `["hello"] is a subset of ["hello" "world"]`}, + {[]int{1, 2, 3}, []int{}, true, `[]int{} is a subset of []int{1, 2, 3}`}, + {[]int{1, 2, 3}, []int{1, 2}, true, `[]int{1, 2} is a subset of []int{1, 2, 3}`}, + {[]int{1, 2, 3}, []int{1, 2, 3}, true, `[]int{1, 2, 3} is a subset of []int{1, 2, 3}`}, + {[]string{"hello", "world"}, []string{"hello"}, true, `[]string{"hello"} is a subset of []string{"hello", "world"}`}, {map[string]string{ "a": "x", "c": "z", @@ -1213,8 +1213,8 @@ func TestSubsetNotSubset(t *testing.T) { }, map[string]string{ "a": "x", "b": "y", - }, true, `map["a":"x" "b":"y"] is a subset of map["a":"x" "b":"y" "c":"z"]`}, - {[]string{"a", "b", "c"}, map[string]int{"a": 1, "c": 3}, true, `map["a":'\x01' "c":'\x03'] is a subset of ["a" "b" "c"]`}, + }, true, `map[string]string{"a":"x", "b":"y"} is a subset of map[string]string{"a":"x", "b":"y", "c":"z"}`}, + {[]string{"a", "b", "c"}, map[string]int{"a": 1, "c": 3}, true, `map[string]int{"a":1, "c":3} is a subset of []string{"a", "b", "c"}`}, // cases that are expected not to contain {[]string{"hello", "world"}, []string{"hello", "testify"}, false, `[]string{"hello", "world"} does not contain "testify"`}, @@ -3653,12 +3653,12 @@ func Test_validateEqualArgs(t *testing.T) { func Test_truncatingFormat(t *testing.T) { t.Parallel() - original := strings.Repeat("a", bufio.MaxScanTokenSize-102) - result := truncatingFormat(original) + original := strings.Repeat("a", bufio.MaxScanTokenSize/2-102) + result := truncatingFormat("%#v", original) Equal(t, fmt.Sprintf("%#v", original), result, "string should not be truncated") original = original + "x" - result = truncatingFormat(original) + result = truncatingFormat("%#v", original) NotEqual(t, fmt.Sprintf("%#v", original), result, "string should have been truncated.") if !strings.HasSuffix(result, "<... truncated>") { @@ -3969,3 +3969,244 @@ func TestNotErrorAs(t *testing.T) { }) } } + +func TestLenWithSliceTooLongToPrint(t *testing.T) { + t.Parallel() + mockT := new(mockTestingT) + longSlice := make([]int, 1_000_000) + Len(mockT, longSlice, 1) + Contains(t, mockT.errorString(), ` + Error Trace: + Error: "[0 0 0`) + Contains(t, mockT.errorString(), `<... truncated>" should have 1 item(s), but has 1000000`) +} + +func TestContainsWithSliceTooLongToPrint(t *testing.T) { + t.Parallel() + mockT := new(mockTestingT) + longSlice := make([]int, 1_000_000) + Contains(mockT, longSlice, 1) + Contains(t, mockT.errorString(), ` + Error Trace: + Error: []int{0, 0, 0,`) + Contains(t, mockT.errorString(), `<... truncated> does not contain 1`) +} + +func TestNotContainsWithSliceTooLongToPrint(t *testing.T) { + t.Parallel() + mockT := new(mockTestingT) + longSlice := make([]int, 1_000_000) + NotContains(mockT, longSlice, 0) + Contains(t, mockT.errorString(), ` + Error Trace: + Error: []int{0, 0, 0,`) + Contains(t, mockT.errorString(), `<... truncated> should not contain 0`) +} + +func TestSubsetWithSliceTooLongToPrint(t *testing.T) { + t.Parallel() + mockT := new(mockTestingT) + longSlice := make([]int, 1_000_000) + Subset(mockT, longSlice, []int{1}) + Contains(t, mockT.errorString(), ` + Error Trace: + Error: []int{0, 0, 0,`) + Contains(t, mockT.errorString(), `<... truncated> does not contain 1`) +} + +func TestSubsetWithMapTooLongToPrint(t *testing.T) { + t.Parallel() + mockT := new(mockTestingT) + longSlice := make([]int, 1_000_000) + Subset(mockT, map[bool][]int{true: longSlice}, map[bool][]int{false: longSlice}) + Contains(t, mockT.errorString(), ` + Error Trace: + Error: map[bool][]int{true:[]int{0, 0, 0,`) + Contains(t, mockT.errorString(), `<... truncated> does not contain map[bool][]int{false:[]int{0, 0, 0,`) +} + +func TestNotSubsetWithSliceTooLongToPrint(t *testing.T) { + t.Parallel() + mockT := new(mockTestingT) + longSlice := make([]int, 1_000_000) + NotSubset(mockT, longSlice, longSlice) + Contains(t, mockT.errorString(), ` + Error Trace: + Error: []int{0, 0, 0,`) + Contains(t, mockT.errorString(), `<... truncated> is a subset of []int{0, 0, 0,`) +} + +func TestNotSubsetWithMapTooLongToPrint(t *testing.T) { + t.Parallel() + mockT := new(mockTestingT) + longSlice := make([]int, 1_000_000) + NotSubset(mockT, map[bool][]int{true: longSlice}, map[bool][]int{true: longSlice}) + Contains(t, mockT.errorString(), ` + Error Trace: + Error: map[bool][]int{true:[]int{0, 0, 0,`) + Contains(t, mockT.errorString(), `<... truncated> is a subset of map[bool][]int{true:[]int{0, 0, 0,`) +} + +func TestSameWithSliceTooLongToPrint(t *testing.T) { + t.Parallel() + mockT := new(mockTestingT) + longSlice := make([]int, 1_000_000) + Same(mockT, &[]int{}, &longSlice) + Contains(t, mockT.errorString(), `&[]int{0, 0, 0,`) +} + +func TestNotSameWithSliceTooLongToPrint(t *testing.T) { + t.Parallel() + mockT := new(mockTestingT) + longSlice := make([]int, 1_000_000) + NotSame(mockT, &longSlice, &longSlice) + Contains(t, mockT.errorString(), `&[]int{0, 0, 0,`) +} + +func TestNilWithSliceTooLongToPrint(t *testing.T) { + t.Parallel() + mockT := new(mockTestingT) + longSlice := make([]int, 1_000_000) + Nil(mockT, &longSlice) + Contains(t, mockT.errorString(), ` + Error Trace: + Error: Expected nil, but got: &[]int{0, 0, 0,`) + Contains(t, mockT.errorString(), `<... truncated>`) +} + +func TestEmptyWithSliceTooLongToPrint(t *testing.T) { + t.Parallel() + mockT := new(mockTestingT) + longSlice := make([]int, 1_000_000) + Empty(mockT, longSlice) + Contains(t, mockT.errorString(), ` + Error Trace: + Error: Should be empty, but was [0 0 0`) + Contains(t, mockT.errorString(), `<... truncated>`) +} + +func TestNotEqualWithSliceTooLongToPrint(t *testing.T) { + t.Parallel() + mockT := new(mockTestingT) + longSlice := make([]int, 1_000_000) + NotEqual(mockT, longSlice, longSlice) + Contains(t, mockT.errorString(), ` + Error Trace: + Error: Should not be: []int{0, 0, 0,`) + Contains(t, mockT.errorString(), `<... truncated>`) +} + +func TestNotEqualValuesWithSliceTooLongToPrint(t *testing.T) { + t.Parallel() + mockT := new(mockTestingT) + longSlice := make([]int, 1_000_000) + NotEqualValues(mockT, longSlice, longSlice) + Contains(t, mockT.errorString(), ` + Error Trace: + Error: Should not be: []int{0, 0, 0,`) + Contains(t, mockT.errorString(), `<... truncated>`) +} + +func TestNoErrorWithErrorTooLongToPrint(t *testing.T) { + t.Parallel() + mockT := new(mockTestingT) + longSlice := make([]int, 1_000_000) + NoError(mockT, fmt.Errorf("long: %v", longSlice)) + Contains(t, mockT.errorString(), ` + Error Trace: + Error: Received unexpected error: + long: [0 0 0`) + Contains(t, mockT.errorString(), `<... truncated>`) +} + +func TestEqualErrorWithErrorTooLongToPrint(t *testing.T) { + t.Parallel() + mockT := new(mockTestingT) + longSlice := make([]int, 1_000_000) + EqualError(mockT, fmt.Errorf("long: %v", longSlice), "EOF") + Contains(t, mockT.errorString(), ` + Error Trace: + Error: Error message not equal: + expected: "EOF" + actual : "long: [0 0 0`) + Contains(t, mockT.errorString(), `<... truncated>`) +} + +func TestErrorContainsWithErrorTooLongToPrint(t *testing.T) { + t.Parallel() + mockT := new(mockTestingT) + longSlice := make([]int, 1_000_000) + ErrorContains(mockT, fmt.Errorf("long: %v", longSlice), "EOF") + Contains(t, mockT.errorString(), ` + Error Trace: + Error: Error "long: [0 0 0`) + Contains(t, mockT.errorString(), `<... truncated> does not contain "EOF"`) +} + +func TestZeroWithSliceTooLongToPrint(t *testing.T) { + t.Parallel() + mockT := new(mockTestingT) + longSlice := make([]int, 1_000_000) + Zero(mockT, longSlice) + Contains(t, mockT.errorString(), ` + Error Trace: + Error: Should be zero, but was [0 0 0`) + Contains(t, mockT.errorString(), `<... truncated>`) +} + +func TestErrorIsWithErrorTooLongToPrint(t *testing.T) { + t.Parallel() + mockT := new(mockTestingT) + longSlice := make([]int, 1_000_000) + ErrorIs(mockT, fmt.Errorf("long: %v", longSlice), fmt.Errorf("also: %v", longSlice)) + Contains(t, mockT.errorString(), ` + Error Trace: + Error: Target error should be in err chain: + expected: "also: [0 0 0`) + Contains(t, mockT.errorString(), `<... truncated> + in chain: "long: [0 0 0`) +} + +func TestNotErrorIsWithErrorTooLongToPrint(t *testing.T) { + t.Parallel() + mockT := new(mockTestingT) + longSlice := make([]int, 1_000_000) + err := fmt.Errorf("long: %v", longSlice) + NotErrorIs(mockT, err, err) + Contains(t, mockT.errorString(), ` + Error Trace: + Error: Target error should not be in err chain: + found: "long: [0 0 0`) + Contains(t, mockT.errorString(), `<... truncated> + in chain: "long: [0 0 0`) +} + +func TestErrorAsWithErrorTooLongToPrint(t *testing.T) { + t.Parallel() + mockT := new(mockTestingT) + longSlice := make([]int, 1_000_000) + var target *customError + ErrorAs(mockT, fmt.Errorf("long: %v", longSlice), &target) + Contains(t, mockT.errorString(), ` + Error Trace: + Error: Should be in error chain: + expected: *assert.customError`) + Contains(t, mockT.errorString(), ` + in chain: "long: [0 0 0`) + Contains(t, mockT.errorString(), "<... truncated>") +} + +func TestNotErrorAsWithErrorTooLongToPrint(t *testing.T) { + t.Parallel() + mockT := new(mockTestingT) + longSlice := make([]int, 1_000_000) + var target *customError + NotErrorAs(mockT, fmt.Errorf("long: %v %w", longSlice, &customError{}), &target) + Contains(t, mockT.errorString(), ` + Error Trace: + Error: Target error should not be in err chain: + found: *assert.customError`) + Contains(t, mockT.errorString(), ` + in chain: "long: [0 0 0`) + Contains(t, mockT.errorString(), "<... truncated>") +} From 28dac5901398e9e2dd5a8dc0f557f9bdc9b78eb0 Mon Sep 17 00:00:00 2001 From: Bracken Dawson Date: Thu, 18 Sep 2025 18:01:34 +0200 Subject: [PATCH 175/178] Don't shadow builtin max --- assert/assertions.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index 58172881b..524fb079a 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -622,9 +622,9 @@ func formatUnequalValues(expected, actual interface{}) (e string, a string) { func truncatingFormat(format string, data interface{}) string { value := fmt.Sprintf(format, data) // Give us space for two truncated objects and the surrounding sentence. - max := bufio.MaxScanTokenSize/2 - 100 - if len(value) > max { - value = value[0:max] + "<... truncated>" + maxMessageSize := bufio.MaxScanTokenSize/2 - 100 + if len(value) > maxMessageSize { + value = value[0:maxMessageSize] + "<... truncated>" } return value } From d5be41440e14cc4e83079992c6dce6f886114550 Mon Sep 17 00:00:00 2001 From: Bracken Dawson Date: Thu, 18 Sep 2025 18:02:00 +0200 Subject: [PATCH 176/178] Don't change the format of failure messages when fixing 1525 --- assert/assertions.go | 4 ++-- assert/assertions_test.go | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index 524fb079a..185d3dca0 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -1108,7 +1108,7 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) } } - return Fail(t, fmt.Sprintf("%s is a subset of %s", truncatingFormat("%#v", subset), truncatingFormat("%#v", list)), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s is a subset of %s", truncatingFormat("%q", subset), truncatingFormat("%q", list)), msgAndArgs...) } subsetList := reflect.ValueOf(subset) @@ -1130,7 +1130,7 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) } } - return Fail(t, fmt.Sprintf("%s is a subset of %s", truncatingFormat("%#v", subset), truncatingFormat("%#v", list)), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s is a subset of %s", truncatingFormat("%q", subset), truncatingFormat("%q", list)), msgAndArgs...) } // ElementsMatch asserts that the specified listA(array, slice...) is equal to specified diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 02bef780b..4975f5e41 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -1202,10 +1202,10 @@ func TestSubsetNotSubset(t *testing.T) { }{ // cases that are expected to contain {[]int{1, 2, 3}, nil, true, `nil is the empty set which is a subset of every set`}, - {[]int{1, 2, 3}, []int{}, true, `[]int{} is a subset of []int{1, 2, 3}`}, - {[]int{1, 2, 3}, []int{1, 2}, true, `[]int{1, 2} is a subset of []int{1, 2, 3}`}, - {[]int{1, 2, 3}, []int{1, 2, 3}, true, `[]int{1, 2, 3} is a subset of []int{1, 2, 3}`}, - {[]string{"hello", "world"}, []string{"hello"}, true, `[]string{"hello"} is a subset of []string{"hello", "world"}`}, + {[]int{1, 2, 3}, []int{}, true, `[] is a subset of ['\x01' '\x02' '\x03']`}, + {[]int{1, 2, 3}, []int{1, 2}, true, `['\x01' '\x02'] is a subset of ['\x01' '\x02' '\x03']`}, + {[]int{1, 2, 3}, []int{1, 2, 3}, true, `['\x01' '\x02' '\x03'] is a subset of ['\x01' '\x02' '\x03']`}, + {[]string{"hello", "world"}, []string{"hello"}, true, `["hello"] is a subset of ["hello" "world"]`}, {map[string]string{ "a": "x", "c": "z", @@ -1213,8 +1213,8 @@ func TestSubsetNotSubset(t *testing.T) { }, map[string]string{ "a": "x", "b": "y", - }, true, `map[string]string{"a":"x", "b":"y"} is a subset of map[string]string{"a":"x", "b":"y", "c":"z"}`}, - {[]string{"a", "b", "c"}, map[string]int{"a": 1, "c": 3}, true, `map[string]int{"a":1, "c":3} is a subset of []string{"a", "b", "c"}`}, + }, true, `map["a":"x" "b":"y"] is a subset of map["a":"x" "b":"y" "c":"z"]`}, + {[]string{"a", "b", "c"}, map[string]int{"a": 1, "c": 3}, true, `map["a":'\x01' "c":'\x03'] is a subset of ["a" "b" "c"]`}, // cases that are expected not to contain {[]string{"hello", "world"}, []string{"hello", "testify"}, false, `[]string{"hello", "world"} does not contain "testify"`}, @@ -4032,19 +4032,19 @@ func TestNotSubsetWithSliceTooLongToPrint(t *testing.T) { NotSubset(mockT, longSlice, longSlice) Contains(t, mockT.errorString(), ` Error Trace: - Error: []int{0, 0, 0,`) - Contains(t, mockT.errorString(), `<... truncated> is a subset of []int{0, 0, 0,`) + Error: ['\x00' '\x00' '\x00'`) + Contains(t, mockT.errorString(), `<... truncated> is a subset of ['\x00' '\x00' '\x00'`) } func TestNotSubsetWithMapTooLongToPrint(t *testing.T) { t.Parallel() mockT := new(mockTestingT) longSlice := make([]int, 1_000_000) - NotSubset(mockT, map[bool][]int{true: longSlice}, map[bool][]int{true: longSlice}) + NotSubset(mockT, map[int][]int{1: longSlice}, map[int][]int{1: longSlice}) Contains(t, mockT.errorString(), ` Error Trace: - Error: map[bool][]int{true:[]int{0, 0, 0,`) - Contains(t, mockT.errorString(), `<... truncated> is a subset of map[bool][]int{true:[]int{0, 0, 0,`) + Error: map['\x01':['\x00' '\x00' '\x00'`) + Contains(t, mockT.errorString(), `<... truncated> is a subset of map['\x01':['\x00' '\x00' '\x00'`) } func TestSameWithSliceTooLongToPrint(t *testing.T) { From 5a4a1cc8ab5446bbb7213567f7bb89f338a9c582 Mon Sep 17 00:00:00 2001 From: Bracken Dawson Date: Thu, 18 Sep 2025 18:27:09 +0200 Subject: [PATCH 177/178] Use links for previously invalid inline code blocks These were previously inline code blocks (which go does not support) containing reference to a single symbol. Link to the symbol instead. --- assert/doc.go | 2 +- require/doc.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/assert/doc.go b/assert/doc.go index 0fb5c6137..c111589c7 100644 --- a/assert/doc.go +++ b/assert/doc.go @@ -41,7 +41,7 @@ // # Assertions // // Assertions allow you to easily write test code, and are global funcs in the assert package. -// All assertion functions take, as the first argument, the *testing.T object provided by the +// All assertion functions take, as the first argument, the [*testing.T] object provided by the // testing framework. This allows the assertion funcs to write the failings and other details to // the correct place. // diff --git a/require/doc.go b/require/doc.go index 7e88f07cd..ee84cc479 100644 --- a/require/doc.go +++ b/require/doc.go @@ -22,7 +22,7 @@ // # Assertions // // The require package have same global functions as in the assert package, -// but instead of returning a boolean result they call "t.FailNow()". +// but instead of returning a boolean result they call [testing.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. // From d24e6b3da81cd671a3ab30742e10aee77e931f97 Mon Sep 17 00:00:00 2001 From: {nikitaratnikov} <{nikita.ratnikov@wallester.com}> Date: Mon, 22 Sep 2025 14:40:24 +0300 Subject: [PATCH 178/178] Fix gofmt script --- .ci.gofmt.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.ci.gofmt.sh b/.ci.gofmt.sh index 1ac21ef10..4c98e8d8e 100755 --- a/.ci.gofmt.sh +++ b/.ci.gofmt.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash -if [ -n "$(gofmt -l .)" ]; then +if [ -n "$(go fmt ./...)" ]; then echo "Go code is not formatted:" - gofmt -d . + go fmt ./... exit 1 fi