{"id":22692205,"url":"https://github.com/nikoksr/assert-go","last_synced_at":"2025-04-12T06:37:15.882Z","repository":{"id":266879649,"uuid":"899636091","full_name":"nikoksr/assert-go","owner":"nikoksr","description":"Tiny (~100 LoC) Go assertion library focused on crystal-clear failure messages and thoughtful source context.","archived":false,"fork":false,"pushed_at":"2025-02-15T11:41:21.000Z","size":47,"stargazers_count":15,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-26T02:02:11.236Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nikoksr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-12-06T17:18:44.000Z","updated_at":"2025-03-11T04:26:46.000Z","dependencies_parsed_at":"2025-02-04T17:49:12.236Z","dependency_job_id":"4a43ecd3-6cda-4556-9151-bf6346d1a24f","html_url":"https://github.com/nikoksr/assert-go","commit_stats":null,"previous_names":["nikoksr/assert-go"],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikoksr%2Fassert-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikoksr%2Fassert-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikoksr%2Fassert-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikoksr%2Fassert-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nikoksr","download_url":"https://codeload.github.com/nikoksr/assert-go/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248530563,"owners_count":21119590,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-10T01:14:55.921Z","updated_at":"2025-04-12T06:37:15.854Z","avatar_url":"https://github.com/nikoksr.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u0026nbsp;\n\u003ch1\u003eassert-go\u003c/h1\u003e\n\u003cp\u003e\u003ci\u003eTiny (~100 LoC) Go assertion library focused on crystal-clear failure messages and thoughtful source context.\u003c/i\u003e\u003c/p\u003e\n\n\u0026nbsp;\n\n[![go.dev reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go\u0026logoColor=white\u0026style=flat)](https://pkg.go.dev/github.com/nikoksr/assert-go)\n\u003c/div\u003e\n\n\u0026nbsp;\n\n## About\n\n- 🔍 Crystal-clear failure messages with contextual values\n- 📚 Rich source context showing the exact failure location\n- 🛠 Tiny and free of dependencies (~100 lines of Go)\n- 💡 Elegant, idiomatic Go API\n- 🎯 Two-tier assertion system with build tag support\n- ⚙️ Configurable source context behavior\n\nInspired by [Tiger Style](https://github.com/tigerbeetle/tigerbeetle/blob/main/docs/TIGER_STYLE.md#safety).\n\n## Installation\n\n```bash\ngo get github.com/nikoksr/assert-go\n```\n\n## Usage\n\n### Basic Usage\n\n```go\nimport \"github.com/nikoksr/assert-go\"\n\nfunc PaymentProcessing() {\n    payment := processPayment(PaymentRequest{\n        Amount:      99.99,\n        CustomerID: \"cust_123\",\n        Currency:   \"USD\",\n    })\n    \n    // Assert payment was processed successfully\n    assert.Assert(payment.Status == \"completed\", \"payment should be completed\",\n        // Optionally, add context to the panic\n        \"payment_id\", payment.ID,\n        \"status\", payment.Status,\n        \"amount\", payment.Amount,\n        \"error\", payment.Error,\n        \"timestamp\", payment.ProcessedAt,\n    )\n}\n```\n\nOn failure, you get:\n\n```\nAssertion failed at payment_test.go:43\nMessage: payment should be completed\n\nRelevant values:\n  [payment_id]: \"pmt_789\"\n  [status]: \"failed\"\n  [amount]: 99.99\n  [error]: \"insufficient_funds\"\n  [timestamp]: \"2024-12-06T15:04:05Z\"\n\nSource context:\n   37 |     payment := processPayment(PaymentRequest{\n   38 |         Amount:      99.99,\n   39 |         CustomerID: \"cust_123\",\n   40 |         Currency:   \"USD\",\n   41 |     })\n   42 |\n→  43 |     assert.Assert(payment.Status == \"completed\", \"payment should be completed\",\n   44 |         \"payment_id\", payment.ID,\n   45 |         \"status\", payment.Status,\n   46 |         \"amount\", payment.Amount,\n   47 |         \"error\", payment.Error,\n   48 |         \"timestamp\", payment.ProcessedAt,\n   49 |     )\n\ngoroutine 1 [running]:\ngithub.com/nikoksr/assert-go.PaymentProcessing(0xc00011c000)\n    /app/payment.go:43 +0x1b4\n# ... regular Go stacktrace continues\n```\n\n### Two-Tier Assertion System\n\nThe library provides two types of assertions:\n\n1. `Assert()` - Always active, meant for critical checks that should run in all environments\n2. `Debug()` - Development-time assertions that can be disabled in production\n\n#### Using Debug Assertions\n\nDebug assertions are disabled by default. To enable them, use the `assertdebug` build tag:\n\n```bash\ngo test -tags assertdebug ./...\ngo run -tags assertdebug main.go\n```\n\nExample usage:\n\n```go\n// This will only be evaluated when built with -tags assertdebug\nassert.Debug(len(items) \u003c 1000, \"items list too large\",\n    \"current_length\", len(items),\n    \"max_allowed\", 1000,\n)\n\n// This will always be evaluated regardless of build tags\nassert.Assert(response != nil, \"HTTP response cannot be nil\",\n    \"status_code\", response.StatusCode,\n)\n```\n\n### Configuration\n\nYou can configure the assertion behavior:\n\n```go\n// Configure assertion behavior\nassert.SetConfig(assert.Config{\n    // Enable/disable source context in error messages\n    IncludeSource: true,\n    // Number of context lines to show before and after the failing line\n    ContextLines:  5,\n})\n```\n\n## A Personal Perspective on Assertions in Go\n\nI initially shared the common view that assertions don't align well with Go's philosophy of explicit error handling. Reading [TigerStyle's perspective on assertions](https://github.com/tigerbeetle/tigerbeetle/blob/main/docs/TIGER_STYLE.md#safety) made me reconsider this stance and experiment with them in my own code.\n\nI've found that assertions serve a distinct and valuable purpose alongside traditional error handling. While I handle operational failures - like network issues or invalid user input - through error returns, I now use assertions to catch programmer mistakes that should never occur in correct code. I used to write sanity checks that would return errors, wondering why I'm burdening users with checks for conditions that should be impossible to be false anyway given my code's structure – like a logger that I initialized and passed down myself just three function calls earlier. It feels weird to check for nil because I know that I just initialized this logger, it feels weird to return these types of errors to users, but at the same time, I always had this urge of checking for the \"impossible\". These aren't cases where graceful error handling makes sense; they're cases where continuing execution would only mask a fundamental bug in my code.\n\nI'm selective about where I use assertions. They belong in application code where I can make strong guarantees about internal state and invariants, particularly during system initialization. I don't use them in libraries or for validating application input - that's firmly error handling territory. But when I know something must be true for my program to be correct, assertions help me catch bugs early and prevent corrupted state from silently spreading.\n\nWhat started as an experiment has become an essential part of how I write Go. At this point, my own experience has convinced me that thoughtful use of assertions makes my code more reliable and bugs easier to diagnose.\n\n## Philosophy\n\n- **Minimal**: Single-purpose library that does one thing well\n- **Context over complexity**: Rich debugging information without complex APIs\n- **Clear failures**: Source context shows exactly where and why things went wrong\n- **Idiomatic Go**: Feels natural in your Go codebase\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnikoksr%2Fassert-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnikoksr%2Fassert-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnikoksr%2Fassert-go/lists"}