2025-11-08 09:37:30 +03:00

199 lines
3.8 KiB
Go

//go:build !release
package debug
import (
"fmt"
"reflect"
)
func Assert(expression bool, message ...string) {
if !expression {
var msg string
if len(message) > 0 {
msg = "False expression: " + message[0]
} else {
msg = "False expression."
}
Fail(msg)
}
}
func isNil[T any](value T) bool {
v := reflect.ValueOf(value)
switch v.Kind() {
case reflect.Pointer, reflect.UnsafePointer, reflect.Interface, reflect.Slice, reflect.Map, reflect.Chan, reflect.Func:
{
return v.IsNil()
}
default:
{
return false
}
}
}
func AssertNil(value any, message ...string) {
if value != nil && !isNil(value) {
var msg string
if len(message) > 0 {
msg = "Nil expression: " + message[0]
} else {
msg = "Nil expression."
}
Fail(msg)
}
}
func AssertEqual(a fmt.Stringer, b fmt.Stringer, message ...string) {
if a != b {
var msg string
if len(message) == 0 {
msg = ""
} else {
msg = message[0]
}
Fail(fmt.Sprintf("Expected %s == %s. %s", a.String(), b.String(), msg))
}
}
func AssertLessThan(a int, b int, message ...string) {
if a >= b {
var msg string
if len(message) == 0 {
msg = ""
} else {
msg = message[0]
}
Fail(fmt.Sprintf("Expected %d < %d. %s", a, b, msg))
}
}
func AssertLessThanOrEqual(a int, b int, message ...string) {
if a > b {
var msg string
if len(message) == 0 {
msg = ""
} else {
msg = message[0]
}
Fail(fmt.Sprintf("Expected %d <= %d. %s", a, b, msg))
}
}
func AssertGreaterThan(a int, b int, message ...string) {
if a <= b {
var msg string
if len(message) == 0 {
msg = ""
} else {
msg = message[0]
}
Fail(fmt.Sprintf("Expected %d > %d. %s", a, b, msg))
}
}
func AssertGreaterThanOrEqual(a int, b int, message ...string) {
if a < b {
var msg string
if len(message) == 0 {
msg = ""
} else {
msg = message[0]
}
Fail(fmt.Sprintf("Expected %d >= %d. %s", a, b, msg))
}
}
func AssertIsDefined(value any, message ...string) {
if value == nil || isNil(value) { // handle all `nil` interfaces
var msg string
if len(message) == 0 {
msg = ""
} else {
msg = message[0]
}
Fail(msg)
}
}
func CheckDefined[T any](value T, message ...string) T {
AssertIsDefined(value, message...)
return value
}
func AssertEachIsDefined[TElem any](value []TElem, message ...string) {
for _, elem := range value {
AssertIsDefined(elem, message...)
}
}
func CheckEachIsDefined[TElem any](value []TElem, message ...string) []TElem {
AssertEachIsDefined(value, message...)
return value
}
var unexpectedNode []string = []string{"Unexpected node."}
func AssertEachNode[TElem any](nodes []TElem, test func(elem TElem) bool, message ...string) {
if len(message) == 0 {
message = unexpectedNode
}
for _, elem := range nodes {
AssertNode(elem, test, message...)
}
}
func AssertNode[TElem any](node TElem, test func(elem TElem) bool, message ...string) {
if len(message) == 0 {
message = unexpectedNode
}
AssertIsDefined(node, message...)
if test != nil {
Assert(test(node), message...)
}
}
func AssertNotNode[TElem any](node TElem, test func(elem TElem) bool, message ...string) {
if isNil(node) {
return
}
if test == nil {
return
}
if len(message) == 0 {
message = unexpectedNode
}
Assert(!test(node), message...)
}
func AssertOptionalNode[TElem any](node TElem, test func(elem TElem) bool, message ...string) {
if isNil(node) {
return
}
if test == nil {
return
}
if len(message) == 0 {
message = unexpectedNode
}
Assert(test(node), message...)
}
func AssertOptionalToken[TElem interface{ KindValue() int16 }](node TElem, kind int16, message ...string) {
if isNil(node) {
return
}
if len(message) == 0 {
message = unexpectedNode
}
Assert(node.KindValue() == kind, message...)
}
func AssertMissingNode[TElem any](node TElem, message ...string) {
if len(message) == 0 {
message = unexpectedNode
}
Assert(isNil(node), message...)
}