{"id":36769407,"url":"https://github.com/nickwells/testhelper.mod","last_synced_at":"2026-01-12T13:03:33.051Z","repository":{"id":57492049,"uuid":"164365311","full_name":"nickwells/testhelper.mod","owner":"nickwells","description":"Some useful functions to simplify and improve testing","archived":false,"fork":false,"pushed_at":"2025-12-13T09:51:50.000Z","size":145,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-15T00:12:50.684Z","etag":null,"topics":["go","go-package","go-testing","golang","golang-package"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nickwells.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2019-01-07T02:03:38.000Z","updated_at":"2025-12-13T09:51:53.000Z","dependencies_parsed_at":"2025-03-30T00:21:01.036Z","dependency_job_id":"df17f7b0-784f-4985-a676-eb7d4f95c299","html_url":"https://github.com/nickwells/testhelper.mod","commit_stats":null,"previous_names":[],"tags_count":54,"template":false,"template_full_name":null,"purl":"pkg:github/nickwells/testhelper.mod","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickwells%2Ftesthelper.mod","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickwells%2Ftesthelper.mod/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickwells%2Ftesthelper.mod/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickwells%2Ftesthelper.mod/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nickwells","download_url":"https://codeload.github.com/nickwells/testhelper.mod/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickwells%2Ftesthelper.mod/sbom","scorecard":{"id":685646,"data":{"date":"2025-08-11","repo":{"name":"github.com/nickwells/testhelper.mod","commit":"2fc69c6b12ee7c4f18ad368fb1f807f8db9e94ad"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.7,"checks":[{"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":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"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":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"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":"Maintained","score":5,"reason":"6 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 5","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 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":"Dangerous-Workflow","score":-1,"reason":"no workflows found","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":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"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":"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: MIT License: 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":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"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":"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":"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-22T00:42:34.542Z","repository_id":57492049,"created_at":"2025-08-22T00:42:34.542Z","updated_at":"2025-08-22T00:42:34.542Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28338991,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T12:22:26.515Z","status":"ssl_error","status_checked_at":"2026-01-12T12:22:10.856Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["go","go-package","go-testing","golang","golang-package"],"created_at":"2026-01-12T13:03:32.981Z","updated_at":"2026-01-12T13:03:33.037Z","avatar_url":"https://github.com/nickwells.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- Code generated by mkbadge; DO NOT EDIT. START --\u003e\n[![go.dev reference](https://img.shields.io/badge/go.dev-reference-green?logo=go)](https://pkg.go.dev/mod/github.com/nickwells/testhelper.mod/v2)\n[![Go Report Card](https://goreportcard.com/badge/github.com/nickwells/testhelper.mod/v2)](https://goreportcard.com/report/github.com/nickwells/testhelper.mod/v2)\n![GitHub License](https://img.shields.io/github/license/nickwells/testhelper.mod)\n\u003c!-- Code generated by mkbadge; DO NOT EDIT. END --\u003e\n\n# testhelper.mod\nSome useful functions and types to simplify and improve testing.\n\nSeveral of these are intended to be used as unnamed members of a testcase\nstruct. The testcase idiom is a table-driven testing scheme where you first\ndefine a slice of structs with the struct holding the parameters to the test\nand the expected results. Then you iterate over the individual test cases\nrunning the code you are testing and compare the results with the expected\nresults.\n\n## the testhelper.ID type\nThis is intended to be used as an unnamed member of a testcase struct. Then\nfor each testcase instance you initialise the value using the constructor:\n\n```go\ntesthelper.MkID(\"...\")\n```\n\nThis has the advantage over a simple string that the constructor records the\nfilename and linenumber where MkID(...)  was called which makes it easier to\nfind the precise test that is failing. It can be used to give a useful\ndescription of the test case through the IDStr() method.\n\nA struct with this embedded will satisfy the testhelper.TestCase interface.\n\n## the testhelper.ExpErr type\nThis is intended to be used as an unnamed member of a testcase struct (though\nif you want to check more than one error condition you can add more). It is\ninitialised using the constructor:\n\n```go\ntesthelper.MkErr(\"part of the error message\", \"some more\", \"etc\")\n```\n\nThe default value expresses that no error is expected. If it is initialised a\nnon-nil error is expected and the strings passed are expected to be found in\nthe error message.\n\nA struct with this embedded will satisfy the testhelper.TestErr interface and\nif the struct also has a testhelper.ID embedded then it will satisfy the\ntesthelper.TestCaseWithErr interface. This can then be passed to\ntesthelper.CheckExpErr which will report a test error if the error is not as\nexpected.\n\n## the testhelper.ExpPanic type\nThis is intended to be used as an unnamed member of a testcase struct (though\nif you want to check more than one panic you can add more). It is initialised\nusing the constructor:\n\n```go\ntesthelper.MkExpPanic(\"part of the panic message\", \"some more\", \"etc\")\n```\n\nThe default value expresses that no panic is expected. If it is initialised a\npanic is expected and the strings passed are expected to be found in\nthe panic value (which is expected to be a string).\n\nA struct with this embedded will satisfy the testhelper.TestPanic interface\nand if the struct also has a testhelper.ID embedded then it will satisfy the\ntesthelper.TestCaseWithPanic interface. This can then be passed to\ntesthelper.CheckExpPanic which will report a test error if the panic is not\nas expected.\n\n## the StringSliceDiff func\nThis takes a pair of string slices and returns true if they differ, false\notherwise.\n\n## the ShouldContain func\nThis takes a string and a slice of strings and reports test errors for each\nstring in the slice that isn't in the string. If any strings are missing it\nwill return true, otherwise false.\n\n## the CheckAgainstGoldenFile func\nThis checks that the passed slice of bytes is the same as the value read from\nthe golden file. You can pass a flag to get the file created initially and to\nupdate it when there has been a desired change in the output being\nchecked. It returns true if the passed bytes match the contents of the golden\nfile, false otherwise.\n\nWhen updating golden files the original contents are recorded in a new file\nwith the same name plus a suffix of `.orig`. These can then be compared\nagainst the original to see the changes. It is recommended that you add a\nline to a `.gitignore` file (if you're using `git`) to make sure that you\ndon't accidentally save these files.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnickwells%2Ftesthelper.mod","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnickwells%2Ftesthelper.mod","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnickwells%2Ftesthelper.mod/lists"}