.github/skills/typespec-go-add-spector-test/SKILL.md
Adds a Spector mock API test for the typespec-go emitter. Use when given a Spector case link (http-specs or azure-http-specs) to generate the Go client, add it to tspcompile.js, write `*_client_test.go` tests, and validate them against the Spector mock server.
npx skillsauth add azure/autorest.go typespec-go-add-spector-testInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You will receive a Spector case link pointing to a specific scenario/case under:
https://github.com/microsoft/typespec/tree/main/packages/http-specs/specs/...https://github.com/Azure/typespec-azure/tree/main/packages/azure-http-specs/specs/...packages/typespec-go/.scripts/tspcompile.js in the appropriate spec group (httpSpecsGroup or azureHttpSpecsGroup).packages/typespec-go/test/http-specs/ or packages/typespec-go/test/azure-http-specs/.*_client_test.go files that validate the generated SDK against the Spector mock API server. One test file per generated client (i.e., per zz_<name>_client.go file).pnpm install, package build)tspcompile.jspnpm tspcompile --filter=<groupname> to generate Go client codemockapi.ts file to understand expected request/response*_client_test.go test file per generated client, matching the mock API expectationspnpm spector --start)pnpm spector --stop)Before starting, ensure the build environment is ready.
All commands below run from the repo root (autorest.go/).
pnpm install
cd packages/typespec-go
pnpm build
If the link is under microsoft/typespec/.../packages/http-specs/specs/<path>:
httpSpecsGroup in tspcompile.js<path> (relative to the http-specs/specs/ root)packages/typespec-go/test/http-specs/If the link is under Azure/typespec-azure/.../packages/azure-http-specs/specs/<path>:
azureHttpSpecsGroup in tspcompile.js<path> (relative to the azure-http-specs/specs/ root)packages/typespec-go/test/azure-http-specs/From the link, extract the path after specs/. For example:
https://github.com/microsoft/typespec/tree/main/packages/http-specs/specs/type/model/emptytype/model/emptySearch tspcompile.js for the spec path. If it already exists, skip to Step 4 (writing tests).
Open packages/typespec-go/.scripts/tspcompile.js and add a new entry to the appropriate group object.
'<groupname>': ['<spec-path>', '<optional-emitter-options>...'],
Group name: lowercase, no hyphens, append group suffix. Derived from the last segment of the spec path.
type/model/empty → emptygroupazure/core/basic → basicgroupencode/datetime → datetimegroupazure/client-generator-core/access → accessgroupSpec path: the path relative to the specs root (e.g., type/model/empty, azure/core/basic).
For http-specs:
const httpSpecsGroup = {
// ... existing entries ...
'bytesgroup': ['encode/bytes'],
};
For azure-http-specs:
const azureHttpSpecsGroup = {
// ... existing entries ...
'basicgroup': ['azure/core/basic'],
};
Insert the new entry in a logical position (typically alphabetical by group name or grouped with related specs).
From the packages/typespec-go directory, run:
pnpm tspcompile --filter=<groupname>
For example:
pnpm tspcompile --filter=emptygroup
This generates Go files (prefixed zz_) into the output directory under test/http-specs/ or test/azure-http-specs/.
Check that the output directory was created and contains generated files:
zz_*_client.go — client implementationzz_models.go — model typeszz_options.go — options structszz_responses.go — response typesgo.mod — Go module fileIf the output directory is empty or missing zz_ files, generation failed. Check the console output for errors.
After generation, you need to ensure go.sum is populated. From the generated module directory:
cd test/<http-specs|azure-http-specs>/<path>/<groupname>
go mod tidy
The mockapi.ts file defines the expected HTTP requests and responses for each scenario. It is located at:
packages/typespec-go/node_modules/@typespec/http-specs/specs/<spec-path>/mockapi.tspackages/typespec-go/node_modules/@azure-tools/azure-http-specs/specs/<spec-path>/mockapi.tsEach scenario entry contains:
uri — the HTTP endpoint pathmethod — HTTP method (get, post, put, patch, delete)request — expected request details:
body — request body (wrapped in json(...))headers — expected request headersquery — expected query parameterspathParams — expected path parametersresponse — what the mock server returns:
status — HTTP status codebody — response body (wrapped in json(...))headers — response headersThe scenario names follow a pattern like Type_Model_Empty_getEmpty which maps to the generated client method GetEmpty. Use the generated zz_*_client.go files to find the exact method signatures.
Create one *_client_test.go file per generated client. Each generated zz_<name>_client.go should have a corresponding <name>_client_test.go test file.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
package <groupname>_test
import (
"context"
"<groupname>"
"testing"
"github.com/stretchr/testify/require"
)
All generated clients have a New<ClientName>WithNoCredential constructor. Always use http://localhost:3000 as the endpoint:
client, err := <groupname>.New<ClientName>WithNoCredential("http://localhost:3000", nil)
require.NoError(t, err)
Test<ClientName>_<MethodName> or Test<ClientName><MethodName>:
TestEmptyClientGetEmptyTestBasicClient_CreateOrReplaceTestHeaderClientDefaultIf the generated code has sub-clients (e.g., NewBytesHeaderClient()), access them via the parent client:
client, err := bytesgroup.NewBytesClientWithNoCredential("http://localhost:3000", nil)
require.NoError(t, err)
resp, err := client.NewBytesHeaderClient().Base64(context.Background(), []byte("test"), nil)
require.Zero(t, resp)require.EqualValues(t, expected, resp.<Field>)to.Ptr(value) from github.com/Azure/azure-sdk-for-go/sdk/azcore/torequire.WithinDuration(t, expected, actual, 0)pager.More() / pager.NextPage(context.Background())poller.PollUntilDone(context.Background(), nil)import (
"context"
"<groupname>"
"testing"
"github.com/Azure/azure-sdk-for-go/sdk/azcore" // for azcore.ETag, etc.
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to" // for to.Ptr()
"github.com/stretchr/testify/require" // for assertions
)
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
package emptygroup_test
import (
"context"
"emptygroup"
"testing"
"github.com/stretchr/testify/require"
)
func TestEmptyClientGetEmpty(t *testing.T) {
client, err := emptygroup.NewEmptyClientWithNoCredential("http://localhost:3000", nil)
require.NoError(t, err)
resp, err := client.GetEmpty(context.Background(), nil)
require.NoError(t, err)
require.Zero(t, resp)
}
func TestEmptyClientPutEmpty(t *testing.T) {
client, err := emptygroup.NewEmptyClientWithNoCredential("http://localhost:3000", nil)
require.NoError(t, err)
resp, err := client.PutEmpty(context.Background(), emptygroup.EmptyInput{}, nil)
require.NoError(t, err)
require.Zero(t, resp)
}
From the packages/typespec-go directory:
pnpm spector --start
This starts the Spector mock server in the background on http://localhost:3000. It serves both http-specs and azure-http-specs scenarios.
Navigate to the generated module directory and run the tests:
cd test/<http-specs|azure-http-specs>/<path>/<groupname>
go test -v ./...
For example:
cd test/http-specs/type/model/emptygroup
go test -v ./...
All tests should pass. If a test fails:
pnpm spector --start should have been run first.http://localhost:3000.zz_*_client.go to verify method signatures and parameter types.After tests pass, stop the server:
pnpm spector --stop
go.mod.zz_ and should NOT be manually edited.*_client_test.go) are hand-written and ARE committed to the repo.go.mod, go.sum, and LICENSE.txt files in the test directory are auto-generated.testdata/_metadata.json file tracks emitter version (normalized to "0.0.0" by the build script).zz_version.go — it is preserved across regenerations for v2+ major version scenarios.http://localhost:3000 — all test clients must use this as the endpoint.require from github.com/stretchr/testify for all assertions (never assert).zz_<name>_client.go, create a corresponding <name>_client_test.go. Do NOT consolidate all tests into a single file.*_client_test.go) and changes to tspcompile.js. Generated zz_* files, go.mod, go.sum, LICENSE.txt, and testdata/ are also committed (they are NOT gitignored for typespec-go tests).tspcompile.js, fixed options (module, emitter-output-dir, file-prefix) cannot be overridden. Default options (generate-fakes, inject-spans, head-as-boolean, fix-const-stuttering) can be overridden per test.tools
Upgrade tsp toolset dependencies for the @azure-tools/typespec-go package in Azure/autorest.go repo. Use when user wants to bump, update, or upgrade the TypeSpec toolset dependencies (e.g., @typespec/compiler, @typespec/http, @azure-tools/typespec-client-generator-core, @azure-tools/azure-http-specs), create a release PR, or publish a new version of typespec-go.
tools
Use when work should span one or more detached tasks but still behave like one job with a single owner context. TaskFlow is the durable flow substrate under authoring layers like Lobster, ACPX, plugins, or plain code. Keep conditional logic in the caller; use TaskFlow for flow identity, child-task linkage, waiting state, revision-checked mutations, and user-facing emergence.
tools
# Lobster Lobster executes multi-step workflows with approval checkpoints. Use it when: - User wants a repeatable automation (triage, monitor, sync) - Actions need human approval before executing (send, post, delete) - Multiple tool calls should run as one deterministic operation ## When to use Lobster | User intent | Use Lobster? | | ------------------------------------------------------ | --------------------------
tools
# Lobster Lobster executes multi-step workflows with approval checkpoints. Use it when: - User wants a repeatable automation (triage, monitor, sync) - Actions need human approval before executing (send, post, delete) - Multiple tool calls should run as one deterministic operation ## When to use Lobster | User intent | Use Lobster? | | ------------------------------------------------------ | --------------------------