跳到正文
cccskills
免费在 GitHub 公开

style-guide

TypeScript and test style conventions for the testmex monorepo. Use when writing or reviewing TypeScript types, interfaces, core domain models, or tests in this repository.

中文简介正在准备中。当前显示原文说明。

查看安装方法

包含的文件(1)

  • SKILL.md3.8 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

Style Guide

Module layout: main types first

Put the main exported types and functions at the top of the file. Place the types and helper functions they depend on below, ordered from outer to inner.

// ✅
export class ProgressReporterFake { /* … */ }

export interface PhaseState {
  steps: readonly StepState[];
}

export interface StepState {
  subSteps: readonly SubStepState[];
}

export interface SubStepState {
  message: string;
}

interface MutablePhaseState { /* … */ }

// ❌ — leaf types before the class that exposes them
export interface SubStepState { /* … */ }
export interface StepState { /* … */ }
export class ProgressReporterFake { /* … */ }

Object shapes: prefer interface

Use interface for object shapes. Use type only when interface cannot express the shape (unions, intersections, mapped types, branded primitives).

// ✅
export interface Workspace {
  info: WorkspaceState;
  tree: Tree;
}

// ❌
export type Workspace = { info: WorkspaceState; tree: Tree };

Branded strings

Use a branded string plus a factory function for domain primitives that must not be confused with plain strings.

export type RelativePath = string & { readonly [__relativePathBrand]: true };

export function relativePath(path: string): RelativePath {
  return path as RelativePath;
}

declare const __relativePathBrand: unique symbol;

Apply the same pattern to FindingType and similar domain strings. Use findingType() at call sites.

Module-level constants

Use UPPER_SNAKE_CASE for module-level constant bindings (arrays, config objects, magic strings shared within a file).

// ✅
const EXCLUDED_CODE_FILE_NAMES = [
  'jest.config.ts',
  'vitest.config.ts',
] as const;

// ❌
const excludedCodeFileNames = ['jest.config.ts', 'vitest.config.ts'] as const;

Test names

Start test descriptions in lower case: it('staged write is visible…').

Use Class or function for describe suite names — do not use Class.name or function.name (e.g. describe(Vitestify, …) not describe(Vitestify.name, …)).

Do not use it.each (or describe.each). Repeat the test case with a separate it for each input.

// ✅
it('returns true for src/app.spec.ts', () => {
  expect(isTestFile(relativePath('src/app.spec.ts'))).toBe(true);
});

it('returns true for src/app.test.ts', () => {
  expect(isTestFile(relativePath('src/app.test.ts'))).toBe(true);
});

// ❌
it.each(['src/app.spec.ts', 'src/app.test.ts'])(
  'returns true for %s',
  (path) => {
    expect(isTestFile(relativePath(path))).toBe(true);
  },
);

Assertions

Prefer inlined expected values over variables — the assertion should read as a self-contained statement of what the test checks.

// ✅
expect(await tree.maybeReadFile(mainPath)).toBe('console.log("hello");');
expect(tree.changes()).toEqual([{ type: 'delete', path: 'the/main/path.ts' }]);

// ❌
const expectedContent = 'console.log("hello");';
const expectedChanges = [{ type: 'delete', path: mainPath }];
expect(await tree.maybeReadFile(mainPath)).toBe(expectedContent);
expect(tree.changes()).toEqual(expectedChanges);

When a test has more than one expect, use expect.soft so every assertion runs and failures are reported together.

// ✅
expect.soft(await tree.maybeReadFile(mainPath)).toBeNull();
expect
  .soft(tree.changes())
  .toEqual([{ type: 'delete', path: 'the/main/path.ts' }]);

// ❌
expect(await tree.maybeReadFile(mainPath)).toBeNull();
expect(tree.changes()).toEqual([{ type: 'delete', path: mainPath }]);

A single expect in a test may use plain expect.

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

Continues Charted Coding work for a PR by routing to scaffold, red, or green based on design doc progress. Use when resuming work on a PR, continuing TDD after a break, or when the user invokes charted continue with a design doc and PR number.

中文简介正在准备中。当前显示原文说明。

testmex/testmex42026年7月23日 更新

Interviews the user section by section to collaboratively produce design documents. Use when creating a design doc, starting feature design, or when the user invokes the design command.

中文简介正在准备中。当前显示原文说明。

testmex/testmex42026年7月23日 更新

Progressively activates todo tests one at a time, updates implementation code until each passes (verified via Wallaby), checks off matching design doc progress, then moves to the next—following the design doc as the single source of truth.

中文简介正在准备中。当前显示原文说明。

testmex/testmex42026年7月23日 更新

Runs Charted Coding iterations in a loop — route via charted-continue, batch red or green work for an entire test file, commit, then repeat until the PR is complete. Infers design doc and PR number when omitted. Use when the user invokes charted loop, wants batch TDD for a PR test file, or asks to continue charted work with commits.

中文简介正在准备中。当前显示原文说明。

testmex/testmex42026年7月23日 更新

Writes the next failing test based on provided design doc and existing todo tests

中文简介正在准备中。当前显示原文说明。

testmex/testmex42026年7月23日 更新

Reviews a design doc with expert sub-agents

中文简介正在准备中。当前显示原文说明。

testmex/testmex42026年7月23日 更新

查看 testmex 的全部技能

报告此技能的问题