{"id":16578226,"url":"https://github.com/dscottboggs/attest","last_synced_at":"2026-05-28T21:31:03.598Z","repository":{"id":52929557,"uuid":"139389263","full_name":"dscottboggs/attest","owner":"dscottboggs","description":"A small library to make go tests more readable.","archived":false,"fork":false,"pushed_at":"2021-04-13T15:08:05.000Z","size":59,"stargazers_count":0,"open_issues_count":3,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-05T21:45:07.217Z","etag":null,"topics":["assertions","conciseness","go","golang-library","readability","testing"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dscottboggs.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}},"created_at":"2018-07-02T04:06:49.000Z","updated_at":"2021-04-13T15:05:17.000Z","dependencies_parsed_at":"2022-08-24T13:51:14.105Z","dependency_job_id":null,"html_url":"https://github.com/dscottboggs/attest","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/dscottboggs/attest","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dscottboggs%2Fattest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dscottboggs%2Fattest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dscottboggs%2Fattest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dscottboggs%2Fattest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dscottboggs","download_url":"https://codeload.github.com/dscottboggs/attest/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dscottboggs%2Fattest/sbom","scorecard":{"id":357581,"data":{"date":"2025-08-11","repo":{"name":"github.com/dscottboggs/attest","commit":"fbad32346af4974b7fc3bf15affb1f7dd05db017"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.8,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":0,"reason":"Found 0/23 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/go.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/dscottboggs/attest/go.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/dscottboggs/attest/go.yml/master?enable=pin","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Mozilla Public License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 12 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-18T09:59:38.046Z","repository_id":52929557,"created_at":"2025-08-18T09:59:38.046Z","updated_at":"2025-08-18T09:59:38.046Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33627934,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-28T02:00:06.440Z","response_time":99,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["assertions","conciseness","go","golang-library","readability","testing"],"created_at":"2024-10-11T22:13:31.729Z","updated_at":"2026-05-28T21:31:03.580Z","avatar_url":"https://github.com/dscottboggs.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# attest\n\nAn ever-growing list of assertions that make Go tests more readable and concise.\n\n![Build and Test](https://github.com/dscottboggs/attest/actions/workflows/go.yml/badge.svg)\n\n## Installation:\n\nInstall Go, from your operating system's package manager or from the [Golang website](https://golang.org/dl/).\n\nOpen a terminal/console window and run\n\n`go get github.com/dscottboggs/attest`\n\ndone!\n\n## Usage:\n\n```go\n  package main\n\nimport (\n  \"testing\"\n\n  \"github.com/dscottboggs/attest\"\n)\n\nfunc TestExample(t *testing.T) {\n  test := attest.Test{t}\n  test.Attest(fmt.Sprintf(\"%T\", \"that something is true\") == \"string\", \"or %s a message\", \"log\")\n  var val1, val2 int\n  test.Equals(val1, val2)\n  val2 = 1\n  test.Greater(val2, val1)\n}\n```\n\nThe implicit tests I use to perform testing on this package also serves as a great\nset of examples of its use. Unfortunately due to limitations in the Go testing\nmethods, it's not really possible to test for failure cases, as they would fail\nthe test. Recommendations are welcome for additional testing methodologies.\n\n### Contributing\n\nHave a clever function that makes testing easier in Go? Submit a pull request or open an issue and let's discuss it!\n\n## About\n\nAttest is a very lightweight testing library aimed at improving the\nintuitiveness and aesthetics of the go standard testing library, as well as\nreducing the amount of keystrokes per test, hence improving developer\nefficiency by a marginal amount with very minimal overhead and risk. Any\ngiven testing.T function can create an attest.Test object, whose methods\ncan then perform tests.\n\nA brief example:\n\n```go\npackage main\n\nimport (\n  \"testing\"\n\n  \"github.com/dscottboggs/attest\"\n)\n\nfunc TestExample(t *testing.T) {\n  test := attest.NewTest(t)\n  test.Attest(fmt.Sprintf(\"%T\", \"that something is true\") == \"string\", \"or %s a message\", \"log\")\n  const unchanging = 0\n  var variable int\n  test.Equals(unchanging, variable)\n  variable = 1\n  test.Greater(variable, unchanging)\n}\n```\n\nThat same test function with the default testing library might be written\nlike:\n\n```go\nfunc TestExample(t *testing.T) {\n  if fmt.Sprintf(\"%T\", \"something is true\") != \"string\" {\n    t.Errorf(\"or %s a message\", \"log\")\n  }\n  const unchanging = 0\n  var variable int\n  if fmt.Sprintf(\"%T\", unchanging) != fmt.Sprintf(\"%T\", variable) {\n    t.Errorf(\"Value 1 had a different type (%T) than value 2 (%T)\", unchanging, variable)\n  }\n  if unchanging != variable {\n    t.Errorf(\"Value 1 (%d) didn't equal value 2 (%d).\")\n  }\n  variable = 1\n  if fmt.Sprintf(\"%T\", unchanging) != fmt.Sprintf(\"%T\", variable) {\n    t.Errorf(\"Value 1 had a different type (%T) than value 2 (%T)\", unchanging, variable)\n  }\n  if variable \u003c= unchanging {\n    t.Errorf(\"Value 1 was less than or equal to value 2\")\n  }\n}\n```\n\nAs you can see, this provides minimal benefit besides a reduced number of\nkeystrokes when _writing_, but when reading back, the attest way is much\neasier to understand. Of course, you can mix-and-match:\n\n```go\nfunc TestExample(t *testing.T){\n  test := attest.New(t)\n  if fmt.Sprintf(\"%T\", \"something is true\") != \"string\" {\n    test.Errorf(\"or %s a message\", \"log\")\n  }\n  const unchanging = 0\n  var variable int\n  test.Equals(unchanging, variable)\n  variable = 1\n  test.GreaterThan(unchanging, variable)\n}\n```\n\n### Logging a custom message\n\nAll tests allow for an optional (or in the case of the few strictly boolean\ntests, required) message string and formatters to be forwarded to\nfmt.Sprintf()\n\n# Available test functions\n\nThe following tests are available:\n\n- **Attest** and **That**: the first argument must equal the boolean value true.\n- **AttestNot** and **Not**: the first argument must equal the boolean value false.\n- **AttestOrDo**: takes a callback function and arguments to forward to the callback in case of a failure\n- **Nil** and **NotNil**: the first argument must be nil or not nil, respectively.\n- **Equals** and **NotEqual**: the second argument must equal (or not equal, respectively) the first argument. Both require that the arguments be the same type\n- **Compares**, **SimilarTo**, **DoesNotCompare**, and **NotSimilarTo**: like Equals and NotEquals but the types don't have to be the same.\n- **GreaterThan** and **LessThan**: like Equals, but checks for the second value to be greater or less than the first argument.\n- **Positive** and **Negative**: are shortcuts for test.LessThan(0, ...) and test.GreaterThan(0, ...)\n- **TypeIs** and **TypeIsNot**: check the type of a value\n- **Matches** and **DoesNotMatch**: Check if the value matches a given regular expression.\n\nIn addition there are the following ways of handling error types and panics:\n\n- **Handle**: Log and fail if the first argument is a non-nil error.\n- **HandleMultiple**: Log and fail if any of the arguments to this are non-nil errors. Does not accept a callback or message.\n- **AttestPanics** and **AttestNoPanic**: ensure the given function panics or doesn't.\n- **StopIf**: Log and fail a fatal non-nil error\n- **EatError**: Logs and fails an error message if the second argument is a non-nil error, and returns the first argument. For handling function calls that return a value and an error in a single line.\n- **FailOnError**: Like StopIf combined with EatError -- stops the test immediately if there is an error, otherwise returns the value.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdscottboggs%2Fattest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdscottboggs%2Fattest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdscottboggs%2Fattest/lists"}