Skip to content

negrel/assert

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

gopher illustration

PkgGoDev Go Report Card

assert - Zero cost debug assertions.

This package provides zero cost debug assertions to your Go programs. It is based on the excellent github.com/stretchr/testify/assert package and provide the same API (minus t testing.T parameter).

Why?

This is a complete rewrite of debuggo that aims to be up to date and more maintainable.

It aims to provide the same API as github.com/stretchr/testify/assert.

  • Prints friendly, easy to read failure descriptions
  • Allows for very readable code
  • Optionally annotate each assertion with a message
  • No performance impact on production build (see benchmarks)

How does it works?

Read my blog post about to understand how assert works and why it is designed that way.

Getting started

Here is our example program:

package main

import "github.com/negrel/assert"

func safeIndex(slice []string, index int) string {
	// Ensure index is not out of bounds.
	assert.GreaterOrEqual(index, 0, "negative index not allowed")
	assert.Lessf(index, len(slice), "index out of bounds (slice: %v)", slice)

	return slice[index]
}

func main() {
	days := []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}
	println(safeIndex(days, 8))
}

A simple go run . will produce the following error:

panic: runtime error: index out of range [8] with length 7

goroutine 1 [running]:
main.safeIndex(...)
        /home/anegrel/code/go/assert/example/main.go:10
main.main()
        /home/anegrel/code/go/assert/example/main.go:15 +0xd6
exit status 2

Now, if you enable assertions with a compile time flags, go run -tags assert ., you will get something similar to:

panic:
        Error Trace:    /home/anegrel/code/go/assert/example/main.go:8
                                                /home/anegrel/code/go/assert/example/main.go:15
                                                /nix/store/dwmb0qcai52d0zkgpm6f5ifx2a8yvsdg-go-1.21.3/share/go/src/runtime/proc.go:267
                                                /nix/store/dwmb0qcai52d0zkgpm6f5ifx2a8yvsdg-go-1.21.3/share/go/src/runtime/asm_amd64.s:1650
        Error:          "8" is not less than "7"
        Messages:       index out of bounds (slice: [Monday Tuesday Wednesday Thursday Friday Saturday Sunday])


goroutine 1 [running]:
github.com/negrel/assert.Fail({0xc0001e2168, 0x18}, {0xc0001be240, 0x2, 0x2})
        /home/anegrel/code/go/assert/assertions.go:331 +0x168
github.com/negrel/assert.compareTwoValues({0x53eb00, 0x695cc0}, {0x53eb00, 0x695cb8}, {0xc0001f5e88, 0x1, 0x40e285?}, {0x57307c, 0x1a}, {0xc0001be240, ...})
        /home/anegrel/code/go/assert/assertion_compare.go:425 +0x2af
github.com/negrel/assert.Less(...)
        /home/anegrel/code/go/assert/assertion_compare.go:380
github.com/negrel/assert.Lessf(...)
        /home/anegrel/code/go/assert/assertion_format.go:355
main.safeIndex({0xc0001bdea0?, 0x7, 0x7}, 0x8)
        /home/anegrel/code/go/assert/example/main.go:8 +0x234
main.main()
        /home/anegrel/code/go/assert/example/main.go:15 +0xb4
exit status 2

That's the same output as testify/assert output except that we have a stacktrace because this is a panic.

Benchmarks

As we've seen previously, assertions are hidden behind a compilation flag. If the flag is absent, all assertions functions will be empty/noop function that the compiler will optimize.

WITH -tags assert:

goos: linux
goarch: amd64
pkg: github.com/negrel/assert/tests
cpu: Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz
BenchmarkSliceIndexWithoutBoundCheckAssertions
BenchmarkSliceIndexWithoutBoundCheckAssertions-8        728439501                1.407 ns/op
BenchmarkSliceIndexWithBoundCheckAssertions
BenchmarkSliceIndexWithBoundCheckAssertions-8           27423670                40.80 ns/op
PASS
ok      github.com/negrel/assert/tests  3.338s

WITHOUT -tags assert:

goos: linux
goarch: amd64
pkg: github.com/negrel/assert/tests
cpu: Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz
BenchmarkSliceIndexWithoutBoundCheckAssertions
BenchmarkSliceIndexWithoutBoundCheckAssertions-8        772181695                1.399 ns/op
BenchmarkSliceIndexWithBoundCheckAssertions
BenchmarkSliceIndexWithBoundCheckAssertions-8           802181890                1.412 ns/op
PASS
ok      github.com/negrel/assert/tests  2.531s

However, keep in mind that assert may slightly increase binary size (~100 KiB) as it imports net/http and reflect.

Contributing

If you want to contribute to assert to add a feature or improve the code contact me at negrel.dev@protonmail.com, open an issue or make a pull request.

🌠 Show your support

Please give a ⭐ if this project helped you!

buy me a coffee

📜 License

MIT © Alexandre Negrel