{"id":13786723,"url":"https://github.com/verygoodsoftwarenotvirus/blanket","last_synced_at":"2025-12-15T15:27:57.223Z","repository":{"id":57497001,"uuid":"102362669","full_name":"verygoodsoftwarenotvirus/blanket","owner":"verygoodsoftwarenotvirus","description":"MOVED TO GITLAB","archived":true,"fork":false,"pushed_at":"2018-07-22T18:28:33.000Z","size":10431,"stargazers_count":18,"open_issues_count":1,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-04-22T10:16:01.982Z","etag":null,"topics":["coverage","coverage-testing","go","golang"],"latest_commit_sha":null,"homepage":"https://gitlab.com/verygoodsoftwarenotvirus/blanket","language":"Go","has_issues":false,"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/verygoodsoftwarenotvirus.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":"2017-09-04T13:09:28.000Z","updated_at":"2023-11-12T15:30:41.000Z","dependencies_parsed_at":"2022-09-03T23:50:28.545Z","dependency_job_id":null,"html_url":"https://github.com/verygoodsoftwarenotvirus/blanket","commit_stats":null,"previous_names":["verygoodsoftwarenotvirus/tarp"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/verygoodsoftwarenotvirus%2Fblanket","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/verygoodsoftwarenotvirus%2Fblanket/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/verygoodsoftwarenotvirus%2Fblanket/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/verygoodsoftwarenotvirus%2Fblanket/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/verygoodsoftwarenotvirus","download_url":"https://codeload.github.com/verygoodsoftwarenotvirus/blanket/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225105768,"owners_count":17421791,"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":["coverage","coverage-testing","go","golang"],"created_at":"2024-08-03T19:01:31.069Z","updated_at":"2025-12-15T15:27:57.142Z","avatar_url":"https://github.com/verygoodsoftwarenotvirus.png","language":"Go","funding_links":[],"categories":["Libraries for creating HTTP middlewares","Code Analysis"],"sub_categories":["Routers"],"readme":"# blanket\n\n`blanket` is a tool that helps you catch functions which don't have direct unit tests in your Go packages.\n\n## Installation\n\n    go get -u gitlab.com/verygoodsoftwarenotvirus/blanket\n\n## Docker Image\n\nIf you don't want to install blanket locally, you can use the pre-built Docker image like so:\n\n    docker run -it --rm -v \"$(pwd):/src/\u003cpkg\u003e\" verygoodsoftwarenotvirus/blanket:latest analyze --package \u003cpkg\u003e\n\nWhere `\u003cpkg\u003e` could be something like `gitlab.com/verygoodsoftwarenotvirus/blanket/analysis`. :)\n\n## Purpose\n\nSay, for example, you had the following Go file:\n\n```go\npackage simple\n\nfunc A() string {\n    return \"A\"\n}\n\nfunc B() string {\n    return \"B\"\n}\n\nfunc C() string {\n    return \"C\"\n}\n\nfunc wrapper() {\n   A()\n   B()\n   C()\n}\n```\n\nand you had the following test for that file:\n\n```go\npackage simple\n\nimport (\n    \"testing\"\n)\n\nfunc TestA(t *testing.T) {\n    A()\n}\n\nfunc TestC(t *testing.T) {\n    C()\n}\n\nfunc TestWrapper(t *testing.T) {\n    wrapper()\n}\n```\n\nRunning `go test -cover` on that package yields the following output:\n\n```bash\nPASS\ncoverage: 100.0% of statements\nok      gitlab.com/verygoodsoftwarenotvirus/blanket/example_packages/simple    0.006s\n```\n\nHowever, note that `B` doesn't have a direct test the way that `A` and `C` do. `B` is only \"tested\" in `TestWrapper`. Because all the functions are called, `-cover` yields a 100% coverage value. If you ever decide that `wrapper` doesn't need to call `B` anymore, and don't delete the function entirely, you'll have a drop in coverage. Running `blanket analyze` on that same package yields the following output:\n\n```bash\nFunctions without direct unit tests:\nin /Users/vgsnv/golang/src/gitlab.com/verygoodsoftwarenotvirus/blanket/example_packages/simple/main.go:\n    B on line 7\n\nGrade: 75% (3/4 functions)\n```\n\nAdditionally, you can use the `cover` command to visualize those functions by passing in a cover profile. So if you run something like `go test -coverprofile=coverage.out \u0026\u0026 blanket cover --html=coverage.out`, a browser window will open that shows untested functions in red, functions without direct tests in yellow, and functions that are directly tested in green, like so:\n\n![example output](example_files/cover_screenshot.png)\n\n## Use Cases\n\nWhat `blanket` seeks to do is catch these sorts of things so that package maintainers can decide what the appropriate course of action is. If you're fine with it, that's cool. If you're not cool with it, then you know what needs to have tests added.\n\nYou can also use `blanket` in your CI pipeline to decline PRs that would add functions that don't have direct unit tests. As a matter of fact, `blanket` does just that for itself! [Here](https://gitlab.com/verygoodsoftwarenotvirus/blanket/merge_requests/22) is an example of such a scenario working on this very repository!\n\nI think `blanket` could also be helpful for new developers looking to contribute towards a project. They can run `blanket` on the package and see if there are some functions they could easily add unit tests for, just to get their feet wet in a project.\n\n## Issues\n\nIf you've tried blanket on something and found that it didn't accurately handle some code, or panicked, please feel free to [file an issue](https://gitlab.com/verygoodsoftwarenotvirus/blanket/issues/new). Having an example of the code you experienced issues with is pretty crucial, so keep that in mind.\n\n## Known Issues\n\n`blanket` doesn't adequately handle deeply nested method calls. So if you had something like this:\n\n```go\npackage main\n\nimport (\n    \"testing\"\n)\n\n/*\n// in another file:\ntype Example struct{}\nfunc methodCall() {\n    return\n}\n*/\n\nfunc TestMethod(t *testing.T) {\n    x := struct{\n        First: struct{\n            Second: struct{\n                Third: Example{},\n            },\n        },\n    }\n    x.First.Second.Third.methodCall()\n}\n```\n\nThat should technically satisfy blanket's strict testing requirement, but it doesn't. Blanket can handle single-level selector expressions with great ease, but it doesn't recursively dive into those selectors for a number of reasons.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fverygoodsoftwarenotvirus%2Fblanket","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fverygoodsoftwarenotvirus%2Fblanket","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fverygoodsoftwarenotvirus%2Fblanket/lists"}