一键导入
sake-testing
Use when writing or running tests for the Sake project — unit tests, macro expansion tests, integration tests, test helpers, and CI test commands.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when writing or running tests for the Sake project — unit tests, macro expansion tests, integration tests, test helpers, and CI test commands.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | sake-testing |
| description | Use when writing or running tests for the Sake project — unit tests, macro expansion tests, integration tests, test helpers, and CI test commands. |
| Target | Tests | Framework |
|---|---|---|
SakeTests | Command, CommandRunner, CommandsPreprocessor, ClosestMatchFinder, CommandListFormatter | XCTest |
SakeCLILibraryTests | ConfigManager, ConfigResolver, SakeAppManager, FileHandle | XCTest |
SakeMacrosTests | @CommandGroup macro expansion | XCTest + SwiftSyntaxMacrosTestSupport |
IntegrationTests | Full CLI execution via subprocess | XCTest + swift-subprocess |
sake test # build + unit + integration
sake build_tests # build only
sake unit_tests --skip-build # unit tests without rebuild
sake integration_tests --skip-build # integration tests without rebuild
Direct swift commands:
swift test --filter "^(?!.*\bIntegrationTests\b).*" # unit + macro tests
swift test --filter IntegrationTests # integration only
swift test # everything
nonisolated(unsafe) var runnedCommands: [String] = []
let command = Command(
skipIf: { _ in runnedCommands.append("skipIf"); return false },
run: { _ in runnedCommands.append("run") },
)
let runner = CommandRunner(command: command, context: .empty)
try await runner.run()
XCTAssertEqual(runnedCommands, ["skipIf", "run"])
private extension Command.Context {
static var empty: Command.Context {
Command.Context(
arguments: [],
environment: [:],
appDirectory: "",
runDirectory: "",
storage: .init(),
interruptionHandler: .init(processMonitor: .init()),
)
}
}
let dep = Command(run: { context in
context.storage["key"] = "value"
})
let main = Command(dependencies: [dep], run: { context in
XCTAssertEqual(context.storage["key"] as? String, "value")
})
import SakeMacros
import SwiftSyntaxMacrosTestSupport
assertMacroExpansion(
inputSource,
expandedSource: expectedOutput,
macros: ["CommandGroup": CommandGroupMacro.self],
)
Use protocol-based mocking for SakeAppManagerFileHandle and SakeAppManagerCommandExecutor. Tests verify:
Full end-to-end: compile SakeApp, execute commands, verify output. Use swift-subprocess to run sake binary.
All test methods use async throws:
func testSomething() async throws {
// ...
}
Use when working on CI workflows, GitHub Actions, release process, changelog generation (git-cliff), or dependabot configuration.
Use when working on SakeCLI or SakeCLILibrary targets — CLI entry point, config resolution, SakeAppManager build/run lifecycle, error handling, shell execution.
Use when writing or modifying Sake commands, CommandGroups, SakeApp files, or SakeApp/ directory code. Covers Command struct, dependencies, skipIf, context, storage, subprocess patterns, argument parsing.
Use when working on Sake configuration — .sake.yml, environment variables, CLI options, ConfigManager, ConfigResolver, or adding new config options.
Use when writing or updating Sake documentation — VitePress site structure, existing pages, how to add new docs, documentation conventions.
Use when modifying the @CommandGroup macro in SakeMacros target — SwiftSyntax ExtensionMacro, code generation patterns, testing with assertMacroExpansion.