all repos

rss-tools @ master

get rss feed from sources that(i need and) dont provide one

rss-tools/vendor/olexsmir.xyz/x/is/is.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
we're vendoring now, 7 days ago
1
package is
2
3
import (
4
	"bytes"
5
	"errors"
6
	"reflect"
7
	"strings"
8
	"testing"
9
)
10
11
// Equal asserts that two values are equal.
12
func Equal[T any](tb testing.TB, expected, got T) {
13
	tb.Helper()
14
15
	if !areEqual(expected, got) {
16
		tb.Errorf("expected: %#v, got: %#v", expected, got)
17
	}
18
}
19
20
// NotEqual asserts that two values are not equal.
21
func NotEqual[T any](tb testing.TB, expected, got T) {
22
	tb.Helper()
23
24
	if areEqual(expected, got) {
25
		tb.Errorf("expected values to be different, but both are: %#v", got)
26
	}
27
}
28
29
// Err asserts error conditions with flexible expected values:
30
//   - nil: asserts no error occurred
31
//   - string: asserts error message contains the string
32
//   - error: asserts errors.Is matches
33
//   - reflect.Type: asserts errors.As succeeds
34
func Err(tb testing.TB, got error, expected any) {
35
	tb.Helper()
36
37
	if expected != nil && got == nil {
38
		tb.Error("got: <nil>, expected: error")
39
		return
40
	}
41
42
	switch e := expected.(type) {
43
	case nil:
44
		if got != nil {
45
			tb.Fatalf("unexpected error: %v", got)
46
		}
47
48
	case string:
49
		if !strings.Contains(got.Error(), e) {
50
			tb.Fatalf("expected: %q, got: %q", got.Error(), e)
51
		}
52
53
	case error:
54
		if !errors.Is(got, e) {
55
			tb.Fatalf("expected: %T(%v), got: %T(%v)", got, got, e, e)
56
		}
57
58
	case reflect.Type:
59
		target := reflect.New(e).Interface()
60
		if !errors.As(got, target) {
61
			tb.Fatalf("expected: %s, got: %T", e, got)
62
		}
63
64
	default:
65
		tb.Fatalf("unexpected type: %T", expected)
66
	}
67
}
68
69
type equaler[T any] interface{ Equal(T) bool }
70
71
func areEqual[T any](a, b T) bool {
72
	if isNil(a) && isNil(b) {
73
		return true
74
	}
75
76
	// some types provide .Equal(like time.Time, net.IP)
77
	if eq, ok := any(a).(equaler[T]); ok {
78
		return eq.Equal(b)
79
	}
80
	if aBytes, ok := any(a).([]byte); ok {
81
		bBytes := any(b).([]byte)
82
		return bytes.Equal(aBytes, bBytes)
83
	}
84
85
	return reflect.DeepEqual(a, b)
86
}
87
88
func isNil(v any) bool {
89
	if v == nil {
90
		return true
91
	}
92
93
	// non-nil interface can hold a nil value, check the underlying value.
94
	rv := reflect.ValueOf(v)
95
	switch rv.Kind() {
96
	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Pointer, reflect.Slice, reflect.UnsafePointer:
97
		return rv.IsNil()
98
	default:
99
		return false
100
	}
101
}