-
Notifications
You must be signed in to change notification settings - Fork 17
/
td_all.go
95 lines (86 loc) · 2.57 KB
/
td_all.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// Copyright (c) 2018, Maxime Soulé
// All rights reserved.
//
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree.
package td
import (
"fmt"
"reflect"
"github.com/maxatome/go-testdeep/internal/ctxerr"
)
type tdAll struct {
tdList
}
var _ TestDeep = &tdAll{}
// summary(All): all expected values have to match
// input(All): all
// All operator compares data against several expected values. During
// a match, all of them have to match to succeed. Consider it
// as a "AND" logical operator.
//
// td.Cmp(t, "foobar", td.All(
// td.Len(6),
// td.HasPrefix("fo"),
// td.HasSuffix("ar"),
// )) // succeeds
//
// Note Flatten function can be used to group or reuse some values or
// operators and so avoid boring and inefficient copies:
//
// stringOps := td.Flatten([]td.TestDeep{td.HasPrefix("fo"), td.HasSuffix("ar")})
// td.Cmp(t, "foobar", td.All(
// td.Len(6),
// stringOps,
// )) // succeeds
//
// One can do the same with All operator itself:
//
// stringOps := td.All(td.HasPrefix("fo"), td.HasSuffix("ar"))
// td.Cmp(t, "foobar", td.All(
// td.Len(6),
// stringOps,
// )) // succeeds
//
// but if an error occurs in the nested All, the report is a bit more
// complex to read due to the nested level. Flatten does not create a
// new level, its slice is just flattened in the All parameters.
//
// TypeBehind method can return a non-nil reflect.Type if all items
// known non-interface types are equal, or if only interface types
// are found (mostly issued from Isa()) and they are equal.
func All(expectedValues ...interface{}) TestDeep {
return &tdAll{
tdList: newList(expectedValues...),
}
}
func (a *tdAll) Match(ctx ctxerr.Context, got reflect.Value) (err *ctxerr.Error) {
var origErr *ctxerr.Error
for idx, item := range a.items {
// Use deepValueEqualFinal here instead of deepValueEqual as we
// want to know whether an error occurred or not, we do not want
// to accumulate it silently
origErr = deepValueEqualFinal(
ctx.ResetErrors().
AddCustomLevel(fmt.Sprintf("<All#%d/%d>", idx+1, len(a.items))),
got, item)
if origErr != nil {
if ctx.BooleanError {
return ctxerr.BooleanError
}
err := &ctxerr.Error{
Message: fmt.Sprintf("compared (part %d of %d)", idx+1, len(a.items)),
Got: got,
Expected: item,
}
if item.IsValid() && item.Type().Implements(testDeeper) {
err.Origin = origErr
}
return ctx.CollectError(err)
}
}
return nil
}
func (a *tdAll) TypeBehind() reflect.Type {
return a.uniqTypeBehind()
}