From claude-resources
Go testing with Ginkgo (BDD) and Gomega (matchers). Describe/Context/It organization, DescribeTable, setup hooks, DeferCleanup. Use when project uses Ginkgo/Gomega instead of stdlib testing. 100% Go-specific.
npx claudepluginhub deandum/claude-resources --plugin go-skillsThis skill uses the workspace's default tool permissions.
BDD-style testing. Use when project already adopted Ginkgo/Gomega.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Guides agent creation for Claude Code plugins with file templates, frontmatter specs (name, description, model), triggering examples, system prompts, and best practices.
BDD-style testing. Use when project already adopted Ginkgo/Gomega.
go install github.com/onsi/ginkgo/v2/ginkgo@latest
go get github.com/onsi/ginkgo/v2
go get github.com/onsi/gomega
ginkgo bootstrap # Creates suite file
var _ = Describe("ParseAmount", func() {
Context("when given valid input", func() {
It("parses whole dollars", func() {
result, err := parser.ParseAmount("42")
Expect(err).ToNot(HaveOccurred())
Expect(result).To(Equal(int64(4200)))
})
})
Context("when given invalid input", func() {
It("returns error for negative amounts", func() {
_, err := parser.ParseAmount("-10")
Expect(err).To(HaveOccurred())
})
})
})
Describe = component/function. Context = scenario. It = expected behavior.
DescribeTable("parsing inputs",
func(input string, expected int64, shouldError bool) {
result, err := parser.ParseAmount(input)
if shouldError { Expect(err).To(HaveOccurred()) } else {
Expect(err).ToNot(HaveOccurred())
Expect(result).To(Equal(expected))
}
},
Entry("whole dollars", "42", int64(4200), false),
Entry("negative", "-10", int64(0), true),
)
PEntry = pending (skipped). FEntry = focused (only this runs).
BeforeEach(func() { repo = &mockRepo{}; service = NewService(repo) })
AfterEach(func() { /* cleanup */ })
BeforeSuite(func() { /* expensive setup once */ })
DeferCleanup(func() { db.Close() }) // Like t.Cleanup
Same function-based mocks as go/testing, wired in BeforeEach:
BeforeEach(func() {
repo.FindByIDFunc = func(_ context.Context, id string) (*User, error) {
if id == "user-1" { return &User{ID: "user-1"}, nil }
return nil, ErrNotFound
}
})
For tests that wait for a condition to become true (timing-sensitive code, eventual consistency, background goroutines), use Eventually and Consistently instead of time.Sleep:
It("marks the job complete within 5 seconds", func() {
go worker.Process(jobID)
Eventually(func() string {
return worker.Status(jobID)
}, 5*time.Second, 100*time.Millisecond).Should(Equal("complete"))
})
It("keeps the connection healthy for 10 seconds", func() {
Consistently(func() bool {
return client.IsConnected()
}, 10*time.Second, 500*time.Millisecond).Should(BeTrue())
})
Eventually polls until the assertion passes or the timeout expires. Consistently fails if the assertion ever fails during the duration. Both take (timeout, pollingInterval) as trailing arguments. These replace time.Sleep in tests — sleeping is slow (takes the full duration) and flaky (may miss a fast state change).
ginkgo -r # All tests recursively
ginkgo -v # Verbose
ginkgo --focus="..." # Filter specs
ginkgo -p --race # Parallel + race detector
ginkgo -r --cover # Coverage
ginkgo -r --race passes with no failures or data racesFIt/FDescribe/FContext/FEntry left in committed codeDeferCleanup used for resource teardown (DB connections, temp files)DescribeTable with Entry used for parameterized test cases